我正在尝试扫描整个进程的内存,但是没有成功...我正在做的是:对于测试,我使用的是记事本,所以我在那儿写了%B,十六进制的值是:25(%)和42 (B)。所以代码是:
while (VirtualQueryEx(PIDHandle, Pointer(MemStart), MemInfo, SizeOf(MemInfo)) <> 0) do
begin
if ((MemInfo.State = MEM_COMMIT) and (not (MemInfo.Protect = PAGE_GUARD)
or (MemInfo.Protect = PAGE_NOACCESS)) and (MemInfo.Protect = PAGE_READWRITE)) then
begin
SetLength(Buff, MemInfo.RegionSize);
if (ReadProcessMemory(PIDHandle, MemInfo.BaseAddress, Buff,
MemInfo.RegionSize, ReceivedBytes)) then
begin
for I := 0 to SizeOf(Buff) do
begin
if (IntToHex(Buff[i], 1) = '25') and (IntToHex(Buff[i+2], 1) = '42') then
Form1.Memo1.Lines.Append(IntToHex(Buff[i], 1));
end;
end;
end;
MemStart:= MemStart + MemInfo.RegionSize;
end;
CloseHandle(PIDHandle);
end;
var'Buff'是TBytes(我读过有关TBytes的内容,并认为它与字节数组相同)。所以我将字节转换为十六进制,并搜索值:分别为25和42。代码如下:
if (IntToHex(Buff[i], 1) = '25') and (IntToHex(Buff[i+2], 1) = '42') then
因为十六进制值之间有00。因此,我需要添加“ +2”。如何扫描整个内存以获取这些值?
最佳答案
记事本使用Unicode,因此您需要查找UTF-16编码的数据$0025
和$0042
。
我不明白您为什么感到在比较之前需要转换为十六进制字符串。十六进制没有什么特别的要求使用字符串。十六进制只是一个以16为底的数字系统。因此,十进制32与十六进制20相同,即32=$20
。直接使用整数值进行比较:
if (Buff[i]=$25) and (Buff[i+2]=$42) then
就是说,考虑到
$00
字节,您的测试实际上应该是这样的:var
Target: string;
....
Target := '%B';
if CompareMem(@Buff[i], @Target[1], Length(Target)*SizeOf(Char)) then
....
我不想深入了解您的其余代码,但这行
for I := 0 to SizeOf(Buff) do
在许多不同层面上都是错误的。
SizeOf(Buff)
返回指针的大小,因为动态数组变量本质上只是一个指针。要记住的一个有用的事情是,SizeOf
是在编译时求值的。如果您使用
Length
而不是SizeOf
,那么您将遍历列表的末尾。要循环遍历动态数组,请从0
循环到Length(...)-1
。但是在这种情况下,您要在循环内访问索引
i+2
,因此您应该从0
循环到Length(...)-3
。但实际上,您需要与4个连续字节进行比较以找到匹配项。也许像这样:
TargetByteLength = Length(Target)*SizeOf(Char);
for i := 0 to Length(Buff)-TargetByteLength do
if CompareMem(@Buff[i], @Target[1], TargetByteLength) then
....