我以前写过一个修改其他程序内存的程序,当然要游戏还差很多。 基本上的思路是遍历整个部标程序地址空间,查找要修改的数据地址。 若第一次找到数个地址,那就更改目标数据(地址不会变,全局变量)再次查找。 用到几个api,比如VirtualQueryEx,ReadProcessMemory,WriteProcessMemory。 var p : Pointer; mi : MEMORY_BASIC_INFORMATION; x,GG : longword; lPbaseAddr : Pointer; lPBuffer : array[0..3] of BYTE;while longword(p)<$80000000do begin if (x<>VirtualQueryEx(Handle_Share,p,mi,x)) then break; if (mi.State = MEM_COMMIT) and (mi.Protect = PAGE_READWRITE) then begin GG := mi.RegionSize; lPbaseAddr := p; while GG > 0 do begin if ReadProcessMemory(Handle_Share,lPbaseAddr,@lpBuffer,4,j) then begin agm := @lpBuffer; if agm^ = ShareData then begin // // showmessage(format('%x',[longword(lPbaseAddr)])+' '+inttostr(agm^)); New(op); op^.Data := LongWord(agm^); op^.Address := Longword(lpBaseAddr); LT.Add(op); end; end; //if ReadProcessMemory(GetCurrentProcess,lPbaseAddr,@lpBuffer,4,j) inc(longword(lpbaseaddr),4); Dec(GG,4); end; //while GG > 0 end; //if (mi.State = MEM_COMMIT) and (mi.Protect = PAGE_READWRITE) inc(longword(p),mi.RegionSize); // showmessage(format('%x',[longword(P)])); // end; //with ListView1.Items.Add do end; 其实遍历很简单,我的代码写的凌乱又松散,不过意思是这个意思。 另外我的程序只是读 integer 类型用的,要修改游戏,应该还要停止所有的线程,改完数据后要用 SetForegroundWindow(游戏.handle)才行,否则会挂掉。
基本上的思路是遍历整个部标程序地址空间,查找要修改的数据地址。
若第一次找到数个地址,那就更改目标数据(地址不会变,全局变量)再次查找。
用到几个api,比如VirtualQueryEx,ReadProcessMemory,WriteProcessMemory。
var
p : Pointer;
mi : MEMORY_BASIC_INFORMATION;
x,GG : longword;
lPbaseAddr : Pointer;
lPBuffer : array[0..3] of BYTE;while longword(p)<$80000000do
begin
if (x<>VirtualQueryEx(Handle_Share,p,mi,x)) then break;
if (mi.State = MEM_COMMIT) and (mi.Protect = PAGE_READWRITE) then begin
GG := mi.RegionSize;
lPbaseAddr := p;
while GG > 0 do begin
if ReadProcessMemory(Handle_Share,lPbaseAddr,@lpBuffer,4,j) then begin
agm := @lpBuffer;
if agm^ = ShareData then begin //
// showmessage(format('%x',[longword(lPbaseAddr)])+' '+inttostr(agm^));
New(op);
op^.Data := LongWord(agm^);
op^.Address := Longword(lpBaseAddr);
LT.Add(op);
end;
end; //if ReadProcessMemory(GetCurrentProcess,lPbaseAddr,@lpBuffer,4,j) inc(longword(lpbaseaddr),4);
Dec(GG,4); end; //while GG > 0
end; //if (mi.State = MEM_COMMIT) and (mi.Protect = PAGE_READWRITE)
inc(longword(p),mi.RegionSize);
// showmessage(format('%x',[longword(P)]));
// end; //with ListView1.Items.Add do
end;
其实遍历很简单,我的代码写的凌乱又松散,不过意思是这个意思。
另外我的程序只是读 integer 类型用的,要修改游戏,应该还要停止所有的线程,改完数据后要用
SetForegroundWindow(游戏.handle)才行,否则会挂掉。