Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

X86_64 code behaves differnt execute single stepped compared to just let it run #999

Closed
pgarba opened this issue Aug 14, 2018 · 4 comments
Closed

Comments

@pgarba
Copy link

pgarba commented Aug 14, 2018

When I single step the x86_64 code with:

uc_emu_start(uc, CurrentVA, -1, 0, 1);

then the code flow is correct.

But when I execute the code with with:

uc_emu_start(uc, CurrentVA, -1, 0, 0);

The code will take a wrong branch and the application will crash.
So far I don't have a test case because its a big application but maybe someone knows the reason and how to avoid the bug.

Thanks

@pgarba
Copy link
Author

pgarba commented Aug 16, 2018

I was able to pinpoint the problem and create a test for it.
It seems that the CF is not set properly.

const uint8_t Code[] = {
0xC1, 0xE6, 0x12, // shl esi, 12h
0x0F, 0x82, 0x4B, 0x8C, 0xF9, 0xFB, // jb wrong_branch
0xCC // int 3
};

const uint64_t ADDR_CODE = 0x1000;
const uint64_t PAGE_SIZE = 0x1000;
const uint64_t EP = 0x1000;

int main(void) {
uc_engine *uc;

uc_open(UC_ARCH_X86, UC_MODE_64, &uc);

uc_mem_map(uc, ADDR_CODE, PAGE_SIZE, UC_PROT_ALL);
uc_mem_write(uc, ADDR_CODE, Code, sizeof(Code));

// Set high bit of ESI
uint64_t RSI = 0xF0000000;
uc_reg_write(uc, UC_X86_REG_RSI, &RSI);

// Execute until error reached
uint64_t CurRIP = EP;
uc_err err;
do {
	err = uc_emu_start(uc, CurRIP, ADDR_CODE + sizeof(Code), 0, 0);

	uc_reg_read(uc, UC_X86_REG_RIP, &CurRIP);
} while (err == UC_ERR_OK);

// Store Current RIP
uint64_t RIP_Unlimited = CurRIP;

// Run again
// Set high bit of ESI
RSI = 0xF0000000;
uc_reg_write(uc, UC_X86_REG_RSI, &RSI);

CurRIP = EP;
do {
	err = uc_emu_start(uc, CurRIP, ADDR_CODE + sizeof(Code), 0, 1);

	uc_reg_read(uc, UC_X86_REG_RIP, &CurRIP);
} while (err == UC_ERR_OK);

// close unicorn
uc_close(uc);

// check if both runs reached the same RIP
if (RIP_Unlimited != CurRIP) {
	printf("Test failed!\n");
	printf("0x%016llX != 0x%016llX\n", CurRIP, RIP_Unlimited);
}
else {
	printf("Test passed!\n");
}

return 0;

}

@pgarba
Copy link
Author

pgarba commented Aug 16, 2018

The problem seems to be related to the injected code by check_exit_request.
The fix from #287 is not working for x86_64 and should be updated.

@Coldzer0
Copy link
Contributor

Coldzer0 commented Aug 17, 2018

i tested the code with FreePascal on Mac OS
with both mode UC_MODE_32 and UC_MODE_64

and there's a problem with "shl" on single step

i try to trace the problem , but failed 😕

@aquynh i think you need to look into this

i tested it with
0x0 : $C1 ,$E6 ,$12 , // shl esi, 12h`
0x3 : $0F ,$82 ,$01 ,$00 ,$00 ,$00 // jb 0000000A
0x9 : ,$CC // int3
0xA : ,$90

i set CF to 1 before the Execution
and result

just run

code --- PC is 0x100000 - Flag CF : 1
code --- PC is 0x100003 - Flag CF : 0
code --- PC is 0x10000A - Flag CF : 0

==================================

Single Step

code --- PC is 0x100000 - Flag CF : 1
code --- PC is 0x100003 - Flag CF : 0
code --- PC is 0x100009 - Flag CF : 0 // this is not good

but when i remove

0x0 : $C1 ,$E6 ,$12 , // shl esi, 12h`

and set CF manually it run as expected in both "just run" & "single step"

0x0 : $0F ,$82 ,$01 ,$00 ,$00 ,$00 // jb 0000000A
0x6 : ,$CC // int3
0x7 : ,$90

CF = 1

just run

code --- PC is 0x100000 - Flag CF : 1
code --- PC is 0x100007 - Flag CF : 1

==================================

Single Step

code --- PC is 0x100000 - Flag CF : 1
code --- PC is 0x100007 - Flag CF : 1

CF = 0

just run

code --- PC is 0x100000 - Flag CF : 0
code --- PC is 0x100006 - Flag CF : 0

==================================

Single Step

code --- PC is 0x100000 - Flag CF : 0
code --- PC is 0x100006 - Flag CF : 0

@Coldzer0
Copy link
Contributor

@aquynh
any update on this ?
and do you gona update to latest QEMU ?

@wtdcode wtdcode closed this as completed Oct 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants