Skip to content

Commit

Permalink
implement the EPT memory watch/cloak routines (100% untested)
Browse files Browse the repository at this point in the history
  • Loading branch information
cheat-engine committed Mar 20, 2018
1 parent 9e5e377 commit 72bb3a4
Show file tree
Hide file tree
Showing 15 changed files with 1,103 additions and 146 deletions.
662 changes: 597 additions & 65 deletions dbvm/vmm/epthandler.c

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions dbvm/vmm/epthandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,19 @@ void initMemTypeRanges();
int handleEPTViolation(pcpuinfo currentcpuinfo, VMRegisters *vmregisters, PFXSAVE64 fxsave);
int handleEPTMisconfig(pcpuinfo currentcpuinfo, VMRegisters *vmregisters);
int ept_handleWatchEventAfterStep(pcpuinfo currentcpuinfo, int ID);
int ept_handleCloakEventAfterStep(pcpuinfo currentcpuinfo, int ID);
int ept_handleSoftwareBreakpointAfterStep(pcpuinfo currentcpuinfo, int ID);

int ept_activateWatch(pcpuinfo currentcpuinfo, int ID);
int ept_disableWatch(pcpuinfo currentcpuinfo, int ID);
int getFreeWatchID(pcpuinfo currentcpuinfo);

int ept_cloak_activate(QWORD physicalAddress);
int ept_cloak_deactivate(QWORD physicalAddress);
int ept_cloak_readOriginal(pcpuinfo currentcpuinfo, VMRegisters *registers, QWORD physicalAddress, QWORD destination);
int ept_cloak_writeOriginal(pcpuinfo currentcpuinfo, VMRegisters *registers, QWORD physicalAddress, QWORD source);
int ept_cloak_changeregonbp(QWORD physicalAddress, PCHANGEREGONBPINFO changereginfo);
int ept_cloak_removechangeregonbp(QWORD physicalAddress);
int ept_handleSoftwareBreakpoint(pcpuinfo currentcpuinfo);

#endif /* VMM_EPTHANDLER_H_ */
50 changes: 48 additions & 2 deletions dbvm/vmm/eptstructs.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define VMM_EPTSTRUCTS_H_

#include "common.h"
#include "vmcallstructs.h"

//the EPT fields are pretty much the same as normal paging fields, Read==Present, RW=write etc... BUT the A and D bits access fields used for other things that WILL cause bad effects.
//so do NOT map them as page tables for easy editing
Expand Down Expand Up @@ -125,40 +126,70 @@ typedef struct _fxsave64
BYTE FTW;
BYTE Reserved;
WORD FOP;
QWORD FPU_IP;
QWORD FPU_DP;
UINT64 FPU_IP;
UINT64 FPU_DP;
DWORD MXCSR;
DWORD MXCSR_MASK;
QWORD FP_MM0;
QWORD FP_MM0_H;
QWORD FP_MM1;
QWORD FP_MM1_H;
QWORD FP_MM2;
QWORD FP_MM2_H;
QWORD FP_MM3;
QWORD FP_MM3_H;
QWORD FP_MM4;
QWORD FP_MM4_H;
QWORD FP_MM5;
QWORD FP_MM5_H;
QWORD FP_MM6;
QWORD FP_MM6_H;
QWORD FP_MM7;
QWORD FP_MM7_H;
QWORD XMM0;
QWORD XMM0_H;
QWORD XMM1;
QWORD XMM1_H;
QWORD XMM2;
QWORD XMM2_H;
QWORD XMM3;
QWORD XMM3_H;
QWORD XMM4;
QWORD XMM4_H;
QWORD XMM5;
QWORD XMM5_H;
QWORD XMM6;
QWORD XMM6_H;
QWORD XMM7;
QWORD XMM7_H;
QWORD XMM8;
QWORD XMM8_H;
QWORD XMM9;
QWORD XMM9_H;
QWORD XMM10;
QWORD XMM10_H;
QWORD XMM11;
QWORD XMM11_H;
QWORD XMM12;
QWORD XMM12_H;
QWORD XMM13;
QWORD XMM13_H;
QWORD XMM14;
QWORD XMM14_H;
QWORD XMM15;
QWORD XMM15_H;
QWORD res1;
QWORD res1_H;
QWORD res2;
QWORD res2_H;
QWORD res3;
QWORD res3_H;
QWORD res4;
QWORD res4_H;
QWORD res5;
QWORD res5_H;
QWORD res6;
QWORD res6_H;
} FXSAVE64, *PFXSAVE64;


Expand Down Expand Up @@ -252,7 +283,22 @@ typedef struct
PPageEventListDescriptor Log;
} EPTWatchEntry, *PEPTWatchEntry;

typedef struct
{
QWORD PhysicalAddressExecutable; //the PA of the original page and used for execute
QWORD PhysicalAddressData; //the PA of the page shown when read/write operations happen
void *Data;
void *Executable;
} CloakedPageInfo, *PCloakedPageInfo;

typedef struct
{
int Active;
int CloakedRangeIndex;
QWORD PhysicalAddress;
unsigned char originalbyte;
CHANGEREGONBPINFO changereginfo;
} ChangeRegBPEntry, *PChangeRegBPEntry;


#endif /* VMM_EPTSTRUCTS_H_ */
2 changes: 2 additions & 0 deletions dbvm/vmm/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ int AMD_hasNRIPS;
extern int IntHandlerDebug;
volatile int NMIcount;

extern pcpuinfo firstcpuinfo;

#define vmclear _vmclear
#define vmptrld _vmptrld
#define vmxon _vmxon
Expand Down
156 changes: 148 additions & 8 deletions dbvm/vmm/mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ Just used for basic initialization allocation, frees shouldn't happen too often

#define BASE_VIRTUAL_ADDRESS 0x1000000000ULL

//MAPPEDMEMORY is the range of virtual memory allocated for individual CPU threads mapping
#define MAPPEDMEMORY 0x08000000000ULL

//GLOBALMAPPEDMEMORY is the virtual memory allocated for the whole system for mapping
#define GLOBALMAPPEDMEMORY 0x07000000000ULL

//for virtual memory allocs
criticalSection AllocCS;
criticalSection GlobalMapCS;


PageAllocationInfo *AllocationInfoList=(PageAllocationInfo *)BASE_VIRTUAL_ADDRESS;
int PhysicalPageListSize=1; //size in pages
Expand Down Expand Up @@ -329,6 +335,104 @@ int mmFindMapPositionForSize(pcpuinfo cpuinfo, int size)

volatile int FreezeOnMapAllocFail=1;


void mapPhysicalAddressToVirtualAddress(QWORD PhysicalAddress, QWORD VirtualAddress)
{
VirtualAddress=0xfffffffffffff000ULL;
PhysicalAddress=PhysicalAddress & MAXPHYADDRMASKPB;
PPTE_PAE pageentry=(PPTE_PAE)getPageTableEntryForAddressEx((void *)VirtualAddress,1);
*(QWORD*)pageentry=PhysicalAddress;
pageentry->P=1;
pageentry->RW=1;
pageentry->US=1;
asm volatile ("": : :"memory");
_invlpg(VirtualAddress);
asm volatile ("": : :"memory");
}

QWORD mmFindGlobalMapAddressForSize(int size)
{
int pagecount=size / 4096;
if (size % 0xfff)
pagecount++;

PPTE_PAE pages;
QWORD currentVirtualAddress=GLOBALMAPPEDMEMORY;

//find a global page not used yet. Every 2MB call getPageTableEntryForAddressEx to make sure the pagetable is present
while (currentVirtualAddress<MAPPEDMEMORY)
{
pages=(PPTE_PAE)getPageTableEntryForAddressEx((void *)currentVirtualAddress,1);
//scan this page for pagecount number of pages
int i;
for (i=0; i<512; i++)
{
if (pages[i].P==0)
{
//scan for i to pagecount and make sure it's all 0
//make sure that all pagetables between i and pagecount are present
int j;
int used=0;

for (j=i+512; j<i+pagecount; j+=512)
getPageTableEntryForAddressEx((void*)(currentVirtualAddress+4096*j),1);

//now scan

for (j=i; j<i+pagecount; j++)
{
if (pages[j].P)
{
used=1;
break;
}
}
if (used==0)
return currentVirtualAddress+4096*i;
}
}
currentVirtualAddress+=2*1024*1024; //next 2MB
}

return 0;
}

void* mapPhysicalMemoryGlobal(QWORD PhysicalAddress, int size) //heavy operation
{
int i;
unsigned int offset=PhysicalAddress & 0xfff;
int totalsize=size+offset;
int pagecount=totalsize / 4096;
if (totalsize % 0xfff)
pagecount++;

PPTE_PAE pages;
QWORD VirtualAddress;
csEnter(&GlobalMapCS);


VirtualAddress=mmFindGlobalMapAddressForSize(totalsize);
if (VirtualAddress)
{
pages=(PPTE_PAE)getPageTableEntryForAddress((void *)VirtualAddress);
for (i=0; i<pagecount; i++)
{
*(QWORD*)&pages[i]=(PhysicalAddress+(4096*i)) & MAXPHYADDRMASKPB;
pages[i].P=1;
pages[i].RW=1;
pages[i].US=1;
asm volatile ("": : :"memory");
_invlpg(VirtualAddress+i*4096);
asm volatile ("": : :"memory");
}
}

_wbinvd();
csLeave(&GlobalMapCS);

return (void*)VirtualAddress;
}

void* mapPhysicalMemoryAddresses(QWORD *addresses, int count)
/*
* Maps the given physical addresses in the order given
Expand Down Expand Up @@ -410,17 +514,52 @@ void* mapPhysicalMemory(QWORD PhysicalAddress, int size)
return (void *)(VirtualAddressBase+pos*4096+offset);
}

void unmapPhysicalMemoryGlobal(void *virtualaddress, int size)
{
if (((QWORD)virtualaddress>GLOBALMAPPEDMEMORY) && ((QWORD)virtualaddress<MAPPEDMEMORY))
{
QWORD base=(QWORD)virtualaddress & 0xfffffffffffff000ULL;;
unsigned int offset=(QWORD)virtualaddress & 0xfff;
int totalsize=size+offset;
int pagecount=totalsize / 4096;
if (totalsize % 0xfff)
pagecount++;

csEnter(&GlobalMapCS);
PPTE_PAE pages=(PPTE_PAE)getPageTableEntryForAddress(virtualaddress);

int i;
for (i=0; i<pagecount; i++)
{
pages[i].P=0;
asm volatile ("": : :"memory");
_invlpg((QWORD)base+i*4096);
asm volatile ("": : :"memory");
}

_wbinvd();
csLeave(&GlobalMapCS);
}
else
{
sendstringf("invalid global address (%6) given to unmapPhysicalMemoryGlobal\n",virtualaddress);
while (1);
}
}

void unmapPhysicalMemory(void *virtualaddress, int size)
{
pcpuinfo c=getcpuinfo();

unsigned int offset=(QWORD)virtualaddress & 0xfff;
int totalsize=size+offset;
int pagecount=(totalsize / 4096)+((totalsize % 4096)?1:0);
int pagecount=totalsize / 4096;
if (totalsize % 0xfff)
pagecount++;

int pos=(((QWORD)virtualaddress & 0xfffffffffffff000ULL)-(MAPPEDMEMORY+(c->cpunr*0x400000)))/4096;

//sendstringf("%d unmapPhysicalMemory: pos=%d\n", c->cpunr, pos);

int pos=(((QWORD)virtualaddress & 0xfffffffffffff000ULL)-(MAPPEDMEMORY+(c->cpunr*0x400000)))/4096;

if ((pos<0) || (pos>1024))
{
Expand All @@ -429,13 +568,14 @@ void unmapPhysicalMemory(void *virtualaddress, int size)
}

int i;
QWORD MappedBase=(QWORD)getMappedMemoryBase();
for (i=pos; i<pos+pagecount; i++)
{
c->mappagetables[i].P=0;

asm volatile ("": : :"memory");

_invlpg((QWORD)virtualaddress);
asm volatile ("": : :"memory");
asm volatile ("": : :"memory");
_invlpg((QWORD)MappedBase+4096*i);
asm volatile ("": : :"memory");
}

}

Expand Down
4 changes: 4 additions & 0 deletions dbvm/vmm/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ void* getMappedMemoryBase();
PPTE_PAE mapAddressAtPML4(QWORD address);
void unmapAddressAtPML4(PPTE_PAE base);

void mapPhysicalAddressToVirtualAddress(QWORD PhysicalAddress, QWORD VirtualAddress);
void* mapMemory(void *destination, void *source, int size); //maps a virtual memory region with the specified virtual memory region

int mmFindMapPositionForSize(pcpuinfo cpuinfo, int size);
Expand All @@ -41,6 +42,9 @@ void unmapPhysicalMemory(void *virtualaddress, int size);
void* mapPhysicalMemory(QWORD PhysicalAddress, int size);
void* mapPhysicalMemoryAddresses(QWORD *addresses, int count);

void* mapPhysicalMemoryGlobal(QWORD PhysicalAddress, int size);
void unmapPhysicalMemoryGlobal(void *virtualaddress, int size);

void VirtualAddressToIndexes(QWORD address, int *pml4index, int *pagedirptrindex, int *pagedirindex, int *pagetableindex);

void *malloc(size_t size);
Expand Down
Loading

0 comments on commit 72bb3a4

Please sign in to comment.