如何在64位Windows上的C代码中发出0x2D中断?

问题描述 投票:0回答:1

我正在寻找一种从C代码发出中断0x2D的方法,就像你可以使用__debugbreak()发出int 3一样

在x86上,我可以使用内联汇编

__asm
{
    int 2dh
}

但我需要一个适用于以下方面的解决方案:

  • x64并且是Visual Studio特定的(最低要求)
  • x86和x64,编译器独立(最佳解决方案)
c windows x86 x86-64 interrupt
1个回答
3
投票

由于x64 Visual Studio根本不支持内联汇编(最后我听说过),你最好的独立于编译器的解决方案是编写一个定义函数的.asm文件,让我们称它为int_2d,只发出这个中断然后返回。您将.asm文件编译为目标文件,将该目标文件与应用程序的其余部分链接,然后您可以在头文件中编写extern void int_2d(void);,并在需要发出中断时从C中正常调用它。

对于the assembler that ships with x64 Visual Studio.asm文件应该如下所示:

_TEXT segment 'CODE'

int_2d proc 
    xor eax,eax 
    int 2dh 
    nop
    ret 
int_2d endp 

_TEXT ENDS 
END

nop之后的int 2dh是必要的,因为根据所使用的操作码以及进程是否附加了调试器,INT 2D处理程序可能会或者可能不会在int指令之后立即导致一个字节的代码(不是一条指令)跳过。所以你需要在那里放一个字节的NOP。

INT 2D还需要A寄存器中的操作码; known values of this opcode的范围从0到5,我没有运气找到他们实际做的文件。示例代码任意选择将A设置为0.(您不需要保存和恢复它,因为A在所有Windows调用约定中都是call-clobbered。)如果要将操作码作为参数传递,可以这样做:

_TEXT segment 'CODE'

int_2d proc 
    mov eax, ecx
    int 2dh 
    nop
    ret 
int_2d endp 

_TEXT ENDS 
END

但是你必须将C侧的函数声明为__fastcall void int_2d(uint32_t op);(我认为__fastcall是不必要的,但无害,在64位模式下进行编译时。)

不幸的是,我不知道如何为需要使用尽可能多的不同Windows工具链的.asm文件编写“样板”(除了实际的汇编指令之外的所有其他内容)。例如,NASM可能无法接受上述内容。

© www.soinside.com 2019 - 2024. All rights reserved.