Genius 2.7


Introduction and Infection

This little package, about 1Mo, is interesting to study for many raisons:

It is protected by ASPack 1.08.03
It has a Registration Box for a serial coded with a magic table, a checksum, a Time Limit, and MessageBoxA or DialogBoxParamA, couldn't give any break in SoftIce, and to finish, when you click on the icon in the task bar of Windows, you get an UNREGISTERED...

More, but it's perhaps a particularity due to ASPack, there are just some String Data references, and not these one which can help us.
In this essay, I've tried to be recognized as a Registered User, by patching Genius 2.7.


Tools
SoftIce 4.0
W32dasm 6.9
PE Snuffer 1.06
Porch Dump 1.5
R!SC's Process Patcher 1.2

Methodology


Decompression of the executable
Live Approach

How To
How can we identify a packed program?
Without having a big experience, there are some signs like:

  • SoftIce don't give the hand when using the Symbol Loader
  • W32dasm could not disassemble the program
  • The entry point is different of the usual 401000

Let take the problem in order.


The AsPack Protection

Knowing is adversary:

Here is a little panel of questions / answers given by the authors of ASPack:

Q. How can ASPack reduce my application from 1.7Mb to 460Kb?

A. ASPack uses a very powerful compression algorithm combined with a very small decompression procedure (less than 1Kb) in the executable image. More details are available on request.
---
Q. How does it work?

A. After compression of the executable image, ASPack writes a small decompressor and places icons at the end of the compressed file. The address of the application's entry point is set to the beginning of the decompressor, and the original entry point is saved. After the decompressor decompress the image in memory, it jumps to the application's original entry point.

Q. Can I decompress an ASPack'ed file?

A. No. One of the reasons for using ASPack is to protect applications against patches and decompilation, and the decompressor - by design -creates obstacles for hackers.
---
Q. When I remove ASPack.exe from my computer what would happen with compressed files?

A. Nothing. Each compressed file has a small decompressor built-in.ASPack itself is not required to run ASPack'ed files.

Shareware authors' questions regarding protection
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Q. Can ASPack protect my program against hackers?

A. ASPack is only a packer, not a full "protector". But ASPack is a good defense against non-professional hackers.
---
Q. How I can better protect my application using ASPack?

A. Use these tricks:

- use multiple layer compression (3-5 passes). On the first pass, turn off the "Resource compression" option and turn it back on only for the last pass. Use should use different section names for each pass
(see the ASPack Option tab), e.g., .text, .code, .idata, .edata, etc.

- use a non-standard Image Base for your .EXEs (see the compiler Linker options). The default is 400000h, but you can change this to, e.g., 300000h.
---
Q. I use your ASPack program, but am still plagued by illegal registration numbers. Why can't ASPack protect my application against this?

A. Because you are using a weak serial number scheme, which falls prey tokey-generators by ackers. Further help is available on request.
---
Here is to quiet the Shareware authors...

How to break this protection:

There is a marvelous little tool, ProcDump. You can found the last version on its official site: http://procdump32.cjb.net/

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 …).
Unknown doesn’t give often satisfied results, and it's quit better to know the packer used before launching ProcDump.

For that, you have an other excellent tool PE SNUFFER by SkyMarshall that you can found on http://start.at/skymarshall. Its job is to found what packer has been used.

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!

+++++++++++++++++++ MENU INFORMATION ++++++++++++++++++
There Are No Menu Resources in This Application

+++++++++++++++++ DIALOG INFORMATION ++++++++++++++++++
Number of Dialogs = 1 (decimal)
Name: DLGTEMPLATE, # of Controls=001, Caption:""
001 - ControlID:045F, Control Class:"" Control Text:""

+++++++++++++++++++ IMPORTED FUNCTIONS ++++++++++++++++++
Number of Imported Modules = 0 (decimal)

+++++++++++++++++++ IMPORT MODULE DETAILS +++++++++++++++

+++++++++++++++++++ EXPORTED FUNCTIONS ++++++++++++++++++
Number of Exported Functions = 0000 (decimal)

+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++
//********************** Start of Code in Object CODE **************
Program Entry Point = 00559CC8 (genius2.exe File Offset:001592C8)


No Dialog Box, no imported or exported functions and an Entry Point at 00559CC8 instead of the usual 401000.

With the help of this dump, you must found the answer, by no choice, using essentially SoftIce

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!
About 131,8%, a joke!
Bpx MessageBoxA to localize it: Nothing. DialogBoxParamA : Same. Task/Hwnd/Bmsg : Break

And a attack by the Entry Point?…
A checksum was rarely at the exit of a program, and we must found it quickly by using F10 in SoftIce.

Once the routine which put the NagScreen localized, you will climb to found the conditional jump who can bypassed it:

: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.
Put a breakpoint on it, at the next time (after being out of SoftIce and launch one more time Genius 2), a simple inversion of Flag (R FL Z) will be enough against the Checksum, which was not very nasty.

At these state, the more simple is to start your hex editor, to load the executable, and to replace the JNE 00559DC7 by a JMP 00559DC7, to be quiet.

ASPack was Out, It is possible, now, to go on:

We have:

  • A Register Box with 2 fields. One for the name and the other is a 3 lines field where you could enter 72 characters on each lines. Oup ! And no break on Bpx GetWindowtexA or GetDlgItemTextA. A BPX Hmemcpy gives the hand.
  • A screen " Your 30 day trial period has ended. Please register… " Which popup if you move your system date, but the Soft will be back normally, is you move backward your clock. No break on MessageBoxA, or on DialogBoxParamA... A Task/Hwnd/Bmsg gives the hand.
  • UNREGISTERED when the cursor of the mouse goes on the icon near the clock on the task bar
  • An item REGISTERS in the main menu.

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&#9;&#9;-> 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&#9;&#9;
: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?

  • 3 mov in eax (our name), ecx (the good serial ?), edx (our serial entered)
  • A call 005515F0, which is probably the one inside the serial, is checked.
  • A test al, al. Man must be seeing in the previous call how AL is manipulating.
  • The Jump for invalid code. By inverting it, you have strong probability to got a message like " Thank you for registering… "
  • A mov [esi+490],01 which was perhaps the flag " Registered user "

But go back to the mov ecx, 005578F4.
If you have been careful, the 2 others registers (eax and edx), push the content of a floating memory address, but not ecx. This one pushes the content of a fixe memory. Is it possible that the serial couldn't be generated by the name entered?

Here is what I got for a " d ecx " in the Data’s Window:
I1QTbC91L85AToWAExP2jSXmLliC8e+NqermA9EI7B++
A 44 characters "code" long... is it the good one? is it the form of the good one?
To know that, wait for the verdict of the registration box...
No chance: " bad name… ".

Back in SoftIce, let's visit the call 005515F0
You will find several times your name and your serial, and plenty of strings like these I've found already in ECX. It's seems that the good serial is generated since a " magic table " greater than 500 characters (You can see it in 00551228). To have read a tutorial of +ORC on the subject, I been too lazy to continue in this way!

The "how to find the good serial" isn’t for me, I've try to find how can the Soft validated a good serial, and the manipulations on AL. Like in most common scheme, it's a little before the RET, that I've find what I am searching:

: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
Now, we have to search manipulations on EBX.
From the beginning of the call 005515F0, and with a F10 tracing, you will land here:

: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

Glop, Glop !

Close Genius, and started it a new time. You are back in the Shareware version, and no break on our previous breakpoint. They are an other control of your Registered state, in other place.
And this control would be behind a call 0049059C…

Put a Bpx on it, and launch again the application.

POP!
When tracing with 10, you will exit from the call 0049059C in these lines:

: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:
Make the same modification as the next time, and your are now a registered User.
But, go back an instant to the mov byte ptr [esi+00000490], 01 we have seen in 00557823.

It's the Flag " Registered User. A research with a text editor will give you 12 occurrences on 00000490 (several [esi+490], and [ebx+490]).
The most interesting one, is a :00553EF8 888390040000 mov [ebx+00000490], al
Other occurrences are only comparisons.

By making a inc byte ptr [ebx+00000490] you will obtain a similar result as our modification in 005515BA, (the flag goes 0 to 1), just one byte to modify.

If you control the result of this change, you will see that the shareware indicators are out: no more Unregistered, Register Box access, Time limit, and the About Screen tell us than we are Unregistered User. We juste have, now, to finalize our change.
Nothing easier with a hex editor. Search for 8A5E2A, you will just find 2, one for the serial validation (via the Reg. Box), the other for the Registered state, and replace these strings by B30190.

Is that all?
It can be., but at each new installation of Genius, we must have to do the same operation, or save a file 2 302 ko big

R!SC’s Process Patcher v1.2 : http://mercury.spaceports.com/~quel/protools/patchers.htm

Is a powerful tool? Here is it's description:

Its a process patcher thingy, creates a win32.exe from simple script, which will then load a process, and wait for it to unpack/deprotect itself, then patch the memory to fix any bugs that the author left in the program. (Like nag screens, time limits, this kind of mistake…)

So, R!SC is a memory patcher which use a script to create a executable Loader file (8 ko big), and we can use it to launch Genius, without any physical modification of him (and with no checksum matter)

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!

There was other possibility. It could be possible to patch directly the genius.exe, in his original version.
The real entry point is in 00559CC8 as you can have seen it in the Wdasm Listing, at the beginning of this essay. The EP for the version AsPacked is in 00681000 :

********************** Start of Code in Object **************
Program Entry Point = 00681000 (Genius2.exe File Offset:00281000)

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.
So, you just have to read in the windows:

  • Entry Point: 281000
  • Image base:400000

When making a addition between 400000 + 281000, you have the Entry point of the compressed version
Wdasm is not in rest, and give some information’s like ProcDump :

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.
With Hiew, a good hex editor, search for the entry point, and replace the value at the offset 681000 (which should be a 60) by a CC, opcode for INT 3.
Now put a BPINT 3 in SoftIce, and fire Genius 2.

POP !

Replace immediately the CC by his original value (PUSHAD) whenever Genius will send a GPF:

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)

Now, we must find some place for our little petit patch. When searching a little more, you will find free spaces not far from the call EAX...
So, I've modified the JNZ 00681563, in JMP 00681FEB + 2 NOP to equilibrate on the mov EAX, 01.

And I've entered this:

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!
But if you search the strings to be modified with a hex editor, you will have a bad surprise. NOTHING!.
A the place of what you have seen in memory, instead of the POPAD, you find this:

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)?
It's because the Loader itself is compressed! ! !

When you started up the application, they are first a discompression of the loader ASPack, which discompresse after the original execute.
You just have to found where and when the Loader make this work, finding a place before this operation to patch the loader, and after minding for Genius…

To know where and when the Loader is discompressed, begin by a bpm 00681559 on the JNZ 00681563.

When the decompressor will write a byte at this address, you will break immediately.

POP !

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 !
Now we have confirmed that there is really a compression of the Loader, search the address where this decompression begins.
The Repz Movsb at 006810AE is in a " clean " place, but the next line?
By putting a Bpm 006810B2, leaving SoftIce, shouting Genius, and started the program a new time, we will know what append.

POP !

OK! So, after 006810B2, the next line are compressed, like your hex editor could confirm you...

Take problems in order:

  • We must have to create 2 patches: one for the loader, a second for Genius, and to find enough place for these patchs.
  • We will have to redirect the loader in this place, just before the beginning of the discompression

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.
OK! This time, I will take place on the icon of the application.
Now, I must have to redirect the Loader by replacing :

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.

The 2 Patchs :

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 "
In memory, No problem: Nice!
With a hex editor, use Find/Replace, this time all strings are found, Save, and launch Genius in his new version, and…
Bingo! ! !

General Consideration about ASPack:

The story is not finish.
One of my friends, Psyché (Hi Master) said to me: "patching on the icon is not very "clean"...
So, he has give me a other solution:

First, a compressor must be general to be applicate on any Soft. No specific thing for one or an other, and by extension, the loader is the same for all programs compressed by ASPack.
The goal, here, is to create a modified Loader, useful for all ASPacked Programs, and in which we will have the place to insert the patch we need, function of the target.

We must know, first, that the ASPack Loader use a full section named .adata, the code of thise one begin at the offset 0 from the address of the beginning of this section.
We find a piece of clean codes (from the offset 0 to the offset @BA) which is use to discompress the rest of the Loader

: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.
After, ESI will point to the section where the discompressed code is, and EDI will point on offset @BD. All that for transferring 49A ( = 1178) bytes of ESI to EDI.
Here is the end of the Loader restoration.

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.
After, ESI will point to the section where the discompressed code is, and EDI will point on offset @BD. All that for transferring 49A ( = 1178) bytes of ESI to EDI.
Here is the end of the Loader restoration.

The idea is to use these 1178 bytes and replace the compressed section by the one discompressed in the .adata section.
By making that, all the necessary code for this discompression will be unusual and we could use this space (from offset @96- in fact @90 will go as well to offset @CA) for our guilty affairs.
If necessary, it is possible to use more byte from offset @76 because the code after is use to prevent eventual errors.
If we search a little more, we can see that the beginning of the Loader use 4 bytes of this section to give Data's (it seems to me that it is the Image Base which is stored inside).
At Offset @21, EBX is stored, and pushed in EAX at Offset @6A.
We will have to take care about this little detail, and be careful to restore the values which are stored in this place after discompression (that I've make at offset @96)

: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
:00000559 E944FBFFFF
jmp 000000A2 <- jump to our free space
:0000055E 0000 add byte ptr [eax], al
:00000560 C20C00 ret 000C
:00000563 50 push eax
:00000564 C3 ret
- - - - - - - -
:00000090 8D9DCF4A4400 lea ebx, dword ptr [ebp+00444ACF]
:00000096 C785BB4E440085DB7471 mov dword ptr [ebp+00444EBB], 7174DB85
:000000A0 EB29 jmp 000000CB
:000000A2 50 push eax
<- here
:000000A3 C3 ret
:000000A4 00000000000000000000 BYTE 10 DUP(0)
:000000AE 00000000000000000000 BYTE 10 DUP(0)
:000000B8 00000000000000000000 BYTE 10 DUP(0)
:000000C2 000000000000000000 BYTE 9 DUP(0)

:000000CB 8D85374C4400 lea eax, dword ptr [ebp+00444C37]
:000000D1 50 push eax
:000000D2 C3 ret

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:

  1. Fire the target
  2. Fire ProcDump
  3. Click on right button on the name of the target
  4. Dump (Full)
  5. Save the exe dumped

We must now, know where the .adata begin in this discompressed version

  1. Fire ProcDump
  2. PE EDITOR
  3. SECTIONS
  4. See the raw Offset (offset on the HD) of the .adata section 

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:
@96 -> A1 (will be the offset 0 of aspack.bin while we have saved since @96)
@A2 -> A3 (offset ]0C [@A2-@96] if aspack.bin)
and @559 -> 55D (offset @4C3 [@559-@96] of aspack.bin)

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