Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
cheat-engine committed Jun 13, 2020
2 parents 8dcacfd + 1f38a3f commit 4418a0e
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 47 deletions.
4 changes: 2 additions & 2 deletions dbvm/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#SERIALPORT is the port to communicate with the debugger, usually 0x3f8, on db's system it's 0xef00
SERIALPORT=0 #release/no serialport build
#SERIALPORT=0x3f8 #bochs and jtagged gigabyte test system
#SERIALPORT=0 #release/no serialport build
SERIALPORT=0x3f8 #bochs and jtagged gigabyte test system
#SERIALPORT=0xbf00 #intel
#SERIALPORT=0xec00 #amd
#SERIALPORT=0xd010 #16 core test system
Expand Down
76 changes: 47 additions & 29 deletions dbvm/vmm/epthandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,16 +165,36 @@ BOOL ept_handleCloakEvent(pcpuinfo currentcpuinfo, QWORD Address, QWORD AddressV
{

cloakdata=currentcpuinfo->NP_Cloak.ActiveRegion;
sendstring("Inside a cloaked region using mode 1 and an execute fault happened");
sendstringf("Inside a cloaked region using mode 1 (which started in %6) and an execute fault happened (CS:RIP=%x:%6)\n", currentcpuinfo->NP_Cloak.LastCloakedVirtualBase, currentcpuinfo->vmcb->cs_selector, currentcpuinfo->vmcb->RIP);

//means we exited the cloaked page
//means we exited the cloaked page (or at the page boundary)
csEnter(&CloakedPagesCS);
NPMode1CloakSetState(currentcpuinfo, 0); //marks all pages back as executable and the stealthed page(s) back as no execute
csLeave(&CloakedPagesCS);

currentcpuinfo->NP_Cloak.ActiveRegion=NULL;
//check if it's a page boundary
// QWORD currentexecbase=currentcpuinfo->vmcb->RIP & 0xffffffffffff000ULL;

if (((currentcpuinfo->vmcb->RIP<currentcpuinfo->NP_Cloak.LastCloakedVirtualBase) &&
((currentcpuinfo->vmcb->RIP+32)>=currentcpuinfo->NP_Cloak.LastCloakedVirtualBase))
||
((currentcpuinfo->vmcb->RIP>=currentcpuinfo->NP_Cloak.LastCloakedVirtualBase+4096) &&
(currentcpuinfo->vmcb->RIP<=currentcpuinfo->NP_Cloak.LastCloakedVirtualBase+4096+32)))
{
sendstringf("Pageboundary. Do a single step with the cloaked page decloaked\n");

//page boundary. Do a single step with the cloaked page executable
*(QWORD *)(cloakdata->npentry[currentcpuinfo->cpunr])=cloakdata->PhysicalAddressExecutable;
cloakdata->npentry[currentcpuinfo->cpunr]->P=1;
cloakdata->npentry[currentcpuinfo->cpunr]->RW=1;
cloakdata->npentry[currentcpuinfo->cpunr]->US=1;
cloakdata->npentry[currentcpuinfo->cpunr]->EXB=0;

vmx_enableSingleStepMode();
vmx_addSingleSteppingReasonEx(currentcpuinfo, 2,cloakdata);
}

currentcpuinfo->NP_Cloak.ActiveRegion=NULL;
ept_invalidate();


Expand All @@ -195,12 +215,12 @@ BOOL ept_handleCloakEvent(pcpuinfo currentcpuinfo, QWORD Address, QWORD AddressV


//it's a cloaked page
sendstringf("ept_handleCloakEvent on the target\n");
sendstringf("ept_handleCloakEvent on the target(CS:RIP=%x:%6)\n", currentcpuinfo->vmcb->cs_selector, currentcpuinfo->vmcb->RIP);

if (isAMD)
{
//AMD handling
//swap the page and make it executable, do one step, and restore back to non-executable
//swap the page and make it executable,
*(QWORD *)(cloakdata->npentry[currentcpuinfo->cpunr])=cloakdata->PhysicalAddressExecutable;
cloakdata->npentry[currentcpuinfo->cpunr]->P=1;
cloakdata->npentry[currentcpuinfo->cpunr]->RW=1;
Expand All @@ -209,32 +229,16 @@ BOOL ept_handleCloakEvent(pcpuinfo currentcpuinfo, QWORD Address, QWORD AddressV

if (cloakdata->CloakMode==0)
{
//do one step, and restore back to non-executable
vmx_enableSingleStepMode();
vmx_addSingleSteppingReasonEx(currentcpuinfo, 2,cloakdata);
}
else
{
//mark all pages as no execute except this one (and any potential still waiting to step cloak events)

//check if it's a page boundary
QWORD codeVA=currentcpuinfo->vmcb->cs_base+currentcpuinfo->vmcb->RIP;
int notpaged;
QWORD codePA=getPhysicalAddressVM(currentcpuinfo,codeVA, &notpaged);
if ((notpaged==0) && ((codePA & MAXPHYADDRMASKPB)!=BaseAddress)) //should be the case 100% of the time
{
//page boundary, do a single step
vmx_enableSingleStepMode();
vmx_addSingleSteppingReasonEx(currentcpuinfo, 2,cloakdata);
}
else
{
//inside the cloaked region
//add this to the active cloaked pages
currentcpuinfo->NP_Cloak.ActiveRegion=cloakdata;

NPMode1CloakSetState(currentcpuinfo, 1);
}

currentcpuinfo->NP_Cloak.ActiveRegion=cloakdata;
currentcpuinfo->NP_Cloak.LastCloakedVirtualBase=currentcpuinfo->vmcb->RIP & 0xffffffffffff000ULL;
NPMode1CloakSetState(currentcpuinfo, 1);
}

}
Expand Down Expand Up @@ -441,6 +445,8 @@ int ept_cloak_activate(QWORD physicalAddress, int mode)
cloakdata->Data=malloc(4096);

copymem(cloakdata->Data, cloakdata->Executable, 4096);


cloakdata->PhysicalAddressExecutable=physicalAddress;
cloakdata->PhysicalAddressData=VirtualToPhysical(cloakdata->Data);

Expand Down Expand Up @@ -495,13 +501,16 @@ int ept_cloak_activate(QWORD physicalAddress, int mode)

if (isAMD)
{
//Make it non-executable
_PTE_PAE temp=*(PPTE_PAE)(cloakdata->eptentry[cpunr]);
temp.EXB=1; //disable execute
//Make it non-executable, and make the data read be the fake data
_PTE_PAE temp;
temp=*((PPTE_PAE)&cloakdata->PhysicalAddressData); // *(PPTE_PAE)(cloakdata->eptentry[cpunr]);

temp.P=1;
temp.RW=1;
temp.US=1;
temp.EXB=1; //disable execute

*(PPTE_PAE)(cloakdata->eptentry[cpunr])=temp;

}
else
{
Expand Down Expand Up @@ -670,6 +679,9 @@ int ept_cloak_writeOriginal(pcpuinfo currentcpuinfo, VMRegisters *registers, QW
int error;
physicalAddress=physicalAddress & MAXPHYADDRMASKPB;

nosendchar[getAPICID()]=0;
sendstring("ept_cloak_writeOriginal");

QWORD pagefault;

void *src=mapVMmemory(currentcpuinfo, source, 4096,&error, &pagefault);
Expand All @@ -688,6 +700,12 @@ int ept_cloak_writeOriginal(pcpuinfo currentcpuinfo, VMRegisters *registers, QW
if (cloakdata)
{
void *dest=mapPhysicalMemory(cloakdata->PhysicalAddressExecutable, 4096);

sendstringf("cloakdata->PhysicalAddressExecutable=%6\n", cloakdata->PhysicalAddressExecutable);
sendstringf("cloakdata->PhysicalAddressData=%6\n", cloakdata->PhysicalAddressData);


sendstringf("Writing to PA %6\n", cloakdata->PhysicalAddressExecutable);
copymem(dest,src,4096);
registers->rax=0;

Expand Down
6 changes: 1 addition & 5 deletions dbvm/vmm/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1178,17 +1178,14 @@ void menu2(void)
displayline("e: efer test\n");
displayline("o: out of memory test\n");

#ifdef DEBUG
if (getDBVMVersion())
{
displayline("w: DBVM write watch test\n");
displayline("r: DBVM write read/write test\n");
displayline("x: DBVM write execute test\n");
displayline("c: DBVM cloak test\n");
displayline("m: DBVM changeregonbp test\n");

}
#endif


key=0;
Expand Down Expand Up @@ -1584,7 +1581,7 @@ void menu2(void)

break;
}
#ifdef DEBUG

case 'w':
{
dbvm_watch_writes_test();
Expand Down Expand Up @@ -1615,7 +1612,6 @@ void menu2(void)
break;
}

#endif

default:
key=0;
Expand Down
11 changes: 9 additions & 2 deletions dbvm/vmm/nphandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ PPTE_PAE np_pagetables= (PPTE_PAE)0xffffff0000000000ULL;
void NPMode1CloakRestoreCallback(QWORD address UNUSED, CloakedPageData *data)
{
pcpuinfo c=getcpuinfo();
*(QWORD *)(data->npentry[c->cpunr])=data->PhysicalAddressData;
data->npentry[c->cpunr]->P=1;
data->npentry[c->cpunr]->RW=1;
data->npentry[c->cpunr]->US=1;

data->npentry[c->cpunr]->EXB=1; //back to non executable
}

Expand Down Expand Up @@ -107,7 +112,7 @@ void NPMode1CloakSetState(pcpuinfo currentcpuinfo, int state)

if (state==0)
{
//reprotect the 'other' cloaked regions
//reprotect the cloaked regions


if (CloakedPagesMap)
Expand Down Expand Up @@ -300,6 +305,7 @@ QWORD NPMapPhysicalMemory(pcpuinfo currentcpuinfo, QWORD physicalAddress, int fo
pagetable->P=1;
pagetable->RW=1;
pagetable->US=1;
pagetable->EXB=0;
}
else
{
Expand All @@ -310,6 +316,7 @@ QWORD NPMapPhysicalMemory(pcpuinfo currentcpuinfo, QWORD physicalAddress, int fo
pagetable->P=1;
pagetable->RW=1;
pagetable->US=1;
pagetable->EXB=0;
}

csLeave(&currentcpuinfo->EPTPML4CS);
Expand Down Expand Up @@ -341,7 +348,7 @@ VMSTATUS handleNestedPagingFault(pcpuinfo currentcpuinfo, VMRegisters *vmregiste
QWORD PhysicalAddress=currentcpuinfo->vmcb->EXITINFO2;
QWORD ErrorInfo=currentcpuinfo->vmcb->EXITINFO1;

sendstringf("%x:%x handleNestedPagingFault. PA=%6 (Code %x)\n", currentcpuinfo->vmcb->cs_selector, currentcpuinfo->vmcb->RIP, PhysicalAddress, ErrorInfo);
sendstringf("%x:%6 handleNestedPagingFault. PA=%6 (Code %x)\n", currentcpuinfo->vmcb->cs_selector, currentcpuinfo->vmcb->RIP, PhysicalAddress, ErrorInfo);
sendstringf("EXITINTINFO=%x\n", currentcpuinfo->vmcb->EXITINTINFO);
sendstringf("CR2=%6 vCR2=%6\n", getCR2(), currentcpuinfo->vmcb->CR2);

Expand Down
55 changes: 46 additions & 9 deletions dbvm/vmm/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,10 +576,11 @@ void dbvm_cloak_test(void)
r=cloakTestFunction();
sendstringf("Returned %d\n", r);


sendstringf("Calling copy\n");
r=newtestfunction();
sendstringf("Returned %d\n", r);

displayline("Unpatched result is %d\n", r);



Expand All @@ -599,58 +600,94 @@ void dbvm_cloak_test(void)
r=newtestfunction();

sendstringf("Patched result of cloakTestFunction() is %d\n", r);
displayline("Patched result without cloak is %d\n", r);

sendstringf("Undo patch. Now trying with cloak\n");
copymem(newtestfunction,cloakTestFunction, size );

int beforecloak=generateCRC((unsigned char*)newtestfunction, size);
displayline("Before cloak crc was %x\n", beforecloak);

unsigned char *buf=(unsigned char *)newtestfunction;
sendstringf("%6:", newtestfunction);
for (i=0; i<size; i++)
sendstringf("%2 ",buf[i]);

sendstringf("\n");

sendstringf("Activating cloak (mode 1)\n");
r=dbvm_cloak_activate(PA, 1);
displayline("Cloak activated\n");
sendstringf("dbvm_cloak_activate(%6) returned %d\n", PA, r);

_invlpg((QWORD)newtestfunction);

buf=(unsigned char *)newtestfunction;
sendstringf("%6:", newtestfunction);
for (i=0; i<size; i++)
sendstringf("%2 ",buf[i]); //when testing, should be all 0xce's

sendstringf("\n");



int aftercloak=generateCRC((unsigned char*)newtestfunction, size);
displayline("After cloak crc is %x\n", aftercloak);



sendstringf("Calling newtestfunction: (cloaked, unpatched)\n");
r=newtestfunction();
sendstringf("After cloak but no patch ,result of cloakTestFunction() is %d\n", r);
displayline("Cloak active but unpatched, result is %d\n",r);

unsigned char* executable=malloc(4096);

sendstringf("Allocated memory for the executable copy at %6\n", executable);

displayline("1: crc=%x\n", generateCRC((unsigned char*)newtestfunction, size));

r=dbvm_cloak_readExecutable(PA, executable);
displayline("2: crc=%x\n", generateCRC((unsigned char*)newtestfunction, size));
sendstringf("dbvm_cloak_readExecutable returned %d\n",r);

if (r==0)
{

int beforepatch=generateCRC((unsigned char*)newtestfunction, size);
displayline("3: crc=%x\n", generateCRC((unsigned char*)newtestfunction, size));

sendstringf("Applying patch to executable memory\n");
for (i=0; i<5; i++)
executable[(QWORD)(&cloakTestFunctionInstruction)-((QWORD)(cloakTestFunction))+i-2]=0x90;

displayline("4: crc=%x\n", generateCRC((unsigned char*)newtestfunction, size));

r=dbvm_cloak_writeExecutable(PA, executable);
sendstringf("dbvm_cloak_writeExectuable returned %d\n",r);
displayline("5: crc=%x\n", generateCRC((unsigned char*)newtestfunction, size));

int afterpatch=generateCRC((unsigned char*)newtestfunction, size);

displayline("6: crc=%x\n", generateCRC((unsigned char*)newtestfunction, size));

if (r==0)
{
sendstringf("Calling newtestfunction: (cloaked, patched)\n");
r=newtestfunction();
sendstringf("After cloak and patch ,result of cloakTestFunction() is %d\n", r);
displayline("Cloak active and patched, result is %d\n",r);
displayline("7: crc=%x\n", generateCRC((unsigned char*)newtestfunction, size));
}

}




r=dbvm_cloak_deactivate(PA);
displayline("8: crc=%x\n", generateCRC((unsigned char*)newtestfunction, size));
sendstringf("dbvm_cloak_deactivate(%6) returned %d\n", PA, r);

sendstringf("Reading it shows:");
for (i=0; i<5; i++)
{
int index=(QWORD)(&cloakTestFunctionInstruction)-((QWORD)(cloakTestFunction))+i;
sendstringf("%2 ",funcindex[index]);
funcindex[index]=0x90;
}
sendstringf("\n");


Expand Down
1 change: 1 addition & 0 deletions dbvm/vmm/vmmhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ typedef volatile struct tcpuinfo
struct
{
CloakedPageData *ActiveRegion; //if not null this contains the current page that is executable
QWORD LastCloakedVirtualBase;
} NP_Cloak; //AMD cloaking


Expand Down

0 comments on commit 4418a0e

Please sign in to comment.