TA的每日心情 | 奋斗 2023-9-22 14:51 |
|---|
签到天数: 341 天 [LV.8]以坛为家I
|
静态链接 游戏逆向的具体问题可以到我们网站了解一下,也有业内领域专业的客服为您解答问题,为成功合作打下一个良好的开端!
我们可以通过链接将两个或者多个不同的目标文件组成一个可执行文件。链接由链接器完成,根据发生时间不同可分为编译时链接,加载时链接和运行时链接。:
1
2
3
4
5
6
7
8
;
(
*
,
*
);
(){
=
0
;
(,);
0
;
}
1
2
3
4
5
6
7
8
=
1
;
=
0
;
(
*
,
*
){
=
*
;
*
=
*
;
*
=
;
}
命令:---------ELF你将得到当前链接器采用相似节合并的方法将和两个目标文件链接成一个可执行文件。此方法将不同目标文件相同属性的节合并为一个节(和的合并为新的)。首先对各个节的长度,属性和偏移进行分析,然后将输入目标文件中的符号表的符号定义与符号引用统一生成全局符号表,比较后读取输入文件的各类信息对符号进行解析,重定位等操作。相似节合并就发生在重定位时。完成后程序中的每条指令和全局变量就有仅有的运行时内存地址了。
静态链接的详细过程
为了构造可执行文件,链接器必须完成两个重要工作:1符号解析将每个符号(函数,全局变量,静态变量)的引用与其定义进行关联。2重定位将每个符号的定义与一个内存地址进行关联,然后修改这些符号的引用,使其指向这个内存地址。
对比ELF(静态链接可执行文件)和ELF-(中间产物)的,和节指令-ELF-
1
2
3
4
5
6
7
8
9
ELF
-
:文件格式64
-
86
-
64
节:
INSVMALMA
F
A
0
000000
0000000000000000
0000000000000000
000000
2
*
*
0
CONTENTS,ALLOC,LOAD,RELOC,READONLY,CODE
1
00000000
0000000000000000
0000000000000000
000000
2
*
*
0
CONTENTS,ALLOC,LOAD,DATA
2
00000000
0000000000000000
0000000000000000
000000
2
*
*
0
ALLOC
3
00000
0000000000000000
0000000000000000
000000
2
*
*
0
CONTENTS,READONLY
4
GNU
-
00000000
0000000000000000
0000000000000000
00000
2
*
*
0
CONTENTS,READONLY
5
000000
0000000000000000
0000000000000000
0000000
2
*
*
3
CONTENTS,ALLOC,LOAD,READONLY,DATA
6
_
0000
0000000000000000
0000000000000000
0000000
2
*
*
3
CONTENTS,ALLOC,LOAD,RELOC,READONLY,DATA
指令-ELF
1
2
3
4
5
6
7
8
9
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
ELF:文件格式64
-
86
-
64
节:
INSVMALMA
F
A
0
000000
0000000000
0000000000
0000
2
*
*
3
CONTENTS,ALLOC,LOAD,READONLY,DATA
1
-
0000
00000000000
00000000000
00000
2
*
*
2
CONTENTS,ALLOC,LOAD,READONLY,DATA
2
ABI
-
000000
000000000
000000000
000
2
*
*
2
CONTENTS,ALLOC,LOAD,READONLY,DATA
3
0000
000000000
000000000
000
2
*
*
3
CONTENTS,ALLOC,LOAD,READONLY,DATA
4
00000
000000000000
000000000000
000000
2
*
*
2
CONTENTS,ALLOC,LOAD,READONLY,CODE
5
0000
0000000000
0000000000
0000
2
*
*
4
CONTENTS,ALLOC,LOAD,READONLY,CODE
6
00458
000000000
000000000
000
2
*
*
6
CONTENTS,ALLOC,LOAD,READONLY,CODE
7
____
000
0000000060
0000000060
0060
2
*
*
4
CONTENTS,ALLOC,LOAD,READONLY,CODE
8
0000000
00000000740
00000000740
00740
2
*
*
2
CONTENTS,ALLOC,LOAD,READONLY,CODE
9
00
000000008000
000000008000
008000
2
*
*
5
CONTENTS,ALLOC,LOAD,READONLY,DATA
000000
0000000004
0000000004
00
2
*
*
0
CONTENTS,ALLOC,LOAD,READONLY,DATA
_
0000
00000000040
00000000040
000
2
*
*
3
CONTENTS,ALLOC,LOAD,READONLY,DATA
__
0000
000000000
000000000
000
2
*
*
0
CONTENTS,ALLOC,LOAD,READONLY,DATA
000000
0000000000
0000000000
0000
2
*
*
3
CONTENTS,ALLOC,LOAD,DATA,THREAD_LOCAL
0000
0000000000
0000000000
0000
2
*
*
3
ALLOC,THREAD_LOCAL
_
000000
0000000000
0000000000
0000
2
*
*
3
CONTENTS,ALLOC,LOAD,DATA
_
000000
0000000008
0000000008
00
2
*
*
3
CONTENTS,ALLOC,LOAD,DATA
0000000000
0000000000
0000
2
*
*
5
CONTENTS,ALLOC,LOAD,DATA
000008
000000000468
000000000468
2
*
*
3
CONTENTS,ALLOC,LOAD,DATA
00000
00000000000
00000000000
00000
2
*
*
3
CONTENTS,ALLOC,LOAD,DATA
008
0000000000
0000000000
0000
2
*
*
5
CONTENTS,ALLOC,LOAD,DATA
___
0000
0000000
0000000
0
2
*
*
3
CONTENTS,ALLOC,LOAD,DATA
___IO_
000068
00000000
00000000
00
2
*
*
5
CONTENTS,ALLOC,LOAD,DATA
___
000000
000000008
000000008
008
2
*
*
3
CONTENTS,ALLOC,LOAD,DATA
0080
00000000
00000000
000
2
*
*
5
ALLOC
____
000000
000000000
000000000
000
2
*
*
3
ALLOC
00000
0000000000000000
0000000000000000
000
2
*
*
0
CONTENTS,READONLY
0048
0000000000000000
0000000000000000
002
2
*
*
2
CONTENTS,READONLY
可以看到尚未链接的目标文件的VMA(虚拟地址)都是0。而链接完成后的ELF的VMA及LMA(加载地址)都不为0,一般情况下VMA和LMA是相等的。ELF完成了虚拟地址的分配,相似节也被合并。
使用指令--M--=ELF-查看反汇编代码
1
2
3
4
5
6
7
8
9
ELF
-
:文件格式64
-
86
-
64
D:
0000000000000000
:
0
:3
0
1
64
4
:
55
5
:
48
89
5,
8
:
48
83
,
0
:7
45
64
00
00
00
DWORDPTR[
-
],
4
:
48
8
45
,[
-
]
:
48
8
00
00
00
00
,[
+
00
]
#1+
1
:
48
89
6,
:
48
89
7,
:8
00
00
00
00
+
9
:8
00
00
00
00
,
00
2
:9
2
:3
可以看到()函数的地址从000开始,对()函数的调用在偏移9处,是指令的操作码,后面四个字节是调用函数相对于调用指令的下一条指令的偏移量。此时符号没有重定位,相对偏移为000000000,指令的下一条指令指令的地址为9,因此指令调用的地址为9+(-0)=9,这只是个临时地址,编译器尚不知道()函数的际地址,于是把地址计算的工作交给了链接器;链接器根据上一步的结果对重定位符号的地址进行修正。同理7处对的取值也以00代替。
接下来看ELF中的符号地址(查看行就可)指令--M--=ELF|-A""
1
2
3
4
5
6
7
8
9
0000000045
:
4745
:3
0
1
64
4749
:
55
474
:
48
89
5,
474
:
48
83
,
0
4751
:7
45
64
00
00
00
DWORDPTR[
-
],
4
4758
:
48
8
45
,[
-
]
475
:
48
8
8
39
0
00
,[
+
98
]
#4500
4763
:
48
89
6,
4766
:
48
89
7,
4769
:8
00
00
00
4775
476
:8
00
00
00
00
,
00
4773
:9
4774
:3
0000000075
:
4775
:3
0
1
64
4779
:
55
477
:
48
89
5,
477
:
48
89
7
8QWORDPTR[
-
],
4781
:
48
89
75
0QWORDPTR[
-
0
],
可以看到调用()函数的指令位于769,其下一条指令位于76,因此相对于指令偏移量为0的地址为76+0=775,刚好就是()函数的地址。
可重定位文件中比较重要的就是要包含重定位表,用于告诉链接器如何修改节的内容。每一个重定位表对应一个需要被重定位的节。指令-ELF-
1
2
3
4
5
6
7
8
9
ELF
-
:文件格式64
-
86
-
64
RELOCATIONRECORDSFOR[]:
OFFSET
TYPE
VALUE
0000000000000
R_X86_64_PC32
-
000000000000000
000000000000
R_X86_64_PLT32
-
000000000000000
RELOCATIONRECORDSFOR[_]:
OFFSET
TYPE
VALUE
00000000000000
R_X86_64_PC32
例如的节保存的重定位表。包含两个重定位入口,的类型R_X86_64_PC32用于相对寻址,将指令中编码的32值加上PC(下一条指令地址)的值得到有效地址。的类型R_X86_64_PLT32也用于相对寻址,而PLT是一个新的函数入口表的格式(为了和旧版本区别改了标记。现在有个参数可以关掉)。
X86_64中的重定位类型(部分)这部分知识可以自行补充
1
2
3
4
X86_64中的重定位类型含义地址在指令中占用的字节数
R_X86_64_PC32
32
位PC相对地址
4
R_X86_64_64
64
位绝对地址
8
R_X86_64_32
32
位绝对地址
4
静态链接库
后缀为的文件就是静态链接库文件,如。一个静态链接库可以视为一组目标文件经过压缩打包后形成的合集执行各种编译任务时,需要许多不同的目标文件,为了方便管理,人们使用工具将这些目标文件进行了压缩,编号和索引,这就形成了。 |
|