1
0
Fork 0

DBG: added basic plugin support (load plugins + register & call callbacks)

This commit is contained in:
mr.exodia 2013-11-22 22:12:56 +01:00
parent f0c1f8966a
commit 6588b90ecd
8 changed files with 308 additions and 2 deletions

View File

@ -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

13
x64_dbg_dbg/_plugins.cpp Normal file
View File

@ -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);
}

79
x64_dbg_dbg/_plugins.h Normal file
View File

@ -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

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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();

View File

@ -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" />