各位高人帮下忙!
这几天在写个内存修改的例子,现在有个问题是我搜索出来的地址从0x00400000-0x7FFFFFFF这么大的区间确只能搜索出50多个地址,这些地址的值也取的出来。其中用到了VirtualQueryEx这个API,请问下这个方法是一次跳过一块那样的执行方式吗?也就是说在后面地址累加时是这样的:BaseAddress = (IntPtr)(inf.BaseAddress + inf.RegionSize); 这里的regionsize增加的太快,所以我现在想让自定义个IntStr类型的地址StartAddress然后每查完一个就StartAddress+0x10也就是每次加16.但是这样是有问题的。
上面是累加的问题,用那种方法就会出现问题了,将内存中的每个地址遍历出来那不是要浪费很长时间,请问下各位在做内存搜索时常用的做法是什么,还望各位帮下,答好的加分!
这几天在写个内存修改的例子,现在有个问题是我搜索出来的地址从0x00400000-0x7FFFFFFF这么大的区间确只能搜索出50多个地址,这些地址的值也取的出来。其中用到了VirtualQueryEx这个API,请问下这个方法是一次跳过一块那样的执行方式吗?也就是说在后面地址累加时是这样的:BaseAddress = (IntPtr)(inf.BaseAddress + inf.RegionSize); 这里的regionsize增加的太快,所以我现在想让自定义个IntStr类型的地址StartAddress然后每查完一个就StartAddress+0x10也就是每次加16.但是这样是有问题的。
上面是累加的问题,用那种方法就会出现问题了,将内存中的每个地址遍历出来那不是要浪费很长时间,请问下各位在做内存搜索时常用的做法是什么,还望各位帮下,答好的加分!
c#在行的不是这个。
你下来分析下吧,看看有没有帮助
while(searchedLength==sizeof(MEMORY_BASIC_INFORMATION)&&(int)BaseAddress < 0x7FFFFFFF) {
System.Console.Write("当前第"+ y +"个 ");
searchedLength = (int)ProcessMemoryWorokApi.VirtualQueryEx(PinballHandle, BaseAddress, out inf,
sizeof(MEMORY_BASIC_INFORMATION));
Console.WriteLine(inf.State+" "+inf.Protect+" "+inf.State+" "+inf.RegionSize);
System.Console.Write(Convert.ToString(inf.BaseAddress, 16));
if (inf.State == MEMMessage.MEM_COMMIT &&
(inf.Protect == PAGEinfo.PAGE_READWRITE || inf.Protect == PAGEinfo.PAGE_WRITECOPY||
inf.Protect == PAGEinfo.PAGE_EXECUTE_READWRITE || inf.Protect == PAGEinfo.PAGE_EXECUTE_WRITECOPY))
{
y++;
ProcessMemoryWorokApi.ReadProcessMemory(PinballHandle,
(IntPtr)inf.BaseAddress, ReadByte, 16, (IntPtr)0); ReadString = ProcessMemoryWorokApi.ConvertByte(ReadByte); System.Console.WriteLine(" "+Convert.ToString(inf.BaseAddress,16)+"=" + ReadString);
if (UserInputString.Trim().Equals(ReadString.Trim()))
{
MessageBox(new IntPtr(0), "查到了,恭喜你!", "提示", 0);
//修改游戏分数
ProcessMemoryWorokApi.WriteProcessMemory(PinballHandle,
(IntPtr)inf.BaseAddress, ProcessMemoryWorokApi.ConvertToBytes(inputByteStr), 16, (IntPtr)0);
break;
}
else
{
BaseAddress = (IntPtr)(inf.BaseAddress + inf.RegionSize);
}
}
else if (inf.State == MEMMessage.MEM_FREE && inf.RegionSize > 0x08000000)
{
break;
}
else if (inf.Protect == PAGEinfo.PAGE_NOACCESS)
{
// || inf.Protect == PAGEinfo.PAGE_GUARD
Console.WriteLine("是不能访问的!");
ProcessMemoryWorokApi.VirtualProtectEx(PinballHandle,
(IntPtr)inf.BaseAddress, inf.RegionSize, PAGEinfo.PAGE_READWRITE, PAGEinfo.PAGE_NOACCESS); ProcessMemoryWorokApi.ReadProcessMemory(PinballHandle,
(IntPtr)inf.BaseAddress, ReadByte, 16, (IntPtr)0); ReadString = ProcessMemoryWorokApi.ConvertByte(ReadByte); System.Console.WriteLine(" " + Convert.ToString(inf.BaseAddress, 16) + "=" + ReadString);
y++;
BaseAddress = (IntPtr)(inf.BaseAddress + inf.RegionSize);
}
else if (inf.Protect == PAGEinfo.PAGE_GUARD||inf.Protect == PAGEinfo.PAGE_READONLY ||
inf.Protect == 0 || inf.Protect == PAGEinfo.PAGE_EXECUTE_READ)
{
// || inf.Protect == PAGEinfo.PAGE_GUARD
Console.WriteLine("是不能访问的!"); ProcessMemoryWorokApi.VirtualProtectEx(PinballHandle,
(IntPtr)inf.BaseAddress, inf.RegionSize, PAGEinfo.PAGE_READWRITE, inf.Protect); ProcessMemoryWorokApi.ReadProcessMemory(PinballHandle,
(IntPtr)inf.BaseAddress, ReadByte, 16, (IntPtr)0); ReadString = ProcessMemoryWorokApi.ConvertByte(ReadByte); System.Console.WriteLine(" " + Convert.ToString(inf.BaseAddress, 16) + "=" + ReadString);
y++;
BaseAddress = (IntPtr)(inf.BaseAddress + inf.RegionSize);
}
else
{
System.Console.WriteLine("xxxxxxxxxxxxxxxxxxxxx"+inf.Protect);
BaseAddress = (IntPtr)(inf.BaseAddress + inf.RegionSize);
} }
{
WinAPI.MEMORY_BASIC_INFORMATION mbi = new WinAPI.MEMORY_BASIC_INFORMATION();
/*
* fuck, 返回len为0的原因是OpenProcess的参数不是PROCESS_ALL_ACCESS
*/
int len = WinAPI.VirtualQueryEx(hProcess, baseAddress, ref mbi, System.Runtime.InteropServices.Marshal.SizeOf(mbi));
if (len != 0 && mbi.State == (int)WinAPI.MEMMessage.MEM_COMMIT && (mbi.Protect == (int)WinAPI.MEMMessage.PAGE_READWRITE || mbi.Protect == (int)WinAPI.MEMMessage.PAGE_EXECUTE_READWRITE))
{
memSize = (int)mbi.RegionSize;
memBytes = new Byte[memSize];
memBytes.Initialize();
ret = WinAPI.ReadProcessMemory(hProcess, baseAddress, memBytes, memSize, out bytesReaded);
if (ret == false)
{
goto NEXTLOOP;
}
}
else if (len == 0 || (mbi.State == (int)WinAPI.MEMMessage.MEM_FREE && mbi.RegionSize > 0x08000000))
{
Trace.WriteLine("fuck the address: 0x" + baseAddress.ToString("x") + " VirtualQueryEx returns: " + len.ToString());
break;
}
else
{
/*
* mbi.BaseAddress 和 baseAddress 用哪个?这是个问题
*/
baseAddress += mbi.RegionSize;
//baseAddress = mbi.BaseAddress + mbi.RegionSize;
continue;
} //TODO:读取比较代码:
bool found = false;
for (int i = 0; i < bytesReaded - targetBytes.Length; i++)
{
for (int j = 0; j < targetBytes.Length; j++)
{
//通配符 ? 匹配任何情况
if (targetBytes[j] == '?')
{
continue;
}
else if (memBytes[i + j] != targetBytes[j])
{
found = false;
goto ENDFIND;
}
found = true;
}
ENDFIND:
if (found == true)
{ Trace.WriteLine(string.Format("Found!postion is 0x{0}", (baseAddress + i).ToString("X")));
Byte[] mem = new Byte[targetBytes.Length];
WinAPI.ReadProcessMemory(hProcess, (baseAddress + (uint)i), mem, mem.Length, out bytesReaded);
string tmp = getMemoryString(mem);
}
} NEXTLOOP:
baseAddress += (uint)memSize;
}
现在不是那个问题了
看下面:
数据地址 块头地址 块大小 堆句柄
0x000a0688 0x000a0680 6144 0x000a0000
当我点这个地址时下面显示的是
000A0688 00 00 00 00 00 00 00 00 04 00 00 01 00 00 00 00
000A0698 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000A06A8 00 00 00 00 62 01 00 00 17 00 00 00 00 00 00 00
........上面是一个软件读出来的
我用BaseAddress加上regionsize取出的地址是 上面的堆句柄的地址,请问各位我怎样取到 数据地址和块头地址,因为我要用数据地址当起始地址,要不我从堆句柄中读出的byte怎么计算它的内存地址呢,你们说呢!
对于一个地址(开始是baseaddr,后面循环加),请求属性会得到一个regionsize,也就是从某个地址开始后面regionsize个字节是可读/用的. 而不是对这些regionsize个字节做地址判断.也就是不可通过某块的数据来确定内存地址,只能通过内存地址获取某块数据
如果你要搜索内存,就只能暴力比较.
0x000a0688 0x000a0680 6144 0x000a0000
当我点这个地址时下面显示的是
000A0688 00 00 00 00 00 00 00 00 04 00 00 01 00 00 00 00
000A0698 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000A06A8 00 00 00 00 62 01 00 00 17 00 00 00 00 00 00 00 那我要实现上面的功能该怎么办呢