* Deprecate rarc2 and rarc2-tool

- Replaced by ragg2 - the new r_egg based tool for r2
* Add r_egg_assemble as a 2nd step for compilation
* Fix memory leak in r_egg_free
* Add support for 'cmp' and more 'test' variants for x86.nz
  - Ignore 'dword ptr' string
  - More test cases
* Fix SCSIZE issue in rasc2 -s

--HG--
rename : binr/rarc2/Makefile => binr/old.rarc2/Makefile
rename : binr/rarc2/README => binr/old.rarc2/README
rename : binr/rarc2/config.def.h => binr/old.rarc2/config.def.h
rename : binr/rarc2/config.h => binr/old.rarc2/config.h
rename : binr/rarc2/emit_arm.c => binr/old.rarc2/emit_arm.c
rename : binr/rarc2/emit_x64.c => binr/old.rarc2/emit_x64.c
rename : binr/rarc2/emit_x86.c => binr/old.rarc2/emit_x86.c
rename : binr/rarc2/i/libc.r => binr/old.rarc2/i/libc.r
rename : binr/rarc2/i/socket.r => binr/old.rarc2/i/socket.r
rename : binr/rarc2/osxtest.r => binr/old.rarc2/osxtest.r
rename : binr/rarc2/out.c => binr/old.rarc2/out.c
rename : binr/rarc2/rarc2-tool => binr/old.rarc2/rarc2-tool
rename : binr/rarc2/rarc2.c => binr/old.rarc2/rarc2.c
rename : binr/rarc2/rarc2.h => binr/old.rarc2/rarc2.h
rename : binr/rarc2/t/Makefile => binr/old.rarc2/t/Makefile
rename : binr/rarc2/t/argv.r => binr/old.rarc2/t/argv.r
rename : binr/rarc2/t/bytedump.r => binr/old.rarc2/t/bytedump.r
rename : binr/rarc2/t/data.r => binr/old.rarc2/t/data.r
rename : binr/rarc2/t/dump.r => binr/old.rarc2/t/dump.r
rename : binr/rarc2/t/hello.r => binr/old.rarc2/t/hello.r
rename : binr/rarc2/t/hi.r => binr/old.rarc2/t/hi.r
rename : binr/rarc2/t/if.r => binr/old.rarc2/t/if.r
rename : binr/rarc2/t/inline.r => binr/old.rarc2/t/inline.r
rename : binr/rarc2/t/input.r => binr/old.rarc2/t/input.r
rename : binr/rarc2/t/loop.r => binr/old.rarc2/t/loop.r
rename : binr/rarc2/t/ptr.r => binr/old.rarc2/t/ptr.r
rename : binr/rarc2/t/rawsys.r => binr/old.rarc2/t/rawsys.r
rename : binr/rarc2/t/rawsys64.r => binr/old.rarc2/t/rawsys64.r
rename : binr/rarc2/t/regs.r => binr/old.rarc2/t/regs.r
rename : binr/rarc2/t/ret.r => binr/old.rarc2/t/ret.r
rename : binr/rarc2/t/room.r => binr/old.rarc2/t/room.r
rename : binr/rarc2/t/segfault.r => binr/old.rarc2/t/segfault.r
rename : binr/rarc2/t/shell.r => binr/old.rarc2/t/shell.r
rename : binr/rarc2/t/sub.r => binr/old.rarc2/t/sub.r
rename : binr/rarc2/t/syscall.r => binr/old.rarc2/t/syscall.r
rename : binr/rarc2/test.r => binr/old.rarc2/test.r
rename : libr/egg/t/syscall.r => binr/ragg2/syscall.r
This commit is contained in:
pancake 2011-08-08 02:07:26 +02:00
parent d99fbd7680
commit 429a475ac0
48 changed files with 223 additions and 45 deletions

View File

@ -7,7 +7,7 @@ PFX=${DESTDIR}/${PREFIX}
BFX=${DESTDIR}/${BINDIR} BFX=${DESTDIR}/${BINDIR}
LFX=${DESTDIR}/${LIBDIR} LFX=${DESTDIR}/${LIBDIR}
BINS=rax2 rasm2 rabin2 rahash2 radiff2 radare2 rafind2 rarc2 ranal2 rasc2 rarun2 BINS=rax2 rasm2 rabin2 rahash2 radiff2 radare2 rafind2 ranal2 rasc2 rarun2 ragg2
#rsc2 #rsc2
all: all:
@ -17,7 +17,7 @@ install:
mkdir -p ${BFX} mkdir -p ${BFX}
pwd pwd
for a in ${BINS} ; do ${INSTALL_PROGRAM} $$a/$$a ${BFX}/$$a ; done for a in ${BINS} ; do ${INSTALL_PROGRAM} $$a/$$a ${BFX}/$$a ; done
cp -f rarc2/rarc2 rarc2/rarc2-tool ${BFX} #cp -f rarc2/rarc2 rarc2/rarc2-tool ${BFX}
# shortcut # shortcut
-cd ${BFX} && rm -f r2 ; ln -fs radare2 r2 -cd ${BFX} && rm -f r2 ; ln -fs radare2 r2
@ -34,12 +34,12 @@ symstall-rsc2:
symstall install-symlink: symstall install-symlink:
mkdir -p ${BFX} mkdir -p ${BFX}
for a in ${BINS} ; do ln -fs ${PWD}/$$a/$$a ${BFX}/$$a ; done for a in ${BINS} ; do ln -fs ${PWD}/$$a/$$a ${BFX}/$$a ; done
ln -fs ${PWD}/rarc2/rarc2-tool ${BFX}/rarc2-tool # ln -fs ${PWD}/rarc2/rarc2-tool ${BFX}/rarc2-tool
-ln -fs ${PFX}/bin/radare2 ${BFX}/r2 -ln -fs ${PFX}/bin/radare2 ${BFX}/r2
deinstall uninstall: deinstall uninstall:
for a in ${BINS} ; do rm -f ${BFX}/$$a ; done for a in ${BINS} ; do rm -f ${BFX}/$$a ; done
rm -f ${BFX}/rarc2-tool #rm -f ${BFX}/rarc2-tool
-rm -f ${BFX}/r2 -rm -f ${BFX}/r2
clean: clean:

View File

@ -52,7 +52,7 @@ static int rabin_show_help() {
" -A list archs\n" " -A list archs\n"
" -a [arch_bits] set arch\n" " -a [arch_bits] set arch\n"
" -b [addr] override baddr\n" " -b [addr] override baddr\n"
" -c [fmt:C:D] create [fmt] binary with Code and Data hexpairs (see -a)\n" " -c [fmt:C:D] create [elf,mach0,pe] with Code and Data hexpairs (see -a)\n"
" -e entrypoint\n" " -e entrypoint\n"
" -f [str] select sub-bin named str\n" " -f [str] select sub-bin named str\n"
" -i imports (symbols imported from libraries)\n" " -i imports (symbols imported from libraries)\n"

8
binr/ragg2/Makefile Normal file
View File

@ -0,0 +1,8 @@
BIN=ragg2
BINDEPS=r_egg r_syscall r_asm r_util
include ../binr.mk
ifeq ($(WITHNONPIC),1)
LDFLAGS+=${DL_LIBS}
endif

106
binr/ragg2/ragg2.c Normal file
View File

@ -0,0 +1,106 @@
/* radare - LGPL - Copyright 2011 pancake<@nopcode.org> */
#include <r_egg.h>
#include <getopt.h>
static int usage () {
eprintf ("ragg2 [options] [file|-]\n");
eprintf (" -a [x86|arm] select architecture\n");
eprintf (" -b [32|64] register size\n");
eprintf (" -f [elf|mach0|pe] output format\n");
eprintf (" -o [file] output file\n");
eprintf (" -s show assembler\n");
eprintf (" -x show hexpairs (enabled by default)\n");
eprintf (" -X execute\n");
eprintf (" -h show this help\n");
return 1;
}
int main(int argc, char **argv) {
const char *arch = "x86";
int show_execute = 0;
int show_hex = 1;
int show_asm = 0;
int bits = 32;
int c, i;
RBuffer *b;
REgg *egg = r_egg_new ();
while ((c = getopt (argc, argv, "ha:b:f:o:sxX")) != -1) {
switch (c) {
case 'a':
arch = optarg;
break;
case 'b':
bits = atoi (optarg);
break;
case 'o':
{
int fd = open (optarg, O_RDWR|O_CREAT, 0644);
if (fd != -1) {
close (1);
dup2 (fd, 1);
} else eprintf ("Cannot open '%s'\n", optarg);
}
break;
case 'f':
// raw, elf, pe, mach0
eprintf ("TODO: -f [format]\n");
break;
case 's':
show_asm = 1;
show_hex = 0;
break;
case 'x':
show_hex = 1;
break;
case 'X':
// execute
show_execute = 1;
break;
case 'h':
return usage ();
}
}
if (optind == argc)
return usage ();
r_egg_setup (egg, arch, bits, 0, 0);
if (!strcmp (argv[optind], "-")) {
char buf[1024];
for (;;) {
fgets (buf, sizeof (buf), stdin);
if (feof (stdin)) break;
r_egg_load (egg, buf, 0);
}
} else {
r_egg_include (egg, argv[optind], 0);
}
// TODO: split into two functions
r_egg_compile (egg);
//r_egg_setup (egg, "x86", 32, 0, 0);
//r_egg_setup (egg, "x86", 64, 0, 0);
//printf ("src (%s)\n", r_egg_get_source (egg));
if (show_asm)
printf ("%s\n", r_egg_get_assembly (egg));
if (show_hex || show_execute) {
r_egg_assemble (egg);
b = r_egg_get_bin (egg);
if (b == NULL) {
eprintf ("Cannot assemble egg :(\n");
} else {
if (show_hex) {
for (i=0; i<b->length; i++)
printf ("%02x", b->buf[i]);
printf ("\n");
}
if (show_execute) {
// TODO
eprintf ("TODO: execute\n");
}
}
}
r_egg_free (egg);
return 0;
}

View File

@ -19,10 +19,6 @@ exit@inline()
: int 0x80 : int 0x80
} }
: .data
: str:
: .string "ftw\n"
: .text
strlen@alias(0); strlen@alias(0);
/* /*
@ -38,3 +34,7 @@ main@global(128)
write($1, $str, .var0); write($1, $str, .var0);
exit($0); exit($0);
} }
: .data
: str:
: .string "ftw\n"

View File

@ -157,7 +157,7 @@ int otf_patch() {
ptr = getenv ("PORT"); ptr = getenv ("PORT");
if (ptr) { if (ptr) {
unsigned short port = atoi(ptr); unsigned short port = atoi(ptr);
memcpy (shellcode+shellcodes[scidx].port,&port,2); memcpy (shellcode+shellcodes[scidx].port, &port, 2);
} }
} }
} }
@ -252,7 +252,7 @@ int print_shellcode() {
} else { } else {
ut8 *ptr = malloc (4096); ut8 *ptr = malloc (4096);
void (*cb)() = (void *)&shellcode; void (*cb)() = (void *)&shellcode;
memcpy (ptr, shellcode, strlen ((const char *)shellcode)); memcpy (ptr, shellcode, SCSIZE);
#if __UNIX__ #if __UNIX__
mprotect (ptr, 4096, PROT_READ|PROT_EXEC); // rx must be ok mprotect (ptr, 4096, PROT_READ|PROT_EXEC); // rx must be ok
mprotect (ptr, 4096, PROT_READ|PROT_WRITE|PROT_EXEC); // try rwx mprotect (ptr, 4096, PROT_READ|PROT_WRITE|PROT_EXEC); // try rwx

View File

@ -41,6 +41,9 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
int l = 0; int l = 0;
strncpy (op, str, sizeof (op)-1); strncpy (op, str, sizeof (op)-1);
arg = strstr (op, "dword ptr");
if (arg) strcpy (arg, arg+strlen ("dword ptr"));
if (!memcmp (op, "rep ", 4)) { if (!memcmp (op, "rep ", 4)) {
data[l++] = 0xf3; data[l++] = 0xf3;
memmove (op, op+4, strlen (op+4)+1); memmove (op, op+4, strlen (op+4)+1);
@ -57,7 +60,7 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
arg = strchr (op, ' '); arg = strchr (op, ' ');
if (arg) { if (arg) {
*arg = '\0'; *arg = '\0';
arg++; for (arg++; *arg==' '; arg++);
} }
if (arg) { if (arg) {
char *arg2 = strchr (arg, ','); char *arg2 = strchr (arg, ',');
@ -131,6 +134,35 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
} }
return l; return l;
} else } else
if (!strcmp (op, "cmp")) {
int arg0 = getreg (arg);
int arg1 = getreg (arg2);
if (a->bits==64)
data[l++] = 0x48;
if (isnum (arg2)) { // reg, num
int n = atoi (arg2);
if (n>127 || n<-127) {
ut8 *ptr = (ut8 *)&n;
data[l++] = 0x81;
data[l++] = 0xf8 | arg0;
//data[l++] = 0x50 | arg0;
data[l++] = ptr[0];
data[l++] = ptr[1];
data[l++] = ptr[2];
data[l++] = ptr[3];
} else {
data[l++] = 0x83;
data[l++] = 0xc0 | arg0 | (arg1<<3);
data[l++] = atoi (arg2);
}
return l;
} else // reg, reg
if (arg0 != 0xff && arg1 != 0xff) {
data[l++] = 0x39;
data[l++] = 0xc0 | arg0 | (arg1<<3);
return l;
}
} else
if (!strcmp (op, "test")) { if (!strcmp (op, "test")) {
int arg0 = getreg (arg); int arg0 = getreg (arg);
if (a->bits==64) if (a->bits==64)
@ -334,7 +366,13 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
} }
if (isnum (arg2)) { if (isnum (arg2)) {
data[l++] = 0xb8; if (delta) {
data[l++] = 0xc7;
data[l++] = 0x40 | getreg (arg);
data[l++] = 0x04;
} else {
data[l++] = 0xb8;
}
data[l++] = ptr[0]; data[l++] = ptr[0];
data[l++] = ptr[1]; data[l++] = ptr[1];
data[l++] = ptr[2]; data[l++] = ptr[2];
@ -399,7 +437,7 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
/* relative address */ /* relative address */
addr -= 2; addr -= 2;
addr -= offset; addr -= offset;
data[l++] = '\xeb'; data[l++] = 0xeb;
data[l++] = (char)dst; data[l++] = (char)dst;
return l; return l;
} else { } else {
@ -418,8 +456,8 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
int num = getnum (arg); int num = getnum (arg);
if (num>-127 && num<127) { if (num>-127 && num<127) {
num-=2; num-=2;
data[l++]='\x75'; data[l++] = 0x75;
data[l++]=(char)num; data[l++] = (char)num;
return l; return l;
} else { } else {
data[l++]=0x0f; data[l++]=0x0f;
@ -434,8 +472,8 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
if (dst>-0x80 && dst<0x7f) { if (dst>-0x80 && dst<0x7f) {
dst-=2; dst-=2;
data[l++]='\x74'; data[l++] = 0x74;
data[l++]=(char)dst; data[l++] = (char)dst;
return l; return l;
} else { } else {
data[l++]=0x0f; data[l++]=0x0f;
@ -447,30 +485,30 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
} }
} else { } else {
if (!strcmp (op, "leave")) { if (!strcmp (op, "leave")) {
data[l++]='\xc9'; data[l++] = 0xc9;
} else } else
if (!strcmp (op, "syscall")) { if (!strcmp (op, "syscall")) {
data[l++]='\x0f'; data[l++] = 0x0f;
data[l++]='\x05'; data[l++] = 0x05;
} else } else
if (!strcmp (op, "ret")) { if (!strcmp (op, "ret")) {
data[l++]='\xc3'; data[l++] = 0xc3;
} else } else
if (!strcmp (op, "ret0")) { if (!strcmp (op, "ret0")) {
memcpy (data+l, "\x31\xc0\xc3", 3); memcpy (data+l, "\x31\xc0\xc3", 3);
l += 3; l += 3;
} else } else
if (!strcmp(op, "int3")) { if (!strcmp(op, "int3")) {
data[l++]='\xcc'; data[l++] = 0xcc;
} else } else
if (!strcmp (op, "pusha")) { if (!strcmp (op, "pusha")) {
data[l++]='\x60'; data[l++] = 0x60;
} else } else
if (!strcmp (op, "popa")) { if (!strcmp (op, "popa")) {
data[l++] = 0x61; data[l++] = 0x61;
} else } else
if (!strcmp (op, "nop")) { if (!strcmp (op, "nop")) {
data[l++]='\x90'; data[l++] = 0x90;
} }
return l; return l;
} }

View File

@ -3,10 +3,11 @@
foo() { foo() {
A=$(rasm2 -a x86.as -b ${BITS} "$1") A=$(rasm2 -a x86.as -b ${BITS} "$1")
B=$(rasm2 -a x86.nz -b ${BITS} "$1") B=$(rasm2 -a x86.nz -b ${BITS} "$1")
D=$(rasm2 -b ${BITS} -d "$A")
if [ "${A}" = "${B}" ]; then if [ "${A}" = "${B}" ]; then
printf "OK %12s.as %12s.nz %20s\n" "$A" "$B" "$1" printf "OK %12s.as %12s.nz %20s = $D\n" "$A" "$B" "$1"
else else
printf "FAILED %12s.as %12s.nz %20s\n" "$A" "$B" "$1" printf "FAILED %12s.as %12s.nz %20s = $D\n" "$A" "$B" "$1"
fi fi
} }
@ -18,9 +19,10 @@ fi
echo "==> Running 32bit tests..." echo "==> Running 32bit tests..."
foo "leal eax, 0x804900" #foo "leal eax, 0x804900"
exit 0
if true ; then
foo "mov dword ptr[esi+4], 33"
foo "pop [eax]" foo "pop [eax]"
foo "pop [esp]" foo "pop [esp]"
foo "pop [ebp]" foo "pop [ebp]"
@ -34,15 +36,13 @@ foo "push [ebp]"
foo "push [edi]" foo "push [edi]"
foo "push [esi]" foo "push [esi]"
foo "push [ecx]" foo "push [ecx]"
exit 0
foo "pop [eax]" foo "pop [eax]"
foo "push [eax]" foo "push [eax]"
foo "push [ebp+4]" foo "push [ebp+4]"
foo "push [eax+8]" foo "push [eax+8]"
foo "pop [ebp+4]" foo "pop [ebp+4]"
foo "pop [eax+4]" foo "pop [eax+4]"
exit 0 fi
if true ; then if true ; then
foo "mov eax, 0x8049000" foo "mov eax, 0x8049000"
@ -114,6 +114,13 @@ foo "mov [eax+eax], eax"
foo "mov [eax+ebx], ebx" foo "mov [eax+ebx], ebx"
foo "mov [eax+2], ebx" foo "mov [eax+2], ebx"
foo "mov [ebx+2], ebx" foo "mov [ebx+2], ebx"
foo "cmp eax, ebx"
foo "cmp eax, 33"
foo "cmp ebx, eax"
foo "cmp edx, esi"
foo "test edx, esi"
foo "test eax, ebx"
fi fi
# 64 bit tests # # 64 bit tests #
@ -144,4 +151,11 @@ foo "add rax, rcx"
foo "add rax, 44" foo "add rax, 44"
foo "sub rax, rbx" foo "sub rax, rbx"
foo "sub rax, 44" foo "sub rax, 44"
foo "cmp rax, rbx"
foo "cmp rax, 33"
foo "cmp rbx, rax"
foo "cmp rdx, rsi"
foo "test rdx, rsi"
foo "test rax, rbx"
fi fi

View File

@ -23,6 +23,11 @@ R_API char *r_egg_to_string (REgg *egg) {
} }
R_API void r_egg_free (REgg *egg) { R_API void r_egg_free (REgg *egg) {
r_buf_free (egg->src);
r_buf_free (egg->buf);
r_buf_free (egg->bin);
r_asm_free (egg->rasm);
r_syscall_free (egg->syscall);
free (egg); free (egg);
} }
@ -130,14 +135,7 @@ R_API void r_egg_printf(REgg *egg, const char *fmt, ...) {
va_end (ap); va_end (ap);
} }
R_API int r_egg_compile(REgg *egg) { R_API int r_egg_assemble(REgg *egg) {
const char *b = (const char *)egg->src->buf;
if (!b || !egg->emit)
return R_FALSE;
for (;*b;b++) {
r_egg_lang_parsechar (egg, *b);
}
// TODO: call r_asm
if (egg->emit == &emit_x86 || egg->emit == &emit_x64) { if (egg->emit == &emit_x86 || egg->emit == &emit_x64) {
RAsmCode *asmcode; RAsmCode *asmcode;
char *code; char *code;
@ -177,6 +175,16 @@ R_API int r_egg_compile(REgg *egg) {
return R_FALSE; return R_FALSE;
} }
R_API int r_egg_compile(REgg *egg) {
const char *b = (const char *)egg->src->buf;
if (!b || !egg->emit)
return R_FALSE;
for (;*b;b++)
r_egg_lang_parsechar (egg, *b);
// TODO: handle errors here
return R_TRUE;
}
R_API RBuffer *r_egg_get_bin(REgg *egg) { R_API RBuffer *r_egg_get_bin(REgg *egg) {
// TODO increment reference // TODO increment reference
return egg->bin; return egg->bin;

View File

@ -29,7 +29,7 @@ enum {
SYSCALLBODY, SYSCALLBODY,
LAST LAST
}; };
// XXX // XXX : globals are ugly
static int nsyscalls = 0; static int nsyscalls = 0;
static char *syscallbody = NULL; static char *syscallbody = NULL;
static int commentmode = 0; static int commentmode = 0;
@ -63,7 +63,7 @@ static int oc = '\n';
static int mode = NORMAL; static int mode = NORMAL;
static const char *skipspaces(const char *s) { static const char *skipspaces(const char *s) {
for(;*s;s++) for (;*s;s++)
switch (*s) { switch (*s) {
case '\n': case '\n':
case '\r': case '\r':
@ -254,7 +254,9 @@ R_API char *r_egg_mkvar(REgg *egg, char *out, const char *_str, int delta) {
} else } else
if (!memcmp (str+1, "reg", 3)) { if (!memcmp (str+1, "reg", 3)) {
// XXX: can overflow if out is small // XXX: can overflow if out is small
snprintf (out, 32, "%%%s", e->regs (egg, atoi (str+4))); if (attsyntax)
snprintf (out, 32, "%%%s", e->regs (egg, atoi (str+4)));
else snprintf (out, 32, "%s", e->regs (egg, atoi (str+4)));
} else { } else {
ret = str; /* TODO: show error, invalid var name? */ ret = str; /* TODO: show error, invalid var name? */
eprintf ("FUCKED UP\n"); eprintf ("FUCKED UP\n");
@ -572,13 +574,13 @@ static void rcc_next(REgg *egg) {
int vs = 'l'; int vs = 'l';
char type, *eq, *ptr = elem; char type, *eq, *ptr = elem;
elem[elem_n] = '\0'; elem[elem_n] = '\0';
ptr = skipspaces (ptr); ptr = (char*)skipspaces (ptr);
if (*ptr) { if (*ptr) {
eq = strchr (ptr, '='); eq = strchr (ptr, '=');
if (eq) { if (eq) {
char str2[64], *p, ch = *(eq-1); char str2[64], *p, ch = *(eq-1);
*eq = '\0'; *eq = '\0';
eq = skipspaces (eq+1); eq = (char*) skipspaces (eq+1);
p = r_egg_mkvar (egg, str2, ptr, 0); p = r_egg_mkvar (egg, str2, ptr, 0);
vs = varsize; vs = varsize;
if (IS_VAR (eq)) { if (IS_VAR (eq)) {

View File

@ -33,6 +33,7 @@ int main(int argc, char **argv) {
r_egg_setup (egg, arch, bits, 0, 0); r_egg_setup (egg, arch, bits, 0, 0);
r_egg_include (egg, argv[optind], 0); r_egg_include (egg, argv[optind], 0);
r_egg_compile (egg); r_egg_compile (egg);
r_egg_assemble (egg);
//r_egg_setup (egg, "x86", 32, 0, 0); //r_egg_setup (egg, "x86", 32, 0, 0);
//r_egg_setup (egg, "x86", 64, 0, 0); //r_egg_setup (egg, "x86", 64, 0, 0);

View File

@ -64,6 +64,7 @@ R_API void r_egg_raw(REgg *egg, const ut8 *b, int len);
R_API void r_egg_if(REgg *egg, const char *reg, char cmp, int v); R_API void r_egg_if(REgg *egg, const char *reg, char cmp, int v);
R_API void r_egg_printf(REgg *egg, const char *fmt, ...); R_API void r_egg_printf(REgg *egg, const char *fmt, ...);
R_API int r_egg_compile(REgg *egg); R_API int r_egg_compile(REgg *egg);
R_API int r_egg_assemble(REgg *egg);
R_API RBuffer *r_egg_get_bin(REgg *egg); R_API RBuffer *r_egg_get_bin(REgg *egg);
//R_API int r_egg_dump (REgg *egg, const char *file) { } //R_API int r_egg_dump (REgg *egg, const char *file) { }
R_API char *r_egg_get_source(REgg *egg); R_API char *r_egg_get_source(REgg *egg);