VBox The Hellraiser
or the "paper tiger" by PreviewSystems
12 November 1998
by Marigold
Courtesy of Reverser's page of reverse engineering
slightly edited
by reverser+
Ah, Marigold! "At first, I was deeply impressed (You know. . . a dead body in a room closed from inside. . . perfect crime). I prepared myself for long and hard struggle". And Marigold, like a Philip Marlowe of our reversing lore, scores another interesting point in the never ending development of the most advanced software reversing techniques on this planet.
Let me repeat it, because even if everyone among us knows it very well, it is really worth remembering that Marigold DID NOT have the source code of this protection scheme. He felt it, he understood it, he reversed it, and then, what's even more important than anything else, he took the time to think and write about it, helping all protectors and all reversers out there...

Xoanino & Weijun Li... the ball is now in your fields
Timelock project
There is a crack, a crack in everything That's how the light gets in
( )Beginner ( )Intermediate (x )Advanced ( )Expert

If you read this essay, you'll see that VBox is a rather tough protection (though any appraisal of a commercial product is entirely out of cracker's customs). But it it also has a characteristic that is very impotant for us - this is a developing scheme, which provides an excellent opportunity for cracker/reverser education. New features are introduced gradually, as if it were specially designed exercises.
VBox The Hellraiser
or "a paper Tiger" by PreviewSystems
Written by Marigold


Not long ago VBox by PreviewSystems was buried on this site. Now it looks a bit premature. Not only because a new version, 4.10, successfully healed all cracks, but mainly because it proved that they are learning.

Moral: Learn!
This essay is meant to review the whole scheme in its development, thus describing cracking approach to a new version in “incremental” way.

Tools required
Standard set: SoftIce/SoftDump/Wdasm/Hexeditor (I use Hiew)

Target's URL/FTP
Target doesn't matter for the following

Program History
All this essay is about history



I’ve never seen a target protected with Timelock version 1.
Timelock 2 used several protection API functions (tl32v20.dll ) which were called from a protected proggy to make checks. Then the proggy tested returned values to decide: to run or not. As you can see, nothing special. Just replace

call ProtectionFunction 


mov eax,RightValue
add esp,. . . 

In fact, I’d never recognized Timelock as a separate protection scheme until I encountered with Timelock 3.

Timelock 3.03..3.10
Version 3 marks the beginning of the Digital Wrappers era.
This particular implementation is as follows. Some length of code after EntryPoint is encrypted and an additional section, PREVIEW, with a new EntryPoint in it is attached to the proggy. That section contains several lines of code to call from tl3xxinj.dll a function with a very suggestive name, which (if all lights are green) decrypts bytes and returns the real EntryPoint or address of ExitProcess (if anything went wrong). Call eax finishes procedure.

A very naïve and straightforward approach that allows the equally straightforward reversal:

  • 1. Step over the call to protection function and remember eax – the EntryPoint
  • 2. Using SoftDump, dump some length of memory starting from this point (2000h bytes will be enough, but you can dump the whole section (.text or whichever))
  • 3. Patch dumped bytes into a target file and change EntryPoint field in the PE-header to the right value.

    (At this moment one got rid of wrapping but aesthetically minded people could also:)

  • 4. Cut off the PREVIEW section from the file
  • 5. Decrease Number Of Sections field in PE-header
  • 6. Correct ImageSize field (reduce by 1000h)
  • 7. Correct Import Directory RVA field (set it equal to .idata RVA)

    Now the proggy is crisp and clean and carries no sign of wrapping.
    The relative ease of protection removing gives no motivation for a deeper study of this version.

    Timelock 3.13..3.15
    I overlooked this version when it first appeared, so I’ll give some detail here.

    New features are:

  • The whole code section is encrypted.
  • .idata section is encrypted.
  • Checksum of the protection dll image in memory is calculated (Actually, I’m not sure that this feature was not present in previous versions. At least, it made no problem).
    *I use word "checksum" here and below in a sense "hash function"

    Unwrapping is not so simple as with the previous version – in addition to the above-described procedure, which generally remains untouched, we need to restore .idata section.

    Restoration of information from .idata section is similar to that that would be used later in Vbox and is described elsewhere .
    Differences are as follows: 1) Encrypted information is stored in .idata section itself; 2) The first field of 26-byte record for an imported object always contains the module name index in the name array (-1 with meaning “previous” is never used).

    Let’s consider how the necessary information could be collected in the case of tl315inj.dll. Differences with tl313inj.dll are minimal.

    :1001830D 8BB52CFEFFFF            mov esi, dword ptr [ebp-1D4]
    :10018313 8B9D30FEFFFF            mov ebx, dword ptr [ebp-1D0]
    :10018319 85F6                    test esi, esi
    :1001831B 742E                    je 1001834B

    Here [ebp-1D4] contains a length and [ebp-1D0] – a pointer to an array of zero terminated strings – names of imported modules and functions – the name array. Dump this array into a file.
    Next, we need a description for each imported function. This description is a 26(1A)-byte long record. Records are decrypted one at time to bind an imported function. Binding is being made in a loop 1839A ..18525.

    :1001839A 813DCC9D0410F8000000    cmp dword ptr [10049DCC], 000000F8
    :100183A4 7523                    jne 100183C9
    :100183A6 85FF                    test edi, edi
    :100183A8 8D8564FAFFFF            lea eax, dword ptr [ebp+FFFFFA64]
    :100183AE 50                      push eax
    :100183AF 750C                    jne 100183BD
    :100183B1 E82A7A0000              call 1001FDE0     ; Decryption of the
    :100183B6 83C404                  add esp, 00000004 ; first record
    :100183B9 8BD8                    mov ebx, eax
    :100183BB EB14                    jmp 100183D1
    * Referenced by a Jump at Address:100183AF(C)
    :100183BD E82E7B0000              call 1001FEF0     ; Decryption of 
    :100183C2 83C404                  add esp, 00000004 ; all following records
    :100183C5 8BD8                    mov ebx, eax
    :100183C7 EB08                    jmp 100183D1
    ;Now ebx contains a pointer to the record for the current imported function

    . . . :10018503 8B4316 mov eax, dword ptr [ebx+16] :10018506 0305F04E0410 add eax, dword ptr [10044EF0] :1001850C 8BC8 mov ecx, eax :1001850E 8B8560FFFFFF mov eax, dword ptr [ebp-A0] :10018514 8901 mov dword ptr [ecx], eax ;< Address of function :10018516 83C71A add edi, 0000001A ; is recorded to Import :10018519 FF45CC inc [ebp-34] ; Address Table :1001851C 8B4DCC mov ecx, dword ptr [ebp-34] :1001851F 398D64FFFFFF cmp dword ptr [ebp-9C], ecx :10018525 0F8F6FFEFFFF jg 1001839A

    One needs to patch code inside this loop to save all records into a mapped file created with SoftDump. As this loop includes error-handling code, which never works, one has plenty of space for this patch. I intentionally give no code for this patch as the next step – rebuilding of .idata section – requires of cracker higher programming skills than this simple task.

    One important note about image checksum. The creators of this protection certainly follow our 14 Commandments: the checksum is never checked against its “right” value. Instead it is incorporated into a decryption key, so if one makes soft-patching (file checksum is another problem) at inappropriate moment, the decryption of the name array goes wrong and system crashes. Now you should take into account that setting a bpx actually means the changing of a byte on this address to CC, though SoftIce doesn’t show it. (Of course, it is applicable to all versions with code checksum checking.)
    Thus, to get to the code snippets above, you should not set breakpoints there.

    Here is a call to the function that calculates checksum:

    :100159DF 8D851CFEFFFF            lea eax, dword ptr [ebp+FFFFFE1C]
    :100159E5 50                      push eax     ;Buffer for checksum
    :100159E6 8D85B4FDFFFF            lea eax, dword ptr [ebp+FFFFFDB4]
    :100159EC 50                      push eax
    :100159ED 8D85BCFDFFFF            lea eax, dword ptr [ebp+FFFFFDBC]
    :100159F3 50                      push eax
    :100159F4 8D85C4FDFFFF            lea eax, dword ptr [ebp+FFFFFDC4]
    :100159FA 50                      push eax
    :100159FB 81F7494C0000            xor edi, 00004C49  ; “LI” < Weijun Li
    :10015A01 57                      push edi
    :10015A02 81F64A570000            xor esi, 0000574A ; “WJ” < initials
    :10015A08 0335EC4E0410            add esi, dword ptr [10044EEC]
    :10015A0E 56                      push esi
    :10015A0F E8ECA50000              call 10020000
    :10015A14 83C418                  add esp, 00000018

    So, you should step all the way through code or you may set bpx 10015A0F , clear it at arrival and set necessary breakpoints after return from this function..

    VBox 4.0..4.03
    Vbox (Timelock 4 so to say) presents further strengthening of protection. In addition to the previous version now:

  • Protected proggy is packed (each section separately)
  • Encrypted .idata section seems to be stored in a separate file
  • Protection itself consists of three dll’s:
    Vboxp4xx.dll – unpacker (and loader for dll’s)
    Vboxt4xx.dll – contains main protection function - PreviewParadise_WJ
    Vboxb4xx.dll – loads vboxt4xx and calls PreviewParadise; its other functions in this version are obscure; (vboxc4xx.dll is included in those versions, which allow “electronic buying”)
    The last two dll’s are packed in the same way as a proggy, but code is not encrypted and information on imported functions is stored in a file. Initialization function first calls unpacker-loader, which unpacks image and binds imported objects.

    Protected proggy is being processed in following steps:

  • Unpacking of image; part of code remains encrypted and .idata section is empty
  • Call to PreviewParadise, which will decrypt code and bind imported functions if it decides that you are a good guy. If not, you will have ExitProcess address as return value. This function calculates checksums for protected proggy, vboxt4xx.dll and vboxb4xx.dll files. If these are wrong, you’ll have a wrong decryption key for the code, then a wrong checksum for decrypted bytes and, as a result, a messagebox that file is corrupted. For some reason they dropped image checksum calculation in this version.

    Cracking of the “virginity restoration” type would include two additional steps as compared with the previous version:

  • Dumping of images for each section and gluing them together
  • Making of PE-header (existing is totally inappropriate)

    Some people think this method is difficult, but one should take into account its aesthetical advantages.
    For people who don’t care, Xoanon invented another crack: Unpacker vboxp4xx.dll may be patched in such a way so it makes patching of PreviewParadise “in flight”, during unpacking, to extend “evaluation period” forever and get rid of start dialog. This cracks Vbox itself, not a particular Vboxed target. Then it looked suitable to bury Vbox as a protection scheme.


    The Hellraiser

    Vbox 4.10

    This version has a whole bunch of new features:

  • Checksums for all involved files are authenticated (for vboxt410 – twice) <----+
  • Checksums for dll’s images in memory are calculated (for vboxt410 – twice)<- Xoanon’s crack R.I.P
  • Debugger presence in memory is detected < - Bye, bye hopes for virginity restoration
  • Diassembling of vboxp410.dll crashes Wdasm; IDA works but gives wrong disassembly

    At first, I was deeply impressed (You know. . . a dead body in a room closed from inside. . . perfect crime). I prepared myself for long and hard struggle: I unpacked vboxt410.dll, redirected file checksum calculation to the original packed file, add a section with a copy of original unchanged code and redirected image checksum calculation to it (it only sounds simple...). You see, I imagined, knowing Weijun Li ways, that the check for debugger presence implicated some subtle modification inside the hash functions, for example, and that it would have been not easy, if ever possible, to find and remove it. So, I planned to use this modified dll to collect information, necessary for unwrapping, without using SoftIce.

    You will understand my disappointment when, after sorting things out, I found a function that simply sets a flag; then this flag is tested, ...jumps... all that primitive stuff... "A paper Tiger", in a word. The only hope, this version must have been made in haste, and the next will show, at last, those crackers a thing or two. Well, let's hope it!

    Here is that unfamous call:

    :07006F4B 6A00                    push 00000000
    :07006F4D 6AFF                    push FFFFFFFF
    :07006F4F 683B9D0000              push 00009D3B
    :07006F54 8D8D34FEFFFF            lea ecx, dword ptr [ebp+FFFFFE34]
    :07006F5A E8E1220100              call 07019240
    :07006F5F 8945BC                  mov dword ptr [ebp-44], eax

    In presence of debugger this function returns 26h, change eax to 0 and you will never see again that awful message: “...If you are using debugger...”

    Other things to mention:

  • Image checksum is calculated here:
    :070066EA 8BC3                    mov eax, ebx
    :070066EC 33FB                    xor edi, ebx
    :070066EE F7D0                    not eax
    :070066F0 3145B0                  xor dword ptr [ebp-50], eax
    :070066F3 8D85F0FDFFFF            lea eax, dword ptr [ebp-210]<-Buffer for checksum
    :070066F9 50                      push eax
    :070066FA 8D8520FFFFFF            lea eax, dword ptr [ebp-E0]<- Relocation table
    :07006700 81F7494C0000            xor edi, 00004C49
    :07006706 50                      push eax
    :07006707 57                      push edi <- Code length
    :07006708 33F3                    xor esi, ebx
    :0700670A FF75B0                  push [ebp-50]
    :0700670D 81F64A570000            xor esi, 0000574A
    :07006713 8975C4                  mov dword ptr [ebp-3C], esi
    :07006716 89BD0CFFFFFF            mov dword ptr [ebp+FFFFFF0C], edi
    :0700671C 56                      push esi <- Code RVA
    :0700671D FF7584                  push [ebp-7C]
    :07006720 E843120000              call 07007968

    and here (parameters are the same):

    :070071B2 8D8514FEFFFF            lea eax, dword ptr [ebp+FFFFFE14]
    :070071B8 C645FC23                mov [ebp-04], 23
    :070071BC 50                      push eax
    :070071BD 8D8520FFFFFF            lea eax, dword ptr [ebp+FFFFFF20]
    :070071C3 50                      push eax
    :070071C4 FFB50CFFFFFF            push dword ptr [ebp+FFFFFF0C]
    :070071CA FF75B0                  push [ebp-50]
    :070071CD FF75C4                  push [ebp-3C]
    :070071D0 FF7584                  push [ebp-7C]
    :070071D3 E890070000              call 07007968

    Remember, that any active softice's bpx actually changes the code, so clear them away before these calls.

    File (vboxt410.dll) checksum is calculated here:

    :07006F62 8D458C                  lea eax, dword ptr [ebp-74]
    :07006F65 50                      push eax
    :07006F66 8D8504FFFFFF            lea eax, dword ptr [ebp+FFFFFF04]
    :07006F6C 50                      push eax
    :07006F6D A138FE0407              mov eax, dword ptr [0704FE38]
    :07006F72 FF7028                  push [eax+28]
    :07006F75 E836DF0000              call 07014EB0

    Another check is made inside vboxb410.dll, which passes the result to PreviewParadise as combination of two parameters:

    :070072D8 8B450C                  mov eax, dword ptr [ebp+0C]
    :070072DB 8B4D2C                  mov ecx, dword ptr [ebp+2C]
    :070072DE F7D0                    not eax
    :070072E0 33C8                    xor ecx, eax;1=OK 
    :070072E2 7510                    jne 070072F4

    When you know all this, you may restore virginity of the target in the same way as with the previous version. There are some minor changes in headers of packed sections and other things... If you are really going to do this, you will easily sort it out.

    But what about a Xoanon-style universal crack for all Vboxed programs? I’ve got it as a by-product of solution to my main objective (total unwrapping, you remember). The modified vboxt410.dll I made allows any patching in its code. . . Any questions?

    Final Notes

    I hope this essay will encourage some crackers to master "virginity restoration" technique.
    I also hope that it will help Preview Systems to improve their protection. I really liked it... deep in my heart. ">Marigold

    Ob Duh
    I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period than the allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all: you'll find it on most Warez sites, complete and already regged, farewell.

    You are deep inside reverser's page of reverse engineering, choose your way out:

    Advanced cracking

    redhomepage redlinks redsearch_forms red+ORC redstudents' essays redacademy database
    redreality cracking redhow to search redjavascript wars
    redtools redanonymity academy redcocktails red"antismut CGI-scripts redmail_reverser
    redIs reverse engineering legal?