Subversion Repositories Kolibri OS

Rev

Rev 8322 | Go to most recent revision | 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 <sys/kos_LoadConsole.h>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <ctype.h>
  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 <io.h>
  25. # include <fcntl.h>
  26. #endif
  27.  
  28. #ifdef __DJGPP__
  29. # include <unistd.h>  /* for isatty() */
  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 <v>   : Set vendor. <v> = {intel, amd}.\n"
  46.   "    -o <pc>  : Set the value of program counter to <pc>. (default = 0)\n"
  47.   "    -s <n>   : Set the number of bytes to skip before disassembly to <n>.\n"
  48.   "    -c <n>   : Set the number of bytes to disassemble to <n>.\n"
  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. }
  268.