home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Quines / files / idb_to_sig.idc < prev    next >
Encoding:
Text File  |  2000-05-25  |  6.1 KB  |  222 lines

  1. // IDB to SIG
  2. // IDC Script for IDA Pro v3.84
  3. // written by Quine (quine@blacksun.res.cmu.edu)
  4. // visit Quine's IDA Page at http://surf.to/quine_ida
  5.  
  6.  
  7. #include <idc.idc>
  8. #define MIN_SIG_LENGTH 0x8
  9. #define ASTR(id, idx) GetArrayElement(AR_STR,id,idx)
  10. #define ALONG(id, idx) GetArrayElement(AR_LONG,id,idx)
  11.  
  12.  
  13. static add_v(pos, arr) {
  14.     auto i;
  15.     for (i=0; i<4; i++) {
  16.         SetArrayString(arr, pos+i, "v");
  17.     }
  18. }
  19.  
  20. static add_b(pos, len, ea, arr) {
  21.     auto i;
  22.     for (i=0; i<len; i++) {
  23.         SetArrayLong(arr, pos+i, Byte(ea+i));
  24.     }
  25. }
  26.  
  27. static crc16(data_p,arr,max) {
  28.     auto i;
  29.     auto data;
  30.     auto crc;
  31.     auto length;
  32.     auto start;
  33.  
  34.     if ( ASTR(arr, data_p) == "v" ) {
  35.           return 0;
  36.     }
  37.     length = 0;
  38.     crc = 0xFFFF;
  39.     data = 0;
  40.     start = data_p;
  41.     while ((ASTR(arr, data_p)!="v")&&((start+length)<=max)) {
  42.         data = ALONG(arr, data_p);
  43.         data_p++;
  44.         for ( i=0; i < 8; i++ ) {
  45.             if ( ((crc ^ data) & 1) ) {
  46.                 crc = ((crc >> 1) ^ 0x8408);
  47.             } else {
  48.                 crc=crc>>1;
  49.             }
  50.             data = data>>1;
  51.         }
  52.  
  53.         length++;
  54.     };
  55.  
  56.     crc = (~crc) & 0xffff;
  57.     data = crc;
  58.     crc = ((crc << 8)&0xffff) | ((data >> 8) & 0xff);
  59.     return (crc | (length<<16));
  60. }
  61.  
  62. static init_array(name) {
  63.  
  64.     auto arr;
  65.     arr = GetArrayId(name);
  66.     if (arr!=-1) {
  67.         DeleteArray(arr);
  68.     }
  69.     arr = CreateArray(name);
  70.     return arr;
  71.  
  72. }
  73.  
  74. static make_func_sig (ea, max, f) {
  75.     
  76.     auto i, arr, crc, item_start, ref, item_len, ref0, ref1, var0_start, var1_start, ref_str;
  77.     auto flags, ref0_off, p_count, r_count, p_arr, r_arr, n_arr, first_bit;
  78.     
  79.     if (max<MIN_SIG_LENGTH) {
  80.         return;
  81.     }
  82.     p_count = 0;
  83.     r_count = 0;
  84.     arr = init_array("__sig_data");
  85.     p_arr = init_array("__sig_publics");
  86.     r_arr = init_array("__sig_refs");
  87.     n_arr = init_array("__sig_names");
  88.     item_start = ea;
  89.     
  90.     // loop through each item (i.e., instruction) in the function, creating the full data array
  91.     while (item_start-ea<=max) {
  92.         flags = GetFlags(item_start);
  93.         
  94.         // are we on a public name?
  95.         if ((flags & FF_NAME) && (GetHashLong(n_arr, item_start)==0)) {
  96.             SetArrayString(p_arr, p_count, ":" + form("%04X", item_start-ea) + " " + Name(item_start));
  97.             p_count++;
  98.             SetHashLong(n_arr, item_start, 1);
  99.         }
  100.         item_len = NextNotTail(item_start) - item_start;
  101.         
  102.         // do we have a data reference?
  103.         if ((ref0=Dfirst(item_start)) != -1) {
  104.             // find the start of the reference
  105.             var0_start = FindBinary(item_start-1, 1, form("%08X", ref0));
  106.             if ((GetHashLong(n_arr, ref0)==0) && (GetFlags(ref0) & FF_NAME)) {
  107.                 SetArrayString(r_arr, r_count, "^" + form("%04X", var0_start-ea) + " " + Name(ref0));
  108.                 r_count++;
  109.                 SetHashLong(n_arr, ref0, 1);
  110.             }
  111.             // add any bytes prior to the reference
  112.             add_b(item_start-ea, var0_start-item_start, item_start, arr);
  113.             // add the reference itself
  114.             add_v(var0_start-ea, arr);
  115.             
  116.             // do we have another data reference
  117.             if((ref1=Dnext(item_start,ref0)) != -1) { // distinguishing ref0 and ref1 not necessary
  118.                 // we only get here if both operands reference mem addrs, which is very uncommon, but not impossible
  119.                 var1_start = FindBinary(item_start, 1, form("%08X", ref1));
  120.                 if ((GetHashLong(n_arr, ref1)==0) && (GetFlags(ref1) & FF_NAME)) {
  121.                     SetArrayString(r_arr, r_count, "^" + form("%04", var1_start-ea) + " " + Name(ref1));
  122.                     r_count++;
  123.                     SetHashLong(n_arr, ref1, 1);
  124.                 }
  125.                 
  126.                 // add any bytes between the 2 references
  127.                 add_b((var0_start-ea)+4, var1_start-1-ea, var0_start+4, arr);
  128.                 // add the second reference
  129.                 add_v(var1_start-ea, arr);
  130.                 // add any bytes following the second reference
  131.                 add_b((var1_start-ea)+4, (item_start+item_len)-ea, var1_start+4, arr);
  132.             } else {
  133.                 // only one reference, so add the rest of the bytes following it
  134.                 add_b((var0_start-ea)+4, (item_start+item_len)-ea, var0_start+4, arr);
  135.             }
  136.         
  137.         // no data references, so do we have a code reference
  138.         } else if (((ref0=Rfirst0(item_start))!=-1) && (GetMnem(item_start) == "call")) {
  139.             // follow basically the same drill as for a single data reference
  140.             // only difference is that you have to compute the displacement to search for
  141.             ref0_off=ref0-(item_start+item_len);
  142.             var0_start = FindBinary(item_start-1, 1, form("%08X", ref0_off));
  143.             if ((GetHashLong(n_arr, ref0)==0) && (GetFlags(ref0) & FF_NAME)) {
  144.                 SetArrayString(r_arr, r_count, "^" + form("%04X", var0_start-ea) + " " + Name(ref0));
  145.                 r_count++;
  146.                 SetHashLong(n_arr, ref0, 1);
  147.             }
  148.             add_b(item_start-ea, var0_start-item_start, item_start, arr);
  149.             add_v(var0_start-ea, arr);
  150.             add_b((var0_start-ea)+4, (item_start+item_len)-ea, var0_start+4, arr);
  151.         } else {
  152.             // we have no references at all
  153.             add_b(item_start-ea, item_len, item_start, arr);
  154.         }
  155.         item_start = item_start+item_len;
  156.     }
  157.     
  158.     // now write the whole line to the file (and do the crc along the way)
  159.     if (max<32) {
  160.         first_bit = max+1;
  161.     } else {
  162.         first_bit = 32;
  163.     }
  164.     for (i=0; i<first_bit; i++) {
  165.         if (ASTR(arr,i) == "v") {
  166.             writestr(f,"..");
  167.         } else {
  168.             writestr(f, form("%02X", ALONG(arr,i)));
  169.         }
  170.     }
  171.     for (i=0; i<(32-first_bit); i++) {
  172.         writestr(f, "..");
  173.     }
  174.     if (max>32) {
  175.         crc = crc16(32, arr, max);
  176.     } else {
  177.         crc = 0;
  178.     }
  179.     writestr(f, form(" %02X %04X %04X", ((crc>>16)&0xffff), (crc&0xffff), max+1));
  180.     for (i=0; i<p_count; i++) {
  181.         writestr(f, " " + ASTR(p_arr,i));
  182.     }
  183.     for (i=0; i<r_count; i++) {
  184.         writestr(f, " " + ASTR(r_arr,i));
  185.     }
  186.     
  187.     writestr(f, " ");
  188.  
  189.     for (i=32+((crc>>16)&0xffff); i<=max; i++) {
  190.         if (ASTR(arr,i) == "v") {
  191.             writestr(f,"..");
  192.         } else {
  193.             writestr(f, form("%02X", ALONG(arr,i)));
  194.         }
  195.     }
  196.     writestr(f,"\n");
  197.     
  198.     DeleteArray(arr);
  199.     DeleteArray(n_arr);
  200.     DeleteArray(p_arr);
  201.     DeleteArray(r_arr);
  202. }
  203.  
  204. static main () {
  205.     auto f_addr, f_len, f, pat_name;
  206.     
  207.     pat_name = AskFile("*.pat", "Choose where to save the .pat file:");
  208.     f=fopen(pat_name,"w");
  209.     f_addr = MinEA();
  210.     if (f==0) {
  211.         return;
  212.     }
  213.     while ((f_addr=NextFunction(f_addr)) != BADADDR) {
  214.         if ((GetFlags(f_addr) & FF_NAME) && !(GetFunctionFlags(f_addr) & FUNC_LIB)) {
  215.             f_len = FindFuncEnd(f_addr) - f_addr - 1;
  216.             make_func_sig (f_addr, f_len, f);
  217.         }
  218.     }
  219.     writestr(f,"---\n");
  220.     fclose(f);
  221.     return;
  222. }