/* radare - LGPL - Copyright 2012 - pancake */ #include #include #include #include #include #include #include #include static int replace(int argc, const char *argv[], char *newstr) { int i,j,k; struct { char *op; char *str; } ops[] = { { "li", "1 = 2"}, { "lui", "1 |= 2:"}, // : = <<16 { "jr", "ret 1"}, { "bne", "if (1 != 2) goto 3"}, { "beq", "if (1 == 2) goto 3"}, { "beqz", "if (!1) goto 2"}, { "bnez", "if (1) goto 2"}, { "begz", "if (1 >= 0) goto 2"}, { "begzal", "if (1 >= 0) call 2"}, { "bgtz", "if (1 > 0) goto 2"}, { "bltz", "if (1 < 0) goto 2"}, { "bltzal", "if (1 < 0) call 2"}, { "negu", "1 = !2"}, { "and", "1 = 2 & 3"}, { "andi", "1 = 2 & 3"}, { "ori", "1 = 2 | 3"}, { "subu", "1 = 2 - 3"}, { "xor", "1 = 2 ^ 3"}, { "xori", "1 = 2 ^ 3"}, { "addi", "1 = 2 + 3"}, { "addiu", "1 = 2 + 3"}, { "addu", "1 = 2 + 3"}, //{ "jal", "call 1"}, { "bal", "call 1"}, { "jalr", "call 1"}, { "b", "goto 1"}, { "move", "1 = 2"}, { "sll", "1 = 2 << 3"}, { "sllv", "1 = 2 << 3"}, { "slr", "1 = 2 >> 3"}, // logic { "sra", "1 = 2 >> 3"}, // arithmetic { "slt", "1 = (2 < 3)"}, { "slti", "1 = (2 < 3)"}, { "sltiu", "1 = (2 < 3)"}, { "sltu", "1 = unsigned (2 < 3)"}, { "lb", "1 = byte [3 + 2]"}, { "lw", "1 = [3 + 2]"}, { "sb", "byte [3 + 2] = 1"}, { "lbu", "1 = byte [3 + 2]"}, { "sw", "[3 + 2] = 1"}, { NULL } }; for (i=0; ops[i].op != NULL; i++) { if (!strcmp (ops[i].op, argv[0])) { if (newstr != NULL) { for (j=k=0;ops[i].str[j]!='\0';j++,k++) { if (ops[i].str[j]>='1' && ops[i].str[j]<='9') { const char *w = argv[ ops[i].str[j]-'0' ]; if (w != NULL) { strcpy (newstr+k, w); k += strlen(w)-1; } } else newstr[k] = ops[i].str[j]; } newstr[k]='\0'; } return R_TRUE; } } /* TODO: this is slow */ if (newstr != NULL) { newstr[0] = '\0'; for (i=0; i>", "%s >>="); REPLACE ("%s = %s <<", "%s <<="); } p = r_str_replace (p, ":", "0000", 0); strcpy (str, p); free (p); } } } free (buf); return R_TRUE; } static int assemble(RParse *p, char *data, char *str) { char *ptr; printf ("assembling '%s' to generate real asm code\n", str); ptr = strchr (str, '='); if (ptr) { *ptr = '\0'; sprintf (data, "mov %s, %s", str, ptr+1); } else strcpy (data, str); return R_TRUE; } static int varsub(RParse *p, RAnalFunction *f, char *data, char *str, int len) { #if USE_VARSUBS char *ptr, *ptr2; int i; strncpy (str, data, len); for (i = 0; i < R_ANAL_VARSUBS; i++) if (f->varsubs[i].pat[0] != '\0' && f->varsubs[i].sub[0] != '\0' && (ptr = strstr (data, f->varsubs[i].pat))) { *ptr = '\0'; ptr2 = ptr + strlen (f->varsubs[i].pat); snprintf (str, len, "%s%s%s", data, f->varsubs[i].sub, ptr2); } return R_TRUE; #else strncpy (str, data, len); return R_FALSE; #endif } struct r_parse_plugin_t r_parse_plugin_mips_pseudo = { .name = "mips.pseudo", .desc = "MIPS pseudo syntax", .init = NULL, .fini = NULL, .parse = parse, .assemble = &assemble, .varsub = &varsub, }; #ifndef CORELIB struct r_lib_struct_t radare_plugin = { .type = R_LIB_TYPE_PARSE, .data = &r_parse_plugin_mips_pseudo }; #endif