Skip to content

Commit

Permalink
some intel fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
cheat-engine committed Mar 23, 2021
1 parent e65f367 commit 3a626d0
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 28 deletions.
23 changes: 20 additions & 3 deletions dbvm/vmm/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ multiple sources. (e.g vmm and vmloader)

//#include <string.h>

#ifdef DEBUG
void sendstringf_nolock(char *string UNUSED, ...);
#endif

QWORD textmemory=0x0b8000;

QWORD spinlocktimeout=0;
Expand Down Expand Up @@ -81,7 +85,7 @@ void outportb(unsigned int port,unsigned char value)
if (port==0x80)
{
nosendchar[getAPICID()]=0;
sendstringf(" - Debug Code %2 -\n", value);
sendstringf_nolock(" - Debug Code %2 -\n", value);
}
asm volatile ("outb %%al,%%dx": :"d" (port), "a" (value));
}
Expand Down Expand Up @@ -1165,6 +1169,8 @@ void csLeave(PcriticalSection CS)
#endif

int apicid=getAPICID()+1; //+1 so it never returns 0
int locked=CS->locked;
int ownerAPICID=CS->apicid;


if ((CS->locked) && (CS->apicid==apicid))
Expand All @@ -1183,9 +1189,20 @@ void csLeave(PcriticalSection CS)
else
{
nosendchar[getAPICID()]=0;
sendstringf("csLeave called for a non-locked or non-owned critical section\n");
sendstringf_nolock("csLeave called for a non-locked or non-owned critical section. Name=%s\n", CS->name);
ddDrawRectangle(0,DDVerticalResolution-100,100,100,0xff0000);
while (1) outportb(0x80,0xc2);
while (1)
{
outportb(0x80,0xc2);
if (locked)
{
outportb(0x80,0xc3);
}
if (ownerAPICID!=apicid)
{
outportb(0x80,0xc4);
}
}
}
}

Expand Down
49 changes: 38 additions & 11 deletions dbvm/vmm/epthandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,14 +1230,17 @@ BOOL ept_handleFrozenThread(pcpuinfo currentcpuinfo, VMRegisters *vmregisters, F
int result=TRUE;
RFLAGS v;
v.value=BrokenThreadList[id].state.basic.FLAGS;
//sendstringf("ept_handleFrozenThread\n");
QWORD RIP=isAMD?currentcpuinfo->vmcb->RIP:vmread(vm_guest_rip);

nosendchar[getAPICID()]=0;
//sendstringf("ept_handleFrozenThread: RIP=%6\n",RIP);

BrokenThreadList[id].state.basic.Count++;//heartbeat to show it's still triggering the BP
if (BrokenThreadList[id].continueMethod)
{
nosendchar[getAPICID()]=0;
sendstringf("continueMethod is not 0\n");

v.RF=1; //tell the watch handler to skip this if it returns at the same spot again



Expand All @@ -1247,13 +1250,16 @@ BOOL ept_handleFrozenThread(pcpuinfo currentcpuinfo, VMRegisters *vmregisters, F
currentcpuinfo->vmcb->RIP=BrokenThreadList[id].state.basic.RIP;
currentcpuinfo->vmcb->RAX=BrokenThreadList[id].state.basic.RAX;
currentcpuinfo->vmcb->RSP=BrokenThreadList[id].state.basic.RSP;

v.RF=1; //tell the watch handler to skip this if it returns at the same spot again
currentcpuinfo->vmcb->RFLAGS=v.value;
}
else
{
vmwrite(vm_guest_rip,BrokenThreadList[id].state.basic.RIP);
vmwrite(vm_guest_rsp, BrokenThreadList[id].state.basic.RSP);
vmwrite(vm_guest_rflags, v.value);

vmwrite(vm_guest_interruptability_state,1); //tell the watch handler to skip this if it returns at the same spot again
}
vmregisters->rbx=BrokenThreadList[id].state.basic.RBX;
vmregisters->rcx=BrokenThreadList[id].state.basic.RCX;
Expand Down Expand Up @@ -1305,7 +1311,7 @@ BOOL ept_handleFrozenThread(pcpuinfo currentcpuinfo, VMRegisters *vmregisters, F
}
else
{
vmwrite(vm_guest_interruptability_state,1); //pop ss state
vmwrite(vm_guest_interruptability_state,1); //blocking by sti
}


Expand All @@ -1314,12 +1320,14 @@ BOOL ept_handleFrozenThread(pcpuinfo currentcpuinfo, VMRegisters *vmregisters, F
}
else
{
RFLAGS v2;
v2.value=currentcpuinfo->vmcb->RFLAGS;
//RFLAGS v2;
//v2.value=currentcpuinfo->vmcb->RFLAGS;

//sendstringf("%d: Still frozen at %6 CR8=%x stored: IF=%d RF=%d current: IF=%d rd=%d INTERRUPT_SHADOW=%d EFER=%x FMASK=%x\n", currentcpuinfo->cpunr, BrokenThreadList[id].state.basic.RIP, getCR8(), v.IF, v.RF, v2.IF, v2.RF, currentcpuinfo->vmcb->INTERRUPT_SHADOW,
// currentcpuinfo->vmcb->EFER,
// currentcpuinfo->vmcb->SFMASK);


sendstringf("%d: Still frozen at %6 CR8=%x stored: IF=%d RF=%d current: IF=%d rd=%d INTERRUPT_SHADOW=%d EFER=%x FMASK=%x\n", currentcpuinfo->cpunr, BrokenThreadList[id].state.basic.RIP, getCR8(), v.IF, v.RF, v2.IF, v2.RF, currentcpuinfo->vmcb->INTERRUPT_SHADOW,
currentcpuinfo->vmcb->EFER,
currentcpuinfo->vmcb->SFMASK);
}

return result;
Expand Down Expand Up @@ -2242,10 +2250,24 @@ BOOL ept_handleWatchEvent(pcpuinfo currentcpuinfo, VMRegisters *registers, PFXSA
DWORD CR8=getCR8();
RFLAGS flags;
flags.value=isAMD?currentcpuinfo->vmcb->RFLAGS:vmread(vm_guest_rflags);
sendstringf("CR8=%6 IF=%d RF=%d\n", CR8,flags.IF,flags.RF);
int is;
int canBreak=(CR8==0) && (flags.IF); //interruptable with no mask (on windows called passive mode)

if (isAMD)
{
sendstringf("CR8=%6 IF=%d RF=%d\n", CR8,flags.IF,flags.RF);
canBreak=canBreak && (flags.RF==0); //on AMD I use the TF flag to skip over dbvmbp watches
}
else
{
is=vmread(vm_guest_interruptability_state);
sendstringf("CR8=%6 IF=%d RF=%d Interruptibility state=%d\n", CR8,flags.IF,flags.RF, is);
canBreak=canBreak && ((is & (1<<0))==0); //on Intel I use the block by sti interruptability state to flag a skip (probably can't use the pop ss as it's used by the single step handler. But should test)
}

sendstringf("canBreak=%d\n", canBreak);

if ((CR8==0) && (flags.IF) && (flags.RF==0)) //if interruptable with no mask (on windows called passive mode)
if (canBreak)
{
int kernelmode=0;
if (isAMD)
Expand Down Expand Up @@ -4172,6 +4194,11 @@ VMSTATUS handleEPTViolation(pcpuinfo currentcpuinfo, VMRegisters *vmregisters UN
vmwrite(vm_entry_interruptioninfo, newintinfo.interruption_information); //entry info field
vmwrite(vm_entry_instructionlength, vmread(vm_exit_instructionlength)); //entry instruction length
}
else
{
//problem: on intel this will set RF to 1. So the handleWatchEvent cannot distinguish a resuming dbvmbp
//solution: use a "skip next watchevent" for this cpu
}

//vi.ExitQualification=vmread(vm_exit_qualification);

Expand Down
5 changes: 3 additions & 2 deletions dbvm/vmm/vmeventhandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -3714,7 +3714,8 @@ BOOL handleHardwareBreakpoint(pcpuinfo currentcpuinfo, VMRegisters *vmregisters,
BOOL handleSoftwareBreakpoint(pcpuinfo currentcpuinfo, VMRegisters *vmregisters, FXSAVE64 *fxsave)
{
//handle specialized software breakpoints
sendstringf("Software breakpoint\n");
nosendchar[getAPICID()]=0;
//sendstringf("Software breakpoint\n");
if (hasEPTsupport || hasNPsupport)
{
if (ept_handleSoftwareBreakpoint(currentcpuinfo, vmregisters, fxsave))
Expand Down Expand Up @@ -4056,7 +4057,7 @@ int handleVMEvent_internal(pcpuinfo currentcpuinfo, VMRegisters *vmregisters, FX

result=handleInterrupt(currentcpuinfo, vmregisters, fxsave);

sendstringf("handleInterrupt returned %d", result);
//sendstringf("handleInterrupt returned %d", result);

return result;
}
Expand Down
20 changes: 8 additions & 12 deletions dbvm/vmm/vmmhelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ int twister=0;
#if DISPLAYDEBUG==1
int verbosity=10;
#else
int verbosity=1;
int verbosity=0;
#endif
int rotations=0;
int cpu2=0; //debug to stop cpu1 when cpu2 is spawned
Expand Down Expand Up @@ -1390,11 +1390,6 @@ int vmexit(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
return raiseNMI();
}

if (currentcpuinfo->cpunr)
{
sendstring("cpunr!=0");
}

if ((result==0) || ((result >> 8)==0xce))
{
if (debugmode)
Expand Down Expand Up @@ -1422,17 +1417,11 @@ int vmexit(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
}
*/

if (currentcpuinfo->cpunr)
{
sendstring("cpunr!=0");
}

enableserial();
sendstringf("\n\r------------(%d)------------------\n\r",vmeventcount);
sendstringf("Hello from vmexit-(cpunr=%d)",currentcpuinfo->cpunr);



sendstringf("currentcpuinfo = %6 : APICID=%d : RSP=%6\n\r",(UINT64)currentcpuinfo, getAPICID(), getRSP());

sendstringf("VM error code=%x\n\r",vmread(vm_errorcode));
Expand All @@ -1457,6 +1446,13 @@ int vmexit(pcpuinfo currentcpuinfo, UINT64 *registers, void *fxsave)
sendstringf("Guest linear address=%6\n\r",vmread(vm_guest_linear_address));
sendstringf("Guest physical address=%6\n\r",vmread(vm_guest_physical_address));

RFLAGS rflags;
rflags.value=vmread(vm_guest_rflags);

sendstringf("rflags=%x (IF=%d TF=%d RF=%d)\n",rflags.value, rflags.IF, rflags.TF, rflags.RF);



sendstringf("csbase=%6\n",vmread(vm_guest_cs_base));
sendstringf("rip=%6\n",vmread(vm_guest_rip));

Expand Down

0 comments on commit 3a626d0

Please sign in to comment.