QtDebugger/src/injector.cpp

74 lines
2.4 KiB
C++

// this file injects the debugger into the QApplication
#include "injector.h"
#include "qtdebugger.h"
#include <dlfcn.h>
#include <QApplication>
using registerFunc = bool (*) (int, const unsigned char*, const unsigned char*, const unsigned char*);
std::map<uint64_t, std::shared_ptr<RegisteredResource>>* registeredResources = nullptr;
RegisteredResource::RegisteredResource(int version, const unsigned char* resourceStruct, const unsigned char* resourceName, const unsigned char* resourceData) :
version( version ), resourceStruct( resourceStruct ), resourceName( resourceName ), resourceData( resourceData ) { }
int QApplication::exec() {
// init debugger
QtDebugger debugger;
// get real exec call
static int (*real_exec)() = (int (*)()) dlsym(RTLD_NEXT, "_ZN12QApplication4execEv");
if ( !real_exec ) {
// failed to init real exec
return -1;
}
// call real exec call
int returnVal = real_exec();
// end debugger
return returnVal;
}
bool qRegisterResourceData(int i, const unsigned char* resourceStruct, const unsigned char* resourceName, const unsigned char* resourceData) {
static registerFunc real_register = (registerFunc) dlsym(RTLD_NEXT, "_Z21qRegisterResourceDataiPKhS0_S0_");
// printf("registerResourceData: %i struct: %p name: %p data: %p\n", i, resourceStruct, resourceName, resourceData);
bool res = real_register(i, resourceStruct, resourceName, resourceData);
if ( res ) {
if ( !registeredResources ) {
registeredResources = new std::map<uint64_t, std::shared_ptr<RegisteredResource>>();
}
(*registeredResources)[(uint64_t) resourceStruct] = std::make_shared<RegisteredResource>(i, resourceStruct, resourceName, resourceData);
}
return res;
}
bool qUnregisterResourceData(int i, const unsigned char* resourceStruct, const unsigned char* resourceName, const unsigned char* resourceData) {
static registerFunc real_unregister = (registerFunc) dlsym(RTLD_NEXT, "_Z23qUnregisterResourceDataiPKhS0_S0_");
// printf("unregisterResourceData: %i struct: %p name: %p data: %p\n", i, resourceStruct, resourceName, resourceData);
bool res = real_unregister(i, resourceStruct, resourceName, resourceData);
if ( res && registeredResources ) {
auto it = registeredResources->find( (uint64_t) resourceStruct );
if ( it != registeredResources->end() ) {
registeredResources->erase( it );
if ( registeredResources->empty() ) {
delete registeredResources;
registeredResources = nullptr;
}
}
}
return res;
}