Import of Vtable scanner
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%402301
This commit is contained in:
parent
2fc7a017e1
commit
7104e187cc
76
tools/Vtable scanner/Makefile
Normal file
76
tools/Vtable scanner/Makefile
Normal 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)
|
BIN
tools/Vtable scanner/libiberty.a
Normal file
BIN
tools/Vtable scanner/libiberty.a
Normal file
Binary file not shown.
192
tools/Vtable scanner/main.cpp
Normal file
192
tools/Vtable scanner/main.cpp
Normal 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;
|
||||
}
|
17
tools/Vtable scanner/tfscan.sh
Normal file
17
tools/Vtable scanner/tfscan.sh
Normal 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
|
Loading…
Reference in New Issue
Block a user