从 getsectbyname 读取字节时崩溃
Crash reading bytes from getsectbyname
更新:回答下面的问题,感谢 Greg Parker 的指点……
我在这里上传了一个示例项目,但我也会对其进行描述:https://github.com/tewha/getsectbyname-crash
我的(仅 64 位)可执行文件崩溃了,但当 Xcode 的 运行 时却没有。但是,如果我从 Terminal 或 Instruments 运行 它会崩溃。
这是不是调试与发布配置问题; 运行在终端中调试可执行程序也会崩溃。 运行 来自 Xcode 的 Release 可执行文件有效。
我正在尝试从 Mach-O 可执行文件中读取一个 inflict 部分,该部分通过 CREATE_INFOPLIST_SECTION_IN_BINARY = YES
链接到应用程序。
const struct section_64 *plistSection = getsectbyname("__TEXT", "__info_plist");
NSLog(@"Found a section %s, %s", plistSection->segname, plistSection->sectname);
void *ptr = ((void *)plistSection->addr);
uint64_t size = plistSection->size;
NSLog(@"It has %zd bytes at %tx", size, plistSection->addr);
NSLog(@"Allocating %zd bytes", size);
void *buffer = malloc(size);
NSLog(@"Moving %zd bytes", size);
NSLog(@"(Crashes when doing the memmove.)");
memmove(buffer, ptr, size);
NSLog(@"Freeing %zd bytes", size);
free(buffer);
输出看起来像这样(我稍微简化了一点以删除 date/time 标记、进程 ID):
bash-4.3$ ./getsectbyname
getsectbyname Found a section __TEXT, __info_plist
getsectbyname It has 658 bytes at 100000d07
getsectbyname Allocating 658 bytes
getsectbyname Moving 658 bytes
getsectbyname (Crashes when doing the memmove.)
Segmentation fault: 11
谁能告诉我如何解决这个问题?
答案:
#import <Foundation/Foundation.h>
#include <mach-o/getsect.h>
#include <mach-o/ldsyms.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSError *e;
unsigned long size;
void *ptr = getsectiondata(&_mh_execute_header, "__TEXT",
"__info_plist", &size);
NSData *plistData = [NSData dataWithBytesNoCopy:ptr length:size
freeWhenDone:NO];
NSPropertyListFormat format;
NSDictionary *infoPlistContents =
[NSPropertyListSerialization propertyListWithData:plistData
options:NSPropertyListImmutable format:&format error:&e];
NSLog(@"The value for Key is %@", infoPlistContents[@"Key"]);
}
return 0;
}
getsectbyname()
不会为 ASLR 调整节的地址。如果您的部署目标允许,您应该使用 getsectiondata()
(我认为首先在 OS X 10.7 中实现)。
更新:回答下面的问题,感谢 Greg Parker 的指点……
我在这里上传了一个示例项目,但我也会对其进行描述:https://github.com/tewha/getsectbyname-crash
我的(仅 64 位)可执行文件崩溃了,但当 Xcode 的 运行 时却没有。但是,如果我从 Terminal 或 Instruments 运行 它会崩溃。
这是不是调试与发布配置问题; 运行在终端中调试可执行程序也会崩溃。 运行 来自 Xcode 的 Release 可执行文件有效。
我正在尝试从 Mach-O 可执行文件中读取一个 inflict 部分,该部分通过 CREATE_INFOPLIST_SECTION_IN_BINARY = YES
链接到应用程序。
const struct section_64 *plistSection = getsectbyname("__TEXT", "__info_plist");
NSLog(@"Found a section %s, %s", plistSection->segname, plistSection->sectname);
void *ptr = ((void *)plistSection->addr);
uint64_t size = plistSection->size;
NSLog(@"It has %zd bytes at %tx", size, plistSection->addr);
NSLog(@"Allocating %zd bytes", size);
void *buffer = malloc(size);
NSLog(@"Moving %zd bytes", size);
NSLog(@"(Crashes when doing the memmove.)");
memmove(buffer, ptr, size);
NSLog(@"Freeing %zd bytes", size);
free(buffer);
输出看起来像这样(我稍微简化了一点以删除 date/time 标记、进程 ID):
bash-4.3$ ./getsectbyname
getsectbyname Found a section __TEXT, __info_plist
getsectbyname It has 658 bytes at 100000d07
getsectbyname Allocating 658 bytes
getsectbyname Moving 658 bytes
getsectbyname (Crashes when doing the memmove.)
Segmentation fault: 11
谁能告诉我如何解决这个问题?
答案:
#import <Foundation/Foundation.h>
#include <mach-o/getsect.h>
#include <mach-o/ldsyms.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSError *e;
unsigned long size;
void *ptr = getsectiondata(&_mh_execute_header, "__TEXT",
"__info_plist", &size);
NSData *plistData = [NSData dataWithBytesNoCopy:ptr length:size
freeWhenDone:NO];
NSPropertyListFormat format;
NSDictionary *infoPlistContents =
[NSPropertyListSerialization propertyListWithData:plistData
options:NSPropertyListImmutable format:&format error:&e];
NSLog(@"The value for Key is %@", infoPlistContents[@"Key"]);
}
return 0;
}
getsectbyname()
不会为 ASLR 调整节的地址。如果您的部署目标允许,您应该使用 getsectiondata()
(我认为首先在 OS X 10.7 中实现)。