DELPHI实现游戏内存的修改

要修改指定程序的指定地址数据,我们需要用到两个api函数,分别是ReadProcessMemory和WriteProcessMemory。

下载是函数的定义:

BOOL ReadProcessMemory(  
  HANDLE hProcess,  
  LPCVOID lpBaseAddress,  
  LPVOID lpBuffer,  
  SIZE_T nSize,  
  SIZE_T
*  lpNumberOfBytesRead  
);  
Parameters  
  
hProcess  
[
in ] A handle to the process with memory that  is  being read. The handle must have PROCESS_VM_READ access to the process.  
lpBaseAddress  
[
in ] A pointer to the  base  address  in  the specified process from which to read. Before any data transfer occurs, the system verifies that all data  in  the  base  address and memory of the specified size  is  accessible  for  read access, and  if  it  is  not accessible the function fails.  
lpBuffer  
[
out ] A pointer to a buffer that receives the contents from the address space of the specified process.  
nSize  
[
in ] The number of bytes to be read from the specified process.  
lpNumberOfBytesRead  
[
out ] A pointer to a variable that receives the number of bytes transferred into the specified buffer. If lpNumberOfBytesRead  is  NULL, the parameter  is  ignored.  
Return Value  
  
If the function succeeds, the 
return  value  is  nonzero.  
  
If the function fails, the 
return  value  is   0  (zero). To  get  extended error information, call GetLastError.  
  
The function fails 
if  the requested read operation crosses into an area of the process that  is  inaccessible.  
  
WriteProcessMemory  
  
Writes data to an area of memory 
in  a specified process. The entire area to be written to must be accessible or the operation fails.  
  
BOOL WriteProcessMemory(  
  HANDLE hProcess,  
  LPVOID lpBaseAddress,  
  LPCVOID lpBuffer,  
  SIZE_T nSize,  
  SIZE_T
*  lpNumberOfBytesWritten  
);  
Parameters  
  
hProcess  
[
in ] A handle to the process memory to be modified. The handle must have PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process.  
lpBaseAddress  
[
in ] A pointer to the  base  address  in  the specified process to which data  is  written. Before data transfer occurs, the system verifies that all data  in  the  base  address and memory of the specified size  is  accessible  for  write access, and  if  it  is  not accessible, the function fails.  
lpBuffer  
[
in ] A pointer to the buffer that contains data to be written  in  the address space of the specified process.  
nSize  
[
in ] The number of bytes to be written to the specified process.  
lpNumberOfBytesWritten  
[
out ] A pointer to a variable that receives the number of bytes transferred into the specified process. This parameter  is  optional. If lpNumberOfBytesWritten  is  NULL, the parameter  is  ignored.  
Return Value  
  
If the function succeeds, the 
return  value  is  nonzero.  
  
If the function fails, the 
return  value  is   0  (zero). To  get  extended error information, call GetLastError. The function fails  if  the requested write operation crosses into an area of the process that  is  inaccessible.  

 

 

下面以星际争霸的矿石修改为例,简述这两个函数的用法。

先获取当前的矿石数,用ReadProcessMemory

ReadProcessMemory(h, ptr(GoldA + i * 4), @Gold, 4, tt);

h是程序进程的句柄,其中GoldA就是地址偏移基准数值,@Gold是一个byte型的数组buffer,读取到的数据也就存放在里面,接下来的4表示buffer的长度,最后的tt是传出值,它显示了成功读取的长度。

好了,现在读取到了,我们把@Gold的值进行一番修改后,再写回去,使用WriteProcessMemory方法

WriteProcessMemory(h, ptr(GoldA + i * 4), @Gold, 4, tt);

与上面的Read过程一模一样,这样就能够写回去了。

下面附上一段完整代码 

procedure  TFormMain.Cheat113;  
var   
hw: HWND;  
pid: DWord;  
h: THandle;  
tt: Cardinal;  
Gold: 
array [ 0 .. 3 of  byte;  
Gas: 
array [ 0 .. 3 of  byte;  
GoldA: integer;  
GasA: integer;  
i: integer;  
const   
Gold130 
=  $ 508600 ;  
Gas130 
=  $ 508630 ;  
begin   
hw :
=  FindWindow( nil ' Brood War ' );  
if  hw  =   0   then   
    Exit;  
GetWindowThreadProcessId(hw, @pid);  
h :
=  OpenProcess(PROCESS_ALL_ACCESS, false, pid);  
if  h  =   0   then   
    Exit;  
Gold[
0 ] : =  $FF;  
Gold[
1 ] : =  $FF;  
Gold[
2 ] : =  $ 00 ;  
Gold[
3 ] : =  $ 00 ;  
Gas[
0 ] : =  $FF;  
Gas[
1 ] : =  $FF;  
Gas[
2 ] : =  $ 00 ;  
Gas[
3 ] : =  $ 00 ;  
GoldA :
=  Gold130;  
GasA :
=  Gas130;  
if  (chkMineral.Enabled)  and  (chkMineral.Checked)  then   
begin   
    
for  i : =   0   to   11   do   
    
begin   
      WriteProcessMemory(h, ptr(GoldA 
+  i  *   4 ), @Gold,  4 , tt);  
    
end ;  
end ;  
if  (chkGas.Enabled)  and  (chkGas.Checked)  then   
begin   
    
for  i : =   0   to   11   do   
    
begin   
      WriteProcessMemory(h, ptr(GasA 
+  i  *   4 ), @Gas,  4 , tt);  
    
end ;  
end ;  
CloseHandle(h);  
end ;    

转载于:https://www.cnblogs.com/rogee/archive/2010/09/15/1827438.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值