我有一个关于将数据(地址表或其他数据)放在.text
部分的功能下或放在.data
部分的问题?例如,我有这样一个函数:
extern int i0();
extern int i1();
extern int i2();
extern int i3();
extern int i4();
extern int i5();
void fff(int x) {
switch (x) {
case 0:
i0();
break;
case 1:
i1();
break;
case 2:
i2();
break;
case 3:
i3();
break;
case 4:
i4();
break;
case 5:
i5();
break;
}
}
在这里,这是我的代码:
fff:
cmp edi, 5
ja .L10
mov edi, edi
xor eax, eax
jmp [QWORD PTR .L4[0+rdi*8]]
.L4:
.quad .L9
.quad .L8
.quad .L7
.quad .L6
.quad .L5
.quad .L3
.L5:
jmp i4
.L3:
jmp i5
.L9:
jmp i0
.L8:
jmp i1
.L7:
jmp i2
.L6:
jmp i3
.L10:
ret
这里我有.L4
保存跳转地址…我应该把这张.L4
表放在哪里?在fff
函数下还是我必须把它放在.data
部分?那么静态数据呢?例如,我有2个QWORD
用于一个函数,我必须把它放在那个函数中,或者我必须把这些QWORDs
放在数据部分?为什么?我知道如果我把它放在。data section中或者放在它的函数下都没有问题,但是我想知道哪种方式更好?
.data
段通常是可写的,您不希望意外地或恶意地覆盖您的跳转表。所以.data
不是最好的地方。
.text
就可以了;它通常是只读的。是否在函数附近并不重要。许多系统有一个.rodata
部分,它是只读的,不可执行的,这将是更好的;这将有助于捕获错误或攻击,无意或故意试图执行跳转表的字节。
是的,你可以把指针表(.L4:
)在.text
部分(如果它不会在运行时修改),但我没有看到双间接跳转到一组外部函数i0
的原因。i5
。可以使用间接近跳转进行分支,它从指向这些外部函数的指针表中获取目标地址。链接器负责外部地址的完成。NASM/Intel语法示例:
| | global fff
| | extern i0,i1,i2,i3,i4,i5
|00000000:4883FF05 |fff: cmp rdi, 5
|00000004:773A | ja .L10
|00000006:FF24FD[10000000] | jmp [.L4+8*rdi]
|0000000D:0F1F00 | align 8 ; For better performance.
|00000010:[0000000000000000] |.L4: dq i0
|00000018:[0000000000000000] | dq i1
|00000020:[0000000000000000] | dq i2
|00000028:[0000000000000000] | dq i3
|00000030:[0000000000000000] | dq i4
|00000038:[0000000000000000] | dq i5
|00000040:C3 |.L10:ret