Category Archives: Sem categoria

[Reverse Engineering] – Crack Agricultural Simulator 2013

Today I’ll show you how you can easily crack Agricultural Simulator 2013 with the stupid method(string textsearch). From now on I won’t explain everything, most of the things I’ll do here were already described in previous tutorials. You’ll always need Olly(or any debugger you like) so you can patch your files(exe or dll usually).

Run the game and you’ll be prompted to write your serial. Hum, enter anything you want and then click in “Register”. Unless you’re some freak of nature you should get a message telling you that the serial you entered is incorrect. Alright.. At this point you probably know what we need to patch! Yeah, we need to trick the program into thinking that it is already registered.

For that, do a string search with anything that may led you to the solution. I choose to write “serial” and the first match I got was this:

Sem Título

I forgot to mention that the file we need to edit is agrasimulator2013.dll. This string looks nice, it seems like we’re creating a registry key in HKEY_CURRENT_USER\ActaLogic folder. Indeed if you Click Ctrl+R on your desktop, then write “regedit” and navigate to that folder. You can clearly check that the folder was created after the first run. It should have a AutoUdpate folder with the key being disabled/enabled. Double click on the first match and press Ctrl+A to run a quick analysis. My procedure it’s the following(your should be similar):

CPU Disasm
Address   Hex dump          Command                                  Comments
004653C0  /$  55            PUSH EBP                                 ; agrarsimulator2013_original.004653C0(guessed Arg1,Arg2)
004653C1  |.  8BEC          MOV EBP,ESP
004653C3  |.  83E4 F8       AND ESP,FFFFFFF8                         ; QWORD (8.-byte) stack alignment
004653C6  |.  B8 18240000   MOV EAX,2418
004653CB  |.  E8 507D1200   CALL 0058D120                            ; Allocates 9240. bytes on stack
004653D0  |.  833D B4650B02 CMP DWORD PTR DS:[20B65B4],0
004653D7  |.  56            PUSH ESI
004653D8  |.  8B75 0C       MOV ESI,DWORD PTR SS:[ARG.2]
004653DB  |.  57            PUSH EDI
004653DC  |.  8B7D 08       MOV EDI,DWORD PTR SS:[ARG.1]
004653DF  |.  0F85 D7000000 JNE 004654BC
004653E5  |.  6A 00         PUSH 0                                   ; /Arg3 = 0
004653E7  |.  68 E0C06500   PUSH OFFSET 0065C0E0                     ; |Arg2 = ASCII "Software\ActaLogic\SerialNumber"
004653EC  |.  68 E8B36A00   PUSH OFFSET 006AB3E8                     ; |Arg1 = agrarsimulator2013_original.6AB3E8
004653F1  |.  8D4C24 1C     LEA ECX,[LOCAL.2308]                     ; |
004653F5  |.  C74424 1C 000 MOV DWORD PTR SS:[LOCAL.2308],0          ; |
004653FD  |.  E8 6E7BFAFF   CALL 0040CF70                            ; \agrarsimulator2013_original.0040CF70
00465402  |.  837C24 10 00  CMP DWORD PTR SS:[LOCAL.2308],0
00465407  |.  0F84 AF000000 JE 004654BC
0046540D  |.  C74424 0C 100 MOV DWORD PTR SS:[LOCAL.2309],10
00465415  |.  83FE FF       CMP ESI,-1
00465418  |.  74 3C         JE SHORT 00465456
0046541A  |.  8D4424 0C     LEA EAX,[LOCAL.2309]
0046541E  |.  50            PUSH EAX                                 ; /Arg3 => OFFSET LOCAL.2309
0046541F  |.  68 20550B02   PUSH OFFSET 020B5520                     ; |Arg2 = agrarsimulator2013_original.20B5520
00465424  |.  B9 50670B02   MOV ECX,OFFSET 020B6750                  ; |
00465429  |.  E8 22BCF9FF   CALL 00401050                            ; |
0046542E  |.  50            PUSH EAX                                 ; |Arg1
0046542F  |.  8D4424 1C     LEA EAX,[LOCAL.2308]                     ; |
00465433  |.  E8 C87DFAFF   CALL 0040D200                            ; \agrarsimulator2013_original.0040D200
00465438  |.  85C0          TEST EAX,EAX
0046543A  |.  74 1A         JZ SHORT 00465456
0046543C  |.  8B4424 10     MOV EAX,DWORD PTR SS:[LOCAL.2308]
00465440  |.  85C0          TEST EAX,EAX
00465442  |.  74 07         JZ SHORT 0046544B
00465444  |.  50            PUSH EAX                                 ; /hKey => NULL
00465445  |.  FF15 04806000 CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKe ; \ADVAPI32.RegCloseKey
0046544B  |>  B8 02000000   MOV EAX,2
00465450  |.  5F            POP EDI
00465451  |.  5E            POP ESI
00465452  |.  8BE5          MOV ESP,EBP
00465454  |.  5D            POP EBP
00465455  |.  C3            RETN
00465456  |>  8D4C24 0C     LEA ECX,[LOCAL.2309]
0046545A  |.  51            PUSH ECX                                 ; /Arg3 => OFFSET LOCAL.2309
0046545B  |.  68 30550B02   PUSH OFFSET 020B5530                     ; |Arg2 = agrarsimulator2013_original.20B5530
00465460  |.  B9 4C670B02   MOV ECX,OFFSET 020B674C                  ; |
00465465  |.  E8 E6BBF9FF   CALL 00401050                            ; |
0046546A  |.  50            PUSH EAX                                 ; |Arg1
0046546B  |.  8D4424 1C     LEA EAX,[LOCAL.2308]                     ; |
0046546F  |.  E8 8C7DFAFF   CALL 0040D200                            ; \agrarsimulator2013_original.0040D200
00465474  |.  85C0          TEST EAX,EAX
00465476  |.  75 35         JNZ SHORT 004654AD
00465478  |.  56            PUSH ESI                                 ; /Arg1
00465479  |.  8BC7          MOV EAX,EDI                              ; |
0046547B  |.  E8 70FEFFFF   CALL 004652F0                            ; \agrarsimulator2013_original.004652F0
00465480  |.  83C4 04       ADD ESP,4
00465483  |.  85C0          TEST EAX,EAX
00465485  |.  74 26         JZ SHORT 004654AD
00465487  |.  E8 34480300   CALL 00499CC0
0046548C  |.  8B4424 10     MOV EAX,DWORD PTR SS:[LOCAL.2308]
00465490  |.  830D B4650B02 OR DWORD PTR DS:[20B65B4],00000002
00465497  |.  85C0          TEST EAX,EAX
00465499  |.  74 07         JZ SHORT 004654A2
0046549B  |.  50            PUSH EAX                                 ; /hKey => NULL
0046549C  |.  FF15 04806000 CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKe ; \ADVAPI32.RegCloseKey
004654A2  |>  B8 01000000   MOV EAX,1
004654A7  |.  5F            POP EDI
004654A8  |.  5E            POP ESI
004654A9  |.  8BE5          MOV ESP,EBP
004654AB  |.  5D            POP EBP
004654AC  |.  C3            RETN
004654AD  |>  8B4424 10     MOV EAX,DWORD PTR SS:[LOCAL.2308]
004654B1  |.  85C0          TEST EAX,EAX
004654B3  |.  74 07         JZ SHORT 004654BC
004654B5  |.  50            PUSH EAX                                 ; /hKey => NULL
004654B6  |.  FF15 04806000 CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKe ; \ADVAPI32.RegCloseKey
004654BC  |>  33D2          XOR EDX,EDX
004654BE  |.  3915 B4650B02 CMP DWORD PTR DS:[20B65B4],EDX
004654C4  |.  0F94C2        SETE DL
004654C7  |.  F6C2 01       TEST DL,01
004654CA  |.  74 08         JZ SHORT 004654D4
004654CC  |.  33C0          XOR EAX,EAX
004654CE  |.  5F            POP EDI
004654CF  |.  5E            POP ESI
004654D0  |.  8BE5          MOV ESP,EBP
004654D2  |.  5D            POP EBP
004654D3  |.  C3            RETN
004654D4  |>  56            PUSH ESI                                 ; /Arg1
004654D5  |.  8BC7          MOV EAX,EDI                              ; |
004654D7  |.  E8 14FEFFFF   CALL 004652F0                            ; \agrarsimulator2013_original.004652F0
004654DC  |.  8BF8          MOV EDI,EAX
004654DE  |.  83C4 04       ADD ESP,4
004654E1  |.  85FF          TEST EDI,EDI
004654E3  |.  74 5F         JZ SHORT 00465544
004654E5  |.  F605 B4650B02 TEST BYTE PTR DS:[20B65B4],02
004654EC  |.  75 51         JNZ SHORT 0046553F
004654EE  |.  6A 01         PUSH 1                                   ; /Arg3 = 1
004654F0  |.  68 E0C06500   PUSH OFFSET 0065C0E0                     ; |Arg2 = ASCII "Software\ActaLogic\SerialNumber"
004654F5  |.  68 E8B36A00   PUSH OFFSET 006AB3E8                     ; |Arg1 = agrarsimulator2013_original.6AB3E8
004654FA  |.  8D4C24 1C     LEA ECX,[LOCAL.2308]                     ; |
004654FE  |.  C74424 1C 000 MOV DWORD PTR SS:[LOCAL.2308],0          ; |
00465506  |.  E8 657AFAFF   CALL 0040CF70                            ; \agrarsimulator2013_original.0040CF70
0046550B  |.  8B7424 10     MOV ESI,DWORD PTR SS:[LOCAL.2308]
0046550F  |.  85F6          TEST ESI,ESI
00465511  |.  74 2C         JZ SHORT 0046553F
00465513  |.  6A 10         PUSH 10                                  ; /DataSize = 16.
00465515  |.  68 30550B02   PUSH OFFSET 020B5530                     ; |Data = agrarsimulator2013_original.20B5530 -> 00
0046551A  |.  6A 03         PUSH 3                                   ; |Type = REG_BINARY
0046551C  |.  6A 00         PUSH 0                                   ; |Reserved = 0
0046551E  |.  B9 4C670B02   MOV ECX,OFFSET 020B674C                  ; |
00465523  |.  E8 28BBF9FF   CALL 00401050                            ; |
00465528  |.  50            PUSH EAX                                 ; |SubKey
00465529  |.  56            PUSH ESI                                 ; |hKey
0046552A  |.  FF15 10806000 CALL DWORD PTR DS:[<&ADVAPI32.RegSetValu ; \ADVAPI32.RegSetValueExA
00465530  |.  8B4424 10     MOV EAX,DWORD PTR SS:[LOCAL.2308]
00465534  |.  85C0          TEST EAX,EAX
00465536  |.  74 07         JZ SHORT 0046553F
00465538  |.  50            PUSH EAX                                 ; /hKey => NULL
00465539  |.  FF15 04806000 CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKe ; \ADVAPI32.RegCloseKey
0046553F  |>  E8 7C470300   CALL 00499CC0
00465544  |>  8BC7          MOV EAX,EDI
00465546  |.  5F            POP EDI
00465547  |.  5E            POP ESI
00465548  |.  8BE5          MOV ESP,EBP
0046554A  |.  5D            POP EBP
0046554B  \.  C3            RETN


Indeed we were right, the program is working with registry keys. You can check that by this call:

CPU Disasm
Address   Hex dump          Command                                  Comments
00465445  |.  FF15 04806000 CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKe ; \ADVAPI32.RegCloseKey

Place a breakpoint on 004653C0 (press F2) or doubleclick on it and run the game. The program will break multiple times on that address, meaning that we are probably in the right place. What we will do next is not to make the program think that we are registered, but instead we’ll skip the registration scheme! How?

You can see that this

CPU Disasm
Address   Hex dump          Command                                  Comments
004653DF  |. /0F85 D7000000 JNE 004654BC

jumps past all the registry checks. Press space on that line and replace the JNE by a JMP. The program will jump to XOR EDX, EDX. A few lines below you have

CPU Disasm
Address   Hex dump          Command                                  Comments
004654CA  |. /74 08         JZ SHORT 004654D4

that also needs to be patched. Replace that with a NOP and the XOR EAX,EAX by a MOV AL,1. The program should now be cracked. Save your new DLL file in the installation directory and you should play with no problems at all 🙂

I’ll also start to post my own cracks.. Here it is the first one(debug mine and check my changes with yours. There are different methods to do this 🙂 ).

Agricultural simulator 2013- CRACK ->!RBdVyYID!Vpn71k10emNn6SKv_Ljy_E8aHXMHmHDiZRfhorC3qZg


Need for Speed Most Wanted(Unlimited Boost)

I wasn’t able to find a working trainer for the new Need for Speed Most Wanted so I decided to create it by myself. On this post I’ll share some information with all of you so other people can develop it better than me 🙂 First of all, this was not an easy challenge for me, it seems that this game is well protected against cheating and it obligated me to spend a bunch of time around this problem!

So, here you have the download link:

Basically just open the game or the trainer and once it finds the window it will inject code in some addresses. Then boost as much as you want, there is no limit 🙂

How did I do this?

If you have some experience in programming(it you haven’t probably this is not going to be very productive for you) you may know that the first thing you need is cheat engine to analize the addresses of the game. Download it on here:

Then open the game and attach the NFS proccess to Cheat Engine. In cheat Engine there are two types of addresses: static addresses and dynamic addresses, which are the most common! Static addresses are represented in green color and never change in Cheat Engine and dynamic ones are represented in black and each time you open the game it’s very likely they will change. So, let’s start… Try to get your boost tank full and then pause the game. There is no numeric indicator for the boost but the value is stored as a float and when the tank is full the value is 100. Boost a bit and then in scan type choose Decreased value. Do it as many times as you can so in the end you will only have 10 or 15 addresses.

In my case the address is the last one in the list. As you can see this address is dynamic, so it will be different every time we open the game. Add that address to the addresslist and click on the value. Change it a couple of times just to make sure that you have found the right address! Once you’re sure about that right click on the address and select find out what accesses this address. With this you’ll be able to find the static address that you’ll need to use in order to patch the game. Boost a bit and your image should look a bit like mine.

The movss means move scalar single and is what interest us. It’s represented in the form:

movss xmm1, xmm2

Basically it moves a floating-point value from the second operand(source operand) to the first operand(destination operand).

After this choose some movss instructions and double click on them. It’ll show to you an address. Do a new scan with those addresses and add pointers to them. If you can get the same value it’s because you’re in the right direction. Try to find the green(static) addresses with that. Although I won’t go in a lot of details because I wasn’t able to find it, so I needed to find other way to solve my problem.. Actually it was pretty simple. I just keep examining the “Count” column and check which columns increased when I was boosting… These were the ones that caught my attention.

With this you’re basically ready to code a trainer for the game.. You have the addresses, now just replace them with NOP’s(0x90). Each of the instructions writes 5 0x90.

I’ll give you some pieces of the code 🙂 I would like to see some people interested on this, mainly in findind new addresses that will allow players to use other cheats.

Addresses of the game:

DWORD addresses[] = {






Values to inject(5 NOP’s): (represented in little-endian where the first byte is the least significant, so it’ll start to replace in the last byte)

BYTE values[] = {







Function to inject:

void writetomemory(HANDLE handle)


for(int i = 0; i < sizeof(addresses)/sizeof(addresses[0]); i++)


WriteProcessMemory(handle, (BYTE*)addresses[i], &values, sizeof(values), NULL);



With this information try to code a DLL 🙂

If you want a permanently hacked exe download it on here:

1st reverse engineering challenge

Today I’ll post here a REALLY basic challenge.. You’ll crack MotoGP 13, the newest MotoGP game! 🙂

First of all let me say that I’m completely against piracy, I bought this game in the release day, what I don’t want is to insert the DVD every single time I want to play this. Also, I found out that this was cracked multiple times by the warez teams. I was surprised when I realized that this game could be cracked with a single instruction, considering that most games are well protected nowadays. The security is nothing more nothing less than a DVD check, something that you can patch very easily. Install the game and give it a try! 🙂

P.S: The file you need to patch is LauncherDialogDLL.dll, this is a big hint!



For this you’ll only need OllyDbg(download: (includes some plugins, delete the DLL files if you don’t want them)).

Open Olly and add the MotoGP13.exe file.

Sem Título

As I said you previously you need to edit the LauncherDialogDLL.dll file(you could find it by tracing the “Insert the DVD” dialog). To do that go to View -> Executable Modules to bring up a list of executable modules loaded with MotoGP13.exe.

Sem Título

Double click on it and press Ctrl+A to run an analysis to the file. After that you should get something like this:

Sem Título

My first guess, as most of the times, was to start with a simple string search. Keep in mind that most of the times this method won’t work on recent software! Right click on your mouse, go to Search for and then All referenced text strings. Right click again on the Text Strings window and choose “Search for text”. Well, the most obvious thing I could think at that time was “dvd”, let’s try that, who knows if it’ll work 🙂

Sem Título

Luckily this was my first match(DVD_NOT_PRESENT). There’s a high chance that the dvd check is performed here. Press Ctrl+L just to make sure Olly didn’t find other strings containing “dvd”…… Baaam, this is the only one! Double click on it and your code should be similar to mine(after cracked, solution is here):

0133C109   . FF15 58644701  CALL DWORD PTR DS:[<&KERNEL32.FindVolumeClose>]     ;  KERNEL32.FindVolumeClose
0133C10F   . 80BD EFEFFFFF >CMP BYTE PTR SS:[EBP-1011],0
0133C116   . E9 97000000    JMP Launcher.0133C1B2
0133C11B     90             NOP
0133C11C     68             DB 68                                               ;  CHAR 'h'
0133C11D   . 748A4701       DD Launcher.01478A74                                ;  UNICODE "DVD_NOT_PRESENT"

This looks really nice. First you should know what FindVolumeClose does. It is part of the Kernel32 library and it is used with FindFirstVolume and FindNextVolume. If you scroll up you can actually check that these functions are there. The FindFirstVolume looks like this(MSDN):

HANDLE WINAPI FindFirstVolume(
  _Out_  LPTSTR lpszVolumeName,
  _In_   DWORD cchBufferLength

The FindNextVolume function take this arguments:

BOOL WINAPI FindNextVolume(
  _In_   HANDLE hFindVolume,
  _Out_  LPTSTR lpszVolumeName,
  _In_   DWORD cchBufferLength

This is probably where the program executes a loop where it’ll search for our DVD:

0169C064   > 6A 00          PUSH 0                                                ; ÚpFileSystemNameSize = NULL
0169C066   . 6A 00          PUSH 0                                                ; ³pFileSystemNameBuffer = NULL
0169C068   . 8D8D DCEFFFFF  LEA ECX,DWORD PTR SS:[EBP-1024]                       ; ³
0169C06E   . 51             PUSH ECX                                              ; ³pFileSystemFlags
0169C06F   . 8D95 E4EFFFFF  LEA EDX,DWORD PTR SS:[EBP-101C]                       ; ³
0169C075   . 52             PUSH EDX                                              ; ³pMaxFilenameLength
0169C076   . 8D85 E0EFFFFF  LEA EAX,DWORD PTR SS:[EBP-1020]                       ; ³
0169C07C   . 50             PUSH EAX                                              ; ³pVolumeSerialNumber
0169C07D   . 68 00040000    PUSH 400                                              ; ³MaxVolumeNameSize = 400 (1024.)
0169C082   . 8D8D F0EFFFFF  LEA ECX,DWORD PTR SS:[EBP-1010]                       ; ³
0169C088   . 51             PUSH ECX                                              ; ³VolumeNameBuffer
0169C089   . 8D95 F0F7FFFF  LEA EDX,DWORD PTR SS:[EBP-810]                        ; ³
0169C08F   . 52             PUSH EDX                                              ; ³RootPathName
0169C090   . FF15 4C647D01  CALL DWORD PTR DS:[<&KERNEL32.GetVolumeInformationW>] ; ÀGetVolumeInformationW
0169C096   . 8D85 F0F7FFFF  LEA EAX,DWORD PTR SS:[EBP-810]
0169C09C   . 50             PUSH EAX                                              ; ÚRootPathName
0169C09D   . FF15 50647D01  CALL DWORD PTR DS:[<&KERNEL32.GetDriveTypeW>]         ; ÀGetDriveTypeW
0169C0A3   . BA 948A7D01    MOV EDX,Launcher.017D8A94                             ;  UNICODE "MotoGP13"
0169C0AE   . 8BFF           MOV EDI,EDI
0169C0B0   > 66:8B31        MOV SI,WORD PTR DS:[ECX]
0169C0B3   . 66:3B32        CMP SI,WORD PTR DS:[EDX]
0169C0B6   .75 1E          JNZ SHORT Launcher.0169C0D6
0169C0B8   . 66:85F6        TEST SI,SI
0169C0BB   .74 15          JE SHORT Launcher.0169C0D2
0169C0BD   . 66:8B71 02     MOV SI,WORD PTR DS:[ECX+2]
0169C0C1   . 66:3B72 02     CMP SI,WORD PTR DS:[EDX+2]
0169C0C5   .75 0F          JNZ SHORT Launcher.0169C0D6
0169C0C7   . 83C1 04        ADD ECX,CEnFile::s_bEnableCallback
0169C0CA   . 83C2 04        ADD EDX,CEnFile::s_bEnableCallback
0169C0CD   . 66:85F6        TEST SI,SI
0169C0D0   .75 DE          JNZ SHORT Launcher.0169C0B0
0169C0D2   > 33C9           XOR ECX,ECX
0169C0D4   .EB 05          JMP SHORT Launcher.0169C0DB
0169C0D6   > 1BC9           SBB ECX,ECX
0169C0D8   . 83D9 FF        SBB ECX,-1
0169C0DB   > 85C9           TEST ECX,ECX
0169C0DD   .75 05          JNZ SHORT Launcher.0169C0E4
0169C0DF   . 83F8 05        CMP EAX,5
0169C0E2   .74 1D          JE SHORT Launcher.0169C101
0169C0E4   > 68 00040000    PUSH 400
0169C0E9   . 8D8D F0F7FFFF  LEA ECX,DWORD PTR SS:[EBP-810]
0169C0EF   . 51             PUSH ECX
0169C0F0   . 53             PUSH EBX
0169C0F1   . FF15 54647D01  CALL DWORD PTR DS:[<&KERNEL32.FindNextVolumeW>]       ;  KERNEL32.FindNextVolumeW
0169C0F7   . 85C0           TEST EAX,EAX
0169C0F9   .0F85 65FFFFFF  JNZ Launcher.0169C064

This is the line that copies “MotoGP13” to EDX:

0169C0A3   . BA 948A7D01    MOV EDX,Launcher.017D8A94

And this is probably where the program check if the DVD label was found or not. If it wasn’t the JNZ is executed, else we go back to 0169C064:

0169C0F1   . FF15 54647D01  CALL DWORD PTR DS:[&KERNEL32.FindNextVolumeW>]       ;  KERNEL32.FindNextVolumeW
0169C0F7   . 85C0           TEST EAX,EAX
0169C0F9   .^0F85 65FFFFFF  JNZ Launcher.0169C064

At this point you probably already know what we need to patch 🙂 Yes, it’s the line right after these two:

0169C109   . FF15 58647D01  CALL DWORD PTR DS:[&KERNEL32.FindVolumeClose] 
0169C10F   . 80BD EFEFFFFF >CMP BYTE PTR SS:[EBP-1011],0

..of course by a JMP! Save your file and replace the original exe with the newly created! MotoGP 13 should start with no problem. I didn’t go in much detail, I’m saving that for later tutorials. Anyway, I hoped you enjoyed reading this 😉 And never forget, support the companies and if you like the game, buy it.

Reverse Engineering tutorial(imcomplete) – How to crack “youtube downloader pro 4.5”

First of all I’ll not show all the steps you need to do in order to crack this software. The method is almost like the one I posted in the previous tutorial(wondershare software), although this is a bit more complex.

You’ll need OllyDbg and ExeInfo PE or Lord PE to check if the program is packed or not. Here you have the ExeInfo PE download link:

Open the program, load the ytd.exe file and you should see “Not packed , try disASM OllyDbg – or  WD32dsm89.exe –”, that’s good news, although this is not always true! You should always check with Olly, so do it now. Did it? See? Olly didn’t detect anything, now we’re “almost” sure that the program is not packed. Let’s jun run it and analyze how it behaves. The program should run without throwing any exception!

The first thing I checked was the “Help” menu. Clicking on “Help” you have one option saying “Your license” that launchs a window where you’re prompted to enter a serial number. Hum, maybe that’s not a good option. The other option I thought is.. If you tick “Automatically convert To” the program will launch another window with the title “Youtube PRO benefits”. On the “Convert” tab you also have a sentence that refers to the PRO version of the program. So let’s just search on Olly where those Strings are being called. Hit F7 until you get something like this:


772E21DC   EA 66252E77 3300 JMP FAR 0033:772E2566                    ; Far jump


(The addresses may be different on your system)

Keep hitting F7 and you’ll get to a point where something very interesting is gonna happen. You’ll find an information similar to this:


ShowState = SW_SHOW

hWnd “For multiple URLs go PRO”


This code was executed after a CALL to a certain address, followed by a TEST AL, AL, followed by a JE. The CALL will decide if the value of AL is 0 or 1. If after the CALL is executed AL is 0, then TEST AL, AL will also gonna be 0, which means that the ZF is set to 1, which consequently forces the JE to be executed and leading to the bad guy. Here it is the code(and my addresses, remember that yours might be different)

CPU Disasm

Address   Hex dump          Command                                  Comments

00BD96D7    E8 A4200000     CALL 00BDB780             ; Decide the value of AL

00BD96DC    84C0            TEST AL,AL                          ; Perform a logical AND

00BD96DE    0F84 19010000   JE 00BD97FD                 ; If AL = 0, then jump to 00BD97FD

All we have to do is to patch the function starting in 00BDB780, so it can return 1 in AL. The function should be this:

CPU Disasm

Address   Hex dump          Command                                  Comments

00BDB780    8B00            MOV EAX,DWORD PTR DS:[EAX]

00BDB782    8B50 F4         MOV EDX,DWORD PTR DS:[EAX-0C]

00BDB785    8D4A E0         LEA ECX,[EDX-20]

00BDB788    83F9 04         CMP ECX,4

00BDB78B    77 5F           JA SHORT 00BDB7EC

00BDB78D    56              PUSH ESI

00BDB78E    33C9            XOR ECX,ECX

00BDB790    57              PUSH EDI

00BDB791    85D2            TEST EDX,EDX

00BDB793    7E 43           JLE SHORT 00BDB7D8

00BDB795    8BF0            MOV ESI,EAX

00BDB797    85C9            TEST ECX,ECX

00BDB799    7C 47           JL SHORT 00BDB7E2

00BDB79B    3BCA            CMP ECX,EDX

00BDB79D    7F 43           JG SHORT 00BDB7E2

00BDB79F    0FB706          MOVZX EAX,WORD PTR DS:[ESI]

00BDB7A2    66:83F8 30      CMP AX,30

00BDB7A6    72 06           JB SHORT 00BDB7AE

00BDB7A8    66:83F8 39      CMP AX,39

00BDB7AC    76 22           JBE SHORT 00BDB7D0

00BDB7AE    66:83F8 41      CMP AX,41

00BDB7B2    72 06           JB SHORT 00BDB7BA

00BDB7B4    66:83F8 46      CMP AX,46

00BDB7B8    76 16           JBE SHORT 00BDB7D0

00BDB7BA    66:83F8 61      CMP AX,61

00BDB7BE    72 06           JB SHORT 00BDB7C6

00BDB7C0    66:83F8 66      CMP AX,66

00BDB7C4    76 0A           JBE SHORT 00BDB7D0

00BDB7C6    BF 2D000000     MOV EDI,2D

00BDB7CB    66:3BF8         CMP DI,AX

00BDB7CE    75 0D           JNE SHORT 00BDB7DD

00BDB7D0    41              INC ECX

00BDB7D1    83C6 02         ADD ESI,2

00BDB7D4    3BCA            CMP ECX,EDX

00BDB7D6  ^ 7C BF           JL SHORT 00BDB797

00BDB7D8    5F              POP EDI

00BDB7D9    B0 01           MOV AL,1

00BDB7DB    5E              POP ESI

00BDB7DC    C3              RETN

00BDB7DD    5F              POP EDI

00BDB7DE    32C0            XOR AL,AL

00BDB7E0    5E              POP ESI

00BDB7E1    C3              RETN

00BDB7E2    68 57000780     PUSH 80070057

00BDB7E7    E8 04A8F7FF     CALL 00B55FF0

00BDB7EC    32C0            XOR AL,AL

00BDB7EE    C3              RETN

And now we know why AL is being set to 0. The 00BDB78B is being executed and jumps straight to 00BDB7EC(XOR AL,AL). The XOR is only true if two bytes are different. For example:





With this, XOR AL,AL could never be 1. We can force the function to return 1, just by editting that XOR for a MOV(mov al,1 for example) Don’t forget to also patch 00BDB7DE. Copy that to the exe and run the program. The PRO version is now working great! 🙂

Reverse Engineering tutorial – How to crack Wondershare “Video Converter Ultimate 6.5.1”

As I want to keep things interesting on my blog, today I’ll approach a topic that fascinates most nerds/geeks, reverse engineering! Many people would like to understand how the “magic” is done and they can’t because the majority of the tutorials out there are outdated, which means they can’t apply those methods to today software. Fortunately I found a couple of programs where I can teach and encourage people to get their hands dirty with software. This tutorial is for educational purposes only, the program was cracked a long time ago and I think there is no problem to teach people how it was done(keep in mind that there is dozens of different ways to crack it!).

As you might imagine there are some prerequisites before you can start reading the tutorial. You should at least be familiar with Assembly language if you want to understand how the program works. There are many tutorials on the internet, a simple Google search will present you tons of it.

Enough of useless conversation, let’s start the real job.. 

Go to Wondershare site(here) and download the free trial version of the program. Run the program and install it.. Usually the program will be installed on C:\\Program Files(Program Files (x86) for 64 bit systems)\Wondershare\Video Converter Ultimate . The first step before you can reverse it is to analyze it’s behavior. On this case we already know that it is a “trial version”, so we should expect some kind of “buy” function after x days had passed. Open up the program, add a video, select the format you want on the right pane and click “Convert”. And the bad things started happening.. Here it is the image you should get on your screen: 


As you can see there are a couple of limitations. To remove this we have two options: Either we regist the program with a registration key and an email or we can buy the program. Before starting writting this I had trouble with the first option(registration key). I was able to bypass the “wrong key” screen but right after that the program rejected the key, telling that was a pirate key. Maybe it is still possible to work on that, but with the second option is far easier! At this point we’ll need a debugger. I’m been using Ollydbg since my first day of Assembly, but you can use the one you want. Just make sure you’re comfortable working with that. If you want to follow the steps exactly like me download it here (version 2.00). After you have downloaded the file, unzip and open the program. Click here:


… and load the VideoConverterUltimate.exe file that is placed on the Wondershare folder. The exe must be in the installation folder because it’ll load some DLL files.

My first guess before doing anything was to check all the strings in the program(the most ridiculous method to work on that :p) and write something that might takes us to something useful. Well, on the top of my head I can only think on “register”. On the disassembled output left click on your mouse, go to the “Search for” option, then “All referenced strings”. A new window will pop up with the strings and the respective address where they are located. Left click again(or Ctrl + F) and select “Search for text”. In the “Search direction” select “Entire block” and tick the “Ignore case” option. Then write “register” and click “OK”. You should see something similar to this:


Click on Ctrl + L(next match) until you get something that you think it may help us to crack the program. Well, I found “UnRegistered” on the address 0055F5D8. It may very well be a check that is done during the startup.. Double click on it. And boom, we get interesting stuff. We’re mainly interested on this:


CPU Disasm

Address   Hex dump          Command                                  Comments

0055F5BC  |.  E8 77C5F8FF   CALL 004EBB38

0055F5C1  |.  84C0          TEST AL,AL

0055F5C3  |.  74 10         JE SHORT 0055F5D5

0055F5C5  |.  8D45 FC       LEA EAX,[LOCAL.1]

0055F5C8  |.  8B55 E0       MOV EDX,DWORD PTR SS:[LOCAL.8]

0055F5CB  |.  8B52 08       MOV EDX,DWORD PTR DS:[EDX+8]

0055F5CE  |.  E8 3D6AEAFF   CALL 00406010

0055F5D3  |.  EB 0D         JMP SHORT 0055F5E2

0055F5D5  |>  8D45 FC       LEA EAX,[LOCAL.1]

0055F5D8  |.  BA 3CF75500   MOV EDX,0055F73C                         ; UNICODE “UnRegistered”

0055F5DD  |.  E8 A668EAFF   CALL 00405E88

0055F5E2  |>  8D55 D8       LEA EDX,[LOCAL.10]

0055F5E5  |.  33C0          XOR EAX,EAX


The instructions that first caught my attention were TEST AL,AL and the following. You should understand what the program is doing here..

The TEST AL,AL instruction tests the AL register against itself and if the result is zero it sets the ZF to 1, otherwise it clears it. The TEST instruction is pretty much an AND between two values. So.. Why do we have a JE instruction after a TEST? We should have it after a CMP(compare). It’s easy.. The JE(jump if equal) will check the state of the ZF flag. If ZF=1 it’ll jump for 0055F5D5, otherwise the program will continue normally. Well, let’s analyze things… If the JE is executed we’re in trouble because we jump exactly to the “UnRegistered” code. If not eventually the program will execute the JMP(jump) instruction at 0055F5D3 and it’ll jump the “UnRegistered” code. It seems like we have all the ingredients we need. Basically what we have to do is to make sure that the JE at 0055F5C3 is NOT executed. For that the ZF flag must be set to 0, in other words, the result of TEST AL, AL can’t be 0. How can all those things happen? The answer is just in the instruction above TEST AL, AL. The CALL instruction will jump to 004EBB38 and at some point you’ll find a RETN that will return the execution to 0055F5C1. Select the call instruction and press Enter. You should now get this:


CPU Disasm

Address   Hex dump          Command                                  Comments

004EBB38  /$  53            PUSH EBX

004EBB39  |.  56            PUSH ESI

004EBB3A  |.  8BF0          MOV ESI,EAX

004EBB3C  |.  837E 0C 00    CMP DWORD PTR DS:[ESI+0C],0

004EBB40  |.  74 3B         JE SHORT 004EBB7D

004EBB42  |.  8B46 08       MOV EAX,DWORD PTR DS:[ESI+8]

004EBB45  |.  E8 9E9FF1FF   CALL 00405AE8

004EBB4A  |.  50            PUSH EAX                                 ; /Arg3

004EBB4B  |.  8B46 48       MOV EAX,DWORD PTR DS:[ESI+48]            ; |

004EBB4E  |.  E8 959FF1FF   CALL 00405AE8                            ; |

004EBB53  |.  50            PUSH EAX                                 ; |Arg2

004EBB54  |.  68 84BB4E00   PUSH 004EBB84                            ; |Arg1 = VideoConverterUltimate.4EBB84

004EBB59  |.  8B46 0C       MOV EAX,DWORD PTR DS:[ESI+0C]            ; |

004EBB5C  |.  E8 879FF1FF   CALL 00405AE8                            ; |

004EBB61  |.  8BC8          MOV ECX,EAX                              ; |

004EBB63  |.  8B56 20       MOV EDX,DWORD PTR DS:[ESI+20]            ; |

004EBB66  |.  8B46 1C       MOV EAX,DWORD PTR DS:[ESI+1C]            ; |

004EBB69  |.  E8 CAF8FFFF   CALL 004EB438                            ; \VideoConverterUltimate.004EB438

004EBB6E  |.  8BD8          MOV EBX,EAX

004EBB70  |.  84DB          TEST BL,BL

004EBB72  |.  75 0B         JNE SHORT 004EBB7F

004EBB74  |.  8BC6          MOV EAX,ESI

004EBB76  |.  E8 39FDFFFF   CALL 004EB8B4                            ; [VideoConverterUltimate.004EB8B4

004EBB7B  |.  EB 02         JMP SHORT 004EBB7F

004EBB7D  |>  33DB          XOR EBX,EBX

004EBB7F  |>  8BC3          MOV EAX,EBX

004EBB81  |.  5E            POP ESI

004EBB82  |.  5B            POP EBX

004EBB83  \.  C3            RETN


There you have a RETN at 004EBB8. The program starts by pushing the EBX and ESI registers into the stack.You should know that usually we do this when we want to run a inner loop for example. When we want to proccess information in the outer loop we POP those registers. The interesting part is at 004EBB40, another JE instruction. If the JE is executed it jumps to 004EBB7D. XOR EBX,EBX sets the EBX register to 0. Then the value of EBX is copied to EAX and that value is returned(0). That is EXACLY what we don’t want(the value is returned in EAX). You probably already know how to fix this. We just need to force the JE instruction to be executed. For that we can simply replace the JE by a JMP. Select the JE instruction and press enter. Replace JE by JMP and click Enter. The instruction should turn red, meaning it was editted. The program will now jump to 004EBB7D. Now the last part.. If we let the program execute XOR EBX, EBX the function will return 0. We must place a different value into EBX. For doing that you can simply replace XOR EBX, EBX by MOV BL,1 or other number you want. With this EBX is 1 and the program will copy 1 to EAX, forcing the JE not to be executed. Select all this piece of code, left click, edit, copy to executable. A new window will pop up.. Left click again on that window and save file(with a different name). Open that exe file and voila! The program is assuming that you bought it! Now you can convert unlimited videos without any limitations 🙂 Two instructions that can save you 60$. In the next days I’ll write other posts showing you how to crack other programs(and probably some games to).

How to download videos from

I was just searching on the internet for some sites like YouTube and I found this one. It has an innovative design and a wide range of videos/episodes.

Usually I like to download videos from those sites and watch them later on my PC, and I try to avoid the available tools for download these videos.

After some research on the site I found a really simple method to download the videos.

Here how it’s done:


Imagine you want to download this video( The first thing you should take note is the video ID, in this case it is 6579050.


Take this as your base URL: and add the video ID. So the url is


Search for “media:content” and you’ll find mp4 and m4v files. Those are the URL’s. Now copy and paste that link and try to open. It’ll download a 37.5kb file saying that you need blip player to watch the video.

How to bypass that? It’s sooo simple. Just add “?showplayer=123(or any number)” and voila.. You can now download the video!



Download URL:

In the next few days I’ll post a downloader for this website, and possibly other(youtube, metacafe, vimeo, etc). The program will be open-source!


EDIT: Here you have it 🙂 Thanks to for building the regex expressions! You can download the binary file here:

Bit Positions problem from CodeEval explained

Recently I’ve been solving some problems from sites like usaco and CodeEval and I found this one in the “Easy” section! Well, this is actually a pretty easy problem to solve but some beginners might have some problems while solving this because it involves bitwise operators.

This is the problem description:

Challenge Description:

Given a number n and two integers p1,p2 determine if the bits in position p1 and p2 are the same or not. Positions p1,p2 and 1 based.

Input sample:

The first argument will be a text file containing a comma separated list of 3 integers, one list per line. e.g.


Output sample:

Print to stdout, ‘true'(lowercase) if the bits are the same, else ‘false'(lowercase).



So, if you’re reading this your problem might be: How do I compare two bits of a number? It’s simple! Let’s take a look at the first example, the number 86.

Number 86 it’s represented in binary as: 1010110

You could have calculated this easily by hand, doing successives divisions by 2 until the quotient was 0.

86/2 = 43 (Remainder is 0)

43/2 = 21 (Remainder is 1 because 43/2 = 2 * 21 + 1, where 1 is the remainder)

21/2 = 10 (Remainder is 1)

10/2 = 5 (Remainder is 0)

5/2 = 2 (Remainder is 1)

2/2 = 1 (Remainder is 0)

1/2 = 0 (Remainder is 1)

So “join” the remainder from bottom to top and you have the binary representation of 86: 1010110

Now the most important question.. How do you compare two bits of a decimal number?

It’s simple, using the bitwise operators! For this what you want to do is a right shift! Let me explain this better:

Imagine for the first case where you want to compare the 2nd and the 3rd binary digit(bit) of the number 86

You already know that the answer is “true” because 1(2nd digit) is equal to 1(3rd digit).

Here it’s the magic formula:

((86 >> 1) & 1) == ((86 >> 2) & 1)

If this is true then the digits are equal, if not they’re not equal.

I’ll now explain how this is done:

For the 2nd digit we start by doing a right shift of 1(86 >> 1)

I used 1 for the 2nd digit because in the statement it says that both bits are 1 based.

Original number: 1010110

After (86 >> 1): 0101011

0101011 & 1 = 1 But why?





With the AND operator the result is only 1 when both bits are 1!

Here it is the table:

0 0 Result: 0
0 1 Result: 0
1 0 Result: 0
1 1 Result: 1

For the second bit you do the same thing:

Original number: 1010110

After (86 >> 2): 0010101

0010101 & 1 = 1 for the same reason





1 == 1? Yes. So the answer is TRUE!

Here it is my poor C++(please go to here)