mcd*_*ton 5 c assembly reverse-engineering elf
我正在玩操纵二进制的调用函数.我有以下代码:
#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));
}
Run Code Online (Sandbox Code Playgroud)
我编译了二进制文件并使用readelf或objdump我可以看到我的两个函数驻留在:
46:0000000000 40072c 52 FUNC GLOBAL DEFAULT 13 myfunc2**
54:0000000000 40064d 77 FUNC GLOBAL DEFAULT 13 myfunc**
使用命令objdump -D test(我的二进制名称),我可以看到main有两个callq函数.我尝试使用上面的地址72c编辑第一个指向myfunc2,但这不起作用; 导致二进制文件失败.
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
Run Code Online (Sandbox Code Playgroud)
我怀疑我需要通过相对位置或使用lea/mov指令来计算地址信息.
任何学习如何修改调用函数的帮助都将非常感激 - 请不要指向编辑字符串,如大多数互联网上的howtos ......
为了重写地址,您必须知道callq指令编码的确切方式.
我们来看看第一次调用的反汇编输出:
4006e1: e8 67 ff ff ff callq 40064d <myfunc>
4006e6: ...
Run Code Online (Sandbox Code Playgroud)
您可以清楚地看到该指令是用5个字节编码的.该e8字节是指令操作码,67 ff ff ff是跳转到的地址.在这一点上,人们会问这个问题,该怎么67 ff ff ff办0x40064d?
好吧,答案是e8编码所谓的"相对调用",并且相对于下一条指令的位置执行跳转.您必须计算被4006e6调用函数之间的距离才能重写地址.如果调用是absolute(ff),你可以将函数地址放在这4个字节中.
要证明这种情况,请考虑以下算法:
0x004006e6 + 0xffffff67 == 0x10040064d
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1054 次 |
| 最近记录: |