unicorn icon indicating copy to clipboard operation
unicorn copied to clipboard

a more Pythonic binding

Open aquynh opened this issue 9 years ago • 17 comments

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?

aquynh avatar Oct 18 '15 17:10 aquynh

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!

JonathonReinhart avatar Oct 18 '15 18:10 JonathonReinhart

I think register names should be lowercase here

lunixbochs avatar Oct 18 '15 18:10 lunixbochs

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.

cforger avatar Jan 31 '16 19:01 cforger

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?

aquynh avatar Jan 31 '16 19:01 aquynh

because all-caps attributes are not pythonic

lunixbochs avatar Jan 31 '16 20:01 lunixbochs

Well two reasons:

  1. 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.

  2. Other Emu's use the same convention.. but I'd be damned if I can find them now. :)

cforger avatar Jan 31 '16 20:01 cforger

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.

cforger avatar Jan 31 '16 20:01 cforger

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

lunixbochs avatar Jan 31 '16 20:01 lunixbochs

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.

aquynh avatar Jan 31 '16 20:01 aquynh

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?

cforger avatar Jan 31 '16 20:01 cforger

yes please. even though i dont think we will ever get rid the current interface due to backward compatibility reason.

aquynh avatar Jan 31 '16 21:01 aquynh

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 avatar Feb 01 '16 15:02 moyix

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.

cforger avatar Feb 02 '16 14:02 cforger

to clarify: we support 1 Python binding, but with 2 interfaces to ensure backward compatibility.

aquynh avatar Feb 02 '16 15:02 aquynh

@cforger Yes, that's the most recent.

moyix avatar Feb 02 '16 20:02 moyix

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'

STKFLT avatar Aug 19 '17 21:08 STKFLT

Re-open and link to #1449

wtdcode avatar Oct 05 '21 13:10 wtdcode