beta.blog

Programming

FASM: WriteProcessMemory

by on Sep.18, 2011, under Programming

The following sample code demonstrates how to use WriteProcessMemory in FASM.
The sample code also covers a way of using VirtualAllocEx.

format PE GUI 4.0
entry start

include 'win32a.inc'

;================== code =====================
section '.code' code readable executable
;=============================================

proc start

        invoke FindWindow, NULL, WindowTitle           ; Find the window titled 'Notepad'
        test eax,eax                                   ; Test whether a window with that title was found or not
        jnz .ju1                                       ; Don't jump = The window was not found
        invoke MessageBox,0, message1, caption, MB_OK  ; - Display an error message (Window not found)
        jmp .exit                                      ; - Exit the application
.ju1:                                                  ; Jumped     = The window was found
        invoke GetWindowThreadProcessId, eax, ProcID   ; Get the ProcessID via the window handle
        invoke OpenProcess, 0x1F0FFF, FALSE, [ProcID]  ; Open the process using PROCESS_ALL_ACCESS (0x1F0FFF) and get a handle
        mov dword[ProcHandle],eax                      ; Save the handle

        ; VirtualAllocEx: Reserves/commits a region of memory within the virtual address space of out target process
        ; We should do this in order to avoid potential access violations (which might cause crashes)
        invoke VirtualAllocEx,dword [ProcHandle], 0, patchSize, MEM_COMMIT, PAGE_READWRITE
        cmp eax, 0                                     ; EAX == 0 : Failed to reserve the memory region
        jnz .cont                                      ; EAX != 0 : Continue with further steps
        invoke MessageBox,0, message4, caption, MB_OK  ; Display an error: VirtualAllocEx failed to reserve the memory region
        jmp .exit                                      ; Exit the application
.cont:
        invoke WriteProcessMemory, dword[ProcHandle], dword[startAddress], patchBytes, patchSize, patchResult
        cmp [patchResult],patchSize                    ; Compare the number of patched bytes with the length of our new bytes
        je .ju2                                        ; Don't jump = Failed to patch the target
        invoke MessageBox,0, message3, caption, MB_OK  ; - Display an error message (An error occured)
        jmp .exit                                      ; - Exit the application
.ju2:                                                  ; Jumped     = Target patched successfully.
        invoke MessageBox,0, message2, caption, MB_OK  ; Display: The target has been patched successfully
.exit:                                                 ; Jumper: Here we're going to exit our application
        invoke  ExitProcess, 0                         ; ExitProcess

endp

;=================== data ====================
section '.data' data readable writeable
;=============================================

WindowTitle     db 'Notepad', 0                        ; Holds the window title   of the target application
ProcID          dd ?                                   ; Holds the process ID     of the target application
ProcHandle      db ?                                   ; Holds the process handle of the target application

caption         db 'Information', 0                    ; The caption displayed in all MessageBoxes
message1        db 'Unable to find the window', 0      ; Message: Window not found
message2        db 'Patched successfully',0            ; Message: Target patched successfully
message3        db 'Patching: An error occured',0      ; Message: An error occured while patching the target
message4        db 'VirtualAllocEx failed',0           ; Message: Failed to successfully execute VirtualAllocEx

startAddress    dd 0x00401090                          ; The memory address we're starting to write from
patchBytes      db 0x2F,0x66                           ; These bytes will be written into the memory of our target executable
patchSize       =  $ - patchBytes                      ; Holds the number of bytes we're going to write
patchResult     dd ?                                   ; Holds the number of successfully written bytes

;=============================================
section '.idata' import data readable
;=============================================

library         kernel32,'KERNEL32.DLL',\
                user32,'USER32.DLL'

import          kernel32,\
                ExitProcess,'ExitProcess',\
                OpenProcess,'OpenProcess',\
                VirtualAllocEx, "VirtualAllocEx",\
                WriteProcessMemory,'WriteProcessMemory'

import          user32,\
                FindWindow,'FindWindowA',\
                GetWindowThreadProcessId,'GetWindowThreadProcessId',\
                MessageBox,'MessageBoxA'
1 Comment more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!