获取dylib模块的SizeOfImage和EntryPoint
Getting SizeOfImage and EntryPoint of dylib module
我正在编写一个跨平台内存分析库,我提供的功能之一是 GetProcessModules。在 windows 上,我使用 EnumProcessModules to get a list of all modules loaded in a process along with GetModuleInformation 检索模块的地址、SizeOfImage 和入口点。
将此翻译成 OSX 我发现 this 和其他帮助我实现此功能的资源。我已经能够使用 dyld_image_info
结构来获取模块的名称和加载的地址,但是我该如何获取 SizeOfImage 和 EntryPoint 值呢?
SizeOfImage
和EntryPoint
是WindowsMODULEINFO
结构中的字段名。当然,OS X 上下文中不存在。
OSX任务使用的动态库是Mach-O格式的目标文件,其基本结构如下:
(来自苹果:Mach-O File Format Reference)
我假设您所追求的 SizeOfImage
值是当前加载到内存中的整个目标文件消耗的字节数。这样做的方法是将 Header、Load Commands 和数据 Segments 的大小相加.大致如下:
size_t size_of_image(struct mach_header *header) {
size_t sz = sizeof(*header); // Size of the header
sz += header->sizeofcmds; // Size of the load commands
struct load_command *lc = (struct load_command *) (header + 1);
for (uint32_t i = 0; i < header->ncmds; i++) {
if (lc->cmd == LC_SEGMENT) {
sz += ((struct segment_command *) lc)->vmsize; // Size of segments
}
lc = (struct load_command *) ((char *) lc + lc->cmdsize);
}
return sz;
}
接下来,入口点有点不同。我的猜测是您想要动态库的 initializer
函数的地址 (ref here)。这可以在 __DATA
段 的 __mod_init_func
部分 中找到。要检索此部分,我们可以使用 getsectbynamefromheader
。此函数 returns 指向一个 "struct section" 的指针,其中包含指向该部分的虚拟内存位置的指针。
#include <mach-o/getsect.h>
uint32_t mod_init_addr(struct mach_header *header) {
struct section *sec;
if (sec = getsectbynamefromheader(header, "__DATA", "__mod_init_func")) {
return sec->addr;
}
return 0;
}
返回值为__mod_init_func
段的虚拟内存地址,其中包含"pointers to module initialization functions".
注意:这些结构和函数有类似的64位实现,后缀为_64
,如struct mach_header_64
、getsectbynamefromheader_64
等. 对于 64 位对象,必须使用这些函数。
免责声明:所有代码未经测试 - 在浏览器中编码
我正在编写一个跨平台内存分析库,我提供的功能之一是 GetProcessModules。在 windows 上,我使用 EnumProcessModules to get a list of all modules loaded in a process along with GetModuleInformation 检索模块的地址、SizeOfImage 和入口点。
将此翻译成 OSX 我发现 this 和其他帮助我实现此功能的资源。我已经能够使用 dyld_image_info
结构来获取模块的名称和加载的地址,但是我该如何获取 SizeOfImage 和 EntryPoint 值呢?
SizeOfImage
和EntryPoint
是WindowsMODULEINFO
结构中的字段名。当然,OS X 上下文中不存在。
OSX任务使用的动态库是Mach-O格式的目标文件,其基本结构如下:
(来自苹果:Mach-O File Format Reference)
我假设您所追求的 SizeOfImage
值是当前加载到内存中的整个目标文件消耗的字节数。这样做的方法是将 Header、Load Commands 和数据 Segments 的大小相加.大致如下:
size_t size_of_image(struct mach_header *header) {
size_t sz = sizeof(*header); // Size of the header
sz += header->sizeofcmds; // Size of the load commands
struct load_command *lc = (struct load_command *) (header + 1);
for (uint32_t i = 0; i < header->ncmds; i++) {
if (lc->cmd == LC_SEGMENT) {
sz += ((struct segment_command *) lc)->vmsize; // Size of segments
}
lc = (struct load_command *) ((char *) lc + lc->cmdsize);
}
return sz;
}
接下来,入口点有点不同。我的猜测是您想要动态库的 initializer
函数的地址 (ref here)。这可以在 __DATA
段 的 __mod_init_func
部分 中找到。要检索此部分,我们可以使用 getsectbynamefromheader
。此函数 returns 指向一个 "struct section" 的指针,其中包含指向该部分的虚拟内存位置的指针。
#include <mach-o/getsect.h>
uint32_t mod_init_addr(struct mach_header *header) {
struct section *sec;
if (sec = getsectbynamefromheader(header, "__DATA", "__mod_init_func")) {
return sec->addr;
}
return 0;
}
返回值为__mod_init_func
段的虚拟内存地址,其中包含"pointers to module initialization functions".
注意:这些结构和函数有类似的64位实现,后缀为_64
,如struct mach_header_64
、getsectbynamefromheader_64
等. 对于 64 位对象,必须使用这些函数。
免责声明:所有代码未经测试 - 在浏览器中编码