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: https://copy.com/iOP0gsjdJ6pU (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.


Posted on 21 de Agosto de 2013, in Sem categoria. Bookmark the permalink. Deixe um comentário.

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão /  Alterar )

Google+ photo

Está a comentar usando a sua conta Google+ Terminar Sessão /  Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão /  Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão /  Alterar )


Connecting to %s

%d bloggers like this: