问题:我正在为学校(我的选择)做一个项目,它是一个程序加载器/DLL 注入(inject)器,我最初发现了这个想法 here ,修改以满足我的需要,并将 DLL 的 ASM 部分转换为扩展 ASM,它将使用 GCC 而不是 Visual Studio 进行编译。我没有在控制台窗口中打印弹球得分,而是加载了我编写的程序,该程序从用户那里获取输入并将其写入文件。加载程序注入(inject)一个 DLL,其中包含一个函数,该函数将用户输入(以前指定用于文件)重定向到消息框,并将我自己的字符串写入文件。
它在我的机器上工作,但是,我担心平台切换,因为我的教授必须在她的机器上编译工作,所以地址 0x004014A6 可能当前包含指令
CALL <some address>
将该字符串写入文件(实际代码为:ofile << user_input;
)不会包含任何与在另一台机器上编译时接近的内容,但仍会调用将字符串写入文件的函数。
我想做的是动态确定该地址是什么,而不是对地址进行硬编码。我想我可以通过在被调用以获取地址的函数上使用 GetProcAddress 来做到这一点,然后创建一个数组来保存表示 CALL <that function>
的字节。 ,并在内存中逐字节搜索我希望找到要进行的调用的某个位置,获取地址,然后从那里开始工作。
不过,我不知 Prop 体该怎么做。
主要问题:如何扫描内存地址范围并将内容与数组元素进行比较?
换句话说,我想在我的 DLL 中包含一个函数,该函数读取内存中任意地址的字节并将其与预期序列进行比较。如何在某个进程中任意读取内存地址的内容?
怀疑:我需要知道原始程序执行的起始地址和结束地址。如何获得起始地址和结束地址之间的范围? (这似乎是这里真正的障碍。我可能只知道如何获取进程开始和结束地址就可以得到其余部分。)
最佳答案
除非程序的版本是你的目标很快就会改变,你可以使用 VA(虚拟地址) = RVA(相对虚拟地址) + 模块基本加载地址(可以通过 GetModuleHandle
) 以获得在不同系统下不会失败的地址。如果版本确实发生了变化,那么您正在查看签名扫描仪。然而,它们并非万无一失,因为您扫描的模式可能会从一个构建到下一个构建发生根本性的变化。任何所需的范围数据都可以从目标应用程序的 PE 中获取,然后可用于临时将读取权限应用于 .code
部分,从而使您可以高效地循环它(效率不高是使用 ReadProcessMemory
)。这是一个小的 sigscanner 库,再往下还有一个简单的 sig 扫描器的源链接:http://www.blizzhackers.cc/viewtopic.php?f=182&t=478228&sid=55fc9a949aa0beb2ca2fb09e933210de
关于python - 如何在 Windows XP/7 机器上找到内存中的字节序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5781498/