UnivesalDisassembler(2003)
|
00001 // uda.cc 00002 // 00003 // uda - universal disassembler 00004 // Date: 2003-05-04 00005 // 00006 // Copyright (c) 2002-2003 Ales Smrcka 00007 // 00008 // This program is licensed under GNU Library GPL. See the file COPYING. 00009 // 00010 // Main program. 00011 // 00012 00013 #include <string> 00014 #include <iomanip> 00015 #include <iostream> 00016 #include <libgen.h> 00017 #include "shared.h" 00018 #include "plugins.h" 00019 #include "sections.h" 00020 #include "symtable.h" 00021 #include "instrset.h" 00022 #include "decoder.h" 00023 using namespace std; 00024 00025 // Parse parameters 00026 int load_parameters(int &argc, char **&argv); 00027 00028 Parameters params; 00029 Parameters *Params=¶ms; 00030 00031 const char *defaultbasedir="/usr/share/uda/"; 00032 string basedir; 00033 00034 const char *par_binfile="-b"; 00035 00036 const char *sec_alldata="*data"; 00037 const char *sec_allexec="*exec"; 00038 const char *sec_all="*"; 00039 00040 extern const char *syntax; 00041 extern const char *options; 00042 typedef vector<string> str_list; 00043 00044 //locates address 00045 void locate_address(BinaryFile &binaryfile, const string address); 00046 //prints all sections 00047 void print_sections(BinaryFile &binaryfile); 00048 //prints section's content 00049 void print_content(BinaryFile &binaryfile, const string section); 00050 //prints all symbols from executable 00051 void print_symbols(BinaryFile &binaryfile); 00052 //disassemble section 00053 void disassemble(BinaryFile &binaryfile, const string section, const string scanned); 00054 00055 void set_base_dir(char *dir) 00056 { 00057 basedir = string(dirname(dir))+"/"; 00058 if (!directory_exists(basedir+instrsetdirectory)) 00059 if (directory_exists(defaultbasedir)) 00060 basedir = defaultbasedir; 00061 } 00062 00064 // M A I N 00065 int main(int argc, char *argv[]) 00066 { 00067 if (sizeof(unsigned)<4) 00068 { 00069 cerr<<"This program must be compiled for min. 32bit architecture!\n"; 00070 return 1; 00071 } 00072 set_base_dir(argv[0]); 00073 if (!load_parameters(argc, argv)) 00074 return 1; 00075 //open plugins 00076 OpenPlugins(); 00077 if (pdefined("--help")) 00078 { 00079 cout<<syntax; 00080 cout<<options; 00081 PluginsInfo(); 00082 return 0; 00083 } 00084 //prepare binary file 00085 BinaryFile binaryfile(params[par_binfile]); 00086 decinfo.binfile=&binaryfile; 00087 //find appop plugin and load all sections 00088 if (binaryfile.Init()) 00089 { // binary file loaded 00090 decinfo.onlyname = pdefined("--onlyname"); 00091 decinfo.address = !pdefined("--noaddress"); 00092 decinfo.hexdump = !pdefined("--nohexdump"); 00093 decinfo.symbolic = !pdefined("--nosymbolic"); 00094 try 00095 { 00096 //create symbols and load it from binary file 00097 symbols = new Symbols(binaryfile.bfdata); 00098 debug(":loading symbol table from binary file\n"); 00099 symbols->Load(); 00100 //load instruction set 00101 instructionset.Load(params["-P"]); 00102 if (pdefined("-m")) //load symbols from user symbol table 00103 { 00104 debug(":loading symbol table from "<<params["-m"]<<endl); 00105 symbols->Load(params["-m"].c_str()); 00106 } 00107 bool symboldefined; 00108 if (pdefined("-start")) // new starting address 00109 { 00110 decinfo.start=symbols->findaddress(params["-start"], symboldefined); 00111 if (!symboldefined) 00112 decinfo.start=hex2uint(params["-start"]); 00113 } 00114 if (pdefined("-stop")) // new stopping address 00115 { 00116 decinfo.stop=symbols->findaddress(params["-stop"], symboldefined); 00117 if (!symboldefined) 00118 decinfo.stop=hex2uint(params["-stop"]); 00119 } 00120 else 00121 if (pdefined("-size")) // new stopping address (by size from start) 00122 decinfo.size=number2uint(params["-size"]); 00123 if (pdefined("-p") || pdefined("--printsymbols")) //print all symbols 00124 print_symbols(binaryfile); 00125 else 00126 if (pdefined("-c")) //print content of section 00127 print_content(binaryfile, params["-c"]); 00128 else 00129 if (pdefined("--sections")) //print all sections' informations 00130 print_sections(binaryfile); 00131 else 00132 if (pdefined("-l")) //locate address 00133 locate_address(binaryfile, params["-l"]); 00134 else 00135 if (pdefined("-d")) //disassemble section 00136 00137 disassemble(binaryfile, params["-d"], params["-s"]); 00138 else 00139 if (pdefined("-f")) //print founded symbols 00140 { 00141 decinfo.print=false; 00142 disassemble(binaryfile, params["-f"], params["-s"]); 00143 print_symbols(binaryfile); 00144 } 00145 else 00146 disassemble(binaryfile, ".text", params["-s"]); 00147 } 00148 catch(Exception &exception) 00149 { 00150 delete symbols; 00151 exception.Print(); 00152 } 00153 } 00154 else 00155 cerr<<"Can not open file "<<params[par_binfile]<<endl; 00156 ClosePlugins(); 00157 debug(":Plugins::Close() ok\n"); 00158 return 0; 00159 } 00160 // M A I N 00162 00163 // Loads and process all parameters 00164 int load_parameters(int &argc, char **&argv) 00165 { 00166 int actarg=1; 00167 if (argc>actarg) 00168 if (argv[actarg][0]!='-') 00169 params[par_binfile]=argv[actarg++]; 00170 while (argc>actarg) 00171 if (argv[actarg][0]=='-') 00172 if (argc>actarg+1) 00173 if (string(argv[actarg])==par_binfile || argv[actarg+1][0]!='-') 00174 { 00175 params[argv[actarg]]=argv[actarg+1]; 00176 actarg+=2; 00177 } 00178 else 00179 params[argv[actarg++]]=""; 00180 else 00181 params[argv[actarg++]]=""; 00182 else 00183 params[par_binfile]=argv[actarg++]; 00184 if ((!pdefined(par_binfile) || params[par_binfile]=="") && !pdefined("--help")) 00185 { 00186 cout<<syntax; 00187 return 0; 00188 } 00189 return 1; 00190 } 00191 00192 str_list parse_sectionname(BinaryFile &binaryfile, const string section) 00193 { 00194 str_list sec; 00195 bool only_data = section==sec_alldata || section==sec_all; 00196 bool only_executable = section==sec_allexec || section==sec_all; 00197 if (only_data || only_executable) 00198 { 00199 MSections::iterator i; 00200 for (i=binaryfile.sections.begin();i!=binaryfile.sections.end();i++) 00201 if ((i->second.data->executable && only_executable) || (!i->second.data->executable && only_data)) 00202 sec.push_back(i->second.data->name); 00203 } 00204 else 00205 { 00206 string s; 00207 const char *c=section.c_str(); 00208 while (*c) 00209 { 00210 s=""; 00211 while (*c && *c!=',') 00212 s+=*c++; 00213 sec.push_back(s); 00214 if (*c) 00215 c++; 00216 } 00217 } 00218 return sec; 00219 } 00220 00221 void print_sections_header() 00222 { 00223 cout<<"no. section name start size (hex) size (dec) executable"<<endl; 00224 } 00225 00226 void print_sections_info(unsigned n, const string name, Address start, unsigned size, bool executable) 00227 { 00228 cout<<"["<<setw(2)<<dec<<setfill('0')<<n<<"] "<<name; 00229 int j=20-name.length(); 00230 for (;j>0;j--) 00231 cout<<" "; 00232 cout<<"0x"<<setw(8)<<setfill('0')<<hex<<start<< 00233 " 0x"<<setw(8)<<setfill('0')<<hex<<size<<" "<< 00234 setw(8)<<setfill(' ')<<dec<<size<<" "; 00235 if (executable) 00236 cout<<"Y"; 00237 else 00238 cout<<"N"; 00239 cout<<endl; 00240 } 00241 00242 //locates address 00243 void locate_address(BinaryFile &binaryfile, const string address) 00244 { 00245 MSections::iterator i; 00246 bool symboldefined; 00247 Address addr; 00248 // find as symbol 00249 addr=symbols->findaddress(address, symboldefined); 00250 // not found -> use as address 00251 if (!symboldefined) 00252 addr=hex2uint(address); 00253 int n=1; 00254 for (i=binaryfile.sections.begin();i!=binaryfile.sections.end();i++,n++) 00255 if (addr>=i->second.data->addr && addr<i->second.data->addr+i->second.data->size) 00256 { 00257 if (pdefined("-v")) 00258 { 00259 cout<<"Symbol "<<address; 00260 if (symboldefined) 00261 cout<<"(0x"<<hex<<setw(8)<<setfill('0')<<addr<<")"; 00262 cout<<" belongs to the section "<<i->first<<endl<<"Section information:"<<endl; 00263 print_sections_header(); 00264 print_sections_info(n, i->first, i->second.data->addr, i->second.data->size, i->second.data->executable); 00265 } 00266 else 00267 cout<<i->first<<endl; 00268 break; 00269 } 00270 } 00271 00272 //prints all sections 00273 void print_sections(BinaryFile &binaryfile) 00274 { 00275 MSections::iterator i; 00276 int n=1; 00277 print_sections_header(); 00278 for (i=binaryfile.sections.begin();i!=binaryfile.sections.end();i++) 00279 print_sections_info(n++, i->first, i->second.data->addr, i->second.data->size, i->second.data->executable); 00280 } 00281 00282 //prints section's content 00283 void print_content(BinaryFile &binaryfile, const string sec) 00284 { 00285 if (binaryfile.sections.find(sec)!=binaryfile.sections.end()) 00286 { 00287 Section §ion=binaryfile[sec]; 00288 Address addr=section.data->addr; 00289 while (section.ValidAddress(addr)) 00290 cout<<section[addr++]; 00291 } 00292 } 00293 00294 //prints all symbols from executable 00295 void print_symbols(BinaryFile &binaryfile) 00296 { 00297 typedef MSymbols::iterator it; 00298 for (it i=symbols->symbols.begin();i!=symbols->symbols.end();i++) 00299 cout<<"0x"<<hex<<i->first<<"=\""<<i->second<<"\";"<<endl; 00300 } 00301 00302 //disassemble section 00303 void disasm_section(BinaryFile &binaryfile, const string section) 00304 { 00305 debug(":disassembling section "<<section<<endl); 00306 if (decinfo.print) 00307 { 00308 for (int i=0;i<78;i++) 00309 cout<<'#'; 00310 cout<<endl<<"section "<<section<<":"<<endl; 00311 } 00312 decinfo.section = &binaryfile[section]; 00313 decoder.Decode(); 00314 } 00315 00316 // disassemble section(s) 00317 void disassemble(BinaryFile &binaryfile, const string section, const string scanned) 00318 { 00319 str_list scan = parse_sectionname(binaryfile, scanned); // e.g. from "*exec" to (.text .init .plt) 00320 str_list s = parse_sectionname(binaryfile, section); 00321 str_list::iterator i; 00322 for (i=scan.begin();i!=scan.end();i++) 00323 binaryfile[*i]->scanaddress=true; 00324 for (i=s.begin();i!=s.end();i++) 00325 disasm_section(binaryfile, *i); 00326 } 00327 00328 const char *syntax = "\ 00329 Usage: uda binary [options]\n\ 00330 uda --help\n"; 00331 00332 const char *options = "\ 00333 Options:\n\ 00334 -b binary use this when you can't use binary as the first parameter\n\ 00335 -m mapfile use mapfile as an additional symbol table\n\ 00336 -p load symbols from binary file (if found\n\ 00337 corresponding plugin) and print them on standart output\n\ 00338 -d section(s) disassemble section(s)\n\ 00339 -f section(s) find all handled addresses and print them\n\ 00340 on standart output\n\ 00341 -s section(s) scan addresses as immediate data for theese sections\n\ 00342 -l address, -l symbol\n\ 00343 print a section containing this address/symbol\n\ 00344 -c section print a content of section\n\ 00345 --sections print the sections informations\n\ 00346 -start address, -start symbol\n\ 00347 start disassembling from this address\n\ 00348 -stop address, -stop symbol\n\ 00349 stop disassembling at this address\n\ 00350 -size number disassemble this number of bytes\n\ 00351 --noaddress print disassembling info without addresses\n\ 00352 --nohexdump print disassembling info without hexdump\n\ 00353 --nosymbolic print disassembling info without symbolic instruction\n\ 00354 --onlyname in symbolic address print only symbolic name\n\ 00355 -v verbosely print the process information\n\ 00356 --debug print all debug informations\n\ 00357 --help print uda options and plugins' informations\n\ 00358 sections could be:\n\ 00359 section section with name \"section\"\n\ 00360 .fini,.init,.text three sections (.fini, .init and .text)\n\ 00361 *data all data sections\n\ 00362 *exec all executable sections\n\ 00363 * all sections\n";