Gcc 在汇编代码中,更改堆栈指针+;跳跃->;赛格断层?
这是第一次在这里上传问题。 我必须做一个函数:Gcc 在汇编代码中,更改堆栈指针+;跳跃->;赛格断层?,gcc,x86,inline-assembly,att,Gcc,X86,Inline Assembly,Att,这是第一次在这里上传问题。 我必须做一个函数: 参数包括:目标函数和全局数组 设置寄存器%ebp&%esp=array 设置寄存器%eip=目标函数 使用asmC中的内嵌汇编代码 如果我忽略第二个条件,这一点也不难: void jump(unsigned int function); void goal(); void main(){ jump((unsigned int)goal); // call jump(goal) } void jump(unsigned int funct
void jump(unsigned int function);
void goal();
void main(){
jump((unsigned int)goal); // call jump(goal)
}
void jump(unsigned int function){
__asm__ __volatile__(
"movl %0, %%eax;"
"jmp %%eax" // jump to 'entry'
::"m"());
}
void goal(){ // desired destination of %eip
printf("goal\n"); // if jmp instruction was successful, put 'goal'
for(;;) { sleep(1); }
}
它确实提出了“目标”
但是,每当我尝试以类似的方式更改%esp&%ebp时,我都失败了:
(主要变化仅为“数组”的声明,在<强> ASM<强>中
中的2行 这造成了分割错误 与所有函数一样,'goal'函数的In.s文件条目包含一个序言,即pushl %ebp
movl %esp, %ebp
所以我的第一个猜测是,通过%ebp或%esp指向类似全局数组的某个位置,然后执行push、pop或mov会导致段错误
为了验证此信息,我修改了装配零件,如下所示:
__asm__ __volatile__(
"movl %0, %%eax;"
"movl %1, %%ebx;"
"movl %%ebp, %%ecx;" // %ecx : backup of %ebp
"movl %%ebx, %%esp;"
"movl %%ebx, %%ebp;" // %esp & %ebp = 'array'
"pushl %%ebp;"
"movl %%esp, %%ebp;" // instructions as in the entry of 'goal'
"movl %%ecx, %%esp;"
"movl %%ecx, %%ebp;" // restore %esp & %ebp before jmp
"jmp %%eax"
::"m"(function),"m"(array));
因此,%esp和%ebp指向“数组”,并遵循jmp前“目标”中的说明
令人惊讶的是,没有出现分割错误,但将“目标”按预期设置
总之
希望得到帮助。tl;dr您希望使用内联asm调用具有手动分配堆栈的函数。但是您使用的是
jmp
而不是call
,那么当它返回时会发生什么呢?哦,它没有,在sleep(1)
上循环。因此,我想,您可以在不告诉编译器的情况下敲击%ebx
。(现在没有时间详细研究这个问题,但您应该使用gdb
找出哪个指令设置错误,并将该信息编辑到问题中。以及寄存器值和/或在您获得segfault时的堆栈内存内容。)我从未使用过gdb
,但将学习并尝试。谢谢你的提示。在没有调试器的情况下编写asm就像试图蒙着眼睛构建一个机器人。这是了解指令如何改变机器状态的好方法。(对于内联asm,也可以单步执行编译器生成的代码。)有关GDB/strace的一些提示,请参阅的底部。GDB
告诉我segfault发生在跳转之后。所以我删除了printf和sleep,这样在跳转之后只剩下(;){}。那么就没有故障了。通过这种方式,无论如何,跳转是成功的,但之后的任何系统调用似乎都是不稳定的。更可能的是,堆栈的任何使用都崩溃了。没有任何调用的inf循环不会尝试将任何内容推送到堆栈上,因此如果ESP出错,它也不会崩溃(我假设发生了这种情况)。使用调试器检查ESP是否指向您分配的缓冲区顶部附近。(您可以在GDB中使用control-C来中断正在调试的进程,就像断点不终止程序一样。)
__asm__ __volatile__(
"movl %0, %%eax;"
"movl %1, %%ebx;"
"movl %%ebp, %%ecx;" // %ecx : backup of %ebp
"movl %%ebx, %%esp;"
"movl %%ebx, %%ebp;" // %esp & %ebp = 'array'
"pushl %%ebp;"
"movl %%esp, %%ebp;" // instructions as in the entry of 'goal'
"movl %%ecx, %%esp;"
"movl %%ecx, %%ebp;" // restore %esp & %ebp before jmp
"jmp %%eax"
::"m"(function),"m"(array));