metasploit-framework/external/source/byakugan/stdwindbg.cpp

329 lines
8.7 KiB
C++

#include <stdio.h>
#include <string.h>
#include "byakugan.h"
#include "stdwindbg.h"
char bypassFalse[] = "\x33\xc0" // xor eax, eax
"\xc2\x08\x00"; // ret 8
struct debugClientNode *headDebugClient = NULL;
detectionCallBack::detectionCallBack() : type(NULL), count(0) {}
HRESULT __stdcall detectionCallBack::QueryInterface(const IID & iid, PVOID * ref) {
*ref = NULL;
if (iid == __uuidof(IDebugEventCallbacks))
*ref = this;
else if (iid == __uuidof(IUnknown))
*ref = static_cast<IUnknown *>(this);
else
return E_NOINTERFACE;
return S_OK;
}
ULONG __stdcall detectionCallBack::AddRef(void) {
return InterlockedIncrement(&count);
}
ULONG __stdcall detectionCallBack::Release(void) {
ULONG c = InterlockedDecrement(&count);
if (c == 0)
delete this;
return c;
}
HRESULT __stdcall detectionCallBack::Breakpoint(PDEBUG_BREAKPOINT bp) {
typeNode *detected = type;
ULONG bpid;
dprintf("CAUGHT A BP\n");
bp->GetId(&bpid);
while (detected != NULL && detected->bpid != bpid)
detected = detected->next;
if (detected == NULL) // Not one of ours.
return (DEBUG_STATUS_BREAK);
dprintf("[Mushishi] Detected %s anti-debugging technique.\n", detected->name);
return (DEBUG_STATUS_BREAK);
//return (DEBUG_STATUS_BREAK);
}
HRESULT __stdcall detectionCallBack::GetInterestMask(PULONG mask) {
if (mask != NULL)
*mask = DEBUG_EVENT_BREAKPOINT;
return (S_OK);
}
HRESULT __stdcall detectionCallBack::Exception(PEXCEPTION_RECORD64 exception, ULONG firstChance) {
return E_NOTIMPL;
}
HRESULT __stdcall detectionCallBack::CreateThread(ULONG64 handle, ULONG64 dataOffset, ULONG64 startOffset) {
return E_NOTIMPL;
}
HRESULT __stdcall detectionCallBack::ExitThread(ULONG exitCode) {
return E_NOTIMPL;
}
HRESULT __stdcall detectionCallBack::CreateProcess(
ULONG64 imageFileHandle,
ULONG64 handle,
ULONG64 baseOffset,
ULONG moduleSize,
PCSTR moduleName,
PCSTR imageName,
ULONG checkSum,
ULONG timeDateStamp,
ULONG64 initialThreadHandle,
ULONG64 threadDataOffset,
ULONG64 startOffset) {
return E_NOTIMPL;
}
HRESULT __stdcall detectionCallBack::ExitProcess(ULONG exitCode) {
return E_NOTIMPL;
}
HRESULT __stdcall detectionCallBack::LoadModule(
ULONG64 imageFileHandle,
ULONG64 baseOffset,
ULONG moduleSize,
PCSTR moduleName,
PCSTR imageName,
ULONG checkSum,
ULONG timeDateStamp) {
return E_NOTIMPL;
}
HRESULT __stdcall detectionCallBack::UnloadModule(PCSTR imageBaseName, ULONG64 baseOffset) {
return E_NOTIMPL;
}
HRESULT __stdcall detectionCallBack::SystemError(ULONG error, ULONG level) {
return E_NOTIMPL;
}
HRESULT __stdcall detectionCallBack::SessionStatus(ULONG status) {
return E_NOTIMPL;
}
HRESULT __stdcall detectionCallBack::ChangeDebuggeeState(ULONG flags, ULONG64 argument) {
return E_NOTIMPL;
}
HRESULT __stdcall detectionCallBack::ChangeEngineState(ULONG flags, ULONG64 argument) {
return E_NOTIMPL;
}
HRESULT __stdcall detectionCallBack::ChangeSymbolState(ULONG flags, ULONG64 argument) {
return E_NOTIMPL;
}
void detectionCallBack::addType(ULONG bpid, char *name) {
typeNode *curr, *newType;
newType = (typeNode *) malloc(sizeof (typeNode));
if (newType == NULL)
return;
newType->bpid = bpid;
newType->name = (char *) malloc(strlen(name) + 2);
if (newType->name == NULL) {
free(newType);
return;
}
strncpy(newType->name, name, strlen(name));
newType->next = type;
type = newType;
}
void detectionCallBack::recTypeNuke(typeNode *type) {
if (type == NULL)
return;
recTypeNuke(type->next);
free(type->name);
free(type);
}
detectionCallBack::~detectionCallBack() {
recTypeNuke(type);
}
struct debugClientNode *addDebugClient(void) {
#if 0
struct debugClientNode *newNode, *cur;
newNode = (struct debugClientNode *) malloc(sizeof(struct debugClientNode));
if (newNode == NULL)
return (newNode);
g_ExtClient->CreateClient(&(newNode->debugClient));
newNode->dcb = new detectionCallBack;
if (headDebugClient == NULL)
headDebugClient = newNode;
else {
cur = headDebugClient;
while (cur->next != NULL)
cur = cur->next;
cur->next = newNode;
}
#endif
if (headDebugClient == NULL) {
headDebugClient = (struct debugClientNode *) malloc(sizeof(struct debugClientNode));
g_ExtClient->CreateClient(&(headDebugClient->debugClient));
headDebugClient->dcb = new detectionCallBack;
}
return (headDebugClient);
}
// Take a function name, resolve it, and replace the first 5 bytes with
// a bypass that returns false.
BOOL disableFunctionFalse(char *funcName) {
ULONG64 funcAddr64;
if ((funcAddr64 = resolveFunctionByName(funcName)) == NULL)
return (FALSE);
g_ExtData->WriteVirtual(funcAddr64, (PVOID) bypassFalse, 5, NULL);
return (TRUE);
}
ULONG64 resolveFunctionByName(char *funcName) {
ULONG64 funcAddr64;
g_ExtSymbols->Reload("/f kernel32.dll");
if (g_ExtSymbols->GetOffsetByName(funcName, &funcAddr64) == E_FAIL)
funcAddr64 = NULL;
if (funcAddr64 != NULL)
dprintf("[Byakugan] Resolved function '%s' @ 0x%16x.\n", funcName, funcAddr64);
else {
dprintf("[Byakugan] Unable to resolve function '%s' :(\n", funcName);
return (NULL);
}
return (funcAddr64);
}
BOOL detectCallByName(char *funcName, char *detectionName) {
if (detectExecByAddr(resolveFunctionByName(funcName), detectionName) == NULL)
return (FALSE);
return (TRUE);
}
PDEBUG_BREAKPOINT detectExecByAddr(ULONG64 funcAddr64, char *detectionName) {
HRESULT retCode;
IDebugBreakpoint *bp;
ULONG id;
struct debugClientNode *newDebugClient;
if (funcAddr64 == NULL)
return (NULL);
newDebugClient = addDebugClient();
g_ExtControl->AddBreakpoint(DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &bp);
bp->SetOffset(funcAddr64);
bp->SetFlags(DEBUG_BREAKPOINT_ENABLED|DEBUG_BREAKPOINT_ONE_SHOT);
bp->GetId(&id);
newDebugClient->dcb->addType(id, detectionName);
retCode = newDebugClient->debugClient->SetEventCallbacks(newDebugClient->dcb);
//dprintf("[Mushishi] SetEventCallbacks: 0x%08x\n", retCode);
return (bp);
}
PDEBUG_BREAKPOINT detectWriteByAddr(ULONG64 funcAddr64, char *detectionName) {
HRESULT retCode;
IDebugBreakpoint *bp;
ULONG id;
struct debugClientNode *newDebugClient;
if (funcAddr64 == NULL)
return (NULL);
newDebugClient = addDebugClient();
g_ExtControl->AddBreakpoint(DEBUG_BREAKPOINT_DATA, DEBUG_ANY_ID, &bp);
bp->SetOffset(funcAddr64);
bp->SetDataParameters(4, DEBUG_BREAK_WRITE);
bp->SetFlags(DEBUG_BREAKPOINT_ENABLED);
bp->GetId(&id);
newDebugClient->dcb->addType(id, detectionName);
retCode = newDebugClient->debugClient->SetEventCallbacks(newDebugClient->dcb);
//dprintf("[Mushishi] SetEventCallbacks: 0x%08x\n", retCode);
return (bp);
}
PDEBUG_BREAKPOINT detectReadByAddr(ULONG64 funcAddr64, char *detectionName) {
HRESULT retCode;
IDebugBreakpoint *bp;
ULONG id;
struct debugClientNode *newDebugClient;
if (funcAddr64 == NULL)
return (NULL);
newDebugClient = addDebugClient();
g_ExtControl->AddBreakpoint(DEBUG_BREAKPOINT_DATA, DEBUG_ANY_ID, &bp);
bp->SetOffset(funcAddr64);
bp->SetDataParameters(4, DEBUG_BREAK_READ);
bp->SetFlags(DEBUG_BREAKPOINT_ENABLED);
bp->GetId(&id);
newDebugClient->dcb->addType(id, detectionName);
retCode = newDebugClient->debugClient->SetEventCallbacks(newDebugClient->dcb);
//dprintf("[Mushishi] SetEventCallbacks: 0x%08x\n", retCode);
return (bp);
}
DWORD parseHexInput(char *hexInput, DWORD size, char *output) {
return (0);
}
DWORD readFileIntoBuf(char *path, DWORD size, char **output, DWORD offset) {
HANDLE inputFile;
DWORD readOut = 1, i = 0;
char out;
BYTE state = 0;
if((inputFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) {
dprintf("[S] Unable to open file: %s\n", path);
return (0);
}
if (size == 0)
size = GetFileSize(inputFile, NULL) - 1;
*output = (char *) malloc(size + 1);
if (!*output) {
dprintf("[S] Unable to allocate memory for %s\n", path);
return (0);
}
if(offset == 0) {
while (readOut > 0 && i < size) {
ReadFile(inputFile, &out, 1, &readOut, NULL);
(*output)[i++] = out;
}
}
else {
if(SetFilePointer(inputFile,offset, NULL,FILE_BEGIN) == INVALID_SET_FILE_POINTER ){
dprintf("[S] Unable to read at offset %d for %s\n", offset, path);
return (0);
}
while (readOut > 0 && i < size) {
ReadFile(inputFile, &out, 1, &readOut, NULL);
(*output)[i++] = out;
}
}
return (i);
}