IDA - The Interactive
Disassembler - part 3
Dans cette 3eme partie
nous allons voir l'export de notre travail. Il est possible à IDA de produire
un fichier .asm à partir du menu / produce / Asm File. Le fichier obtenu,
n'est pas directement compilable il faut arranger quelques détails, et
selon la complexité du programme il est fort probable pour que ca ne soit
pas du tout compilable, mais il peux toujours etre interressant d'extraire
des parties, ou des fonctions que l'on recopiera dans une autre source.
En reprenant le listing
du code du crackme etudié dans la 2eme partie, nous allons pouvoir admirer
le beau boulot que fait IDA, puisque nous allons pouvoir recompiler ce
listing en un vrai programmme, tel que l'original.
Bien sur ce programme est très simple donc la ca sera assez facile mais
pour des programmes plus complexe c'est beaucoup plus dur voire impossible
(quoique).
Avant tout
U n petit détail que je n'ai pas preciser pour faire un peu plus propre
dans la déclaration des variables du listing. Les 2 buffers pour
le serial et le name sont declaré comme suit :
SerialBuffer
db 0 ; ; DATA XREF: _CheckProc+36o
; _CheckProc+4Do
db 0 ;
db 0 ;
db 0 ;
etc... selon le nbr de char
Il est évident
que c'est un tableau de caractères, donc pour faire plus propre
on se place sur le nom de la variable et on clique sur le boutton de la
barre d'outil avec une étoile qui permet de transformer en tableau.
Laissez les options par défaut. Vous obtenez :
DATA:0040200D
NameBuffer db 40h dup(0) ; DATA XREF: _CheckProc+9o
DATA:0040200D ; _CheckProc+20o Ce
qui est beaucoup plus lisible :)
Export en .asm
et extraction d'une ressource
Il n'y rien de special à retoucher sous IDA, nous ferons les modifs sur
le fichier .asm et on peux donc exporter le fichier avce le Menu / produce
/ asm file. Bien sur il fodra que les modifications que vous y avez apportés
respectent les valeurs originelles. Nous obtenons, le code dans un fichier
.asm, Maintenant si le programme comporte des ressources comme dans cet
exemple il va falloir les dumper du programme original vers un fichier .RES
que nous pourrons linker avce le code, ce qui me semble la solution la plus
simple. Pour extraire une ressource d'un programme on peux utiliser un extracteur
de resource et l'exporter dans un fomat .RC ou .RES (le .RC necessitera
une manipulation supplementaire afin de produire un fichier .RES lequel
nous pouvons linker) moi j'utilise Resources Hacker un excellent
petit outil qui permet directement d'étraire au format .res. Une fois le
fichier .asm et .res obtenu on peux passer à l'étape suivante.
Arrangement et compilation sous Tasm
Maintenant, on peux essayer de compiler notre source afin de voir les erreurs
que nous indique le compilateur et tenter de les corriger.Voyons
les erreurs du crackme, qui sont trés simple à éliminer. Il nous manque
la directive specifiant le type d'instructions du processeur, il suffit
de rajouter .386 tout en debut. Il se peux que vous obteniez en debut
tout une liste de definitions de constantes windows, vous pouvez pour eclaircir
la source les effacer et remplacer par l'inclusion du fichier qui contient
ces definissions de constante : include
WINDOWS.INC
Ensuite les problemes
qui surviennent proviennent tous d'erreurs de déclaration de fonctions
comme par exemple Undefined symbol: SetDlgItemTextA
Pour corriger ca on
va lister toutes les API utilisés et les déclarer en debut de source comme
suit
global GetModuleHandleA
:PROC
global DialogBoxParamA :PROC
global ExitProcess :PROC
global GetDlgItem :PROC
global SetFocus :PROC
global SendMessageA :PROC
global EndDialog :PROC
global GetDlgItemTextA :PROC
global MessageBoxA :PROC
global SetDlgItemTextA :PROC Voila
tout est près on peux compiler avec Tasm et linker avce la ressource,
je n'ai pas essayé sous Masm mais c'est surement possible, peut
être avec quelques modifs supplementaires...
Voici mon exemple qui contient le fichier .asm produit par IDA, le fichier
.res dumpé du programme original et le batch pour la compilation. Download me
Je tiens à répéter
que cela n'est pas aussi simple sur d'autres programmes,
voir surement impossible. Mais si vous arrivez à recompiler le prog je
vous laisse imaginer les possibilitées qui s'ouvre à vous. Notamment un
petit truc interressant : la compilation en mode debugging, qui aura pour
effet d'ajouter quelques info dans l'exe
(NDOracle: Cf. Tutorial d'Anubis sur la structure du PE)
qui pourront être lues par un debugger comme Soft-Ice où
vous pourrez alors switcher du code asm à la source qui s'affichera sous
Soft-Ice avec les commentaires, variables, fonctions, etc...
Juste pour
le fun voici comment faire:
- on recompile le
programme avec les options de debugging, pour ca il suffit d'ajouter la
commande /zi pour tasm32 et /v pour tlink32 ,comme par exemple:
tasm32
/ml /m3 /zi idaa.asm >> debug.txt
tlink32 -x /Tpe /aa /c /V4.0 /o /v idaa.obj,Crackme1.exe,,c:\tasm\lib\import32.lib,,ress.res
>> debug.txt
- On
lance le symbol loader de Softice
Par
le menu / File / open module on ouvre le programme que l'on vient de compiler.
En s'assurrant que la source qui nous à servit à le compiler se
situe dans le même répertoire, sinon Softice nous
dira qu'il ne peux pas la trouver et proposera soit d'effectuer une recherche
manuelle soit de ne pas y preter attention.
Et on
charge le programme, avec l'icone représenté par un rouage mecanique.
Le loader va s'occuper de générer un fichier .NMS et de
charger la source dont le nom a été specifié lors de la compilation et
l'ajout des debugs infos.
Et hop nous voila sous Softice dans la source asm :
EAX=00401000 EBX=00000000 ECX=81985AD4 EDX=81985B14 ESI=81985AB4 EDI=00000000 EBP=0063FF78 ESP=0063FE3C EIP=00401000 O d I S z a P c CS=01B7 DS=01BF SS=01BF ES=01BF FS=12D7 GS=0000 -------------------------------------------------------------------------------- * ES:DI void * = 0x00000000 --------------------------------------------------byte-------------------------- 0030:00000000 00 00 00 00 65 04 70 00-16 00 CD 09 65 04 70 00 ....e.p.....e.p. 0030:00000010 65 04 70 00 54 FF 00 F0-79 EA 00 F0 21 EA 00 F0 e.p.T...y...!... 0030:00000020 00 00 00 D0 D2 08 A6 0A-3A 00 CD 09 52 00 CD 09 ........:...R... 0030:00000030 6A 00 CD 09 82 00 CD 09-9A 00 CD 09 65 04 70 00 j...........e.p. 0030:00000040 07 00 70 D0 4D F8 00 F0-41 F8 00 F0 E2 24 60 FD ..p.M...A....$`. 0030:00000050 39 E7 00 F0 40 02 B6 06-2D 04 70 00 28 0A B9 07 9...@...-.p.(... 0030:00000060 00 E0 00 F0 2F 00 8F 0A-6E FE 00 F0 04 06 B9 07 ..../...n....... 0030:00000070 1D 00 00 D0 A4 F0 00 F0-22 05 00 00 12 22 53 04 ........"...."S. 0030:00000080 A8 0F CA 00 45 04 CC 0F-F2 2F AF FC B2 22 83 FD ....E..../...".. 0030:00000090 03 00 D9 10 BC 0F CA 00-82 24 66 FD D0 0F CA 00 .........$f..... ----idaa.asm-------------------------------------------------------------------- 00047: 00048: public start 00049:start proc near 00050: push 0 ; lpModuleName 00051: call GetModuleHandleA 00052: mov ds:hInstance, eax 00053: push 0 ; dwInitParam 00054: push offset DialogProc ; lpDialogFunc 00055: push 0 ; hWndParent 00056: push offset aMydialog ; lpTemplateName 00057: push ds:hInstance ; hInstance 00058: call DialogBoxParamA 00059: push eax ; uExitCode 00060: call ExitProcess 00061:start endp 00062: 00063: 00064:; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ 00065: 00066: 00067:; BOOL DialogProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) 00068:; Attributes: bp-based frame 00069: 00070:DialogProc proc near ; DATA XREF: start+Eo 00071: ------------------------------------Crackme1------------------------------------ :!screendump scd1.txt |
C'est y pas beau ça
mon gars ;)... On dispose des commentaires, des noms de variables, des
nom de procédures, les noms des labels etc... Et
bien sûr il est possible de tracer le code ainsi que de poser des
BP sur ces labels et fonctions et de consulter ces variables avec les
commandes habituelles de SI ;)
Allez un ptit screen sur la fonction DialogProc :
EAX=00000000 EBX=0063FBE2 ECX=00000000 EDX=00008C22 ESI=00008C06 EDI=0063FB98 EBP=0063FBB0 ESP=0063FB94 EIP=0040102B o d I s z a P c CS=01B7 DS=01BF SS=01BF ES=01BF FS=12D7 GS=1237 -------------------------------------------------------------------------------- * ES:DI void * = 0x54415000 --------------------------------------------------byte-------------------------- 0030:00000000 00 00 00 00 65 04 70 00-16 00 CD 09 65 04 70 00 ....e.p.....e.p. 0030:00000010 65 04 70 00 54 FF 00 F0-79 EA 00 F0 21 EA 00 F0 e.p.T...y...!... 0030:00000020 00 00 00 D0 D2 08 A6 0A-3A 00 CD 09 52 00 CD 09 ........:...R... 0030:00000030 6A 00 CD 09 82 00 CD 09-9A 00 CD 09 65 04 70 00 j...........e.p. 0030:00000040 07 00 70 D0 4D F8 00 F0-41 F8 00 F0 E2 24 60 FD ..p.M...A....$`. 0030:00000050 39 E7 00 F0 40 02 B6 06-2D 04 70 00 28 0A B9 07 9...@...-.p.(... 0030:00000060 00 E0 00 F0 2F 00 8F 0A-6E FE 00 F0 04 06 B9 07 ..../...n....... -----idaa.asm------------------------------------------------------------------- 00063: 00064:; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ 00065: 00066: 00067:; BOOL DialogProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) 00068:; Attributes: bp-based frame 00069: 00070:DialogProc proc near ; DATA XREF: start+Eo 00071: 00072:hWnd = dword ptr 8 00073:uMsg = dword ptr 0Ch 00074:wParam = dword ptr 10h 00075:lParam = dword ptr 14h 00076: 00077: enter 0, 0 00078: cmp [ebp+uMsg], WM_CLOSE 00079: jz short _CloseDlg ; Ferme le dialog 00080: cmp [ebp+uMsg], WM_INITDIALOG 00081: jz short _InitDlg ; Initialisation du dialog 00082: cmp [ebp+uMsg], WM_COMMAND 00083: jz short _Command ; Command actionn, sur le dialog 00084: mov eax, 0 00085: jmp short _LeaveProc 00086:; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 00087: 00088:_CloseDlg: ; CODE XREF: DialogProc+8j 00089: push 0 ; nResult 00090: push [ebp+hWnd] ; hDlg 00091: call EndDialog 00092: mov eax, 1 00093: jmp short _LeaveProc ------------------------------------Crackme1------------------------------------ :!screendump scd2.txt |
On peux switcher entre 3 types
de sources : la source depuis le fichier .asm, un melange de celle-ci
et du code asm classique, ou alors le code asm classique avce tout de
meme les noms des labels. Pour changer de vue on tape src et on
peux les faires défiler avce F3.
Screen mode
de vue source asm et code classique mélangé:
EAX=00000000 EBX=0063FBE2 ECX=00000000 EDX=00008C22 ESI=00008C06 EDI=0063FB98 EBP=0063FB90 ESP=0063FB90 EIP=0040103C o d I S z a p C CS=01B7 DS=01BF SS=01BF ES=01BF FS=12D7 GS=1237 -------------------------------------------------------------------------------- * ES:DI void * = 0x54415000 --------------------------------------------------byte-------------------------- 0030:00000000 00 00 00 00 65 04 70 00-16 00 CD 09 65 04 70 00 ....e.p.....e.p. 0030:00000010 65 04 70 00 54 FF 00 F0-79 EA 00 F0 21 EA 00 F0 e.p.T...y...!... 0030:00000020 00 00 00 D0 D2 08 A6 0A-3A 00 CD 09 52 00 CD 09 ........:...R... 0030:00000030 6A 00 CD 09 82 00 CD 09-9A 00 CD 09 65 04 70 00 j...........e.p. 0030:00000040 07 00 70 D0 4D F8 00 F0-41 F8 00 F0 E2 24 60 FD ..p.M...A....$`. 0030:00000050 39 E7 00 F0 40 02 B6 06-2D 04 70 00 28 0A B9 07 9...@...-.p.(... 0030:00000060 00 E0 00 F0 2F 00 8F 0A-6E FE 00 F0 04 06 B9 07 ..../...n....... -----DialogProc+000------------------------------------------------------------- 00080 cmp [ebp+uMsg], WM_INITDIALOG 01B7:00401035 817D0C10010000 CMP DWORD PTR [EBP+0C],00000110 00081 jz short _InitDlg ; Initialisation du dialog 01B7:0040103C 7421 JZ _InitDlg (NO JUMP) 00082 cmp [ebp+uMsg], WM_COMMAND 01B7:0040103E 817D0C11010000 CMP DWORD PTR [EBP+0C],00000111 00083 jz short _Command ; Command actionn, sur le dialog 01B7:00401045 7432 JZ _Command 00084 mov eax, 0 01B7:00401047 B800000000 MOV EAX,00000000 00085 jmp short _LeaveProc 01B7:0040104C EB57 JMP _LeaveProc _CloseDlg 00089 push 0 ; nResult 01B7:0040104E 6A00 PUSH 00 00090 push [ebp+hWnd] ; hDlg 01B7:00401050 FF7508 PUSH DWORD PTR [EBP+08] 00091 call EndDialog 01B7:00401053 E8A20F0000 CALL USER32!EndDialog 00092 mov eax, 1 01B7:00401058 B801000000 MOV EAX,00000001 00093 jmp short _LeaveProc 01B7:0040105D EB46 JMP _LeaveProc _InitDlg 00097 push 3E8h ; Edit-box Name 01B7:0040105F 68E8030000 PUSH 000003E8 00098 push [ebp+hWnd] ; hDlg 01B7:00401064 FF7508 PUSH DWORD PTR [EBP+08] 00099 call GetDlgItem 01B7:00401067 E86A0F0000 CALL USER32!GetDlgItem 00100 push eax ; hWnd 01B7:0040106C 50 PUSH EAX ------------------------------------CRACKME1!CODE+0035-------------------------- :!screendump scd3.txt |
Et code classique avec nom des labels
EAX=00000000 EBX=0063FBE2 ECX=00000000 EDX=00008C22 ESI=00008C06 EDI=0063FB98 EBP=0063FB90 ESP=0063FB90 EIP=0040103C o d I S z a p C CS=01B7 DS=01BF SS=01BF ES=01BF FS=12D7 GS=1237 -------------------------------------------------------------------------------- * ES:DI void * = 0x54415000 --------------------------------------------------byte-------------------------- 0030:00000000 00 00 00 00 65 04 70 00-16 00 CD 09 65 04 70 00 ....e.p.....e.p. 0030:00000010 65 04 70 00 54 FF 00 F0-79 EA 00 F0 21 EA 00 F0 e.p.T...y...!... 0030:00000020 00 00 00 D0 D2 08 A6 0A-3A 00 CD 09 52 00 CD 09 ........:...R... 0030:00000030 6A 00 CD 09 82 00 CD 09-9A 00 CD 09 65 04 70 00 j...........e.p. 0030:00000040 07 00 70 D0 4D F8 00 F0-41 F8 00 F0 E2 24 60 FD ..p.M...A....$`. 0030:00000050 39 E7 00 F0 40 02 B6 06-2D 04 70 00 28 0A B9 07 9...@...-.p.(... 0030:00000060 00 E0 00 F0 2F 00 8F 0A-6E FE 00 F0 04 06 B9 07 ..../...n....... -----DialogProc+000------------------------------------------------------------- 01B7:00401035 817D0C10010000 CMP DWORD PTR [EBP+0C],00000110 01B7:0040103C 7421 JZ _InitDlg (NO JUMP) 01B7:0040103E 817D0C11010000 CMP DWORD PTR [EBP+0C],00000111 01B7:00401045 7432 JZ _Command 01B7:00401047 B800000000 MOV EAX,00000000 01B7:0040104C EB57 JMP _LeaveProc _CloseDlg 01B7:0040104E 6A00 PUSH 00 01B7:00401050 FF7508 PUSH DWORD PTR [EBP+08] 01B7:00401053 E8A20F0000 CALL USER32!EndDialog 01B7:00401058 B801000000 MOV EAX,00000001 01B7:0040105D EB46 JMP _LeaveProc _InitDlg 01B7:0040105F 68E8030000 PUSH 000003E8 01B7:00401064 FF7508 PUSH DWORD PTR [EBP+08] 01B7:00401067 E86A0F0000 CALL USER32!GetDlgItem 01B7:0040106C 50 PUSH EAX 01B7:0040106D E8820F0000 CALL USER32!SetFocus 01B7:00401072 B800000000 MOV EAX,00000000 01B7:00401077 EB2C JMP _LeaveProc _Command 01B7:00401079 8B4510 MOV EAX,[EBP+10] 01B7:0040107C 663DEA03 CMP AX,03EA 01B7:00401080 750A JNZ _TestNextId 01B7:00401082 FF7508 PUSH DWORD PTR [EBP+08] 01B7:00401085 E81F000000 CALL _CheckProc 01B7:0040108A EB14 JMP _LeaveProc2 _TestNextId 01B7:0040108C 663DEB03 CMP AX,03EB 01B7:00401090 750E JNZ _LeaveProc2 01B7:00401092 6A00 PUSH 00 01B7:00401094 6A00 PUSH 00 ------------------------------------CRACKME1!CODE+0035-------------------------- :!screendump scd4.txt |
Pour continuer dans l'export nous verrons dans la 4eme et derniere partie,
à defaut de ne pouvoir recompiler la source, comment exporter tout de meme
le listing de IDA vers Softice à l'aide des fichiers .MAP et du fabuleux
plug-in 'ida2sice'.
|