angr / tracer

Utilities for generating dynamic traces
BSD 2-Clause "Simplified" License
88 stars 28 forks source link

Basic block's max size in Qemu is greater than the one in angr ? #40

Closed joyceqi closed 2 years ago

joyceqi commented 7 years ago

Hello, I have been using tracer with an elf. I find that when there is a large basic block, qemu will recognize it as one BB, but angr will take it as two BBs, which causes "the dynamic trace and the symbolic trace disagreed" . How would I fix it? Thanks! qq20170827-0 de82f125-cb9d-452f-bdf3-47c30ed22acc

rhelmot commented 7 years ago

That is... very strange. The 800 number isn't the hardcoded limit in angr, but a number we added to tracer because we thought that was the size limit for qemu's basic blocks. You can try increasing it in tracer to see what happens, but libvex has a hard limit of 99 machine instructions per basic block.

salls commented 7 years ago

We had the issue where angr's basicblocks were bigger than in qemu so we limited it to match. That was on 32 bit x86. Maybe the max qemu basic block size is different on 64 bit or has changed.

joyceqi commented 7 years ago

@rhelmot The fact is that the basic block got from libvex just only includes instructions until 0x4242CD, which should be limited by the num "99". So does it means that if I change the hard limit to a larger number, I would fix this problem?

joyceqi commented 7 years ago

@salls Yes, the binary I test is 64bit. I really don't know what's the max size of qemu basic block and how can I get this information? What's more, another similar issue happened where angr and qemu both recognize one large BB as two, but they step to two different instructions ...

salls commented 7 years ago

I think we looked at qemu source code last time to check its max bb size. Maybe we should have some other solution for when angr has a smaller basic block size. Like detect it and step 2x

ltfish commented 7 years ago

Why can't we handle the mismatch more intelligently, i.e., when we see a mismatch, we either try to step less bytes (if the latest Qemu block is smaller than the latest angr block), or step again (if the latest Qemu block is larger than the latest angr block). What do you think?

salls commented 7 years ago

I think it should be possible, but we have to be careful. We have no way to check the size of the qemu block at the moment. There can be situations where a block jumps back to the middle of itself. We have to differentiate that from the case where the max block sizes didn't match. So we need to do some extra checks

zardus commented 7 years ago

I do a lot of this in the CongruencyChecker. Exporting that logic and merging it with the existing checks in tracer would probably be a good step.

On Aug 27, 2017 5:43 PM, "salls" notifications@github.com wrote:

I think it should be possible, but we have to be careful. We have no way to check the size of the qemu block at the moment. There can be situations where a block jumps back to the middle of itself. We have to differentiate that from the case where the max block sizes didn't match. So we need to do some extra checks

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/angr/tracer/issues/40#issuecomment-325235853, or mute the thread https://github.com/notifications/unsubscribe-auth/ADSzly61azfiIcq20NJByD-sQ9kVC-y4ks5scg0tgaJpZM4PDuWX .

tyb0807 commented 7 years ago

@joyceqi Do you mind uploading the problematic binary?

Thank you

joyceqi commented 7 years ago

binary.zip

tyb0807 commented 7 years ago

Thanks, but can you give me the input and all other options that you passed to tracer as well?

joyceqi commented 7 years ago

@tyb0807 It seems that tracer doesn't deal with binaries that accept a cmd file as input. So I implement it in personal way, which can't be for your reference. But the command is: ./binary -f lame_input out.wav You can try with your way :) lame_input.zip

tyb0807 commented 7 years ago

So how did you do to trigger the issue? I'm trying to reproduce it but yeah, tracer doesn't read the input correctly I think...

joyceqi commented 7 years ago

I init the entry_state in this way, but I am not very sure ...

cmd_file = 'lame_input' args = ['./binary','-f',cmd_file,'out.wav'] entry_state = project.factory.full_init_state( add_options=self.add_options, remove_options=self.remove_options, args = args) with open(cmd_file, "r") as f: content = f.read() fs = {cmd_file:simuvex.storage.file.SimFile( cmd_file, "rw", size=len(content)} fs[cmd_file].set_state(entry_state) entry_state.posix.fs = fs

tyb0807 commented 7 years ago

I'm not sure I have understood correctly. What did you do after creating that entry_state? What are the options that you've passed to tracer? Can you post your Python script that triggered the the dynamic trace and the symbolic trace disagreed error here ?

Thanks

joyceqi commented 7 years ago

tracer_test.zip I upload with another tracer.py with a little change made by myself. I am not sure whether you can reproduce successfully.

edmcman commented 2 years ago

This is affecting me too