6 #include "GameConfigs.h"
7 #include "MemoryUtils.h"
15 int main(int argc, char **argv)
17 char *gamedata = NULL;
22 while ((opt = getopt(argc, argv, "b:de:f:g:")) != -1)
45 printf("Usage: ./gdc -g <game> -e <engine> -f <gamedata file> -b <binary>\n");
53 if (!game || !engine || !gamedata || !binary)
55 printf("Usage: ./gdc -g <game> -e <engine> -f <gamedata file> -b <binary>\n");
59 printf("Game: %s\nEngine: %s\nGamedata: %s\nBinary: %s\n", game, engine, gamedata, binary);
61 void *handle = dlopen(binary, RTLD_LAZY);
64 printf("Couldn't open %s (%s)\n", binary, dlerror());
70 if (!gc.EnterFile(gamedata, err, sizeof(err)))
72 printf("%s: %s\n", gamedata, err);
77 if (!symbols.EnterFile("symbols.txt", err, sizeof(err)))
79 printf("symbols.txt: %s\n", err);
84 for (map<const char*, const char*, cmp_str>::iterator it = symbols.m_Keys.begin(); it != symbols.m_Keys.end(); it++)
85 printf("%s - %s\n", it->first, it->second);
87 const char *vtsym = symbols.GetKeyValue("vtsym");
90 printf("Couldn't find vtsym\n");
95 void *lolwhat = (void*)1;
96 void *handle = lolwhat;
97 handle = dlopen(binary, RTLD_LAZY);
100 printf("Couldn't open %s\n", binary);
105 void **vt = (void**) mu.ResolveSymbol(handle, vtsym);
108 printf("Couldn't find vtable %s\n", vtsym);
114 for (list<Offset>::iterator it = gc.m_Offsets.begin(); it != gc.m_Offsets.end(); it++)
116 if (debug) printf("DEBUG %s - l: %d w: %d\n", it->name, it->lin, it->win);
119 const char *symbol = symbols.GetKeyValue(it->name);
122 int offset = findVFunc(handle, vt, symbol);
124 if (offset == it->lin) printf("%s - good\n", it->name);
125 else printf("%s - l: %d w: %d\n", it->name, offset, offset + it->lin - it->win);
127 else printf("%s - no Linux symbol, skipping\n", it->name);
131 printf("\nWindows offsets are wild guesses!\n\n");
133 for (list<Sig>::iterator it = gc.m_Sigs.begin(); it != gc.m_Sigs.end(); it++)
135 if (debug) printf("DEBUG %s - %s - l: %s\n", it->name, it->lib == Server ? "server" : "engine", it->lin);
138 if (it->lib != Server)
140 printf("%s - isn't server, skipping\n", it->name);
144 const char *symbol = it->lin;
148 printf("%s - no Linux symbol, skipping\n", it->name);
152 if (symbol[0] != '@')
154 printf("%s - didn't start with '@', skipping\n", it->name);
158 void *addr = mu.ResolveSymbol(handle, symbol + 1);
160 if (addr) printf("%s - good\n", it->name);
161 else printf("%s - %s not found\n", it->name, it->lin);
169 takes a mangled member function symbol and returns the position where the function name and parameters start
170 01234567890123456789012345678
171 _ZN9CTFPlayer12ForceRespawnEv
174 void findFuncPos(const char *sym, int &func, int ¶ms)
177 while ((sym[i] < '0') || (sym[i] > '9')) i++;
178 int classLen = atoi(sym + i);
179 func = i + (int)ceil(log10(classLen)) + classLen;
180 int funcLen = atoi(sym + func);
181 params = func + (int)ceil(log10(funcLen)) + funcLen;
184 int findVFunc(void *handle, void **vt, const char *symbol)
188 int funcPos, paramPos;
189 findFuncPos(symbol, funcPos, paramPos);
191 for (int i = 0; i < 1000; i++)
197 // if (!mu.ResolveAddr(pFunc, &info)) continue;
198 if (!(s = mu.ResolveAddr(handle, pFunc))) continue;
200 // if ((i > 1) && (strncmp(info.dli_sname, "_ZTI", 4) == 0)) break;
201 if ((i > 1) && (strncmp(s, "_ZTI", 4) == 0)) break;
204 int tempFuncPos, tempParamPos;
205 // findFuncPos(info.dli_sname, tempFuncPos, tempParamPos);
206 findFuncPos(s, tempFuncPos, tempParamPos);
209 if (strncmp(info.dli_sname[tempFuncPos], symbol[funcPos], paramPos - funcPos) == 0)
212 if (firstOverload == -1) firstOverload = i - 1;
213 if (strncmp(info.dli_sname[tempParamPos], symbol[paramPos], strlen(symbol) - paramPos) == 0)
216 matchingOverload = overloads;
220 // if (strcmp(info.dli_sname + tempFuncPos, symbol + funcPos) == 0)
221 if (strcmp(s + tempFuncPos, symbol + funcPos) == 0)
232 unsigned int strncopy(char *dest, const char *src, size_t count)
240 while ((*src) && (--count))
246 return (dest - start);
249 size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
253 size_t len = vsnprintf(buffer, maxlength, fmt, ap);
256 if (len >= maxlength)
258 buffer[maxlength - 1] = '\0';
259 return (maxlength - 1);