Pour les nouveaux arrivants à la fissuration, cible HP-crackme




La cible: le HP-crackme (272kb)
Ce que vous devez:
1. OllyDbg + plugins
2. ImpRec 1.6 final
3. IDA
4. Eh bien, estessno nekrivye Rica;)

Pour qui est-il écrit?

article Shoyu je l'ai écrit, en particulier pour les nouveaux arrivants à la fissuration, qui (comme je l'entends) ne sont souvent pas tout est clair dans une approche moderne d'un côté quelques-uns à la question de la fissuration. En effet, au fil du temps disparaissent devant attelles, qui ne peut être décrit, que l'une des approches d'inversion (seule décompression, restauration de l'importation, le code d'édition dans la mémoire programme, trouver le numéro de série correct, ou Patcher un programme), et ils ont utilisé le complexe. Premonition que les «as» de craquage c sourire lire la dernière ligne, et je vais répéter que, par exemple, la décompression - est déjà plus de la moitié du travail effectué. Mais en dépit de cela, je décidai d'écrire une attelle, "A à Z" - du manuel d'extraction «victime» de piratage avant patcher le fichier et trouver les informations de connexion correcte. Je pense que beaucoup de débutants seront utiles pour "toucher" les différentes options krekmi piratage.

décompression manuelle


Il ressemble à notre krekmi

Exécutez OllyDbg et le télécharger sur notre krekmi. Nous allons nous concentrer sur le PE et voir la photo suivante:


Nous trouvons le point d'entrée d'origine

Nous voyons ce que l'on appelle une fonction, qui a passé 3 arguments. Ensuite, vous sautez sur le même code est pas connu. Nous notons que, à 00.482.019 Un tableau de lignes intéressantes. Selon lui, notre programme est emballé avec un PKLite runtime packer et d'explorer, le modifier devra décompresser. (Passez le chemin de moindre soprativleniya il a été décidé d'utiliser le plug-in avtoraspakovki peid 0,92, mais il, pour une raison quelconque, Packer a «trop dur»). Peu à retracer le code que vous pouvez voir que, à 0040200F est la procédure d'extraction de "corps" comprimé du programme. Après l'achèvement de son krekmi de travail en mémoire sera en mesure de pleinement funktsionilnom. Pour sa otdampit trouver OEP. La chose la plus intéressante est que, immédiatement après le déballage des procédures et effectué un saut sur ce OEP très (JMP 00468A48). Hit F8 et nous nous trouvons sur elle. Maintenant, vous pouvez et vider. Vous pouvez utiliser le plugin pour Ole OllyDump (Plugins-OllyDump-DumpDebuggedProcess-Dump). Il y a une telle fenêtre:


Dump ...



Récupération d'importation


Juste krekmi dampnuty (j'ai appelé fichier dumped.exe) ne démarre pas (erreur de trouver émis le point de l'un des api d'entrée) - il a besoin pour restaurer la table des fonctions importées. Pour ce faire, exécutez la krekmi (hp.exe) et après ImpRec. Dans ce document, entrez l'adresse de notre OEP et cliquez sur le "IAT AutoSearch" - "Get importations" - "Fix Dump"


Imprec restaure import ...



Donc, nous avons une krekmi de raspakovanom pleinement fonctionnel (dumped_.exe)! Passez à son analyse ...



Démonter et la rupture de trouver la bonne clé


Démonter Ida dump et load Delphi signature (parce que le programme est écrit dans l'environnement de programmation). Même une visualisation rapide de code dans les yeux jette immédiatement un grand nombre d'opérations de chaîne (depuis 00466BC7 adresse). Regardez un peu plus haut:
loc_466B0C: ; CODE XREF: CODE:00466B11j push 0 push 0 dec ecx jnz short loc_466B0C push ecx push ebx push esi push edi mov [ebp- 4 ], eax mov ebx, offset unk_46BC58 mov esi, offset unk_46BC78 xor eax, eax push ebp push offset loc_468100 push dword ptr fs:[eax] mov fs:[eax], esp lea edx, [ebp- 8 ] mov eax, [ebp- 4 ] mov eax, [eax+ 308h ] call @TControl@GetText$qqrv ; считываем имя юзера с Edit1 cmp dword ptr [ebp- 8 ], 0 jnz short loc_466B58 ; прыгаем если ввели хоть что-то mov eax, offset _str________________.Text call @Dialogs@ShowMessage$qqrx17System@AnsiString ; Dialogs::ShowMessage(System::AnsiString) jmp loc_4680C0 ; jmp на выход 
Suivant (00466C43) est le nom de la clé de code de lecture, et la formule de seriynika test nous les introduit:
 call @TControl@GetText$qqrv ; eax = length(name) mov edx, [ebp- 0Ch ] mov eax, offset dword_46BC64 call @System@@LStrAsg$qqrv ; System::__linkproc__ LStrAsg(void) lea edx, [ebp- 10h ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F4h ] call @TControl@GetText$qqrv ; eax = length(key) mov edx, [ebp- 10h ] ; edx = *key mov eax, offset unk_46BC5C call @System@@LStrAsg$qqrv ; System::__linkproc__ LStrAsg(void) lea edx, [ebp- 14h ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F0h ] call @TControl@GetText$qqrv ; eax=length(serial) mov edx, [ebp- 14h ] ; edx= *serial mov eax, offset unk_46BC60 call @System@@LStrAsg$qqrv ; System::__linkproc__ LStrAsg(void) mov eax, ds:dword_46BC64 call @System@_16823 ; eax=length(name) mov edi, eax test edi, edi jle loc_46740E ; если не ввели имя, то выходим mov ds:dword_46BC7C, 1
call @TControl@GetText$qqrv ; eax = length(name) mov edx, [ebp- 0Ch ] mov eax, offset dword_46BC64 call @System@@LStrAsg$qqrv ; System::__linkproc__ LStrAsg(void) lea edx, [ebp- 10h ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F4h ] call @TControl@GetText$qqrv ; eax = length(key) mov edx, [ebp- 10h ] ; edx = *key mov eax, offset unk_46BC5C call @System@@LStrAsg$qqrv ; System::__linkproc__ LStrAsg(void) lea edx, [ebp- 14h ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F0h ] call @TControl@GetText$qqrv ; eax=length(serial) mov edx, [ebp- 14h ] ; edx= *serial mov eax, offset unk_46BC60 call @System@@LStrAsg$qqrv ; System::__linkproc__ LStrAsg(void) mov eax, ds:dword_46BC64 call @System@_16823 ; eax=length(name) mov edi, eax test edi, edi jle loc_46740E ; если не ввели имя, то выходим mov ds:dword_46BC7C, 1 
Sauter environ 100 opérations de copie et la conversion des lignes et le même nombre d'arithmétique (l'auteur semble penser que ce nombre devrait effrayer les craquelins novices) voir plus d'une image intéressante: IDA - C: \ article \ dumped_.idb (dumped_.exe)
 push eax lea edx, [ebp- 6Ch ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F4h ] call @TControl@GetText$qqrv ; считываем ключ mov edx, [ebp- 6Ch ] pop eax ; eax = valid key! call @System@@LStrCmp$qqrv ; System::__linkproc__ LStrCmp(void) jnz loc_4680C0 ; прыгаем если не равны push ds:dword_46BD00 push ds:dword_46BD04 push ds:dword_46BD08 push ds:dword_46BD0C push offset _str___22.Text push ds:dword_46BC98 push ds:dword_46BC9C push ds:dword_46BCA0 push ds:dword_46BCA4 push ds:dword_46BCA8 push offset _str___22.Text push ds:dword_46BCF4 push ds:dword_46BCF8 push ds:dword_46BCFC lea eax, [ebp- 70h ] mov edx, 0Eh ; --------------- SUBROUTINE --------------------------------------- sub_468062 proc near call @System@@LStrCatN$qqrv ; подс4ет валидного регномера mov eax, [ebp- 70h ] ; сохраняем его в eax push eax lea edx, [ebp- 74h ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F0h ] call @TControl@GetText$qqrv ; TControl::GetText(void) mov edx, [ebp- 74h ] pop eax call @System@@LStrCmp$qqrv ; финальное сравнение ! jnz short loc_4680C0 ; прыгаем, если BadGuy mov edx, 190h mov eax, ds:dword_46BC50 call @Forms@TCustomForm@SetClientWidth$qqri ; Forms::TCustomForm::SetClientWidth(int) mov eax, [ebp- 4 ] mov eax, [eax+ 310h ] mov dl, 1 call @Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool) mov eax, [ebp- 4 ] mov eax, [eax+ 314h ] mov dl, 1 call @Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool) mov ds:dword_46BCC4, 1 loc_4680C0: ; CODE XREF: CODE:00466B53j ; CODE:00468002j ... xor eax, eax ; выходим... pop edx pop ecx pop ecx mov fs:[eax], edx push offset loc_468107 qqri; push eax lea edx, [ebp- 6Ch ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F4h ] call @TControl@GetText$qqrv ; считываем ключ mov edx, [ebp- 6Ch ] pop eax ; eax = valid key! call @System@@LStrCmp$qqrv ; System::__linkproc__ LStrCmp(void) jnz loc_4680C0 ; прыгаем если не равны push ds:dword_46BD00 push ds:dword_46BD04 push ds:dword_46BD08 push ds:dword_46BD0C push offset _str___22.Text push ds:dword_46BC98 push ds:dword_46BC9C push ds:dword_46BCA0 push ds:dword_46BCA4 push ds:dword_46BCA8 push offset _str___22.Text push ds:dword_46BCF4 push ds:dword_46BCF8 push ds:dword_46BCFC lea eax, [ebp- 70h ] mov edx, 0Eh ; --------------- SUBROUTINE --------------------------------------- sub_468062 proc near call @System@@LStrCatN$qqrv ; подс4ет валидного регномера mov eax, [ebp- 70h ] ; сохраняем его в eax push eax lea edx, [ebp- 74h ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F0h ] call @TControl@GetText$qqrv ; TControl::GetText(void) mov edx, [ebp- 74h ] pop eax call @System@@LStrCmp$qqrv ; финальное сравнение ! jnz short loc_4680C0 ; прыгаем, если BadGuy mov edx, 190h mov eax, ds:dword_46BC50 call @Forms@TCustomForm@SetClientWidth$qqri ; Forms::TCustomForm::SetClientWidth(int) mov eax, [ebp- 4 ] mov eax, [eax+ 310h ] mov dl, 1 call @Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool) mov eax, [ebp- 4 ] mov eax, [eax+ 314h ] mov dl, 1 call @Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool) mov ds:dword_46BCC4, 1 loc_4680C0: ; CODE XREF: CODE:00466B53j ; CODE:00468002j ... xor eax, eax ; выходим... pop edx pop ecx pop ecx mov fs:[eax], edx push offset loc_468107 qqro; push eax lea edx, [ebp- 6Ch ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F4h ] call @TControl@GetText$qqrv ; считываем ключ mov edx, [ebp- 6Ch ] pop eax ; eax = valid key! call @System@@LStrCmp$qqrv ; System::__linkproc__ LStrCmp(void) jnz loc_4680C0 ; прыгаем если не равны push ds:dword_46BD00 push ds:dword_46BD04 push ds:dword_46BD08 push ds:dword_46BD0C push offset _str___22.Text push ds:dword_46BC98 push ds:dword_46BC9C push ds:dword_46BCA0 push ds:dword_46BCA4 push ds:dword_46BCA8 push offset _str___22.Text push ds:dword_46BCF4 push ds:dword_46BCF8 push ds:dword_46BCFC lea eax, [ebp- 70h ] mov edx, 0Eh ; --------------- SUBROUTINE --------------------------------------- sub_468062 proc near call @System@@LStrCatN$qqrv ; подс4ет валидного регномера mov eax, [ebp- 70h ] ; сохраняем его в eax push eax lea edx, [ebp- 74h ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F0h ] call @TControl@GetText$qqrv ; TControl::GetText(void) mov edx, [ebp- 74h ] pop eax call @System@@LStrCmp$qqrv ; финальное сравнение ! jnz short loc_4680C0 ; прыгаем, если BadGuy mov edx, 190h mov eax, ds:dword_46BC50 call @Forms@TCustomForm@SetClientWidth$qqri ; Forms::TCustomForm::SetClientWidth(int) mov eax, [ebp- 4 ] mov eax, [eax+ 310h ] mov dl, 1 call @Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool) mov eax, [ebp- 4 ] mov eax, [eax+ 314h ] mov dl, 1 call @Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool) mov ds:dword_46BCC4, 1 loc_4680C0: ; CODE XREF: CODE:00466B53j ; CODE:00468002j ... xor eax, eax ; выходим... pop edx pop ecx pop ecx mov fs:[eax], edx push offset loc_468107 qqro; push eax lea edx, [ebp- 6Ch ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F4h ] call @TControl@GetText$qqrv ; считываем ключ mov edx, [ebp- 6Ch ] pop eax ; eax = valid key! call @System@@LStrCmp$qqrv ; System::__linkproc__ LStrCmp(void) jnz loc_4680C0 ; прыгаем если не равны push ds:dword_46BD00 push ds:dword_46BD04 push ds:dword_46BD08 push ds:dword_46BD0C push offset _str___22.Text push ds:dword_46BC98 push ds:dword_46BC9C push ds:dword_46BCA0 push ds:dword_46BCA4 push ds:dword_46BCA8 push offset _str___22.Text push ds:dword_46BCF4 push ds:dword_46BCF8 push ds:dword_46BCFC lea eax, [ebp- 70h ] mov edx, 0Eh ; --------------- SUBROUTINE --------------------------------------- sub_468062 proc near call @System@@LStrCatN$qqrv ; подс4ет валидного регномера mov eax, [ebp- 70h ] ; сохраняем его в eax push eax lea edx, [ebp- 74h ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F0h ] call @TControl@GetText$qqrv ; TControl::GetText(void) mov edx, [ebp- 74h ] pop eax call @System@@LStrCmp$qqrv ; финальное сравнение ! jnz short loc_4680C0 ; прыгаем, если BadGuy mov edx, 190h mov eax, ds:dword_46BC50 call @Forms@TCustomForm@SetClientWidth$qqri ; Forms::TCustomForm::SetClientWidth(int) mov eax, [ebp- 4 ] mov eax, [eax+ 310h ] mov dl, 1 call @Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool) mov eax, [ebp- 4 ] mov eax, [eax+ 314h ] mov dl, 1 call @Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool) mov ds:dword_46BCC4, 1 loc_4680C0: ; CODE XREF: CODE:00466B53j ; CODE:00468002j ... xor eax, eax ; выходим... pop edx pop ecx pop ecx mov fs:[eax], edx push offset loc_468107
push eax lea edx, [ebp- 6Ch ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F4h ] call @TControl@GetText$qqrv ; считываем ключ mov edx, [ebp- 6Ch ] pop eax ; eax = valid key! call @System@@LStrCmp$qqrv ; System::__linkproc__ LStrCmp(void) jnz loc_4680C0 ; прыгаем если не равны push ds:dword_46BD00 push ds:dword_46BD04 push ds:dword_46BD08 push ds:dword_46BD0C push offset _str___22.Text push ds:dword_46BC98 push ds:dword_46BC9C push ds:dword_46BCA0 push ds:dword_46BCA4 push ds:dword_46BCA8 push offset _str___22.Text push ds:dword_46BCF4 push ds:dword_46BCF8 push ds:dword_46BCFC lea eax, [ebp- 70h ] mov edx, 0Eh ; --------------- SUBROUTINE --------------------------------------- sub_468062 proc near call @System@@LStrCatN$qqrv ; подс4ет валидного регномера mov eax, [ebp- 70h ] ; сохраняем его в eax push eax lea edx, [ebp- 74h ] mov eax, [ebp- 4 ] mov eax, [eax+ 2F0h ] call @TControl@GetText$qqrv ; TControl::GetText(void) mov edx, [ebp- 74h ] pop eax call @System@@LStrCmp$qqrv ; финальное сравнение ! jnz short loc_4680C0 ; прыгаем, если BadGuy mov edx, 190h mov eax, ds:dword_46BC50 call @Forms@TCustomForm@SetClientWidth$qqri ; Forms::TCustomForm::SetClientWidth(int) mov eax, [ebp- 4 ] mov eax, [eax+ 310h ] mov dl, 1 call @Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool) mov eax, [ebp- 4 ] mov eax, [eax+ 314h ] mov dl, 1 call @Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool) mov ds:dword_46BCC4, 1 loc_4680C0: ; CODE XREF: CODE:00466B53j ; CODE:00468002j ... xor eax, eax ; выходим... pop edx pop ecx pop ecx mov fs:[eax], edx push offset loc_468107 
Ainsi Olga navire et fixer sur les points d'arrêt 00467FFD et 00468080, qui sont stockés dans eax'ah nos données d'enregistrement fidèles. Pour les espionner et entrer dans crackme. Mes codes de données sont les suivantes:


Hacking jump-correction

Et pendant une longue période ne souhaitant pas être pris dans le débogueur peut offrir tout simplement créer un simple fichier .crk * et le patch de la fissure. Maintenant, il ne vérifie pas la longueur des noms d'entrée et de penser que les données valides sont entrées toujours =)
00066B47: 75 EB
00068002: 0F 90
00068003 85 90
00068004: 90 B8
00068005: 00 90
00068006: 00 90
00068007: 00 90
00068085 75 90
00068086 39 90

Copyright © 2005 NGH Group