技术开发 频道

.Net巧妙实现植物大战僵尸修改器

  为什么要区别是否是第一次搜索?因为第一次搜索是在整个进程可访问内存范围内查找,而之后的查找是基于第一次找到的地址。这样做不是唯一的,但是最好的方法。

  下面是搜索按钮单击的事件处理代码:

  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;

        }

 

  很明显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;

        }

 

0
相关文章