(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:
parent
e406019b60
commit
2aac3c2de9
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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[]);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue