forked from GameChaos/cs2_things
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cs2_vtable_dump.idc
117 lines (100 loc) · 2.88 KB
/
cs2_vtable_dump.idc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// *****************************************************************************
// - IDA Pro script -
// Name: ida_vtables.idc
// Desc: Recreates the methods of a class from a vtable
//
// Ver: 1.0b - July 20, 2006 - By Sirmabus
// Ver: 2.0 - July 7, 2006 by BAILOPAN
// �������������������������������������������������������������������������-��-
//
// -----------------------------------------------------------------------------
#include <idc.idc>
static main()
{
auto pAddress, iIndex;
auto szFilePath, hFile;
auto skipAmt;
SetStatus(IDA_STATUS_WORK);
// User selected vtable block
pAddress = ScreenEA();
if (pAddress == BADADDR)
{
Message("** No vtable selected! Aborted **");
Warning("No vtable selected!\nSelect vtable block first.");
SetStatus(IDA_STATUS_READY);
return;
}
skipAmt = AskLong(0, "Number of vtable entries to ignore for indexing:");
auto dumpasVirtualFuncs = AskYN(0, "Format as C++ virtual method definitions.");
// Request output header file
SetStatus(IDA_STATUS_WAITING);
if ((szFilePath = AskFile(1, "*.txt", "Select output dump file:")) == 0)
{
Message("Aborted.");
SetStatus(IDA_STATUS_READY);
return;
}
// And create it..
if ((hFile = fopen(szFilePath, "wb")) != 0)
{
auto szFuncName, szFullName, BadHits;
BadHits = 0;
// Create the header
fprintf(hFile, "// Auto reconstructed from vtable block @ 0x%08X\n// from \"%s\", by ida_vtables.idc\n", pAddress, GetInputFile());
/* For linux, skip the first entry */
if (Qword(pAddress) == 0)
{
pAddress = pAddress + 16;
}
pAddress = pAddress + (skipAmt * 8);
// Loop through the vtable block
while (pAddress != BADADDR)
{
auto real_addr;
real_addr = Qword(pAddress);
szFuncName = GetFunctionName(real_addr);
Message("%x\n", real_addr);
if (szFuncName == 0 || strlen(szFuncName) == 0)
{
break;
}
szFullName = Demangle(szFuncName, INF_LONG_DN);
if (szFullName == "")
{
szFullName = szFuncName;
}
if (strstr(szFullName, "_ZN") != -1)
{
fclose(hFile);
Warning("You must toggle GCC v3.x demangled names!\n");
break;
}
if (!dumpasVirtualFuncs)
{
fprintf(hFile, "%d\t%s\n", iIndex, szFullName);
}
else
{
if (strstr(szFullName, "sub_") != -1)
{
fprintf(hFile, "virtual void Unk_%d(); // %d %s\n", iIndex, iIndex, szFullName);
}
else
{
fprintf(hFile, "virtual void %s(); // %d\n", szFullName, iIndex);
}
}
pAddress = pAddress + 8;
iIndex++;
};
fclose(hFile);
Message("Successfully wrote %d vtable entries.\n", iIndex);
}
else
{
Message("** Error opening \"%s\"! Aborted **\n", szFilePath);
Warning("Error creating \"%s\"!\n", szFilePath);
}
Message("\nDone.\n\n");
SetStatus(IDA_STATUS_READY);
}