]> andersk Git - udis86.git/blob - udcli/udcli.c
Initial commit
[udis86.git] / udcli / udcli.c
1 /* udis86 - udcli/udcli.c
2  *
3  * Copyright (c) 2002-2009 Vivek Thampi
4  * All rights reserved.
5  * 
6  * Redistribution and use in source and binary forms, with or without modification, 
7  * are permitted provided that the following conditions are met:
8  * 
9  *     * Redistributions of source code must retain the above copyright notice, 
10  *       this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above copyright notice, 
12  *       this list of conditions and the following disclaimer in the documentation 
13  *       and/or other materials provided with the distribution.
14  * 
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
22  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <udis86.h>
31 #include <config.h>
32
33 #if defined(__amd64__) || defined(__x86_64__)
34 #  define FMT "l"
35 #else
36 #  define FMT "ll"
37 #endif
38
39 #if defined(__DJGPP__) || defined(_WIN32)
40 # include <io.h>
41 # include <fcntl.h>
42 #endif 
43
44 #ifdef __DJGPP__
45 # include <unistd.h>  /* for isatty() */
46 # define _setmode setmode
47 # define _fileno fileno
48 # define _O_BINARY O_BINARY
49 #endif
50
51 /* help string */
52 static char help[] = 
53 {
54   "Usage: %s [-option[s]] file\n"
55   "Options:\n"
56   "    -16      : Set the disassembly mode to 16 bits. \n"
57   "    -32      : Set the disassembly mode to 32 bits. (default)\n"
58   "    -64      : Set the disassembly mode to 64 bits.\n"
59   "    -intel   : Set the output to INTEL (NASM like) syntax. (default)\n"
60   "    -att     : Set the output to AT&T (GAS like) syntax.\n"
61   "    -v <v>   : Set vendor. <v> = {intel, amd}.\n"
62   "    -o <pc>  : Set the value of program counter to <pc>. (default = 0)\n"
63   "    -s <n>   : Set the number of bytes to skip before disassembly to <n>.\n"
64   "    -c <n>   : Set the number of bytes to disassemble to <n>.\n"
65   "    -x       : Set the input mode to whitespace seperated 8-bit numbers in\n"
66   "               hexadecimal representation. Example: 0f 01 ae 00\n"
67   "    -noff    : Do not display the offset of instructions.\n"
68   "    -nohex   : Do not display the hexadecimal code of instructions.\n"
69   "    -h       : Display this help message.\n"
70   "    --version: Show version.\n"
71   "\n"
72   "Udcli is a front-end to the Udis86 Disassembler Library.\n" 
73   "http://udis86.sourceforge.net/\n"
74 };
75
76 FILE* fptr = NULL;
77 uint64_t o_skip = 0;
78 uint64_t o_count = 0;
79 unsigned char o_do_count= 0;
80 unsigned char o_do_off = 1;
81 unsigned char o_do_hex = 1;
82 unsigned char o_do_x = 0;
83 unsigned o_vendor = UD_VENDOR_AMD;
84
85 int input_hook_x(ud_t* u);
86 int input_hook_file(ud_t* u);
87
88 int main(int argc, char **argv)
89 {
90   char *prog_path = *argv;
91   char *s;
92   ud_t ud_obj;
93   int mode = 0;
94
95   /* initialize */
96   ud_init(&ud_obj);
97   ud_set_mode(&ud_obj, 32);
98   ud_set_syntax(&ud_obj, UD_SYN_INTEL);
99
100 #ifdef __DJGPP__
101   if ( !isatty( fileno( stdin ) ) )
102 #endif
103 #if defined(__DJGPP) || defined(_WIN32)
104   _setmode(_fileno(stdin), _O_BINARY);
105 #endif  
106
107   fptr = stdin;
108
109   argv++;
110
111   /* loop through the args */
112   while(--argc > 0) {
113         if (strcmp(*argv,"-16") == 0) {
114                 ud_set_mode(&ud_obj, 16);
115                 mode = 16;
116         } else if (strcmp(*argv,"-32") == 0) {
117                 ud_set_mode(&ud_obj, 32);
118                 mode = 32;
119         } else if (strcmp(*argv,"-64") == 0) {
120                 ud_set_mode(&ud_obj, 64);
121                 mode = 64;
122         } else if (strcmp(*argv,"-intel") == 0)
123                 ud_set_syntax(&ud_obj, UD_SYN_INTEL);
124         else if (strcmp(*argv,"-att") == 0)
125                 ud_set_syntax(&ud_obj, UD_SYN_ATT);
126         else if (strcmp(*argv,"-noff") == 0)
127                 o_do_off = 0;
128         else if (strcmp(*argv,"-nohex") == 0)
129                 o_do_hex = 0;
130         else if (strcmp(*argv,"-x") == 0)
131                 o_do_x = 1;
132         else if (strcmp(*argv,"-s") == 0)
133                 if (--argc) {
134                         s = *(++argv);
135                         if (sscanf(s, "%"  FMT "d", &o_skip) == 0)
136                                 fprintf(stderr, "Invalid value given for -s.\n");
137                 } else { 
138                         fprintf(stderr, "No value given for -s.\n");
139                         printf(help, prog_path);
140                         exit(EXIT_FAILURE);
141                 }
142         else if (strcmp(*argv,"-c") == 0)
143                 if (--argc) {
144                         o_do_count= 1;
145                         s = *(++argv);
146                         if (sscanf(s, "%" FMT "d", &o_count) == 0)
147                                 fprintf(stderr, "Invalid value given for -c.\n");
148                 } else { 
149                         fprintf(stderr, "No value given for -c.\n");
150                         printf(help, prog_path);
151                         exit(EXIT_FAILURE);
152                 }
153         else if (strcmp(*argv,"-v") == 0)
154                 if (--argc) {
155                         s = *(++argv);
156                         if (*s == 'i')
157                                 ud_set_vendor(&ud_obj, UD_VENDOR_INTEL);
158                 } else { 
159                         fprintf(stderr, "No value given for -v.\n");
160                         printf(help, prog_path);
161                         exit(EXIT_FAILURE);
162                 }
163         else if (strcmp(*argv,"-o") == 0) {
164                 if (--argc) {
165                         uint64_t pc = 0;
166                         s = *(++argv);
167                         if (sscanf(s, "%" FMT "x", &pc) == 0)
168                                 fprintf(stderr, "Invalid value given for -o.\n");
169                         ud_set_pc(&ud_obj, pc);
170                 } else { 
171                         fprintf(stderr, "No value given for -o.\n");
172                         printf(help, prog_path);
173                         exit(EXIT_FAILURE);
174                 }
175         } else if ( strcmp( *argv, "--version" ) == 0 ) {
176                 fprintf(stderr, "%s\n", PACKAGE_STRING );
177                 exit(0);
178         } else if((*argv)[0] == '-') {
179                 fprintf(stderr, "Invalid option %s.\n", *argv);
180                 printf(help, prog_path);
181                 exit(EXIT_FAILURE);
182         } else {
183                 static int i = 0;
184                 s = *argv;
185                 if (i) {
186                         fprintf(stderr, "Multiple files specified.\n");
187                         exit(EXIT_FAILURE);
188                 } else i = 1;
189                 if ((fptr = fopen(s, "rb")) == NULL) {
190                         fprintf(stderr, "Failed to open file: %s.\n", s);
191                                 exit(EXIT_FAILURE);
192                 }
193         }
194         argv++;
195   }
196
197   if (o_do_x)
198         ud_set_input_hook(&ud_obj, input_hook_x);
199   else  ud_set_input_hook(&ud_obj, input_hook_file);    
200
201   if (o_skip) {
202         o_count += o_skip;
203         ud_input_skip(&ud_obj, o_skip);
204   }
205
206   /* disassembly loop */
207   while (ud_disassemble(&ud_obj)) {
208         if (o_do_off)
209                 printf("%016" FMT "x ", ud_insn_off(&ud_obj));
210         if (o_do_hex) {
211                 char* hex1, *hex2;
212                 char c;
213                 hex1 = ud_insn_hex(&ud_obj);
214                 hex2 = hex1 + 16;
215                 c = hex1[16];
216                 hex1[16] = 0;
217                 printf("%-16s %-24s", hex1, ud_insn_asm(&ud_obj));
218                 hex1[16] = c;
219                 if (strlen(hex1) > 16) {
220                         printf("\n");
221                         if (o_do_off)
222                                 printf("%15s -", "");
223                         printf("%-16s", hex2);
224                 }
225         } 
226         else printf(" %-24s", ud_insn_asm(&ud_obj));
227
228         printf("\n");
229   }
230   
231   exit(EXIT_SUCCESS);
232   return 0;
233 }
234
235 int input_hook_x(ud_t* u)
236 {
237   unsigned int c, i;
238
239   if (o_do_count) {
240         if (! o_count)
241                 return UD_EOI;
242         else --o_count;
243   }
244
245   i = fscanf(fptr, "%x", &c);
246
247   if (i == EOF)
248         return UD_EOI;
249   if (i == 0) {
250         fprintf(stderr, "Error: Invalid input, should be in hexadecimal form (8-bit).\n");
251         return UD_EOI;
252   }
253   if (c > 0xFF)
254         fprintf(stderr, "Warning: Casting non-8-bit input (%x), to %x.\n", c, c & 0xFF);
255   return (int) (c & 0xFF);
256 }       
257
258 int input_hook_file(ud_t* u)
259 {
260   int c;
261
262   if (o_do_count) {
263           if (! o_count) {
264                 return -1;
265           } else o_count -- ;
266   }
267
268   if ((c = fgetc(fptr)) == EOF)
269         return UD_EOI;
270   return c;
271 }
This page took 0.055581 seconds and 5 git commands to generate.