Cracking & Reverse Engineering by TeeJi --------------------------------------- Hello, j'avais commencé un gros projet sur VB6, lorsque j'ai eu fini le cours, j'ai tout perdu sauf ce qui suis.. Ca explique l'API spoofing, en gros, comment modifier l'Export Table des DLL pour exécuter notre fonction avant l'original. Export Directory : 660930C0 --> 660981DE Name Byte | DWord ---------------------------------------------------------- Characteristics 00 00 00 00 | 00000000 TimeDatStamp FD 15 0C 36 | 360C15FD MajorVersion 00 00 | 0000 MinorVersion 00 00 | 0000 RvaName A6 5D 09 00 | 00095DA6 Base 64 00 00 00 | 00000064 NumberOfFunctions 77 07 00 00 | 00000777 NumberOfName 7B 02 00 00 | 0000027B ArrayOfRvaFctEP E8 30 09 00 | 000930E8 ArrayOfRvaFctName C4 4E 09 00 | 00094EC4 ArrayOfFctOrd B0 58 09 00 | 000958B0 ( Real Ord = Ord + Base ) ---------------------------------------------------------- RvaName : .66095DA6: 4D 53 56 42 56 4D 36 30 2E 44 4C 4C 00 MSVBVM60.DLL Base : 0x64 NumberOfSection : 0x777 = 1911 NumberOfName : 0x27B = 635 ArrayOfRvaFctEP ( Array of DWord ): .660930E0: ?? ?? ?? ??-?? ?? ?? ??-0E 41 02 00-D8 24 05 00 A Ï$ .660930F0: A0 13 04 00-8D A6 0C 00-FA 3B 04 00-D8 19 05 00 á ìª ·; Ï ... ArrayOfRvaFctName ( Array of DWord ): .66094EC0: ?? ?? ?? ??-4E 60 09 00-61 60 09 00-7B 60 09 00 ,% N` a` {` .66094ED0: 8E 60 09 00-A9 60 09 00-BD 60 09 00-DC 60 09 00 Ä` ®` ¢` _` ... ArrayOfFctOrd ( Array of Word ): .660958B0: 37 01 39 01-3A 01 36 01-38 01 40 01-41 01 5A 00 79:68@AZ .660958C0: 6C 07 35 00-36 00 57 00-37 00 06 00-07 00 54 01 l5 6 W 7   T ... Maintenant, effectuons la recherche pour la 1ere fonction du tableau. Le DWord en .66094EC4 = 0009604E = RvaNAME de la Fonction Le Word en .660958B0 = 0x137 = Ord => RealOrd = Ord + Base = 0x137 + 0x64 = 0x19B Le DWord en .(660930E8 + 4*137) soit en .660935C4 = 00001B58 = RvaEP de la FCT Regardons d'abord en .6609604E : .66096040: ?? ?? ?? ??-?? ?? ?? ??-?? ?? ?? ??-?? ?? 42 41 BA .66096050: 53 49 43 5F-43 4C 41 53-53 5F 41 64-64 52 65 66 SIC_CLASS_AddRef .66096060: 00 ... ( Rem : Termine par NULL. ) Le Nom de la FCT = BASIC_CLASS_AddRef L'Ord réel de la Fct = 0x137+0x64 = 0x19B l'EP de la Fct = RvaName + ImageBase = 0x66001B58 Donc, l'astuce serait maintenant de modifier l'ArrayOfEP pour qu'il pointe sur notre fonction et ensuite nous redonnerions la main à la fct original. Rajoutons d'abord notre section. Reguardons les Infos des sections : Object01: .text RVA: 00001000 Offset: 00001000 Size: 00101000 Flags: 60000020 VSize : 1007CC Object02: ENGINE RVA: 00102000 Offset: 00102000 Size: 0000E000 Flags: 60000020 VSize : D0B5 Object03: .data RVA: 00110000 Offset: 00110000 Size: 00007000 Flags: C0000040 VSize : 6E30 Object04: .rsrc RVA: 00117000 Offset: 00117000 Size: 00031000 Flags: 40000040 VSize : 30CE0 Object05: .reloc RVA: 00148000 Offset: 00148000 Size: 00010000 Flags: 42000040 VSize : F484 Voici le SectionHeader de notre Section : Name 2E 54 65 65 4A 69 00 00 ; ".TeeJi" VirtualSize 00 10 00 00 ; VirtualSize = RawSize = 0x1000 VirtualAddress 00 80 15 00 ; VirtualAdd = 0x158000 SizeOfRawData 00 10 00 00 ; VSize = RawSize = 0x1000 PointerToRawData 00 80 15 00 ; RawOffset = 0x158000 PointerToRelocations 00 00 00 00 ; inutilisé PointerToLinenumbers 00 00 00 00 ; inutilisé NumberOfRelocations 00 00 ; inutilisé NumberOfLinenumbers 00 00 ; inutilisé Characteristics 20 00 00 E0 ; code, exécutable, readable, writable On le rajoute dans le fichier, sans oublier de modifier ImageSize et NumberOfSection. On rajoute ensuite les 0x1000 bytes à la fin du fichier. ( Nous allons peut-etre augmenter cette section par après.. ) Maintenant, nous allons passer aux choses sérieuses.. :) L'idée serait de modifier le tableau des Rva des EntryPoint des Fonctions Exportées en les redirigeant vers un truc du genre : PUSH REAL_EP; JMP HooKFcT Un simple mov EAX, [ESP] mettra dans EAX l'EIP du CALL qui appel la fonction. Une petite fonction pourra retrouver le nom de la fonction ainsi que sont ord a partir du Real_EP. Il faudra ensuite détourner la fonction DllMain lorsque le paramètre DLL_PROCESS_DETACH lui sera donné. A ce moment là, il faudra sauveguarder les différentes informations dans un fichier, ou dans le pire des cas les afficher. On pourra aussi, par apres, rajouter une option qui permettra de choisir si on veux etre averti a chaque appel d'une fonction. Cette option devra être décidé au chargement de la Dll. Vu que la pluspart des fct USER32 et KERNEL32 sont présentes dans l'IAT, nous pourrons les utiliser simplement. Pour terminer ce cours en beauté, nous rajouterons le moyen de définir le nombre de parametre de chaque fonctions, et même peut-etre le type de chaque parametre, et donner les infos en conséquence. 1ere Approche du probleme.. On hook une fonction VB et on affiche une MessageBox lorsqu'elle est exécutée. Pour la fonction, nous allons choisir une fonction qui est certainement executée.. //******************** Program Entry Point ******** :00401204 6824134000 push 00401324 * Reference To: MSVBVM60.ThunRTMain, Ord:0064h | :00401209 E8EEFFFFFF Call 004011FC ThunRTMain est une fonction qui est exécutée toujours comme 2ème instruction d'un programme VB. Maintenant, nous devons détourner cette fonction vers une fonction qui fera : PUSH Real_EP; JMP HooKFcT. Nous devons rechercher les info sur cette Fonction.. Pour cela, désassemblez MSVBVM60.DLL avec W32Dasm et nous voyons ceci : Exported fn(): ThunRTMain - Ord:0064h :6602410E 55 push ebp Ord Real = 64h, or la Base = 64h donc le Ord = 0h ! Nous savons donc que l'EP de la fonction se trouve en .(660930E8 + 4*0) = .660930E8 Nous pouvons deja commencer notre fonction Rappelons d'abord ce quelle est censé faire. 1) Récupérer l'EIP appelant 2) Afficher une MassageBox donnant l'EIP appelant. 3) redonner la main à la fonction original. .66158000: 50 push eax Sauveguarde les registres utilisés .66158001: 53 push ebx .66158002: 51 push ecx .66158003: 52 push edx .66158004: 8B442404 mov eax,[esp][00014] Récupère l'EIP appelant .00158008: BB00811566 mov ebx,066158100 Variable en [066158100] contenant le text .0015800D: 90 nop de la messagebox qui sera l'EIP appelant. .0015800E: 90 nop .0015800F: B908000000 mov ecx,000000008 ECX = 8 ( 8 characters ) .66158014: C1C004 rol eax,004 rot de 4 bits sur la gauche .66158017: 8BD0 mov edx,eax edx = eax .66158019: 83E20F and edx,00F on isole les 4 bits de poid faible .6615801C: 83FA0A cmp edx,00A edx > 10 ? .6615801F: 7D05 jge .066158026 .66158021: 80C230 add dl,030 Si non, on affiche un chiffre 0x30 = "0" .66158024: EB03 jmps .066158029 .66158026: 80C237 add dl,037 Si oui, on affiche une lettre 0x37 = "A"-10 .66158029: 8813 mov [ebx],dl Place le char dans la chaine ( sur la pile ) .6615802B: 43 inc ebx ebx = ebx+1 .6615802C: E2E6 loop .066158014 et on loop pour chaque char. .6615802E: C60300 mov b,[ebx],000 NULL terminated string .66158031: 83EB08 sub ebx,008 EBX = début du Text MessageBoxA est dans l'IAT : * Reference To: USER32.MessageBoxA, Ord:0195h | :660B162D FF159C130066 Call dword ptr [6600139C] .66158034: 6A00 push 000 uType .66158036: 6809811566 push 066158109 Offset Titre .6615803B: 53 push ebx Offset Text .6615803C: 6A00 push 000 Handle .66158041: FF159C130066 call MessageBoxA Affiche la MsgBox .66158047: 5A pop edx Récupère les registres .66158048: 59 pop ecx .66158049: 5B pop ebx .6615804A: 58 pop eax .66158048: 83C404 add esp,004 Restore la pile .6615804E: FF6424FC jmp d,[esp][-0004] Redonne la main à la fonction Notre code se trouve en .66158000 et se termine en .66158052 donc nous devons modifier la valeur en .660930E8 par 00158052 Sans oublier la valeur d'origine : 0002410E. On rajoute ensuite ici : .66158052: 680E410266 push 06602410E .66158057: EBA7 jmps .066158000 Pour un peu plus d'estétique, vous pouvez mettre un titre à la messagebox. Pour cela, placé par exemple votre titre juste apres l'espace ou l'EIP va s'écrire, soit en [.66158100+9] : .66158100: 00 00 00 00-00 00 00 00-00 45 49 50-20 64 65 20 EIP de .66158110: 6C 27 69 6E-73 74 72 75-63 74 69 6F-6E 20 61 70 l'instruction ap .66158120: 70 65 6C 61-6E 74 65 00-00 00 00 00-00 00 00 00 pelante Et modifier l'instruction en .66158036 push 00000000 par un push 066158109. Ce cours s'arrête là bien malgré moi, je ne retrouve pas le courage à le continuer, mais si qqn veux continuer ce projet, je veux bien lui donner mais idées et mes conseils ! Amicalement, TeeJi