/* this script is designed to set the SCHEME variables with the symbol name associated with them (via C_h_intern and C_string calls) */ #define UNLOADED_FILE 1 #include static main(){ auto r_eax, r_ecx, r_edx; auto startAddr, endAddr; auto op1, op2; auto index, i, j; auto lastCall; auto symString; auto cmtString; auto varAddy; auto letter; auto nameString, newNameString; auto nameIndexer; auto FoundStartMarker, FoundEndMarker; auto hitCounter, successfulHits; /* set up the initial conditions */ FoundEndMarker = 0; /* set when call _C_register_lf is found */ FoundStartMarker = 0; /* set when call _C_initialize_lf is found */ lastCall = 0; /* 0-non sym based call, 1-intern, 2-string */ hitCounter = 0; successfulHits = 0; /* figure out start and end addresses for C_toplevel function */ startAddr = ChooseFunction("Select C_toplevel function to manipulate"); if (startAddr == -1) { Message("Unable to find start of C_toplevel function"); return; } endAddr = FindFuncEnd(startAddr); if (endAddr == BADADDR) { Message("Unable to find end of C_toplevel funciton"); return; } i = startAddr; Message("StartAddr = %x, EndAddr = %x\n", startAddr, endAddr); while(i< endAddr && i != BADADDR) { op1 = GetOpnd(i, 0); op2 = GetOpnd(i, 1); /* check for call markers */ if (strstr(GetDisasm(i), "call") >= 0) { if (op1 == "_C_initialize_lf") FoundStartMarker = 1; else if (op1 == "_C_register_lf") FoundEndMarker = 1; else if (op1 == "_C_h_intern") lastCall = 1; else if (op1 == "_C_string") lastCall = 2; else lastCall = 0; } /* just focus on important section */ if (FoundStartMarker == 1 && FoundEndMarker != 1) { if (op1 == "eax") r_eax = op2; /* this is really unneeded but left for completeness */ if (op1 == "edx") r_edx = op2; if (op1 == "ecx") { OpHex(i, 1); /* disable the name of the value passed to ecx, make it a number */ r_ecx = GetOpnd(i, 1); /* get the number passed to ecx */ OpOff(i, 1, 0); /* turn the variable back into a name */ } if (op2 == "eax" && (op1 != "edx" && op1 != "eax" && op1 != "ecx")) { if (lastCall == 1 || lastCall == 2) { if (lastCall == 1) nameString = "symi_"; else nameString = "syms_"; hitCounter++; symString = GetString(xtol(r_ecx), -1, ASCSTR_C); if (symString != 0) { OpHex(i, 0); index = strstr(op1, "dword_"); if (index > 0) varAddy = LocByName(substr(op1, index, -1)); else varAddy = xtol(GetOpnd(i, 0)); OpOff(i, 0, 0); MakeRptCmt(varAddy, symString); /* convert the symbol string into a usable variable name */ for (j = 0; j < strlen(symString); j++) { letter = substr(symString, j, j+1); if ((letter >= "0" && letter <= "9") || (letter >= "a" && letter <= "z") || (letter >= "A" && letter <="Z")) nameString = nameString + letter; else nameString = nameString + '_'; if (j > 50) break; /* don't make names longer than 55 characters */ } /* before we set the name, make sure its available */ if (LocByName(nameString) != BADADDR) /* if this returns an address, the variable name is in use */ { if (LocByName(nameString) != varAddy) /* if we are talking about something we already have set, ignore*/ { /* try appending numbers to the end of the string until we find an open name */ newNameString = nameString; nameIndexer = 0; while (LocByName(newNameString) != BADADDR) /* yes, in theory you could infinitely loop here */ { /* start appending a number to the end of the original name until a free name is found */ newNameString = nameString + "__" + ltoa(nameIndexer, 10); nameIndexer++; } nameString = newNameString; } } /* set the location's name */ MakeName(varAddy, nameString); successfulHits++; } /*if (symString != 0)..*/ else Message("%x : invalid symbol string found.. manually fix this\n", i); } /*if (lastCall == 1 || lastCall == 2)..*/ } /*if (op2 == "eax" && (op1 != "edx" && op1 != "eax" && op1 != "ecx"))..*/ } /*if (FoundStartMarker == 1 && FoundEndMarker != 1) ...*/ i = FindCode(i, SEARCH_DOWN); /* get the next instruction location .. and repeat */ } Message("Tagged %d of %d symbols\n", successfulHits, hitCounter); }