Egg Issues (#8593)

* Fix pushing inmmediate args using the x64 arch
Added directive .rargX (ar0, ar1,...etc)

* replaced atoi() by r_num_math()
This commit is contained in:
josediazfer 2017-09-27 11:29:15 +02:00 committed by radare
parent 13f7995120
commit bacd615e0d
4 changed files with 79 additions and 36 deletions

View File

@ -252,35 +252,43 @@ R_API void r_egg_printf(REgg *egg, const char *fmt, ...) {
va_end (ap);
}
R_API int r_egg_assemble(REgg *egg) {
R_API int r_egg_assemble_asm(REgg *egg, char **asm_list) {
RAsmCode *asmcode = NULL;
char *code = NULL;
int ret = false;
if (egg->remit == &emit_x86 || egg->remit == &emit_x64) {
r_asm_use (egg->rasm, "x86.nz");
char *asm_name = NULL;
if (asm_list) {
char **asm_;
for (asm_ = asm_list; *asm_; asm_+= 2) {
if (!strcmp (egg->remit->arch, asm_[0])) {
asm_name = asm_[1];
break;
}
}
}
if (!asm_name) {
if (egg->remit == &emit_x86 || egg->remit == &emit_x64) {
asm_name = "x86.nz";
} else if (egg->remit == &emit_arm) {
asm_name = "arm";
}
}
if (asm_name) {
r_asm_use (egg->rasm, asm_name);
r_asm_set_bits (egg->rasm, egg->bits);
r_asm_set_big_endian (egg->rasm, egg->endian);
r_asm_set_syntax (egg->rasm, R_ASM_SYNTAX_INTEL);
code = r_buf_to_string (egg->buf);
asmcode = r_asm_massemble (egg->rasm, code);
if (asmcode) {
if (asmcode->len > 0)
if (asmcode->len > 0) {
r_buf_append_bytes (egg->bin, asmcode->buf, asmcode->len);
}
// LEAK r_asm_code_free (asmcode);
} else eprintf ("fail assembling\n");
} else
if (egg->remit == &emit_arm) {
r_asm_use (egg->rasm, "arm");
r_asm_set_bits (egg->rasm, egg->bits);
r_asm_set_big_endian (egg->rasm, egg->endian);
r_asm_set_syntax (egg->rasm, R_ASM_SYNTAX_INTEL);
code = r_buf_to_string (egg->buf);
asmcode = r_asm_massemble (egg->rasm, code);
if (asmcode) {
r_buf_append_bytes (egg->bin, asmcode->buf, asmcode->len);
// LEAK r_asm_code_free (asmcode);
} else {
eprintf ("fail assembling\n");
}
}
free (code);
@ -289,6 +297,10 @@ R_API int r_egg_assemble(REgg *egg) {
return ret;
}
R_API int r_egg_assemble(REgg *egg) {
return r_egg_assemble_asm (egg, NULL);
}
R_API int r_egg_compile(REgg *egg) {
const char *b = (const char *)egg->src->buf;
if (!b || !egg->remit) {

View File

@ -556,7 +556,7 @@ static void rcc_pushstr(REgg *egg, char *str, int filter) {
}
R_API char *r_egg_mkvar(REgg *egg, char *out, const char *_str, int delta) {
int i, idx, len, qi;
int i, len, qi;
char *oldstr = NULL, *str = NULL, foo[32], *q, *ret = NULL;
delta += stackfixed; // XXX can be problematic
@ -581,20 +581,27 @@ R_API char *r_egg_mkvar(REgg *egg, char *out, const char *_str, int delta) {
}
if (str[0] == '.') {
REggEmit *e = egg->remit;
idx = atoi (str + 4) + delta + e->size;
if (!strncmp (str + 1, "ret", 3)) {
strcpy (out, e->retvar);
} else if (!strncmp (str + 1, "fix", 3)) {
int idx = (int)r_num_math (NULL, str + 4) + delta + e->size;
e->get_var (egg, 0, out, idx - stackfixed);
// sprintf(out, "%d(%%"R_BP")", -(atoi(str+4)+delta+R_SZ-stackfixed));
} else if (!strncmp (str + 1, "var", 3)) {
int idx = (int)r_num_math (NULL, str + 4) + delta + e->size;
e->get_var (egg, 0, out, idx);
// sprintf(out, "%d(%%"R_BP")", -(atoi(str+4)+delta+R_SZ));
} else if (!strncmp (str + 1, "rarg", 4)) {
if (e->get_ar) {
int idx = (int)r_num_math (NULL, str + 5);
e->get_ar (egg, out, idx);
}
} else if (!strncmp (str + 1, "arg", 3)) {
if (str[4]) {
if (stackframe == 0) {
e->get_var (egg, 1, out, 4); // idx-4);
} else {
int idx = (int)r_num_math (NULL, str + 4) + delta + e->size;
e->get_var (egg, 2, out, idx + 4);
}
} else {
@ -708,10 +715,12 @@ static void rcc_fun(REgg *egg, const char *str) {
dstval = malloc (4096);
} else if (strstr (ptr, "naked")) {
mode = NAKED;
/*
free (dstvar);
dstvar = strdup (skipspaces (str));
dstval = malloc (4096);
ndstval = 0;
*/
r_egg_printf (egg, "%s:\n", str);
} else if (strstr (ptr, "inline")) {
mode = INLINE;
@ -1150,16 +1159,16 @@ static void rcc_next(REgg *egg) {
/* store result of call */
if (dstvar) {
if (mode != NAKED) {
*buf = 0;
free (str);
str = r_egg_mkvar (egg, buf, dstvar, 0);
if (*buf == 0) {
eprintf ("Cannot resolve variable '%s'\n", dstvar);
} else {
e->get_result (egg, buf);
}
//if (mode != NAKED) {
*buf = 0;
free (str);
str = r_egg_mkvar (egg, buf, dstvar, 0);
if (*buf == 0) {
eprintf ("Cannot resolve variable '%s'\n", dstvar);
} else {
e->get_result (egg, buf);
}
//}
R_FREE (dstvar);
}
rcc_reset_callname ();

View File

@ -13,10 +13,10 @@
# define R_SP "rsp"
# define R_BP "rbp"
# define R_AX "rax"
# define R_GP { "rax", "rdi", "rsi", "rdx" }
# define R_NGP 4
# define SYSCALL_ATT "syscall"
# define SYSCALL_INTEL "syscall"
# define R_REG_AR_OFF 1
static char *regs[] = { "rax", "rdi", "rsi", "rdx", "r10", "r8", "r9" };
#else
# define EMIT_NAME emit_x86
# define R_ARCH "x86"
@ -24,14 +24,13 @@
# define R_SP "esp"
# define R_BP "ebp"
# define R_AX "eax"
# define R_GP { "eax", "ebx", "ecx", "edx" }
# define R_NGP 4
# define SYSCALL_ATT "int $0x80"
# define SYSCALL_INTEL "int 0x80"
# define R_REG_AR_OFF 0
static char *regs[] = { "eax", "ebx", "ecx", "edx" };
#endif
static char *regs[] = R_GP;
static int regs_count = R_NGP;
# define R_NGP (sizeof (regs)/sizeof (char *))
static void emit_init (REgg *egg) {
// TODO: add 'andb rsp, 0xf0'
@ -112,7 +111,7 @@ static void emit_equ (REgg *egg, const char *key, const char *value) {
}
static const char *getreg(int i) {
if (i < 0 || i >= regs_count) {
if (i < 0 || i >= R_NGP) {
return NULL;
}
return regs[i];
@ -225,7 +224,21 @@ static void emit_arg (REgg *egg, int xs, int num, const char *str) {
str = str +1;
switch (xs) {
case 0:
#ifdef ARCH_X86_64
/* push imm64 instruction not exist, it´s translated to:
mov rax, 0x0102030405060708
push rax
*/
if (attsyntax) {
r_egg_printf (egg, " mov %s, %%"R_AX "\n", str);
r_egg_printf (egg, " push %%"R_AX "\n");
} else {
r_egg_printf (egg, " mov "R_AX ", %s\n", str);
r_egg_printf (egg, " push "R_AX "\n");
}
#else
r_egg_printf (egg, " push %s\n", str);
#endif
break;
case '*':
if (attsyntax) r_egg_printf (egg, " push (%s)\n", str);
@ -436,6 +449,12 @@ static const char* emit_regs(REgg *egg, int idx) {
return regs[idx%R_NGP];
}
static void emit_get_ar (REgg *egg, char *out, int idx) {
const char *reg = emit_regs (egg, R_REG_AR_OFF + idx);
if (reg) strcpy (out, reg);
}
REggEmit EMIT_NAME = {
.retvar = R_AX,
.arch = R_ARCH,
@ -455,6 +474,7 @@ REggEmit EMIT_NAME = {
.get_result = emit_get_result,
.syscall_args = emit_syscall_args,
.set_string = emit_string,
.get_ar = emit_get_ar,
.get_var = emit_get_var,
.while_end = emit_while_end,
.get_while_end = emit_get_while_end,

View File

@ -106,6 +106,7 @@ typedef struct r_egg_emit_t {
void (*restore_stack)(REgg *egg, int size);
void (*syscall_args)(REgg *egg, int nargs);
void (*get_var)(REgg *egg, int type, char *out, int idx);
void (*get_ar)(REgg *egg, char *out, int idx);
void (*while_end)(REgg *egg, const char *label);
void (*load)(REgg *egg, const char *str, int sz);
void (*load_ptr)(REgg *egg, const char *str);
@ -143,6 +144,7 @@ R_API void r_egg_printf(REgg *egg, const char *fmt, ...);
R_API int r_egg_compile(REgg *egg);
R_API int r_egg_padding (REgg *egg, const char *pad);
R_API int r_egg_assemble(REgg *egg);
R_API int r_egg_assemble_asm(REgg *egg, char **asm_list);
R_API void r_egg_pattern(REgg *egg, int size);
R_API RBuffer *r_egg_get_bin(REgg *egg);
//R_API int r_egg_dump (REgg *egg, const char *file) { }