3

Maybe I am stupid, but I really dont see anything in their documentation. Say I emulate this code

mov eax, 1
mov ecx, 2

Then I can get the result like so:

int rr;
uc_reg_read(uc, UC_X86_REG_ECX, &rr);

Now I have to wonder - what happens when I read from an undefined register, say ESI?

uc_reg_read(uc, UC_X86_REG_ESI, &rr);

Answer is rr == 0. But how can I detect that this register is undefined, rather than '0'?

1

an emulator requires your input to emulate if you didn't define something you would obviously get what it was initialized with

apparently unicorn starts initialized with 0 for all registers it seems

src to read all registers using the given 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]);
    }
}

compiled and linked with vc2017 community cmd prompt for x86

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

:\>

results of compiled executable

:\>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

:\> 
  • what i want to find out is essentially if a given emulated asm snipped modified/set a register. For that I could set all the register to some magic value and then check after emulation which ones differ. I am wondering if there is a better method. – bernd feinman Nov 19 '17 at 23:19
1

Unicorn only supports concrete values in registers. You could cheat your way around this by doing two runs with two sets of magic values.

But what you really want is a symbolic execution framework like angr. There registers can be undefined after execution or even contain expression trees like old_ebx*2+1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.