From de5f4061ee2b5aafb2fe9c18a41e8300a32aff4b Mon Sep 17 00:00:00 2001 From: pancake Date: Sat, 13 Aug 2011 17:23:24 +0200 Subject: [PATCH] * Add support for jl, jle, jg, jge, jne, je in x86.nz - support for signed/unsigned values in r_egg --- TODO | 2 + binr/ragg2/t/hello.r | 2 + libr/asm/p/asm_x86_nz.c | 82 ++++++++++++++++++++++++++++++++++++++--- libr/asm/t/test.nz | 18 +++++++-- libr/egg/emit_x86.c | 19 ++++++++-- libr/egg/lang.c | 5 ++- 6 files changed, 114 insertions(+), 14 deletions(-) diff --git a/TODO b/TODO index 49c67c0418..4965395710 100644 --- a/TODO +++ b/TODO @@ -6,6 +6,8 @@ * Cant set register values in OSX debugger - This is probably because we are using the 32bit binary on 64bit dbg +* rahash2 -f (full file) + ====[[ 0.9 ]]==== * rax2 hex->bin doesnt works for hex values (rax2 Bx1d) (it is just dec->bin O_o) * Implement r_search_xrefs() diff --git a/binr/ragg2/t/hello.r b/binr/ragg2/t/hello.r index 517ebe96e8..69aa8a86e3 100644 --- a/binr/ragg2/t/hello.r +++ b/binr/ragg2/t/hello.r @@ -5,8 +5,10 @@ exit@syscall(1); main@global(128) { .var0 = 4; .var4 = "Hello World\n"; + .var40 = "LOL\n"; while (.var0 > 0) { write (1, .var4, 12); +// if (.var0 == 2) { write (1, .var20, 4); } .var0 -= 2; } exit (0); diff --git a/libr/asm/p/asm_x86_nz.c b/libr/asm/p/asm_x86_nz.c index 23880a0499..ea6239223d 100644 --- a/libr/asm/p/asm_x86_nz.c +++ b/libr/asm/p/asm_x86_nz.c @@ -605,6 +605,79 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) { return l; } } else +// SPAGUETTI + if (!strcmp (op, "jle")) { + ut64 dst = r_num_math (NULL, arg) - offset; + int d, num = getnum (arg); + d = num - a->pc; + //if (num>-127 && num<127) { + if (d>-127 && d<127) { + d-=2; + data[l++] = 0x7e; + data[l++] = (char)d; + return l; + } else { + data[l++]=0x0f; + data[l++]=0x8e; + dst -= 6; + memcpy (data+l, &dst, 4); + return l+4; + } + } else + if (!strcmp (op, "jl")) { + ut64 dst = r_num_math (NULL, arg) - offset; + int d, num = getnum (arg); + d = num - a->pc; + //if (num>-127 && num<127) { + if (d>-127 && d<127) { + d-=6; + data[l++] = 0x7c; + data[l++] = (char)d; + return l; + } else { + data[l++]=0x0f; + data[l++]=0x8c; + dst -= 6; + memcpy (data+l, &dst, 4); + return l+4; + } + } else + if (!strcmp (op, "jg")) { + ut64 dst = r_num_math (NULL, arg) - offset; + int d, num = getnum (arg); + d = num - a->pc; + //if (num>-127 && num<127) { + if (d>-127 && d<127) { + d-=2; + data[l++] = 0x7f; + data[l++] = (char)d; + return l; + } else { + data[l++]=0x0f; + data[l++]=0x8f; + dst -= 6; + memcpy (data+l, &dst, 4); + return l+4; + } + } else + if (!strcmp (op, "jge")) { + ut64 dst = r_num_math (NULL, arg) - offset; + int d, num = getnum (arg); + d = num - a->pc; + //if (num>-127 && num<127) { + if (d>-127 && d<127) { + d-=2; + data[l++] = 0x7d; + data[l++] = (char)d; + return l; + } else { + data[l++]=0x0f; + data[l++]=0x8d; + dst -= 6; + memcpy (data+l, &dst, 4); + return l+4; + } + } else if (!strcmp (op, "jb")) { ut64 dst = r_num_math (NULL, arg) - offset; int d, num = getnum (arg); @@ -623,8 +696,8 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) { return l+4; } } else - if (!strcmp (op, "jnz")) { - ut64 dst = r_num_math (NULL, arg) - offset; + if (!strcmp (op, "jnz") || !strcmp (op, "jne")) { + ut32 dst = r_num_math (NULL, arg) - offset; int num = getnum (arg); if (num>-127 && num<127) { num-=2; @@ -639,9 +712,8 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) { return l+4; } } else - if (!strcmp (op, "jz")) { - ut64 dst = r_num_math (NULL, arg) - offset; - + if (!strcmp (op, "jz") || !strcmp (op, "je")) { + ut32 dst = getnum (arg) - offset; if (dst>-0x80 && dst<0x7f) { dst-=2; data[l++] = 0x74; diff --git a/libr/asm/t/test.nz b/libr/asm/t/test.nz index 97da40acc4..7afdd79a18 100755 --- a/libr/asm/t/test.nz +++ b/libr/asm/t/test.nz @@ -18,11 +18,24 @@ if [ -n "$1" ]; then foo "$1" exit 0 fi - AS=x86.olly +foo 'jl 0x8049300' +foo 'jl 0x8048010' +foo 'jle 0x8049300' +foo 'jle 0x8048010' +foo 'jg 0x8049300' +foo 'jge 0x8049300' +foo 'jge 0x8048010' +exit 0 + foo 'call 0x8049100' foo 'jmp 0x8049200' +echo "UNSIGNED" foo 'jb 0x8049300' +foo 'ja 0x8049300' +echo "SIGNED" +foo 'jl 0x8049300' +foo 'jg 0x8049300' exit 0 AS=x86.as @@ -148,9 +161,6 @@ BITS=32 foo "test edx, esi" foo "test eax, ebx" - - - if true ; then foo "pop [eax]" foo "pop [esp]" diff --git a/libr/egg/emit_x86.c b/libr/egg/emit_x86.c index 5710cc3145..0a0af1541d 100644 --- a/libr/egg/emit_x86.c +++ b/libr/egg/emit_x86.c @@ -257,17 +257,28 @@ static void emit_branch(REgg *egg, char *b, char *g, char *e, char *n, int sz, c char *p, str[64]; char *arg = NULL; char *op = "jz"; + int signed_value = 1; // XXX: add support for signed/unsigned variables /* NOTE that jb/ja are inverted to fit cmp opcode */ if (b) { *b = '\0'; - if (e) op = "jae"; - else op = "ja"; + if (signed_value) { + if (e) op = "jge"; + else op = "jg"; + } else { + if (e) op = "jae"; + else op = "ja"; + } arg = b+1; } else if (g) { *g = '\0'; - if (e) op = "jbe"; - else op = "jb"; + if (signed_value) { + if (e) op = "jle"; + else op = "jl"; + } else { + if (e) op = "jbe"; + else op = "jb"; + } arg = g+1; } if (arg == NULL) { diff --git a/libr/egg/lang.c b/libr/egg/lang.c index 9c0aab926e..174065176b 100644 --- a/libr/egg/lang.c +++ b/libr/egg/lang.c @@ -101,8 +101,10 @@ static char *get_frame_label(int type) { int nb = nbrackets; int ct = context; /* TODO: this type hack to substruct nb and ctx looks weird */ +#if 1 if (type == 1) nb--; else if (type == 2) ct--; +#endif /* THIS IS GAS_ONLY */ snprintf (label, sizeof (label), FRAME_FMT, nf, nb, ct); return label; @@ -110,9 +112,9 @@ static char *get_frame_label(int type) { static char *get_end_frame_label(REgg *egg) { static char label[128]; - /* THIS IS GAS_ONLY */ snprintf (label, sizeof (label)-1, FRAME_END_FMT, nfunctions, nbrackets, context-1); + //snprintf (label, sizeof (label)-1, "frame_end_%d_%d", nfunctions, nbrackets); return label; } @@ -448,6 +450,7 @@ static int parsedatachar(REgg *egg, char c) { dstval[ndstval++] = c; return 0; } + static int parseinlinechar(REgg *egg, char c) { static int inlinectr = 0;