【发布时间】:2017-02-02 18:33:27
【问题描述】:
我在使用 jmp 时遇到了分段错误。
第一次使用jmp 0x30,出现segmentation fault。
我用gdb调试了我的程序,看到jmp被调用后,跳转到了一个绝对地址。
(gdb) b main
Breakpoint 1 at 0x80483b7: file f.c, line 3.
(gdb) r
Starting program: /root/work/f
Breakpoint 1, main () at f.c:3
3 __asm__("jmp 0x30\n"
(gdb) n
0x00000030 in ?? ()
(gdb)
我还以为可能是相对地址,所以我把jmp的参数从disassemble main修改为call的地址。
就是这样,
#include<stdio.h>
int main(){
__asm__("jmp 0x080483e6\n"
"popl %esi\n"
"movl %esi,0x8(%esi)\n"
"movb $0x0,0x7(%esi)\n"
"movl $0x0,0xc(%esi)\n"
"movl $0xb,%eax\n"
"movl %esi,%ebx\n"
"leal 0x8(%esi),%ecx\n"
"leal 0xc(%esi),%edx\n"
"int $0x80\n"
"movl $0x1, %eax\n"
"movl $0x0, %ebx\n"
"int $0x80\n"
"call 0x2a\n"
".string \"/bin/sh\"\n");
return 0;
}
但我得到了这个
Breakpoint 1, main () at f.c:3
3 __asm__("jmp 0x080483e6\n"
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x0000002a in ?? ()
(gdb)
我发现了这个相关的问题confusing with JMP instruction,我像这样修改了我的代码。
#include<stdio.h>
int main(){
__asm__("jmp L\n"
"sub:\n"
"popl %esi\n"
"movl %esi,0x8(%esi)\n"
"movb $0x0,0x7(%esi)\n"
"movl $0x0,0xc(%esi)\n"
"movl $0xb,%eax\n"
"movl %esi,%ebx\n"
"leal 0x8(%esi),%ecx\n"
"leal 0xc(%esi),%edx\n"
"int $0x80\n"
"movl $0x1, %eax\n"
"movl $0x0, %ebx\n"
"int $0x80\n"
"jmp exit\n"
"L:\n"
"call sub\n"
".string \"/bin/sh\"\n"
"exit:\n");
return 0;
}
但是不适合我,jmp被调用后,指令地址还是jmp这一行
(gdb) b main
Breakpoint 1 at 0x80483b7: file f.c, line 3.
(gdb) r
Starting program: /root/work/f
Breakpoint 1, main () at f.c:3
3 __asm__("jmp L\n"
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x080483ba in main () at f.c:3
3 __asm__("jmp L\n"
(gdb) n
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb)
我不知道问题出在哪里,非常感谢您的帮助!
【问题讨论】:
-
我不确定您要在这里完成什么。如果您的目标是学习 c,那么这是一个不好的开始方式。如果目标是学习 asm,这是最复杂的开始方式。也就是说,您正在修改 asm 中的(一堆)寄存器,而不通知编译器。当您的 asm() 退出时,这会造成混乱。如果您必须这样做,请考虑使用extended asm,它允许您破坏寄存器。
标签: c assembly x86 segmentation-fault inline-assembly