1
0
Fork 0

(Re)implemented loadlib using inline asm: save the current context, allocate a memory page in the debugged process' context, assemble a CALL LoadLibraryA there, execute it and then free the memory and restore the previous context.

This commit is contained in:
SmilingWolf 2014-12-08 02:04:00 +01:00
parent e406019b60
commit 2aac3c2de9
4 changed files with 87 additions and 1 deletions

View File

@ -109,6 +109,7 @@ void cbSystemBreakpoint(void* ExceptionData);
void cbMemoryBreakpoint(void* ExceptionAddress);
void cbHardwareBreakpoint(void* ExceptionAddress);
void cbUserBreakpoint();
void cbLoadLibBPX();
void cbLibrarianBreakpoint(void* lpData);
DWORD WINAPI threadDebugLoop(void* lpParameter);
bool cbDeleteAllBreakpoints(const BREAKPOINT* bp);

View File

@ -9,8 +9,12 @@
#include "plugin_loader.h"
#include "simplescript.h"
#include "symbolinfo.h"
#include "assemble.h"
static bool bScyllaLoaded = false;
CONTEXT backupctx = { 0 };
LPVOID DLLNameMem;
LPVOID ASMAddr;
CMDRESULT cbDebugInit(int argc, char* argv[])
{
@ -1764,6 +1768,85 @@ CMDRESULT cbDebugSetPageRights(int argc, char* argv[])
return STATUS_CONTINUE;
}
CMDRESULT cbDebugLoadLib(int argc, char* argv[])
{
if(argc < 2)
{
dprintf("Error: you must specify the name of the DLL to load\n");
return STATUS_ERROR;
}
DLLNameMem = VirtualAllocEx(fdProcessInfo->hProcess, NULL, strlen(argv[1]) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
ASMAddr = VirtualAllocEx(fdProcessInfo->hProcess, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(!DLLNameMem || !ASMAddr)
{
dprintf("Error: couldn't allocate memory");
return STATUS_ERROR;
}
if(!WriteProcessMemory(fdProcessInfo->hProcess, DLLNameMem, argv[1], strlen(argv[1]), NULL))
{
dprintf("Error: couldn't write process memory");
return STATUS_ERROR;
}
int size = 0;
int counter = 0;
uint LoadLibraryA = 0;
char command[50] = "";
char error[256] = "";
backupctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(fdProcessInfo->hThread, &backupctx);
valfromstring("kernel32:LoadLibraryA", &LoadLibraryA, false);
// Arch specific asm code
#ifdef _WIN64
sprintf(command, "mov rcx, "fhex, DLLNameMem);
#else
sprintf(command, "push "fhex, DLLNameMem);
#endif // _WIN64
assembleat((uint)ASMAddr, command, &size, error, true);
counter += size;
sprintf(command, "call "fhex, LoadLibraryA);
assembleat((uint)ASMAddr + counter, command, &size, error, true);
counter += size;
SetContextDataEx(fdProcessInfo->hThread, UE_CIP, (uint)ASMAddr);
SetBPX((uint)ASMAddr + counter, UE_SINGLESHOOT | UE_BREAKPOINT_TYPE_INT3, (void*)cbLoadLibBPX);
unlock(WAITID_RUN);
return STATUS_CONTINUE;
}
void cbLoadLibBPX()
{
uint LibAddr = 0;
#ifdef _WIN64
LibAddr = GetContextDataEx(fdProcessInfo->hThread, UE_RAX);
#else
LibAddr = GetContextDataEx(fdProcessInfo->hThread, UE_EAX);
#endif
varset("$result", LibAddr, false);
SetThreadContext(fdProcessInfo->hThread, &backupctx);
VirtualFreeEx(fdProcessInfo->hProcess, DLLNameMem, 0, MEM_RELEASE);
VirtualFreeEx(fdProcessInfo->hProcess, ASMAddr, 0, MEM_RELEASE);
//update GUI
GuiSetDebugState(paused);
DebugUpdateGui(GetContextDataEx(hActiveThread, UE_CIP), true);
//lock
lock(WAITID_RUN);
SetForegroundWindow(GuiGetWindowHandle());
PLUG_CB_PAUSEDEBUG pauseInfo;
pauseInfo.reserved = 0;
plugincbcall(CB_PAUSEDEBUG, &pauseInfo);
wait(WAITID_RUN);
}
void showcommandlineerror(cmdline_error_t* cmdline_error)
{
bool unkown = false;
@ -1868,4 +1951,4 @@ CMDRESULT cbDebugSetCmdline(int argc, char* argv[])
dprintf("New command line: %s\n", argv[1]);
return STATUS_CONTINUE;
}
}

View File

@ -53,6 +53,7 @@ CMDRESULT cbDebugKillthread(int argc, char* argv[]);
CMDRESULT cbDebugSetPriority(int argc, char* argv[]);
CMDRESULT cbDebugGetCmdline(int argc, char* argv[]);
CMDRESULT cbDebugSetCmdline(int argc, char* argv[]);
CMDRESULT cbDebugLoadLib(int argc, char* argv[]);
CMDRESULT cbDebugEnableHardwareBreakpoint(int argc, char* argv[]);
CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[]);
CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[]);

View File

@ -82,6 +82,7 @@ static void registercommands()
dbgcmdnew("setjitauto\1jitsetauto", cbDebugSetJITAuto, false); //set JIT Auto
dbgcmdnew("getcmdline\1getcommandline", cbDebugGetCmdline, true); //Get CmdLine
dbgcmdnew("setcmdline\1setcommandline", cbDebugSetCmdline, true); //Set CmdLine
dbgcmdnew("loadlib", cbDebugLoadLib, true); //Load DLL
//breakpoints
dbgcmdnew("bplist", cbDebugBplist, true); //breakpoint list