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

Add ability to mark memory area read only. Add new API uc_mem_map_ex t… #60

Merged
merged 20 commits into from
Aug 29, 2015
Merged

Conversation

cseagle
Copy link
Contributor

@cseagle cseagle commented Aug 26, 2015

Add ability to mark memory area read only. Add new API uc_mem_map_ex to allow permissions to be passed. Change MemoryBlock to track created MemoryRegions. Add regress/ro_mem_test.c

This also solves the memory leak issue on uc->ram because now all MemoryRegion allocations are tracked in the uc->mapped_blocks array.

…o allow permissions to be passed. Change MemoryBlock to track created MemoryRegions. Add regress/ro_mem_test.c
@cseagle cseagle changed the title Add ability to mark memory are read only. Add new API uc_mem_map_ex t… Add ability to mark memory area read only. Add new API uc_mem_map_ex t… Aug 26, 2015
@aquynh
Copy link
Member

aquynh commented Aug 27, 2015

you do not setup the stack in the sample ro_mem_test.c, but somehow this still works ??

@cseagle
Copy link
Contributor Author

cseagle commented Aug 27, 2015

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Good point. Magic I guess. I will investigate.

On 8/26/2015 9:06 PM, Nguyen Anh Quynh wrote:

you do not setup the stack in the sample |ro_mem_test.c|, but
somehow this still works ??

— Reply to this email directly or view it on GitHub
<#60 (comment)
351>.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (MingW32)

iEYEARECAAYFAlXejhcACgkQ9zL2pkgLDWmlYgCdG5Q6oRMXPN44Fzzf5BdxVvAA
CQAAn2HnLG20ZMHmTOSCnfkf2xNYUkHl
=yrE5
-----END PGP SIGNATURE-----

@aquynh
Copy link
Member

aquynh commented Aug 27, 2015

few more things:

  • please sync with upstream, because there is a minor conflict at the moment in Makefile.
  • the main() function should return int value. current code either just return;, or do not return anything at the end.
  • there are few other warnings on printf() arguments, but apparently your compiler does not report them. can you find a way to turn on the warning messages?

thanks.

@cseagle
Copy link
Contributor Author

cseagle commented Aug 27, 2015

Will you paste the warnings please? It would help me figure out what compiler options you may henabled that I do not.

@aquynh
Copy link
Member

aquynh commented Aug 27, 2015

sure, there are the warnings generated by Clang on OSX: https://gist.github.com/aquynh/58f83e579f6d32695e58

@cseagle
Copy link
Contributor Author

cseagle commented Aug 27, 2015

Note that you will need to decide what to do with the uc_struct.ram field as seems to no longer be needed, but I do not know what your design goal for that field was.

@aquynh
Copy link
Member

aquynh commented Aug 27, 2015

a question: we can intercept invalid memory access events via hooking, like in hook_mem_invalid() in sample_x86.c. have you investigated if you can still do that now with this PR, after you write protect the memory with uc_mem_map_ex(handle, 0x400000, 0x4000, UC_PROT_READ | UC_PROT_EXEC)? do you still get the callback executed when writing to this memory?

thanks.

@cseagle
Copy link
Contributor Author

cseagle commented Aug 27, 2015

Yes, you still receive the hook_mem_invalid callbacks for regions that are not mapped. I will change ro_mem_test to demonstrate by omitting the stack, then mapping it in in the callback.

@aquynh
Copy link
Member

aquynh commented Aug 27, 2015

no, i mean that if you do not write protect the memory, the emulated code (with MOV instruction) works without any issue. now because you write protect it, MOV will fail. i am asking if you now can intercept this failure with UC_HOOK_MEM_INVALID, or not. if not, then we need to handle this situation now.

@cseagle
Copy link
Contributor Author

cseagle commented Aug 27, 2015

Ah ok, let me test

@cseagle
Copy link
Contributor Author

cseagle commented Aug 27, 2015

The answer is that no error condition is recognized in uc_emu_start. So, while the memory is in fact read only, no signal is propagating out of uc_emu_start, so it will need its own detection and error code

@cseagle
Copy link
Contributor Author

cseagle commented Aug 27, 2015

This should probably be detected at the same places memory writes are detected in the softmmu. The big question is whether you want to overload the meaning of UC_ERR_MEM_WRITE which currently means that a write outside a mapped region occurred, or do you want to introduce a new error type or new uc_mem_type value. I think a new uc_mem_type such as UC_MEM_WRITE_RO might work.

@aquynh
Copy link
Member

aquynh commented Aug 27, 2015

yes adding that new error code sounds OK.

@radare
Copy link
Contributor

radare commented Aug 27, 2015

why use uc_mem_map_ex? what’s the meaning of that “ex” suffix suposed to be?

imho _prot or _perm sounds better to me for that purpose.

On 27 Aug 2015, at 10:09, Nguyen Anh Quynh notifications@github.com wrote:

yes adding that new error code sounds OK.


Reply to this email directly or view it on GitHub #60 (comment).

@aquynh
Copy link
Member

aquynh commented Aug 27, 2015

i think "ex" here means "extended". this is the typical way to name API in Windows platform, when they want to extend the existing API to add more features/functionalities.

since we do not need to worry backward compatibility, we can think about extending the original uc_mem_map() to have one more argument about permission, without having to add uc_mem_map_ex() like this.

@radare
Copy link
Contributor

radare commented Aug 27, 2015

+1 for adding one parameter for it, but then we will need another function to change those permissions after the map is allocated.

On 27 Aug 2015, at 15:15, Nguyen Anh Quynh notifications@github.com wrote:

i think "ex" here means "extended". this is the typical way to name API in Windows platform, when they want to extend the existing API to add more features/functionalities.

since we do not need to worry backward compatibility, we can think about extending the original uc_mem_map() to have one more argument about permission, without having to add uc_mem_map_ex() like this.


Reply to this email directly or view it on GitHub #60 (comment).

@cseagle
Copy link
Contributor Author

cseagle commented Aug 27, 2015

The general idea is that uc_mem_map_ex would supersede uc_mem_map, hence the nearly identical name. I need to get it all working cleanly first. Once that happens, I have every intention of adding a uc_mprotect and a uc_munmap.

@radare
Copy link
Contributor

radare commented Aug 27, 2015

why not follow the standard naming as uc_mem_protect() and uc_mem_unmap() ?

On 27 Aug 2015, at 17:29, Chris Eagle notifications@github.com wrote:

The general idea is that uc_mem_map_ex would supersede uc_mem_map, hence the nearly identical name. I need to get it all working cleanly first. Once that happens, I have every intention of adding a uc_mprotect and a uc_munmap.


Reply to this email directly or view it on GitHub #60 (comment).

…lity on write to read only. Add new error type UC_ERR_MEM_WRITE_RO and new access type UC_MEM_WRITE_RO for use in callback
@cseagle
Copy link
Contributor Author

cseagle commented Aug 28, 2015

That is fine with me I will use those names when I get over the basic read only memory implementation

@aquynh
Copy link
Member

aquynh commented Aug 28, 2015

we also need to put mem_protect.c into samples/Makefile to compile it.

thanks.

@aquynh
Copy link
Member

aquynh commented Aug 28, 2015

another issue with uc_mem_protect is that while we have "address" & "size" parameters, internally it seems to set permission for the whole region, but not only for the range [address, address + size]. any solution for this?

btw, it would be nice if you open another branch, and issue another PR for uc_mem_protect, since your work on setting the permission for uc_mem_map() seems to be ready to merge.

thanks.

@cseagle
Copy link
Contributor Author

cseagle commented Aug 28, 2015

Regarding uc_mem_protect, it needs more research to figure out how to split MemoryRegions with the qemu api, until then, it would be necessary to force changing permissions on entire blocks only to at least stub out an API that people can work on

@aquynh
Copy link
Member

aquynh commented Aug 28, 2015

two functions getMemoryBlock and memory_mapping are similar. please use one, and remove the other.

another thing: so far we can deal with the case of writing to read-only memory. do we need to also handle the case of reading from memory with no permission? is there such a case, when we map memory with 0 permission - no RWX at all?

thanks.

@cseagle
Copy link
Contributor Author

cseagle commented Aug 28, 2015 via email

@JonathonReinhart
Copy link
Member

@cseagle Well normally I would say it is useful to trigger a trap when that memory is accessed, so you can do different things. However in this case, we already have the memory read hook, so allowing non-readable memory might not be useful in unicorn.

@aquynh
Copy link
Member

aquynh commented Aug 28, 2015

this is just a question to make sure we handle all the corner cases. it is trivial to implement, anyway.

if you do not want this situation, then uc_mem_map() must reject permission without UC_PROT_READ. then we might come back to this in the future if this should be handled differently.

@cseagle
Copy link
Contributor Author

cseagle commented Aug 28, 2015

Ok now it rejects reads from non-readable regions

@aquynh
Copy link
Member

aquynh commented Aug 28, 2015

i merged this with some minor fixes into a new branch "mem_map_ex". will look closer before merging it to the "master" branch.

thanks.

@aquynh
Copy link
Member

aquynh commented Aug 28, 2015

i feel that UC_ERR_MEM_WRITE_NW & UC_ERR_MEM_READ_NR are not very intuitive. it is hard to figre out what "N" means here.

how about these names instead: UC_ERR_MEM_WRITE_RO & UC_ERR_MEM_READ_WO ?

thanks.

@cseagle
Copy link
Contributor Author

cseagle commented Aug 28, 2015

If we add an execute but in the future then the memory is not nessarily RO
or WO. I borrowed from NX for not executable. Feel free to change if you
wish but RO and WO will become misnomers.
On Aug 28, 2015 7:20 AM, "Nguyen Anh Quynh" notifications@github.com
wrote:

i feel that UC_ERR_MEM_WRITE_NW & UC_ERR_MEM_READ_NR are not very
intuitive. it is hard to figre out what "N" means here.

how about these names instead: UC_ERR_MEM_WRITE_RO & UC_ERR_MEM_READ_WO ?

thanks.


Reply to this email directly or view it on GitHub
#60 (comment)
.

@JonathonReinhart
Copy link
Member

Why not follow the mmap(2) convention:

The prot argument describes the desired memory protection of the
   mapping (and must not conflict with the open mode of the file).  It
   is either PROT_NONE or the bitwise OR of one or more of the following
   flags:

   PROT_EXEC  Pages may be executed.

   PROT_READ  Pages may be read.

   PROT_WRITE Pages may be written.

   PROT_NONE  Pages may not be accessed.

@cseagle
Copy link
Contributor Author

cseagle commented Aug 28, 2015 via email

printf("BEGIN execution - 2\n");
uint32_t eax = 0x40002C;
uc_reg_write(handle, UC_X86_REG_EAX, &eax);
err = uc_emu_start(handle, 0x400015, 0x400000 + sizeof(PROGRAM), 0, 2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this 0x400015 here? do you really mean 0x400000 ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems you want to start from mov dword ptr [eax], 0x87654321. some more comments in the source should be helpful here.

@cseagle
Copy link
Contributor Author

cseagle commented Aug 28, 2015 via email

@aquynh
Copy link
Member

aquynh commented Aug 28, 2015

these error code are starting to get ugly. perhaps we should keep them simple to be just UC_ERR_MEM_WRITE & UC_ERR_MEM_READ ?

@JonathonReinhart
Copy link
Member

@cseagle I missed the ERR part. Sorry for the noise.

@cseagle
Copy link
Contributor Author

cseagle commented Aug 28, 2015

I have no problem with that either. It does make it harder for the
programmer to determine exactly which read or write related issue occured.
With a robust enough set of apis that should still be possible.
On Aug 28, 2015 8:37 AM, "Nguyen Anh Quynh" notifications@github.com
wrote:

these error code are starting to get ugly. perhaps we should keep them
simple to be just UC_ERR_MEM_WRITE & UC_ERR_MEM_READ ?


Reply to this email directly or view it on GitHub
#60 (comment)
.

@aquynh
Copy link
Member

aquynh commented Aug 29, 2015

merged this into master branch, thanks!

now lets rename uc_mem_map_ex() to uc_mem_map to support memory permission at mapping time?

@cseagle
Copy link
Contributor Author

cseagle commented Aug 29, 2015 via email

@aquynh
Copy link
Member

aquynh commented Aug 29, 2015

please go ahead doing that as soon as you can. i can fix the Python binding right after this change.

@aquynh aquynh merged commit c8d64cf into unicorn-engine:master Aug 29, 2015
@cseagle cseagle deleted the mem_map_ex branch August 29, 2015 06:14
chfl4gs added a commit to chfl4gs/unicorn that referenced this pull request Mar 6, 2020
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

5 participants