[英]Illegal assembly instruction in C
我正在尝试使用 C 程序生成汇编指令跟踪。 我正在使用 asm 函数插入在 x86_64 中非法的汇编指令并检测它们。
我有以下 C 程序 -
int main()
{
asm(".byte 0x16"); // Illegal in x86_64
asm(".byte 0x17"); // Illegal in x86_64
return 0;
}
这是主函数的指令跟踪,这是预期的 -
.text:004004d6 55 push %rbp
.text:004004d7 48 89 e5 mov %rsp,%rbp
.text:004004da 16 (bad)
.text:004004db 17 (bad)
.text:004004dc b8 00 00 00 00 mov $0x0,%eax
.text:004004e1 5d pop %rbp
.text:004004e2 c3 retq
.text:004004e3 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:0x0(%rax,%rax,1)
.text:004004ed 0f 1f 00 nopl (%rax)
我正在使用英特尔 PIN 来运行程序跟踪,并根据我得到的指令进行某种分析。 因此,对于(坏的)指令,它们是非法的,从而导致程序崩溃。 我检查跟踪中每条指令的指令地址以及下一条指令的地址。
Pin所示的mov %rsp, %rbp指令的下一条指令地址(地址0x004004d7,0x16指令之前的那个)是0x0。 当下一条指令是条件/无条件分支指令时,0x0 由 Pin 显示。 由于它也显示为错误指令,我怀疑错误指令正在调用终止程序并给出以下消息的异常处理程序 -
Illegal instruction (core dumped)
我正在使用 Pin 来检测指令,当我收到非法指令时,我会进行某种模拟,然后删除该指令,以便跟踪可以进一步进行。
是否有任何类型的设置/标志来禁用此非法指令异常生成?
我正在使用 gcc 生成我的可执行文件,它可以简单地编译而不会产生错误。 当我执行指令时问题就来了。 当遇到非法指令时,是否有任何设置只是简单地遍历指令?
根据要求,这是我用来将ud2
未定义指令修补到ud2
核机器上的nop nop
和多核机器上的nop lock
。 我删除了与您的用例完全无关的代码:
void __gmon_start__(void)
{
if(ill) return;
ill=true;
struct sigaction act;
memset((void *) &act, 0, sizeof(act));
act.sa_sigaction=sigill;
act.sa_flags=SA_SIGINFO;
sigaction(SIGILL, &act, NULL);
// more code to set IsUP goes here
}
和:
static void sigill(int, struct siginfo *info, void *extra)
{
// Dynamically patch a 'ud2' to a 'nop lock' or a 'nop nop'
// Begin with a full CPU sync (purge unmodified code)
__asm__ __volatile__("cpuid" : : : "ax", "bx", "cx", "dx");
// There was code here to acquire a mutex to prevent
// multiple attempts to change the same code
ucontext_t *uc=(ucontext_t *) extra;
if (uc==NULL) { char *j=NULL; *j++; } // fatal
unsigned char *instr=(unsigned char *) uc->uc_mcontext.gregs[14]; // EIP
if(instr==NULL) { char *j=NULL; *j++; } // fatal
if(instr[0] != 0x90)
{ // instruction wasn't already patched
if ( (instr[0] != 0x0f) || // must be a ud2
((instr[1] != 0x0b) && (instr[1] != 0xb9)) )
{ char *j=NULL; *j++; } // fatal
mprotect( (void *) ( ((int) instr) & ~(PAGESIZE-1)),
PAGESIZE, PROT_WRITE | PROT_EXEC | PROT_READ);
instr[0] = 0x90; // first byte is always a nop
instr[1] = (IsUP) ? 0x90 : 0xf0;
mprotect( (void *) ( ((int) instr) & ~(PAGESIZE-1)),
PAGESIZE, PROT_EXEC | PROT_READ);
}
// mutex was released here
// Reflush the CPU
__asm__ __volatile__("cpuid" : : : "ax", "bx", "cx", "dx");
}
抱歉,代码一团糟。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.