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

GDT not fully working #522

Closed
sparktrend opened this issue Apr 15, 2016 · 14 comments
Closed

GDT not fully working #522

sparktrend opened this issue Apr 15, 2016 · 14 comments

Comments

@sparktrend
Copy link

sparktrend commented Apr 15, 2016

Hi Guys,
I have trouble getting GDT up and running. I call Setup() function in the following class:

https://gist.github.com/sparktrend/4e0f3234449a4524b5a6f30b38d5ebea

This is a slightly corrected version of the sample in regress/x86_gdt.py of the package. I changed the 'access' bit field definition to deal with stack segment and code segment. I can't post the full code because it's really long, but essentially I just call Setup(teb) function after initializing memory map. Basically there are two symptoms:

1 If I enable all selector creations in Setup(), the system triggers segmentation fault 11.
I figured the last line (stack segment selector) causes this trouble. Disabling the ss selector creation, no segmentation fault gets triggered.

2 If I disable ss selector creation, I have the following error:
1301012: call 0x1301002 INVALID MEM-WRITE 0xfd8c/4 *=0x1301017
ERROR: Invalid memory write (UC_ERR_WRITE_UNMAPPED)

ESP at the time of exception was 0x3dfd90. This 'call' instruction attempts to push the return address (0x1301017) onto '0xfd8c' where it, in fact, should have accessed ESP-4, which is 0x3dfd8c.

What do you think causes these symptoms?

BTW, what is the expected behaviour when you don't set the selectors?

Much appreciated,
Sean

@aquynh
Copy link
Member

aquynh commented Apr 15, 2016

is this with the latest Unicorn from Github?

your code is broken. can you post it to gist.github.com, and paste the link here?

@sparktrend
Copy link
Author

I implemented this lengthy code because reg_write(UC_X86_REG_FS, arg) should now take the real selector for the second parameter. I totally agree that correct emulation is important. However, this caused a total mess on our end especially for those people working in Windows world where FS register initialisation is a must for malware emulation. I just wanted to point this out.

Looking forward to your good answer on my problem. Thanks heaps!

@sparktrend
Copy link
Author

Yes I just rebuilt with the source I downloaded from github a couple of days ago. My emulation engine suddenly stopped working, which is the reason why I devoted all day debugging the issue today, but with no result.

@aquynh
Copy link
Member

aquynh commented Apr 15, 2016

your code is broken. can you post it to gist.github.com, and paste the link here?

@sparktrend
Copy link
Author

@aquynh
Copy link
Member

aquynh commented Apr 19, 2016

i run your script on Mac, and see no crash or anything. it just silently returned.
so how to reproduce your issue?

would you mind sending a pull request to put this script under tests/regress/ directory?

thanks.

@sparktrend
Copy link
Author

sparktrend commented Apr 19, 2016

Thanks for your reply.

That code has only a class. It won't run the test. So I wrote a bit of code to do the test at:
https://gist.github.com/sparktrend/3eed134615b96265b0bbe90bd96dd346

You need capstone to run it and I ran it in OS X.

I have embedded a couple of hooks. The messages below occurs when I disable SS selector setup in GDT.

1301000: jmp 0x1301012
1301012: call 0x1301002
ESP at 3dfd90
1301012: call 0x1301002 MEM-WRITE 0xfd8c/4 *=0x1301017
ESP at 3dfd90
1301012: call 0x1301002 INVALID MEM-WRITE 0xfd8c/4 *=0x1301017
ERROR: Invalid memory write (UC_ERR_WRITE_UNMAPPED)
emulation complete

I printed ESP register on memory access and invalid memory access. But as you can see above, unicorn attempts to write to a different stack location. (Also note that I changed A_DIRECTION_DOWN to A_DIRECTION_UP in SS descriptor to see if it makes a difference, which it doesn't.)

In addition, as I mentioned earlier, the code simply crashes if I enable SS selector creation code.

@sparktrend
Copy link
Author

I didn't specify the granularity for flags. I corrected it below. But it still crashes with ss enabled.

https://gist.github.com/sparktrend/256e3af76a2b542bff8c0bd647e3feca

@sparktrend
Copy link
Author

Just to clarify the problem,

I'm not really interested in setting up SS descriptor in GDT as long as it works. So crash when SS descriptor setup is attempted is not a concern for me. The concern is why unicorn accesses a stack location, which appears to be an address with its top 16 bits masked off. With the above test, unicorn accesses 0x0000fd8c when it should access 0x003dfd8c.

Your help is greatly appreciated.

@sparktrend
Copy link
Author

Oh by the way, the above test code works perfectly without GDT set. However, the target sample won't be able to access FS, which occurs in almost all Windows binary files because FS:[0] contains the first pointer to the SEH (Structured Exception Handler) chain that every SEH-enabled binary uses.

@sparktrend
Copy link
Author

sparktrend commented Apr 19, 2016

regress/x86_gdt.py also triggers an exception if you replace 'CODE' variable to a sequence of code that includes 'call' instruction.

CODE = '\xEB\x10\x5B\x4B\x31\xC9\x66\xB9\x96\x02\x80\x34\x0B\x9C\xE2\xFA\xEB\x05\xE8\xEB\xFF\xFF\xFF\x1F\x78\x6C\xAD\x55\xF8\x17\xED\xAC'

This proves unicorn's GDT implementation has some real issue there.

@cseagle
Copy link
Contributor

cseagle commented Apr 19, 2016

I think this is a privilege level thing. The path that this goes through in the qemu code requires cpl to match dpl and rpl in order to set SS and the cpl is 0 during emulations. Try changing from A_PRIV_3 to A_PRIV_0 for your CreateSegmentSelector on ss. You will also need to set S_PRIV_0 rather than S_PRIV_3 when you call create_selector for SS only.. Also see samples/sample_x86_32_gdt_and_seg_regs.c

@sparktrend
Copy link
Author

I changed to A_PRIV_0 and S_PRIV_0 for all segment registers. It works like a charm!

Thanks heaps, cseagle.

@lunixbochs
Copy link
Contributor

I'm still having trouble setting SS, @sparktrend did you get that working?

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

4 participants