如何取得某个程序在内存中的偏移地址

fffddd 2004-03-17 12:02:31
我的程序为A另一程序为B
打开B之后,我用我的A程序如何读B程序的内存变量?
有人说用ReadProcessMemory读,但要知道内存偏移地址,所以想请教各位如何取得B程序的内存偏移地址。谢谢!
...全文
130 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
yansea 2004-03-19
  • 打赏
  • 举报
回复
可以用TLHelp32下的Module32First/Moudule32Next函数
naughtyboy 2004-03-19
  • 打赏
  • 举报
回复
0x7FFFFFFF-0x00400000为每个进程的WIN32专用地址
也就是说你以0x00400000为基址,offset自己来设定就行了
fffddd 2004-03-18
  • 打赏
  • 举报
回复
我是想知道如何取得内存中的某个文件的起始地址。
loveyankee 2004-03-17
  • 打赏
  • 举报
回复
你理解错别人的意思了
一个程序一旦创建了进行,操作系统便会为其分配4GB的虚拟内存空间,而这其4G中有不到2G是程序自己的私有空间,它的一切数据都在这里
所以你需要得到B的变量数据,需要在A中找到B的进程ID,通过进程ID得到进行句柄,然后你就可以通过ReadProcessMemory来读取了

不过有个问题就是,一般来说程序每次运行时它的数据在虚拟内存里的offset都不是固定的,你需要找到其他的一些固定参考点或者进行搜索才能得到你想要的东西

以下是给你的一点参考,效率不高,但是却能让你明白其中的一些过程

function GetPID:THandle;
var
lppe: tprocessentry32;
sshandle: thandle;
found: boolean;
begin
result:=0;
sshandle := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
found := process32first(sshandle, lppe);
while found do
begin
if ansiCompareText(ExtractFileName(lppe.szExefile),'hypertrm.exe') = 0 then
begin
result:=lppe.th32ProcessID;
break;
end;
found := process32next(sshandle, lppe);
end;
CloseHandle(sshandle);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
ProcessHandle , MyHandle: THandle;
lpBuffer: pchar;
nSize: DWORD;
lpNumberOfBytes: DWORD;
i,n: integer;
addr:dword;
r,s,t: string;
mbi_thunk:TMemoryBasicInformation;
dwOldProtect:dword;
begin
MyHandle := GetPID;
ShowMessage(inttostr(MyHandle));
if GetPID<>0 then
begin
Memo1.Lines.Clear;
Memo2.Lines.Clear;
Memo3.Lines.Clear;
ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, false, MyHandle);
addr:=HexToInt('00AB7000');
nSize:=HexToInt('00AB8FFF')-addr+1;
lpBuffer := AllocMem(nSize);
if(not ReadProcessMemory(ProcessHandle, Pointer(addr), lpBuffer, nSize, lpNumberOfBytes))
or(nSize<>lpNumberOfBytes) then
begin
showmessage('读数据出错,可能是指定的地址不存在.');
exit;
end;
s:='';
t:='';
r:='';
for i :=0 to nSize-1 do
begin
s := s + format('%.2X ',[ord(lpBuffer[i])]);
n:= HextoInt(Trim(RightStr(S,3)));
t:=t + InttoStr(n) + ' ';
if Trim(RightStr(S,3)) = '00' then r := r + '@ '
else r:=r + CHR(n) + ' ';
if ((i mod 16 ) = 15) or (i=nSize-1) then
begin
Memo1.Lines.Add(s);//从内存中读取到的16进制数据
Memo2.Lines.Add(t);//转换成为ASSII的数据
Memo3.Lines.Add(r);//转换为字符后的数据,空数据用@表示
s := '';
t := '';
r := '';
end;
end;
FreeMem(lpBuffer, nSize);
CloseHandle(ProcessHandle);
Form1.Caption:='获取当前'+IntToStr(nSize)+'位内存数据';
end;
end;
loveyankee 2004-03-17
  • 打赏
  • 举报
回复

上面有点错别字,个别词写错了
但是我实在不知道该怎么修改帖子,晕了
上面是一个获取hypertrm.exe中从00AB7000到00AB8FFF中所有数据的一个例子

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧