|
skamonkey@3513
|
1 |
#include <stdio.h> |
|
skamonkey@3513
|
2 |
#include <unistd.h> |
|
skamonkey@3513
|
3 |
#include <dlfcn.h> |
|
skamonkey@3513
|
4 |
#include <fcntl.h> |
|
skamonkey@3513
|
5 |
#include <math.h> |
|
skamonkey@3513
|
6 |
#include "gdc.h" |
|
skamonkey@3513
|
7 |
#include "GameConfigs.h" |
|
skamonkey@3513
|
8 |
#include "MemoryUtils.h" |
|
skamonkey@3513
|
9 |
|
|
skamonkey@3513
|
10 |
MemoryUtils mu; |
|
skamonkey@3513
|
11 |
|
|
skamonkey@3513
|
12 |
char *game = NULL; |
|
skamonkey@3513
|
13 |
char *engine = NULL; |
|
skamonkey@3513
|
14 |
char *game_binary = NULL; |
|
skamonkey@3513
|
15 |
char *engine_binary = NULL; |
|
skamonkey@3513
|
16 |
char *wgame_binary = NULL; |
|
skamonkey@3513
|
17 |
char *wengine_binary = NULL; |
|
skamonkey@3513
|
18 |
|
|
skamonkey@3513
|
19 |
int main(int argc, char **argv) |
|
skamonkey@3513
|
20 |
{ |
|
skamonkey@3513
|
21 |
char *gamedata = NULL; |
|
skamonkey@3513
|
22 |
bool debug = false; |
|
skamonkey@3513
|
23 |
|
|
skamonkey@3513
|
24 |
opterr = 0; |
|
skamonkey@3513
|
25 |
int opt; |
|
skamonkey@3513
|
26 |
while ((opt = getopt(argc, argv, "b:de:f:g:x:w:y:")) != -1) |
|
skamonkey@3513
|
27 |
switch (opt) |
|
skamonkey@3513
|
28 |
{ |
|
skamonkey@3513
|
29 |
case 'd': |
|
skamonkey@3513
|
30 |
debug = true; |
|
skamonkey@3513
|
31 |
break; |
|
skamonkey@3513
|
32 |
case 'g': |
|
skamonkey@3513
|
33 |
game = optarg; |
|
skamonkey@3513
|
34 |
break; |
|
skamonkey@3513
|
35 |
|
|
skamonkey@3513
|
36 |
case 'e': |
|
skamonkey@3513
|
37 |
engine = optarg; |
|
skamonkey@3513
|
38 |
break; |
|
skamonkey@3513
|
39 |
|
|
skamonkey@3513
|
40 |
case 'f': |
|
skamonkey@3513
|
41 |
gamedata = optarg; |
|
skamonkey@3513
|
42 |
break; |
|
skamonkey@3513
|
43 |
|
|
skamonkey@3513
|
44 |
case 'b': |
|
skamonkey@3513
|
45 |
game_binary = optarg; |
|
skamonkey@3513
|
46 |
break; |
|
skamonkey@3513
|
47 |
|
|
skamonkey@3513
|
48 |
case 'x': |
|
skamonkey@3513
|
49 |
engine_binary = optarg; |
|
skamonkey@3513
|
50 |
break; |
|
skamonkey@3513
|
51 |
|
|
skamonkey@3513
|
52 |
case 'w': |
|
skamonkey@3513
|
53 |
wgame_binary = optarg; |
|
skamonkey@3513
|
54 |
break; |
|
skamonkey@3513
|
55 |
|
|
skamonkey@3513
|
56 |
case 'y': |
|
skamonkey@3513
|
57 |
wengine_binary = optarg; |
|
skamonkey@3513
|
58 |
break; |
|
skamonkey@3513
|
59 |
|
|
skamonkey@3513
|
60 |
case '?': |
|
skamonkey@3513
|
61 |
printf("Usage: ./gdc -g <game> -e <engine name> -f <gamedata file> -b <game binary> -x <engine binary> -w <win game binary> -y <win engine binary>\n"); |
|
skamonkey@3513
|
62 |
return 0; |
|
skamonkey@3513
|
63 |
|
|
skamonkey@3513
|
64 |
default: |
|
skamonkey@3513
|
65 |
printf("WHAT\n"); |
|
skamonkey@3513
|
66 |
return 0; |
|
skamonkey@3513
|
67 |
} |
|
skamonkey@3513
|
68 |
|
|
skamonkey@3513
|
69 |
if (!game || !engine || !gamedata || !game_binary || !engine_binary || !wgame_binary || !wengine_binary) |
|
skamonkey@3513
|
70 |
{ |
|
skamonkey@3513
|
71 |
printf("Usage: ./gdc -g <game> -e <engine name> -f <gamedata file> -b <game binary> -x <engine binary> -w <win game binary> -y <win engine binary>\n"); |
|
skamonkey@3513
|
72 |
return 0; |
|
skamonkey@3513
|
73 |
} |
|
skamonkey@3513
|
74 |
|
|
skamonkey@3513
|
75 |
printf("Game: %s\n", game); |
|
skamonkey@3513
|
76 |
if (debug) |
|
skamonkey@3513
|
77 |
{ |
|
skamonkey@3513
|
78 |
printf("Engine: %s\nGame binary: %s\nEngine binary: %s\nWin game binary: %s\nWin engine binary: %s\n", |
|
skamonkey@3513
|
79 |
engine, game_binary, engine_binary, wgame_binary, wengine_binary |
|
skamonkey@3513
|
80 |
); |
|
skamonkey@3513
|
81 |
} |
|
skamonkey@3513
|
82 |
printf("Gamedata: %s\n\n", gamedata); |
|
skamonkey@3513
|
83 |
|
|
skamonkey@3513
|
84 |
void *ghandle; |
|
skamonkey@3513
|
85 |
ghandle = dlopen(game_binary, RTLD_LAZY); |
|
skamonkey@3513
|
86 |
if (!ghandle) |
|
skamonkey@3513
|
87 |
{ |
|
skamonkey@3513
|
88 |
printf("Couldn't open %s (%s)\n", game_binary, dlerror()); |
|
skamonkey@3513
|
89 |
return 0; |
|
skamonkey@3513
|
90 |
} |
|
skamonkey@3513
|
91 |
void *ehandle; |
|
skamonkey@3513
|
92 |
ehandle = dlopen(engine_binary, RTLD_LAZY); |
|
skamonkey@3513
|
93 |
if (!ehandle) |
|
skamonkey@3513
|
94 |
{ |
|
skamonkey@3513
|
95 |
printf("Couldn't open %s (%s)\n", engine_binary, dlerror()); |
|
skamonkey@3513
|
96 |
return 0; |
|
skamonkey@3513
|
97 |
} |
|
skamonkey@3513
|
98 |
|
|
skamonkey@3513
|
99 |
int wgfile = open(wgame_binary, O_RDONLY); |
|
skamonkey@3513
|
100 |
if (wgfile == -1) |
|
skamonkey@3513
|
101 |
{ |
|
skamonkey@3513
|
102 |
printf("Couldn't open %s\n", wgame_binary); |
|
skamonkey@3513
|
103 |
return 0; |
|
skamonkey@3513
|
104 |
} |
|
skamonkey@3513
|
105 |
|
|
skamonkey@3513
|
106 |
int wefile = open(wengine_binary, O_RDONLY); |
|
skamonkey@3513
|
107 |
if (wefile == -1) |
|
skamonkey@3513
|
108 |
{ |
|
skamonkey@3513
|
109 |
printf("Couldn't open %s\n", wengine_binary); |
|
skamonkey@3513
|
110 |
return 0; |
|
skamonkey@3513
|
111 |
} |
|
skamonkey@3513
|
112 |
|
|
skamonkey@3513
|
113 |
CGameConfig gc; |
|
skamonkey@3513
|
114 |
char err[512]; |
|
skamonkey@3513
|
115 |
if (!gc.EnterFile(gamedata, err, sizeof(err))) |
|
skamonkey@3513
|
116 |
{ |
|
skamonkey@3513
|
117 |
printf("%s: %s\n", gamedata, err); |
|
skamonkey@3513
|
118 |
return 0; |
|
skamonkey@3513
|
119 |
} |
|
skamonkey@3513
|
120 |
|
|
skamonkey@3513
|
121 |
CGameConfig symbols; |
|
skamonkey@3513
|
122 |
if (!symbols.EnterFile("symbols.txt", err, sizeof(err))) |
|
skamonkey@3513
|
123 |
{ |
|
skamonkey@3513
|
124 |
printf("symbols.txt: %s\n", err); |
|
skamonkey@3513
|
125 |
return 0; |
|
skamonkey@3513
|
126 |
} |
|
skamonkey@3513
|
127 |
|
|
skamonkey@3513
|
128 |
const char *vtsym = symbols.GetKeyValue("vtsym"); |
|
skamonkey@3513
|
129 |
if (!vtsym) |
|
skamonkey@3513
|
130 |
{ |
|
skamonkey@3513
|
131 |
printf("Couldn't find vtsym\n"); |
|
skamonkey@3513
|
132 |
return 0; |
|
skamonkey@3513
|
133 |
} |
|
skamonkey@3513
|
134 |
|
|
skamonkey@3513
|
135 |
void **vt = (void**) mu.ResolveSymbol(ghandle, vtsym); |
|
skamonkey@3513
|
136 |
if (!vt) |
|
skamonkey@3513
|
137 |
{ |
|
skamonkey@3513
|
138 |
printf("Couldn't find vtable %s\n", vtsym); |
|
skamonkey@3513
|
139 |
dlclose(ghandle); |
|
skamonkey@3513
|
140 |
dlclose(ehandle); |
|
skamonkey@3513
|
141 |
close(wgfile); |
|
skamonkey@3513
|
142 |
close(wefile); |
|
skamonkey@3513
|
143 |
|
|
skamonkey@3513
|
144 |
return 0; |
|
skamonkey@3513
|
145 |
} |
|
skamonkey@3513
|
146 |
|
|
skamonkey@3513
|
147 |
|
|
skamonkey@3513
|
148 |
for (list<Offset>::iterator it = gc.m_Offsets.begin(); it != gc.m_Offsets.end(); it++) |
|
skamonkey@3513
|
149 |
{ |
|
skamonkey@3513
|
150 |
if (debug) |
|
skamonkey@3513
|
151 |
{ |
|
skamonkey@3513
|
152 |
printf("DEBUG %s - l: %d w: %d\n", it->name, it->lin, it->win); |
|
skamonkey@3513
|
153 |
} |
|
skamonkey@3513
|
154 |
|
|
skamonkey@3513
|
155 |
const char *symbol = symbols.GetKeyValue(it->name); |
|
skamonkey@3513
|
156 |
if (symbol) |
|
skamonkey@3513
|
157 |
{ |
|
skamonkey@3513
|
158 |
int newOffset; |
|
skamonkey@3513
|
159 |
char symvt[128]; |
|
skamonkey@3513
|
160 |
strcpy(symvt, it->name); |
|
skamonkey@3513
|
161 |
strcat(symvt, "_vt"); |
|
skamonkey@3513
|
162 |
const char *newvtsym = symbols.GetKeyValue(symvt); |
|
skamonkey@3513
|
163 |
if (newvtsym && newvtsym[0]) |
|
skamonkey@3513
|
164 |
{ |
|
skamonkey@3513
|
165 |
void **newvt = (void**) mu.ResolveSymbol(ghandle, newvtsym); |
|
skamonkey@3513
|
166 |
if (!newvt) |
|
skamonkey@3513
|
167 |
{ |
|
skamonkey@3513
|
168 |
printf("O: %-22s - can't find, skipping\n", symvt); |
|
skamonkey@3513
|
169 |
continue; |
|
skamonkey@3513
|
170 |
} |
|
skamonkey@3513
|
171 |
|
|
skamonkey@3513
|
172 |
newOffset = findVFunc(ghandle, newvt, symbol); |
|
skamonkey@3513
|
173 |
} |
|
skamonkey@3513
|
174 |
else |
|
skamonkey@3513
|
175 |
{ |
|
skamonkey@3513
|
176 |
newOffset = findVFunc(ghandle, vt, symbol); |
|
skamonkey@3513
|
177 |
} |
|
skamonkey@3513
|
178 |
|
|
skamonkey@3513
|
179 |
if (newOffset == it->lin) |
|
skamonkey@3513
|
180 |
{ |
|
skamonkey@3513
|
181 |
printf("O: %-22s - GOOD. current [ w: %3d, l: %3d ].\n", it->name, it->win, it->lin); |
|
skamonkey@3513
|
182 |
} |
|
skamonkey@3513
|
183 |
else |
|
skamonkey@3513
|
184 |
{ |
|
skamonkey@3513
|
185 |
printf("O: %-22s - CHANGED. old [ w: %3d, l: %3d ]. new [ w: %3d, l: %3d ].\n", |
|
skamonkey@3513
|
186 |
it->name, |
|
skamonkey@3513
|
187 |
it->win, it->lin, |
|
skamonkey@3513
|
188 |
newOffset - (it->lin - it->win), newOffset |
|
skamonkey@3513
|
189 |
); |
|
skamonkey@3513
|
190 |
} |
|
skamonkey@3513
|
191 |
} |
|
skamonkey@3513
|
192 |
else // !symbol |
|
skamonkey@3513
|
193 |
{ |
|
skamonkey@3513
|
194 |
printf("O: %-22s - no Linux symbol, skipping\n", it->name); |
|
skamonkey@3513
|
195 |
} |
|
skamonkey@3513
|
196 |
} |
|
skamonkey@3513
|
197 |
|
|
skamonkey@3513
|
198 |
printf("\nWindows offsets are (semi-)wild guesses!\n\n"); |
|
skamonkey@3513
|
199 |
|
|
skamonkey@3513
|
200 |
for (list<Sig>::iterator it = gc.m_Sigs.begin(); it != gc.m_Sigs.end(); it++) |
|
skamonkey@3513
|
201 |
{ |
|
skamonkey@3513
|
202 |
if (debug) |
|
skamonkey@3513
|
203 |
{ |
|
skamonkey@3513
|
204 |
printf("DEBUG %s - %s - l: %s\n", it->name, it->lib == Server ? "server" : "engine", it->lin); |
|
skamonkey@3513
|
205 |
} |
|
skamonkey@3513
|
206 |
|
|
skamonkey@3513
|
207 |
const char *linSymbol = it->lin; |
|
skamonkey@3513
|
208 |
const char *winSymbol = it->win; |
|
skamonkey@3513
|
209 |
bool hasLinux = (linSymbol && linSymbol[0]); |
|
skamonkey@3513
|
210 |
bool hasWindows = (winSymbol && winSymbol[0]); |
|
skamonkey@3513
|
211 |
if (!hasLinux && !hasWindows) |
|
skamonkey@3513
|
212 |
{ |
|
skamonkey@3513
|
213 |
printf("S: %-22s - hasn't linux nor windows data, skipping\n", it->name); |
|
skamonkey@3513
|
214 |
continue; |
|
skamonkey@3513
|
215 |
} |
|
skamonkey@3513
|
216 |
|
|
skamonkey@3513
|
217 |
int winFile; |
|
skamonkey@3513
|
218 |
void *linHandle; |
|
skamonkey@3513
|
219 |
if (it->lib == Server) |
|
skamonkey@3513
|
220 |
{ |
|
skamonkey@3513
|
221 |
winFile = wgfile; |
|
skamonkey@3513
|
222 |
linHandle = ghandle; |
|
skamonkey@3513
|
223 |
} |
|
skamonkey@3513
|
224 |
else if (it->lib == Engine) |
|
skamonkey@3513
|
225 |
{ |
|
skamonkey@3513
|
226 |
winFile = wefile; |
|
skamonkey@3513
|
227 |
linHandle = ehandle; |
|
skamonkey@3513
|
228 |
} |
|
skamonkey@3513
|
229 |
else |
|
skamonkey@3513
|
230 |
{ |
|
skamonkey@3513
|
231 |
printf("S: %-22s - isn't from server nor engine, skipping\n", it->name); |
|
skamonkey@3513
|
232 |
continue; |
|
skamonkey@3513
|
233 |
} |
|
skamonkey@3513
|
234 |
|
|
skamonkey@3513
|
235 |
bool foundLinux = (!hasLinux || checkSigStringL(linHandle, linSymbol)); |
|
skamonkey@3513
|
236 |
bool foundWindows = (!hasWindows || checkSigStringW(winFile, winSymbol)); |
|
skamonkey@3513
|
237 |
|
|
skamonkey@3513
|
238 |
// Prepare for ternery ABUSE |
|
skamonkey@3513
|
239 |
|
|
skamonkey@3513
|
240 |
if (foundLinux && foundWindows) |
|
skamonkey@3513
|
241 |
{ |
|
skamonkey@3513
|
242 |
// too much clutter to print current data if it matches anyway, unlike with offsets |
|
skamonkey@3513
|
243 |
/* |
|
skamonkey@3513
|
244 |
printf("%-22s (%s) - GOOD. current:\n\t[w:%s]\n\t[l:%s]\n", |
|
skamonkey@3513
|
245 |
it->name, |
|
skamonkey@3513
|
246 |
(it->lib == Server) ? "server" : "engine", |
|
skamonkey@3513
|
247 |
winSymbol ? winSymbol : "", |
|
skamonkey@3513
|
248 |
linSymbol ? linSymbol : "" |
|
skamonkey@3513
|
249 |
); |
|
skamonkey@3513
|
250 |
*/ |
|
skamonkey@3513
|
251 |
printf("S: %-22s (%s) - GOOD.\n", |
|
skamonkey@3513
|
252 |
it->name, |
|
skamonkey@3513
|
253 |
(it->lib == Server) ? "server" : "engine" |
|
skamonkey@3513
|
254 |
); |
|
skamonkey@3513
|
255 |
} |
|
skamonkey@3513
|
256 |
else |
|
skamonkey@3513
|
257 |
{ |
|
skamonkey@3513
|
258 |
// extra \n at end is intentional to add buffer after possibly long sigs |
|
skamonkey@3513
|
259 |
printf("S: %-22s (%s) - w: %s - l: %s\n%s%s%s%s%s%s%s%s\n", |
|
skamonkey@3513
|
260 |
it->name, |
|
skamonkey@3513
|
261 |
(it->lib == Server) ? "server" : "engine", |
|
skamonkey@3513
|
262 |
hasWindows ? (foundWindows ? "GOOD" : "CHANGED") : "UNKNOWN", |
|
skamonkey@3513
|
263 |
hasLinux ? (foundLinux ? "GOOD" : "CHANGED") : "UNKNOWN", |
|
skamonkey@3513
|
264 |
|
|
skamonkey@3513
|
265 |
hasWindows ? "\tcurrent - w: " : "", |
|
skamonkey@3513
|
266 |
(hasWindows && foundWindows) ? " (found) \"" : (hasWindows ? "(NOT found) \"" : ""), |
|
skamonkey@3513
|
267 |
(hasWindows && winSymbol) ? winSymbol : "", |
|
skamonkey@3513
|
268 |
hasWindows ? "\"\n" : "", |
|
skamonkey@3513
|
269 |
|
|
skamonkey@3513
|
270 |
hasLinux ? "\tcurrent - l: " : "", |
|
skamonkey@3513
|
271 |
(hasLinux && foundLinux) ? " (found) \"" : (hasLinux ? "(NOT found) \"" : ""), |
|
skamonkey@3513
|
272 |
(hasLinux && linSymbol) ? linSymbol : "", |
|
skamonkey@3513
|
273 |
hasLinux ? "\"\n" : "" |
|
skamonkey@3513
|
274 |
); |
|
skamonkey@3513
|
275 |
|
|
skamonkey@3513
|
276 |
} |
|
skamonkey@3513
|
277 |
|
|
skamonkey@3513
|
278 |
// j/k, no way that anyone could have been prepared for that |
|
skamonkey@3513
|
279 |
} |
|
skamonkey@3513
|
280 |
|
|
skamonkey@3513
|
281 |
return 0; |
|
skamonkey@3513
|
282 |
} |
|
skamonkey@3513
|
283 |
|
|
skamonkey@3513
|
284 |
bool checkSigStringW(int file, const char* symbol) |
|
skamonkey@3513
|
285 |
{ |
|
skamonkey@3513
|
286 |
void *addr = NULL; |
|
skamonkey@3513
|
287 |
bool isAt = (symbol[0] == '@'); |
|
skamonkey@3513
|
288 |
// we can't support this on windows from here |
|
skamonkey@3513
|
289 |
if (isAt) |
|
skamonkey@3513
|
290 |
return false; |
|
skamonkey@3513
|
291 |
|
|
skamonkey@3513
|
292 |
unsigned char real_sig[511]; |
|
skamonkey@3513
|
293 |
size_t real_bytes = UTIL_DecodeHexString(real_sig, sizeof(real_sig), symbol); |
|
skamonkey@3513
|
294 |
|
|
skamonkey@3513
|
295 |
if (real_bytes >= 1) |
|
skamonkey@3513
|
296 |
{ |
|
skamonkey@3513
|
297 |
addr = mu.FindPatternInFile(file, (char*)real_sig, real_bytes); |
|
skamonkey@3513
|
298 |
} |
|
skamonkey@3513
|
299 |
|
|
skamonkey@3513
|
300 |
if (addr) |
|
skamonkey@3513
|
301 |
return true; |
|
skamonkey@3513
|
302 |
|
|
skamonkey@3513
|
303 |
return false; |
|
skamonkey@3513
|
304 |
} |
|
skamonkey@3513
|
305 |
|
|
skamonkey@3513
|
306 |
bool checkSigStringL(void *handle, const char* symbol) |
|
skamonkey@3513
|
307 |
{ |
|
skamonkey@3513
|
308 |
void *addr = NULL; |
|
skamonkey@3513
|
309 |
bool isAt = (symbol[0] == '@'); |
|
skamonkey@3513
|
310 |
|
|
skamonkey@3513
|
311 |
if (isAt) |
|
skamonkey@3513
|
312 |
{ |
|
skamonkey@3513
|
313 |
addr = mu.ResolveSymbol(handle, symbol + 1); |
|
skamonkey@3513
|
314 |
} |
|
skamonkey@3513
|
315 |
else |
|
skamonkey@3513
|
316 |
{ |
|
skamonkey@3513
|
317 |
unsigned char real_sig[511]; |
|
skamonkey@3513
|
318 |
size_t real_bytes = UTIL_DecodeHexString(real_sig, sizeof(real_sig), symbol); |
|
skamonkey@3513
|
319 |
|
|
skamonkey@3513
|
320 |
if (real_bytes >= 1) |
|
skamonkey@3513
|
321 |
{ |
|
skamonkey@3513
|
322 |
addr = mu.FindPattern(handle, (char*)real_sig, real_bytes); |
|
skamonkey@3513
|
323 |
} |
|
skamonkey@3513
|
324 |
} |
|
skamonkey@3513
|
325 |
|
|
skamonkey@3513
|
326 |
if (addr) |
|
skamonkey@3513
|
327 |
return true; |
|
skamonkey@3513
|
328 |
|
|
skamonkey@3513
|
329 |
return false; |
|
skamonkey@3513
|
330 |
} |
|
skamonkey@3513
|
331 |
|
|
skamonkey@3513
|
332 |
/* |
|
skamonkey@3513
|
333 |
takes a mangled member function symbol and returns the position where the function name and parameters start |
|
skamonkey@3513
|
334 |
01234567890123456789012345678 |
|
skamonkey@3513
|
335 |
_ZN9CTFPlayer12ForceRespawnEv |
|
skamonkey@3513
|
336 |
^13 ^28 |
|
skamonkey@3513
|
337 |
*/ |
|
skamonkey@3513
|
338 |
void findFuncPos(const char *sym, int &func, int ¶ms) |
|
skamonkey@3513
|
339 |
{ |
|
skamonkey@3513
|
340 |
int i = 0; |
|
skamonkey@3513
|
341 |
while ((sym[i] < '0') || (sym[i] > '9')) i++; |
|
skamonkey@3513
|
342 |
int classLen = atoi(sym + i); |
|
skamonkey@3513
|
343 |
func = i + (int)ceil(log10(classLen)) + classLen; |
|
skamonkey@3513
|
344 |
int funcLen = atoi(sym + func); |
|
skamonkey@3513
|
345 |
params = func + (int)ceil(log10(funcLen)) + funcLen; |
|
skamonkey@3513
|
346 |
} |
|
skamonkey@3513
|
347 |
|
|
skamonkey@3513
|
348 |
int findVFunc(void *handle, void **vt, const char *symbol) |
|
skamonkey@3513
|
349 |
{ |
|
skamonkey@3513
|
350 |
int offset = 1; |
|
skamonkey@3513
|
351 |
int funcPos, paramPos; |
|
skamonkey@3513
|
352 |
findFuncPos(symbol, funcPos, paramPos); |
|
skamonkey@3513
|
353 |
|
|
skamonkey@3513
|
354 |
|
|
skamonkey@3513
|
355 |
|
|
skamonkey@3513
|
356 |
for (int i = 0; i < 1000; i++) |
|
skamonkey@3513
|
357 |
{ |
|
skamonkey@3513
|
358 |
void *pFunc = vt[i]; |
|
skamonkey@3513
|
359 |
const char *s; |
|
skamonkey@3513
|
360 |
|
|
skamonkey@3513
|
361 |
if (!(s = mu.ResolveAddr(handle, pFunc))) |
|
skamonkey@3513
|
362 |
continue; |
|
skamonkey@3513
|
363 |
|
|
skamonkey@3513
|
364 |
if ((i > 1) && (strncmp(s, "_ZTI", 4) == 0)) |
|
skamonkey@3513
|
365 |
break; |
|
skamonkey@3513
|
366 |
|
|
skamonkey@3513
|
367 |
|
|
skamonkey@3513
|
368 |
int tempFuncPos, tempParamPos; |
|
skamonkey@3513
|
369 |
findFuncPos(s, tempFuncPos, tempParamPos); |
|
skamonkey@3513
|
370 |
|
|
skamonkey@3513
|
371 |
if (strcmp(s + tempFuncPos, symbol + funcPos) == 0) |
|
skamonkey@3513
|
372 |
{ |
|
skamonkey@3513
|
373 |
offset = i; |
|
skamonkey@3513
|
374 |
break; |
|
skamonkey@3513
|
375 |
} |
|
skamonkey@3513
|
376 |
} |
|
skamonkey@3513
|
377 |
|
|
skamonkey@3513
|
378 |
return offset - 2; |
|
skamonkey@3513
|
379 |
} |
|
skamonkey@3513
|
380 |
|
|
skamonkey@3513
|
381 |
unsigned int strncopy(char *dest, const char *src, size_t count) |
|
skamonkey@3513
|
382 |
{ |
|
skamonkey@3513
|
383 |
if (!count) |
|
skamonkey@3513
|
384 |
{ |
|
skamonkey@3513
|
385 |
return 0; |
|
skamonkey@3513
|
386 |
} |
|
skamonkey@3513
|
387 |
|
|
skamonkey@3513
|
388 |
char *start = dest; |
|
skamonkey@3513
|
389 |
while ((*src) && (--count)) |
|
skamonkey@3513
|
390 |
{ |
|
skamonkey@3513
|
391 |
*dest++ = *src++; |
|
skamonkey@3513
|
392 |
} |
|
skamonkey@3513
|
393 |
*dest = '\0'; |
|
skamonkey@3513
|
394 |
|
|
skamonkey@3513
|
395 |
return (dest - start); |
|
skamonkey@3513
|
396 |
} |
|
skamonkey@3513
|
397 |
|
|
skamonkey@3513
|
398 |
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...) |
|
skamonkey@3513
|
399 |
{ |
|
skamonkey@3513
|
400 |
va_list ap; |
|
skamonkey@3513
|
401 |
va_start(ap, fmt); |
|
skamonkey@3513
|
402 |
size_t len = vsnprintf(buffer, maxlength, fmt, ap); |
|
skamonkey@3513
|
403 |
va_end(ap); |
|
skamonkey@3513
|
404 |
|
|
skamonkey@3513
|
405 |
if (len >= maxlength) |
|
skamonkey@3513
|
406 |
{ |
|
skamonkey@3513
|
407 |
buffer[maxlength - 1] = '\0'; |
|
skamonkey@3513
|
408 |
return (maxlength - 1); |
|
skamonkey@3513
|
409 |
} |
|
skamonkey@3513
|
410 |
else |
|
skamonkey@3513
|
411 |
{ |
|
skamonkey@3513
|
412 |
return len; |
|
skamonkey@3513
|
413 |
} |
|
skamonkey@3513
|
414 |
} |
|
skamonkey@3513
|
415 |
|
|
skamonkey@3513
|
416 |
size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char *hexstr) |
|
skamonkey@3513
|
417 |
{ |
|
skamonkey@3513
|
418 |
size_t written = 0; |
|
skamonkey@3513
|
419 |
size_t length = strlen(hexstr); |
|
skamonkey@3513
|
420 |
|
|
skamonkey@3513
|
421 |
for (size_t i = 0; i < length; i++) |
|
skamonkey@3513
|
422 |
{ |
|
skamonkey@3513
|
423 |
if (written >= maxlength) |
|
skamonkey@3513
|
424 |
break; |
|
skamonkey@3513
|
425 |
|
|
skamonkey@3513
|
426 |
buffer[written++] = hexstr[i]; |
|
skamonkey@3513
|
427 |
if (hexstr[i] == '\\' && hexstr[i + 1] == 'x') |
|
skamonkey@3513
|
428 |
{ |
|
skamonkey@3513
|
429 |
if (i + 3 >= length) |
|
skamonkey@3513
|
430 |
continue; |
|
skamonkey@3513
|
431 |
/* Get the hex part. */ |
|
skamonkey@3513
|
432 |
char s_byte[3]; |
|
skamonkey@3513
|
433 |
int r_byte; |
|
skamonkey@3513
|
434 |
s_byte[0] = hexstr[i + 2]; |
|
skamonkey@3513
|
435 |
s_byte[1] = hexstr[i + 3]; |
|
skamonkey@3513
|
436 |
s_byte[2] = '\0'; |
|
skamonkey@3513
|
437 |
/* Read it as an integer */ |
|
skamonkey@3513
|
438 |
sscanf(s_byte, "%x", &r_byte); |
|
skamonkey@3513
|
439 |
/* Save the value */ |
|
skamonkey@3513
|
440 |
buffer[written - 1] = r_byte; |
|
skamonkey@3513
|
441 |
/* Adjust index */ |
|
skamonkey@3513
|
442 |
i += 3; |
|
skamonkey@3513
|
443 |
} |
|
skamonkey@3513
|
444 |
} |
|
skamonkey@3513
|
445 |
|
|
skamonkey@3513
|
446 |
return written; |
|
skamonkey@3513
|
447 |
} |
|
skamonkey@3513
|
448 |
|