From 54e763a16268bc6f85e2d53814412901211e06d1 Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 31 Dec 2013 23:50:17 +0200 Subject: [PATCH] mark pure __stdcall funcs as such some of them are callbacks to WINAPI or some dlls.. --- run_mkpubinc.sh | 1 + tools/mkbridge.c | 40 +++++++++++++++++++++++++++------------- tools/translate.c | 24 +++++++++++++++++++++++- 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/run_mkpubinc.sh b/run_mkpubinc.sh index 889e0db..8d6afe8 100755 --- a/run_mkpubinc.sh +++ b/run_mkpubinc.sh @@ -25,5 +25,6 @@ cat $2 | \ while read a; do # echo "_$a equ $a" >> $3 # echo "PUBLIC _$a" >> $3 + a=`echo $a | awk -F@ '{print $1}'` echo "PUBLIC $a" >> $3 done diff --git a/tools/mkbridge.c b/tools/mkbridge.c index 3b3f4ce..4fb10a9 100644 --- a/tools/mkbridge.c +++ b/tools/mkbridge.c @@ -23,7 +23,8 @@ static int is_x86_reg_saved(const char *reg) return !nosave; } -static void out_toasm_x86(FILE *f, char *sym, const struct parsed_proto *pp) +static void out_toasm_x86(FILE *f, const char *sym_in, + const char *sym_out, const struct parsed_proto *pp) { int must_save = 0; int sarg_ofs = 1; // stack offset to args, in DWORDs @@ -40,11 +41,11 @@ static void out_toasm_x86(FILE *f, char *sym, const struct parsed_proto *pp) must_save |= is_x86_reg_saved(pp->arg[i].reg); } - fprintf(f, ".global _%s\n", sym); - fprintf(f, "_%s:\n", sym); + fprintf(f, ".global _%s\n", sym_in); + fprintf(f, "_%s:\n", sym_in); - if (pp->argc_reg == 0 && !pp->is_stdcall) { - fprintf(f, "\tjmp %s\n\n", sym); + if (pp->argc_reg == 0) { + fprintf(f, "\tjmp %s\n\n", sym_out); return; } @@ -56,7 +57,7 @@ static void out_toasm_x86(FILE *f, char *sym, const struct parsed_proto *pp) fprintf(f, "\tmovl %d(%%esp), %%%s\n", (i + sarg_ofs) * 4, pp->arg[i].reg); } - fprintf(f, "\tjmp %s\n\n", sym); + fprintf(f, "\tjmp %s\n\n", sym_out); return; } @@ -89,7 +90,7 @@ static void out_toasm_x86(FILE *f, char *sym, const struct parsed_proto *pp) } fprintf(f, "\n\t# %s\n", pp->is_stdcall ? "__stdcall" : "__cdecl"); - fprintf(f, "\tcall %s\n\n", sym); + fprintf(f, "\tcall %s\n\n", sym_out); if (args_repushed && !pp->is_stdcall) fprintf(f, "\tadd $%d,%%esp\n", args_repushed * 4); @@ -103,7 +104,8 @@ static void out_toasm_x86(FILE *f, char *sym, const struct parsed_proto *pp) fprintf(f, "\tret\n\n"); } -static void out_fromasm_x86(FILE *f, char *sym, const struct parsed_proto *pp) +static void out_fromasm_x86(FILE *f, const char *sym, + const struct parsed_proto *pp) { int sarg_ofs = 1; // stack offset to args, in DWORDs int argc_repush; @@ -121,8 +123,12 @@ static void out_fromasm_x86(FILE *f, char *sym, const struct parsed_proto *pp) fprintf(f, ".global %s\n", sym); fprintf(f, "%s:\n", sym); - if (pp->argc_reg == 0 && !pp->is_stdcall) { - fprintf(f, "\tjmp _%s\n\n", sym); + if (pp->argc_reg == 0) { + //fprintf(f, "\tjmp _%s\n\n", sym); + fprintf(f, "\tjmp _%s", sym); + if (pp->is_stdcall && pp->argc > 0) + fprintf(f, "@%d", pp->argc * 4); + fprintf(f, "\n\n"); return; } @@ -168,8 +174,10 @@ int main(int argc, char *argv[]) FILE *fout, *fsyms_to, *fsyms_from, *fhdr; const struct parsed_proto *pp; char line[256]; + char sym_noat[256]; char sym[256]; - int ret; + char *p; + int ret = 1; if (argc != 5) { printf("usage:\n%s \n", @@ -199,11 +207,17 @@ int main(int argc, char *argv[]) if (sym[0] == 0 || sym[0] == ';' || sym[0] == '#') continue; - pp = proto_parse(fhdr, sym); + // IDA asm doesn't do '@' notation.. + strcpy(sym_noat, sym); + p = strchr(sym_noat, '@'); + if (p != NULL) + *p = 0; + + pp = proto_parse(fhdr, sym_noat); if (pp == NULL) goto out; - out_toasm_x86(fout, sym, pp); + out_toasm_x86(fout, sym, sym_noat, pp); } fprintf(fout, "# from asm\n\n"); diff --git a/tools/translate.c b/tools/translate.c index ef38d73..8b48a1a 100644 --- a/tools/translate.c +++ b/tools/translate.c @@ -2189,19 +2189,41 @@ static void gen_func(FILE *fout, FILE *fhdr, const char *funcn, int opcnt) ferr(ops, "proto_parse failed for '%s'\n", funcn); fprintf(fout, "%s ", g_func_pp->ret_type.name); + if (g_func_pp->is_stdcall && g_func_pp->argc_reg == 0) + fprintf(fout, "__stdcall "); if (g_ida_func_attr & IDAFA_NORETURN) fprintf(fout, "noreturn "); fprintf(fout, "%s(", funcn); + for (i = 0; i < g_func_pp->argc; i++) { if (i > 0) fprintf(fout, ", "); - fprintf(fout, "%s a%d", g_func_pp->arg[i].type.name, i + 1); + if (g_func_pp->arg[i].fptr != NULL) { + // func pointer.. + pp = g_func_pp->arg[i].fptr; + fprintf(fout, "%s (", pp->ret_type.name); + if (pp->is_stdcall && pp->argc_reg == 0) + fprintf(fout, "__stdcall "); + fprintf(fout, "*a%d)(", i + 1); + for (j = 0; j < pp->argc; j++) { + if (j > 0) + fprintf(fout, ", "); + if (pp->arg[j].fptr) + ferr(ops, "nested fptr\n"); + fprintf(fout, "%s", pp->arg[j].type.name); + } + fprintf(fout, ")"); + } + else { + fprintf(fout, "%s a%d", g_func_pp->arg[i].type.name, i + 1); + } } if (g_func_pp->is_vararg) { if (i > 0) fprintf(fout, ", "); fprintf(fout, "..."); } + fprintf(fout, ")\n{\n"); // pass1: -- 2.39.2