This tutorial describes how to crack Winrar.
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
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:
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
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
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.
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
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
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
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
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 is the least significant byte of the
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 ->
The value of
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
Hardware, Write ->
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
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
Analysing the routine, at
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.
00007FF70E2F80D2 is taken and
mov al,1 is not executed.
We check what happens when
je is not taken by changing the
nop instructions (we could also invert
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.
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.