Skip to content

Commit

Permalink
Move the threadstate to a backup before enabling interrupts, and fix …
Browse files Browse the repository at this point in the history
…showing the xmm state, and implement writing to xmm
  • Loading branch information
cheat-engine committed Nov 18, 2020
1 parent dcbc8c3 commit d8b3574
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 15 deletions.
2 changes: 2 additions & 0 deletions DBKKernel/DBKDrvr.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,8 @@ void UnloadDriver(PDRIVER_OBJECT DriverObject)
return; //
}

debugger_shutdown();

ultimap_disable();
DisableUltimap2();
UnregisterUltimapPMI();
Expand Down
150 changes: 135 additions & 15 deletions DBKKernel/debugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ volatile struct

char b[1];

volatile BYTE DECLSPEC_ALIGN(16) fxstate[512];
//volatile BYTE DECLSPEC_ALIGN(16) fxstate[512];

BOOL isSteppingTillClear; //when set the user has entered single stepping mode. This is a one thread only thing, so when it's active and another single step happens, discard it

Expand All @@ -80,6 +80,17 @@ JUMPBACK Int1JumpBackLocation;



typedef struct _SavedStack
{
BOOL inuse;
QWORD stacksnapshot[600];
} SavedStack, *PSavedStack;

criticalSection StacksCS;
int StackCount;
PSavedStack *Stacks;



void debugger_dr7_setGD(int state)
{
Expand Down Expand Up @@ -191,6 +202,71 @@ void debugger_initialize(void)

//DbgPrint("DebuggerState.fxstate=%p\n",DebuggerState.fxstate);



StackCount = getCpuCount() * 4;
Stacks = (PSavedStack*)ExAllocatePool(NonPagedPool, StackCount*sizeof(PSavedStack));


int i;
for (i = 0; i < StackCount; i++)
{
Stacks[i] = (PSavedStack)ExAllocatePool(NonPagedPool, sizeof(SavedStack));
RtlZeroMemory(Stacks[i], sizeof(SavedStack));
}
}

void debugger_shutdown(void)
{
if (Stacks)
{
int i;
for (i = 0; i < StackCount; i++)
{
if (Stacks[i])
{
ExFreePool(Stacks[i]);
Stacks[i] = NULL;
}
}

ExFreePool(Stacks);
Stacks = NULL;
}
}

void debugger_growstack()
//only call when the critical section has been obtained
{
if (Stacks)
{
int newStackCount = StackCount * 2;
int i;
PSavedStack *newStacks;
newStacks = (PSavedStack*)ExAllocatePool(NonPagedPool, newStackCount * sizeof(PSavedStack));

if (newStacks)
{
for (i = 0; i < StackCount; i++)
newStacks[i] = Stacks[i];

for (i = StackCount; i < newStackCount; i++)
{
newStacks[i] = (PSavedStack)ExAllocatePool(NonPagedPool, sizeof(SavedStack));
if (newStacks[i])
RtlZeroMemory(newStacks[i], sizeof(SavedStack));
else
{
ExFreePool(newStacks);
return;
}
}

ExFreePool(Stacks);
Stacks = newStacks;
}

}
}

void debugger_setInitialFakeState(void)
Expand Down Expand Up @@ -469,10 +545,9 @@ NTSTATUS debugger_getDebuggerState(PDebugStackState state)
state->r13=DebuggerState.LastStackPointer[si_r13];
state->r14=DebuggerState.LastStackPointer[si_r14];
state->r15=DebuggerState.LastStackPointer[si_r15];
#endif

#endif

memcpy(state->fxstate, (void *)DebuggerState.fxstate,512);
memcpy(state->fxstate, (void *)&DebuggerState.LastStackPointer[si_xmm],512);


//generally speaking, NOTHING should touch the esp register, but i'll provide it anyhow
Expand All @@ -481,7 +556,6 @@ NTSTATUS debugger_getDebuggerState(PDebugStackState state)
//priv level change, so the stack info was pushed as well
state->rsp=DebuggerState.LastStackPointer[si_esp];
state->ss=DebuggerState.LastStackPointer[si_ss];

}
else
{
Expand Down Expand Up @@ -586,6 +660,8 @@ NTSTATUS debugger_setDebuggerState(PDebugStackState state)
DebuggerState.LastStackPointer[si_r14]=(UINT_PTR)state->r14;
DebuggerState.LastStackPointer[si_r15]=(UINT_PTR)state->r15;
#endif
memcpy((void *)&DebuggerState.LastStackPointer[si_xmm], state->fxstate, 512);


if (!DebuggerState.globalDebug)
{
Expand Down Expand Up @@ -670,14 +746,7 @@ int breakpointHandler_kernel(UINT_PTR *stackpointer, UINT_PTR *currentdebugregs,
DebuggerState.CausedByDBVM = causedbyDBVM;


#ifdef AMD64
//_fxsave(DebuggerState.fxstate);
#else
__asm
{
// fxsave [DebuggerState.fxstate]
}
#endif




Expand Down Expand Up @@ -1258,19 +1327,70 @@ int interrupt1_handler(UINT_PTR *stackpointer, UINT_PTR *currentdebugregs)

//if (1) return 1;

//save the state of the thread to a place that won't get overwritten

//todo: breaks 32-bit
int i;
BOOL NeedsToGrowStackList = FALSE;
UINT_PTR *newStackPointer = NULL;

csEnter(&StacksCS);
for (i = 0; i < StackCount; i++)
{
if (Stacks[i]->inuse == FALSE)
{
Stacks[i]->inuse = TRUE;
newStackPointer = (UINT_PTR *)Stacks[i]->stacksnapshot;

RtlCopyMemory(newStackPointer, stackpointer, 600 * 8);

if (i > StackCount / 2)
NeedsToGrowStackList = TRUE;

break;
}
}

enableInterrupts();

//grow stack if needed
if (NeedsToGrowStackList)
debugger_growstack();

csLeave(&StacksCS);

{
int rs=1;
int rs=1;
int RestoreStack = newStackPointer != NULL;


//DbgPrint("calling breakpointHandler_kernel\n");

if (newStackPointer == NULL) //fuck
newStackPointer = stackpointer;


rs = breakpointHandler_kernel(stackpointer, currentdebugregs, LBR_Stack, causedbyDBVM);
rs = breakpointHandler_kernel(newStackPointer, currentdebugregs, LBR_Stack, causedbyDBVM);
//DbgPrint("After handler\n");

if (RestoreStack) //restore the stack
{
RtlCopyMemory(stackpointer, newStackPointer, 600 * 8);

csEnter(&StacksCS);
Stacks[i]->inuse = FALSE;
csLeave(&StacksCS);
}



//DbgPrint("rs=%d\n",rs);


disableInterrupts();

//restore the


//we might be on a different CPU now
if (DebuggerState.globalDebug)
Expand Down
1 change: 1 addition & 0 deletions DBKKernel/debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ typedef enum {bt_OnInstruction=0,bt_OnWrites=1, bt_OnIOAccess=2, bt_OnReadsAndWr
typedef enum {bl_1byte=0, bl_2byte=1, bl_8byte=2/*Only when in 64-bit*/, bl_4byte=3} BreakLength;

void debugger_initialize(void);
void debugger_shutdown(void);
int debugger_initHookForCurrentCPU(void);
int debugger_setGlobalDebugState(BOOL state);
void debugger_setStoreLBR(BOOL state);
Expand Down

0 comments on commit d8b3574

Please sign in to comment.