Subversion Repositories Kolibri OS

Rev

Rev 8518 | Blame | Compare with Previous | Last modification | View Log | RSS feed

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