编辑ELF程序调用指令 [英] Editing ELF binary call instruction
问题描述
我玩弄操纵二进制的通话功能。我有以下code:
I am playing around with manipulating a binary's call functions. I have the below code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void myfunc2(char *str2, char *str1);
enter code here
void myfunc(char *str2, char *str1)
{
memcpy(str2 + strlen(str2), str1, strlen(str1));
}
int main(int argc, char **argv)
{
char str1[4] = "tim";
char str2[10] = "hello ";
myfunc((char *)&str2, (char *)&str1);
printf("%s\n", str2);
myfunc2((char *)&str2, (char *)&str1);
printf("%s\n", str2);
return 0;
}
void myfunc2(char *str2, char *str1)
{
memcpy(str2, str1, strlen(str1));
}
我已经编译二进制和使用readelf或objdump的,我可以看到我的两个功能居住在:
I have compiled the binary and using readelf or objdump I can see that my two functions reside at:
46:0000000000 40072c 52 FUNC全局默认13 myfunc2 **
46: 000000000040072c 52 FUNC GLOBAL DEFAULT 13 myfunc2**
54:0000000000 40064d 77 FUNC全局默认13 MYFUNC **
54: 000000000040064d 77 FUNC GLOBAL DEFAULT 13 myfunc**
使用命令objdump的-D测试(我的二进制文件名),我可以看到,主要有两个callq功能。我试图编辑第一个点使用上述地址72℃myfunc2,但是,这并不正常工作;导致二进制失败。
Using the command objdump -D test (my binaries name), I can see that main has two callq functions. I tried to edit the first one to point to myfunc2 using the above address 72c, but that does not work; causes the binary to fail.
000000000040069a <main>:
40069a: 55 push %rbp
40069b: 48 89 e5 mov %rsp,%rbp
40069e: 48 83 ec 40 sub $0x40,%rsp
4006a2: 89 7d cc mov %edi,-0x34(%rbp)
4006a5: 48 89 75 c0 mov %rsi,-0x40(%rbp)
4006a9: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
4006b0: 00 00
4006b2: 48 89 45 f8 mov %rax,-0x8(%rbp)
4006b6: 31 c0 xor %eax,%eax
4006b8: c7 45 d0 74 69 6d 00 movl $0x6d6974,-0x30(%rbp)
4006bf: 48 b8 68 65 6c 6c 6f movabs $0x206f6c6c6568,%rax
4006c6: 20 00 00
4006c9: 48 89 45 e0 mov %rax,-0x20(%rbp)
4006cd: 66 c7 45 e8 00 00 movw $0x0,-0x18(%rbp)
4006d3: 48 8d 55 d0 lea -0x30(%rbp),%rdx
4006d7: 48 8d 45 e0 lea -0x20(%rbp),%rax
4006db: 48 89 d6 mov %rdx,%rsi
4006de: 48 89 c7 mov %rax,%rdi
4006e1: e8 67 ff ff ff callq 40064d <myfunc>
4006e6: 48 8d 45 e0 lea -0x20(%rbp),%rax
4006ea: 48 89 c7 mov %rax,%rdi
4006ed: e8 0e fe ff ff callq 400500 <puts@plt>
4006f2: 48 8d 55 d0 lea -0x30(%rbp),%rdx
4006f6: 48 8d 45 e0 lea -0x20(%rbp),%rax
4006fa: 48 89 d6 mov %rdx,%rsi
4006fd: 48 89 c7 mov %rax,%rdi
400700: e8 27 00 00 00 callq 40072c <myfunc2>
400705: 48 8d 45 e0 lea -0x20(%rbp),%rax
400709: 48 89 c7 mov %rax,%rdi
40070c: e8 ef fd ff ff callq 400500 <puts@plt>
400711: b8 00 00 00 00 mov $0x0,%eax
400716: 48 8b 4d f8 mov -0x8(%rbp),%rcx
40071a: 64 48 33 0c 25 28 00 xor %fs:0x28,%rcx
400721: 00 00
400723: 74 05 je 40072a <main+0x90>
400725: e8 f6 fd ff ff callq 400520 <__stack_chk_fail@plt>
40072a: c9 leaveq
40072b: c3 retq
我怀疑我需要做一些与通过计算相对位置的地址信息或使用LEA / MOV指令。
I suspect I need to do something with calculating the address information through relative location or using the lea/mov instructions.
任何帮助,学习如何修改呼叫功能将大大AP preciated - 请像上的howtos遍布大部分上网...
Any assistance to learn how to modify the call function would be greatly appreciated - please no pointers on editing strings like the howtos all over most of the internet...
推荐答案
为了改写的地址,你必须知道确切的方式 callq
指令都设有codeD。
In order to rewrite the address, you have to know the exact way the callq
instructions are encoded.
让我们第一次调用的反汇编输出:
Let's take the disassembly output of the first call:
4006e1: e8 67 ff ff ff callq 40064d <myfunc>
4006e6: ...
您可以清楚地看到该指令是带5个字节codeD。在 E8
字节指令运算code和 67 FF FF FF
是跳转到该地址。在这一点上,人们可能会问的问题,什么也 67 FF FF FF
做 0x40064d
?
You can clearly see that the instruction is encoded with 5 bytes. The e8
byte is the instruction opcode, and 67 ff ff ff
is the address to jump to. At this point, one would ask the question, what has 67 ff ff ff
to do with 0x40064d
?
那么,答案是 E8
连接codeS所谓的相对呼和跳转相对于下一条指令的位置进行。你算算为了改写地址 4006e6
和被调用函数之间的距离。有呼叫被绝对的( FF
),你可以只把函数地址在这些4个字节。
Well, the answer is that e8
encodes a so-called "relative call" and the jump is performed relative to the location of the next instruction. You have to calculate the distance between 4006e6
and the called function in order to rewrite the address. Had the call been absolute (ff
), you could just put the function address in these 4 bytes.
要证明这种情况下,考虑下面的算术:
To prove that this is the case, consider the following arithmetic:
0x004006e6 + 0xffffff67 == 0x10040064d
这篇关于编辑ELF程序调用指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!