Contribute  :  Web Resources  :  Past Polls  :  Site Statistics  :  Downloads  :  Forum  
    BiW ReversingThe challenge is yours    
 Welcome to BiW Reversing
 Tuesday, March 31 2020 @ 10:00 PM CEST

Creating a simple standalone patcher

   

CodingLevel : newbie

OS : windows
Language : ASM

Once you patched a program you cracked, you might want to share it. Instead of uploading the entire executable, you can make a small patch that changes the neccessary bytes.


1. General Theory



Now how are we going to do that?

=> First we have to look for the file we have to patch. Most patches suppose that the file is in the same directory.

=> If it's there, we have to open it.

=> Next we should check if it's the exact same file as the one we cracked. We could eg. check the size, or some random bytes, or even better, the bytes we are going to patch.

=> If it is the same, we can do the neccessary adjustments : )
Put the filepointer on the right position, and write the new opcodes to it.

=> Close the file, and give a message about the status.

Take a program you just cracked, or use this example I will use.
Let's code this...

2. API Theory


What API's will we need to code this?

First of all, we will have to open the executable. The suitable API is :

HANDLE CreateFile(

LPCTSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
);

This API is used for opening, or creating a file.
dwDesiredAccess should be 'GENERIC_WRITE OR GENERIC_READ' because we want to read and write from/to the file.
dwShareMode = 'FILE_SHARE_WRITE OR FILE_SHARE_READ'
dwCreationDistribution = 'OPEN_EXISTING' We only want to open a file that is there. If it's not there, the function will fail, and we can give an Error Message.
Check your WIN32.HLP for details. If you don't have this API library, get it in the Reference section.
As you can see the API returns the handle of the file we requested. We need this handle for the next step : writing to the file.

BOOL WriteFile(

HANDLE hFile, // handle to file to write to
LPCVOID lpBuffer, // pointer to data to write to file
DWORD nNumberOfBytesToWrite, // number of bytes to write
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O
);


We will use this API to write the two bytes to the file (in the right place, of course :)
The handle hFile is the one CreateFile has returned.

lpOverlapped should point to an OVERLAPPED structure. We need this to put the filepointer at the right offset.

typedef struct _OVERLAPPED { // o
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
} OVERLAPPED;

Offset will contain the position where we want to write.

3. The Target


The Target is crackme5.exe, let's say we don't find a valid serial, and we want to patch it.
Of course you are a good cracker : ) and you found the bytes to patch quickly.
Here they are :

Offset 53Fh : 74h, 15h -> 90h, 90h

That's all the information we need : )

4. The Code

; Find the complete source and binary here :
;attachment


.386
.model flat,stdcall
option casemap:none 
include /masm32/include/windows.inc
include /masm32/include/user32.inc
include /masm32/include/kernel32.inc
includelib /masm32/lib/user32.lib
includelib /masm32/lib/kernel32.lib

.data 
FileName db "Crackme5.exe",0
AppName db "Crackme 5 Patch",0
Done db "File patched succesfully !",0
NoFile db "Can't find crackme5.exe !",0
ReFile db "Wrong version of crackme5.exe !",0
WrFile db "Error writing to crackme5.exe !",0
RBuffer db 75h, 15h
WBuffer db 90h,90h
OffsetPos OVERLAPPED <NULL,NULL,53Fh,NULL,NULL>

.data?

hInstance HINSTANCE ?
CommandLine LPSTR ?
hwndname HWND ?
hFile HANDLE ?
Numb dd ?
Buffer db 2 dup(?) 

.const

.code
start:

invoke GetModuleHandleA, NULL
mov hInstance,eax 

invoke CreateFile,ADDR FileName, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ OR FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL 

.IF eax!=INVALID_HANDLE_VALUE

    mov hFile, eax ; Store handle of file
    Invoke ReadFile, hFile, ADDR Buffer, 2, ADDR Numb, ADDR OffsetPos
    mov ax, word ptr [Buffer]     .IF ax == word ptr [RBuffer]
        Invoke WriteFile, hFile, ADDR WBuffer, 2, ADDR Numb, ADDR OffsetPos
        .IF Numb == 2
            push MB_OK
            push OFFSET AppName
            push OFFSET Done
        .ELSE 
            push MB_OK OR MB_ICONINFORMATION
             push OFFSET AppName
             push OFFSET WrFile
        .ENDIF       
    .ELSE 
          push MB_OK OR MB_ICONINFORMATION
          push OFFSET AppName
          push OFFSET ReFile        
    .ENDIF    

.ELSE 
      push MB_OK OR MB_ICONINFORMATION
      push OFFSET AppName
      push OFFSET NoFile  
.ENDIF

push NULL
Call MessageBox
invoke CloseHandle, hFile
invoke ExitProcess,eax

end start


If you understand the code above, which is self-explanatory, you can try to make a simular patch for another target.

Now you can make a simple WIN32ASM-patch. Of course we can also make a more user-friendly version eg. with an open-dialogbox to select the target. But that will be covered in a next tutorial about the subject : )

If you have questions, remarks about this tutorial, mail me!

Greetings,

Detten
Detten (at) reversing (dot) be




What's Related

Story Options

Creating a simple standalone patcher | 1 comments | Create New Account
The following comments are owned by whomever posted them. This site is not responsible for what they say.
Creating a simple standalone patcher
Authored by: g3nuin3 on Saturday, July 02 2005 @ 04:39 PM CEST
Hey detn can this be used to make a game patcher also?
 Copyright © 2020 BiW Reversing
 All trademarks and copyrights on this page are owned by their respective owners.
Powered By Geeklog 
Created this page in 0.76 seconds