forked from ufrisk/pcileech
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmacos_common.c
More file actions
148 lines (132 loc) · 4.71 KB
/
Copy pathmacos_common.c
File metadata and controls
148 lines (132 loc) · 4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// macos_common.c : support functions used by macOS KMDs started by stage3 EXEC.
// Compatible with macOS.
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
#include "macos_common.h"
//-------------------------------------------------------------------------------
// EFI related defines below.
//-------------------------------------------------------------------------------
typedef struct PE_state {
QWORD initialized;
QWORD video_dummy[18];
PVOID deviceTreeHead;
PVOID bootArgs;
} PE_state_t, *PPE_state_t;
enum {
EfiReservedMemoryType = 0,
EfiLoaderCode = 1,
EfiLoaderData = 2,
EfiBootServicesCode = 3,
EfiBootServicesData = 4,
EfiRuntimeServicesCode = 5,
EfiRuntimeServicesData = 6,
EfiConventionalMemory = 7,
EfiUnusableMemory = 8,
EfiACPIReclaimMemory = 9,
EfiACPIMemoryNVS = 10,
EfiMemoryMappedIO = 11,
EfiMemoryMappedIOPortSpace = 12,
EfiPalCode = 13,
EfiMaxMemoryType = 14
};
typedef struct tdEFI_MEMORY_RANGE {
DWORD Type;
DWORD Pad;
QWORD PhysicalStart;
QWORD VirtualStart;
QWORD NumberOfPages;
QWORD Attribute;
} EFI_MEMORY_RANGE, *PEFI_MEMORY_RANGE;
#define BOOT_LINE_LENGTH 1024
typedef struct tdBOOT_ARGS {
QWORD RevisionAndVersion;
CHAR CommandLine[BOOT_LINE_LENGTH]; // Passed in command line
DWORD MemoryMap; // Physical address of memory map
DWORD MemoryMapSize;
DWORD MemoryMapDescriptorSize;
DWORD MemoryMapDescriptorVersion;
// truncated struct members exists
} BOOT_ARGS, *PBOOT_ARGS;
//-------------------------------------------------------------------------------
// Kernel module functions below.
//-------------------------------------------------------------------------------
BOOL GetMemoryMap(PKMDDATA pk, PBYTE pbBuffer4k_PhysicalMemoryRange, PQWORD pcbBuffer4k_PhysicalMemoryRange)
{
PBOOT_ARGS ba = ((PPE_state_t)pk->fn._PE_state)->bootArgs;
PEFI_MEMORY_RANGE pEFIr;
PPHYSICAL_MEMORY_RANGE pmr;
QWORD cPmr = 0, o = 0;
SysVCall(pk->fn.memset, pbBuffer4k_PhysicalMemoryRange, 0ULL, 4096ULL);
pmr = (PPHYSICAL_MEMORY_RANGE)pbBuffer4k_PhysicalMemoryRange;
while(o < ba->MemoryMapSize) {
pEFIr = (PEFI_MEMORY_RANGE)(VM_MIN_KERNEL_ADDRESS + ba->MemoryMap + o);
if(pEFIr->Type < EfiMaxMemoryType && pEFIr->Type != EfiReservedMemoryType && pEFIr->Type != EfiUnusableMemory && pEFIr->Type != EfiMemoryMappedIO && pEFIr->Type != EfiMemoryMappedIOPortSpace) {
if(cPmr && (pEFIr->PhysicalStart == pmr[cPmr - 1].BaseAddress + pmr[cPmr - 1].NumberOfBytes)) {
pmr[cPmr - 1].NumberOfBytes += pEFIr->NumberOfPages * 0x1000;
} else {
pmr[cPmr].BaseAddress = pEFIr->PhysicalStart;
pmr[cPmr].NumberOfBytes = pEFIr->NumberOfPages * 0x1000;
cPmr++;
}
}
o += ba->MemoryMapDescriptorSize;
}
*pcbBuffer4k_PhysicalMemoryRange = cPmr * sizeof(PHYSICAL_MEMORY_RANGE);
return TRUE;
}
QWORD MapMemoryPhysical(PKMDDATA pk, QWORD qwMemoryBase)
{
for(DWORD i = 0; i < 512 * 8; i++) { // PT*8 -> Pages (16MB)
((PQWORD)(pk->ReservedKMD[0] + 0x2000))[i] = 0x0000000000000003 | (qwMemoryBase + 0x1000 * i);
}
PageFlush();
return 0xffffee8000000000;
}
BOOL IsRangeInPhysicalMap(PBYTE pbMemoryRanges, QWORD cbMemoryRanges, QWORD qwBaseAddress, QWORD qwNumberOfBytes)
{
PPHYSICAL_MEMORY_RANGE ppmr;
for(QWORD i = 0; i < cbMemoryRanges / sizeof(PHYSICAL_MEMORY_RANGE); i++) {
ppmr = ((PPHYSICAL_MEMORY_RANGE)pbMemoryRanges) + i;
if(((ppmr->BaseAddress <= qwBaseAddress) && (ppmr->BaseAddress + ppmr->NumberOfBytes > qwBaseAddress + qwNumberOfBytes))) {
return TRUE;
}
}
return FALSE;
}
QWORD GetMemoryPhysicalMaxAddress(PBYTE pbMemoryRanges, QWORD cbMemoryRanges)
{
PPHYSICAL_MEMORY_RANGE pMemMap = (PPHYSICAL_MEMORY_RANGE)pbMemoryRanges;
QWORD cMemMap = cbMemoryRanges / sizeof(PHYSICAL_MEMORY_RANGE);
return pMemMap[cMemMap - 1].BaseAddress + pMemMap[cMemMap - 1].NumberOfBytes;
}
BOOL _WriteLargeOutput_WaitForAck(PKMDDATA pk)
{
PEXEC_IO pis = (PEXEC_IO)(pk->DMAAddrVirtual + EXEC_IO_DMAOFFSET_IS);
PEXEC_IO pos = (PEXEC_IO)(pk->DMAAddrVirtual + EXEC_IO_DMAOFFSET_OS);
while((pk->_op == KMD_CMD_EXEC_EXTENDED) && ((pis->magic != EXEC_IO_MAGIC) || (!pis->bin.fCompletedAck && (pis->bin.seqAck != pos->bin.seq)))) {
SysVCall(pk->fn.IOSleep, 25);
}
return (pk->_op == KMD_CMD_EXEC_EXTENDED) && !pis->bin.fCompletedAck;
}
BOOL WriteLargeOutput_WaitNext(PKMDDATA pk)
{
PEXEC_IO pos = (PEXEC_IO)(pk->DMAAddrVirtual + EXEC_IO_DMAOFFSET_OS);
pos->magic = EXEC_IO_MAGIC;
CacheFlush();
pos->bin.seq++;
pk->_op = KMD_CMD_EXEC_EXTENDED;
return _WriteLargeOutput_WaitForAck(pk);
}
VOID WriteLargeOutput_Finish(PKMDDATA pk)
{
PEXEC_IO pos = (PEXEC_IO)(pk->DMAAddrVirtual + EXEC_IO_DMAOFFSET_OS);
WriteLargeOutput_WaitNext(pk);
pk->dataOutExtraLength = 0;
CacheFlush();
pos->bin.fCompleted = TRUE;
pos->bin.seq++;
_WriteLargeOutput_WaitForAck(pk);
pk->_op = KMD_CMD_EXEC;
}