Messing with LibR







radare2 @ lacon2k9





--pancake

ired


But first... a bit of spam :)


I wrote ired. which is a minimalistic version of radare.

Teh plan



The plan is:




NOTE: All examples in this presentation are real
NOTE: Some features listed are work-in-progress

W is LibR?



$ hg clone http://radare.org/hg/radare2

Global picture



Inner view



Much moar...



And...



W Vala?



$ surf http://live.gnome.org/Vala

Object dis-Orientation



r_asm



r_asm




Let's go for some examples...

r_asm : example


$ cat asm.vala

using Radare; public static void main(string[] args) { Asm st = new Asm(); st.use("x86.olly"); st.set_pc(0x8048000); Asm.Aop op; st.disassemble(out op, "\x83\xe4\xf0", 3); print("Disassemble: '%s'\n", op.buf_asm); st.massemble(out op, "jmp _foo;nop;mov eax,33;_foo:push eax"); print("Assembled bytes: %s\n", op.buf_hex); }

$ valac --pkg r_asm asm.vala $ ./asm

Disassemble: 'and esp,0xFFFFFFF0' Assembled bytes: eb0790c7c03300000050

r_asm : example


Let's do it in Genie for those py-ple:
$ cat asm.gs

uses Radare init var st = new Asm() st.use("x86.olly") st.set_syntax(Asm.Syntax.INTEL) st.set_bits(32) st.set_big_endian(false) st.set_pc(0x8048000) op : Radare.Asm.Aop st.disassemble(out op, "\x83\xe4\xf0", 3) print "opcode: %s", op.buf_asm print "bytes: %s", op.buf_hex print "length: %d", op.inst_len

r_asm : example


Or just in C:
$ cat test-asm.c

#include <r_asm.h> int main() { struct r_asm_aop_t aop; struct r_asm_t *st = r_asm_new(); r_asm_use(st, "x86.olly"); r_asm_set_bits(st, 32); r_asm_set_pc(st, 0x8048000); r_asm_disassemble(st, &aop, "\x83\xe4\xf0", 3); printf("%s\t%s ; size=%d\n", op.buf_hex, op.buf_asm, op.inst_len); return 0; }

$ gcc `pkg-config --cflags --libs r_asm` test-asm.c

r_bin/r_bininfo



r_bin : example



using Radare;

void main(string[] args) {
  if (args.length<2)
    error("No file given");
  var bin = new Bin();
  if (bin.open(args[1], false)<0)
    error("Cannot open file");

  uint64 baddr = bin.get_baddr();
  print("Base address: 0x%08llx\n", baddr);

  Bin.Entrypoint entry = bin.get_entry();
  print("Entrypoint: 0x%08llx\n", entry.rva+baddr);

  foreach(Bin.Symbol s in bin.get_symbols())
    print(" - 0x%08llx  %s\n", s.offset, s.name);
  foreach(Bin.Section s in bin.get_sections())
    print(" - 0x%08llx  %s\n", s.offset, s.name);

  bin.close();
}

r_io



r_io : example



#include <r_io.h>

int main () {
  int ret, fd;
  char buf[4];
  struct r_io_t *io = r_io_new();

  fd = r_io_open(io, "dbg:///bin/ls", R_IO_READ, 0);

  /* map 0xfffff bytes at address 0 pointing to 0x8048000 */
  r_io_map_add(io, fd, R_IO_READ, 0x8048000, 0, 0xffff);

  memset(buf, 0, 4);
  ret = r_io_read_at(io, 0, buf, 4); // reading at 0x8048000
  printf("%d = %02x %02x %02x %02x\n",
      ret, buf[0], buf[1], buf[2], buf[3]);

  return r_io_free(io);
}

r_hash



r_hash : example



using Radare;

void print_md5(string str, uint8 *buf) {
  print(str);
  for(int i=0;i<Hash.Size.MD5; i++)
    print("%02x", buf[i]);
  print("\n");
}

void main() {
  /* calculate crc32 */
  print("CRC32: %x\n", Hash.crc32("hello", 5));

  /* direct md5 */
  Hash.State st = new Hash.State(true);
  print_md5("Single MD5: ", (uint8*)st.md5("helloworld", 10));

  /* incremental md5 */
  st = new Hash.State(false);
  st.md5("hello", 5);
  st.md5("world", 5);
  print_md5("Incremental MD5: ", (uint8*)st.md5(null,0));
}

r_search



r_search : example



using Radare.Search;

void main() {
  string buf = "liblubliuamlibfoo";
  var s = new Searcher(Mode.KEYWORD);

  s.kw_add("lib", "");
  s.set_callback( (kw, user, addr) => {
        print("Hit %d! at 0x%llx\n", (int)kw.count, addr);
        return 0;
      }, null);
  s.begin();

  print("string: \"%s\"\n", buf);
  print("search: \"%s\"\n", "lib");
  print("length: %ld\n", buf.len());

  s.update_i(0LL, (uint8*)buf, buf.len());
}

r_debug



r_reg



r_bp



Sample programatic debugger

#include <r_debug.h>
void main() {
  int ret, tid, pid;
  struct r_debug_t *dbg = r_debug_new();
  struct r_io_t *io = r_io_new();

  if (r_io_open(io, "dbg:///bin/ls", 0, 0) == -1)
  	return;
  ret = r_io_read_at(io, 0x8048000, buf, 128);
  printf("%d : %02x %02x %02x\n", ret, buf[0], buf[1], buf[2]);

  r_debug_use(dbg, "ptrace");
  tid = pid = r_io_system(io, "pid");
  r_debug_select(dbg, pid, tid);
  
  r_debug_reg_sync(dbg, R_REG_TYPE_GPR, 0);
  r_debug_reg_list(dbg, R_REG_TYPE_GPR, 32, 0);
  
  r_debug_step(dbg, 2);
  
  r_debug_reg_sync(dbg, R_REG_TYPE_GPR, 0);
  r_debug_reg_list(dbg, R_REG_TYPE_GPR, 32, 0);
  
  r_debug_continue (dbg);
  r_debug_free(dbg);
  r_io_free(io);
}

In vala

using Radare;

void main() {
  var dbg = new Debug();
  var io = new Io();

  if (io.open(io, "dbg:///bin/ls", 0, 0) == -1)
  	return;
  uint8[] buf = new uint8[128];
  int ret = io.read_at(io, 0x8048000, out buf, 128);
  print("%d : %02x %02x %02x\n", ret, buf[0], buf[1], buf[2]);

  dbg.use(dbg, "ptrace");
  tid = pid = io.system(io, "pid");
  dbg.select(dbg, pid, tid);
  
  dbg.reg_sync(dbg, Register.Type.GPR, 0);
  dbg.reg_list(dbg, Register.Type.GPR, 32, 0);
  
  dbg.step(dbg, 2);
  
  dbg.reg_sync(dbg, Register.Type.GPR, 0);
  dbg.reg_list(dbg, Register.Type.GPR, 32, 0);
  
  dbg.continue (dbg);
}

Oh fuck!





Melting all together



Grasm: Graphical assembler in Vala+Grava+r_asm

ragui



Pure wip in gtkaml+vala+libr:

$ surf http://radare.org/ragui 

Contact



We are not so many, if you are happy with it, feel free to join us:
$ echo subscribe | mail radare@lists.nopcode.org

Feedback



EOF









EOF