Genius 2.7
This little package, about 1Mo, is interesting to study for many raisons:
Let take the problem in order.
Knowing is adversary: When using it, you would have to choose between a "Unknown" Packer or
one of the most common used (Néolite, PC Guard, pETITE, Shrinker, Vbox, Pklite, Wwpack …). After, you just have to click on UNPACK, choosing one of the ASPack 's versions you found (<108, 108, 108.2, 180.3), and eventually trying all of them, waiting to fall on the good one that could launch the program, discompress it in memory, and propose you to create a save copy of the discompressed program... All that done, you will have a 2 302 ko's program instead of the 938 ko of the original package. Not bad for a compression algorithm, isn’t it? With this new executable, the logic want that we jump on our disassembler (no?). No luck, the listing you obtain is not rather different of these you have already got. Same for SoftIce, if you used the Symbol Loader Not Good! Is it possible, like ASPack said to his client, that the PE format of the executable has been a little modified? With ProcDump (nice this tool), click on PE EDITOR, load Genius 2, and choose SECTIONS. Right click on the " Code " section, and by choosing " Edit Section ", you will see the characteristics of this section: C0000040. If you have the curiosity to compare with other Softs, you will see that this value is not really usual. In most of the case you found 60000020 and sometimes E0000020 for "normal" programs! Change le C0000040 by E0000020 (for a file Readable Writable and Executable), and Wdasm or SoftIce will function normally… The String Data References you got now are not very interesting, but you have got it!
The Checksum : When launching your discompresse copy, the program will immediately detect that
you have more bytes as the original version. The "punish" is a dialog box " The file has been modified
". We know! :00559DA4 E80F37F0FF call 0045D4B8 :00559DA9 8BD8 mov ebx, eax :00559DAB 8BC6 mov eax, esi :00559DAD E8DE91EAFF call 00402F90 :00559DB2 84DB test bl , bl :00559DB4 7511 jne 00559DC7 Here it is! It's the first you will see, and which bypassed the procedure of the
NagScreen. ASPack was Out, It is possible, now, to go on: We have:
The register box:
It's often the best way to find how to crack a shareware. I usually go on the idea that the control routines of the serial are not far from the place where the program got the serial entered, and just a little before the nag screen like " bad name/key combination ". Bpx hemecpy. After 7 keypresses on F12, you will land in the codes of Genius at 0042D8F1, and have 2 breaks (one for the name, one for the serial entered) Trace Over with F10, searching the call for the box " Bad name… " :00557880 EB25 jmp 005578A7 :00557882 A114305600 mov eax, [00563014] :00557887 8B00 mov eax, [eax] :00557889 8B4024 mov eax, [eax+24] :0055788C 50 push eax :0055788D E83A01EBFF call 004079CC :00557892 6A00 push 00000000 :00557894 668B0D24795500 mov cx, [00557924] :0055789B B201 mov dl, 01 :0055789D B8A4795500 mov eax, 005579A4 :005578A2 E80543F0FF call 0045BBAC		-> nag screen The jump at 0055788A let suppose that the routine " invalid code " was placed just upper. Climbing up in the codes of Genius, to see if there hasn't a jump for 00557882 :0055780F 8B45F8 mov eax, [ebp-08] :00557812 B9F4785500 mov ecx, 005578F4 :00557817 8B55FC mov edx, [ebp-04] :0055781A E8D19DFFFF call 005515F0		 :0055781F 84C0 test al , al :00557821 745F je 00557882 :00557823 C6869004000001 mov byte ptr [esi+00000490], 01 Here it is, not very far from are nasty call. Well, we have?
But go back to the mov ecx, 005578F4. Here is what I got for a " d ecx " in the Data’s Window: :005516F2 8BC3 mov eax, ebx -> ebx in eax :005516F4 5F pop edi :005516F5 5E pop esi :005516F6 5B pop ebx :005516F7 8BE5 mov esp, ebp :005516F9 5D pop ebp :005516FA C3 ret Ebx equal 0, and the mov eax, ebx will send 0 in AL :005516C1 E8D6EEF3FF call 0049059C :005516C6 8A5E2A mov bl , [esi+2A] -> ebx get is value :005516C9 8BC6 mov eax, esi :005516CB E8C018EBFF call 00402F90 Man will continue to search what append with [esi+2A], but a first modification at this stair will authorize us to make our serial accepted. :005516C1 E8D6EEF3FF call 0049059C :005516C6 B301 mov bl , 01 :005516C8 90 nop :005516C9 8BC6 mov eax, esi :005516CB E8C018EBFF call 00402F90 When launching Genius by F5, you will see a box " Thank you for registering…
", No item REGISTER in the menu, and the About Box tell you that you are a Registered User :005515B5 E8E2EFF3FF call 0049059C :005515BA 8A5E2A mov bl , [esi+2A] :005515BD 8BC6 mov eax, esi :005515BF E8CC19EBFF call 00402F90 We have already seen things like that:
R!SC’s Process Patcher v1.2 : http://mercury.spaceports.com/~quel/protools/patchers.htm Is a powerful tool? Here is it's description: here is the possible script: T=2000: ; time allocated to find byte to be modified F=genius2.exe: ; name of the executable O=loader_genius.exe: ; name of the Loader you will create P=5515BA/8A,5E,2A/B3,01,90: ; modifications at 005515BA $ ; end of script With the help of these script, R!SC will generated a Loader which, once launched,
will start up the application / target, as you will have modified it physically, like the one discompressed by
ProcDump. Efficacité garantie!
A other method to know this entry point is to use, one more time, ProcDump, to click
on PE EDITOR, and to load the program in his compressed version.
When making a addition between 400000 + 281000, you have the Entry point of the
compressed version Object08: .rsrc RVA: 001C4000 Offset: 00092A00 Size: 0002EC00 Flags: Object09: .adata RVA: 00281000 Offset: 000C1600 Size: 00001C00 Flags: Object10: .udata RVA: 00283000 Offset: 000C3200 Size: 00000000 Flags: The Interrupt 3 : SoftIce couldn’t give the hand when started up Genius 2; I will use the INT 3 technique
to force SoftIce making a break. 0177:00681000 60 PUSHAD -> entry point 0177:00681001 E800000000 CALL 00681006 0177:00681006 5D POP EBP Now, you must trace with F10 to find the end of the discompression, and you will land here: 0177:00681554 8944241C MOV [ESP+1C], EAX 0177:00681558 61 POPAD 0177:00681559 7508 JNZ 00681563 0177:0068155B B801000000 MOV EAX,00000001 0177:00681560 C20C00 RET 000C 0177:00681563 50 PUSH EAX 0177:00681565 55 RET Interesting, indeed. Just before the RET, the Soft push the value of EAX on the
stack, and this value is no more then 00559CC8, the entry point of the discompressed version. This operation let
the Soft going at the right address (in other case, you should have also some JMP EAX) 66C705BA155500B301 MOV WORD PTR [005515BA],01B3 > Registered user C605BC15550090 MOV BYTE PTR [005515BC],90 > nop 66C705BA9D5500EB11 MOV WORD PTR [00559DBA],11EB > Bye Bye checksum 50 PUSH EAX > Push the entry point C3 RET > and GO! In Memory, all is Good! 0177:00681554 1A6F68 SBB CH,[EDI+68] 0177:00681557 27 DAA 0177:00681558 F0E98D0A0000 LOCK JMP 00681FEB 0177:0068155E 90 NOP 0177:0068155F 90 NOP So, why this difference between the active version (in memory), and this one (the
passive)? When the decompressor will write a byte at this address, you will break immediately.
0177:0068109F 8DBDCF4A4400 LEA EDI,[EBP+00444ACF] 0177:006810A5 8BB5B5504400 MOV ESI,[EBP+004450B5] 0177:006810AB C1F902 SAR ECX,02 0177:006810AE F3A5 REPZ MOVSB > classical 0177:006810B0 8BC8 MOV ECX,EAX Take a look in the registers Window: EDI = 00681559. OK !
Wee need free spaces for 55 bytes, and there must be placed somewhere which will
not be replace by codes when the discompression was done. 0177:006810A5 8BB5B5504400 MOV ESI,[EBP+004450B5] 0177:006810AB C1F902 SAR ECX,02 0177:006810AE F3A5 REPZ MOVSB 0177:006810B0 8BC8 MOV ECX,EAX 0177:006810B2 83E103 AND ECX,03 By 0177:0068109F 8DBDCF4A4400 LEA EDI,[EBP+00444ACF] 0177:006810A5 8BB5B5504400 MOV ESI,[EBP+004450B5] 0177:006810AB E9C00E0000 JMP 00681F70 > ici 0177:006810B0 8BC8 MOV ECX,EAX 0177:006810B2 83E103 AND ECX,03 0177:006810B5 F3A4 REPZ MOVSB Just before the first discompressed byte. 1er patch 0177:00681F6F 90 NOP > 0177:00681F70 C1F902 SAR ECX,02 > restore bytes 0177:00681F73 F3A5 REPZ MOVSD > erase by the JMP 00681F70 0177:00681F75 C70559156800E9300A00MOV DWORD PTR [00681559],000A30E9 > modification of the jmp 00681F8E which will redirect to the second Patch 0177:00681F7F C7055D156800009090C2MOV DWORD PTR [0068155D],C2909000 > 0177:00681F89 E922F1FFFF JMP 006810B0 > end of 1er Patch 0177:00681F8E C705BA155500B301908BMOV DWORD PTR [005515BA],8B9001B3 > 2ème Patch : modification of the Flag registered user 0177:00681F98 66C705B49D5500EB11 MOV WORD PTR [00559DB4],11EB > modification of the Checksum 0177:00681FA1 50 PUSH EAX > push the address of the entry point on the stack 0177:00681FA2 C3 RET > launch Genius 0177:00681FA3 0000 ADD [EAX],AL > "free" spaces If all goes like we hope, the first Jump will send to our Patch n°1, which will
discompress the codes of the Loader, discompress after the codes of Genius, and before leaving the Loader and started
up the application, the program will make a little travel in Patch n°2, modifying the User Flag, and bye bye
the nag screen " The file has been modified " General Consideration about ASPack: The story is not finish. :00000000 60 pushad :00000001 E800000000 call 00000006 :00000006 5D pop ebp :00000007 81ED0A4A4400 sub ebp, 00444A0A :0000000D BB044A4400 mov ebx, 00444A04 :00000012 03DD add ebx, ebp :00000014 2B9DB1504400 sub ebx, dword ptr [ebp+004450B1] :0000001A 83BDAC50440000 cmp dword ptr [ebp+004450AC], 00000000 :00000021 899DBB4E4400 mov dword ptr [ebp+00444EBB], ebx :00000027 0F8517050000 jne 00000544 :0000002D 8D85D1504400 lea eax, dword ptr [ebp+004450D1] :00000033 50 push eax :00000034 FF9594514400 call dword ptr [ebp+00445194] :0000003A 8985CD504400 mov dword ptr [ebp+004450CD], eax :00000040 8BF8 mov edi, eax :00000042 8D9DDE504400 lea ebx, dword ptr [ebp+004450DE] :00000048 53 push ebx :00000049 50 push eax :0000004A FF9590514400 call dword ptr [ebp+00445190] :00000050 8985B9504400 mov dword ptr [ebp+004450B9], eax :00000056 8D9DEB504400 lea ebx, dword ptr [ebp+004450EB] :0000005C 53 push ebx :0000005D 57 push edi :0000005E FF9590514400 call dword ptr [ebp+00445190] :00000064 8985BD504400 mov dword ptr [ebp+004450BD], eax :0000006A 8B85BB4E4400 mov eax, dword ptr [ebp+00444EBB] :00000070 8985AC504400 mov dword ptr [ebp+004450AC], eax :00000076 6A04 push 00000004 :00000078 6800100000 push 00001000 :0000007D 689A040000 push 0000049A :00000082 6A00 push 00000000 :00000084 FF95B9504400 call dword ptr [ebp+004450B9] :0000008A 8985B5504400 mov dword ptr [ebp+004450B5], eax :00000090 8D9DCF4A4400 lea ebx, dword ptr [ebp+00444ACF] :00000096 50 push eax :00000097 53 push ebx :00000098 E8C8040000 call 00000565 <- discompression of the loader :0000009D 8BC8 mov ecx, eax <- ecx = 49A :0000009F 8DBDCF4A4400 lea edi, dword ptr [ebp+00444ACF] :000000A5 8BB5B5504400 mov esi, dword ptr [ebp+004450B5] :000000AB C1F902 sar ecx, 02 :000000AE F3 repz :000000AF A5 movsd :000000B0 8BC8 mov ecx, eax :000000B2 83E103 and ecx, 00000003 :000000B5 F3 repz :000000B6 A4 movsb :000000B7 8B85B5504400 mov eax, dword ptr [ebp+004450B5] :000000BD 6800800000 push 00008000 <- beginning of the compressed section :000000C2 6A00 push 00000000 :000000C4 50 push eax :000000C5 FF95BD504400 call dword ptr [ebp+004450BD] :000000CB 8D0E lea ecx, dword ptr [esi] :000000CD 8537 test dword ptr [edi], esi :000000CF 4C dec esp :000000D0 44 inc esp :000000D1 07 pop es :000000D2 50 push eax :000000D3 C3 ret The call at offset @98 will discompress all the code that begins at offset @BD in
the memory allocated for that, in the call at offset @5E. The call at offset @98 will discompress all the code that begins at offset @BD in
the memory allocated for that, in the call at offset @5E. :00000000 60 pushad :00000001 E800000000 call 00000006 :00000006 5D pop ebp :00000007 81ED0A4A4400 sub ebp, 00444A0A :0000000D BB044A4400 mov ebx, 00444A04 :00000012 03DD add ebx, ebp :00000014 2B9DB1504400 sub ebx, dword ptr [ebp+004450B1] :0000001A 83BDAC50440000 cmp dword ptr [ebp+004450AC], 00000000 :00000021 899DBB4E4400 mov dword ptr [ebp+00444EBB], ebx :00000027 0F8517050000 jne 00000544 :0000002D 8D85D1504400 lea eax, dword ptr [ebp+004450D1] :00000033 50 push eax :00000034 FF9594514400 call dword ptr [ebp+00445194] :0000003A 8985CD504400 mov dword ptr [ebp+004450CD], eax :00000040 8BF8 mov edi, eax :00000042 8D9DDE504400 lea ebx, dword ptr [ebp+004450DE] :00000048 53 push ebx :00000049 50 push eax :0000004A FF9590514400 call dword ptr [ebp+00445190] :00000050 8985B9504400 mov dword ptr [ebp+004450B9], eax :00000056 8D9DEB504400 lea ebx, dword ptr [ebp+004450EB] :0000005C 53 push ebx :0000005D 57 push edi :0000005E FF9590514400 call dword ptr [ebp+00445190] :00000064 8985BD504400 mov dword ptr [ebp+004450BD], eax :0000006A 8B85BB4E4400 mov eax, dword ptr [ebp+00444EBB] :00000070 8985AC504400 mov dword ptr [ebp+004450AC], eax :00000076 6A04 push 00000004 :00000078 6800100000 push 00001000 :0000007D 689A040000 push 0000049A :00000082 6A00 push 00000000 :00000084 FF95B9504400 call dword ptr [ebp+004450B9] :0000008A 8985B5504400 mov dword ptr [ebp+004450B5], eax :00000090 8D9DCF4A4400 lea ebx, dword ptr [ebp+00444ACF] :00000096 C785BB4E440085DB7471 mov dword ptr [ebp+00444EBB], 7174DB85 <- restore the dword :000000A0 EB29 jmp 000000CB <- we jump the code which discompress the loader :000000A2 4A dec edx :000000A3 44 inc esp :000000A4 008BB5B55044 add byte ptr [ebx+4450B5B5], cl :000000AA 00C1 add cl, al :000000AC F9 stc :000000AD 02F3 add dh, bl :000000AF A5 movsd :000000B0 8BC8 mov ecx, eax :000000B2 83E103 and ecx, 00000003 :000000B5 F3 repz :000000B6 A4 movsb :000000B7 8B85B5504400 mov eax, dword ptr [ebp+004450B5] :000000BD 6800800000 push 00008000 :000000C2 6A00 push 00000000 :000000C4 50 push eax :000000C5 FF95BD504400 call dword ptr [ebp+004450BD] :000000CB 8D85374C4400 lea eax, dword ptr [ebp+00444C37] -> we arrive here :000000D1 50 push eax :000000D2 C3 ret Well, 41 bytes free to play with. We must have now to found the end of the loader that means the place where the main program takes the hand. So, here: :00000558 61 popad :00000559 7508 jne 00000563 :0000055B B801000000 mov eax, 00000001 :00000560 C20C00 ret 000C :00000563 50 push eax :00000564 C3 ret EAX stored the Entry Point of the main program. The Loader push EAX on the stack, and the RET after, will take this address to land in the Soft. Now, we have to redirect the Loader to our eventual patch, before starting up the target. :00000558 61 popad I've just put the PUSH EAX and the RET while it's here some general consideration (don’t ' forget to write it) but when you want to patch a program you can write your Patch in this section. By the way, we have 39 bytes to dispose, that is, in most of the case, enough. Now, have a look on the process. We have first to examine a .adata section discompressed. ProcDump can give us that quickly:
We must now, know where the .adata begin in this discompressed version
What do you need? The part who is going from offset @96 to @557 (@CB +49A [= number of discompressed bytes]) from the beginning of .adata (= raw offset of .adata). With any hex editor, it's possible to extract the piece we are interesting about, and make a file "aspack.bin" (for example) by simply Cut/Paste. We have now 4C1 (557-96) bytes in our "aspack.bin" file. For the moment, we have just a simple copy of a piece of .adata. We have to make
the modifications seen upper at offsets: We save all, and we have now a "standard" version, that mean that we just have to replace by a Cut/Paste the code of .adata since @96 (be careful: raw offset +@96) by our aspack.bin The execution won't do any problem... You can, by now, use aspack.bin to insert your patch with replace the good bytes at offset @C (@A2-]96) in aspack.bin without forgot to replace the PUSH EAX and the RET at the end of the patch OF COURSE! Good reflection and Bye |
Christal