or the "paper tiger" by PreviewSystems
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 Fravias out there...
Xoanino & Weijun Li... the ball is now in your fields :-)
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.
This essay is meant to review the whole scheme in its development, thus describing cracking approach to a new version in “incremental” way.
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
mov eax,RightValue add esp,. . .
In fact, I’d never recognized Timelock as a separate protection scheme until I encountered with Timelock 3.
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:
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:)
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.
I overlooked this version when it first appeared, so I’ll give some detail here.
New features are:
*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
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
certainly follow our 14 Commandments: the checksum is never checked against
value. Instead it is incorporated into a decryption key, so if one
soft-patching (file checksum is another problem) at
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
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 (Timelock 4 so to say) presents further strengthening of protection. In addition to the previous version now:
Protected proggy is being processed in following steps:
Cracking of the “virginity restoration” type would include two additional steps as compared with the previous version:
Some people think this method is difficult, but one should take into
account its aesthetical
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.
This version has a whole bunch of new features:
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:
: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
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?
I hope this essay will encourage some crackers to master "virginity
I also hope that it will help Preview Systems to improve their protection. I really liked it... deep in my heart. ">Marigold