C++ 获取二进制指令的内存地址

C++ 获取二进制指令的内存地址,c++,winapi,exe,binaryfiles,C++,Winapi,Exe,Binaryfiles,我目前正在研究一些系统级代码,我希望能够识别加载的二进制文件中的内存部分,以便检测损坏或修改的指令 本质上,我所追求的是一种在Win32中使用C++获得指向指令范围的指针的方法。这有点类似于请求一个指向.text节的开始和结束的函数指针。我对exe格式的理解是,.text部分是存储指令的地方,而.data部分保存全局变量等内容。不幸的是,我发现了0个关于这可能在哪里的提示(我没有看到win32函数调用,TIB中没有任何内容,等等) 有人能告诉我在哪里可以找到/计算这些信息吗 另外,我明白如果任何

我目前正在研究一些系统级代码,我希望能够识别加载的二进制文件中的内存部分,以便检测损坏或修改的指令

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

有人能告诉我在哪里可以找到/计算这些信息吗


另外,我明白如果任何人恶意更改代码,他们可能会发现并更改此代码;出于好奇,我仍然对如何获取这些信息的细节感兴趣。

这并不能直接回答您的问题,但对于您的总体解决方案,您可以研究一下。如果您喜欢此解决方案,Windows上已有一些实现


正如您所说,单靠二进制验证并不能解决您的问题。您还应该考虑将应用程序安装在需要提升/管理权限才能写入的文件系统区域,例如程序文件,或者将其部署到用户无法直接修改的地方,如web服务器。

这并不能直接回答您的问题,但对于您的整体解决方案,您可以考虑。如果您喜欢此解决方案,Windows上已有一些实现


正如您所说,单靠二进制验证并不能解决您的问题。您还应该考虑将应用程序安装在文件系统中需要提升/管理权限才能写入的区域,例如程序文件,或者将其部署到用户无法直接修改的地方,如web服务器。

您不能指望它与内存中的二进制文件一起工作。加载程序将修改对导入DLL的任何函数调用,以指向加载的DLL中目标过程的实际位置

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

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


等等,等等。

你不能指望它在内存二进制文件中工作。加载程序将修改对导入DLL的任何函数调用,以指向加载的DLL中目标过程的实际位置

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

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


依此类推。

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

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

好的方面David,事实上,这样做的目的之一是检测是否发生了自修改代码。我没有考虑过DLL加载会改变这一点,但是。。。嗯,谢谢,每天学点东西!事实上,从我读的更多资料来看,这似乎是不正确的。基于此:当你加载一个DLL时,它不会改变实际的DLL调用,这更像是设置一个你的应用程序正在调用的函数指针。但这只是它,加载的代码不会因此而改变。你不理解这篇文章。请告诉我;这不是一个有用的评论。只要函数的位置作为数据存储在函数查找表(例如,导入地址表)中,则在加载时更改该数据是无关的。因为我只关心二进制指令,所以其他数据更改是不相关的。David的优点是,事实上,这样做的目的之一是检测是否出现了一些自修改代码。我没有考虑过DLL加载会改变这一点,但是。。。嗯,谢谢,每天学点东西!事实上,从我读的更多资料来看,这似乎是不正确的。基于此:当你加载一个DLL时,它不会改变实际的DLL调用,这更像是设置一个你的应用程序正在调用的函数指针。但这只是它,加载的代码不会因此而改变。你不理解这篇文章。请告诉我;这不是一个有用的评论。只要函数的位置作为数据存储在函数查找表(例如,导入地址表)中,则在加载时更改该数据是无关的。因为我只关心二进制指令,所以其他数据更改是不相关的。另一条新信息。嗯,你知道如果句柄只是第一页的内存地址,那么确保始终关闭句柄的目的是什么吗?我想是的