d8891fcc |
1 | #define NO_OBSOLETE_FUNCS |
2 | #include <ida.hpp> |
3 | #include <idp.hpp> |
4 | #include <bytes.hpp> |
5 | #include <loader.hpp> |
6 | #include <kernwin.hpp> |
7 | |
8 | #include <name.hpp> |
9 | #include <frame.hpp> |
10 | #include <struct.hpp> |
11 | #include <auto.hpp> |
12 | |
13 | #define IS_START(w, y) !strncmp(w, y, strlen(y)) |
14 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) |
15 | |
16 | //-------------------------------------------------------------------------- |
17 | static int idaapi init(void) |
18 | { |
19 | return PLUGIN_OK; |
20 | } |
21 | |
22 | //-------------------------------------------------------------------------- |
23 | static void idaapi term(void) |
24 | { |
25 | } |
26 | |
27 | //-------------------------------------------------------------------------- |
28 | |
29 | static const char *reserved_names[] = { |
30 | "name", |
31 | "offset", |
32 | }; |
33 | |
34 | static int is_name_reserved(const char *name) |
35 | { |
36 | int i; |
37 | for (i = 0; i < ARRAY_SIZE(reserved_names); i++) |
38 | if (strcasecmp(name, reserved_names[i]) == 0) |
39 | return 1; |
40 | |
41 | return 0; |
42 | } |
43 | |
44 | static void do_def_line(char *buf, size_t buf_size, const char *line) |
45 | { |
46 | int len; |
47 | |
48 | tag_remove(line, buf, buf_size); // remove color codes |
49 | len = strlen(buf); |
50 | if (len < 9) { |
51 | buf[0] = 0; |
52 | return; |
53 | } |
54 | memmove(buf, buf + 9, len - 9 + 1); // rm address |
55 | } |
56 | |
57 | static void idaapi run(int /*arg*/) |
58 | { |
59 | // isEnabled(ea) // address belongs to disassembly |
60 | // ea_t ea = get_screen_ea(); |
61 | // nextaddr(ea) - no worky? |
62 | FILE *fout = NULL; |
63 | int fout_line = 0; |
64 | char buf[MAXSTR]; |
65 | struc_t *frame; |
66 | func_t *func; |
67 | ea_t ui_ea_block = 0; |
68 | ea_t tmp_ea; |
69 | ea_t ea; |
70 | int i, o, m, n; |
71 | int ret; |
72 | char *p; |
73 | |
74 | // rename global syms which conflict with frame member names |
75 | ea = inf.minEA; |
76 | func = get_next_func(ea); |
77 | while (func != NULL) |
78 | { |
79 | frame = get_frame(func); |
80 | if (frame != NULL) |
81 | { |
82 | for (m = 0; m < (int)frame->memqty; m++) |
83 | { |
84 | ret = get_member_name(frame->members[m].id, buf, sizeof(buf)); |
85 | if (ret <= 0) { |
86 | msg("%x: member has no name?\n", ea); |
87 | return; |
88 | } |
89 | if (buf[0] == ' ') // what's this? |
90 | continue; |
91 | if (IS_START(buf, "arg_") || IS_START(buf, "var_")) |
92 | continue; |
93 | |
94 | if (is_name_reserved(buf)) { |
95 | msg("%x: renaming '%s'\n", ea, buf); |
96 | qstrncat(buf, "_", sizeof(buf)); |
97 | ret = set_member_name(frame, frame->members[m].soff, buf); |
98 | if (!ret) { |
99 | msg("%x: renaming failed\n", ea); |
100 | return; |
101 | } |
102 | } |
103 | |
104 | tmp_ea = get_name_ea(ea, buf); |
105 | if (tmp_ea == 0 || tmp_ea == ~0) |
106 | continue; |
107 | |
108 | msg("%x: from %x: renaming '%s'\n", tmp_ea, ea, buf); |
109 | qstrncat(buf, "_g", sizeof(buf)); |
110 | set_name(tmp_ea, buf); |
111 | } |
112 | } |
113 | |
114 | func = get_next_func(ea); |
115 | if (func) |
116 | ea = get_next_func_addr(func, ea); |
117 | } |
118 | |
119 | char *fname = askfile_c(1, NULL, "Save asm file"); |
120 | if (fname == NULL) |
121 | return; |
122 | fout = qfopen(fname, "w"); |
123 | if (fout == NULL) { |
124 | msg("couldn't open '%s'\n", fname); |
125 | return; |
126 | } |
127 | |
128 | show_wait_box("Saving.."); |
129 | |
130 | // deal with the beginning |
131 | ea = inf.minEA; |
132 | int flags = 0; // calc_default_idaplace_flags(); |
133 | linearray_t ln(&flags); |
134 | idaplace_t pl; |
135 | pl.ea = ea; |
136 | pl.lnnum = 0; |
137 | ln.set_place(&pl); |
138 | n = ln.get_linecnt(); |
139 | for (i = 0; i < n - 1; i++) { |
140 | do_def_line(buf, sizeof(buf), ln.down()); |
141 | if (strstr(buf, "include")) |
142 | continue; |
143 | |
144 | fout_line++; |
145 | qfprintf(fout, "%s\n", buf); |
146 | p = strstr(buf, ".mmx"); |
147 | if (p != NULL) { |
148 | memcpy(p, ".xmm", 4); |
149 | fout_line++; |
150 | qfprintf(fout, "%s\n", buf); |
151 | } |
152 | } |
153 | |
154 | for (;;) |
155 | { |
156 | if ((ea >> 14) != ui_ea_block) { |
157 | ui_ea_block = ea >> 14; |
158 | showAddr(ea); |
159 | if (wasBreak()) |
160 | break; |
161 | } |
162 | |
163 | segment_t *seg = getseg(ea); |
164 | if (!seg || seg->type != SEG_CODE) |
165 | goto pass; |
166 | if (!decode_insn(ea)) |
167 | goto pass; |
168 | |
169 | // note: decode_insn() picks up things like dd, size is then weird |
170 | //cmd_size = cmd.size; |
171 | |
172 | for (o = 0; o < UA_MAXOP; o++) { |
173 | if (cmd.Operands[o].type == o_void) |
174 | break; |
175 | |
176 | } |
177 | |
178 | pass: |
179 | fout_line++; |
180 | do_def_line(buf, sizeof(buf), ln.down()); |
181 | qfprintf(fout, "%s\n", buf); |
182 | |
183 | ea = next_not_tail(ea); // correct? |
184 | if (ea == 0 || ea == ~0) |
185 | break; |
186 | |
187 | pl.ea = ea; |
188 | pl.lnnum = 0; |
189 | ln.set_place(&pl); |
190 | n = ln.get_linecnt(); |
191 | for (i = 0; i < n - 1; i++) |
192 | { |
193 | fout_line++; |
194 | do_def_line(buf, sizeof(buf), ln.down()); |
195 | qfprintf(fout, "%s\n", buf); |
196 | } |
197 | } |
198 | |
199 | if (fout != NULL) |
200 | qfclose(fout); |
201 | |
202 | hide_wait_box(); |
203 | msg("%d lines saved.\n", fout_line); |
204 | } |
205 | |
206 | //-------------------------------------------------------------------------- |
207 | |
208 | static const char comment[] = "Generate disassembly lines for one address"; |
209 | static const char help[] = "Generate asm file\n"; |
210 | static const char wanted_name[] = "Save asm"; |
211 | static const char wanted_hotkey[] = "Ctrl-F6"; |
212 | |
213 | //-------------------------------------------------------------------------- |
214 | // |
215 | // PLUGIN DESCRIPTION BLOCK |
216 | // |
217 | //-------------------------------------------------------------------------- |
218 | plugin_t PLUGIN = |
219 | { |
220 | IDP_INTERFACE_VERSION, |
221 | 0, // plugin flags |
222 | init, // initialize |
223 | term, // terminate. this pointer may be NULL. |
224 | run, // invoke plugin |
225 | comment, // long comment about the plugin |
226 | // it could appear in the status line |
227 | // or as a hint |
228 | help, // multiline help about the plugin |
229 | wanted_name, // the preferred short name of the plugin |
230 | wanted_hotkey // the preferred hotkey to run the plugin |
231 | }; |
232 | |
233 | // vim:ts=2:shiftwidth=2:expandtab |