dvander@1055: dvander@1055: // ***************************************************************************** dvander@1055: // - IDA Pro script - dvander@1055: // Name: ida_vtables.idc dvander@1055: // Desc: Recreates the methods of a class from a vtable dvander@1055: // dvander@1055: // Ver: 1.0b - July 20, 2006 - By Sirmabus dvander@1055: // Ver: 2.0 - July 7, 2006 by BAILOPAN dvander@1055: // 컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴�-컴- dvander@1055: // dvander@1055: // ----------------------------------------------------------------------------- dvander@1055: dvander@1055: #include dvander@1055: dvander@1055: static main() dvander@1055: { dvander@1055: auto pAddress, iIndex; dvander@1055: auto szFilePath, hFile; dvander@1055: auto skipAmt; dvander@1055: dvander@1055: SetStatus(IDA_STATUS_WORK); dvander@1055: dvander@1055: // User selected vtable block dvander@1055: pAddress = ScreenEA(); dvander@1055: dvander@1055: if (pAddress == BADADDR) dvander@1055: { dvander@1055: Message("** No vtable selected! Aborted **"); dvander@1055: Warning("No vtable selected!\nSelect vtable block first."); dvander@1055: SetStatus(IDA_STATUS_READY); dvander@1055: return; dvander@1055: } dvander@1055: dvander@1055: skipAmt = AskLong(1, "Number of vtable entries to ignore for indexing:"); dvander@1055: dvander@1055: // Request output header file dvander@1055: SetStatus(IDA_STATUS_WAITING); dvander@1055: if ((szFilePath = AskFile(1, "*.txt", "Select output dump file:")) == 0) dvander@1055: { dvander@1055: Message("Aborted."); dvander@1055: SetStatus(IDA_STATUS_READY); dvander@1055: return; dvander@1055: } dvander@1055: dvander@1055: // And create it.. dvander@1055: if ((hFile = fopen(szFilePath, "wb")) != 0) dvander@1055: { dvander@1055: auto szFuncName, szFullName, BadHits; dvander@1055: dvander@1055: BadHits = 0; dvander@1055: dvander@1055: // Create the header dvander@1055: fprintf(hFile, "// Auto reconstructed from vtable block @ 0x%08X\n// from \"%s\", by ida_vtables.idc\n", pAddress, GetInputFile()); dvander@1055: dvander@1055: /* For linux, skip the first entry */ dvander@1055: if (Dword(pAddress) == 0) dvander@1055: { dvander@1055: pAddress = pAddress + 8; dvander@1055: } dvander@1055: dvander@1055: pAddress = pAddress + (skipAmt * 4); dvander@1055: dvander@1055: // Loop through the vtable block dvander@1055: while (pAddress != BADADDR) dvander@1055: { dvander@1055: auto real_addr; dvander@1055: real_addr = Dword(pAddress); dvander@1055: pred@2121: szFuncName = Name(real_addr); dvander@1055: if (strlen(szFuncName) == 0) dvander@1055: { dvander@1055: break; dvander@1055: } dvander@1055: szFullName = Demangle(szFuncName, INF_LONG_DN); dvander@1055: if (szFullName == "") dvander@1055: { dvander@1055: szFullName = szFuncName; dvander@1055: } dvander@1055: if (strstr(szFullName, "_ZN") != -1) dvander@1055: { dvander@1055: fclose(hFile); dvander@1055: Warning("You must toggle GCC v3.x demangled names!\n"); dvander@1055: break; dvander@1055: } dvander@1055: fprintf(hFile, "%d\t%s\n", iIndex, szFullName); dvander@1055: dvander@1055: pAddress = pAddress + 4; dvander@1055: iIndex++; dvander@1055: }; dvander@1055: dvander@1055: fclose(hFile); dvander@1055: Message("Successfully wrote %d vtable entries.\n", iIndex); dvander@1055: } dvander@1055: else dvander@1055: { dvander@1055: Message("** Error opening \"%s\"! Aborted **\n", szFilePath); dvander@1055: Warning("Error creating \"%s\"!\n", szFilePath); dvander@1055: } dvander@1055: dvander@1055: Message("\nDone.\n\n"); dvander@1055: SetStatus(IDA_STATUS_READY); dvander@1055: }