Import of Vtable scanner

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%402301
This commit is contained in:
Matt Woodrow 2008-06-30 02:03:56 +00:00
parent 2fc7a017e1
commit 7104e187cc
4 changed files with 285 additions and 0 deletions

View File

@ -0,0 +1,76 @@
# (C)2004-2008 SourceMod Development Team
# Makefile written by David "BAILOPAN" Anderson
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
OBJECTS = main.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
##############################################
C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
C_GCC4_FLAGS = -fvisibility=hidden
CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
CPP = gcc-4.1
BINARY = vtablecheck
LINK += -L. -liberty -ldl
INCLUDE += -I.
CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
-D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror \
-Wno-uninitialized -mfpmath=sse -msse -DHAVE_STDINT_H -DSM_DEFAULT_THREADER -m32
CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
################################################
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
################################################
ifeq "$(DEBUG)" "true"
BIN_DIR = Debug
CFLAGS += $(C_DEBUG_FLAGS)
else
BIN_DIR = Release
CFLAGS += $(C_OPT_FLAGS)
endif
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
ifeq "$(GCC_VERSION)" "4"
CFLAGS += $(C_GCC4_FLAGS)
CPPFLAGS += $(CPP_GCC4_FLAGS)
endif
OBJ_LINUX := $(OBJECTS:%vm_engine.cpp=$(BIN_DIR)/%vm_engine.o)
OBJ_LINUX := $(OBJ_LINUX:%.cpp=$(BIN_DIR)/%.o)
OBJ_LINUX := $(OBJ_LINUX:%.c=$(BIN_DIR)/%.o)
$(BIN_DIR)/%vm_engine.o: %vm_engine.cpp
$(CPP) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
$(BIN_DIR)/%.o: %.cpp
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
$(BIN_DIR)/%.o: %.c
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
all:
mkdir -p $(BIN_DIR)
$(MAKE) -f Makefile sourcemod
sourcemod: $(OBJ_LINUX)
$(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -o$(BIN_DIR)/$(BINARY)
debug:
$(MAKE) -f Makefile all DEBUG=true
default: all
clean:
rm -rf $(BIN_DIR)/$(BINARY)

Binary file not shown.

View File

@ -0,0 +1,192 @@
#include <stdio.h>
#include <dlfcn.h>
#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)
{
void *handle;
void **pVtable;
handle = dlopen(argv[1], RTLD_NOW);
VOffset offsets;
char *params = NULL;
bool ret;
if (argc < 4)
{
fprintf(stderr, "Usage: <binary> <vtable start symbol> <function> <optional: params> <optional: vtable end symbol>\n");
return -1;
}
if (handle == NULL)
{
printf("Failed to open server image, error [%s]\n", dlerror());
return -1;
}
pVtable = (void **)dlsym(handle, argv[2]);
if (argc >= 5)
{
params = argv[4];
if (params[0] == '"')
{
params++;
}
int len = strlen(params)-1;
if (params[len] == '"')
{
params[len] = '\0';
}
if (params[0] == 0)
{
params = NULL;
}
}
if (argc == 6)
{
ret = FindVFunc(handle, pVtable, argv[5], argv[3], params, &offsets);
}
else
{
ret = FindVFunc(handle, pVtable, "_ZTI", argv[3], params, &offsets);
}
if (ret)
{
printf("%s - Win: %i Linux : %i\n", argv[3], offsets.windows_offset, offsets.linux_offset);
return 0;
}
fprintf(stderr, "Failed to find function!");
return -1;
#if 0
if (FindVFunc(handle, pVtable, "CommitSuicide", "(bool, bool)", &offsets))
printf("Commit Suicide - Win: %i Linux : %i\n", offsets.windows_offset, offsets.linux_offset);
if (FindVFunc(handle, pVtable, "KeyValue", "(char const*, char const*)", &offsets))
printf("KeyValue - Win: %i Linux : %i\n", offsets.windows_offset, offsets.linux_offset);
if (FindVFunc(handle, pVtable, "KeyValue", "(char const*, float)", &offsets))
printf("KeyValue Float - Win: %i Linux : %i\n", offsets.windows_offset, offsets.linux_offset);
if (FindVFunc(handle, handle, pVtable, "KeyValue", "(char const*, Vector const&)", &offsets))
printf("KeyValue Vector - Win: %i Linux : %i\n", offsets.windows_offset, offsets.linux_offset);
if (FindVFunc(handle, pVtable, "Ignite", NULL, &offsets))
printf("Ignite - Win: %i Linux : %i\n", offsets.windows_offset, offsets.linux_offset);
if (FindVFunc(handle, pVtable, "Extinguish", NULL, &offsets))
printf("Extinguish - Win: %i Linux : %i\n", offsets.windows_offset, offsets.linux_offset);
return 0;
#endif
}
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;
dlclose(handle);
offsets->linux_offset = linux_offset - 2;
offsets->windows_offset = windows_offset - 2;
return true;
}

View File

@ -0,0 +1,17 @@
echo "sdktools.games.ep2.txt
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer RemovePlayerItem
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer Weapon_GetSlot
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer Ignite
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer Extinguish
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer Teleport
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer CommitSuicide "(bool, bool)"
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer GetVelocity
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer EyeAngles
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer KeyValue "(char const*, char const*)"
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer KeyValue "(char const*, float)"
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer KeyValue "(char const*, Vector const&)"
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer SetModel
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer AcceptInput
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer Activate
echo "sm-tf2.games.txt"
./vtablecheck ~/srcds/orangebox/tf/bin/server_i486.so _ZTV9CTFPlayer ForceRespawn