内存读取

在WIN32中,每个应用程序都可“看见”4GB的线性地址空间,其中最开始的4MB和最后的2GB由操作系统保留,剩下不足2GB的空间用于应用程序私有空间。
具体分配如下:
0xFFFFFFFF-0xC0000000的1GB用于VxD、存储器管理和文件系统;
0xBFFFFFFF-0x80000000的1GB用于共享的WIN32 DLL、存储器映射文件和共享存储区;
0x7FFFFFFF-0x00400000为每个进程的WIN32专用地址;
0x003FFFFF-0x00001000为MS-DOS 和 WIN16应用程序;
0x00000FFF-0x00000000为防止使用空指针的4,096字节。
以上都是指逻辑地址,也就是虚拟内存。 
虚拟内存通常是由固定大小的块来实现的,在WIN32中这些块称为“页”,每页大小为4,096字节。
在 Intel CPU结构中,通过在一个控制寄存器中设置一位来启用分页。
启用分页时CPU并不能直接访问内存,对每个地址要经过一个映射进程,通过一系列称作“页表”的查找表把虚拟内存地址映射成实际内存地址。
通过使用硬件地址映射和页表WIN32可使虚拟内存即有好的性能而且还提供保护。
利用处理器的页映射能力,操作系统为每个进程提供独立的从逻辑地址到物理地址的映射,
使每个进程的地址空间对另一个进程完全不可见。WIN32中也提供了一些访问进程内存空间的函数,但使用时要谨慎,一不小心就有可能破坏被访问的进程。
本文介绍如何读另一个进程的内存,写内存与之相似,完善一下你也可以做个 FPE 之类的内存修改工具。好吧,先准备好编程利器Delphi 和 参考手册 MSDN ,Now begin 
{=============================================} 
{=============的到进程的ID=====================} 
{=============================================} 
function TReadMemory.GetProcessInfo: TList; 
var 
ProcessInfoList : TList; 
ProcessInfo : PProcessInfo; 
hSnapShot : THandle; 
mProcessEntry32 : TProcessEntry32; 
bFound : Boolean; 
begin 
ProcessInfoList:=TList.Create; 
ProcessInfoList.Clear; 
hSnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); 
mProcessEntry32.dwSize := Sizeof(mProcessEntry32); 
bFound := Process32First(hSnapShot, mProcessEntry32); 
while bFound do 
begin 
New(ProcessInfo); 
ProcessInfo.ProcessExe := mProcessEntry32.szExeFile; 
ProcessInfo.ProcessId := mProcessEntry32.th32ProcessID; 
ProcessInfoList.Add(ProcessInfo); 
bFound := Process32Next(hSnapShot, mProcessEntry32); 
end; 
Result := ProcessInfoList; 
end; 
本文来自Delphi之窗,原文地址:http://www.52delphi.com






这里用到 
1:CreateToolhelp32Snapshot()创建系统快照句柄(hSnapShot是我们声明用来保存 
创建的快照句柄) 
2:Process32First、Process32Next是用来枚举进程 
{=============================================} 
{=============内存查找=========================} 
{=============================================} 
function TReadMemoryFrm.StartSearch: Boolean; 
var 
ProcHandle:Integer; 
begin 
Result:=False; 
ReadMemoryProgress.Position:=0; 
if Not CheckInput then Exit; 


if FileName=TabSheet1.Caption then //-------------搜索次数>1次 
begin 
PParameter.FirstSearch:=False; 
PParameter.Data:=StrToInt(EdtSearchData.Text); 
end else 
begin //------------------------------第一次搜索 
PParameter.FirstSearch:=True; 
if PParameter.ProcessHandle>0 then 
CloseHandle(PParameter.ProcessHandle); 
ProcHandle:=OpenProcess(PROCESS_ALL_ACCESS,false,StrToInt(EdtProcID.Text)); 
if ProcHandle>0 then 
begin 
PParameter.Data:=StrToInt(EdtSearchData.Text); 
Case DataType.ItemIndex of 
0:PParameter.DataType:=1; 
1:PParameter.DataType:=2; 
2:PParameter.DataType:=4; 
end; 
end else Exit; 
FileName:=TabSheet1.Caption; 
PParameter.ProcessHandle:=ProcHandle; 
end; 


SearchButton.Enabled:=False; 
ToolSearchMemory.Enabled:=False; 
MemoryAddrList.Clear; 
PReadMemory.StartSearch; 
Result:=True; 
end; 


1: 
HANDLE OpenProcess( 
DWORD dwDesiredAccess, // 希望获得的访问权限 
BOOL bInheritHandle, // 指明是否希望所获得的句柄可以继承 
DWORD dwProcessId // 要访问的进程ID 
); 


分析内存块 
//----------------------------------------------------分析内存块 
function TReadMemoryThread.GetMemoryRegion: Boolean; 
var 
TempStartAddress : DWord; 
TempEndAddress : DWord; 
I,J,k : Integer; 
NewMemoryRegions : array [0..40000] of TmemoryRegion; 
begin 
Result:=False; 
MemoryRegionsIndex := 0; 
TempStartAddress := 1*1024*1024; 
TempEndAddress := 2*1024*1024; 
TempEndAddress := TempEndAddress*1024; 
While (VirtualQueryEx(PParameter.ProcessHandle, 
pointer(TempStartAddress), 
MBI, 
sizeof(MBI))>0) and (TempStartAddress<TempEndAddress) do 
begin 
if (MBI.State=MEM_COMMIT) then 
begin 
if (MBI.Protect=PAGE_READWRITE) or 
(MBI.Protect=PAGE_WRITECOPY) or 
(MBI.Protect=PAGE_EXECUTE_READWRITE) or 
(MBI.Protect=PAGE_EXECUTE_WRITECOPY) 
then 
begin 
PMemoryRegion[MemoryRegionsIndex].BaseAddress:=Dword(MBI.BaseAddress); 
PMemoryRegion[MemoryRegionsIndex].MemorySize:=MBI.RegionSize; 
Inc(MemoryRegionsIndex); 
end; 
end; 
TempStartAddress:=Dword(MBI.BaseAddress)+MBI.RegionSize; 
end; 
if MemoryRegionsIndex=0 then Exit; 
//---------------------------------------------判断内存块是否过大 
J:=0; 
for i:=0 to MemoryRegionsIndex-1 do 
begin 
if PMemoryRegion[i].MemorySize>$FFFF then 
begin 
for K:=0 to PMemoryRegion[i].MemorySize div $FFFF do 
begin 
if K=PMemoryRegion[i].MemorySize div $FFFF+1 then 
begin 
NewMemoryRegions[j].BaseAddress:=PMemoryRegion[i].BaseAddress+K*$FFFF; 
NewMemoryRegions[j].MemorySize:=PMemoryRegion[i].MemorySize Mod $FFFF; 
end else 
begin 
NewMemoryRegions[j].BaseAddress:=PMemoryRegion[i].BaseAddress+K*$FFFF; 
NewMemoryRegions[j].MemorySize:=$FFFF; 
end; 
Inc(J); 
end; 
end else 
begin 
NewMemoryRegions[j].BaseAddress:=PMemoryRegion[i].BaseAddress; 
NewMemoryRegions[j].MemorySize:=PMemoryRegion[i].MemorySize; 
Inc(J); 
end; 
end; 
//---------------------------------------------------数据转换 
MemoryRegionsIndex:=j; 
for i:=0 to MemoryRegionsIndex-1 do 
begin 
PMemoryRegion[i].MemorySize:=NewMemoryRegions[i].MemorySize; 
PMemoryRegion[i].BaseAddress:=NewMemoryRegions[i].BaseAddress; 
end; 
Result:=True; 
end; 
1:查找的内存大小 
TempStartAddress := 1*1024*1024; 
TempEndAddress := 2*1024*1024; 
TempEndAddress := TempEndAddress*1024; 


2:VirtualQueryEx :查询地址空间中内存地址的信息。 
参数: 
hProcess 进程句柄。 
LpAddress 查询内存的地址。 
LpBuffer 指向MEMORY_BASIC_INFORMATION结构的指针,用于接收内存信息。 
DwLength MEMORY_BASIC_INFORMATION结构的大小。 
本文来自Delphi之窗,原文地址:http://www.52delphi.com






返回值: 
函数写入lpBuffer的字节数,如果不等于sizeof(MEMORY_BASIC_INFORMATION)表示失败。  
{=============================================} 
{=============开始查找=========================} 
{=============================================} 
procedure TReadMemoryThread.Execute; 
var 
//StopAddr,StartAddr:Dword; 
BeginTime,EndTime:String; 
I:Integer; 
begin 
inherited; 
while Not Terminated do 
begin 
AddrCount := 0; 
if PParameter.FirstSearch then 
begin 
if Not GetMemoryRegion then Exit; 
GetMaxMemoryRange; 
GetMinMemoryRange; 
SendMessage(APPHandle,WM_READMEMORY,RM_MAXPROGRESS,MemoryRegionsIndex); 
BeginTime:=FloatToStr(CPUTimeCounterQPC); 
for I:=0 to MemoryRegionsIndex-1 do 
begin 
FirstCheckMemory(PMemoryRegion[i].BaseAddress,PMemoryRegion[i].MemorySize); 
end; 
EndTime:=FloatToStr(CPUTimeCounterQPC); 
SendMessage(APPHandle, 
WM_READMEMORY, 
RM_USETIME, 
StrToInt(Copy(EndTime,1,Pos('.',EndTime)-1))-StrToInt(Copy(BeginTime,1,Pos('.',BeginTime)-1))); 
SendMessage(APPHandle,WM_READMEMORY,RM_ADDRCOUNT,AddrCount); 
SendMessage(APPHandle,WM_READMEMORY,RM_FINISH,RM_FINISH); 
end else 
begin 
SendMessage(APPHandle,WM_READMEMORY,RM_MAXPROGRESS,100); 
BeginTime:=FloatToStr(CPUTimeCounterQPC); 
for i:=0 to High(PSearchAgain) do 
begin 
SecondCheckMemory(PSearchAgain[i].DataAddr); 
end; 
EndTime:=FloatToStr(CPUTimeCounterQPC); 
SendMessage(APPHandle, 
WM_READMEMORY, 
RM_USETIME, 
StrToInt(Copy(EndTime,1,Pos('.',EndTime)-1))-StrToInt(Copy(BeginTime,1,Pos('.',BeginTime)-1))); 
SendMessage(APPHandle,WM_READMEMORY,RM_ADDRCOUNT,AddrCount); 
SendMessage(APPHandle,WM_READMEMORY,RM_FINISH,RM_FINISH); 
end; 
Suspend; 
end; 
end;   


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值