From d8891fcce603bb8c7147cce943111b000d54d193 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 26 Jan 2014 17:53:17 +0200 Subject: [PATCH] starting a plugin --- plugin/Makefile | 16 ++++ plugin/saveasm.cpp | 233 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 plugin/Makefile create mode 100644 plugin/saveasm.cpp diff --git a/plugin/Makefile b/plugin/Makefile new file mode 100644 index 0000000..aa48e8c --- /dev/null +++ b/plugin/Makefile @@ -0,0 +1,16 @@ +CROSS_COMPILE ?= i586-mingw32msvc- +CC = $(CROSS_COMPILE)gcc +CXX = $(CROSS_COMPILE)g++ +IDASDK = $(wildcard idasdk*) + +CFLAGS += -Wall -Wno-sign-compare +CFLAGS += -I$(IDASDK)/include/ -D__IDP__ -D__PLUGIN__ -D__NT__ +LDLIBS += $(IDASDK)/lib/x86_win_gcc_32/ida.a + +all: saveasm.plw + +%.plw: %.cpp + $(CXX) -shared -o $@ $(CFLAGS) $^ $(LDFLAGS) $(LDLIBS) + +clean: + $(RM) saveasm.plw diff --git a/plugin/saveasm.cpp b/plugin/saveasm.cpp new file mode 100644 index 0000000..97e049e --- /dev/null +++ b/plugin/saveasm.cpp @@ -0,0 +1,233 @@ +#define NO_OBSOLETE_FUNCS +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define IS_START(w, y) !strncmp(w, y, strlen(y)) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + +//-------------------------------------------------------------------------- +static int idaapi init(void) +{ + return PLUGIN_OK; +} + +//-------------------------------------------------------------------------- +static void idaapi term(void) +{ +} + +//-------------------------------------------------------------------------- + +static const char *reserved_names[] = { + "name", + "offset", +}; + +static int is_name_reserved(const char *name) +{ + int i; + for (i = 0; i < ARRAY_SIZE(reserved_names); i++) + if (strcasecmp(name, reserved_names[i]) == 0) + return 1; + + return 0; +} + +static void do_def_line(char *buf, size_t buf_size, const char *line) +{ + int len; + + tag_remove(line, buf, buf_size); // remove color codes + len = strlen(buf); + if (len < 9) { + buf[0] = 0; + return; + } + memmove(buf, buf + 9, len - 9 + 1); // rm address +} + +static void idaapi run(int /*arg*/) +{ + // isEnabled(ea) // address belongs to disassembly + // ea_t ea = get_screen_ea(); + // nextaddr(ea) - no worky? + FILE *fout = NULL; + int fout_line = 0; + char buf[MAXSTR]; + struc_t *frame; + func_t *func; + ea_t ui_ea_block = 0; + ea_t tmp_ea; + ea_t ea; + int i, o, m, n; + int ret; + char *p; + + // rename global syms which conflict with frame member names + ea = inf.minEA; + func = get_next_func(ea); + while (func != NULL) + { + frame = get_frame(func); + if (frame != NULL) + { + for (m = 0; m < (int)frame->memqty; m++) + { + ret = get_member_name(frame->members[m].id, buf, sizeof(buf)); + if (ret <= 0) { + msg("%x: member has no name?\n", ea); + return; + } + if (buf[0] == ' ') // what's this? + continue; + if (IS_START(buf, "arg_") || IS_START(buf, "var_")) + continue; + + if (is_name_reserved(buf)) { + msg("%x: renaming '%s'\n", ea, buf); + qstrncat(buf, "_", sizeof(buf)); + ret = set_member_name(frame, frame->members[m].soff, buf); + if (!ret) { + msg("%x: renaming failed\n", ea); + return; + } + } + + tmp_ea = get_name_ea(ea, buf); + if (tmp_ea == 0 || tmp_ea == ~0) + continue; + + msg("%x: from %x: renaming '%s'\n", tmp_ea, ea, buf); + qstrncat(buf, "_g", sizeof(buf)); + set_name(tmp_ea, buf); + } + } + + func = get_next_func(ea); + if (func) + ea = get_next_func_addr(func, ea); + } + + char *fname = askfile_c(1, NULL, "Save asm file"); + if (fname == NULL) + return; + fout = qfopen(fname, "w"); + if (fout == NULL) { + msg("couldn't open '%s'\n", fname); + return; + } + + show_wait_box("Saving.."); + + // deal with the beginning + ea = inf.minEA; + int flags = 0; // calc_default_idaplace_flags(); + linearray_t ln(&flags); + idaplace_t pl; + pl.ea = ea; + pl.lnnum = 0; + ln.set_place(&pl); + n = ln.get_linecnt(); + for (i = 0; i < n - 1; i++) { + do_def_line(buf, sizeof(buf), ln.down()); + if (strstr(buf, "include")) + continue; + + fout_line++; + qfprintf(fout, "%s\n", buf); + p = strstr(buf, ".mmx"); + if (p != NULL) { + memcpy(p, ".xmm", 4); + fout_line++; + qfprintf(fout, "%s\n", buf); + } + } + + for (;;) + { + if ((ea >> 14) != ui_ea_block) { + ui_ea_block = ea >> 14; + showAddr(ea); + if (wasBreak()) + break; + } + + segment_t *seg = getseg(ea); + if (!seg || seg->type != SEG_CODE) + goto pass; + if (!decode_insn(ea)) + goto pass; + + // note: decode_insn() picks up things like dd, size is then weird + //cmd_size = cmd.size; + + for (o = 0; o < UA_MAXOP; o++) { + if (cmd.Operands[o].type == o_void) + break; + + } + +pass: + fout_line++; + do_def_line(buf, sizeof(buf), ln.down()); + qfprintf(fout, "%s\n", buf); + + ea = next_not_tail(ea); // correct? + if (ea == 0 || ea == ~0) + break; + + pl.ea = ea; + pl.lnnum = 0; + ln.set_place(&pl); + n = ln.get_linecnt(); + for (i = 0; i < n - 1; i++) + { + fout_line++; + do_def_line(buf, sizeof(buf), ln.down()); + qfprintf(fout, "%s\n", buf); + } + } + + if (fout != NULL) + qfclose(fout); + + hide_wait_box(); + msg("%d lines saved.\n", fout_line); +} + +//-------------------------------------------------------------------------- + +static const char comment[] = "Generate disassembly lines for one address"; +static const char help[] = "Generate asm file\n"; +static const char wanted_name[] = "Save asm"; +static const char wanted_hotkey[] = "Ctrl-F6"; + +//-------------------------------------------------------------------------- +// +// PLUGIN DESCRIPTION BLOCK +// +//-------------------------------------------------------------------------- +plugin_t PLUGIN = +{ + IDP_INTERFACE_VERSION, + 0, // plugin flags + init, // initialize + term, // terminate. this pointer may be NULL. + run, // invoke plugin + comment, // long comment about the plugin + // it could appear in the status line + // or as a hint + help, // multiline help about the plugin + wanted_name, // the preferred short name of the plugin + wanted_hotkey // the preferred hotkey to run the plugin +}; + +// vim:ts=2:shiftwidth=2:expandtab -- 2.39.5