2011-03-25 52 views
1

我目前正在研究一些系统级代码,我希望能够识别来自加载的二进制文件的内存部分以检测损坏或修改的指令等内容;获取二进制指令的内存地址

本质上,我所追求的是一种在使用C++的Win32中获取指向范围指令的指针。这有点类似于要求一个指向.text段的开始和结束的函数指针。我对exe格式的理解是,.text部分是存储指令的地方,而.data部分则包含全局变量之类的东西。不幸的是,我发现这里可能有0个提示(我没有看到win32函数调用,TIB中没有任何内容等)。

任何人都可以指示我在哪里可以找到/计算此信息?

P.S.我明白,如果任何人恶意更改代码,他们可能会发现此代码并进行更改;我仍然对如何根据自己的好奇心获取这些信息的细节感兴趣。

回答

1

您可以在PE头中找到代码的入口点。从MSDN下载PE(可移植可执行文件)文件定义 - 它具有所有信息。内存中程序的格式与磁盘上的格式几乎相同。从代码中,您可以通过GetModuleHandle()函数获得指向内存中PE头的指针(句柄实际上是指向第一页的指针)。

+0

另一个新的信息。嗯,你知道如果一个句柄只是第一页的内存地址,确保你总是关闭句柄的目的是什么?我假设操作系统必须跟踪页面分开打开的次数,否则有什么意义?只是在这里好奇。 – Tom 2011-03-25 23:14:27

+0

一般来说,它的确如此,但GetModuleHandle(作为特例)不会增加句柄的引用计数。 – 2011-03-28 17:16:30

+0

您正在讨论与HANDLE非常不同的HMODULE。 – 2011-04-05 21:49:16

1

这并不直接回答你的问题,但对于你的整体解决方案,你可以看看Code Signing。如果你喜欢这个解决方案,那么Windows上就有现有的实现。

正如你所说的,二进制验证本身并不能解决你的问题。您还应该考虑在需要提升/管理权限的文件系统区域(如Program Files)中安装应用程序,或者将其部署到用户无法直接修改它的某处(如Web服务器)。

4

你不可能真的期望这与内存二进制文件一起工作。对导入的DLL的任何函数调用都将被加载器修改为指向加载的DLL中的目标过程的实际位置。

例如,假设你在kernel32.dll中调用一个函数。然后发生更新kernel32.dll的Windows更新。下一次运行应用程序时,kernel32.dll中的函数跳转到的内存地址与应用Windows更新之前的内存地址不同。

当然,这一切都假定DLL加载在他们的首选地址。然后你可能会有一些自我修改的代码。

依此类推,等等。

+0

好点大卫,其实这其中的目的之一是检测是否有一些自修改代码已经发生。然而,我没有考虑DLL加载,但是......嗯。谢谢,每天学习一些东西! – Tom 2011-03-25 23:09:04

+0

从我做过的更多阅读中,实际上,这看起来不正确。基于此:http://msdn.microsoft.com/en-us/library/aa271769(VS.60).aspx加载DLL时,它不会改变实际的DLL调用,它更类似于设置函数你的应用程序正在调用的指针。 – Tom 2011-03-31 01:54:58

+0

不过你想去想,代码改变了 – 2011-03-31 06:16:27