也许我很愚蠢,但我的确没有看到他们的文档中的任何内容。
说我仿真此代码

mov eax, 1
mov ecx, 2


然后我可以得到如下结果: />现在我不得不怀疑-当我从一个未定义的寄存器读取数据时,例如ESI,会发生什么?该寄存器是未定义的,而不是“ 0”?

#1 楼

一个仿真器需要您的输入来仿真,如果您未定义某些内容,您显然会得到使用

初始化的内容。显然,对于所有寄存器,独角兽都以0初始化。 src使用给定的api读取所有寄存器

:\>cat testumu.cpp
#include "unicorn.h"
#pragma comment(lib,"unicorn.lib")
#define REG_NUMS 9
void main (void) {
    uc_engine *uc;
    int regs[REG_NUMS]  = {
        UC_X86_REG_EAX,UC_X86_REG_EBX,UC_X86_REG_ECX,
        UC_X86_REG_EDX,UC_X86_REG_EBP,UC_X86_REG_ESP,
        UC_X86_REG_ESI,UC_X86_REG_EDI,UC_X86_REG_EIP
    };
    int bugs[REG_NUMS] = {1,2,3,4,5,6,7,8,9};
    void *vals[REG_NUMS];
    for(int i =0; i<REG_NUMS;i++) {
        vals[i] = &bugs[i];
    }
    printf("values before reading\n\n");
    for(int i =0 ; i< REG_NUMS; i++) {
        printf("%x\t%x\n" , regs[i],*(int *)vals[i]);
    }
    if((uc_open(UC_ARCH_X86, UC_MODE_32, &uc)) == UC_ERR_OK) {
        uc_reg_read_batch(uc,regs,vals,9);
    }
    printf("values after reading\n\n");
    for(int i =0 ; i< REG_NUMS; i++) {
        printf("%x\t%x\n" , regs[i],*(int *)vals[i]);
    }
}


与vc2017社区cmd编译并链接,提示x86

:\>cl /nologo /Zi /W4 /analyze /Ox testumu.cpp /link /release
testumu.cpp

:\>


编译后的可执行文件的结果

:\>testumu.exe
values before reading

13      1
15      2
16      3
18      4
14      5
1e      6
1d      7
17      8
1a      9
values after reading

13      0
15      0
16      0
18      0
14      0
1e      0
1d      0
17      0
1a      0

:\> 


评论


我要找出的本质上是给定的模拟asm是否被修改/设置了寄存器。为此,我可以将所有寄存器设置为某个魔术值,然后在仿真后检查哪些不同。我想知道是否有更好的方法。

–伯恩·费曼
17年11月19日在23:19

#2 楼

Unicorn仅支持寄存器中的具体值。
您可以通过使用两组魔术值进行两次运行来欺骗自己的方法。执行后,这些寄存器可以是未定义的,甚至可以包含表达式树,例如old_ebx * 2 + 1。