问题:我正在为学校开发一个项目(我的选择),它是一个程序加载器/DLL 注入器,我最初发现的想法 此处,进行修改以满足我的需要,并将 DLL 的 ASM 部分转换为扩展 ASM,该扩展 ASM 将使用 GCC 而不是 Visual Studio 进行编译。我不是在控制台窗口中打印弹球得分,而是加载一个我编写的程序,该程序接受用户的输入并将其写入文件。加载程序注入一个 DLL,其中包含一个函数,该函数将以前发送到文件的用户输入重定向到消息框,并将我自己的字符串写入该文件。
它可以在我的机器上运行,但是,我担心平台切换,因为我的教授必须在她的机器上编译工作,因此地址 0x004014A6 有可能,该地址当前包含以下指令:
CALL
将该字符串写入文件(实际代码是:ofile << user_input;
)不会包含任何接近该字符串的内容在另一台机器上编译,但仍然会调用该函数,将字符串写入文件。
我想要做的是动态确定该地址是什么,而不是对地址进行硬编码。我想我可以通过在被调用的函数上使用 GetProcAddress 来获取地址,然后创建一个数组来保存表示 CALL
的字节,并在内存中逐字节搜索我希望在某个地方找到要拨打的电话,获取地址,然后从那里开始工作。
但我不知道具体该怎么做。
主要问题:如何扫描内存地址范围并将内容与数组元素进行比较?
换句话说,我想在 DLL 中包含一个函数,该函数读取内存中任意地址的字节并将其与预期序列进行比较。如何才能任意读取某个进程内内存地址的内容呢?
怀疑:我需要知道原始程序执行的起始地址和结束地址。如何获取起始地址和结束地址之间的范围? (这似乎是这里真正的障碍。我可能只能让其余的人知道如何获取进程的开始和结束地址。)
Problem: I'm working on a project for school (my choice) which is a program loader/DLL injector, the idea of which I initially found here, modified to suit my needs, and converted the ASM portions of the DLL to extended ASM that will compile with GCC instead of Visual Studio. Rather than do the pinball score print in a console window thing, I'm loading a program I wrote that takes input from a user and writes it to a file. The loader injects a DLL with a function in it that redirects user input, formerly destined for a file, to a messagebox, and will write my own string to the file.
It works on my machine, however, I have concerns about platform switching because my professor has to compile the work on her machine, so it is possible that the address 0x004014A6, which currently contains the instruction to
CALL <some address>
which writes that string to a file(the actual code is: ofile << user_input;
) won't contain anything close to that when compiled on another machine, but will still have a call to that function that writes a string to a file.
What I want to do is dynamically determine what that address will be, as opposed to hardcoding the address. I think I can do this by using GetProcAddress on the function that gets called to get the address, then create an array to hold the bytes representing CALL <that function>
, and search byte by byte in memory somewhere around where I expect to find that call to be made, take the address, and work from there.
I don't know exactly how to do that, though.
MAIN QUESTION: How can I scan a range of memory addresses and compare the contents to elements of an array?
Put another way, I want to include in my DLL a function that reads bytes at an arbitrary address in memory and compares it to an expected sequence. How can I just arbitrarily read contents of memory addresses within a certain process?
Suspicions: I'll need to know the starting and ending addresses where execution of the original program takes place. How can I get the range between starting and ending addresses? (This seems like the real hurdle here. I can probably get the rest knowing only how to obtain the processes beginning and ending addresses.)
发布评论
评论(2)
除非您的目标程序版本很快就会改变,否则您可以使用 VA(虚拟地址) = RVA(相对虚拟地址) + 模块基本加载地址(可以通过
GetModuleHandle
获取)来得到一个在不同系统下都不会失败的地址。如果版本确实发生变化,那么您将查看签名扫描仪。然而,它们并不是万无一失的,因为您扫描的模式可能会从一个构建到下一个构建发生根本性的变化。所需的任何范围数据都可以从目标应用程序的 PE 中获取,然后可以使用这些数据临时将读取权限应用于.code
部分,从而允许您高效地循环它(效率不太高)是使用ReadProcessMemory
)。这是一个小的 sigscanner 库,再往下还有一个简单 sig 扫描器的源链接: http://www.blizzhackers.cc/viewtopic.php?f=182&t=478228&sid=55fc9a949aa0beb2ca2fb09e933210deUnless the version of the program is your targeting is gonna change soon, you can use VA(virtual address) = RVA(relative virtual address) + module Base load address(which can be gotten with
GetModuleHandle
) to get an address that won't fail under different systems. If the version does change, then your looking at a signature scanner. They aren't foolproof however, as the patterns your scanning for can radically change from one build to the next. Any range data needed can be gotten from the PE of the targetted app, that can then be used to temporarily apply read privilages to the.code
section, allowing you to loop through it efficiently(the not so efficient was is to useReadProcessMemory
). Here is a small sigscanner lib, farther down is also a link to source for a simple sig scanner: http://www.blizzhackers.cc/viewtopic.php?f=182&t=478228&sid=55fc9a949aa0beb2ca2fb09e933210de如果您使用 Python,也许 ptrace 可以提供帮助。它是跨平台的,可以通过 pip 安装。这是我在这里抓取的 unix 代码片段: http://sixserv.org/2010/07/26/memory-debugging-or-a-universal-game-trainer-with-python-and-ptrace/
如果您使用C/C++,这是我之前从 ITH 使用的一个特定于 Windows 的函数 (http://code.google.com/p/interactive-text-hooker/):
If you are using Python, maybe ptrace could help. It is cross-platfrom, and could be installed from pip. Here's a code snip for unix that I grabbed here: http://sixserv.org/2010/07/26/memory-debugging-or-a-universal-game-trainer-with-python-and-ptrace/
If you are using C/C++, here's a function specific for Windows that I used before from ITH (http://code.google.com/p/interactive-text-hooker/):