Let vtablecheck take class names instead of just vtable symbols (also fix line endings)

This commit is contained in:
Fyren 2009-03-21 18:17:43 -07:00
parent 4364ba46e2
commit ccc4386285

View File

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