Rev 8322 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8322 | maxcodehac | 1 | /* ----------------------------------------------------------------------------- |
2 | * udcli.c - front end to udis86. |
||
3 | * |
||
4 | * Copyright (c) 2004,2005,2006,2007 Vivek Mohan |
||
5 | * All rights reserved. |
||
6 | * See (LICENSE) |
||
7 | * ----------------------------------------------------------------------------- |
||
8 | */ |
||
8518 | maxcodehac | 9 | #include |
8322 | maxcodehac | 10 | #include |
11 | #include |
||
12 | #include |
||
13 | #include |
||
14 | #include "udis86.h" |
||
15 | #include "config.h" |
||
16 | |||
17 | #if defined(__amd64__) || defined(__x86_64__) |
||
18 | # define FMT "l" |
||
19 | #else |
||
20 | # define FMT "ll" |
||
21 | #endif |
||
22 | |||
23 | #if defined(__DJGPP__) || defined(_WIN32) |
||
24 | # include |
||
25 | # include |
||
26 | #endif |
||
27 | |||
28 | #ifdef __DJGPP__ |
||
29 | # include |
||
30 | //# define _setmode setmode |
||
31 | # define _fileno fileno |
||
32 | # define _O_BINARY O_BINARY |
||
33 | #endif |
||
34 | |||
35 | /* help string */ |
||
36 | static char help[] = |
||
37 | { |
||
38 | "Usage: %s [-option[s]] file\n" |
||
39 | "Options:\n" |
||
40 | " -16 : Set the disassembly mode to 16 bits. \n" |
||
41 | " -32 : Set the disassembly mode to 32 bits. (default)\n" |
||
42 | " -64 : Set the disassembly mode to 64 bits.\n" |
||
43 | " -intel : Set the output to INTEL (NASM like) syntax. (default)\n" |
||
44 | " -att : Set the output to AT&T (GAS like) syntax.\n" |
||
45 | " -v |
||
46 | " -o |
||
47 | " -s |
||
48 | " -c |
||
49 | " -x : Set the input mode to whitespace seperated 8-bit numbers in\n" |
||
50 | " hexadecimal representation. Example: 0f 01 ae 00\n" |
||
51 | " -noff : Do not display the offset of instructions.\n" |
||
52 | " -nohex : Do not display the hexadecimal code of instructions.\n" |
||
53 | " -h : Display this help message.\n" |
||
54 | " --version: Show version.\n" |
||
55 | "\n" |
||
56 | "Udcli is a front-end to the Udis86 Disassembler Library.\n" |
||
57 | "http://udis86.sourceforge.net/\n" |
||
58 | }; |
||
59 | |||
60 | FILE* fptr = NULL; |
||
61 | uint64_t o_skip = 0; |
||
62 | uint64_t o_count = 0; |
||
63 | unsigned char o_do_count= 0; |
||
64 | unsigned char o_do_off = 1; |
||
65 | unsigned char o_do_hex = 1; |
||
66 | unsigned char o_do_x = 0; |
||
67 | unsigned o_vendor = UD_VENDOR_AMD; |
||
68 | |||
69 | int input_hook_x(ud_t* u); |
||
70 | int input_hook_file(ud_t* u); |
||
71 | |||
72 | int main(int argc, char **argv) |
||
73 | { |
||
74 | load_console(); |
||
75 | con_set_title("udi disassembler"); |
||
76 | FILE *stream; |
||
77 | stream = fopen( "disasm.out", "w" ); |
||
78 | |||
79 | char *prog_path = *argv; |
||
80 | char *s; |
||
81 | ud_t ud_obj; |
||
82 | int mode = 0; |
||
83 | |||
84 | /* initialize */ |
||
85 | ud_init(&ud_obj); |
||
86 | ud_set_mode(&ud_obj, 32); |
||
87 | ud_set_syntax(&ud_obj, UD_SYN_INTEL); |
||
88 | |||
89 | #ifdef __DJGPP__ |
||
90 | if ( !isatty( fileno( stdin ) ) ) |
||
91 | #endif |
||
92 | #if defined(__DJGPP) || defined(_WIN32) |
||
93 | // _setmode(_fileno(stdin), _O_BINARY); |
||
94 | #endif |
||
95 | |||
96 | fptr = stdin; |
||
97 | |||
98 | argv++; |
||
99 | |||
100 | /* loop through the args */ |
||
101 | while(--argc > 0) { |
||
102 | if (strcmp(*argv,"-16") == 0) { |
||
103 | ud_set_mode(&ud_obj, 16); |
||
104 | mode = 16; |
||
105 | } else if (strcmp(*argv,"-32") == 0) { |
||
106 | ud_set_mode(&ud_obj, 32); |
||
107 | mode = 32; |
||
108 | } else if (strcmp(*argv,"-64") == 0) { |
||
109 | ud_set_mode(&ud_obj, 64); |
||
110 | mode = 64; |
||
111 | } else if (strcmp(*argv,"-intel") == 0) |
||
112 | ud_set_syntax(&ud_obj, UD_SYN_INTEL); |
||
113 | else if (strcmp(*argv,"-att") == 0) |
||
114 | ud_set_syntax(&ud_obj, UD_SYN_ATT); |
||
115 | else if (strcmp(*argv,"-noff") == 0) |
||
116 | o_do_off = 0; |
||
117 | else if (strcmp(*argv,"-nohex") == 0) |
||
118 | o_do_hex = 0; |
||
119 | else if (strcmp(*argv,"-x") == 0) |
||
120 | o_do_x = 1; |
||
121 | else if (strcmp(*argv,"-s") == 0) |
||
122 | if (--argc) { |
||
123 | s = *(++argv); |
||
124 | if (sscanf(s, "%" FMT "d", &o_skip) == 0) |
||
125 | printf( "Invalid value given for -s.\n"); |
||
126 | } else { |
||
127 | printf( "No value given for -s.\n"); |
||
128 | printf(help, prog_path); |
||
129 | exit(EXIT_FAILURE); |
||
130 | } |
||
131 | else if (strcmp(*argv,"-c") == 0) |
||
132 | if (--argc) { |
||
133 | o_do_count= 1; |
||
134 | s = *(++argv); |
||
135 | if (sscanf(s, "%" FMT "d", &o_count) == 0) |
||
136 | printf( "Invalid value given for -c.\n"); |
||
137 | } else { |
||
138 | printf( "No value given for -c.\n"); |
||
139 | printf(help, prog_path); |
||
140 | exit(EXIT_FAILURE); |
||
141 | } |
||
142 | else if (strcmp(*argv,"-v") == 0) |
||
143 | if (--argc) { |
||
144 | s = *(++argv); |
||
145 | if (*s == 'i') |
||
146 | ud_set_vendor(&ud_obj, UD_VENDOR_INTEL); |
||
147 | } else { |
||
148 | printf( "No value given for -v.\n"); |
||
149 | printf(help, prog_path); |
||
150 | exit(EXIT_FAILURE); |
||
151 | } |
||
152 | else if (strcmp(*argv,"-o") == 0) { |
||
153 | if (--argc) { |
||
154 | uint64_t pc = 0; |
||
155 | s = *(++argv); |
||
156 | if (sscanf(s, "%" FMT "x", &pc) == 0) |
||
157 | printf( "Invalid value given for -o.\n"); |
||
158 | ud_set_pc(&ud_obj, pc); |
||
159 | } else { |
||
160 | printf( "No value given for -o.\n"); |
||
161 | printf(help, prog_path); |
||
162 | exit(EXIT_FAILURE); |
||
163 | } |
||
164 | } else if ( strcmp( *argv, "--version" ) == 0 ) { |
||
165 | printf( "%s\n", PACKAGE_STRING ); |
||
166 | exit(0); |
||
167 | } else if((*argv)[0] == '-') { |
||
168 | printf( "Invalid option %s.\n", *argv); |
||
169 | printf(help, prog_path); |
||
170 | exit(EXIT_FAILURE); |
||
171 | } else { |
||
172 | static int i = 0; |
||
173 | s = *argv; |
||
174 | if (i) { |
||
175 | printf( "Multiple files specified.\n"); |
||
176 | exit(EXIT_FAILURE); |
||
177 | } else i = 1; |
||
178 | if ((fptr = fopen(s, "rb")) == NULL) { |
||
179 | printf( "Failed to open file: %s.\n", s); |
||
180 | exit(EXIT_FAILURE); |
||
181 | } |
||
182 | } |
||
183 | argv++; |
||
184 | } |
||
185 | |||
186 | if (o_do_x) |
||
187 | ud_set_input_hook(&ud_obj, input_hook_x); |
||
188 | else ud_set_input_hook(&ud_obj, input_hook_file); |
||
189 | |||
190 | if (o_skip) { |
||
191 | o_count += o_skip; |
||
192 | ud_input_skip(&ud_obj, o_skip); |
||
193 | } |
||
194 | |||
195 | /* disassembly loop */ |
||
196 | while (ud_disassemble(&ud_obj)) { |
||
197 | if (o_do_off) |
||
198 | {printf("%016" FMT "x ", ud_insn_off(&ud_obj)); |
||
199 | fprintf(stream,"%016" FMT "x ", ud_insn_off(&ud_obj));} |
||
200 | if (o_do_hex) { |
||
201 | char* hex1, *hex2; |
||
202 | char c; |
||
203 | hex1 = ud_insn_hex(&ud_obj); |
||
204 | hex2 = hex1 + 16; |
||
205 | c = hex1[16]; |
||
206 | hex1[16] = 0; |
||
207 | printf("%-16s %-24s", hex1, ud_insn_asm(&ud_obj)); |
||
208 | fprintf(stream,"%-16s %-24s", hex1, ud_insn_asm(&ud_obj)); |
||
209 | hex1[16] = c; |
||
210 | if (strlen(hex1) > 16) { |
||
211 | printf("\n"); |
||
212 | if (o_do_off) |
||
213 | printf("%15s -", ""); |
||
214 | printf("%-16s", hex2); |
||
215 | } |
||
216 | } |
||
217 | else {printf(" %-24s", ud_insn_asm(&ud_obj)); |
||
218 | fprintf(stream," %-24s", ud_insn_asm(&ud_obj)); |
||
219 | } |
||
220 | |||
221 | printf("\n"); |
||
222 | fprintf(stream,"\n"); |
||
223 | } |
||
224 | |||
225 | exit(EXIT_SUCCESS); |
||
226 | fclose( stream ); |
||
227 | |||
228 | return 0; |
||
229 | } |
||
230 | |||
231 | int input_hook_x(ud_t* u) |
||
232 | { |
||
233 | unsigned int c, i; |
||
234 | |||
235 | if (o_do_count) { |
||
236 | if (! o_count) |
||
237 | return UD_EOI; |
||
238 | else --o_count; |
||
239 | } |
||
240 | |||
241 | i = fscanf(fptr, "%x", &c); |
||
242 | |||
243 | if (i == EOF) |
||
244 | return UD_EOI; |
||
245 | if (i == 0) { |
||
246 | printf( "Error: Invalid input, should be in hexadecimal form (8-bit).\n"); |
||
247 | return UD_EOI; |
||
248 | } |
||
249 | if (c > 0xFF) |
||
250 | printf( "Warning: Casting non-8-bit input (%x), to %x.\n", c, c & 0xFF); |
||
251 | return (int) (c & 0xFF); |
||
252 | } |
||
253 | |||
254 | int input_hook_file(ud_t* u) |
||
255 | { |
||
256 | int c; |
||
257 | |||
258 | if (o_do_count) { |
||
259 | if (! o_count) { |
||
260 | return -1; |
||
261 | } else o_count -- ; |
||
262 | } |
||
263 | |||
264 | if ((c = fgetc(fptr)) == EOF) |
||
265 | return UD_EOI; |
||
266 | return c; |
||
267 | } |