pwndbg> ptype Struct
超大的栈溢出,保护只开了NX和Partial RELRO
ELF中没有后门函数,可利用字符串,可用的函数也只有read
>>>elf.plt<br>
{'read': 4195312}<br>
>>>elf.got<br>
{'__libc_startmain': 6295536, '\_gmon_start__': 6295544, 'read': 6295576}
由于程序中提供的函数符号有限,所以无法正常泄露出libc基址,需要ret2dl-resolve泄露libc函数地址,并使用其和system函数的偏移计算得到system函数
为避免在运行程序时加载过多的动态链接导致卡顿,操作系统实现了延迟绑定(Lazy Binding)的技术,只有在函数首次调用时才进行绑定,
当程序首次 call func@plt,将执行以下操作,此处拿read@plt作为示例
当程序每次call _read
时,都将跳转至0x4003F0执行jmp语句,在首次调用时,cs:off_601018
指向read@plt的下一条指令,即0x4003F6以进行绑定操作,在第一次调用后,cs:off_601018
将指向read的真正地址
在push cs:linkMap
后跳转至_dl_runtime_resolve
函数,加上read@plt中push 0
,此处即调用_dl_runtime_resolve(linkMap,0)
可以看到_dl_runtime_resolve_xsavec
函数只负责
1.保存原目标函数(read)的参数环境<br>
2.调用_dl_fixup查询并绑定read的真正地址至linkMap中指定的重定位地址<br>
3.还原原目标函数(read)的参数环境<br>
4.跳转至_dl_fixup的查询结果<br>
而真正做查询绑定操作的是_dl_fixup
函数
由于本题是x64且保护Partial RELRO,所以暂不分析st_other==0的情况
根据源码和汇编的分析,可知
伪造LinkMap
<br>
伪造LinkMap->l_addr
作为偏移以计算最终绑定函数地址<br>
伪造LinkMap->l_info[JMPREL]
及ELF64_Rela
以定位sym索引及重定位地址<br>
伪造LinkMap->l_info[SYMTAB]
来定位libc函数将st_value
作为基址以计算最终绑定函数地址
__dl_fixup
函数会根据LinkMap->l_info\[SYMTAB\]->ELF_SYM
获得st_value
,并将其与LinkMap->l_addr
相加最后作为查询结果<br>
而目前在ELF中的libc函数已知的已有read
和__libc_start_main
,其中若使用__libc_start_main@got - 0x8
作为ELF_SYM
的话,st_other
值为0x58<br>
在对__dl_fixup<+87>
汇编分析中,程序检查了st_other
的低2位是否为0,若为0则不会执行DL_FIXUP_MAKE_VALUE
转而执行_dl_lookup_symbol_x
,而我们最终目的是使用DL_FIXUP_MAKE_VALUE
来泄露libc函数地址并计算出system
函数地址,所以__libc_start_main
不能作为伪造的ELF_SYM
<br>
而对于read@got-0x8
作为伪造的ELF_SYM
,其st_other
的值为0x7e,符合低两位不为0的条件
以下是需要伪造的LinkMap
结构分析
左 为LinkMap成员和FakeLinkMap需伪造成员的对照<br>
中 为FakeLinkMap需伪造成员的结构和位置<br>
右 为FakeLinkMap伪造后的具体成员结构和值
由于不采用_dl_lookup_symbol_x
查询函数,所以无需伪造ELF_Sym结构体,直接将其指向read@got-0x8
即可,这样即可得到sym->st_value
为read
的真实地址,而最终地址为 l_addr - sym->st_value
,所以只需计算并传入这个偏移 l_addr
即可获得最终函数的地址
1.虽然在利用中DT_STRTAB未被使用,但仍需将其和成员String table指向一块可读写的空间<br>
2.虽然并不需要用到绑定写入的最终函数地址,但仍需计算并指定reloc->r_offset使重定位地址落在一个可读写的内存空间上<br>
3.LinkMap的DT_PTR并不直接指向ELF结构体,而是指向Dynamic结构体
最终的EXP如下
l_addr的计算有可能是负数,Python里-1就是-1,但是p64函数并不接受一个负数,必须让-1不是-1而是0xFFFFFFFFFFFFFFFF,所以我手动计算负数的值并将其写为十六进制以避免p64()函数报错,由于我编码能力垃圾暂时也没想明白怎么解决
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
char buf[
256
];
/
/
[rsp
+
0h
] [rbp
-
100h
] BYREF
read(
0
, buf,
0x1000uLL
);
return
0
;
}
/
*
Arch: amd64
-
64
-
little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (
0x3ff000
)
RUNPATH: b
'/root/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/'
*
/
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
char buf[
256
];
/
/
[rsp
+
0h
] [rbp
-
100h
] BYREF
read(
0
, buf,
0x1000uLL
);
return
0
;
}
/
*
Arch: amd64
-
64
-
little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (
0x3ff000
)
RUNPATH: b
'/root/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/'
*
/
.text:
0000000000400506
call _read
.text:
0000000000400506
call _read
_read proc near
.plt:
00000000004003F0
jmp cs:off_601018
_read endp
.plt:
00000000004003F6
push
0
.plt:
00000000004003FB
jmp plt_0
_read proc near
.plt:
00000000004003F0
jmp cs:off_601018
_read endp
.plt:
00000000004003F6
push
0
.plt:
00000000004003FB
jmp plt_0
plt_0 proc near
.plt:
00000000004003E0
push cs:linkMap
.plt:
00000000004003E6
jmp cs:_dl_runtime_resolve
plt_0 endp
plt_0 proc near
.plt:
00000000004003E0
push cs:linkMap
.plt:
00000000004003E6
jmp cs:_dl_runtime_resolve
plt_0 endp
;↓↓↓↓↓↓↓↓↓↓保存调用参数环境↓↓↓↓↓↓↓↓↓↓
0x00007ffff7c17750
<
+
0
>: push rbx
0x00007ffff7c17751
<
+
1
>: mov rbx,rsp
0x00007ffff7c17754
<
+
4
>:
and
rsp,
0xffffffffffffffc0
0x00007ffff7c17758
<
+
8
>: sub rsp,QWORD PTR [rip
+
0x2100a9
]
0x00007ffff7c1775f
<
+
15
>: mov QWORD PTR [rsp],rax
0x00007ffff7c17763
<
+
19
>: mov QWORD PTR [rsp
+
0x8
],rcx
0x00007ffff7c17768
<
+
24
>: mov QWORD PTR [rsp
+
0x10
],rdx
0x00007ffff7c1776d
<
+
29
>: mov QWORD PTR [rsp
+
0x18
],rsi
0x00007ffff7c17772
<
+
34
>: mov QWORD PTR [rsp
+
0x20
],rdi
0x00007ffff7c17777
<
+
39
>: mov QWORD PTR [rsp
+
0x28
],r8
0x00007ffff7c1777c
<
+
44
>: mov QWORD PTR [rsp
+
0x30
],r9
0x00007ffff7c17781
<
+
49
>: mov eax,
0xee
0x00007ffff7c17786
<
+
54
>: xor edx,edx
0x00007ffff7c17788
<
+
56
>: mov QWORD PTR [rsp
+
0x250
],rdx
0x00007ffff7c17790
<
+
64
>: mov QWORD PTR [rsp
+
0x258
],rdx
0x00007ffff7c17798
<
+
72
>: mov QWORD PTR [rsp
+
0x260
],rdx
0x00007ffff7c177a0
<
+
80
>: mov QWORD PTR [rsp
+
0x268
],rdx
0x00007ffff7c177a8
<
+
88
>: mov QWORD PTR [rsp
+
0x270
],rdx
0x00007ffff7c177b0
<
+
96
>: mov QWORD PTR [rsp
+
0x278
],rdx
0x00007ffff7c177b8
<
+
104
>: xsavec [rsp
+
0x40
]
0x00007ffff7c177bd
<
+
109
>: mov rsi,QWORD PTR [rbx
+
0x10
]
0x00007ffff7c177c1
<
+
113
>: mov rdi,QWORD PTR [rbx
+
0x8
]
;↑↑↑↑↑↑↑↑↑↑保存调用参数环境↑↑↑↑↑↑↑↑↑↑
0x00007ffff7c177c5
<
+
117
>: call
0x7ffff7c0fdf0
<_dl_fixup>;真正的绑定查询函数
0x00007ffff7c177ca
<
+
122
>: mov r11,rax ;将结果保存至R11
;↓↓↓↓↓↓↓↓↓↓还原调用参数环境↓↓↓↓↓↓↓↓↓↓
0x00007ffff7c177cd
<
+
125
>: mov eax,
0xee
0x00007ffff7c177d2
<
+
130
>: xor edx,edx
0x00007ffff7c177d4
<
+
132
>: xrstor [rsp
+
0x40
]
0x00007ffff7c177d9
<
+
137
>: mov r9,QWORD PTR [rsp
+
0x30
]
0x00007ffff7c177de
<
+
142
>: mov r8,QWORD PTR [rsp
+
0x28
]
0x00007ffff7c177e3
<
+
147
>: mov rdi,QWORD PTR [rsp
+
0x20
]
0x00007ffff7c177e8
<
+
152
>: mov rsi,QWORD PTR [rsp
+
0x18
]
0x00007ffff7c177ed
<
+
157
>: mov rdx,QWORD PTR [rsp
+
0x10
]
0x00007ffff7c177f2
<
+
162
>: mov rcx,QWORD PTR [rsp
+
0x8
]
0x00007ffff7c177f7
<
+
167
>: mov rax,QWORD PTR [rsp]
0x00007ffff7c177fb
<
+
171
>: mov rsp,rbx
0x00007ffff7c177fe
<
+
174
>: mov rbx,QWORD PTR [rsp]
0x00007ffff7c17802
<
+
178
>: add rsp,
0x18
;↑↑↑↑↑↑↑↑↑↑还原调用参数环境↑↑↑↑↑↑↑↑↑↑
0x00007ffff7c17806
<
+
182
>: bnd jmp r11 ;跳转至原目标函数
;↓↓↓↓↓↓↓↓↓↓保存调用参数环境↓↓↓↓↓↓↓↓↓↓
0x00007ffff7c17750
<
+
0
>: push rbx
0x00007ffff7c17751
<
+
1
>: mov rbx,rsp
0x00007ffff7c17754
<
+
4
>:
and
rsp,
0xffffffffffffffc0
0x00007ffff7c17758
<
+
8
>: sub rsp,QWORD PTR [rip
+
0x2100a9
]
0x00007ffff7c1775f
<
+
15
>: mov QWORD PTR [rsp],rax
0x00007ffff7c17763
<
+
19
>: mov QWORD PTR [rsp
+
0x8
],rcx
0x00007ffff7c17768
<
+
24
>: mov QWORD PTR [rsp
+
0x10
],rdx
0x00007ffff7c1776d
<
+
29
>: mov QWORD PTR [rsp
+
0x18
],rsi
0x00007ffff7c17772
<
+
34
>: mov QWORD PTR [rsp
+
0x20
],rdi
0x00007ffff7c17777
<
+
39
>: mov QWORD PTR [rsp
+
0x28
],r8
0x00007ffff7c1777c
<
+
44
>: mov QWORD PTR [rsp
+
0x30
],r9
0x00007ffff7c17781
<
+
49
>: mov eax,
0xee
0x00007ffff7c17786
<
+
54
>: xor edx,edx
0x00007ffff7c17788
<
+
56
>: mov QWORD PTR [rsp
+
0x250
],rdx
0x00007ffff7c17790
<
+
64
>: mov QWORD PTR [rsp
+
0x258
],rdx
0x00007ffff7c17798
<
+
72
>: mov QWORD PTR [rsp
+
0x260
],rdx
0x00007ffff7c177a0
<
+
80
>: mov QWORD PTR [rsp
+
0x268
],rdx
0x00007ffff7c177a8
<
+
88
>: mov QWORD PTR [rsp
+
0x270
],rdx
0x00007ffff7c177b0
<
+
96
>: mov QWORD PTR [rsp
+
0x278
],rdx
0x00007ffff7c177b8
<
+
104
>: xsavec [rsp
+
0x40
]
0x00007ffff7c177bd
<
+
109
>: mov rsi,QWORD PTR [rbx
+
0x10
]
0x00007ffff7c177c1
<
+
113
>: mov rdi,QWORD PTR [rbx
+
0x8
]
;↑↑↑↑↑↑↑↑↑↑保存调用参数环境↑↑↑↑↑↑↑↑↑↑
0x00007ffff7c177c5
<
+
117
>: call
0x7ffff7c0fdf0
<_dl_fixup>;真正的绑定查询函数
0x00007ffff7c177ca
<
+
122
>: mov r11,rax ;将结果保存至R11
;↓↓↓↓↓↓↓↓↓↓还原调用参数环境↓↓↓↓↓↓↓↓↓↓
0x00007ffff7c177cd
<
+
125
>: mov eax,
0xee
0x00007ffff7c177d2
<
+
130
>: xor edx,edx
0x00007ffff7c177d4
<
+
132
>: xrstor [rsp
+
0x40
]
0x00007ffff7c177d9
<
+
137
>: mov r9,QWORD PTR [rsp
+
0x30
]
0x00007ffff7c177de
<
+
142
>: mov r8,QWORD PTR [rsp
+
0x28
]
0x00007ffff7c177e3
<
+
147
>: mov rdi,QWORD PTR [rsp
+
0x20
]
0x00007ffff7c177e8
<
+
152
>: mov rsi,QWORD PTR [rsp
+
0x18
]
0x00007ffff7c177ed
<
+
157
>: mov rdx,QWORD PTR [rsp
+
0x10
]
0x00007ffff7c177f2
<
+
162
>: mov rcx,QWORD PTR [rsp
+
0x8
]
0x00007ffff7c177f7
<
+
167
>: mov rax,QWORD PTR [rsp]
0x00007ffff7c177fb
<
+
171
>: mov rsp,rbx
0x00007ffff7c177fe
<
+
174
>: mov rbx,QWORD PTR [rsp]
0x00007ffff7c17802
<
+
178
>: add rsp,
0x18
;↑↑↑↑↑↑↑↑↑↑还原调用参数环境↑↑↑↑↑↑↑↑↑↑
0x00007ffff7c17806
<
+
182
>: bnd jmp r11 ;跳转至原目标函数
_dl_fixup(struct link_map
*
l, ElfW(Word) reloc_arg)
{
/
/
符号表symtab
=
linkMap
-
>l_info[
6
]
const ElfW(Sym)
*
const symtab
=
(const void
*
)D_PTR(l, l_info[DT_SYMTAB]);
/
/
字符串表strtab
=
linkMap
-
>l_info[
5
]
const char
*
strtab
=
(const void
*
)D_PTR(l, l_info[DT_STRTAB]);
/
/
重定位表reloc
=
linkMap
-
>l_info[
23
]
+
reloc_arg
const PLTREL
*
const reloc
=
(const void
*
)(D_PTR(l, l_info[DT_JMPREL])
+
reloc_offset);
/
/
定位符号sym
=
symtab[reloc
-
>r_info] 此处使用reloc
-
>r_info的高
32
位作为索引
const ElfW(Sym)
*
sym
=
&symtab[ELFW(R_SYM)(reloc
-
>r_info)];
const ElfW(Sym)
*
refsym
=
sym;
/
/
重定位地址(rel_addr)
=
LinkMap
-
>l_addr
+
reloc
-
>r_offset
void
*
const rel_addr
=
(void
*
)(l
-
>l_addr
+
reloc
-
>r_offset);
lookup_t result;
DL_FIXUP_VALUE_TYPE value;
/
*
判断重定位类型是否为
7
-
-
ELF_MACHINE_JMP_SLOT
*
/
assert
(ELFW(R_TYPE)(reloc
-
>r_info)
=
=
ELF_MACHINE_JMP_SLOT);
/
*
此处判断sym
-
>st_other的最后两位是否为
0
*
/
if
(__builtin_expect(ELFW(ST_VISIBILITY)(sym
-
>st_other),
0
)
=
=
0
)
{
const struct r_found_version
*
version
=
NULL;
if
(l
-
>l_info[VERSYMIDX(DT_VERSYM)] !
=
NULL)
{
const ElfW(Half)
*
vernum
=
(const void
*
)D_PTR(l, l_info[VERSYMIDX(DT_VERSYM)]);
ElfW(Half) ndx
=
vernum[ELFW(R_SYM)(reloc
-
>r_info)] &
0x7fff
;
version
=
&l
-
>l_versions[ndx];
if
(version
-
>
hash
=
=
0
)
version
=
NULL;
}
int
flags
=
DL_LOOKUP_ADD_DEPENDENCY;
/
/
156
if
(!RTLD_SINGLE_THREAD_P)
/
/
171
{
THREAD_GSCOPE_SET_FLAG();
flags |
=
DL_LOOKUP_GSCOPE_LOCK;
}
RTLD_ENABLE_FOREIGN_CALL;
result
=
_dl_lookup_symbol_x(strtab
+
sym
-
>st_name, l, &sym, l
-
>l_scope,
version, ELF_RTYPE_CLASS_PLT, flags, NULL);
/
*
We are done with the
global
scope.
*
/
if
(!RTLD_SINGLE_THREAD_P)
/
/
+
226
THREAD_GSCOPE_RESET_FLAG();
RTLD_FINALIZE_FOREIGN_CALL;
/
*
Currently result contains the base load address (
or
link
map
)
of the
object
that defines sym. Now add
in
the symbol
offset.
*
/
value
=
DL_FIXUP_MAKE_VALUE(result,sym ? (LOOKUP_VALUE_ADDRESS(result)
+
sym
-
>st_value) :
0
);
}
else
{
/
/
绑定查询结果等于 linkMap
-
>l_addr
+
sym
-
>st_value
value
=
DL_FIXUP_MAKE_VALUE(l, l
-
>l_addr
+
sym
-
>st_value);
result
=
l;
}
value
=
elf_machine_plt_value(l, reloc, value);
if
(sym !
=
NULL && __builtin_expect(ELFW(ST_TYPE)(sym
-
>st_info)
=
=
STT_GNU_IFUNC,
0
))
value
=
elf_ifunc_invoke(DL_FIXUP_VALUE_ADDR(value));
/
*
Finally, fix up the plt itself.
*
/
if
(__glibc_unlikely(GLRO(dl_bind_not)))
return
value;
return
elf_machine_fixup_plt(l, result, refsym, sym, reloc, rel_addr, value);
}
_dl_fixup(struct link_map
*
l, ElfW(Word) reloc_arg)
{
/
/
符号表symtab
=
linkMap
-
>l_info[
6
]
const ElfW(Sym)
*
const symtab
=
(const void
*
)D_PTR(l, l_info[DT_SYMTAB]);
/
/
字符串表strtab
=
linkMap
-
>l_info[
5
]
const char
*
strtab
=
(const void
*
)D_PTR(l, l_info[DT_STRTAB]);
/
/
重定位表reloc
=
linkMap
-
>l_info[
23
]
+
reloc_arg
const PLTREL
*
const reloc
=
(const void
*
)(D_PTR(l, l_info[DT_JMPREL])
+
reloc_offset);
/
/
定位符号sym
=
symtab[reloc
-
>r_info] 此处使用reloc
-
>r_info的高
32
位作为索引
const ElfW(Sym)
*
sym
=
&symtab[ELFW(R_SYM)(reloc
-
>r_info)];
const ElfW(Sym)
*
refsym
=
sym;
/
/
重定位地址(rel_addr)
=
LinkMap
-
>l_addr
+
reloc
-
>r_offset
void
*
const rel_addr
=
(void
*
)(l
-
>l_addr
+
reloc
-
>r_offset);
lookup_t result;
DL_FIXUP_VALUE_TYPE value;
/
*
判断重定位类型是否为
7
-
-
ELF_MACHINE_JMP_SLOT
*
/
assert
(ELFW(R_TYPE)(reloc
-
>r_info)
=
=
ELF_MACHINE_JMP_SLOT);
/
*
此处判断sym
-
>st_other的最后两位是否为
0
*
/
if
(__builtin_expect(ELFW(ST_VISIBILITY)(sym
-
>st_other),
0
)
=
=
0
)
{
const struct r_found_version
*
version
=
NULL;
if
(l
-
>l_info[VERSYMIDX(DT_VERSYM)] !
=
NULL)
{
const ElfW(Half)
*
vernum
=
(const void
*
)D_PTR(l, l_info[VERSYMIDX(DT_VERSYM)]);
ElfW(Half) ndx
=
vernum[ELFW(R_SYM)(reloc
-
>r_info)] &
0x7fff
;
version
=
&l
-
>l_versions[ndx];
if
(version
-
>
hash
=
=
0
)
version
=
NULL;
}
int
flags
=
DL_LOOKUP_ADD_DEPENDENCY;
/
/
156
if
(!RTLD_SINGLE_THREAD_P)
/
/
171
{
THREAD_GSCOPE_SET_FLAG();
flags |
=
DL_LOOKUP_GSCOPE_LOCK;
}
RTLD_ENABLE_FOREIGN_CALL;
result
=
_dl_lookup_symbol_x(strtab
+
sym
-
>st_name, l, &sym, l
-
>l_scope,
version, ELF_RTYPE_CLASS_PLT, flags, NULL);
/
*
We are done with the
global
scope.
*
/
if
(!RTLD_SINGLE_THREAD_P)
/
/
+
226
THREAD_GSCOPE_RESET_FLAG();
RTLD_FINALIZE_FOREIGN_CALL;
/
*
Currently result contains the base load address (
or
link
map
)
of the
object
that defines sym. Now add
in
the symbol
offset.
*
/
value
=
DL_FIXUP_MAKE_VALUE(result,sym ? (LOOKUP_VALUE_ADDRESS(result)
+
sym
-
>st_value) :
0
);
}
else
{
/
/
绑定查询结果等于 linkMap
-
>l_addr
+
sym
-
>st_value
value
=
DL_FIXUP_MAKE_VALUE(l, l
-
>l_addr
+
sym
-
>st_value);
result
=
l;
}
value
=
elf_machine_plt_value(l, reloc, value);
if
(sym !
=
NULL && __builtin_expect(ELFW(ST_TYPE)(sym
-
>st_info)
=
=
STT_GNU_IFUNC,
0
))
value
=
elf_ifunc_invoke(DL_FIXUP_VALUE_ADDR(value));
/
*
Finally, fix up the plt itself.
*
/
if
(__glibc_unlikely(GLRO(dl_bind_not)))
return
value;
return
elf_machine_fixup_plt(l, result, refsym, sym, reloc, rel_addr, value);
}
<
+
0
>: push rbx
<
+
1
>: mov r10,rdi ;r10
=
rdi
=
LinkMap
<
+
4
>: mov esi,esi
<
+
6
>: lea rdx,[rsi
+
rsi
*
2
] ;rdx
=
rsi
=
0
<
+
10
>: sub rsp,
0x10
;const char
*
strtab
=
(const void
*
)D_PTR(l, l_info[DT_STRTAB]);
<
+
14
>: mov rax,QWORD PTR [rdi
+
0x68
] ;rax
=
DT_STRTAB
<
+
18
>: mov rdi,QWORD PTR [rax
+
0x8
] ;rdi
=
ELF String Table
;const PLTREL
*
const reloc
=
(const void
*
)(D_PTR(l, l_info[DT_JMPREL])
+
reloc_offset);
<
+
22
>: mov rax,QWORD PTR [r10
+
0xf8
] ;rax
=
DT_JMPREL
<
+
29
>: mov rax,QWORD PTR [rax
+
0x8
] ;rax
=
Elf64_Rela
;const ElfW(Sym)
*
const symtab
=
(const void
*
)D_PTR(l, l_info[DT_SYMTAB]);
<
+
33
>: lea r8,[rax
+
rdx
*
8
] ;r8
=
rax
=
Elf64_Rela
<
+
37
>: mov rax,QWORD PTR [r10
+
0x70
] ;rax
=
DT_SYMTAB
;const PLTREL
*
const reloc
=
(const void
*
)(D_PTR(l, l_info[DT_JMPREL])
+
reloc_offset);
<
+
41
>: mov rcx,QWORD PTR [r8
+
0x8
] ;rcx
=
Elf64_Rela
-
>r_info
<
+
45
>: mov rbx,QWORD PTR [r8] ;rbx
=
Elf64_Rela
-
>r_offset
const ElfW(Sym)
*
sym
=
&symtab[ELFW(R_SYM)(reloc
-
>r_info)];
<
+
48
>: mov rax,QWORD PTR [rax
+
0x8
] ;rax
=
Elf64_Sym
<
+
52
>: mov rdx,rcx ;rdx
=
rcx
=
Elf64_Rela
-
>r_info
<
+
55
>: shr rdx,
0x20
;rdx
=
rdx >>
0x20
=
Elf64_Rela
-
>r_info>>
0x20
<
+
59
>: lea rsi,[rdx
+
rdx
*
2
]
<
+
63
>: lea rsi,[rax
+
rsi
*
8
] ;rsi
=
Elf64_Sym[Elf64_Rela
-
>r_info >>
32
]
;const PLTREL
*
const reloc
=
(const void
*
)(D_PTR(l, l_info[DT_JMPREL])
+
reloc_offset);
<
+
67
>: mov rax,QWORD PTR [r10] ;rax
=
linkMap
-
>l_addr
<
+
70
>: mov QWORD PTR [rsp
+
0x8
],rsi ;var_sym
=
rsi
<
+
75
>: add rbx,rax
;
assert
(ELFW(R_TYPE)(reloc
-
>r_info)
=
=
ELF_MACHINE_JMP_SLOT);
<
+
78
>:
cmp
ecx,
0x7
<
+
81
>: jne
0x7fa516a0ff64
<_dl_fixup
+
372
>
;
if
(__builtin_expect(ELFW(ST_VISIBILITY)(sym
-
>st_other),
0
)
=
=
0
)
<
+
87
>: test BYTE PTR [rsi
+
0x5
],
0x3
<
+
91
>: jne
0x7fa516a0fee8
<_dl_fixup
+
248
>
<
+
97
>: mov rax,QWORD PTR [r10
+
0x1c8
]
<
+
104
>: xor r8d,r8d
<
+
107
>: test rax,rax
<
+
110
>: je
0x7fa516a0fe8c
<_dl_fixup
+
156
>
<
+
112
>: mov rax,QWORD PTR [rax
+
0x8
]
<
+
116
>: movzx eax,WORD PTR [rax
+
rdx
*
2
]
<
+
120
>:
and
eax,
0x7fff
<
+
125
>: lea rdx,[rax
+
rax
*
2
]
<
+
129
>: mov rax,QWORD PTR [r10
+
0x2e0
]
<
+
136
>: lea r8,[rax
+
rdx
*
8
]
<
+
140
>: mov eax,
0x0
<
+
145
>: mov r9d,DWORD PTR [r8
+
0x8
]
<
+
149
>: test r9d,r9d
<
+
152
>: cmove r8,rax
<
+
156
>: mov edx,DWORD PTR fs:
0x18
<
+
164
>: test edx,edx
<
+
166
>: mov eax,
0x1
<
+
171
>: jne
0x7fa516a0ff48
<_dl_fixup
+
344
>
<
+
177
>: mov esi,DWORD PTR [rsi]
<
+
179
>: mov rcx,QWORD PTR [r10
+
0x380
]
<
+
186
>: lea rdx,[rsp
+
0x8
]
<
+
191
>: push
0x0
<
+
193
>: push rax
<
+
194
>: mov r9d,
0x1
<
+
200
>: add rdi,rsi
<
+
203
>: mov rsi,r10
<
+
206
>: call
0x7fa516a0b0b0
<_dl_lookup_symbol_x>
<
+
211
>: mov r8,rax
<
+
214
>: mov eax,DWORD PTR fs:
0x18
<
+
222
>: test eax,eax
<
+
224
>: pop rcx
<
+
225
>: pop rsi
<
+
226
>: jne
0x7fa516a0ff10
<_dl_fixup
+
288
>
<
+
228
>: mov rsi,QWORD PTR [rsp
+
0x8
]
<
+
233
>: xor eax,eax
;
if
(sym !
=
NULL && __builtin_expect(ELFW(ST_TYPE)(sym
-
>st_info)
=
=
STT_GNU_IFUNC,
0
))
<
+
235
>: test rsi,rsi
<
+
238
>: je
0x7fa516a0fef8
<_dl_fixup
+
264
>;sym
=
=
NULL
<
+
240
>: test r8,r8
<
+
243
>: je
0x7fa516a0fee8
<_dl_fixup
+
248
>
<
+
245
>: mov rax,QWORD PTR [r8]
;value
=
DL_FIXUP_MAKE_VALUE(l, l
-
>l_addr
+
sym
-
>st_value);
<
+
248
>: movzx edx,BYTE PTR [rsi
+
0x4
] ;edx
=
[rsi
+
0x4
]
=
sym
-
>st_info
<
+
252
>: add rax,QWORD PTR [rsi
+
0x8
] ;rax
=
rax
+
[rsi
+
0x8
]
=
linkMap
-
>l_addr
+
sym
-
>st_value 此命令执行完后rax
=
真正函数地址
;
if
(sym !
=
NULL && __builtin_expect(ELFW(ST_TYPE)(sym
-
>st_info)
=
=
STT_GNU_IFUNC,
0
))
<
+
256
>:
and
edx,
0xf
<
+
259
>:
cmp
dl,
0xa
;
if
sym
-
>st_info
=
=
STT_GNU_IFUNC
<
+
262
>: je
0x7fa516a0ff60
<_dl_fixup
+
368
>
;
if
(__glibc_unlikely(GLRO(dl_bind_not)))
<
+
264
>: mov edx,DWORD PTR [rip
+
0x2178aa
] ;edx
=
dl_bind_not
<
+
270
>: test edx,edx
<
+
272
>: jne
0x7fa516a0ff05
<_dl_fixup
+
277
> ;
if
(__glibc_unlikely(GLRO(dl_bind_not)))
;
return
value;
<
+
274
>: mov QWORD PTR [rbx],rax ;reloc
=
绑定查询结果
<
+
277
>: add rsp,
0x10
<
+
281
>: pop rbx
<
+
282
>: ret
<
+
283
>: nop DWORD PTR [rax
+
rax
*
1
+
0x0
]
<
+
288
>: xor eax,eax
<
+
290
>: xchg DWORD PTR fs:
0x1c
,eax
<
+
298
>:
cmp
eax,
0x2
<
+
301
>: jne
0x7fa516a0fed4
<_dl_fixup
+
228
>
<
+
303
>: mov rdi,QWORD PTR fs:
0x10
<
+
312
>: xor r10d,r10d
<
+
315
>: add rdi,
0x1c
<
+
319
>: mov edx,
0x1
<
+
324
>: mov esi,
0x81
<
+
329
>: mov eax,
0xca
<
+
334
>: syscall
<
+
336
>: jmp
0x7fa516a0fed4
<_dl_fixup
+
228
>
<
+
338
>: nop WORD PTR [rax
+
rax
*
1
+
0x0
]
<
+
344
>: mov DWORD PTR fs:
0x1c
,
0x1
<
+
356
>: mov eax,
0x5
<
+
361
>: jmp
0x7fa516a0fea1
<_dl_fixup
+
177
>
<
+
366
>: xchg ax,ax
;value
=
elf_ifunc_invoke(DL_FIXUP_VALUE_ADDR(value));
<
+
368
>: call rax
<
+
370
>: jmp
0x7fa516a0fef8
<_dl_fixup
+
264
> ;
if
(__glibc_unlikely(GLRO(dl_bind_not)))
<
+
372
>: lea rcx,[rip
+
0x132fd
]
<
+
379
>: lea rsi,[rip
+
0x1115a
]
<
+
386
>: lea rdi,[rip
+
0x132b7
]
<
+
393
>: mov edx,
0x50
<
+
398
>: call
0x7fa516a1b790
<__GI___assert_fail>;重定位类型不等于
7
<
+
0
>: push rbx
<
+
1
>: mov r10,rdi ;r10
=
rdi
=
LinkMap
<
+
4
>: mov esi,esi
<
+
6
>: lea rdx,[rsi
+
rsi
*
2
] ;rdx
=
rsi
=
0
<
+
10
>: sub rsp,
0x10
;const char
*
strtab
=
(const void
*
)D_PTR(l, l_info[DT_STRTAB]);
<
+
14
>: mov rax,QWORD PTR [rdi
+
0x68
] ;rax
=
DT_STRTAB
<
+
18
>: mov rdi,QWORD PTR [rax
+
0x8
] ;rdi
=
ELF String Table
;const PLTREL
*
const reloc
=
(const void
*
)(D_PTR(l, l_info[DT_JMPREL])
+
reloc_offset);
<
+
22
>: mov rax,QWORD PTR [r10
+
0xf8
] ;rax
=
DT_JMPREL
<
+
29
>: mov rax,QWORD PTR [rax
+
0x8
] ;rax
=
Elf64_Rela
;const ElfW(Sym)
*
const symtab
=
(const void
*
)D_PTR(l, l_info[DT_SYMTAB]);
<
+
33
>: lea r8,[rax
+
rdx
*
8
] ;r8
=
rax
=
Elf64_Rela
<
+
37
>: mov rax,QWORD PTR [r10
+
0x70
] ;rax
=
DT_SYMTAB
;const PLTREL
*
const reloc
=
(const void
*
)(D_PTR(l, l_info[DT_JMPREL])
+
reloc_offset);
<
+
41
>: mov rcx,QWORD PTR [r8
+
0x8
] ;rcx
=
Elf64_Rela
-
>r_info
<
+
45
>: mov rbx,QWORD PTR [r8] ;rbx
=
Elf64_Rela
-
>r_offset
const ElfW(Sym)
*
sym
=
&symtab[ELFW(R_SYM)(reloc
-
>r_info)];
<
+
48
>: mov rax,QWORD PTR [rax
+
0x8
] ;rax
=
Elf64_Sym
<
+
52
>: mov rdx,rcx ;rdx
=
rcx
=
Elf64_Rela
-
>r_info
<
+
55
>: shr rdx,
0x20
;rdx
=
rdx >>
0x20
=
Elf64_Rela
-
>r_info>>
0x20
<
+
59
>: lea rsi,[rdx
+
rdx
*
2
]
<
+
63
>: lea rsi,[rax
+
rsi
*
8
] ;rsi
=
Elf64_Sym[Elf64_Rela
-
>r_info >>
32
]
;const PLTREL
*
const reloc
=
(const void
*
)(D_PTR(l, l_info[DT_JMPREL])
+
reloc_offset);
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!