diff --git a/tools/vtable_scanner/main.cpp b/tools/vtable_scanner/main.cpp index 59ba8761..2469bf41 100644 --- a/tools/vtable_scanner/main.cpp +++ b/tools/vtable_scanner/main.cpp @@ -1,18 +1,18 @@ -#include -#include -#include "string.h" -#include "malloc.h" - -extern "C" char * cplus_demangle(const char *, int); -#define DMGL_PARAMS (1 << 0) - -struct VOffset -{ - int linux_offset; - int windows_offset; -}; - -static bool FindVFunc(void *handle, void **vtable, const char* vtable_end, const char *class_function, const char *params, VOffset *offsets); +#include +#include +#include "string.h" +#include "malloc.h" + +extern "C" char * cplus_demangle(const char *, int); +#define DMGL_PARAMS (1 << 0) + +struct VOffset +{ + int linux_offset; + int windows_offset; +}; + +static bool FindVFunc(void *handle, void **vtable, const char* vtable_end, const char *class_function, const char *params, VOffset *offsets); int main(int argc, char **argv) { @@ -39,6 +39,13 @@ int main(int argc, char **argv) pVtable = (void **)dlsym(handle, argv[2]); + if (pVtable == NULL) + { + char startSym[128]; + snprintf(startSym, sizeof(startSym), "_ZTV%d%s", strlen(argv[2]), argv[2]); + pVtable = (void **)dlsym(handle, startSym); + } + if (pVtable == NULL) { fprintf(stderr, "Invalid vtable symbol \"%s\"\n", argv[2]); @@ -96,91 +103,91 @@ int main(int argc, char **argv) dlclose(handle); return -1; } - -static bool FindVFunc(void *handle, void **vtable, const char* vtable_end, const char *class_function, const char *params, VOffset *offsets) -{ - Dl_info d; - - int linux_offset = -1; - int windows_offset = -1; - - int overloads = 0; - int location = 0; - int start_offset = -1; - - for (int i=0; i< 1000; i++) - { - void *FuncPtr = vtable[i]; - - int status = dladdr(FuncPtr, &d); - - if (!status) - { - continue; - } - - if (i > 1 && strncmp(d.dli_sname, vtable_end, strlen(vtable_end)) == 0) - { - break; - } - - char *name = cplus_demangle(d.dli_sname, DMGL_PARAMS); - - if (name == NULL) - { - printf("Demangling failed\n"); - continue; - } - - char *foundfunction = strpbrk(name, ":"); - - if (foundfunction == NULL) - { - //printf("Couldnt split function\n"); - free(name); - continue; - } - - //Skip both ':' chars - foundfunction += 2; - - - if (strncmp(foundfunction, class_function, strlen(class_function)) == 0 && foundfunction[strlen(class_function)] == '(') - { - //printf("Symbol: %s Demangled: %s Offset: %i\n", d.dli_sname, name, i); - - //We have a pointer to a function, but it may be overloaded. - overloads++; - - if (start_offset == -1) - { - start_offset = i-1; - } - - char *foundparams = strpbrk(foundfunction, "("); - - if (foundparams == NULL) - { - printf("ARGH\n"); - free(name); - continue; - } - - if(params == NULL || strcmp(foundparams, params) == 0) - { - //This is actually our function - So this is the linux offset - linux_offset = i; - location = overloads; - } - } - - free(name); - } - - windows_offset = (overloads-location) + start_offset; - - offsets->linux_offset = linux_offset - 2; - offsets->windows_offset = windows_offset - 2; - - return true; -} + +static bool FindVFunc(void *handle, void **vtable, const char* vtable_end, const char *class_function, const char *params, VOffset *offsets) +{ + Dl_info d; + + int linux_offset = -1; + int windows_offset = -1; + + int overloads = 0; + int location = 0; + int start_offset = -1; + + for (int i=0; i< 1000; i++) + { + void *FuncPtr = vtable[i]; + + int status = dladdr(FuncPtr, &d); + + if (!status) + { + continue; + } + + if (i > 1 && strncmp(d.dli_sname, vtable_end, strlen(vtable_end)) == 0) + { + break; + } + + char *name = cplus_demangle(d.dli_sname, DMGL_PARAMS); + + if (name == NULL) + { + printf("Demangling failed\n"); + continue; + } + + char *foundfunction = strpbrk(name, ":"); + + if (foundfunction == NULL) + { + //printf("Couldnt split function\n"); + free(name); + continue; + } + + //Skip both ':' chars + foundfunction += 2; + + + if (strncmp(foundfunction, class_function, strlen(class_function)) == 0 && foundfunction[strlen(class_function)] == '(') + { + //printf("Symbol: %s Demangled: %s Offset: %i\n", d.dli_sname, name, i); + + //We have a pointer to a function, but it may be overloaded. + overloads++; + + if (start_offset == -1) + { + start_offset = i-1; + } + + char *foundparams = strpbrk(foundfunction, "("); + + if (foundparams == NULL) + { + printf("ARGH\n"); + free(name); + continue; + } + + if(params == NULL || strcmp(foundparams, params) == 0) + { + //This is actually our function - So this is the linux offset + linux_offset = i; + location = overloads; + } + } + + free(name); + } + + windows_offset = (overloads-location) + start_offset; + + offsets->linux_offset = linux_offset - 2; + offsets->windows_offset = windows_offset - 2; + + return true; +}