I have a question about putting data (address table or other data) in the .text
section under its function or put in .data
section?
For example, I have a function like this :
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;
}
}
here in assembly, this is my code:
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
Here I have .L4
which holds the jump addresses ... where should I put this .L4
table ? Under the fff
function or I have to put it in the .data
section ? What about static data ? For example, I have 2 QWORD
for a function, I must put it in that function, or I must put those QWORDs
in the data section ? Why ? I know that there will be no problem if I put it in .data section or under its function, but I want to know which way is better?
CodePudding user response:
The .data
section is usually writable, and you would not want your jump table to be accidentally or maliciously overwritten. So .data
isn't the best place for it.
.text
would be fine; it is normally read-only. It doesn't really matter whether it's near the function or not. Many systems have a .rodata
section which is read-only and not executable, which would be even better; it would help catch bugs or attacks which accidentally or deliberately try to execute the bytes of the jump table.
CodePudding user response:
Yes, you can put the table of pointers (.L4:
) in .text
section (if it won't be modified at run time) but I don't see a reason for double indirection to a set of jumps to external functions i0
..i5
. You can jump to those functions with immediate near jump E9xxxxxxxx
which is 5 byte long; the linker will take care of xxxxxxxx
completion. Just multiply the index x in rdi
by five and jump to one of the five immediate jumps:
| | global fff
| | extern i0,i1,i2,i3,i4,i5
|00000000:4883FF05 |fff: cmp rdi, 5
|00000004:7725 | ja .L10
|00000006:FFA4BF[0D000000] | jmp [.L4 rdi 4*rdi]
|0000000D:E9(00000000) |.L4: jmp i0
|00000012:E9(00000000) | jmp i1
|00000017:E9(00000000) | jmp i2
|0000001C:E9(00000000) | jmp i3
|00000021:E9(00000000) | jmp i4
|00000026:E9(00000000) | jmp i5
|0000002B:C3 |.L10:ret
|0000002C: |