/
renameACMDScripts.py
125 lines (111 loc) · 4.4 KB
/
renameACMDScripts.py
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
118
119
120
121
122
123
124
125
import idc
import idaapi
import idautils
import re
def decompile_func(ea):
if not idaapi.init_hexrays_plugin():
return False
f = idaapi.get_func(ea)
if f is None:
return False
cfunc = idaapi.decompile(f);
if cfunc is None:
# Failed to decompile
return False
lines = []
sv = cfunc.get_pseudocode();
for sline in sv:
line = idaapi.tag_remove(sline.line);
lines.append(line)
return "\n".join(lines)
def getACMDName(scriptName):
# game, effect, sound, expression
if scriptName.startswith('me_'):
return 'ga'+scriptName
elif scriptName.startswith('fect_'):
return 'ef'+scriptName
elif scriptName.startswith('und_'):
return 'so'+scriptName
elif scriptName.startswith('pression_'):
return 'ex'+scriptName
def animcmdHashTable(filetext):
lines = filetext.split("\n")
animation = ""
functionName = ""
hashTable = {}
variableValues = {}
inSetHashCall = False
setHashParam = 0
for line in lines:
if "lib::L2CAgent::sv_set_function_hash" in line:
if ");" in line:
functionMatch = re.search('hash\(.*\, (\\w+)\, \~?(v\\d+)', line)
if functionMatch:
functionName = functionMatch.group(1)
varGet = functionMatch.group(2)
if varGet in variableValues:
hashTable[functionName] = getACMDName(variableValues[varGet])
else:
hashTable[functionName] = getACMDName(animation)
animation = ""
else:
inSetHashCall = True
setHashParam = 1
continue
charMatch = charMatch = re.search('(v\\d*) = phx::detail::CRC32Table::table\_.*(v\\d*).*(?:v\\d*).*\^\ (0x..)', line)
if not charMatch:
charMatch = re.search('(v\\d*) = phx::detail::CRC32Table::table\_.*(v\\d*).*\^\ (0x..)', line)
charMatchCall = re.search('phx::detail::CRC32Table::table\_.*(v\\d*).*(?:v\\d*).*\^\ (0x..)', line)
if not charMatchCall:
charMatchCall = re.search('phx::detail::CRC32Table::table\_.*(v\\d*)\ \^\ (0x..)', line)
setVarMatch = re.search('(v\\d*) = (v\\d*).*;', line)
if not setVarMatch:
setVarMatch = re.search('(v\\d*) = .*(v\\d*).*;', line)
if charMatch:
varSet = charMatch.group(1)
varGet = charMatch.group(2)
charHex = int(charMatch.group(3), 16)
if charHex <= 122:
if varGet in variableValues:
variableValues[varSet] = variableValues[varGet] + chr(charHex)
animation = variableValues[varSet]
else:
variableValues[varSet] = chr(charHex)
animation = variableValues[varSet]
elif charMatchCall:
varGet = charMatchCall.group(1)
charHex = int(charMatchCall.group(2), 16)
if charHex <= 122:
animation = variableValues[varGet] + chr(charHex)
elif setVarMatch:
varSet = setVarMatch.group(1)
varGet = setVarMatch.group(2)
try:
variableValues[varSet] = variableValues[varGet]
except:
continue
animation = variableValues[varSet]
if inSetHashCall:
if setHashParam == 1:
setHashParam += 1
elif setHashParam == 2:
functionMatch = re.search('(\\w+)\,', line)
if functionMatch:
functionName = functionMatch.group(1)
setHashParam += 1
elif setHashParam == 3:
hashTable[functionName] = getACMDName(animation)
inSetHashCall = False
setHashParam = 0
animation = ""
return hashTable
hashTable = animcmdHashTable(decompile_func(here()))
print "begin renaming"
for segea in Segments():
for funcea in Functions(segea, SegEnd(segea)):
functionName = GetFunctionName(funcea)
if functionName in hashTable:
if hashTable[functionName] != "":
print hashTable[functionName]
idc.MakeName(funcea, hashTable[functionName])
print "end renaming"