DBG: added basic plugin support (load plugins + register & call callbacks)
This commit is contained in:
parent
f0c1f8966a
commit
6588b90ecd
|
@ -0,0 +1,32 @@
|
|||
#ifndef _PLUGIN_DATA_H
|
||||
#define _PLUGIN_DATA_H
|
||||
|
||||
#ifdef BUILD_DBG
|
||||
|
||||
#include "_global.h"
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include "dbghelp\dbghelp.h"
|
||||
#else
|
||||
#include <dbghelp.h>
|
||||
#endif //__GNUC__
|
||||
|
||||
#define deflen 1024
|
||||
|
||||
#ifdef _WIN64 //defined by default
|
||||
#define fhex "%.16llX"
|
||||
#define fext "ll"
|
||||
typedef unsigned long long duint;
|
||||
typedef long long dsint;
|
||||
#else
|
||||
#define fhex "%.8X"
|
||||
#define fext ""
|
||||
typedef unsigned long duint;
|
||||
typedef long dsint;
|
||||
#endif // _WIN64
|
||||
|
||||
#endif //BUILD_DBG
|
||||
|
||||
#endif // _PLUGIN_DATA_H
|
|
@ -0,0 +1,13 @@
|
|||
#include "_plugins.h"
|
||||
#include "plugin_loader.h"
|
||||
|
||||
///debugger plugin exports (wrappers)
|
||||
PLUG_IMPEXP void _plugin_registercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin)
|
||||
{
|
||||
pluginregistercallback(pluginHandle, cbType, cbPlugin);
|
||||
}
|
||||
|
||||
PLUG_IMPEXP bool _plugin_unregistercallback(int pluginHandle, CBTYPE cbType)
|
||||
{
|
||||
return pluginunregistercallback(pluginHandle, cbType);
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
#ifndef _PLUGINS_H
|
||||
#define _PLUGINS_H
|
||||
|
||||
#ifndef PLUG_IMPEXP
|
||||
#ifdef BUILD_DBG
|
||||
#define PLUG_IMPEXP __declspec(dllexport)
|
||||
#else
|
||||
#define PLUG_IMPEXP __declspec(dllimport)
|
||||
#endif //BUILD_DBG
|
||||
#endif //PLUG_IMPEXP
|
||||
|
||||
#include "_plugin_types.h"
|
||||
|
||||
//structures
|
||||
struct PLUG_INITSTRUCT
|
||||
{
|
||||
//provided by the debugger
|
||||
int pluginHandle;
|
||||
//provided by the pluginit function
|
||||
int sdkVersion;
|
||||
int pluginVersion;
|
||||
char pluginName[256];
|
||||
};
|
||||
|
||||
//callback structures
|
||||
struct PLUG_CB_INITDEBUG
|
||||
{
|
||||
const char* szFileName;
|
||||
};
|
||||
|
||||
struct PLUG_CB_STOPDEBUG
|
||||
{
|
||||
void* reserved;
|
||||
};
|
||||
|
||||
struct PLUG_CB_CREATEPROCESS
|
||||
{
|
||||
CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo;
|
||||
IMAGEHLP_MODULE64* modInfo;
|
||||
const char* DebugFileName;
|
||||
};
|
||||
|
||||
//enums
|
||||
enum CBTYPE
|
||||
{
|
||||
CB_INITDEBUG, //PLUG_CB_INITDEBUG
|
||||
CB_STOPDEBUG, //PLUG_CB_STOPDEBUG
|
||||
CB_CREATEPROCESS, //PLUG_CB_CREATEPROCESS
|
||||
CB_EXITPROCESS,
|
||||
CB_CREATETHREAD,
|
||||
CB_EXITTHREAD,
|
||||
CB_SYSTEMBREAKPOINT,
|
||||
CB_LOADDLL,
|
||||
CB_UNLOADDLL,
|
||||
CB_OUTPUTDEBUGSTRING,
|
||||
CB_EXCEPTION,
|
||||
CB_BREAKPOINT,
|
||||
CB_PAUSEDEBUG,
|
||||
CB_RESUMEDEBUG,
|
||||
CB_STEPPED
|
||||
};
|
||||
|
||||
//typedefs
|
||||
typedef void (*CBPLUGIN)(CBTYPE cbType, void* callbackInfo);
|
||||
|
||||
//exports
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
PLUG_IMPEXP void _plugin_registercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin);
|
||||
PLUG_IMPEXP bool _plugin_unregistercallback(int pluginHandle, CBTYPE cbType);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _PLUGINS_H
|
|
@ -8,6 +8,7 @@
|
|||
#include "memory.h"
|
||||
#include "_exports.h"
|
||||
#include "addrinfo.h"
|
||||
#include "plugin_loader.h"
|
||||
|
||||
static PROCESS_INFORMATION g_pi= {0,0,0,0};
|
||||
PROCESS_INFORMATION* fdProcessInfo=&g_pi;
|
||||
|
@ -377,6 +378,13 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo)
|
|||
char modname[256]="";
|
||||
if(modnamefromaddr((uint)base, modname, true))
|
||||
bpenumall(cbSetModuleBreakpoints, modname);
|
||||
|
||||
//call plugin callback
|
||||
PLUG_CB_CREATEPROCESS callbackInfo;
|
||||
callbackInfo.CreateProcessInfo=CreateProcessInfo;
|
||||
callbackInfo.modInfo=&modInfo;
|
||||
callbackInfo.DebugFileName=DebugFileName;
|
||||
plugincbcall(CB_CREATEPROCESS, &callbackInfo);
|
||||
}
|
||||
|
||||
static void cbSystemBreakpoint(void* ExceptionData)
|
||||
|
@ -463,10 +471,18 @@ static DWORD WINAPI threadDebugLoop(void* lpParameter)
|
|||
SetCustomHandler(UE_CH_UNLOADDLL, (void*)cbUnloadDll);
|
||||
//inform GUI start we started without problems
|
||||
GuiSetDebugState(initialized);
|
||||
//call plugin callback
|
||||
PLUG_CB_INITDEBUG initInfo;
|
||||
initInfo.szFileName=szFileName;
|
||||
plugincbcall(CB_INITDEBUG, &initInfo);
|
||||
//run debug loop (returns when process debugging is stopped)
|
||||
DebugLoop();
|
||||
DeleteFileA("DLLLoader.exe");
|
||||
//call plugin callback
|
||||
PLUG_CB_STOPDEBUG stopInfo;
|
||||
stopInfo.reserved=0;
|
||||
plugincbcall(CB_STOPDEBUG, &stopInfo);
|
||||
//message the user/do final stuff
|
||||
DeleteFileA("DLLLoader.exe");
|
||||
SymCleanup(fdProcessInfo->hProcess);
|
||||
dbclose();
|
||||
modclear();
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
#include "plugin_loader.h"
|
||||
#include "console.h"
|
||||
|
||||
static std::vector<PLUG_DATA> pluginList;
|
||||
static int curPluginHandle=0;
|
||||
static std::vector<PLUG_CALLBACK> pluginCallbackList;
|
||||
|
||||
///internal plugin functions
|
||||
void pluginload(const char* pluginDir)
|
||||
{
|
||||
char currentDir[deflen]="";
|
||||
GetCurrentDirectoryA(deflen, currentDir);
|
||||
SetCurrentDirectoryA(pluginDir);
|
||||
char searchName[deflen]="";
|
||||
#ifdef _WIN64
|
||||
sprintf(searchName, "%s\\*.dp64", pluginDir);
|
||||
#else
|
||||
sprintf(searchName, "%s\\*.dp32", pluginDir);
|
||||
#endif // _WIN64
|
||||
WIN32_FIND_DATA foundData;
|
||||
HANDLE hSearch=FindFirstFileA(searchName, &foundData);
|
||||
if(hSearch==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetCurrentDirectoryA(currentDir);
|
||||
return;
|
||||
}
|
||||
PLUG_DATA pluginData;
|
||||
char errorMsg[deflen]="";
|
||||
do
|
||||
{
|
||||
memset(&pluginData, 0, sizeof(PLUG_DATA));
|
||||
pluginData.initStruct.pluginHandle=curPluginHandle;
|
||||
pluginData.hPlugin=LoadLibraryA(foundData.cFileName); //load the plugin library
|
||||
if(!pluginData.hPlugin)
|
||||
{
|
||||
sprintf(errorMsg, "Failed to load plugin: %s", foundData.cFileName);
|
||||
MessageBoxA(0, errorMsg, "Plugin Error!", MB_ICONERROR|MB_SYSTEMMODAL);
|
||||
continue;
|
||||
}
|
||||
pluginData.pluginit=(PLUGINIT)GetProcAddress(pluginData.hPlugin, "pluginit");
|
||||
if(!pluginData.pluginit)
|
||||
{
|
||||
sprintf(errorMsg, "Export \"pluginit\" not found in plugin: %s", foundData.cFileName);
|
||||
MessageBoxA(0, errorMsg, "Plugin Error!", MB_ICONERROR|MB_SYSTEMMODAL);
|
||||
FreeLibrary(pluginData.hPlugin);
|
||||
continue;
|
||||
}
|
||||
pluginData.plugstop=(PLUGSTOP)GetProcAddress(pluginData.hPlugin, "plugstop");
|
||||
if(!pluginData.plugstop)
|
||||
{
|
||||
sprintf(errorMsg, "Export \"plugstop\" not found in plugin: %s", foundData.cFileName);
|
||||
MessageBoxA(0, errorMsg, "Plugin Error!", MB_ICONERROR|MB_SYSTEMMODAL);
|
||||
FreeLibrary(pluginData.hPlugin);
|
||||
continue;
|
||||
}
|
||||
//TODO: handle exceptions
|
||||
if(!pluginData.pluginit(&pluginData.initStruct))
|
||||
{
|
||||
sprintf(errorMsg, "pluginit failed for plugin: %s", foundData.cFileName);
|
||||
MessageBoxA(0, errorMsg, "Plugin Error!", MB_ICONERROR|MB_SYSTEMMODAL);
|
||||
FreeLibrary(pluginData.hPlugin);
|
||||
continue;
|
||||
}
|
||||
pluginList.push_back(pluginData);
|
||||
curPluginHandle++;
|
||||
}
|
||||
while(FindNextFileA(hSearch, &foundData));
|
||||
SetCurrentDirectoryA(currentDir);
|
||||
}
|
||||
|
||||
void pluginunload()
|
||||
{
|
||||
int pluginCount=pluginList.size();
|
||||
for(int i=0; i<pluginCount; i++)
|
||||
{
|
||||
pluginList.at(i).plugstop();
|
||||
FreeLibrary(pluginList.at(i).hPlugin);
|
||||
}
|
||||
}
|
||||
|
||||
///debugging plugin exports
|
||||
void pluginregistercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin)
|
||||
{
|
||||
pluginunregistercallback(pluginHandle, cbType); //remove previous callback
|
||||
PLUG_CALLBACK cbStruct;
|
||||
cbStruct.pluginHandle=pluginHandle;
|
||||
cbStruct.cbType=cbType;
|
||||
cbStruct.cbPlugin=cbPlugin;
|
||||
pluginCallbackList.push_back(cbStruct);
|
||||
}
|
||||
|
||||
bool pluginunregistercallback(int pluginHandle, CBTYPE cbType)
|
||||
{
|
||||
int pluginCallbackCount=pluginCallbackList.size();
|
||||
for(int i=0; i<pluginCallbackCount; i++)
|
||||
{
|
||||
if(pluginCallbackList.at(i).pluginHandle==pluginHandle and pluginCallbackList.at(i).cbType==cbType)
|
||||
{
|
||||
pluginCallbackList.erase(pluginCallbackList.begin()+i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void plugincbcall(CBTYPE cbType, void* callbackInfo)
|
||||
{
|
||||
int pluginCallbackCount=pluginCallbackList.size();
|
||||
for(int i=0; i<pluginCallbackCount; i++)
|
||||
{
|
||||
if(pluginCallbackList.at(i).cbType==cbType)
|
||||
{
|
||||
//TODO: handle exceptions
|
||||
pluginCallbackList.at(i).cbPlugin(cbType, callbackInfo);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef _PLUGIN_LOADER_H
|
||||
#define _PLUGIN_LOADER_H
|
||||
|
||||
#include "_global.h"
|
||||
#include "_plugins.h"
|
||||
|
||||
//typedefs
|
||||
typedef bool (*PLUGINIT)(PLUG_INITSTRUCT* initStruct);
|
||||
typedef bool (*PLUGSTOP)();
|
||||
|
||||
//structures
|
||||
struct PLUG_DATA
|
||||
{
|
||||
HINSTANCE hPlugin;
|
||||
PLUGINIT pluginit;
|
||||
PLUGSTOP plugstop;
|
||||
PLUG_INITSTRUCT initStruct;
|
||||
};
|
||||
|
||||
struct PLUG_CALLBACK
|
||||
{
|
||||
int pluginHandle;
|
||||
CBTYPE cbType;
|
||||
CBPLUGIN cbPlugin;
|
||||
};
|
||||
|
||||
//plugin management functions
|
||||
void pluginload(const char* pluginDir);
|
||||
void pluginunload();
|
||||
void pluginregistercallback(int pluginHandle, CBTYPE cbType, CBPLUGIN cbPlugin);
|
||||
bool pluginunregistercallback(int pluginHandle, CBTYPE cbType);
|
||||
void plugincbcall(CBTYPE cbType, void* callbackInfo);
|
||||
|
||||
#endif // _PLUGIN_LOADER_H
|
|
@ -12,6 +12,7 @@
|
|||
#include "msgqueue.h"
|
||||
#include "addrinfo.h"
|
||||
#include "threading.h"
|
||||
#include "plugin_loader.h"
|
||||
|
||||
static MESSAGE_STACK* gMsgStack=0;
|
||||
static COMMAND* command_list=0;
|
||||
|
@ -123,7 +124,10 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
|
|||
registercommands();
|
||||
scriptSetList(command_list);
|
||||
CreateThread(0, 0, DbgCommandLoopThread, 0, 0, 0);
|
||||
//CreateThread(0, 0, ConsoleReadLoopThread, 0, 0, 0);
|
||||
char plugindir[deflen]="";
|
||||
strcpy(plugindir, dir);
|
||||
PathAppendA(plugindir, "plugins");
|
||||
pluginload(plugindir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -132,6 +136,7 @@ extern "C" DLL_EXPORT void _dbg_dbgexitsignal()
|
|||
//TODO: handle exit signal
|
||||
cbStopDebug("");
|
||||
wait(WAITID_STOP); //after this, debugging stopped
|
||||
pluginunload();
|
||||
DeleteFileA("DLLLoader.exe");
|
||||
cmdfree(command_list);
|
||||
varfree();
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
<Option compiler="gcc" />
|
||||
<Option host_application="../bin/x32/x32_dbg.exe" />
|
||||
<Option run_host_application_in_terminal="0" />
|
||||
<Option createDefFile="1" />
|
||||
<Option createStaticLib="1" />
|
||||
<Compiler>
|
||||
<Add option="-fomit-frame-pointer" />
|
||||
<Add option="-Os" />
|
||||
|
@ -34,6 +36,8 @@
|
|||
<Option compiler="gnu_gcc_compiler_x64" />
|
||||
<Option host_application="../bin/x64/x64_dbg.exe" />
|
||||
<Option run_host_application_in_terminal="0" />
|
||||
<Option createDefFile="1" />
|
||||
<Option createStaticLib="1" />
|
||||
<Compiler>
|
||||
<Add option="-O3" />
|
||||
<Add option="-Wno-narrowing" />
|
||||
|
@ -51,6 +55,7 @@
|
|||
<Compiler>
|
||||
<Add option="-Wall" />
|
||||
<Add option="-fexceptions -Wno-format" />
|
||||
<Add option="-DBUILD_DBG" />
|
||||
<Add directory="$(project_dir)" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
|
@ -63,6 +68,9 @@
|
|||
<Unit filename="_exports.h" />
|
||||
<Unit filename="_global.cpp" />
|
||||
<Unit filename="_global.h" />
|
||||
<Unit filename="_plugin_types.h" />
|
||||
<Unit filename="_plugins.cpp" />
|
||||
<Unit filename="_plugins.h" />
|
||||
<Unit filename="addrinfo.cpp" />
|
||||
<Unit filename="addrinfo.h" />
|
||||
<Unit filename="argument.cpp" />
|
||||
|
@ -87,6 +95,8 @@
|
|||
<Unit filename="memory.h" />
|
||||
<Unit filename="msgqueue.cpp" />
|
||||
<Unit filename="msgqueue.h" />
|
||||
<Unit filename="plugin_loader.cpp" />
|
||||
<Unit filename="plugin_loader.h" />
|
||||
<Unit filename="simplescript.cpp" />
|
||||
<Unit filename="simplescript.h" />
|
||||
<Unit filename="sqlhelper.cpp" />
|
||||
|
|
Loading…
Reference in New Issue