How to crack WinRAR
This tutorial describes how to crack Winrar.
Needed
Note
Memory addresses mentioned in this tutorial are likely to be different on your system. Only the last couple of bytes should be the same. E.g. for address 00007FF6A403AE4A
only check if 4A
is the same.
Load the application inside the debugger
Run x64dbg and open the WinRAR.exe executable in x64dbg by pressing F3 to open a file. Now the application is running inside the debugger and it will pause (break) at some address, this is the entry break point. Click the right arrow located under the menu in x64dbg (or press F9) repeatedly until the text in the lower-left of the window stays at ‘Running’.
The application is now running without pausing at any break points.
Finding the routine that checks if the application is registered
When the application starts it must somehow check if the application is registered. So somewhere in the executable there must be a function (routine in Assembly) that checks if the application is registered. The trick is to find that routine and modify it so that the application thinks it is registered. The registration routine can be found in many ways, but usually a good place to search is for certain strings. The application window states that this is an evaluation copy
:
If you think of how this application was written, somewhere in the code a decision must be made (if/else statement) to show the string evaluation copy
instead of something else like registered
. We don’t know what the string will be when the application is registerd, but we know for sure that evaluation copy
should not be shown.
Attack the string
In x64dbg you can search for strings in the executable. You want to limit your search to only the Winrar executable and not search all the other modules (DLL’s) that are loaded by the application. Goto the symbols
tab in x64dbg and double click the row that contains the winrar.exe module.
You are now in winrar.exe region of the memory shown in the CPU
tab. Right click somewhere in the CPU
window and goto Search for
-> Current module
-> String references
. Now you are in the References
tab of x64dbg. Enter evaluation copy
in the search
box below.
The string cannot be found, so most likely it is not stored as consecutive characters in the executable. Windows applications can store strings in a string table ‘resource’, so we use a tool to read the string tables of the executable which is called Resource hacker.
Search for the string in string tables
Run Resource hacker and open the WinRAR.exe executable. Press ctrl+f
to search for a string. Enter evaluation copy
and click search. The string evaluation copy
appears to be in a string table with the constant 873
mapped to it. These constants are used in the executable to load the string mapped to it. String tables are used to save memory.
Find constant mapped to the string
Search for the constant 873
in x64dbg: right click somewhere in the CPU
window and goto Search for
-> Current module
-> Constant
. In the window that appears enter 873
in the Signed:
box and click OK.
x64dbg finds one occurance of the constant located at address 00007FF6A403AE4A
. This address is likely to be a bit different on your system, but the last two bytes should be the same: 4A
.
If nothing is found, make sure you are in the winrar.exe memory region by going to the Symbols
tab and double clicking winrar.exe.
Double click the search results to go to that address location in the CPU
tab. We are now in the CPU
tab at the memory address that uses the constant. You see that the constant is represented as 369
, which is hexadecimal for 873
. The instruction that uses the constant is mov ecx, 369
which means copy the value 369
to the register ecx
.
Change the string
As this is the only location where 369
is used it is highly likely that this instruction will load the evaluation copy
string from the string table. We test this by changing 369
to another constant from the string table. In Resource Hacker we see the constant 872
mapped to the string Registration has been successfully completed
. Modify the assembly by double clicking on it. Change 369
to 368
, which is 872
in hex. Click OK once, and then click cancel to not further modify instructions
The instruction at 00007FF6A403AE4A
should now be mov ecx, 368
as show below:
Press F9 or the right arrow a couple of times until the application is running without pausing at a breakpoint. The string in the titlebar has changed to Registration has been successfully completed
. We have verified that the constant 369
in the instruction is used for the evaluation copy
string.
Find the registration-check routine
In WinRAR goto help -> about WinRAR. It still mentions the 40 days trial copy
. We have only patched the executable to show another string. Logically, the string evaluation copy
will be shown when the registration routine has decided that the application is not registered.
Have a look at the instructions surrounding the instruction where the constant 369
is used. More specifically, trace back which instructions preceded the instruction at 00007FF6A403AE4A
, how did we get there? The only way that instruction could have been executed is by coming from address 00007FF7B91EAE20
, which is also made clear by the grey dashed arrow on the left of the addresses.
At 00007FF7B91EAE20
a conditional jump is done, ja
, which means jump above. This means the jump will be taken when the zero flag ZF
and the carry flag CF
are set. These flags are in turn set by the instruction before that at 00007FF7B91EAE1D
. There, the instruction cmp eax, 13
will compare the eax
register with the value 13
(in hex), and set the ZF
if eax <= 0x13
. Set a breakpoint at 00007FF7B91EAE20
by highlighting the row and pressing F2. Now restart the application by pressing ctrl+F2. Press F9 until x64dbg breaks at the breakpoint you just set at 00007FF7B91EAE20
. The value of eax
are the 32 least significant bits of the rax
register (image), which can be seen on the top-right window in x64dbg. The value of eax
is FFFFFFEE
.
This means the instruction you are at now, cmp eax, 13
, will result in a value that is higher than 0. This results in the CF
flag not be set and the jump at ja
is taken. We modify the eax
register so that it contains a value <= 13
and the ja
jump is not taken. Double click on the rax
register, and enter the value 13
(or anything lower than 13).
Press OK and press F9 to continue execution. The string in the title bar has now changed to only xx days left to buy a license
. Apparently this is not the registration flow we are looking for.
Trace back a bit trough the instructions in x64dbg. We are looking for jumps that will change the instruction flow to show another string in the title bar. At 00007FF70E2FAE0E
there is a jump, jne
, that jumps past both the instructions mov ecx, 368
and mov eax, 369
. jne
stands for jump not equal and takes the jump when ZF == 0
. Right now the jump is not taken because we will end up in the instructions right after this jne
. To see what will happen when the jump is taken, we change jne
to jmp
, so it will unconditionally jump. Set a break point at 00007FF70E2FAE0E
and restart the application. Press F9 until the application pauses at the break point we just set. Press space to modify the row and change jne
to jmp
.
Press F9 again until the application runs. No string is shown any more in the title bar, this looks like the registration flow.
So when the jne
is taken we get into the registration flow. The instruction at 00007FF70E2FAE07
that decides if the jne
is taken, cmp byte ptr ds:[7FF7B92848E4],dil
, compares the byte located at memory address 7FF7B92848E4
with the contents of the dil
register. dil
is the least significant byte of the rdi
register.
We want to know what value is at memory location 7FF7B92848E4
and in dil
when the application breaks at 00007FF70E2FAE07
, because this value decides whether we come in the registration flow or in the ‘evaluation’ flow. Set a break point at 00007FF70E2FAE07
, restart the application with ctrl+F2 and press F9 until you pause at the break point. Right click on the row where the cmp
instruction is and goto Follow in Dump
-> Constant: 7FF7B92848E4
.
The value of 7FF7B92848E4
and dil
is both 00
. This means that the result of cmp byte ptr ds:[7FF7B92848E4],dil
will be 0
and ZF will be set. jne
is then not taken an we will enter the flow where the evaluation copy
string is set.
We could trace back where dil
is set or we can check whether the byte located at 7FF7B92848E4
is written to at some point. We do the latter first because this can be easily checked by setting a hardware write breakpoint at 7FF7B92848E4
. Right click on the 00
byte and goto Breakpoint
-> Hardware, Write
-> Byte
.
This type of breakpoint will break when a value is written to that memory address. Now restart the application (ctrl+F2). Press F9 until you arrive the hardware breakpoint you just set.
x64 will break at 00007FF6F0E78FB1
, one instruction after the byte was written. So the byte was written at 00007FF6F0E78FAB
, with the instruction mov byte ptr ds:[7FF6F0F148E4],al
. We trace back again where al
is modified. al
is the the least significant byte of the rax
register, which is used to hold return values of routines (functions). The instruction before this one at 00007FF6F0E78FA6
is a routine call. After exiting a routine call the return value is stored in rax
. It is highly likely that the rax
register is modified in there.
We have a look inside that routine by right clicking on the row and goto Follow in Disassembler
-> click on the address.
We are now at the beginning of the routine that is very likely to modify the al
(rax
) register that eventually will decide if evaluation copy
or no string is shown in the title bar.
We back trace from the end of the routine, which can be found by the ret
instruction. We search for the instructions that modify the rax
register.
Analysing the routine, at 00007FF70E2F80D4
the al
register is specifically modified to contain the value 1
. This does not look like a coincidence. We test what execution path will be taken around this instruction mov al,1
by setting a break point at the beginning of the routine at 00007FF70E2F80A8
. Press F9 until we arrive at the break point and then press F8 (step over) until 00007FF70E2F80D2
. Then watch what happens when we press F9 again. je
at 00007FF70E2F80D2
is taken and mov al,1
is not executed.
We check what happens when je
is not taken by changing the je
with nop
instructions (we could also invert je
to jne
). Break at the beginning of the routine. Click on the row with je
and press space, enter nop
and tick “keep size” and “fill with NOP’s”
nop
means no-op and does not execute anything. So now the je
has basically been erased and execution will continue at 00007FF70E2F80D4
. Press F9 until the application runs. The evaluation copy
string is not in the title bar any more and the “about” window also shows that the application is registered to “” (empty). The application is now cracked.
Wrap up
We found the registration routine by tracing back from the evaluation copy
string. Then we patched this routine by removing the je
instruction that was causing the application to execute in the non-registered state.