c++ - mach_header 64 位和 __PAGEZERO 段 64 位

标签 c++ ios objective-c c

const struct mach_header *mach = _dyld_get_image_header(0);
struct load_command *lc;
struct segment_command_64 *sc64;
struct segment_command *sc;

if (mach->magic == MH_MAGIC_64) {
    lc = (struct load_command *)((unsigned char *)mach + sizeof(struct mach_header_64));
    printf("[+] detected 64bit ARM binary in memory.\n");
} else {
    lc = (struct load_command *)((unsigned char *)mach + sizeof(struct mach_header));
    printf("[+] detected 32bit ARM binary in memory.\n");
}

for (int i = 0; i < mach->ncmds; i++) {

    if (lc->cmd == LC_SEGMENT) {
        sc = (struct segment_command *)lc;
        NSLog(@"32Bit: %s (%x - 0x%x)",sc->segname,sc->vmaddr,sc->vmsize);
    } else if (lc->cmd == LC_SEGMENT_64) {
        sc64 = (struct segment_command_64 *)lc;
        NSLog(@"64Bit: %s (%llx - 0x%llx)",sc64->segname,sc64->vmaddr,sc64->vmsize);
    }
    lc = (struct load_command *)((unsigned char *)lc+lc->cmdsize);
}

当我以 32 位运行此代码时,我得到正常输出:

__PAGEZERO (0 - 0x1000) 
But on 64Bit: __PAGEZERO (0 - 0x100000000) 

__PAGEZERO 的大小从 0x1000 变为超过 0x100000000,是否有任何修复或任何解决方案来解决此问题?

最佳答案

在 64 位架构中制作一个大的 __PAGEZERO 非常有意义。 64 位系统的地址范围,即使高 16 位像 x86_64 那样被“裁掉”,也允许有大量内存(x86_64 的 48 位地址空间是 256TB 的内存地址空间)。这很有可能在未来的某个时候被认为是“小”,但目前,最大的服务器有 1-4TB,因此还有很大的增长空间,更多的普通机器有 16-32GB。

另请注意,实际上没有内存被占用。它只是“保留的虚拟空间”(即“它永远不会被使用”)。它占用的资源绝对为零,因为它没有映射到页表中,物理上不存在。它只是文件中的一个条目,它告诉加载程序保留此空间以使其永远无法使用,从而“受到保护”。该部分的实际“数据”大小为零,因为实际上那里什么也没有,只是“确保未使用它”。因此,如果此部分的大小发生变化,您的实际文件大小将不会变大或变小。如果它根本不存在,它会小几个字节(部分描述的大小)。但这确实是唯一会产生任何影响的东西。

__PAGEZERO 的目的是捕获 NULL 指针取消引用。通过在内存的开头保留一大段内存,任何通过 NULL 指针的访问都将被捕获并中止应用程序。在 32 位架构中,类似于:

int *p = NULL;
int x = p[0x100000]; 

很可能会成功,因为代码空间从 0x400000 (4MB) 开始(尝试写入这样的位置可能会崩溃,但读取会成功 - 当然假设代码空间实际上从那里开始而不是某个地方else 在地址范围内。

编辑:

This presentation显示最新进入 64 位处理器空间的 ARM 也在使用 48 位虚拟地址空间,并强制执行规范地址(前 16 位需要全部为相同值)以便将来可以扩展。也就是说,64位ARM处理器上可用的虚拟空间也是256TB。

关于c++ - mach_header 64 位和 __PAGEZERO 段 64 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23188378/

相关文章:

c++ - 确保最多设置一次静态成员 (C++)

ios - 如何通过发送产品名称来查找特定的产品 ID?

ios - UITabBarController 内的 UINavigationController 在 iOS 6 中不会旋转

c++ - 编写数学类/函数时的最佳做法是什么?

c++ - 在使用 send() 之前使用 select() 检查套接字

c++ - 使用自动/指向 child 的指针,访问 child 的父方法

iOS 状态栏覆盖 phonegap

ios - 使用ARKit读取iOS光传感器

ios - 比较两个具有特定约束的 NSDates

objective-c - 阻止 UIPopover 自动关闭