确定内存中函数/存根/命名空间的大小
Posted
技术标签:
【中文标题】确定内存中函数/存根/命名空间的大小【英文标题】:Determine size of functions/stub/namespace in memory 【发布时间】:2009-12-23 15:16:09 【问题描述】:我在名为stub
的命名空间中有几个函数。
我必须确定命名空间的确切起始地址和结束地址,至少是内存中命名空间的大小(将这些函数复制到另一个进程中)。
虽然这在 Visual C++ 2008 中通过添加一个
void stub_end()
在命名空间的末尾并使用
size_t size = reinterpret_cast<ULONG_PTR>(stub_end) - reinterpret_cast<ULONG_PTR>(stub_start);
确定存根的大小。
这很有效,因为 Visual C++ 保留了 .cpp 文件中的函数顺序,但在 Visual C++ 2010 中似乎不再是这种情况了。
如何使用编译指示指令、编译器/链接器工具或类似工具找出函数或整个命名空间/存根的大小?
【问题讨论】:
命名空间并不意味着存储所包含的类型和函数,它们是一种语法工具。 我知道,但基本上问题是关于任何类型的函数包(给定第一个和最后一个函数,其中最后一个函数也可能为空,如示例中所示) 编译器不必按照声明的顺序对代码进行排序,而且在启用优化后肯定不会。 我很想知道你为什么要这样做? 远程代码注入 -> 在使用带有 THREAD_SUSPENDED 的 CreateProcess 启动进程后获取 kernel32.dll 地址。 Toolhelp32 API 此时还无法读取 LDR 表。 【参考方案1】:随着这些天在安全方面的新推动(堆随机化、layout randomization 等),我认为这将变得更加困难。您最终可能不得不单独复制每个函数。
【讨论】:
【参考方案2】:您可以尝试将每个函数放在不同的部分,使用 VC++ 等效 GCC 的 attribute ((section ("name"))) http://www.delorie.com/gnu/docs/gcc/gcc_62.html 然后使用您的技术,或者您可以将每个函数放在不同的源文件中。
【讨论】:
【参考方案3】:C++ 语言不保证查找名称空间的地址或大小。也就是说,冒险使用汇编语言和链接器指令。
许多汇编语言都有一个操作码或助记符,用于将代码放置在特定地址。这允许设置标签以指示存储区域的开始。一些链接器具有用于获取段起始地址和大小的变量。这些将是用户定义的逻辑地址。
总而言之,使用您的程序集和链接器工具来定义命名空间开始和长度的公共符号或可选的段结束。在您的 C++ 程序中,以extern
访问这些标签。
【讨论】:
你能举出Visual C++中指令的例子吗?以上是关于确定内存中函数/存根/命名空间的大小的主要内容,如果未能解决你的问题,请参考以下文章