1
0
Fork 0

DBG: fixed up the loadlib and freelib functions

This commit is contained in:
mrexodia 2017-06-06 23:58:24 +02:00
parent 39b66f3b0f
commit 8ba0580626
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
3 changed files with 88 additions and 81 deletions

View File

@ -81,7 +81,6 @@ bool apienumimports(duint base, const IMPORTENUMCALLBACK & cbEnum)
bool readSuccess; bool readSuccess;
Memory<char*> importName(MAX_IMPORT_SIZE + 1, "apienumimports:buffer"); Memory<char*> importName(MAX_IMPORT_SIZE + 1, "apienumimports:buffer");
char importModuleName[MAX_MODULE_SIZE + 1] = ""; char importModuleName[MAX_MODULE_SIZE + 1] = "";
duint regionSize;
PIMAGE_IMPORT_DESCRIPTOR importTableVa; PIMAGE_IMPORT_DESCRIPTOR importTableVa;
IMAGE_IMPORT_DESCRIPTOR importDescriptor; IMAGE_IMPORT_DESCRIPTOR importDescriptor;
PIMAGE_THUNK_DATA imageIATVa, imageINTVa; PIMAGE_THUNK_DATA imageIATVa, imageINTVa;

View File

@ -191,7 +191,7 @@ static bool isInstructionPointingToExMemory(duint addr, const unsigned char* des
bool assembleat(duint addr, const char* instruction, int* size, char* error, bool fillnop) bool assembleat(duint addr, const char* instruction, int* size, char* error, bool fillnop)
{ {
int destSize; int destSize = 0;
Memory<unsigned char*> dest(16 * sizeof(unsigned char), "AssembleBuffer"); Memory<unsigned char*> dest(16 * sizeof(unsigned char), "AssembleBuffer");
unsigned char* newbuffer = nullptr; unsigned char* newbuffer = nullptr;
if(!assemble(addr, dest(), 16, &destSize, instruction, error)) if(!assemble(addr, dest(), 16, &destSize, instruction, error))
@ -200,11 +200,12 @@ bool assembleat(duint addr, const char* instruction, int* size, char* error, boo
{ {
dest.realloc(destSize); dest.realloc(destSize);
if(!assemble(addr, dest(), destSize, &destSize, instruction, error)) if(!assemble(addr, dest(), destSize, &destSize, instruction, error))
{
return false; return false;
}
} }
else
return false;
} }
//calculate the number of NOPs to insert //calculate the number of NOPs to insert
int origLen = disasmgetsize(addr); int origLen = disasmgetsize(addr);
while(origLen < destSize) while(origLen < destSize)

View File

@ -87,69 +87,72 @@ bool cbDebugLoadLib(int argc, char* argv[])
return false; return false;
} }
unsigned char loader[] =
#ifdef _WIN64
{
0x48, 0xB9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //movabs rcx, DLLNameAddr
0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //movabs rax, p_LoadLibraryW
0xFF, 0xD0, //call rax
0x90 //nop
};
#else
{
0x68, 0xFF, 0xFF, 0xFF, 0xFF, //push DLLNameMem
0xB8, 0xFF, 0xFF, 0xFF, 0xFF, //mov eax, p_LoadLibraryW
0xFF, 0xD0, //call eax
0x90 //nop
};
#endif //_WIN64
auto DLLNameOffset = ArchValue(1, 2), LoadLibraryOffset = ArchValue(6, 12);
LoadLibThreadID = fdProcessInfo->dwThreadId; LoadLibThreadID = fdProcessInfo->dwThreadId;
HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID); HANDLE LoadLibThread = ThreadGetHandle((DWORD)LoadLibThreadID);
DLLNameMem = MemAllocRemote(0, strlen(argv[1]) + 1); auto DLLNameW = StringUtils::Utf8ToUtf16(argv[1]);
ASMAddr = MemAllocRemote(0, 0x1000); auto DLLNameSize = (DLLNameW.length() + 1) * 2;
if(!DLLNameMem || !ASMAddr) duint p_LoadLibraryW = 0;
if(!valfromstring("kernel32:LoadLibraryW", &p_LoadLibraryW, false))
{
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't get kernel32:LoadLibraryW"));
return false;
}
ASMAddr = MemAllocRemote(0, sizeof(loader));
DLLNameMem = MemAllocRemote(0, DLLNameSize);
if(!ASMAddr || !DLLNameMem)
{ {
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't allocate memory in debuggee")); dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't allocate memory in debuggee"));
return false; return false;
} }
if(!MemWrite(DLLNameMem, argv[1], strlen(argv[1]))) // Set addresses in the loader
memcpy(loader + DLLNameOffset, &DLLNameMem, sizeof(duint));
memcpy(loader + LoadLibraryOffset, &p_LoadLibraryW, sizeof(duint));
if(!MemWrite(ASMAddr, loader, sizeof(loader)) || !MemWrite(DLLNameMem, DLLNameW.c_str(), DLLNameSize))
{ {
MemFreeRemote(ASMAddr);
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't write process memory")); dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't write process memory"));
return false; return false;
} }
int size = 0; if(!SetBPX(ASMAddr + sizeof(loader) - 1, UE_SINGLESHOOT | UE_BREAKPOINT_TYPE_INT3, (void*)cbDebugLoadLibBPX))
int counter = 0;
duint LoadLibraryA = 0;
char command[50] = "";
char error[MAX_ERROR_SIZE] = "";
GetFullContextDataEx(LoadLibThread, &backupctx);
if(!valfromstring("kernel32:LoadLibraryA", &LoadLibraryA, false))
{ {
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't get kernel32:LoadLibraryA")); MemFreeRemote(ASMAddr);
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't SetBPX"));
return false; return false;
} }
// Arch specific asm code
#ifdef _WIN64
sprintf_s(command, "mov rcx, %p", DLLNameMem);
#else
sprintf_s(command, "push %p", DLLNameMem);
#endif // _WIN64
assembleat(ASMAddr, command, &size, error, true);
counter += size;
#ifdef _WIN64
sprintf_s(command, "mov rax, %p", LoadLibraryA);
assembleat(ASMAddr + counter, command, &size, error, true);
counter += size;
sprintf_s(command, "call rax");
#else
sprintf_s(command, "call %p", LoadLibraryA);
#endif // _WIN64
assembleat(ASMAddr + counter, command, &size, error, true);
counter += size;
SetContextDataEx(LoadLibThread, UE_CIP, ASMAddr);
auto ok = SetBPX(ASMAddr + counter, UE_SINGLESHOOT | UE_BREAKPOINT_TYPE_INT3, (void*)cbDebugLoadLibBPX);
ThreadSuspendAll(); ThreadSuspendAll();
GetFullContextDataEx(LoadLibThread, &backupctx);
SetContextDataEx(LoadLibThread, UE_CIP, ASMAddr);
SetContextDataEx(LoadLibThread, UE_CSP, backupctx.csp & ~0xF);
ResumeThread(LoadLibThread); ResumeThread(LoadLibThread);
unlock(WAITID_RUN); unlock(WAITID_RUN);
return ok; return true;
} }
static void cbDebugFreeLibBPX() static void cbDebugFreeLibBPX()
@ -187,61 +190,65 @@ bool cbDebugFreeLib(int argc, char* argv[])
return false; return false;
} }
unsigned char loader[] =
#ifdef _WIN64
{
0x48, 0xB9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //movabs rcx, ModuleBase
0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //movabs rax, p_FreeLibrary
0xFF, 0xD0, //call rax
0x90 //nop
};
#else
{
0x68, 0xFF, 0xFF, 0xFF, 0xFF, //push ModuleBase
0xB8, 0xFF, 0xFF, 0xFF, 0xFF, //mov eax, p_FreeLibrary
0xFF, 0xD0, //call eax
0x90 //nop
};
#endif //_WIN64
auto ModuleBaseOffset = ArchValue(1, 2), FreeLibraryOffset = ArchValue(6, 12);
FreeLibThreadID = fdProcessInfo->dwThreadId; FreeLibThreadID = fdProcessInfo->dwThreadId;
HANDLE UnLoadLibThread = ThreadGetHandle((DWORD)FreeLibThreadID); HANDLE UnLoadLibThread = ThreadGetHandle((DWORD)FreeLibThreadID);
ASMAddr = MemAllocRemote(0, 0x1000); duint p_FreeLibrary = 0;
if(!valfromstring("kernel32:FreeLibrary", &p_FreeLibrary, false))
{
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't get kernel32:FreeLibrary"));
return false;
}
ASMAddr = MemAllocRemote(0, sizeof(loader));
if(!ASMAddr) if(!ASMAddr)
{ {
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't allocate memory in debuggee")); dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't allocate memory in debuggee"));
return false; return false;
} }
int size = 0; // Set addresses in the loader
int counter = 0; memcpy(loader + ModuleBaseOffset, &base, sizeof(duint));
duint FreeLibrary = 0; memcpy(loader + FreeLibraryOffset, &p_FreeLibrary, sizeof(duint));
char command[50] = "";
char error[MAX_ERROR_SIZE] = "";
GetFullContextDataEx(UnLoadLibThread, &backupctx); if(!MemWrite(ASMAddr, loader, sizeof(loader)))
if(!valfromstring("kernel32:FreeLibrary", &FreeLibrary, false))
{ {
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't get kernel32:FreeLibrary")); MemFreeRemote(ASMAddr);
dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't write process memory"));
return false; return false;
} }
// Arch specific asm code if(!SetBPX(ASMAddr + sizeof(loader) - 1, UE_SINGLESHOOT | UE_BREAKPOINT_TYPE_INT3, (void*)cbDebugFreeLibBPX))
#ifdef _WIN64 {
sprintf_s(command, "mov rcx, %p", base); MemFreeRemote(ASMAddr);
#else dputs(QT_TRANSLATE_NOOP("DBG", "Error: couldn't SetBPX"));
sprintf_s(command, "push %p", base); return false;
#endif // _WIN64 }
assembleat(ASMAddr, command, &size, error, true);
counter += size;
#ifdef _WIN64
sprintf_s(command, "mov rax, %p", FreeLibrary);
assembleat(ASMAddr + counter, command, &size, error, true);
counter += size;
sprintf_s(command, "call rax");
#else
sprintf_s(command, "call %p", FreeLibrary);
#endif // _WIN64
assembleat(ASMAddr + counter, command, &size, error, true);
counter += size;
SetContextDataEx(UnLoadLibThread, UE_CIP, ASMAddr);
auto ok = SetBPX(ASMAddr + counter, UE_SINGLESHOOT | UE_BREAKPOINT_TYPE_INT3, (void*)cbDebugFreeLibBPX);
ThreadSuspendAll(); ThreadSuspendAll();
GetFullContextDataEx(UnLoadLibThread, &backupctx);
SetContextDataEx(UnLoadLibThread, UE_CIP, ASMAddr);
ResumeThread(UnLoadLibThread); ResumeThread(UnLoadLibThread);
unlock(WAITID_RUN); unlock(WAITID_RUN);
return true;
return ok;
} }
bool cbInstrAssemble(int argc, char* argv[]) bool cbInstrAssemble(int argc, char* argv[])