从getsectbyname读取字节时崩溃 [英] Crash reading bytes from getsectbyname

查看:205
本文介绍了从getsectbyname读取字节时崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:感谢格雷格·帕克(Greg Parker)的指点…

UPDATE: Answer below in question, thanks to Greg Parker's pointer…

我在此处上传了一个示例项目,但我也会对其进行描述: https://github. com/tewha/getsectbyname-crash

I uploaded a sample project here, but I'll describe it as well: https://github.com/tewha/getsectbyname-crash

我(仅64位)可执行文件崩溃了,但是从 Xcode 运行时却没有崩溃.但是,如果我是从 Terminal Instruments 运行的,它将崩溃.

I get a crash from my my (64-bit only) executable, but not when run from Xcode. If I run it from Terminal or Instruments, however, it crashes.

这不是 调试与发布配置问题;在终端中运行调试可执行文件也会崩溃.从Xcode运行Release可执行文件.

This is not a Debug vs. Release configuration problem; running the Debug executable in Terminal also crashes. Running the Release executable from Xcode works.

我正在尝试从Mach-O可执行文件读取冲突部分,该可执行文件通过CREATE_INFOPLIST_SECTION_IN_BINARY = YES链接到应用程序.

I am trying to read a inflict section from the Mach-O executable, linked into the app via 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);

输出看起来像这样(我已经简化了一点,以删除日期/时间戳,进程ID):

The output looks like this (I've simplified this a bit to remove date/time stamps, process IDs):

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

有人可以告诉我如何解决此问题吗?

Can anyone tell me how to fix this?

答案:

#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中实现).

getsectbyname() does not adjust the section's address for ASLR. You should use getsectiondata() instead if your deployment target allows (first implemented in OS X 10.7, I think).

这篇关于从getsectbyname读取字节时崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆