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

Issues with count for code patching #1512

Merged
merged 2 commits into from Dec 22, 2021
Merged

Conversation

QDucasse
Copy link
Contributor

@QDucasse QDucasse commented Dec 10, 2021

Hello, when rewriting (what I called code patching) the code memory to change an instruction, the previous instruction will be executed instead.
In the tests, I wrote an add 1 to a register, emulated to see the result, then overwrote the instruction with add 7ff to the same register and re-emulated. When using the start_address/end_address method, the execution of the new instruction proceeds however when using a count, the previous instruction is executed instead.

@wtdcode
Copy link
Member

wtdcode commented Dec 10, 2021

I believe it should be addressed by this unit test:

static void test_x86_clear_tb_cache()

Really weird but a workaround is uc_ctl_remove_cache on the instruction before emulation.

@guillep
Copy link
Contributor

guillep commented Dec 17, 2021

I believe it should be addressed by this unit test:

static void test_x86_clear_tb_cache()

Really weird but a workaround is uc_ctl_remove_cache on the instruction before emulation.

Do you mean that we need to flush some cache using uc_ctl_remove_cache after patching code? I think that's a good solution. I don't expect unicorn to realize that we are overwriting code...

@wtdcode
Copy link
Member

wtdcode commented Dec 17, 2021

I believe it should be addressed by this unit test:

static void test_x86_clear_tb_cache()

Really weird but a workaround is uc_ctl_remove_cache on the instruction before emulation.

Do you mean that we need to flush some cache using uc_ctl_remove_cache after patching code? I think that's a good solution. I don't expect unicorn to realize that we are overwriting code...

Not exactly. Unicorn tracks all code page and when you are overwriting code, the cache should be flushed accordingly.

@wtdcode
Copy link
Member

wtdcode commented Dec 22, 2021

Okay, I confirm it's a bug. The code cache is not flushed by uc_mem_write.

@wtdcode
Copy link
Member

wtdcode commented Dec 22, 2021

After some investigation, I'm aware that it's not a bug. It's somewhat subtle for this case. Internally, uc_mem_write would treat the address as the physical address while the translation cached is based on the virtual address. Unfortunately, the conversion from virtual address to physical address is straightforward and easy while the vice versa is almost impossible (consider: 1. many virtual addresses are mapped to the same physical address 2. some virtual address is not backed by virtual address). Thus, @guillep is correct: We don't know whether the user is overwriting some code or data during uc_mem_write and therefore it's users' responsibility to flush cache when they are patching some code.

Btw, SMC code, i.e. the code that patching themselves during emulation works fine and doesn't need extra care.

@wtdcode wtdcode merged commit dfb14e9 into unicorn-engine:dev Dec 22, 2021
@wtdcode
Copy link
Member

wtdcode commented Dec 22, 2021

Merged, thanks.

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

Successfully merging this pull request may close these issues.

None yet

3 participants