Gcc 在X86代码中插入一条未定义的指令,由英特尔引脚检测
我正在使用一个基于PIN的模拟器来测试一些新的架构修改。我需要使用我的模拟器用两个操作数(一个寄存器和一个内存位置)测试一条“新”指令 由于使用GCC机器描述只添加一条指令很乏味,因此使用NOPs或未定义的指令似乎是合乎逻辑的PIN可以使用Gcc 在X86代码中插入一条未定义的指令,由英特尔引脚检测,gcc,assembly,x86,inline-assembly,intel-pin,Gcc,Assembly,X86,Inline Assembly,Intel Pin,我正在使用一个基于PIN的模拟器来测试一些新的架构修改。我需要使用我的模拟器用两个操作数(一个寄存器和一个内存位置)测试一条“新”指令 由于使用GCC机器描述只添加一条指令很乏味,因此使用NOPs或未定义的指令似乎是合乎逻辑的PIN可以使用INS_IsNop轻松检测NOP指令,但它会干扰自然添加到代码中的NOP,它也没有操作数或只有一个内存操作数 剩下的唯一选项是使用和未定义的指令。未定义的指令永远不会干扰代码的其余部分,可以通过INS\u IsInvalid通过PIN检测到 问题是我不知道如何
INS_IsNop
轻松检测NOP指令,但它会干扰自然添加到代码中的NOP,它也没有操作数或只有一个内存操作数
剩下的唯一选项是使用和未定义的指令。未定义的指令永远不会干扰代码的其余部分,可以通过INS\u IsInvalid
通过PIN检测到
问题是我不知道如何使用GCC内联汇编添加未定义的指令(带操作数)。我该怎么做呢?所以x86有一条明确的“未知指令”(请参阅)。gcc可以通过简单地使用:
asm("ud2");
对于带有操作数的未定义指令,我不确定这意味着什么。一旦您有了一个未定义的操作码,附加的字节将全部未定义
但也许你可以通过以下方式得到你想要的:
asm(".byte 0x0f, 0x0b");
尝试使用通常不适用于指令的前缀。e、 g
rep add eax, [rsi + rax*4 - 15]
会很好的。有些指令集扩展是这样做的。e、 g.lzcnt
编码为rep bsf
,因此它在较旧的CPU上执行为bsf
,而不是生成非法指令异常。(根据x86 ISA的要求,不适用的前缀将被忽略。)
这将使您能够利用汇编程序对指令操作数进行编码的能力,正如David Wohlferd在他的回答中所指出的,如果您使用
ud2
则这是一个问题。该指令仅在GCC中未定义,对我来说,它是我的新指令的表示。假设我的新指令是add OP1,OP2。我会使用PIN来提取操作数,然后插入对INS_Delete()的调用,这样指令就不会引发异常。如果目标是生成GCC不理解的asm操作码,那你就倒霉了。GCC不解释操作码。在asm中放入任何内容,gcc将只输出它。如果目标是输出汇编程序不理解的操作码,那么可以使用asm(“xxx1,2”),汇编程序将拒绝它。如果目标是输出CPU不理解的操作码,那么可以使用“已知”无效操作码(ud2)。类似于asm(“.byte 0x0f,0x0b,0x90,0x90”)的代码怎么样。这将生成(看起来像)一条不会自然出现的4字节指令。您能解释一下为什么0x0f、0x0b
是特殊的吗?它们是否在x86中是无效的操作码,因此使用它们将导致非法指令?@umopapidn检查ud2的。根据您的问题,您这里的问题是在gcc中发出未定义的指令。从您的评论来看,另一个问题似乎是解码指令。你有没有其他问题?