home *** CD-ROM | disk | FTP | other *** search
- // IDB to SIG
- // IDC Script for IDA Pro v3.84
- // written by Quine (quine@blacksun.res.cmu.edu)
- // visit Quine's IDA Page at http://surf.to/quine_ida
-
-
- #include <idc.idc>
- #define MIN_SIG_LENGTH 0x8
- #define ASTR(id, idx) GetArrayElement(AR_STR,id,idx)
- #define ALONG(id, idx) GetArrayElement(AR_LONG,id,idx)
-
-
- static add_v(pos, arr) {
- auto i;
- for (i=0; i<4; i++) {
- SetArrayString(arr, pos+i, "v");
- }
- }
-
- static add_b(pos, len, ea, arr) {
- auto i;
- for (i=0; i<len; i++) {
- SetArrayLong(arr, pos+i, Byte(ea+i));
- }
- }
-
- static crc16(data_p,arr,max) {
- auto i;
- auto data;
- auto crc;
- auto length;
- auto start;
-
- if ( ASTR(arr, data_p) == "v" ) {
- return 0;
- }
- length = 0;
- crc = 0xFFFF;
- data = 0;
- start = data_p;
- while ((ASTR(arr, data_p)!="v")&&((start+length)<=max)) {
- data = ALONG(arr, data_p);
- data_p++;
- for ( i=0; i < 8; i++ ) {
- if ( ((crc ^ data) & 1) ) {
- crc = ((crc >> 1) ^ 0x8408);
- } else {
- crc=crc>>1;
- }
- data = data>>1;
- }
-
- length++;
- };
-
- crc = (~crc) & 0xffff;
- data = crc;
- crc = ((crc << 8)&0xffff) | ((data >> 8) & 0xff);
- return (crc | (length<<16));
- }
-
- static init_array(name) {
-
- auto arr;
- arr = GetArrayId(name);
- if (arr!=-1) {
- DeleteArray(arr);
- }
- arr = CreateArray(name);
- return arr;
-
- }
-
- static make_func_sig (ea, max, f) {
-
- auto i, arr, crc, item_start, ref, item_len, ref0, ref1, var0_start, var1_start, ref_str;
- auto flags, ref0_off, p_count, r_count, p_arr, r_arr, n_arr, first_bit;
-
- if (max<MIN_SIG_LENGTH) {
- return;
- }
- p_count = 0;
- r_count = 0;
- arr = init_array("__sig_data");
- p_arr = init_array("__sig_publics");
- r_arr = init_array("__sig_refs");
- n_arr = init_array("__sig_names");
- item_start = ea;
-
- // loop through each item (i.e., instruction) in the function, creating the full data array
- while (item_start-ea<=max) {
- flags = GetFlags(item_start);
-
- // are we on a public name?
- if ((flags & FF_NAME) && (GetHashLong(n_arr, item_start)==0)) {
- SetArrayString(p_arr, p_count, ":" + form("%04X", item_start-ea) + " " + Name(item_start));
- p_count++;
- SetHashLong(n_arr, item_start, 1);
- }
- item_len = NextNotTail(item_start) - item_start;
-
- // do we have a data reference?
- if ((ref0=Dfirst(item_start)) != -1) {
- // find the start of the reference
- var0_start = FindBinary(item_start-1, 1, form("%08X", ref0));
- if ((GetHashLong(n_arr, ref0)==0) && (GetFlags(ref0) & FF_NAME)) {
- SetArrayString(r_arr, r_count, "^" + form("%04X", var0_start-ea) + " " + Name(ref0));
- r_count++;
- SetHashLong(n_arr, ref0, 1);
- }
- // add any bytes prior to the reference
- add_b(item_start-ea, var0_start-item_start, item_start, arr);
- // add the reference itself
- add_v(var0_start-ea, arr);
-
- // do we have another data reference
- if((ref1=Dnext(item_start,ref0)) != -1) { // distinguishing ref0 and ref1 not necessary
- // we only get here if both operands reference mem addrs, which is very uncommon, but not impossible
- var1_start = FindBinary(item_start, 1, form("%08X", ref1));
- if ((GetHashLong(n_arr, ref1)==0) && (GetFlags(ref1) & FF_NAME)) {
- SetArrayString(r_arr, r_count, "^" + form("%04", var1_start-ea) + " " + Name(ref1));
- r_count++;
- SetHashLong(n_arr, ref1, 1);
- }
-
- // add any bytes between the 2 references
- add_b((var0_start-ea)+4, var1_start-1-ea, var0_start+4, arr);
- // add the second reference
- add_v(var1_start-ea, arr);
- // add any bytes following the second reference
- add_b((var1_start-ea)+4, (item_start+item_len)-ea, var1_start+4, arr);
- } else {
- // only one reference, so add the rest of the bytes following it
- add_b((var0_start-ea)+4, (item_start+item_len)-ea, var0_start+4, arr);
- }
-
- // no data references, so do we have a code reference
- } else if (((ref0=Rfirst0(item_start))!=-1) && (GetMnem(item_start) == "call")) {
- // follow basically the same drill as for a single data reference
- // only difference is that you have to compute the displacement to search for
- ref0_off=ref0-(item_start+item_len);
- var0_start = FindBinary(item_start-1, 1, form("%08X", ref0_off));
- if ((GetHashLong(n_arr, ref0)==0) && (GetFlags(ref0) & FF_NAME)) {
- SetArrayString(r_arr, r_count, "^" + form("%04X", var0_start-ea) + " " + Name(ref0));
- r_count++;
- SetHashLong(n_arr, ref0, 1);
- }
- add_b(item_start-ea, var0_start-item_start, item_start, arr);
- add_v(var0_start-ea, arr);
- add_b((var0_start-ea)+4, (item_start+item_len)-ea, var0_start+4, arr);
- } else {
- // we have no references at all
- add_b(item_start-ea, item_len, item_start, arr);
- }
- item_start = item_start+item_len;
- }
-
- // now write the whole line to the file (and do the crc along the way)
- if (max<32) {
- first_bit = max+1;
- } else {
- first_bit = 32;
- }
- for (i=0; i<first_bit; i++) {
- if (ASTR(arr,i) == "v") {
- writestr(f,"..");
- } else {
- writestr(f, form("%02X", ALONG(arr,i)));
- }
- }
- for (i=0; i<(32-first_bit); i++) {
- writestr(f, "..");
- }
- if (max>32) {
- crc = crc16(32, arr, max);
- } else {
- crc = 0;
- }
- writestr(f, form(" %02X %04X %04X", ((crc>>16)&0xffff), (crc&0xffff), max+1));
- for (i=0; i<p_count; i++) {
- writestr(f, " " + ASTR(p_arr,i));
- }
- for (i=0; i<r_count; i++) {
- writestr(f, " " + ASTR(r_arr,i));
- }
-
- writestr(f, " ");
-
- for (i=32+((crc>>16)&0xffff); i<=max; i++) {
- if (ASTR(arr,i) == "v") {
- writestr(f,"..");
- } else {
- writestr(f, form("%02X", ALONG(arr,i)));
- }
- }
- writestr(f,"\n");
-
- DeleteArray(arr);
- DeleteArray(n_arr);
- DeleteArray(p_arr);
- DeleteArray(r_arr);
- }
-
- static main () {
- auto f_addr, f_len, f, pat_name;
-
- pat_name = AskFile("*.pat", "Choose where to save the .pat file:");
- f=fopen(pat_name,"w");
- f_addr = MinEA();
- if (f==0) {
- return;
- }
- while ((f_addr=NextFunction(f_addr)) != BADADDR) {
- if ((GetFlags(f_addr) & FF_NAME) && !(GetFunctionFlags(f_addr) & FUNC_LIB)) {
- f_len = FindFuncEnd(f_addr) - f_addr - 1;
- make_func_sig (f_addr, f_len, f);
- }
- }
- writestr(f,"---\n");
- fclose(f);
- return;
- }