Contact Me : dheeraj_np@usa.net or vbox_gl@usa.net
http://mxb.cjb.net

Main | Index

Vbox 4.2 A generic crack explained
No more hairs on WeiJunLi's head !

01/11/99 by +Tsehp


Courtesy of Fravia's page of reverse engineering

There is a crack, a crack in everything That's how the light gets in
Rating ( )Beginner ( )Intermediate (x)Advanced ( )Expert

You first have to read all the essays about vbox to understand this one. Those are written by marigold who first discovered the way to beat the first versions and the ancient timelock.
--------------------------------------------------------------------------------


Vbox 4.2 A generic crack explained
No more hairs on WeiJunLi's head !

Written by +Tsehp - tsehp@yahoo.com

Introduction


I will not explain what vbox is all about, it is actually used by symantec and others. This ready made
commercial protector was easy to beat in the past and this time, the author WeiJunli seems to have learned
a lot !
What is new :
1-Global check of vboxt420.dll injected in the executable, so you can't write a global crack by distributing
this cracked dll, you have to manually patch the protected executable at first.
2-Multiple auto decrypts of the code in several places in memory, run time memory patches are FINISHED !
3-A license file and all the dlls are located in systemroot\vbox\...This license file allows prolongations
of trial or number of executions. Buy options included.
4-You still can't dump your executable from memory to restore his virginity, it use crypted parameters at
run time.



Tools required
Windows nt 2000 (should work on win98)
Softice 4.0
Hexeditor
Frogsice (anti softice checks)


*A more devious brain than WeiJunLi. That helps.



Target's URL/FTP
www.previewsystems.com just to download the vbox builder



Essay

I used vbox builder to protect procdump, the purpose was to write a method that could work on any prog
protected by vbox, remember that I'm on Win NT so the mem locations of the listings could be slight
different.
First Part : Allowing the patches
If you want to make this work, you'll have to patch vboxt420.dll. I first tried a local Api spoofing and it was not working. The purpose is simplistic
you have to patch this file when it is loaded,the precedent version was possible to by using api spoofing at
level, I mean modifying the file import table values to redirect the api call to your routine, but this time
it's not possible,'cause the entire file integrity is checked by your vboxed executable and not in vboxt420 at
first. But what does the executable need ? Api's ! So we'll patch the windoze apis themselves to redirect the flow
to the patching routines. Where to put those routines ? In your vboxed executable at the beginning of your file
in the rsc places where thay are not used. I will not explain this in detail it's done in other essays about api
spoofing.
Well weiJunLi, you can check whatever you want, but you just can't check the operating system, so we'll
have to patch windows in memory, just at the time the prog does this call.
To understand this technique that I will not explain, read iceman's essays.
An explanation of what I've done :
I deviate the first instruction to 43d7a0, patching one of the few not crypted imports (getprocaddress)
that was at procdump's memory location 428298, so at the first call to getprocdump, it goes to this address.
I want to intercept the call to getprocaddress, I remove the memory write protect by a call to virtualprotect.
I patch window's getprocaddress so it goes back to my procdumps writings and when we don't need it anymore
we put the good values back to the api, it could be used by other programs ;-)
AND IT WORKS !!! Just think of all the possibilities of this wonderfull method discovered by iceman.

The protected progs will NEVER be able to detecte a sudden patch to windows.


Second Part : Anti-Softice routines...
Since vbox 4.1, this prog checks for the memory presence of softice. The essay about vbox 4.1 gave you a way to avoid the check but the check was not explain

but the author. Softice can be triggered by another process, this process have to do the following :

B81109 MOV AX,0911 ; execute command.
8B17 MOV DX,[BX] ; ds:dx point to the command (see below).
BE4746 MOV SI,4647 ; 1st magic value.
BF4D4A MOV DI,4A4D ; 2nd magic value.
CC INT 3 ; Int call.(if SIce is not loaded, jmp to 00AD)

extracted from frogsice doc (courtesy of frog's print)

Whats happening ? if sice is loaded, the int 3 call is not executed by the processor to the IDT corresponding table because softice triggers it.

In vbox scheme, they used the same, the int 3 is a "must do" call for vboxt420 to continue its execution. If Sice is present, the int 3 triggers sice and vbox detects

this.

How could you find the place to patch ? you could search for be4746 for example in vbox7420 but no way, just not present. This could be too easy for sure !

Weijun knew that, he did just the following : just before vbox needs this routine : it allocates some mem by virtualAlloc, decrypts a part of its code and put it

in memory, executes it and then deletes it by a good VirtualFree... well done. Not resident in memory and crypted inside vboxt420.

But he made a terrible mistake : there are other debbugers on the market and he could not trick all of them. So I used Windebug from microsoft to find this int 3 location. Just putting a breakpoint on int 3 and it stopped just in the middle of this stealth tricky routine.

How to defeat this ? just change one of the magic values and softice doesn't trigger anymore for the int 3.



Third Part : A look at the protection
Well you've got all the old protections (see precedent essays), we have more memory integrity tests -> Well have to patch this prog just at the right time, by the use of counters and remove the patches just after (same as 4.10).

So what's new ? I first applied all the old 4.1 tricks and the program crashed with a page memory error. I looked at what was done to create this error and it's due to a
decrypting routine with no end, so the memory access creates the crash. What is decrypted ? Well I saw in memory the first parts well decrypted :

SHELL32.DLL
ShellExecuteA..../...MessageboxA...654654iuouiµ%LMLmù

this routine located around 7011c78 just decrypts the vboxed import table, good at the first time and bad at the second, well you can believe me those guys did their
job very well, they use a random key to decrypt this, it took me a very long time to find how and where and I will not detail how I found this, just try with under 30 days
and above the time limit and use memory tracing techniques with softice.

I traced the key, it's changed several time, crypted and decrypted, since the beginning of the program execution so I lead you directly to the key creation.

The program uses the *.lic file to generate a good and a bad key....But the terrible mistake they made is that they couldn't avoid the good key generation when you're

after the time period. At at point, a subroutine just chooses between the two keys if you're above or under the time limit :

called by 7032e22, at the second time we look at :

703cd4a push esi
703cd4b push edx
703cd4c push ebx
703cd4d push eax
703cd4e call 703fb40

in ebx+9e9 the memory location of the actual key

in ebx+9e9+4 the memory location of the good key

those keys are generated after this call (this routine is called very often in vbox for other purposes, so exchange the keys only after the second call from 7032e22.

If you invert the keys at this time, the program will we decrypt his import tables and work correctly.

ONE VERY STRANGE FEATURE : after the first time you invert the keys, vbox re - generates a lic file and at the other times the good key will be generated every time
even after the time limit ! Well I take that as a reconnaissance for the crackers, just to ease a little their work !

Fourth Part : The patching
On the last essay about vbox , V porguen made a successful patch inside the vbox dlls, in a part that was not checked, now this is kind of impossible 'cause all the
file is checked.

Well at this point , you understand that it would be pretty difficult to do a generic crack inside vboxt420.dll. But the generic method I'll explain should work on
every program protected by it.

The patch will work like a virus, first at the start point of your vboxed exe (procdump.exe in my example), you put a jump to your patching routines, this just will be
replaced after the first patches by the original code (to fool the mem checks) and you will jump back to the starting point. This exe doesn't check itself on disk.

In our case : procdump.exe start point at 4221bc :

//******************** Program Entry Point ********

:004221BC E9DFB50100 jmp 0043D7A0 ***This is replaced on the file, as a jump to our patching routines.What was first is replaced in my prog

First part of my prog, explained line by line. A litteral explanation will follow :

0008:0043D700 6890D74300 PUSH 0043D790 *This location contains 'Kernel32'
0008:0043D705 E86595A577 CALL KERNEL32!GetModuleHandleA *So we have a valid handle for kernel32
0008:0043D70A A380D74300 MOV [0043D780],EAX *save this handle
0008:0043D70F 6870D74300 PUSH 0043D770 *This location contains 'GetProcAddress' watchout it's case sensitive.
0008:0043D714 50 PUSH EAX *as an argument to have the mem adress of GetProcAddress API
0008:0043D715 E80B6AA577 CALL KERNEL32!GetProcAddress *this returns in eax the mem adress of GetProcAddress
0008:0043D71A A384D74300 MOV [KERNEL32!GetProcAddress],EAX *save this adress in 43d784

What I'm doing ? I need several parameters concerning the api function I want to patch, In windows those functions are memory protected, so if you attend
to patch them directly you will produce some page faults. You can use a api called VirtualProtect to remove (and put back) the memory protection, so you can patch
windows in memory.

The purpose is to force the getprocaddress function to return to our program everytime it will be called by vbox, so wa don't have to first patch the files on disk or in memory.

Virtual protect needs 4 parameters :

1) address of mem to tweak
2) size of mem
3)a protection flag (meaning read / write / execute rights)
4)a mem location where this function will put the old protection flag (use it when you're finished)

***SPECIAL NOTE TO THE READER

This is working on windows nt4 and win2k, not on win 98, you actually have to find the good parameters to write enable
the process or find another way on win 98. Read iceman's essay about this



0008:0043D71F 688CD74300 PUSH 0043D78C *param 4 contains 0 in mem in our case
0008:0043D724 FF3588D74300 PUSH DWORD PTR [0043D788] *IMPORTANT I'm on windows nt, the flag is 0x 40
0008:0043D72A B896400000 MOV EAX,00004096 *size of 4096 in mem, large enough to patch 5 bytes ;-)
0008:0043D72F 50 PUSH EAX *param 2 pushed
0008:0043D730 FF3584D74300 PUSH DWORD PTR [KERNEL32!GetProcAddress] *param 1 pushed (result in 43d784 of the code above)
0008:0043D736 E8BC0DA577 CALL KERNEL32!VirtualProtect *well the memory is write enabled, so we can patch it.
0008:0043D73B A184D74300 MOV EAX,[KERNEL32!GetProcAddress] *get the address of the api
0008:0043D740 C700E925965A MOV DWORD PTR [EAX],5A9625E9 *patch the win api with 5 bytes, those bytes in my case, means unassembled jmp 43d74f in the

beginning of getprocadress in memory


0008:0043D746 C6400488 MOV BYTE PTR [EAX+04],88 *end of the patch
:u
0008:0043D74A E9D669A577 JMP KERNEL32!GetProcAddress *and go back to the real win function to continue the prog execution we land just in 43d74f

We will land at this point now every time the getprocaddress function is called :


0008:0043D74F FF0500D84300 INC DWORD PTR [0043D800] *this variable is a counter
0008:0043D755 813D00D84300B0010000CMP DWORD PTR [0043D800],000001B0 *this value means the getprocaddress function needs to be called 1b0 times

for my prog to go to 43d7c1 (just to let vboxt420 decrypt itself)


0008:0043D75F 7460 JZ 0043D7C1 *if getprocaddress was called 1b0 times, we go there
0008:0043D761 55 PUSH EBP *all of theses are the normal first instruction inside getprocaddress crushed by my patch,
0008:0043D762 8BEC MOV EBP,ESP *you sure have to execute them for getprocaddress to work fine
0008:0043D764 51 PUSH ECX
0008:0043D765 51 PUSH ECX
:u
0008:0043D766 E9BF69A577 JMP 77E9412A *we continue in $GetProcAddress+5 (the patch was 5 bytes long)

0008:0043D7C1 C7052541E977558BEC51MOV DWORD PTR [KERNEL32!GetProcAddress],51EC8B55 *we don't need The patched api getprocaddress
0008:0043D7CB C6052941E97751 MOV BYTE PTR [77E94129],51 *so we put back the original values
0008:0043D7D2 E9B52AFCFF JMP 0040028C *jump to the second part of my work

The purpose of all this was to wait for vboxt420.dll to self decrypt in memory, getprocaddress was called 1b0 times, this value was calculated for us to be
able to patch vboxt420 after his first mem integrity checks, we had to wait just for the right moment, I mean patch the code just before it is used, and put it back
the way it was just after its execution.

First we have to deal with the vbox call to dialogboxParama, this protection is already explained by v porguen on the vbox 4.10 essay (porvbox.htm)

I just reproduced what he did, in summary make believe the window procedure called by dialogboxparama that it is finished and put eax to 0 when the call to dialogboxparama returns.

Second part, we land here :

0008:0040028C A1BC5A0807 MOV EAX,[07085ABC] *put in eax the table import address of dialogboxparama of vboxt420.dll
0008:00400291 A304D84300 MOV [USER32!DialogBoxParamA],EAX *put this address in 43d84d for later
0008:00400296 C705BC5A080776034000MOV DWORD PTR [07085ABC],00400376 *patch the table import so when vbox will call dialogboxparama, it will land in 400376


0008:004002A0 C7054ECD0307E963353CMOV DWORD PTR [0703CD4E],3C3563E9 *remember 703cd4e ? this is the place where vbox generates the decryption keys

I patch this address to force vbox to jmp to 4002b6 everytime 703cd4e is called.


0008:004002AA C60552CD0307F9 MOV BYTE PTR [0703CD52],F9 *end of the patch
0008:004002B1 E96F3EA977 JMP KERNEL32!GetProcAddress *go back to the normal prog execution


0008:004002B6 6681FE7E4D CMP SI,4D7E *a call to 703cd4e occured !so the flow lands here. when the keys are created, si always contains 4d7e so we test this
0008:004002BB 740A JZ 004002C7 *we go there if we're in key creation state.
0008:004002BD E87EF8C306 CALL 0703FB40 *original first statement of 703cd4e
0008:004002C2 E98CCAC306 JMP 0703CD53 *go back to vbox 703cd4e+5


0008:004002C7 891DE4D74300 MOV [0043D7E4],EBX *we save ebx, this is a pointer to retrieve the keys after the next call
0008:004002CD E86EF8C306 CALL 0703FB40 *generate the keys
0008:004002D2 A3E0D74300 MOV [0043D7E0],EAX *we save eax, to restore it to its original state after our statements
0008:004002D7 891DE8D74300 MOV [0043D7E8],EBX *same with ebx
0008:004002DD EB0D JMP 004002EC *jump to the CRACK part :-)

0008:004002EC 8B1DE4D74300 MOV EBX,[0043D7E4] *lets restore the keys pointer (before the key creation)
0008:004002F2 8B83F1090000 MOV EAX,[EBX+000009F1] *eax contains the address of the good key
0008:004002F8 8983E9090000 MOV [EBX+000009E9],EAX *THE CRACK ! put the good key over the bad one.
0008:004002FE 8983F9090000 MOV [EBX+000009F9],EAX *on this adress too

After this, the good key replaces the bad one, the procdump import table will be correctly decrypted. How did I found this ? It could take me one week long to
explain you, use the mem tracing methods...


0008:00400304 C6050D1C0007EB MOV BYTE PTR [07001C0D],EB *this patch is like the one made in vbox4.10 jnz to jmp
0008:0040030B C705821C0007E9210300MOV DWORD PTR [07001C82],000321E9 *same as above
0008:00400315 A1E0D74300 MOV EAX,[0043D7E0] *restore eax
0008:0040031A 8B1DE8D74300 MOV EBX,[0043D7E8] *and ebx
:u
0008:00400320 C705A81F0007E989E33FMOV DWORD PTR [07001FA8],3FE389E9 *at this place, all the serious protections will be passed, so we patch this point
to put back the original values inside vboxt420.dll before the other integrity checks occurs.


0008:0040032A C605AC1F0007F9 MOV BYTE PTR [07001FAC],F9 *end of the patch
0008:00400331 E91DCAC306 JMP 0703CD53 *back to vbox

0008:00400336 C7054ECD0307E8ED2D00MOV DWORD PTR [0703CD4E],002DEDE8 *in vbox, 7001fa8 is reached, so we land here
0008:00400340 C60552CD030700 MOV BYTE PTR [0703CD52],00 *put all the values
0008:00400347 C6050D1C000775 MOV BYTE PTR [07001C0D],75 *in their
0008:0040034E C705821C00070F852003MOV DWORD PTR [07001C82],0320850F *original state
0008:00400358 C705A81F00078065FC00MOV DWORD PTR [07001FA8],00FC6580 *to defeat mem checkings
:u
0008:00400362 C605AC1F00076A MOV BYTE PTR [07001FAC],6A
0008:00400369 E93A1CC006 JMP 07001FA8 *go back to vbox and BOOM your prog works with no time limits anymore

The dialogboxparama trick (copied on v porguen essay about vboxt410.dll

0008:00400376 8B442410 MOV EAX,[ESP+10] *we patched vbox import table address to land here at every call to dialogboxparama (address 40028c)
eax contains dialogboxparama procedure

To understand all this, read the essay I'm talking about.


0008:0040037A A308D84300 MOV [0043D808],EAX *save the procedure address
0008:0040037F C7442410A0034000 MOV DWORD PTR [ESP+10],004003A0 *replaces the procedure with 4003a0
0008:00400387 8F050CD84300 POP DWORD PTR [0043D80C] *this is made to trick the return address of dialogboxparama
0008:0040038D 6898034000 PUSH 00400398 *to go to 400398
0008:00400392 FF2504D84300 JMP [USER32!DialogBoxParamA]
0008:00400398 33C0 XOR EAX,EAX *make believe vbox you pressed the try button
0008:0040039A FF250CD84300 JMP [0043D80C] *go to window procedure
0008:004003A0 837C240818 CMP DWORD PTR [ESP+08],18 *is it finished loading ?
0008:004003A5 7510 JNZ 004003B7 *no we loop
0008:004003A7 C744240811010000 MOV DWORD PTR [ESP+08],00000111 *finished loading, force the window procedure exit
0008:004003AF C744240C95040000 MOV DWORD PTR [ESP+0C],00000495 *by modifying the window message
0008:004003B7 FF2508D84300 JMP [0043D808] *go back to win procedure.

Final Notes

At this point the crack is finished, this should work on every vboxed prog. Sure you've got to put this prog every time inside the vboxed executable to make this work.

Now let me tell you something, I emailed previewsoftware for the incoming release of this crack, you know, just to tell them that we could give them informations

to help them build some better protections and they didn't even answer me ! Maybe they're too proud or sceptical. So feel motivated to crack every prog protected

by this, you will make a good action for them. They need to learn more and maybe the next time they will be more polite...