On Sun, 06 Jun 2010 19:44:27 +0200
Joxean Koret <[email protected]> wrote:

> Hi,
> 
> NOTE: First of all, sorry for the long email XD 

SMTP servers never forgive ;)

> I fixed the problems I have had in my local box by adding the
> corresponding $DIR/plugin.o files where the symbols are, namely:
> 
> ../../libr/bp/plugin.o ../../libr/io/plugin.o ../../libr/cmd/plugin.o
> ../../libr/bp/plugin.o ../../libr/io/plugin.o ../../libr/cmd/plugin.o
> 
> After fixing those errors radare2 is working OK, however, there is also
> another error I fixed too locally. The problem is with the python
> bindings. A lot of the generated C++ files throws the same error when
> compiling:

You just have to setup the environment vars correctly.

Let's explain in deeper..

The build system of r2 is a bunch of makefiles in a kinda funny way, and
the structure of directories and design of modules is mostly designed to
fit into this form of build system.

Recently I have moved the r2 programs into a directory named 'binr/'
instead of having to find them all into libr/*/t which was inneficient
and more complicated to work.

When I did this change I didnt tested it on a clean system, so this is why
you can't build it.

The .mk file describing the build rules for binr programs is located in
binr/binr.mk And all the programs use these rules to build.

The linkage in libr/ is done correct, but in binr/ not all libraries are
specified as dependencies, so the linker follows the library dependencies
into the paths he knows they can be /lib, /usr/lib ... you can add other
paths by setting LDFLAGS to -L../../libr/foo/ for each of the required
libraries (missing symbols you get).

So in the fix would be just adding few library names into the LIBS= list
in the binr/*/Makefile files.

> g++ -fPIC -shared r_core_wrap.cxx -I/usr/include/libr
> -I/usr/include/python2.5 -o _r_core.so -lr_sign -lr_syscall -lr_search
> -lr_meta -lr_reg -lr_bp -lr_print -lr_parse -lr_anal -lr_io -lr_lang
> -lr_bin -lr_hash -lr_debug -lr_lib -lr_asm -lr_flags -lr_util -lr_cmd
> -lr_line -lr_cons -lr_config -lr_core -I/usr/include/python2.5
> -lpython2.5
> r_core_wrap.cxx: In function 'void init_r_core()':
> r_core_wrap.cxx:48777: error: 'R_LIB_TYPE_BININFO' was not declared in
> this scope
> make: [r_core.so] Error 1 (ignored)

Yeah, fixed. r_bininfo has been merged into r_bin some time ago. It's fixed now.

The fix is by removing the BININFO enum value in the swig/vapi/r_lib.vapi file.

> I recompiled those objects adding a -DR_LIB_TYPE_BININFO and "it seems
> to work".
> 
> After having my bindings working right I tried some of the samples and
> found that not all of them are working OK as, for example, test-r_hash.
> It complains about missing classes/functions in libr:
> 
> $ python test-r_hash.py
> Traceback (most recent call last):
>   File "test-r_hash.py", line 2, in <module>
>     from libr import RHash, Size_MD4
> ImportError: cannot import name RHash
> 

This test is supossed to work only in the directory where the python bindings
are compiled. When installed the import is in r2.RHash. But..certainly the
status of the RHash module is

> Anyway, my main intentions is to use radare2's python bindings for
> debugging and disassembling and, when writting my code for disassembly I
> noticed that there are some incongruencies between the disassembler
> radare2 uses and the ones available for use inside a python script. Take
> the following example: 
> 
> $ cat test-r_asm.py
> def test2():
>         asm = RAsm()
>         asm.use("x86.olly")
>         ret = asm.mdisassemble_hexstr("f3c7c033000000")
>         if ret:
>                 print ret.buf_asm
>         else:
>                 print "Invalid opcode?"
> 
> $ python test-r_asm.py
> ???
> ???
> xor eax, [eax]
> add [eax], al
> 
> The disassembly is obviously wrong due to olly's disassembler capacities
> but I looks OK in radare2: 

nope, olly is broken in some cases, feel free to provide patches for it.

> $ radare2 -w test.buf
> [0x00000000]> pd
>     0x00000000    0       f3c7c033000000  rep mov eax, 0x33
> 
> ...so, I decided to change the disassembler from x86.olly to the one
> radare2 is using: 
> 
> [0x00000000]> e | grep x86
> asm.arch = x86
> asm.parser = x86.pseudo
> [0x00000000]> q
> $ vi test-r_asm.py
> (...change the disassembler to x86.pseudo...)
> $ python test-r_asm.py
> error disassemble at offset 0
> Invalid opcode?

x86.pseudo is not a disassembler.

Let's explain..

asm.arch is the eval variable used to define the plugin name to be used by
the r_asm backend (and others like r_reg..)

asm.parser is used to select a parser backend, this is used for example to
"translate" cpu opcodes into evaluable expressions:

   mov eax, 33    -->   eax=33

the x86.parser is used for this.

You can read an example about how to use it in libr/core/cmd.c (find 'r_parse')

The way to disassemble x86, is by doing: 'asm.use("x86")' in python. There's
also x86.nasm and x86.bea (in r2-extras)

> So, either I can't use the disassembler or there is something I do not
> understand :/ I tried too with x86.nasm but with no luck... I tried,
> also, listing the availabe disassemblers but <asm obj>.list() is not
> available anymore.

The list() method has been recently deprecated in order to use iterators.
there's a linked list of plugins in asm.plugins you should be able to iterate
over it like this:

  for p in asm.plugins:
      print p.name

In vala this is:

  foreach (var p in a.plugins)
     print (p.name);

but the output of this must be the same of 'rasm2 -L'

x86.nasm requires 'nasm' to be installed. You have to use just 'x86'

> And, after all those errors, I have another one more question: How can I
> debug one application and capture exceptions/signals/whatever using the
> radare2 api? There is neither documentation nor a sample script for this
> task. Any tip?

The debugger API is still under development. So all the documentation is in the 
sauce :)

The python debugger code can be found in r2w, there's one in C at 
libr/debug/t/main.c

this is a test program to check if debugger works. What basically does is:

----(pseudo-python)--------
program="/bin/ls"
io= RIO()
if not io.open("dbg://"+program):
   print "FAIL"
dbg=RDebug()
dbg.use("native")
pid=io.system("pid")
dbg.select(pid, pid)

dbg.continue()
...
# here you can get registers, memory, event information (signal, ...)

In r2w most of the debugger stuff is done by core commands (core.cmd("pd 20"))
and stuff like this.. so it's not really using the debugger API because it is
not yet defined at all and using radare commands you ensure that the program
will continue working in the future.

> Thanks you so much and sorry for the very long email!
> Joxean Koret

np, thanks for reporting ;)

Here's the disasm script you are looking forI

-----------------------------------------
[panc...@dazo ~]$ cat a
from r2.r_asm import *
asm = RAsm()
asm.use("x86")
ret=asm.mdisassemble_hexstr("f3c7c033000000")
if ret:
        print ret.buf_asm
else:
        print "Invalid opcode?"
[panc...@dazo ~]$ python a
rep mov eax, 0x33
------------------------

Note, that you also need to setup other variables if you want to correctly
disassemble a binary file. This is:

1) offset of opcode to disassemble
2) bit size (8, 16, 32, 64)

If the program has sections and so on, you can handle the RVA emulation getting
the information from r_bin and setting it into r_io, that's how r2 works when
e io.va=true

Hope it helps :)

--pancake
_______________________________________________
radare mailing list
[email protected]
http://lists.nopcode.org/listinfo.cgi/radare-nopcode.org

Reply via email to