
網絡安全【免費下載鏈接】BlackboneWindows memory hacking library項目地址https://gitcode.com/gh_mirrors/bl/Blackbone點擊查看免費下載導讀WOW64Ext 是運行在 x64 Windows 系統(tǒng) WOW64 兼容層之下的 x8632 位程序專用輔助庫它解決了 32 位進程無法直接讀寫、枚舉原生 x64 進程內存的經典難題并額外提供X64Call()這一核心機制使 x86 代碼可以間接調用 x64 版 NTDLL 中的任意函數(shù)。本篇文章以 WOW64Ext 官方文檔 為骨架結合 wow64ext.h 與 wow64ext.cpp 源碼及 示例程序完整講解每個導出 API 的簽名、參數(shù)語義與底層實現(xiàn)并展示該庫如何被本項目 Blackbone 的 WOW64 子系統(tǒng)直接吸收利用。讀完本文你將掌握從 32 位進程訪問 64 位目標進程的內存、模塊與線程上下文的完整方法以及 x86 模式切換至 x64 模式調用原生函數(shù)的底層原理。背景32 位進程在 64 位系統(tǒng)上面臨的內存訪問難題x64 版本 Windows 通過 WOW64Windows 32-bit on Windows 64-bit兼容層運行 x86 程序。WOW64 環(huán)境中的 32 位進程在功能上有很大限制標準 Win32 APIReadProcessMemory、VirtualAllocEx、OpenProcess等的SIZE_T指針位寬被截斷為 32 位無法表示 x64 目標進程中的高地址默認情況下32 位進程的地址空間被限制在 4GB 之內無法直接尋址 64 位進程位于 4GB 之上的內存區(qū)域32 位代碼無法直接調用 64 位 NTDLL 中的系統(tǒng)服務封裝函數(shù)Nt*系列因為兩者使用不同的調用約定與代碼段。WOW64Ext 正是為了解決這些限制而設計的它在不依賴任何驅動的情況下讓 x86 程序獲得對原生 x64 進程內存、模塊與線程的完整操作能力。該庫在 Blackbone 中承擔了關鍵角色——Blackbone 的NativeWow64子系統(tǒng)Wow64Subsystem.cpp直接編譯并使用了本庫的wow64ext.cpp見 CMakeLists.txt 與 BlackBone.vcxproj這正是 Blackbone 支持跨越 WOW64 屏障管理 x64 進程功能的技術基礎。庫概覽與目錄結構WOW64Ext 由作者 ReWolf 開發(fā)在倉庫中位于src/3rd_party/rewolf-wow64ext/核心文件如下文件作用src/wow64ext.h公共頭文件導出函數(shù)聲明、PEB/TEB/TIB/LDR 等結構定義、_CONTEXT64_2定義src/wow64ext.cpp全部導出函數(shù)的實現(xiàn)內含 x86 內聯(lián)匯編src/internal.h內部宏X64_Start()/X64_End()模式切換匯編字節(jié)碼、REX_W、reg64聯(lián)合體src/CMemPtr.h臨時內存自動釋放的 RAII 輔助WATCH宏sample/main.cpp示例程序x64 進程內存轉儲器 功能自測doc/wow64ext.txt完整 API 文檔src/wow64ext.vcxproj32 位動態(tài)庫工程配置構建工程只面向 Win32 平臺wow64ext.vcxproj 僅包含Debug|Win32與Release|Win32兩種配置這是因為該庫的設計目標就是讓 x86 進程跨越 WOW64 屏障64 位進程直接使用標準 API 即可無需此庫。編譯時定義WOW64EXT_EXPORTS會將導出函數(shù)標記為dllexport否則標記為dllimport見 wow64ext.h。核心機制X64Call() 與 x86/x64 模式切換函數(shù)簽名與參數(shù)約定DWORD64 __cdecl X64Call(DWORD64 func, int argC, ...);這是整個庫的引擎。官方文檔對其語義的定義如下func要調用的 x64 函數(shù)地址通常由GetProcAddress64()取得argC傳給func的參數(shù)個數(shù)...func的其余參數(shù)所有參數(shù)都必須顯式轉換為DWORD64。返回值是被調用 x64 函數(shù)在RAX中的返回值以DWORD64形式返回。底層原理x86 內聯(lián)匯編 遠程段切換從實現(xiàn)上看wow64ext.cppX64Call的代碼被編譯為 x86 內聯(lián)匯編但在運行時通過修改 CS代碼段寄存器以 x64 模式執(zhí)行這些字節(jié)碼。關鍵步驟包括切換 FS 段先將 FS 段保存隨后將 FS 寫入 x64 選擇子0x2B以正確處理 64 位環(huán)境的 FS 基址TEB64 定位依賴于此棧對齊將esp對齊到0x10邊界——源碼注釋明確指出未對齊的棧可能導致某些 syscall 返回錯誤且 SSE 指令要求 16 字節(jié)對齊通過X64_Start()宏切換到 x64 代碼段宏展開后是一段精心構造的字節(jié)碼push cs; call $5; add dword [esp], 5; retf通過retf遠返回切換 CS 到 x64 選擇子0x33見 internal.h填充寄存器參數(shù)按 x64 調用約定把前 4 個參數(shù)放入rcx、rdx、r8、r9其余參數(shù)逆序壓棧注意其中REX_W前綴的作用——32 位匯編器會省略這些字節(jié)但 CPU 在 x64 模式下需要它們把指令解析為 64 位操作調用目標函數(shù)并清理棧調用完畢后按參數(shù)個數(shù)恢復棧retf返回 32 位模式X64_End()恢復ss、esp與 FS 段。為了在 32 位匯編中安全地操作 64 位值internal.h 定義了reg64聯(lián)合體用兩個DWORD模擬一個DWORD64注釋說明直接使用DWORD64會產生錯誤的pop word ptr[]并破壞棧。配套輔助函數(shù)DWORD64 __cdecl getNTDLL64();返回 x64 版 ntdll.dll 的基址內部緩存X64Call與內存 API 的延遲解析都依賴它。GetModuleHandle64(Lntdll.dll)是它的實現(xiàn)基礎見 wow64ext.cpp。此外還有VOID __cdecl SetLastErrorFromX64Call(DWORD64 status);X64Call直接返回 NTSTATUS而內存類 API 需要遵循 Win32 慣例設置GetLastError()。該函數(shù)通過 x86 版RtlNtStatusToDosError與RtlSetLastWin32Error把 NTSTATUS 轉成對應的 Win32 錯誤碼見 wow64ext.cpp。模塊枚舉與函數(shù)解析GetModuleHandle64 與 GetProcAddress64GetModuleHandle64DWORD64 __cdecl GetModuleHandle64(const wchar_t* lpModuleName);行為類似 x86 版GetModuleHandle但檢索的是已加載 x64 庫的模塊鏈表。官方文檔特別指出通常 WOW64 層下的 x86 進程只加載 4 個 x64 庫——ntdll.dll、wow64.dll、wow64cpu.dll、wow64win.dll。參數(shù)lpModuleName為寬字符串模塊名。其實現(xiàn)wow64ext.cpp展示了 WOW64Ext 結構定義的典型用法通過getTEB64()拿到當前線程的 TEB64——在 WOW64 進程中R12寄存器恒指向 TEB64因此實現(xiàn)只是把R12壓棧再彈出從TEB64.ProcessEnvironmentBlock得到 PEB64從PEB64.Ldr得到PEB_LDR_DATA64沿InLoadOrderModuleList鏈表遍歷LDR_DATA_TABLE_ENTRY64逐個比較BaseDllName與目標模塊名命中則返回DllBase。GetProcAddress64DWORD64 __cdecl GetProcAddress64(DWORD64 hModule, const char* funcName);行為類似 x86 版GetProcAddress內部調用x64 版LdrGetProcedureAddress()。參數(shù)hModule為 x64 模塊基址funcName為函數(shù)名ANSI 字符串。解析LdrGetProcedureAddress地址的過程wow64ext.cpp體現(xiàn)了對 x64 內存的基礎讀寫能力定位 ntdll64 的 PE 頭 → 讀取導出目錄 → 用getMem64/cmpMem64將導出名稱表、序號表、函數(shù)地址表批量復制到本地內存 → 線性匹配LdrGetProcedureAddress名稱 → 算出其 RVA 對應的絕對地址。之后通過X64Call(_LdrGetProcedureAddress, 4, hModule, fName, 0, funcRet)完成真正的函數(shù)地址解析見 wow64ext.cpp。內存操作 API在 x64 目標進程上執(zhí)行虛擬內存管理以下 6 個 API 的參數(shù)與行為都與 x86 對應版 Win32 函數(shù)同名同義區(qū)別在于地址一律使用DWORD64寬指針且內部通過X64Call調用 x64 NTDLL 中的Nt*系統(tǒng)服務。VirtualQueryEx64SIZE_T __cdecl VirtualQueryEx64(HANDLE hProcess, DWORD64 lpAddress, MEMORY_BASIC_INFORMATION64* lpBuffer, SIZE_T dwLength);hProcess進程句柄由標準 x86 版OpenProcess()獲取lpAddress待查詢區(qū)域的基址lpBuffer指向MEMORY_BASIC_INFORMATION64標準 SDK 頭中已定義的緩沖區(qū)dwLength緩沖區(qū)大小。內部經X64Call(NtQueryVirtualMemory, 6, ...)調用 x64 版NtQueryVirtualMemory失敗時通過SetLastErrorFromX64Call設置 Win32 錯誤碼成功則返回ReturnLength見 wow64ext.cpp。VirtualAllocEx64DWORD64 __cdecl VirtualAllocEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);lpAddress期望的分配起始地址可傳 0 讓系統(tǒng)選擇dwSize區(qū)域大小flAllocationType分配類型MEM_COMMIT、MEM_RESERVE等flProtect內存保護屬性PAGE_READWRITE等。底層調用NtAllocateVirtualMemory成功時返回實際分配的地址注意NtAllocateVirtualMemory會通過指針參數(shù)回寫實際地址因此傳入的是tmpAddr失敗返回FALSE并設置錯誤碼見 wow64ext.cpp。VirtualFreeEx64BOOL __cdecl VirtualFreeEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD dwFreeType);dwFreeType釋放操作類型官方文檔明確給出可取MEM_RELEASE、MEM_DECOMMIT。底層調用NtFreeVirtualMemory見 wow64ext.cpp。VirtualProtectEx64BOOL __cdecl VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect);flNewProtect新的內存保護屬性lpflOldProtect接收舊保護值的指針。底層調用NtProtectVirtualMemory見 wow64ext.cpp。ReadProcessMemory64 與 WriteProcessMemory64BOOL __cdecl ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead); BOOL __cdecl WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten);lpBaseAddress目標內存基址64 位寬lpBuffer讀/寫數(shù)據(jù)的本地緩沖區(qū)nSize讀/寫字節(jié)數(shù)lpNumberOfBytesRead/lpNumberOfBytesWritten實際讀/寫字節(jié)數(shù)輸出指針。兩者底層分別調用 x64 版NtReadVirtualMemory與NtWriteVirtualMemory見 wow64ext.cpp。線程上下文 APIGetThreadContext64 與 SetThreadContext64BOOL __cdecl GetThreadContext64(HANDLE hThread, _CONTEXT64_2* lpContext); BOOL __cdecl SetThreadContext64(HANDLE hThread, _CONTEXT64_2* lpContext);hThread目標線程句柄文檔中寫作進程句柄為筆誤實現(xiàn)與 Win32 語義均為線程句柄lpContext指向_CONTEXT64結構的指針GetThreadContext64依據(jù)ContextFlags字段填充結構SetThreadContext64僅寫入ContextFlags指定的字段。底層分別調用 x64 版NtGetContextThread/NtSetContextThread見 wow64ext.cpp。由于 32 位 SDK 不包含 x64 上下文結構庫在 wow64ext.h 中自定義了完整的_CONTEXT64_2包含 6 個參數(shù) home 區(qū)、ContextFlags、各段寄存器、調試寄存器Dr0-Dr7、通用寄存器Rax-R15、Rip、_XSAVE_FORMAT64浮點保存區(qū)以及Xmm0-Xmm15、AVXVectorRegister[26]等。文件同時定義了一組與 WinNT.h 對應的ContextFlags常量#define CONTEXT64_CONTROL (CONTEXT_AMD64 | 0x1L) #define CONTEXT64_INTEGER (CONTEXT_AMD64 | 0x2L) #define CONTEXT64_SEGMENTS (CONTEXT_AMD64 | 0x4L) #define CONTEXT64_FLOATING_POINT (CONTEXT_AMD64 | 0x8L) #define CONTEXT64_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L) #define CONTEXT64_FULL (CONTEXT64_CONTROL | CONTEXT64_INTEGER | CONTEXT64_FLOATING_POINT) #define CONTEXT64_ALL (CONTEXT64_CONTROL | CONTEXT64_INTEGER | CONTEXT64_SEGMENTS | \ CONTEXT64_FLOATING_POINT | CONTEXT64_DEBUG_REGISTERS) #define CONTEXT64_XSTATE (CONTEXT_AMD64 | 0x20L)見 wow64ext.h。附贈結構定義模板化的 PEB / TEB / TIB / LDR 結構官方文檔提到wow64ext.h還包含一批可能對訪問 PEB、TEB、TIB 等有用的結構定義。它們全部是模板化的——以指針位寬T為模板參數(shù)DWORD得到 32 位版、DWORD64得到 64 位版模板實例化別名說明_LIST_ENTRY_TT—雙向鏈表節(jié)點Flink/Blink_UNICODE_STRING_TT—寬字符串Length/MaximumLength/Buffer_NT_TIB_TT—線程信息塊 TIB 前 7 個字段_CLIENT_ID_TT—UniqueProcess/UniqueThread_TEB_T_TTEB32/TEB64線程環(huán)境塊注釋說明其余部分暫未定義因為暫不需要_LDR_DATA_TABLE_ENTRY_TTLDR_DATA_TABLE_ENTRY32/LDR_DATA_TABLE_ENTRY64加載器鏈表條目_PEB_LDR_DATA_TTPEB_LDR_DATA32/PEB_LDR_DATA64PEB 中的加載器數(shù)據(jù)_PEB_TT,NGF,APEB32/PEB64進程環(huán)境塊含BeingDebugged、NtGlobalFlag、GdiHandleBuffer等常用字段定義位于 wow64ext.h注意文件頂部使用了#pragma pack(1)單字節(jié)對齊以保證與真實內核結構布局一致。PEB32/PEB64的模板參數(shù)A表示GdiHandleBuffer數(shù)組大小32 位為 34、64 位為 30NGF用于適配NtGlobalFlag字段類型差異。實戰(zhàn)示例官方內存轉儲器解讀示例程序位于 sample/main.cpp它是 WOW64Ext 各 API 的綜合演示運行方式為sample.exe hex_process_ID // 十六進制格式的進程 ID程序依次演示了以下能力解析 x64 模塊導出GetProcAddress64(GetModuleHandle64(Lwow64cpu.dll), TurboDispatchJumpAddressStart)直接取得 WOW64 CPU 調度函數(shù)的地址枚舉并轉儲 x64 進程內存以VirtualQueryEx64從地址 0 開始逐區(qū)域掃描跳過PAGE_NOACCESS/PAGE_GUARD區(qū)域對可讀區(qū)域用ReadProcessMemory64讀取并以進程ID_基址_保護屬性.bin命名寫入文件——這正是官方文檔所說的簡單內存轉儲器調用任意 x64 函數(shù)取得RtlComputeCrc32后執(zhí)行X64Call(rtlcrc32, 3, (DWORD64)0, (DWORD64)ReWolf, (DWORD64)6)計算字符串 CRC32注意所有參數(shù)顯式轉為DWORD64完整的內存操作閉環(huán)AllocTest()展示了分配 → 查詢 → 改保護 → 寫入 → 讀出比對 → 釋放的完整流程其中VirtualAllocEx64(hProcess, 0x70000020000, 0x2000, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE)在 4GB 以上地址分配內存之后WriteProcessMemory64/ReadProcessMemory64配合memcmp校驗讀寫一致性最后VirtualFreeEx64(..., 0, MEM_RELEASE)釋放并再查詢確認狀態(tài)該測試還對當前進程執(zhí)行了一次驗證在 WOW64 內部跨越 4GB 邊界分配內存的能力讀寫線程上下文ctx.ContextFlags CONTEXT64_ALL; GetThreadContext64(GetCurrentThread(), ctx)后打印rsp、rip、r8、r9、r12。注釋中保留了被注釋掉的危險代碼——把ctx.Rip 0后SetThreadContext64會直接崩潰進程從反面印證了上下文寫入確實生效。在 Blackbone 中的集成NativeWow64 子系統(tǒng)Blackbone 將該庫作為 WOW64 子系統(tǒng)的底層實現(xiàn)直接編譯進項目BlackBone.vcxproj 將wow64ext.cpp編入BlackBone.vcxproj.filters 將其歸入 Subsystem 分組CMake 構建同樣包含該源文件見 CMakeLists.txt。集成點是 Wow64Subsystem.cpp其中NativeWow64類把 WOW64Ext 的底層原語封裝成 Blackbone 風格的NTSTATUS接口VirtualAllocExT/VirtualFreeExT/VirtualQueryExT/VirtualProtectExT與 WOW64Ext 的內存 API 一一對應直接使用GetProcAddress64(getNTDLL64(), Nt*)配合X64Call實現(xiàn)見 Wow64Subsystem.cppReadProcessMemoryT/WriteProcessMemoryT對 4GB 以下的低地址走標準ReadProcessMemory/WriteProcessMemory快速路徑目標本身也是 WOW64 進程時高地址則通過 Blackbone 動態(tài)導入的NtWow64ReadVirtualMemory64/NtWow64WriteVirtualMemory64處理見 Wow64Subsystem.cppGetThreadContextT/SetThreadContextT通過X64Call調用NtGetContextThread/NtSetContextThread讀寫 x64 上下文同時保留了對_CONTEXT32的重載見 Wow64Subsystem.cppgetPEB/getTEB借助NtWow64QueryInformationProcess64、NtWow64ReadVirtualMemory64讀取目標的_PEB64/_TEB64其結構直接取自 WOW64Ext 的模板化定義見 Wow64Subsystem.cppCreateRemoteThreadT、QueueApcT、SetProcessInfoT同樣通過X64Call調用NtCreateThreadEx、NtQueueApcThread、NtSetInformationProcess等 x64 函數(shù)見 Wow64Subsystem.cpp。由此可以推斷WOW64Ext 提供的X64CallGetProcAddress64 64 位結構定義三件套是 Blackbone 實現(xiàn)Manage process through WOW64 barrier見 README.md這一核心特性的直接依賴。32 位 Blackbone 進程正是憑借這套機制才能對原生 x64 目標進程完成注入、Hook、遠程調用等整套操作。集成到自有項目時的注意事項使用前提本庫僅適用于 x86 程序且宿主系統(tǒng)必須是 x64 Windows。X64Call與GetModuleHandle64在非 WOW64 環(huán)境下直接返回 0見 wow64ext.cpp參數(shù)位寬所有傳給X64Call的參數(shù)必須以(DWORD64)顯式轉換指針參數(shù)傳遞(DWORD64)var這是最常見的誤用點棧對齊X64Call內部已處理 16 字節(jié)對齊與棧平衡調用方無需干預但被調用的 x64 函數(shù)必須遵循標準 x64 調用約定錯誤處理內存類 API 遵循 Win32 慣例——失敗返回 0/FALSE并設置線程本地錯誤碼可用GetLastError()獲取結構布局使用PEB64、TEB64、LDR_DATA_TABLE_ENTRY64等結構時注意它們按#pragma pack(1)單字節(jié)對齊定義字段布局需與實際目標系統(tǒng)版本核對授權該第三方庫以 LGPL-3.0 授權見 lgpl-3.0.txt作為 Blackbone 的 3rd_party 依賴隨項目分發(fā)。小結WOW64Ext 以極小的代碼規(guī)模解決了 32 位進程與 64 位進程之間的位寬鴻溝X64Call提供模式切換能力GetModuleHandle64/GetProcAddress64打通 x64 模塊與導出解析六個內存 API 覆蓋查詢、分配、釋放、改保護、讀、寫全部虛擬內存操作兩個上下文 API 實現(xiàn) x64 線程上下文的讀寫模板化結構定義則讓 PEB/TEB 的訪問不再依賴 64 位 SDK。在本倉庫 Blackbone 中它已作為NativeWow64子系統(tǒng)的基石被實際編譯與使用是理解跨 WOW64 進程操作技術的絕佳學習樣本也是一份可直接復用的 32 位/64 位混合內存操作工具箱。贊分享網絡安全【免費下載鏈接】BlackboneWindows memory hacking library項目地址https://gitcode.com/gh_mirrors/bl/Blackbone點擊查看免費下載相關推薦Blackbone WOW64子系統(tǒng)跨越32位與64位進程屏障的終極指南Blackbone WOW64子系統(tǒng)跨越32位與64位進程屏障的終極指南 Blackbone是一款強大的Windows內存操作庫而其中的WOW64子系統(tǒng)更是網絡安全inih輕量級 C 語言 INI 解析器詳解及其在 mGBA 中的集成實踐inih輕量級 C 語言 INI 解析器詳解及其在 mGBA 中的集成實踐 導讀 inihINI Not Invented Here是一個用純 C 編寫的游戲開發(fā)深入解析 Go 版 XXH3 哈希庫zeebo/xxh3及其在 Cloudpods 中的 UUID 生成實踐深入解析 Go 版 XXH3 哈希庫zeebo/xxh3及其在 Cloudpods 中的 UUID 生成實踐 XXH3 是知名非加密哈希算法 xxHash后端云原生運維虛擬化人工智能AI 應用上一篇如何快速提取微信聊天記錄3步實現(xiàn)數(shù)據(jù)永久保存的完整指南下一篇伊斯蘭星形圖案二在 p5.js 中利用正弦定理精確計算 Hankin 長度的鋪貼算法優(yōu)化創(chuàng)作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考