Вы находитесь на странице: 1из 20

The Winlicense tutorials v1.2.

1
by quosego/snd
17-04-2009
Teddy suggested I put all my small tuts in one big paper, so this document holds
all the tutorials Ive made about Winlicense/Themida. Itll be updated when
needed, so make sure you got the latest version.
Some of the topics discussed in this paper may get outdated quickly other things
may only get slightly changed, if you get stuck its always best to just tinker
along, reversing is only the result of a few idiots that tinkered along.

quosego

Contents
The Winlicense tutorials v1.2.1.............................................................................. 1
Patching the Winlicense 2.0.5.0 - 2.0.7.0 Checksum..............................................3
Intro;................................................................................................................ 3
The checking;................................................................................................... 3
Analysis;........................................................................................................... 3
Patching the checksum 1.x until 2.0.5.0;.........................................................4
Patching the checksum 2.0.5.0 until 2.0.6.5;...................................................4
Patching the checksum 2.0.7.0........................................................................5
Finding the Winlicense Is_Registered dwords and patching them in Winlicense
2.0.6.5-2.0.7.0 (and lower)..................................................................................... 6
Intro;................................................................................................................ 6
Finding the dwords in 2.0.6.5;..........................................................................6
Finding the dwords in 2.0.7.0;..........................................................................7
Patching the dwords;........................................................................................ 8
Final notes;....................................................................................................... 9
The REGISTERED macro unraveled in Winlicense 2.0.6.5.....................................10
Intro;.............................................................................................................. 10
Analysis of the Cryptoblock function;.............................................................10
Analysis of the origin of the decryption dwords;............................................11
Analysis of the origin of the second decryption dword;..................................12
Analysis of the origin of the first decryption dword;.......................................12
Conclusion;.................................................................................................... 13

Using the is_registered dwords to bypass HWID and banning locks.....................14


Intro;.............................................................................................................. 14
Setting the is_registered dwords correct at the right time.............................14
The Stack Antidump in Winlicense and Themida 2.0.6.5......................................15
Intro;.............................................................................................................. 15
The location of the stackantidump;................................................................15
The method of checking antidump by the VM;...............................................15
Conclusion;.................................................................................................... 16
The LoadLibraryA antidump in WL an TM 2.0.7.0.................................................17
Intro;.............................................................................................................. 17
Finding the antidump location;.......................................................................17
Fixing the antidump;...................................................................................... 17
Final Notes;........................................................................................................... 18

Patching the Winlicense 2.0.5.0 - 2.0.7.0 Checksum.


Intro;
In this tut I'll try to explain how Winlicense checks if the app has been tampered
with and how to patch it.
The checking;
Winlicense his anti patching procedure only holds an simple checksum check, it
uses imagehlp.CheckSumMappedFile to compute this checksum and then
compares it to the one stored by Winlicense and if it isn't the same it fails.
To be exactly it does the following,
-Alloc a memory buffer to store itself from disk.
-Store the PE in this memory buffer.
-Use GetProcaddress to obtain CheckSumMappedFile.
-Use CheckSumMappedFile to compute a checksum.
-Use some logical instructions to modify the checksum.
-Compare the checksum to the one stored at the end of the file.
-If it passes proceed, if it fails give an error.
Analysis;
If you'd breakpoint GetProcaddress and wait for quite some while sooner or later
WL will obtain the CheckSumMappedFile location. If you'd then bp this api and
return to WL code you'll end up somewhere similar to here;
(If the app is using cisc VM, risc VM has a different VM entry.)
0112A5AF
0112A5B4

68 2C31AA09
^ E9 3B7BF9FF

PUSH 9AA312C
JMP 010C20F4

This'll of course leads you to nowhere since it's VM and studying it obfuud is
greatly annoying. However if you look at the stack and scroll up four dwords
you'll see the following;
(these are simply the arguments pushed into CheckSumMappedFile)
(http://msdn.microsoft.com/en-us/library/ms679281(VS.85).aspx)
0007FF6C
0007FF70
0007FF74
0007FF78

012A0000
000B41FC
0112A4D0 cisc_+_f.0112A4D0
0112A4D4 cisc_+_f.0112A4D4

and their meaning;


PIMAGE_NT_HEADERS CheckSumMappedFile(
__in PVOID BaseAddress,
__in DWORD FileLength,
__out PDWORD HeaderSum,
__out PDWORD CheckSum
);
The checksum is the most important (located at 0112A4D4). If you'd check out
that dword you'll find the checksum. You can, if you've patched WL, feed it here

the correct checksum. But that would include hooking the WL decrypting routines
or GetProcAddress or similar. There are easier methods.
WL does not directly compare the CheckSumMappedFile generated checksum
with a checksum it has stored, instead it does some computations before
comparing the checksum.
In my case it did the following computations, extracted from the Cisc Virtual
Machine.
ROL {checksum}, {last byte checksum}
;ROL 000B6D92,92
XOR B648002D,2AC8914C
ADD 9C809161,87C05B78
XOR 2440ECD9,6D10B8E2

= B648002D
= 9C809161
= 2440ECD9
= 4950543B

In this case 4950543B is considered the final calculated checksum. If you now set
a memory breakpoint on access on the BaseAddress of the mapped PE (see the
CheckSumMappedFile structure) in the memory map. You'll see the VM accessing
the very last dword in the mapped file. This will if the executable is unmodified be
the same as the calculated checksum. WL will next do a compare and fail or
proceed.
Patching the checksum 1.x until 2.0.5.0;
So if you've modified your WL protected app you must update the checksum
located in a dword at the end of the file, however as I stated all calculations of
this checksum are done within the VM and it would be tedious to extract them
every time.
However WL stores the calculated checksum in the VM registers before
comparing it with the stored one. So to find it easily you can do the following;
- When you've returned from CheckSumMappedFile API memory bp the
BaseAddress on access in the memory map. Press shift-f9. (It now has obtained
the last dword of the mapped PE.)
- Follow edi in dump and look for the first dword that appears two times, this is
the calculated checksum. In cisc VM's it should be [edi+4] and [edi+8], in risc
VM's it should be further down with some empty dwords between it.
- Copy the calculated checksum to the end of the file (search for the old one or
just scroll down). It'll now run again with its new checksum.
Patching the checksum 2.0.5.0 until 2.0.6.5;
There's not much they've updated, except it gets the CheckSumMappedFile API
through the internal kernel32.dll GetProcAddress of Winlicense. So here's another
method, though you can also bp the internal Getprocaddress and proceed with
the above tutorial the following might be easier.
- HW bp on access the last dword of the file that needs checksum updating and
run. (This is the stored checksum, as you know)
- Wait until it writes it using a rep to a memory buffer.
- Then HW bp the checksum at the memory buffer. (eg. the last dword in the
memory buffer.) Just follow EDI in dump and hw bp that dword. Run and wait until
it gets accessed by the VM.

- Follow edi in dump and look for the first dword that appears two times, this is
the calculated checksum. In cisc VM's it should be easy to spot, in risc VM's it
should be further down with some empty dwords between it.
- Copy the calculated checksum to the end of the file (search for the old one or
just scroll down). It'll now run again with its new checksum.
Patching the checksum 2.0.7.0
Theyve did some updates, not many interesting ones.. Generic idea is still the
same, however one updates makes sure the previous tuts are useless;
-Load the stored checksum prior to the calculations, this means when you hw bp
it the new checksum wont be in [EDI] anymore.
Theyve probably made some other updates but since I didnt notice them they
are of no concern.
But as usual they made a mistake so that once again an easy fix without VM
digging is possible. To update the checksum in 2.0.7.0 follow the following tut.
- bp FreeLibray, run and wait until it breaks, eax and ecx hold the old and
calculated checksum.
- Copy the calculated checksum to the end of the file (search for the old one or
just scroll down). It'll now run again with its new checksum.
Hmm kinda short tutorial.. Was hoping for more, but it seems oreans is not in
the mood.
This also works for the previous versions.

Finding the Winlicense Is_Registered dwords and


patching them in Winlicense 2.0.6.5-2.0.7.0 (and
lower).
Intro;
Most Winlicense protected apps simply rely on Winlicense to check for
registration. They always do this using the WL API's and occasionally with some
custom macro's. You can easily modify the API to return eax=1 and be done with
it, however this usually does not fix the macro's/other custom checks or Trial
checks. You can patch these as well and this is what I usually did. However it
seems Winlicense only has two dwords it checks to see if it's registered, making
sure that these hold the correct dwords registers the entire app with only a two
dword patch.
Update Notes for 2.0.6.5;
Oreans has updated the dwords, and to be honest not as lame as the other
updates. This time I'll have to guide you through the Virtual Machine to obtain the
correct is_registered dwords. Since they're now no longer fixed and available in
normal code. But don't worry, it'll be painless. :)
Update Notes for 2.0.7.0;
Oreans finally has hidden the is_registered dword correctly. They can no longer be
found using the search strings used in the 2.0.6.5 version. All accesses to them
are decrypted and encrypted when executed or VMed. The registered macro now
uses a different dword to check if its registered. And finally the name api does
not crash anymore when youve got the is_registered dwords fixed.
Finding the dwords in 2.0.6.5;
Not much updates here since the older versions, run the app and search for the
following strings in the WL section.
1)
B8 01 00 00 00 89 85 ?? ?? ?? ?? C7 85
Finds the following code;
MOV EAX,1
// Not important
MOV DWORD PTR SS:[EBP+xxxxxxxx],EAX
// Not important
MOV DWORD PTR SS:[EBP+xxxxxxxx], {Variable_1)
// EBP+xxxxxxxx
holds the dword
(The EBP+xxxxxxxx in the third line of the found code is the location of the first
is_registered dword)
{Variable_1} is a random value, which WL checks for to see if it's not registered,
however the correct value is not 2 here, but also random. If {Variable_1} equals
the stored value then WL accepts the program as unregistered.
2)
00 00 00 00 00 00 00 00 81 BD
Finds the following code;

CMP DWORD PTR SS:[EBP+xxxxxxxx],{Variable_2)


(EBP+xxxxxxxx is the location of the second is_registered dword)
{Variable_2) is in this case, the value the second is_registered dword needs to be.
If the stored second is_registered dword equals {Variable_2) then WL accepts the
program as registered. (If of course the first dword is also valid.)
Put a hardware breakpoint on execute on the found addresses and restart the
app. Next when you stop on these instructions you can read the memory
locations which they compare to or write to. These are the locations were WL
stores the is_registered dwords.
Finding the dwords in 2.0.7.0;
New search strings new chances.
Start your app let it run and search for the following strings in the WL sections;
1)
50 53 B8 89 04 00 00
When found scroll up until you find something similar to this;
Also it is possible that theres also a sub ecx,5 rep movs instruction before this
loop, search for it as mentioned in 2).

The above is a encryption/wiping loop, it overwrites everything above itself. As


you probably can see above this is only bogus junk code that has already been
wiped by the above loop. So HWBP on execute this loop and restart to see the
function prior to being wiped.
However make sure theres not another loop slightly above this loop. If youve
restarted and scrolled up to above the loop youll see the function thats about to
get wiped. Now in this function search for the following;
CMP DWORD PTR SS:[EBP+xxxxxxxx], {Variable_1)
holds the dword

// EBP+xxxxxxxx

Here the EBP+xxxxxxxx in this line of the found code is the location of the first
is_registered dword.
{Variable_1} is a random value, which WL checks for to see if it's not registered,
however the correct value is not 2 here, but also random. If {Variable_1} equals
the stored value then WL accepts the program as unregistered.
2)
50 53 8B C0 B8 9F 04 00 00
When found scroll up until you find the following (~10 lines);
SUB ECX,5
REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]

However often olly doesnt analyse the above code correctly so you can also
search for the following byte string; 83 ?? 05 F3 A4. When found, HWBP it on
execute and restart. Now scroll up and youll see another encryption/wiping loop
thats about to get wiped by the rep movs mentioned above. Now HWBP on
execute this loop (wipe the previous HWBP) and restart. Now when you again
scroll up youll once again see a function thats about to get wiped. In this
function search for the following;
CMP DWORD PTR SS:[EBP+xxxxxxxx],{Variable_2)
Here EBP+xxxxxxxx is the location of the second is_registered dword.
{Variable_2) is in this case, the value the second is_registered dword needs to be.
If the stored second is_registered dword equals {Variable_2) then WL accepts the
program as registered. (If of course the first dword is also valid.)
So now youve found the locations of the is_registered dwords in version 2.0.7.0
and the value that the second is_registered dword must be when registered.
Patching the dwords;
In previous versions the correct values of the is_registered dwords were fixed (2 &
500), however now they're randomly generated and using the information
discussed in the previous paragraph you only know the correct value of the
second dword. As for the first dword you only know the correct dword to make it
unregistered. Which pretty much helps you nothing at all.
I will now explain how you can trace the Oreans virtual machines to get the
correct first is_registered dword. As you might know there are two possible Virtual
Machines, Risc and Cisc. Since they differ in complexity and execution methods,
I've made two tuts to find the first is_registered dword. Use the correct one for
the correct VM. A simple rule is if the VM is located inside the WL section it's cisc,
else it's risc.
For version 2.0.6.5;
Winlicense accesses and compares the correct first is_registered dword with the
stored one the second time it accesses it in the VM. So first HW bp on access the
location of the first dword. Then restart and press shift-f9 until you hit the code
were it writes the {Variable_1). (See 1) in Finding the dwords.) Next press f9 and
you'll be at the first access in the VM, next press f9 and you're at the second
access. Next it'll compare the stored first is_registered dword with the correct
one. Now you'll have to choose between the cisc or risc tut.
For version 2.0.7.0;
Winlicense accesses and compares the correct first is_registered dword with the
stored one the third time it accesses it in the VM. So first HW bp on access the
location of the first dword. Then restart and press shift-f9, first time youll break
at a rep that writes zeroes and the second time you end up in the VM. Now press
shift_f9 another two times and youre near the compare to the correct value.
Comparing in cisc Virtual machine;
- Press F7 to arrive at the main lods handler, you can see {Variable_1) in the
stack.
- Put a breakpoint here and f9 until you see {Variable_1) in ecx

- eax now holds the correct is_registered dword. Store this at the first
is_registered dword location and your app will be registered. (If you also fix the
second of course.)
You'll now prolly think, well that's nice but since I'm in this screwy virtual machine
you better tell me why this actually works. Simple see the unobfuscated handler
below which compares values in the cisc VM;
POP EAX
POP ECX
CMP ECX,EAX
PUSHFD
JMP {Main_Handler)

// All handlers return to the main handler.

Since your {Variable_1) was pushed first it will be in ecx, and eax must hold
whatever it is compared to. Junk VM code never writes stack values to eax or ecx
so {Variable_1) can never get to ecx unless it's intended. (The above handler is
unobfuscated, it can take extremely long if you try to trace and find this handler
yourself.)
Comparing in risc Virtual machine;
- Trace until {Variable_1) which is retrieved from its store location is located at
second dword of the stack, should be a pretty short trace 20 instructions max.
00391FF8
{Variable_1)
00391FFC

7EAC5730

<-- pushed is_registered dword

00000000

<-- begin of stack

- Hardware bp that stack address on access (here 391ff8), and run. When it
breaks the correct is_registered dword is now located in the dword above the old
one in the stack. Store this dword at the first is_registered dword location and
your app will be registered. (If you also fix the second of course.)
Once again you might ask yourself and why does this work?? And again once you
know the unobfuscated code all becomes clear;
MOV ECX,DWORD PTR DS:[ESI]
MOV EBX,DWORD PTR DS:[ESI-4]
PUSH DWORD PTR DS:[EDI+70]
POPFD
CMP ECX,EBX
PUSHFD

<-- get {Variable_1)


<-- get correct
<-- compare

Well that's all, after you've unpacked the app just set the first and second dwords
correctly and everything will once be registered. Or use an inline to fix these
dwords after the app has been unpacked in memory.
Final notes;
Once again Winlicense can crypt certain blocks of code using dwords written
when a keyfile is present, these will not be decrypted and can crash. Also the
Get_name API will crash! Since there's no name you can put a ret 0c in its place
which most apps will accept or patch it to return a name.

The REGISTERED macro unraveled in Winlicense 2.0.6.5


Intro;
In this part of my series about Winlicense I'll unravel the decryption of certain
code parts that use the REGISTERED_START REGISTERED_END macro. This tut
won't be as directly useful as the previous parts. Since you prolly still need a
correct keyfile to fix these blocks, and after you've unpacked an app with a key
it's unnecessary to do anything with these blocks. But still it'll give you a nice
idea what Winlicense does and how it uses the keyfiles.
Cryptoblocks, as I decided to call them, are encrypted pieces of information/code,
that only get decrypted when a valid keyfile/or the required decryption dwords
are available, and the program thinks it's registered. (These blocks also use the
is_registered dwords, I've mentioned in previous tutorials that these blocks can
crash if you've fixed the is_registered dwords.)
Once again this'll include some VM tracing and analysis. Please note, I make use
of an unobfuscated Virtual Machine. Sadly enough the techniques developed by
me and others to unobfuscate VM's are not publicly available, except for the
recent release of the Code Unvirtualizer 0.1 by Deathway which has this
implemented. You can use this tool to do some analysis yourself if you wish to
expand on this tutorial. I however have not used this tool so I don't know its
effectiveness. I will however try to make it so that you can even follow this tut
with an obfuscated cisc VM.
Analysis of the Cryptoblock function;
First of all how can you find these CryptoBlocks, this is actually quite easy and
very similar to the finding of CodeEncrypt functions. A simple search for the
following binary string will find you the Cryptoblocks.
E8??????00????00000000000000????2020
This'll lead you to a call to the REGISTERED macro, below I'll explain an example
of such a REGISTERED macro in parts.
PUSHAD
CALL 0064EC8F
POP EBP
SUB EBP,9D41080

//call the line below


//pop call return address into ebp
//substract to get correct ebp value

As often the case with Themida and Winlicense uses EBP to get memory
locations.
(eg MOV DWORD PTR SS:[EBP+9D41076],ESI now equals for instance, MOV
DWORD PTR SS:
[00551849],ESI)
MOV ESI,DWORD PTR SS:[ESP+20]
macro was called
[2];
CMP DWORD PTR DS:[ESI],20204C57
JNZ [1]

//load the address from which the


//are we at the beginning/end

CMP DWORD PTR DS:[ESI+4],3


JE 0064ECB6
[1];
INC ESI
JMP [2]
SUB ESI,2
MOV DWORD PTR SS:[EBP+9D41076],ESI

//are we at the last 20204c57 (end)

Store the address that marks the end of the encrypted data.
CMP DWORD PTR SS:[EBP+9C11311],70D42925
JNZ [end]
CMP DWORD PTR SS:[EBP+9C1219D],72EF7845
JNZ [end]
JMP 0064ECE9
[...]
Check for the is_registered dwords, also a nice place to see what they are
supposed to be. Though not always available.
MOV EAX,DWORD PTR SS:[EBP+9C10F19]
MOV EBX,DWORD PTR SS:[EBP+9C10FDD]
Get the decryption dwords from the Winlicense data.
MOV ESI,DWORD PTR SS:[ESP+20]
ADD ESI,0D
[3];
CMP ESI,DWORD PTR SS:[EBP+9D41076]
JE [exit]
Load start address of the cryptoblock to decrypt, and compare to the end of the
block.
ADD BYTE PTR DS:[ESI],AL
ADD BYTE PTR DS:[ESI],BL
XOR BYTE PTR DS:[ESI],AH
XOR BYTE PTR DS:[ESI],BH
SUB BYTE PTR DS:[ESI],AL
SUB BYTE PTR DS:[ESI],BL
XOR BYTE PTR DS:[ESI],AH
XOR BYTE PTR DS:[ESI],BH
ROR EAX,4
ROR EBX,3
INC ESI
JMP [3]
Decrypt the block using the EAX and EBX dwords a simple decryption routine.
Analysis of the origin of the decryption dwords;
The origin of the decryption dwords as loaded in EBX and EAX is interesting as it
could proof to be an interesting point of attack. Are they simply random numbers
preloaded in a Winlicense protected app or are they actually retrieved from the

keyfile. The first would make the cryptoblocks easily retrievable whilst the keyfile
is not available, the second would make it harder. However I've already spoiled it
somewhat for you guys saying that they are actually retrieved from the keyfile.
I'll now discuss how I achieved this.
--First, something about the VM. It has the following simplified structure, a main
handler interprets bytes and jumps to the accompanying specific handler. This
handler executes its code and the main handler interprets the next byte.
So the main handler gets byte 31, decrypts it and sees that byte 31 means
executing handler number 4 which pushes ebx. It'll jump to the "push
ebx/number 4 handler" which will push ebx and go back to the main handler. Now
it'll get the next byte and so on.
--Analysis of the origin of the second decryption dword;
Now HW bp the location of the first decryption dword and restart, this'll get you
at least to the area of code where this decryption dword is written. Skip a few
reps that write zeroes at this location until you get to the virtual machine handler
that writes this dword.
POP DWORD PTR DS:[EDX]
JMP {Main_Handler)
handler.

// All handlers return to the main

Hw bp the VM register (follow EDI in dump and find the decryption value) that
contains the first decryption dword. Next time it'll be accessed it'll be for the
calculation of the second decryption dword, and it'll have pushed it onto the
stack. You can also find this by bping the main handler and see the dword
appearing in the stack. Unless you've deobfuscated your VM I don't suggest
tracing through specific handlers. There are ~30 handlers between the writing of
the first dword and the calculation of the second.
Next you can bp this dword in the stack to see where it gets accessed, (remove
the previous one) once again unless you've got no obfu don't trace since there's a
lot of junk code between normal instructions. (push pops, word loads, 4 adds.
etc.) You'll end up in a handler doing the following;
POP EAX
ADD DWORD PTR SS:[ESP],EAX
PUSHFD
JMP {Main_Handler)
[ESP] holds a fixed value loaded from VM_code and eax holds the first decryption
dword. It should be obvious that they get added to each other here.. Now check
out the value in the stack, indeed it's the second decryption dword.
So you now know the second decryption dword is derived from the first. However
that does not tell us anything about the origin of the first dword. This will be
discussed in the next chapter.

Analysis of the origin of the first decryption dword;


Restart the app and use an hw bp on access on the first decryption dword
location to once again break in the VM were it writes this dword. However right
now you're already too late, the decryption has both been calculated and written.
But as you might have noticed the main handler loads VM_code bytes from ESI
which makes it decide which handler it needs to call, this is the actual code being
executed right now in the VM. So why not scroll back a bit here and put a bp
earlier in the VM. So follow ESI in dump, marvel at the encrypted VM_code scroll
up about 13 lines. There's lots of junk in VM_code so you can scroll up quite some
bytes. (Please note that the amount of lines is guesswork, the amount of
junkcode is variable.)
Hw bp this byte on access and restart and f9 until you're in the VM. If you now
follow EDI in dump to see the VM_registers, you must check to see if the first
decryption dword is no longer in the VM registers. If it still is then you've not
scrolled up enough lines. The first VM_register ( simply [EDI] ) holds an
interesting value, a memory buffer. A few lines down in another VM_register
there's the first dword located at this memory buffer.
00528645 02660000
[..]
00528651 A3D9D3B7
VM_register [EDI+4])

//First VM_register, [EDI]


//dword located at 2660000 (fourth

Right now I'll just tell you that the 2660000 is the memory buffer holding the
keyfile which went through a few decryptions. Hw bp this address and restart to
find out for yourself.
Now hw bp the VM_register containing the first dword of the keyfile memory
buffer. (In the above example the one with A3D9D3B7.) and press f9. When you
break it'll have pushed this value on the stack. Next you can bp this dword in the
stack to see where it gets accessed,(remove the previous one). You'll end up in a
handler doing the following;
POP EAX
XOR DWORD PTR SS:[ESP],EAX
PUSHFD
JMP {Main_Handler)
Check the stack and you'll see the first decryption dword.
We now know that the first decryption dword is derived from the first decrypted
dword of the keyfile. The first decryption dword is then used to calculate the
second decryption dword.
Conclusion;
To decrypt certain codeparts in registered Winlicense protected apps Winlicense
uses the first dword of the keyfile to calculate the decryption dwords. These
dwords then get used to decrypt the REGISTERED macro's encrypted code/data.
In pseudocode the following happens to obtain these decryption dwords.
MOV EAX, [FIRST_BYTE_KEYFILE]

XOR EAX, [FIXED_VALUE_85737364]


MOV [WL_DATA_1],EAX
ADD EAX, [FIXED_VALUE_05BE6546]
MOV [WL_DATA_2],EAX
[WL_DATA_1] & [WL_DATA_2] now contain the decryption dwords.

Using the is_registered dwords to bypass HWID and


banning locks.
Intro;
As proven by the loaders/scripts that bypass trial and HWID made by LCF_AT the
is_registered dwords are also used to see if licenses are valid in packer code. A
logical result is that changing them to their correct values when incorrect but
valid license are present will result in running programs.
This tut will simply show hoe you can use the is_registered dwords to make
programs that use banned license and wrong HWIDs work once more. These
apps however require unpacking, loaders or inlines to keep working.
Setting the is_registered dwords correct at the right time.
HWID;
This one is quite simple and wont require much explanation. Normally youll get
two message boxes when you try to run a program with a license meant for a
different computer;
1. This application has been registered to xxxx xxxx.
2. The current key has been locked to a different machine.
Simply modifying the is_registered dwords at the first message box to their
correct values will make the program run.
Banned License;
Here youve only got a message box saying that your license has been banned.
So well need to dig somewhat further. Not too much though.
Put an hw bp on write on the second is_registered dword and run. First youll see
it zeroed and then changed to the correct value and then to a different value.
Now change it to the correct value again and the program runs.
Quite simple and whole lot easier than digging VM searching for zeroes and 1 and
other HWID tricks. Trial values etc. can also be fixed using these kinds of tricks.

The Stack Antidump in Winlicense and Themida 2.0.6.5


Intro;
Yes this is it; I will now explain the complete workings of the stack antidump.
Though this is just one antidump, there are many more, it is the one I know best.
The other antidumps will stay a mystery until someone decides to make a tut
about these.
The antidumps are checks by the Oreans Virtual Machine to see if it was dumped.
If it is itll check these and if not available the VM will produce an error. The
stackantidump in particular is a check for a qword in the stack. If its not
available, the check for it in the Virtual machine will not pass.
I will not tell you how to defeat it, only what makes it tick. You should be able to
defeat it yourself.
The location of the stackantidump;
Well the name says it all, its located in the stack. As you might have noticed
when an Oreans protected app is at its oep the stack is already filled with some
info. Normally in XP apps start at xxffc4 in the stack (esp), most protectors at the
oep start the app at this same location. However the OEP in Oreans protected
apps start at lower values (~xxff38). This has no effect on apps theyll still just
run, theyll only use different stack addresses than unprotected apps.
Now when you unpack an app the app will once again start at xxffc4 and all those
values Winlicense or Themida put before their oep will not be there, the stack
gets wiped when you restart a program. The VM makes use of this by checking
these addresses for their correct values. When unpacked these values are not
there so the VM knows its been dumped.
To be exact the location of the stackantidump is when you are at the EP of an
Oreans protected app [esp] and [esp-4] usually 12ffc4 and 12ffc0 in XP.
The method of checking antidump by the VM;
The antidump is written using the following code, this was obtained from the VM,
the methods used to do this however stay private.
mov
mov
mov
mov
mov
xor
mov
xor
mov

[data_1], fixed_value_1
ecx, xxffc0
[ecx], fixed_value_1
eax, [ecx]
ebx, [ecx+4]
eax,ebx
[ecx],eax
ecx, fixed_value_2
[data_2],ecx

//Store random value(1)in packer_data.


//Get stackantidump location.
//Store random value(1)@esp_xxffc0
//xor [xxffc0],[xxffc0+4]
//Store result at esp xxffc0
//xor xxffc0 with a random value
//Store in packer_data.

The above stores 2 dwords that the VM will later use to check stackantidump,
data_1 and data_2. Data_1 holds the variable that must be the same when
[xxffc0] and [xxffc0+4] are xorred. Data_2 holds the location xorred with
fixed_value_2, the VM will use data_2 to calculate where the stackantidump is
located.
To check stackantidump the VM now only needs to the folowing;

- Retrieve data_1 and data_2.


- Xor data_2 with fixed_value_2 to get the location of the stackantidump.
-Get the dword located at that location.
-Xor this dword with the dword at [location + 4].
-Check if this result equals data_1, if not press selfdestruct.
Conclusion;
To check if the VM is dumped the VM checks certain values in the stack. It then
xors these values and checks if they are the same as a stored value. If they are
not the VM will take action to prevent execution.

The LoadLibraryA antidump in WL an TM 2.0.7.0


Intro;
In this tut Ill show you how to defeat the newest antidump in Winlicense and
Themida 2.0.7.0, the first few apps have emerged using the new version and
have proven to be unable to run on most other computers when unpacked. This is
because Oreans has implemented a new antidump based on the location of the
kernel32 dll in memory. This differs in most OSs and service packs.
Finding the antidump location;
Oreans checks for the content of the LoadLibraryA+16 dword. It has the location
of LoadLibraryA of the computer it was unpacked stored In the
Themida/Winlicense data. When you run an unpacked app on the same
computer it was unpacked there will be no problems, LoadLibraryA will be exactly
located at the same place as stored in the TM/WL data and the check will pass.
However when runned on some other computer it will obtain the location of
LoadLibraryA from the TM/WL data and check LoadLibraryA+16 for its correct
value. However since kernel32 can be loaded at a different memory location, the
check will fail since the retrieved LoadLibraryA +16 address will no longer hold
the same value as expected.
Example;
When runned the packer shell gets the LoadLibraryA location and gets the
dword located at LoadLibraryA+16. It now stores the location of LoadLibraryA in
Themida data and also stores the LoadLibraryA+16 dword. You unpack the app
and dump this WL/TM data to disk.
Okay so now run it on some other computer with a wholly different LoadLibraryA
location (a different OS/SP is usually enough). The VM gets the location of what it
thinks to be LoadLibraryA from the WL/TM data en adds 16 to it, then it checks if
the bytes here are the same as the bytes originally stored by packer code. Itll
now notice that they differ and knows youre running it on a different computer.
Fixing the antidump;
Now this is actually quite easy. If you think of it, it has stored the LoadLibraryA
location in TM/WL data and then adds 16 to and checks if this dword is correct.
Now how easy is it to find LoadLibraryA in the TM/WL section and change this to
somewhere you do have the correct dword at any time.
So in short when youve unpacked an app;
-Search for the LoadLibraryA location in the WL/TM section.
-Change it to a location within your dump. (At the end of the TM/WL section
is always some room.)
-Add 16 to this and change the memory located here to the memory values
located at LoadLibraryA+16 so that they are the same as the
LoadLibraryA+16 bytes in your original unpacking computer.
-And voila every time the VM accesses what it thinks to be
LoadLibraryA+16, itll access some location at the end of the TM/WL
section always holding the same value.

Final Notes;
Thank you all for reading this, hope you enjoyed it.
Greetings to all webscene teams, and the reversers visiting the RE boards and
thnx to a certain provider of executables.
You cannot stop a tide with a spoon. Cracking technology will
always be several steps ahead of DRM and content will be
redistributed on anonymous networks. Giulio Prisco, chief
executive of Metafuturing Second Life, formerly of CERN

-q

Вам также может понравиться