为什么要区别是否是第一次搜索?因为第一次搜索是在整个进程可访问内存范围内查找,而之后的查找是基于第一次找到的地址。这样做不是唯一的,但是最好的方法。
下面是搜索按钮单击的事件处理代码:
private void button1_Click(object sender, EventArgs e)
{
if (_selectedProcess == null) return;
if (isFirstSearch)
{
uint baseAddr = 0x00010000;
uint endAddr = 0x7ffeffff;
for (uint i = baseAddr; i < endAddr; i += (4 * 1024))
{
var addrs = CreateAddrList(new IntPtr(i), int.Parse(textBox1.Text));
if (addrs !=null )
_addrList.AddRange( addrs);
}
isFirstSearch = false;
}
else
{
RefreshAddrList(int.Parse(textBox1.Text));
}
label2.Text = "找到结果”+ _addrList.Count.ToString() + "个";
if (_addrList.Count == 1)
textBox2.Enabled = true;
}
{
if (_selectedProcess == null) return;
if (isFirstSearch)
{
uint baseAddr = 0x00010000;
uint endAddr = 0x7ffeffff;
for (uint i = baseAddr; i < endAddr; i += (4 * 1024))
{
var addrs = CreateAddrList(new IntPtr(i), int.Parse(textBox1.Text));
if (addrs !=null )
_addrList.AddRange( addrs);
}
isFirstSearch = false;
}
else
{
RefreshAddrList(int.Parse(textBox1.Text));
}
label2.Text = "找到结果”+ _addrList.Count.ToString() + "个";
if (_addrList.Count == 1)
textBox2.Enabled = true;
}
很明显CreateAddrList是第一次查找掉用的方法,RefreshAddrList是之后查找调用的方法。在第一次查找中,我们以4KB作一次跳跃。为什么查找的地址范围如此本文开始已作说明,这里就不再赘述。
好了,现在来看看CreateAddrList方法:
private List<IntPtr> CreateAddrList(IntPtr baseAddr, int value)
{
int bytesRead;
byte[] buffer = new byte[4096];
bool ok;
List<IntPtr> result = new List<IntPtr>();
ok = ReadProcessMemory(_selectedProcess.Handle, baseAddr, buffer, 4096, out bytesRead);
if (!ok)
return null ;
int currentVal;
for (int i = 0; i < 4096 - 3; i++)
{
currentVal = BitConverter.ToInt32(buffer, i);
if (currentVal == value)
{
IntPtr addr = new IntPtr(baseAddr.ToInt32() + i);
result.Add(addr);
i += 3;
}
}
return result;
}
{
int bytesRead;
byte[] buffer = new byte[4096];
bool ok;
List<IntPtr> result = new List<IntPtr>();
ok = ReadProcessMemory(_selectedProcess.Handle, baseAddr, buffer, 4096, out bytesRead);
if (!ok)
return null ;
int currentVal;
for (int i = 0; i < 4096 - 3; i++)
{
currentVal = BitConverter.ToInt32(buffer, i);
if (currentVal == value)
{
IntPtr addr = new IntPtr(baseAddr.ToInt32() + i);
result.Add(addr);
i += 3;
}
}
return result;
}