1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/tools/gdc/gdc.cpp Fri Oct 01 12:15:43 2010 -0700
1.3 @@ -0,0 +1,266 @@
1.4 +#include <stdio.h>
1.5 +#include <unistd.h>
1.6 +#include <dlfcn.h>
1.7 +#include <math.h>
1.8 +#include "gdc.h"
1.9 +#include "GameConfigs.h"
1.10 +#include "MemoryUtils.h"
1.11 +
1.12 +MemoryUtils mu;
1.13 +
1.14 +char *game = NULL;
1.15 +char *engine = NULL;
1.16 +char *binary = NULL;
1.17 +
1.18 +int main(int argc, char **argv)
1.19 +{
1.20 + char *gamedata = NULL;
1.21 + bool debug = false;
1.22 +
1.23 + opterr = 0;
1.24 + int opt;
1.25 + while ((opt = getopt(argc, argv, "b:de:f:g:")) != -1)
1.26 + switch (opt)
1.27 + {
1.28 + case 'd':
1.29 + debug = true;
1.30 + break;
1.31 + case 'g':
1.32 + game = optarg;
1.33 + break;
1.34 +
1.35 + case 'e':
1.36 + engine = optarg;
1.37 + break;
1.38 +
1.39 + case 'f':
1.40 + gamedata = optarg;
1.41 + break;
1.42 +
1.43 + case 'b':
1.44 + binary = optarg;
1.45 + break;
1.46 +
1.47 + case '?':
1.48 + printf("Usage: ./gdc -g <game> -e <engine> -f <gamedata file> -b <binary>\n");
1.49 + return 0;
1.50 +
1.51 + default:
1.52 + printf("WHAT\n");
1.53 + return 0;
1.54 + }
1.55 +
1.56 + if (!game || !engine || !gamedata || !binary)
1.57 + {
1.58 + printf("Usage: ./gdc -g <game> -e <engine> -f <gamedata file> -b <binary>\n");
1.59 + return 0;
1.60 + }
1.61 +
1.62 + printf("Game: %s\nEngine: %s\nGamedata: %s\nBinary: %s\n", game, engine, gamedata, binary);
1.63 +
1.64 + void *handle = dlopen(binary, RTLD_LAZY);
1.65 + if (!handle)
1.66 + {
1.67 + printf("Couldn't open %s (%s)\n", binary, dlerror());
1.68 + return 0;
1.69 + }
1.70 +
1.71 + CGameConfig gc;
1.72 + char err[512];
1.73 + if (!gc.EnterFile(gamedata, err, sizeof(err)))
1.74 + {
1.75 + printf("%s: %s\n", gamedata, err);
1.76 + return 0;
1.77 + }
1.78 +
1.79 + CGameConfig symbols;
1.80 + if (!symbols.EnterFile("symbols.txt", err, sizeof(err)))
1.81 + {
1.82 + printf("symbols.txt: %s\n", err);
1.83 + return 0;
1.84 + }
1.85 +
1.86 + if (debug)
1.87 + for (map<const char*, const char*, cmp_str>::iterator it = symbols.m_Keys.begin(); it != symbols.m_Keys.end(); it++)
1.88 + printf("%s - %s\n", it->first, it->second);
1.89 +
1.90 + const char *vtsym = symbols.GetKeyValue("vtsym");
1.91 + if (!vtsym)
1.92 + {
1.93 + printf("Couldn't find vtsym\n");
1.94 + return 0;
1.95 + }
1.96 +
1.97 +#if 0
1.98 + void *lolwhat = (void*)1;
1.99 + void *handle = lolwhat;
1.100 + handle = dlopen(binary, RTLD_LAZY);
1.101 + if (!handle)
1.102 + {
1.103 + printf("Couldn't open %s\n", binary);
1.104 + return 0;
1.105 + }
1.106 +#endif
1.107 +
1.108 + void **vt = (void**) mu.ResolveSymbol(handle, vtsym);
1.109 + if (!vt)
1.110 + {
1.111 + printf("Couldn't find vtable %s\n", vtsym);
1.112 + dlclose(handle);
1.113 + return 0;
1.114 + }
1.115 +
1.116 +
1.117 + for (list<Offset>::iterator it = gc.m_Offsets.begin(); it != gc.m_Offsets.end(); it++)
1.118 + {
1.119 + if (debug) printf("DEBUG %s - l: %d w: %d\n", it->name, it->lin, it->win);
1.120 +// else
1.121 + {
1.122 + const char *symbol = symbols.GetKeyValue(it->name);
1.123 + if (symbol)
1.124 + {
1.125 + int offset = findVFunc(handle, vt, symbol);
1.126 +
1.127 + if (offset == it->lin) printf("%s - good\n", it->name);
1.128 + else printf("%s - l: %d w: %d\n", it->name, offset, offset + it->lin - it->win);
1.129 + }
1.130 + else printf("%s - no Linux symbol, skipping\n", it->name);
1.131 + }
1.132 + }
1.133 +
1.134 + printf("\nWindows offsets are wild guesses!\n\n");
1.135 +
1.136 + for (list<Sig>::iterator it = gc.m_Sigs.begin(); it != gc.m_Sigs.end(); it++)
1.137 + {
1.138 + if (debug) printf("DEBUG %s - %s - l: %s\n", it->name, it->lib == Server ? "server" : "engine", it->lin);
1.139 +// else
1.140 + {
1.141 + if (it->lib != Server)
1.142 + {
1.143 + printf("%s - isn't server, skipping\n", it->name);
1.144 + continue;
1.145 + }
1.146 +
1.147 + const char *symbol = it->lin;
1.148 +
1.149 + if (!symbol)
1.150 + {
1.151 + printf("%s - no Linux symbol, skipping\n", it->name);
1.152 + continue;
1.153 + }
1.154 +
1.155 + if (symbol[0] != '@')
1.156 + {
1.157 + printf("%s - didn't start with '@', skipping\n", it->name);
1.158 + continue;
1.159 + }
1.160 +
1.161 + void *addr = mu.ResolveSymbol(handle, symbol + 1);
1.162 +
1.163 + if (addr) printf("%s - good\n", it->name);
1.164 + else printf("%s - %s not found\n", it->name, it->lin);
1.165 + }
1.166 + }
1.167 +
1.168 + return 0;
1.169 +}
1.170 +
1.171 +/*
1.172 + takes a mangled member function symbol and returns the position where the function name and parameters start
1.173 + 01234567890123456789012345678
1.174 + _ZN9CTFPlayer12ForceRespawnEv
1.175 + ^13 ^28
1.176 +*/
1.177 +void findFuncPos(const char *sym, int &func, int ¶ms)
1.178 +{
1.179 + int i = 0;
1.180 + while ((sym[i] < '0') || (sym[i] > '9')) i++;
1.181 + int classLen = atoi(sym + i);
1.182 + func = i + (int)ceil(log10(classLen)) + classLen;
1.183 + int funcLen = atoi(sym + func);
1.184 + params = func + (int)ceil(log10(funcLen)) + funcLen;
1.185 +}
1.186 +
1.187 +int findVFunc(void *handle, void **vt, const char *symbol)
1.188 +{
1.189 + int offset = 1;
1.190 + //int overloads = 0;
1.191 + int funcPos, paramPos;
1.192 + findFuncPos(symbol, funcPos, paramPos);
1.193 +
1.194 + for (int i = 0; i < 1000; i++)
1.195 + {
1.196 + void *pFunc = vt[i];
1.197 + const char *s;
1.198 +
1.199 +// Dl_info info;
1.200 +// if (!mu.ResolveAddr(pFunc, &info)) continue;
1.201 + if (!(s = mu.ResolveAddr(handle, pFunc))) continue;
1.202 +
1.203 +// if ((i > 1) && (strncmp(info.dli_sname, "_ZTI", 4) == 0)) break;
1.204 + if ((i > 1) && (strncmp(s, "_ZTI", 4) == 0)) break;
1.205 +
1.206 +
1.207 + int tempFuncPos, tempParamPos;
1.208 +// findFuncPos(info.dli_sname, tempFuncPos, tempParamPos);
1.209 + findFuncPos(s, tempFuncPos, tempParamPos);
1.210 +
1.211 +#if 0
1.212 + if (strncmp(info.dli_sname[tempFuncPos], symbol[funcPos], paramPos - funcPos) == 0)
1.213 + {
1.214 + overloads++;
1.215 + if (firstOverload == -1) firstOverload = i - 1;
1.216 + if (strncmp(info.dli_sname[tempParamPos], symbol[paramPos], strlen(symbol) - paramPos) == 0)
1.217 + {
1.218 + offset = i;
1.219 + matchingOverload = overloads;
1.220 + }
1.221 + }
1.222 +#else
1.223 +// if (strcmp(info.dli_sname + tempFuncPos, symbol + funcPos) == 0)
1.224 + if (strcmp(s + tempFuncPos, symbol + funcPos) == 0)
1.225 + {
1.226 + offset = i;
1.227 + break;
1.228 + }
1.229 +#endif
1.230 + }
1.231 +
1.232 + return offset - 2;
1.233 +}
1.234 +
1.235 +unsigned int strncopy(char *dest, const char *src, size_t count)
1.236 +{
1.237 + if (!count)
1.238 + {
1.239 + return 0;
1.240 + }
1.241 +
1.242 + char *start = dest;
1.243 + while ((*src) && (--count))
1.244 + {
1.245 + *dest++ = *src++;
1.246 + }
1.247 + *dest = '\0';
1.248 +
1.249 + return (dest - start);
1.250 +}
1.251 +
1.252 +size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
1.253 +{
1.254 + va_list ap;
1.255 + va_start(ap, fmt);
1.256 + size_t len = vsnprintf(buffer, maxlength, fmt, ap);
1.257 + va_end(ap);
1.258 +
1.259 + if (len >= maxlength)
1.260 + {
1.261 + buffer[maxlength - 1] = '\0';
1.262 + return (maxlength - 1);
1.263 + }
1.264 + else
1.265 + {
1.266 + return len;
1.267 + }
1.268 +}
1.269 +