苹果为什么要用(mach_header的指针减去`__TEXT`的vmaddr)来计算ASLR的slide值

发布于 2025-01-18 02:54:45 字数 1179 浏览 3 评论 0原文

实在是让我很困惑!当我阅读 getsecbyname 的苹果开源代码时。 c。其中一些代码:

uint8_t * 
getsectiondata(
const struct mach_header *mhp,
const char *segname,
const char *sectname,
unsigned long *size) {
    slide = 0;
    sp = 0;
    sgp = (struct segment_command *)
          ((char *)mhp + sizeof(struct mach_header));
    for(i = 0; i < mhp->ncmds; i++){
        if(sgp->cmd == LC_SEGMENT){
        if(strcmp(sgp->segname, "__TEXT") == 0){
            slide = (uintptr_t)mhp - sgp->vmaddr;
        }
    ......
}

我可以理解什么是ASLR(地址空间布局随机)。我还知道幻灯片的值应该等于加载器地址减去链接器地址:slide = L(加载器地址) - A(链接器地址)。但为什么这里的幻灯片值是slide = (uintptr_t)mhp - sgp->vmaddr;。这是否意味着 mhp(mach_header) 是加载器地址?我可以勉强识别出“__TEXT”的 vmaddr 是链接器地址,因为它是从加载命令中读取的。但是为什么mach_header地址在这里变成了加载器地址,在我看来应该始终是0x00000000。

而且我粗略地阅读了Apple的xnu的源代码。我认真阅读了xnu源码中的函数load_machfile和函数parse_machfile。然而,我现在更困惑了。如果有人能帮助我,我真的很感激!

It is really confused me a lot! When I read apple open source code of getsecbyname.c. Some code In it:

uint8_t * 
getsectiondata(
const struct mach_header *mhp,
const char *segname,
const char *sectname,
unsigned long *size) {
    slide = 0;
    sp = 0;
    sgp = (struct segment_command *)
          ((char *)mhp + sizeof(struct mach_header));
    for(i = 0; i < mhp->ncmds; i++){
        if(sgp->cmd == LC_SEGMENT){
        if(strcmp(sgp->segname, "__TEXT") == 0){
            slide = (uintptr_t)mhp - sgp->vmaddr;
        }
    ......
}

I can understand what is ASLR(Address Space Layout Random). And I also know that slide's value should be equal to loader address subtract linker address: slide = L(loader address) - A(linker address). But why slide value in here which is slide = (uintptr_t)mhp - sgp->vmaddr;. Does that mean mhp(mach_header) is the loader address? I can constrainedly recognize "__TEXT"'s vmaddr is the linker address because which is read from the load command. But why the mach_header address become the loader address in here, which should be always 0x00000000 in my opinion.

And I have roughly read the source code of xnu of Apple. I read function load_machfile and function parse_machfile consisted in xnu source earnestly. However, I'm more confused now. I really appreciate if someone can help me!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

空袭的梦i 2025-01-25 02:54:45

必要时,Mach-O 标头位于文件偏移量 0 处(否则它就不是标头)。按照惯例,__TEXT 段映射文件偏移量 0 处的内容。因此,Mach-O 标头的地址和 __TEXT 段的地址是相同的。

现在,您只需获取该地址的链接时间值和运行时值,将其中一个值减去另一个值,就可以得到幻灯片了。 sgp->vmaddr 中的值是链接时值,因为在加载期间不会修改 Mach-O 标头(对于独立可执行文件,该值通常为 0x100000000如果您没有传递任何自定义链接器选项)。同时,mhp 是一个实时指针,因此它具有相同的值,但应用了幻灯片。

By necessity, the Mach-O header is at file offset 0 (otherwise it wouldn't be a header). And by convention, the __TEXT segment maps the content at file offset 0. So the address of the Mach-O header and that of the __TEXT segment are one and the same.

Now you just have to get the link-time value and the runtime value of that address, subtract one from the other and you have the slide. The value in sgp->vmaddr is the link-time one, because the Mach-O header is not modified during load (and it will usually be 0x100000000 for standalone executables if you didn't pass any custom linker options). Meanwhile, mhp is a live pointer so it is the same value, but with the slide applied.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文