苹果为什么要用(mach_header的指针减去`__TEXT`的vmaddr)来计算ASLR的slide值
实在是让我很困惑!当我阅读 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
必要时,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 be0x100000000
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.