unicorn
unicorn copied to clipboard
a more Pythonic binding
a proposal for a more Pythonic binding was posted on Twitter at https://gist.github.com/moyix/669344f534c83e0704e0 - by @moyix.
this looks cool. @JonathonReinhart, is this similar to what you plan to propose?
Yes, that is nearly identical to what I was planning, right down to the ability to use slices to access target memory. I like it!
I think register names should be lowercase here
What is the story on this? The code looks good, it runs without error. What is needed to move it forward?
I also agree with keeping the registers lower case.
even if nothing is missing, we are still looking forward to the pull request :-)
on the register name: why keeping them in lower case, while we have UC_ARCH_X86
?
because all-caps attributes are not pythonic
Well two reasons:
-
The registers are variable, we'll change the values, so that's usually lower, where UC_ARCH_* isn't being changed (at least that's what I'm seeing so far), so it can be a const and in caps.
-
Other Emu's use the same convention.. but I'd be damned if I can find them now. :)
Re: pull request
It's been 3 months, so that may be the best we're going to get.
Was the idea for this to replace the current binding? It's currently importing much of what it needs from the existing binding, which is an improvement, but needs cleanup.
If no one feels that the new binding is on the way anytime soon, I can create it using this code as the base idea, replacing the existing binding, and referencing moyix's contribution.
I feel that this should not completely replace the current Python bindings.
If nothing else, it adds significant overhead to the current bindings, which is already very noticeable when doing much register access.
Test case: https://bochs.info/p/f48ma
$ python test.py
magic: 2.89082503319
native: 1.85509109497
$ python test.py
magic: 3.02654600143
native: 1.85136508942
$ python test.py
magic: 2.88477110863
native: 1.84552502632
it is better to keep the old interface, but not replace it, so all the existing apps do not need to be rewritten.
on the performance, we should find all the problems, so we can either fix them, or document the issues.
I can probably get those test times closer together.
So: create a new binding, keep the old for compatibility and speed, and eventually switch as people find the new binding better?
yes please. even though i dont think we will ever get rid the current interface due to backward compatibility reason.
Sorry for not following up on this – I got caught up on trying to figure out the best way to do things like callbacks, and then other projects intruded. I would be very happy if others picked it up from here! :)
moyix: I assume the post you have above is the most recent? If so, I'll run with that later on this week.
I don't mind the idea of two bindings, it's the easiest way to keep everyone happy I think.
to clarify: we support 1 Python binding, but with 2 interfaces to ensure backward compatibility.
@cforger Yes, that's the most recent.
Hello all, I recently started a similar project that I have integrated into the bindings directly (https://github.com/Jake-R/unicorn) and I'm looking for some feedback on the interface. the interface is a superset of the old one with the following new features:
from unicorn import arm64
mu = arm64.arm64el_arm()
#mapping memory
mu[ADDRESS] = 2*1024*1024 # I don't really like this, any suggestions?
#writing to memory:
mu[ADDRESS] = ARM64_CODE
#reading memory:
mem = mu[ADDRESS:ADDRESS+len(ARM64_CODE)]
#reading a register
x11 = mu.reg.x11
#writing a register:
mu.reg.x11 = 0x12345678
#hooking
@Hook.block
def hook_block(uc, address, size, user_data):
print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size))
# or
mu.hook.block(hook_block)
The bindings are generated by looking at the values in {}_const modules and inserting them into a jinja2 template. I haven't done a ton of testing for speed but it seems like the performance impact is pretty minimal since there is only the overhead of __get__/__set__
and __getitem__/__setitem__
. Replicating @lunixbochs 's test I got:
magic: 4.411244699997042
native: 3.900663774998975
magic: 4.60627108799963
native: 3.8136738930006686
magic: 4.460894711999572
native: 3.8876221419996
Are there any other features you would like to see? would you change anything about the implementation?
if you want to try it out I've found that the easiest way to install it is with sudo -H pip3 install -e 'git+https://github.com/Jake-R/unicorn.git#egg=unicorn&subdirectory=bindings/python'
Re-open and link to #1449