Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly ASM-在“运行”期间修改寄存器;函数调用";_Assembly_Call_Cpu Registers - Fatal编程技术网

Assembly ASM-在“运行”期间修改寄存器;函数调用";

Assembly ASM-在“运行”期间修改寄存器;函数调用";,assembly,call,cpu-registers,Assembly,Call,Cpu Registers,我尝试钩住一些函数,不管是x86上的stdcall还是cdecl 我想做以下事情: 1.保存堆栈 2.保留反寄存器 3.做我的事 4.恢复寄存器 5.恢复堆栈 我的堆栈没有问题,但我的寄存器备份确实有一些问题:我无法在不修改某些寄存器的情况下备份寄存器(我无法使用堆栈,因为我无法以这种方式备份堆栈) 我可以将它们备份到堆上(我使用一个包含一些.EAX、.EBX等成员的结构),我从ASM访问该结构,这就是问题所在。。。我必须修改一些寄存器才能做到这一点 然而,这是我的故事。我真正想了解的是以下问题

我尝试钩住一些函数,不管是x86上的stdcall还是cdecl

我想做以下事情:
1.保存堆栈
2.保留反寄存器
3.做我的事
4.恢复寄存器
5.恢复堆栈

我的堆栈没有问题,但我的寄存器备份确实有一些问题:我无法在不修改某些寄存器的情况下备份寄存器(我无法使用堆栈,因为我无法以这种方式备份堆栈)

我可以将它们备份到堆上(我使用一个包含一些.EAX、.EBX等成员的结构),我从ASM访问该结构,这就是问题所在。。。我必须修改一些寄存器才能做到这一点

然而,这是我的故事。我真正想了解的是以下问题的答案:

关于函数调用期间可以修改的寄存器和不修改的寄存器,是否有任何“规则”

我用调试器检查了一些函数调用。我在“调用某个函数”处添加了一个断点,按F8键“跳过函数调用”,然后检查修改的寄存器。我可以看到这样的情况: 1.ESP/EBP可以根据呼叫约定进行修改(cdecl与stdcall) 2.EAX、EBX、EDX-几乎总是经过修改! 3.EBX、EDI、ESI似乎总是保留着

所以我的“伪解决方案”来了:如果我只保留那些寄存器(EBX、EDI、ESI),可以吗?我不会弄乱堆栈,因此EBP和ESP不是问题。但我必须修改一些寄存器(EAX、ECX、EDX)

我在一些编译器优化方面会有问题吗?是否有可能通过修改那些“无辜”寄存器(EAX、ECX、EDX)来搞乱代码


谢谢

不清楚除了保存寄存器的标准技术之外,为什么还需要其他技术。通常的方案是:

    ; call site: push args into stack, move to registers as required for callee
          push  arg1
          push  arg2
          mov   reg, arg3
          call  subroutine
          lea   esp, sizeof(arg1)+sizeof(arg2)[esp]  ; pop arg1 and arg2
          ...

    subroutine:
          push  ebp

          push  reg1     ; save the registers that subroutine is documented to preserve
          ...
          push  regn     ; if you insist, save *all* the registers
          mov   ebp, esp ; now ebp points to stacked args/saved registers no matter what you do next
          ; note: we have not saved the ESP, but we do know how much we pushed on ESP
          ...
          body of subroutine, move ESP up and down
          ...
    subroutine_exit:
          mov    esp, ebp ; now points to saved registers
          pop    regn
          ...
          pop    reg1
          pop    ebp
          ret

是的,调用约定允许您关闭
EAX
ECX
EDX
。我相信微软C++ >代码> ECX < /C> >用于<代码> < <代码>指针。注:这仅适用于遵循约定的功能。如果您试图钩住一个内部函数,而该函数可能已经优化为不使用标准约定,那么它将不起作用


您只需将内容保存在数据部分,如果适用,请特别注意可重入性和并发性。

是的,我会做以下事情:
1.跳转到而不是前5个函数字节(经典挂钩)
2.跳转到仅我的裸体asm功能
3.在我的函数中,我需要调用一些函数(memcpy-还原原始字节,flushintruction缓存)并使用一个结构,因此这里我需要修改一些寄存器
4.我在堆栈上添加了内容,但在堆栈的末尾与“调用”时刻相同
5.我跳转到具有正确堆栈的回调函数(jmp EAX)!我无法回到这里,因为在回调函数中,我需要调用原始函数并返回“call function+5”(返回调用时放在堆栈上的EIP)。我必须跳转到正确的堆栈,因为参数在堆栈上,钩子是通用的,我不知道有多少参数

所以,在回调函数中,我做我的工作,调用原始函数并恢复钩子。我需要的正是:我需要恢复寄存器,或者确保不修改它们,但正如我所说的,我必须这样做

目前,我正试图避免使用EBX、EDI和ESI。我希望它能工作,我不会有优化问题。如果它不起作用,我将尝试在我的结构中备份它们,并在回调函数中恢复它们


谢谢大家!

保留堆栈是什么意思?您并没有真正保留它,只需在完成后恢复SP。是的,我不修改EBP,我只修改恢复ESP。问题比我描述的更复杂。我只需要知道是否可以只保留那些寄存器:EBX、EDI、ESI。@但必须保留所有寄存器。但我不明白你的问题,这听起来很简单;调用函数;调用在堆栈上推送下一个EIP并转到该函数。1.在该函数上,我跳转到我的代码(仅asm函数,裸体)2。我必须调用一些函数并跳转到另一个函数(回调)3。回调函数必须具有与调用之前相同的堆栈(相同的原型)4。执行回调函数后,我必须有未修改的寄存器和stack@lonut对不起,我还是不明白。你想做些定制的还是什么?Wny不是吗?你只是遵循调用约定并保持简单?我假设他在做一个通用钩子,而不知道参数占用了多少空间。我的代码示例不关心他推了多少参数,或者它们是否在寄存器中。但它也不是钩子,或者至少我不明白它是怎么回事。钩子只是一个看起来很有趣的子例程,它保留了寄存器。这样说似乎很奇怪,但子例程只是保留它们使用的寄存器。钩子也一样。