invoke ReadProcessMemory,hProcess,lpBaseAddress,lpBuffer,dwSize,lpNumberOfBytesReadinvoke WriteProcessMemory,hProcess,lpBaseAddress,lpBuffer,dwSize,lpNumberOfBytesWritten
hProcess 指定將要被讀寫的目標進程句柄
lpBaseAddress 目標進程中被讀寫的起始線性地址.
lpBuffer 用來接受數據的緩沖區
dwSize要讀取的字節數
lpNumberOfBytesRead 或 lpNumberOfBytesWritten 指向一個雙字變量,用來供函數返回實際讀寫的字節數,如果不關心讀寫結果,可以在這里使用NULL
?
如果函數執行成功則返回非0值,否則返回0
?
注意
(1)lpBaseAddress 和 lpBuffer參數指向的地址位于不同的進程空間內,lpBuffer指向的緩沖區位于自身進程地址空間中,lpBaseAddress指向的地址位于目標進程的地址空間內
(2)要對 目標進程的地址空間進行讀寫,必須具備PROCESS_VM_READ或PROCESS_VM_WRITE或PROCESS_VM_OPERATION
(3)lpBaseAddress位置開始的dwSize大小的內存必須可存取的,函數在執行前會對整個區域進行測試,如果中間有某處是不可存取的,(如沒有遞交到物理內存),那么函數直接返回失敗
,所以一般不會出現只讀寫了一部分內存的情況
(4)在ring3級下,自己進程中,代碼段是不可寫的,但使用WriteProcessMemory函數是 可以去寫目標進程的代碼段是允許的
也不是一定不能寫自己的代碼段,可以通過修改PE導入表中的屬性來達到自己可寫的目的
?
下面給出一個內存補丁的例子
.386
.model flat,stdcall
option casemap:noneinclude windows.incinclude kernel32.incinclude user32.incincludelib user32.libincludelib kernel32.lib
L MACRO var:VARARG
local lbl
.constlbl db var,0
.codeexitm <offset lbl>
ENDM
.code
start:xor eax,eax.if eaxinvoke MessageBox,NULL,L("您使用的是正版軟件"),L("Caption"),MB_OK.elseinvoke MessageBox,NULL,L("您所使用的是盜版軟件"),L("錯誤"),MB_OK.endifinvoke ExitProcess,NULL
end start
?
?可以通過OD等軟件來查看.if eax的語句的地址....
?
;--------------------------------------------------------------------------------
;程序環境設置
.386
.model flat,stdcall
option casemap:none
;--------------------------------------------------------------------------------
;頭文件與庫文件導入
include windows.inc
include kernel32.inc
include user32.incincludelib kernel32.lib
includelib user32.lib
;--------------------------------------------------------------------------------
;函數定義
;--------------------------------------------------------------------------------
;等值替換定義
PATCH_POSITION equ 00401014h
;--------------------------------------------------------------------------------
;宏定義
L macro var:VARARGLOCAL @lbl.const@lbl db var,0.codeexitm <offset @lbl>
endm
;--------------------------------------------------------------------------------
;包含文件
;--------------------------------------------------------------------------------
;已初始化數據段
.data
;--------------------------------------------------------------------------------
;未初始化數據段
.data?
dwOldBytes db 2 dup(?)
stStartUp STARTUPINFO <?>
stProcessInfo PROCESS_INFORMATION <?>
;--------------------------------------------------------------------------------
;常量段
.const
dbPatched db 90h,90h
dbPatch db 74h,15h
;--------------------------------------------------------------------------------
;代碼段
.code
start:invoke GetStartupInfo,addr stStartUpinvoke CreateProcess,L("Test.exe"),NULL,NULL,NULL,NULL,NORMAL_PRIORITY_CLASS or CREATE_SUSPENDED,0,0,offset stStartUp,offset stProcessInfo.if eaxinvoke ReadProcessMemory,stProcessInfo.hProcess,PATCH_POSITION,addr dwOldBytes,2,NULL.if eaxmov ax,word ptr dwOldBytes.if ax == word ptr dbPatchinvoke WriteProcessMemory,stProcessInfo.hProcess,PATCH_POSITION,addr dbPatched,2,NULLinvoke ResumeThread,stProcessInfo.hThread.elseinvoke TerminateProcess,stProcessInfo.hProcess,-1invoke MessageBox,NULL,L("可執行文件版本不正確"),NULL,MB_OK or MB_ICONSTOP.endif.endifinvoke CloseHandle,stProcessInfo.hProcessinvoke CloseHandle,stProcessInfo.hThread.elseinvoke MessageBox,NULL,L("無法加載執行文件 或 可執行文件沒有找到"),NULL,MB_OK or MB_ICONSTOP.endifinvoke ExitProcess,NULL;--------------------------------------------------------------------------------
end start ;函數入口地址