├── .gitattributes ├── .github └── workflows │ ├── driver.yaml │ └── lib.yaml ├── .gitignore ├── BlackBone.sln ├── DIA ├── Win32 │ ├── msdia140.dll │ └── symsrv.dll └── x64 │ ├── msdia140.dll │ └── symsrv.dll ├── LICENSE ├── README.md ├── Testing ├── TestDll32.dll ├── TestDll64.dll ├── TestHelper32.exe └── TestHelper64.exe └── src ├── 3rd_party ├── AsmJit │ ├── ApiBegin.h │ ├── ApiEnd.h │ ├── AsmJit.h │ ├── Build.h │ ├── Config.h │ ├── LICENSE.md │ ├── README.md │ ├── base.h │ ├── base │ │ ├── assembler.cpp │ │ ├── assembler.h │ │ ├── codegen.cpp │ │ ├── codegen.h │ │ ├── compiler.cpp │ │ ├── compiler.h │ │ ├── constpool.cpp │ │ ├── constpool.h │ │ ├── containers.cpp │ │ ├── containers.h │ │ ├── context.cpp │ │ ├── context_p.h │ │ ├── cpuinfo.cpp │ │ ├── cpuinfo.h │ │ ├── cputicks.cpp │ │ ├── cputicks.h │ │ ├── error.cpp │ │ ├── error.h │ │ ├── globals.cpp │ │ ├── globals.h │ │ ├── intutil.cpp │ │ ├── intutil.h │ │ ├── lock.h │ │ ├── logger.cpp │ │ ├── logger.h │ │ ├── operand.cpp │ │ ├── operand.h │ │ ├── runtime.cpp │ │ ├── runtime.h │ │ ├── string.cpp │ │ ├── string.h │ │ ├── vectypes.h │ │ ├── vmem.cpp │ │ ├── vmem.h │ │ ├── zone.cpp │ │ └── zone.h │ ├── host.h │ ├── x86.h │ └── x86 │ │ ├── x86assembler.cpp │ │ ├── x86assembler.h │ │ ├── x86compiler.cpp │ │ ├── x86compiler.h │ │ ├── x86context.cpp │ │ ├── x86context_p.h │ │ ├── x86cpuinfo.cpp │ │ ├── x86cpuinfo.h │ │ ├── x86inst.cpp │ │ ├── x86inst.h │ │ ├── x86operand.cpp │ │ ├── x86operand.h │ │ ├── x86operand_regs.cpp │ │ ├── x86scheduler.cpp │ │ └── x86scheduler_p.h ├── BeaEngine │ ├── Warning_for_C_coders.txt │ ├── Win32 │ │ ├── Dll │ │ │ ├── BeaEngine.dll │ │ │ ├── BeaEngine.exp │ │ │ ├── BeaEngine.lib │ │ │ ├── BeaEngineCheetah.dll │ │ │ ├── BeaEngineCheetah.exp │ │ │ └── BeaEngineCheetah.lib │ │ └── Lib │ │ │ ├── BeaEngine.lib │ │ │ └── BeaEngineCheetah.lib │ ├── Win64 │ │ ├── Dll │ │ │ ├── BeaEngine64.dll │ │ │ ├── BeaEngine64.exp │ │ │ ├── BeaEngine64.lib │ │ │ ├── BeaEngineCheetah64.dll │ │ │ ├── BeaEngineCheetah64.exp │ │ │ └── BeaEngineCheetah64.lib │ │ └── Lib │ │ │ ├── BeaEngine64.lib │ │ │ └── BeaEngineCheetah64.lib │ └── headers │ │ ├── BeaEngine.h │ │ └── Includes │ │ ├── basic_types.h │ │ └── export.h ├── CorError.h ├── DIA │ ├── cvconst.h │ ├── dia2.h │ ├── diacreate.h │ └── lib │ │ ├── amd64 │ │ └── diaguids.lib │ │ └── diaguids.lib ├── VersionApi.h ├── cor.h ├── corhdr.h ├── gchost.h ├── ivalidator.h ├── ivehandler.h ├── metahost.h ├── mscoree.h ├── rewolf-wow64ext │ ├── .gitignore │ ├── .hgignore │ ├── README.md │ ├── doc │ │ └── wow64ext.txt │ ├── lgpl-3.0.txt │ ├── sample │ │ ├── build.bat │ │ └── main.cpp │ └── src │ │ ├── CMemPtr.h │ │ ├── internal.h │ │ ├── resource.h │ │ ├── wow64ext.cpp │ │ ├── wow64ext.h │ │ ├── wow64ext.rc │ │ ├── wow64ext.sln │ │ └── wow64ext.vcxproj ├── winapifamily.h └── winpackagefamily.h ├── BlackBone ├── Asm │ ├── AsmFactory.h │ ├── AsmHelper32.cpp │ ├── AsmHelper32.h │ ├── AsmHelper64.cpp │ ├── AsmHelper64.h │ ├── AsmStack.hpp │ ├── AsmVariant.hpp │ ├── IAsmHelper.h │ ├── LDasm.c │ └── LDasm.h ├── BlackBone.vcxproj ├── BlackBone.vcxproj.filters ├── CMakeLists.txt ├── Config.h ├── DllMain.cpp ├── DriverControl │ ├── DriverControl.cpp │ └── DriverControl.h ├── Exports.def ├── Include │ ├── ApiSet.h │ ├── CallResult.h │ ├── FunctionTypes.h │ ├── HandleGuard.h │ ├── Macro.h │ ├── NativeEnums.h │ ├── NativeStructures.h │ ├── Types.h │ ├── Win7Specific.h │ ├── Win8Specific.h │ ├── WinXPSpecific.h │ └── Winheaders.h ├── LocalHook │ ├── HookHandlerCdecl.h │ ├── HookHandlerFastcall.h │ ├── HookHandlerStdcall.h │ ├── HookHandlerThiscall.h │ ├── HookHandlers.h │ ├── LocalHook.hpp │ ├── LocalHookBase.cpp │ ├── LocalHookBase.h │ ├── TraceHook.cpp │ ├── TraceHook.h │ └── VTableHook.hpp ├── ManualMap │ ├── MExcept.cpp │ ├── MExcept.h │ ├── MMap.cpp │ ├── MMap.h │ └── Native │ │ ├── NtLoader.cpp │ │ └── NtLoader.h ├── Misc │ ├── DynImport.h │ ├── InitOnce.cpp │ ├── InitOnce.h │ ├── NameResolve.cpp │ ├── NameResolve.h │ ├── Thunk.hpp │ ├── Trace.hpp │ ├── Utils.cpp │ └── Utils.h ├── PE │ ├── ImageNET.cpp │ ├── ImageNET.h │ ├── PEImage.cpp │ └── PEImage.h ├── Patterns │ ├── PatternSearch.cpp │ └── PatternSearch.h ├── Process │ ├── MemBlock.cpp │ ├── MemBlock.h │ ├── MultPtr.hpp │ ├── Process.cpp │ ├── Process.h │ ├── ProcessCore.cpp │ ├── ProcessCore.h │ ├── ProcessMemory.cpp │ ├── ProcessMemory.h │ ├── ProcessModules.cpp │ ├── ProcessModules.h │ ├── RPC │ │ ├── RemoteContext.hpp │ │ ├── RemoteExec.cpp │ │ ├── RemoteExec.h │ │ ├── RemoteFunction.hpp │ │ ├── RemoteHook.cpp │ │ ├── RemoteHook.h │ │ ├── RemoteLocalHook.cpp │ │ ├── RemoteLocalHook.h │ │ ├── RemoteMemory.cpp │ │ └── RemoteMemory.h │ └── Threads │ │ ├── Thread.cpp │ │ ├── Thread.h │ │ ├── Threads.cpp │ │ └── Threads.h ├── Subsystem │ ├── NativeSubsystem.cpp │ ├── NativeSubsystem.h │ ├── Wow64Subsystem.cpp │ ├── Wow64Subsystem.h │ ├── x86Subsystem.cpp │ └── x86Subsystem.h ├── Symbols │ ├── PDBHelper.cpp │ ├── PDBHelper.h │ ├── PatternLoader.cpp │ ├── PatternLoader.h │ ├── SymbolData.cpp │ ├── SymbolData.h │ ├── SymbolLoader.cpp │ └── SymbolLoader.h └── Syscalls │ ├── Syscall.h │ ├── Syscall32.asm │ └── Syscall64.asm ├── BlackBoneDrv ├── BlackBoneDef.h ├── BlackBoneDrv.c ├── BlackBoneDrv.h ├── BlackBoneDrv.sln ├── BlackBoneDrv.vcxproj ├── BlackBoneDrv.vcxproj.filters ├── Dispatch.c ├── Imports.h ├── Inject.c ├── Loader.c ├── Loader.h ├── MMap.c ├── NativeEnums.h ├── NativeStructs.h ├── NativeStructs10.h ├── NativeStructs7.h ├── NativeStructs8.h ├── NativeStructs81.h ├── NotifyRoutine.c ├── PEStructs.h ├── Private.c ├── Private.h ├── Remap.c ├── Remap.h ├── Routines.c ├── Routines.h ├── Utils.c ├── Utils.h ├── VadHelpers.c ├── VadHelpers.h ├── VadRoutines.c ├── VadRoutines.h ├── apiset.h ├── bin │ └── x64 │ │ ├── Win10Release │ │ └── BlackBoneDrv10.sys │ │ ├── Win7Release │ │ └── BlackBoneDrv7.sys │ │ ├── Win8.1Release │ │ └── BlackBoneDrv81.sys │ │ └── Win8Release │ │ └── BlackBoneDrv8.sys └── ldrreloc.c ├── BlackBoneTest ├── BlackBoneTest.vcxproj ├── BlackBoneTest.vcxproj.filters ├── Common.h ├── TestAsmJit.cpp ├── TestAsmVariant.cpp ├── TestBasic.cpp ├── TestDriver.cpp ├── TestGuard.cpp ├── TestLocalHook.cpp ├── TestManualMap.cpp ├── TestModules.cpp ├── TestMultiPtr.cpp ├── TestPatternScan.cpp ├── TestRemoteCall.cpp ├── TestRemoteHook.cpp ├── TestRemoteMemory.cpp ├── TestSymbols.cpp └── TestSyscall.cpp ├── CMakeLists.txt ├── PythonicBlackBone ├── BlackBone.py ├── __pycache__ │ └── BlackBone.cpython-38.pyc └── test │ └── ReadWriteProcMem.py └── Samples ├── CMakeLists.txt ├── Main.cpp ├── ManualMap.cpp ├── Samples.vcxproj └── Samples.vcxproj.filters /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.github/workflows/driver.yaml: -------------------------------------------------------------------------------- 1 | name: Driver 2 | on: 3 | push: 4 | paths: 5 | - '.github/**' 6 | - 'src/BlackBoneDrv/**' 7 | 8 | jobs: 9 | driver: 10 | name: Build driver 11 | strategy: 12 | matrix: 13 | configuration: [Win10Release, 'Win8.1 Release', 'Win8 Release', 'Win7 Release'] 14 | runs-on: windows-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v1 18 | - name: Add msbuild to PATH 19 | uses: microsoft/setup-msbuild@v1.0.2 20 | - name: Build 21 | shell: cmd 22 | run: | 23 | MSBuild.exe src\BlackBoneDrv\BlackBoneDrv.sln /p:Platform="x64" /p:Configuration="${{ matrix.configuration }}" 24 | -------------------------------------------------------------------------------- /.github/workflows/lib.yaml: -------------------------------------------------------------------------------- 1 | name: Library 2 | on: 3 | push: 4 | paths: 5 | - '.github/**' 6 | - 'src/**' 7 | - '!src/BlackBoneDrv/**' 8 | 9 | jobs: 10 | library: 11 | name: Build and test library 12 | strategy: 13 | matrix: 14 | platfom: [win32, x64] 15 | configuration: [Release, Release(DLL)] 16 | runs-on: windows-latest 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v1 20 | - name: Add msbuild to PATH 21 | uses: microsoft/setup-msbuild@v1.0.2 22 | - name: Add VSTest to PATH 23 | uses: darenm/Setup-VSTest@v1 24 | - name: Build 25 | shell: cmd 26 | run: | 27 | MSBuild.exe BlackBone.sln /p:CI=true /p:Platform="${{ matrix.platfom }}" /p:Configuration="${{ matrix.configuration }}" 28 | - name: Test 29 | shell: cmd 30 | run: | 31 | vstest.console.exe "build/${{ matrix.platfom }}/${{ matrix.configuration }}/BlackboneTest.dll" 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #OS junk files 2 | [Tt]humbs.db 3 | *.DS_Store 4 | 5 | #Visual Studio files 6 | *.[Oo]bj 7 | *.user 8 | *.aps 9 | *.pch 10 | *.vspscc 11 | *.vssscc 12 | *_i.c 13 | *_p.c 14 | *.ncb 15 | *.suo 16 | *.tlb 17 | *.tlh 18 | *.bak 19 | *.[Cc]ache 20 | *.ilk 21 | *.log 22 | *.tlog 23 | *.pdb 24 | *.cer 25 | *.lib 26 | *.sbr 27 | *.sdf 28 | *.opensdf 29 | *.unsuccessfulbuild 30 | *.lastbuildstate 31 | ipch/ 32 | obj/ 33 | cmake/ 34 | [Bb]in 35 | [Dd]ebug*/ 36 | [Rr]elease*/ 37 | Ankh.NoLoad 38 | 39 | #MonoDevelop 40 | *.pidb 41 | *.userprefs 42 | 43 | #Tooling 44 | _ReSharper*/ 45 | *.resharper 46 | [Tt]est[Rr]esult* 47 | *.sass-cache 48 | 49 | #Project files 50 | [Bb]uild/ 51 | obj/ 52 | 53 | #Subversion files 54 | .svn 55 | 56 | # Office Temp Files 57 | ~$* 58 | 59 | #NuGet 60 | packages/ 61 | 62 | #ncrunch 63 | *ncrunch* 64 | *crunch*.local.xml 65 | 66 | # visual studio database projects 67 | *.dbmdl 68 | 69 | #Test files 70 | *.testsettings 71 | 72 | #Generated libraries 73 | *.dll 74 | *.bin 75 | *.sys 76 | #and files 77 | GeneratedFiles*/ 78 | 79 | *.ggpk 80 | *.idb 81 | *.opendb 82 | *.db 83 | *.sqlite 84 | /.vs 85 | *.db-shm 86 | *.db-wal 87 | *.json 88 | -------------------------------------------------------------------------------- /DIA/Win32/msdia140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/DIA/Win32/msdia140.dll -------------------------------------------------------------------------------- /DIA/Win32/symsrv.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/DIA/Win32/symsrv.dll -------------------------------------------------------------------------------- /DIA/x64/msdia140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/DIA/x64/msdia140.dll -------------------------------------------------------------------------------- /DIA/x64/symsrv.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/DIA/x64/symsrv.dll -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 DarthTon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Blackbone 2 | 3 | ### Windows memory hacking library 4 | 5 | ## Features 6 | 7 | - **x86 and x64 support** 8 | 9 | **Process interaction** 10 | - Manage PEB32/PEB64 11 | - Manage process through WOW64 barrier 12 | 13 | **Process Memory** 14 | - Allocate and free virtual memory 15 | - Change memory protection 16 | - Read/Write virtual memory 17 | 18 | **Process modules** 19 | - Enumerate all (32/64 bit) modules loaded. Enumerate modules using Loader list/Section objects/PE headers methods. 20 | - Get exported function address 21 | - Get the main module 22 | - Unlink module from loader lists 23 | - Inject and eject modules (including pure IL images) 24 | - Inject 64bit modules into WOW64 processes 25 | - Manually map native PE images 26 | 27 | **Threads** 28 | - Enumerate threads 29 | - Create and terminate threads. Support for cross-session thread creation. 30 | - Get thread exit code 31 | - Get main thread 32 | - Manage TEB32/TEB64 33 | - Join threads 34 | - Suspend and resume threads 35 | - Set/Remove hardware breakpoints 36 | 37 | **Pattern search** 38 | - Search for arbitrary pattern in local or remote process 39 | 40 | **Remote code execution** 41 | - Execute functions in remote process 42 | - Assemble own code and execute it remotely 43 | - Support for cdecl/stdcall/thiscall/fastcall conventions 44 | - Support for arguments passed by value, pointer or reference, including structures 45 | - FPU types are supported 46 | - Execute code in new thread or any existing one 47 | 48 | **Remote hooking** 49 | - Hook functions in remote process using int3 or hardware breakpoints 50 | - Hook functions upon return 51 | 52 | **Manual map features** 53 | - x86 and x64 image support 54 | - Mapping into any arbitrary unprotected process 55 | - Section mapping with proper memory protection flags 56 | - Image relocations (only 2 types supported. I haven't seen a single PE image with some other relocation types) 57 | - Imports and Delayed imports are resolved 58 | - Bound import is resolved as a side effect, I think 59 | - Module exports 60 | - Loading of forwarded export images 61 | - Api schema name redirection 62 | - SxS redirection and isolation 63 | - Activation context support 64 | - Dll path resolving similar to native load order 65 | - TLS callbacks. Only for one thread and only with PROCESS_ATTACH/PROCESS_DETACH reasons. 66 | - Static TLS 67 | - Exception handling support (SEH and C++) 68 | - Adding module to some native loader structures(for basic module api support: GetModuleHandle, GetProcAdress, etc.) 69 | - Security cookie initialization 70 | - C++/CLI images are supported 71 | - Image unloading 72 | - Increase reference counter for import libraries in case of manual import mapping 73 | - Cyclic dependencies are handled properly 74 | 75 | **Driver features** 76 | - Allocate/free/protect user memory 77 | - Read/write user and kernel memory 78 | - Disable permanent DEP for WOW64 processes 79 | - Change process protection flag 80 | - Change handle access rights 81 | - Remap process memory 82 | - Hiding allocated user-mode memory 83 | - User-mode dll injection and manual mapping 84 | - Manual mapping of drivers 85 | 86 | ## Requirements 87 | 88 | - Visual Studio 2017 15.7 or higher 89 | - Windows SDK 10.0.17134 or higher 90 | - WDK 10.0.17134 or higher (driver only) 91 | - VC++ 2017 Libs for Spectre (x86 and x64) 92 | - Visual C++ ATL (x86/x64) with Spectre Mitigations 93 | 94 | ## License 95 | Blackbone is licensed under the MIT License. Dependencies are under their respective licenses. 96 | 97 | ![Library](https://github.com/DarthTon/Blackbone/workflows/Library/badge.svg?branch=master) ![Driver](https://github.com/DarthTon/Blackbone/workflows/Driver/badge.svg?branch=master) 98 | -------------------------------------------------------------------------------- /Testing/TestDll32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/Testing/TestDll32.dll -------------------------------------------------------------------------------- /Testing/TestDll64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/Testing/TestDll64.dll -------------------------------------------------------------------------------- /Testing/TestHelper32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/Testing/TestHelper32.exe -------------------------------------------------------------------------------- /Testing/TestHelper64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/Testing/TestHelper64.exe -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/ApiBegin.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #if !defined(_ASMJIT_BUILD_H) 8 | #include "build.h" 9 | #endif // !_ASMJIT_BUILD_H 10 | 11 | // ============================================================================ 12 | // [MSVC] 13 | // ============================================================================ 14 | 15 | #if defined(_MSC_VER) 16 | // Disable some warnings we know about 17 | # pragma warning(push) 18 | # pragma warning(disable: 4127) // conditional expression is constant 19 | # pragma warning(disable: 4201) // nameless struct/union 20 | # pragma warning(disable: 4244) // '+=' : conversion from 'int' to 'x', possible 21 | // loss of data 22 | # pragma warning(disable: 4251) // struct needs to have dll-interface to be used 23 | // by clients of struct ... 24 | # pragma warning(disable: 4275) // non dll-interface struct ... used as base for 25 | // dll-interface struct 26 | # pragma warning(disable: 4355) // this used in base member initializer list 27 | # pragma warning(disable: 4480) // specifying underlying type for enum 28 | # pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' 29 | 30 | // Rename symbols. 31 | # if !defined(vsnprintf) 32 | # define ASMJIT_DEFINED_VSNPRINTF 33 | # define vsnprintf _vsnprintf 34 | # endif // !vsnprintf 35 | # if !defined(snprintf) 36 | # define ASMJIT_DEFINED_SNPRINTF 37 | # define snprintf _snprintf 38 | # endif // !snprintf 39 | #endif // _MSC_VER 40 | 41 | // ============================================================================ 42 | // [GNUC] 43 | // ============================================================================ 44 | 45 | #if defined(__GNUC__) && !defined(__clang__) 46 | # if __GNUC__ >= 4 && !defined(__MINGW32__) 47 | # pragma GCC visibility push(hidden) 48 | # endif // __GNUC__ >= 4 49 | #endif // __GNUC__ 50 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/ApiEnd.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // ============================================================================ 8 | // [MSVC] 9 | // ============================================================================ 10 | 11 | #if defined(_MSC_VER) 12 | // Pop disabled warnings by ApiBegin.h 13 | # pragma warning(pop) 14 | // Rename symbols back. 15 | # if defined(ASMJIT_DEFINED_VSNPRINTF) 16 | # undef ASMJIT_DEFINED_VSNPRINTF 17 | # undef vsnprintf 18 | # endif // ASMJIT_DEFINED_VSNPRINTF 19 | # if defined(ASMJIT_DEFINED_SNPRINTF) 20 | # undef ASMJIT_DEFINED_SNPRINTF 21 | # undef snprintf 22 | # endif // ASMJIT_DEFINED_SNPRINTF 23 | #endif // _MSC_VER 24 | 25 | // ============================================================================ 26 | // [GNUC] 27 | // ============================================================================ 28 | 29 | #if defined(__GNUC__) && !defined(__clang__) 30 | # if __GNUC__ >= 4 && !defined(__MINGW32__) 31 | # pragma GCC visibility pop 32 | # endif // __GNUC__ >= 4 33 | #endif // __GNUC__ 34 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/Config.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_CONFIG_H 9 | #define _ASMJIT_CONFIG_H 10 | 11 | // This file can be used to modify built-in features of AsmJit. AsmJit is by 12 | // default compiled only for host processor to enable JIT compilation. Both 13 | // Assembler and Compiler code generators are compiled by default. 14 | // 15 | // ASMJIT_BUILD_... flags can be defined to build additional backends that can 16 | // be used for remote code generation. 17 | // 18 | // ASMJIT_DISABLE_... flags can be defined to disable standard features. These 19 | // are handy especially when building asmjit statically and some features are 20 | // not needed or unwanted (like Compiler). 21 | 22 | #ifdef _DEBUG 23 | #define ASMJIT_DEBUG // Define to enable debug-mode. 24 | #else 25 | #define ASMJIT_RELEASE // Define to enable release-mode. 26 | #endif 27 | 28 | // ============================================================================ 29 | // [AsmJit - Build-Type] 30 | // ============================================================================ 31 | 32 | #ifdef BLACKBONE_STATIC 33 | #define ASMJIT_STATIC 34 | #elif BLACKBONE_EXPORTS 35 | #define ASMJIT_EXPORTS 36 | #endif 37 | 38 | // #define ASMJIT_EMBED // Asmjit is embedded (implies ASMJIT_STATIC). 39 | // #define ASMJIT_STATIC // Define to enable static-library build. 40 | 41 | // ============================================================================ 42 | // [AsmJit - Build-Mode] 43 | // ============================================================================ 44 | 45 | // #define ASMJIT_DEBUG // Define to enable debug-mode. 46 | // #define ASMJIT_RELEASE // Define to enable release-mode. 47 | // #define ASMJIT_TRACE // Define to enable tracing. 48 | 49 | // ============================================================================ 50 | // [AsmJit - Features] 51 | // ============================================================================ 52 | 53 | // If none of these is defined AsmJit will select host architecture by default. 54 | #define ASMJIT_BUILD_X86 // Define to enable x86 instruction set (32-bit). 55 | #define ASMJIT_BUILD_X64 // Define to enable x64 instruction set (64-bit). 56 | // #define ASMJIT_BUILD_HOST // Define to enable host instruction set. 57 | 58 | // AsmJit features are enabled by default. 59 | #define ASMJIT_DISABLE_COMPILER // Disable Compiler (completely). 60 | #define ASMJIT_DISABLE_LOGGER // Disable Logger (completely). 61 | #define ASMJIT_DISABLE_NAMES // Disable everything that uses strings 62 | // (instruction names, error names, ...). 63 | 64 | // [Guard] 65 | #endif // _ASMJIT_CONFIG_H 66 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/LICENSE.md: -------------------------------------------------------------------------------- 1 | AsmJit - Complete x86/x64 JIT and Remote Assembler for C++ 2 | Copyright (c) 2008-2014, Petr Kobalicek 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/base.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_BASE_H 9 | #define _ASMJIT_BASE_H 10 | 11 | // [Dependencies - AsmJit] 12 | #include "build.h" 13 | 14 | #include "base/assembler.h" 15 | #include "base/codegen.h" 16 | #include "base/compiler.h" 17 | #include "base/constpool.h" 18 | #include "base/containers.h" 19 | #include "base/cpuinfo.h" 20 | #include "base/cputicks.h" 21 | #include "base/error.h" 22 | #include "base/globals.h" 23 | #include "base/intutil.h" 24 | #include "base/lock.h" 25 | #include "base/logger.h" 26 | #include "base/operand.h" 27 | #include "base/runtime.h" 28 | #include "base/string.h" 29 | #include "base/vectypes.h" 30 | #include "base/vmem.h" 31 | #include "base/zone.h" 32 | 33 | // [Guard] 34 | #endif // _ASMJIT_BASE_H 35 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/base/codegen.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Dependencies - AsmJit] 11 | #include "../base/codegen.h" 12 | #include "../base/intutil.h" 13 | 14 | // [Api-Begin] 15 | #include "../apibegin.h" 16 | 17 | namespace asmjit { 18 | 19 | // ============================================================================ 20 | // [asmjit::CodeGen - Construction / Destruction] 21 | // ============================================================================ 22 | 23 | CodeGen::CodeGen(Runtime* runtime) : 24 | _runtime(runtime), 25 | _logger(NULL), 26 | _errorHandler(NULL), 27 | _baseAddress(runtime->getBaseAddress()), 28 | _arch(kArchNone), 29 | _regSize(0), 30 | _reserved(0), 31 | _features(IntUtil::mask(kCodeGenOptimizedAlign)), 32 | _instOptions(0), 33 | _error(kErrorOk), 34 | _baseZone(16384 - kZoneOverhead) {} 35 | 36 | CodeGen::~CodeGen() { 37 | if (_errorHandler != NULL) 38 | _errorHandler->release(); 39 | } 40 | 41 | // ============================================================================ 42 | // [asmjit::CodeGen - Logging] 43 | // ============================================================================ 44 | 45 | #if !defined(ASMJIT_DISABLE_LOGGER) 46 | Error CodeGen::setLogger(Logger* logger) { 47 | _logger = logger; 48 | return kErrorOk; 49 | } 50 | #endif // !ASMJIT_DISABLE_LOGGER 51 | 52 | // ============================================================================ 53 | // [asmjit::CodeGen - Error] 54 | // ============================================================================ 55 | 56 | Error CodeGen::setError(Error error, const char* message) { 57 | if (error == kErrorOk) { 58 | _error = kErrorOk; 59 | return kErrorOk; 60 | } 61 | 62 | if (message == NULL) { 63 | #if !defined(ASMJIT_DISABLE_NAMES) 64 | message = ErrorUtil::asString(error); 65 | #else 66 | static const char noMessage[] = ""; 67 | message = noMessage; 68 | #endif // ASMJIT_DISABLE_NAMES 69 | } 70 | 71 | // Error handler is called before logger so logging can be skipped if error 72 | // has been handled. 73 | ErrorHandler* handler = _errorHandler; 74 | ASMJIT_TLOG("[ERROR] %s %s\n", message, !handler ? "(Possibly unhandled?)" : ""); 75 | 76 | if (handler != NULL && handler->handleError(error, message)) 77 | return error; 78 | 79 | #if !defined(ASMJIT_DISABLE_LOGGER) 80 | Logger* logger = _logger; 81 | if (logger != NULL) { 82 | logger->logFormat(kLoggerStyleComment, 83 | "*** ERROR: %s (%u).\n", message, static_cast(error)); 84 | } 85 | #endif // !ASMJIT_DISABLE_LOGGER 86 | 87 | // The handler->handleError() function may throw an exception or longjmp() 88 | // to terminate the execution of setError(). This is the reason why we have 89 | // delayed changing the _error member until now. 90 | _error = error; 91 | 92 | return error; 93 | } 94 | 95 | Error CodeGen::setErrorHandler(ErrorHandler* handler) { 96 | ErrorHandler* oldHandler = _errorHandler; 97 | 98 | if (oldHandler != NULL) 99 | oldHandler->release(); 100 | 101 | if (handler != NULL) 102 | handler = handler->addRef(); 103 | 104 | _errorHandler = handler; 105 | return kErrorOk; 106 | } 107 | 108 | } // asmjit namespace 109 | 110 | // [Api-End] 111 | #include "../apiend.h" 112 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/base/containers.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Dependencies - AsmJit] 11 | #include "../base/containers.h" 12 | #include "../base/intutil.h" 13 | 14 | // [Api-Begin] 15 | #include "../apibegin.h" 16 | 17 | namespace asmjit { 18 | 19 | // ============================================================================ 20 | // [asmjit::PodVectorBase - NullData] 21 | // ============================================================================ 22 | 23 | const PodVectorData PodVectorBase::_nullData = { 0, 0 }; 24 | 25 | // ============================================================================ 26 | // [asmjit::PodVectorBase - Reset] 27 | // ============================================================================ 28 | 29 | //! Clear vector data and free internal buffer. 30 | void PodVectorBase::reset(bool releaseMemory) { 31 | PodVectorData* d = _d; 32 | 33 | if (d == &_nullData) 34 | return; 35 | 36 | if (releaseMemory) { 37 | ASMJIT_FREE(d); 38 | _d = const_cast(&_nullData); 39 | return; 40 | } 41 | 42 | d->length = 0; 43 | } 44 | 45 | // ============================================================================ 46 | // [asmjit::PodVectorBase - Helpers] 47 | // ============================================================================ 48 | 49 | Error PodVectorBase::_grow(size_t n, size_t sizeOfT) { 50 | PodVectorData* d = _d; 51 | 52 | size_t threshold = kMemAllocGrowMax / sizeOfT; 53 | size_t capacity = d->capacity; 54 | size_t after = d->length; 55 | 56 | if (IntUtil::maxUInt() - n < after) 57 | return kErrorNoHeapMemory; 58 | 59 | after += n; 60 | 61 | if (capacity >= after) 62 | return kErrorOk; 63 | 64 | // PodVector is used as a linear array for some data structures used by 65 | // AsmJit code generation. The purpose of this agressive growing schema 66 | // is to minimize memory reallocations, because AsmJit code generation 67 | // classes live short life and will be freed or reused soon. 68 | if (capacity < 32) 69 | capacity = 32; 70 | else if (capacity < 128) 71 | capacity = 128; 72 | else if (capacity < 512) 73 | capacity = 512; 74 | 75 | while (capacity < after) { 76 | if (capacity < threshold) 77 | capacity *= 2; 78 | else 79 | capacity += threshold; 80 | } 81 | 82 | return _reserve(capacity, sizeOfT); 83 | } 84 | 85 | Error PodVectorBase::_reserve(size_t n, size_t sizeOfT) { 86 | PodVectorData* d = _d; 87 | 88 | if (d->capacity >= n) 89 | return kErrorOk; 90 | 91 | size_t nBytes = sizeof(PodVectorData) + n * sizeOfT; 92 | if (nBytes < n) 93 | return kErrorNoHeapMemory; 94 | 95 | if (d == &_nullData) { 96 | d = static_cast(ASMJIT_ALLOC(nBytes)); 97 | if (d == NULL) 98 | return kErrorNoHeapMemory; 99 | d->length = 0; 100 | } 101 | else { 102 | d = static_cast(ASMJIT_REALLOC(d, nBytes)); 103 | if (d == NULL) 104 | return kErrorNoHeapMemory; 105 | } 106 | 107 | d->capacity = n; 108 | _d = d; 109 | 110 | return kErrorOk; 111 | } 112 | 113 | } // asmjit namespace 114 | 115 | // [Api-End] 116 | #include "../apiend.h" 117 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/base/cpuinfo.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Dependencies - AsmJit] 11 | #include "../base/cpuinfo.h" 12 | 13 | #if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) 14 | #include "../x86/x86cpuinfo.h" 15 | #else 16 | // ? 17 | #endif // ASMJIT_HOST || ASMJIT_HOST_X64 18 | 19 | // [Dependencies - Posix] 20 | #if defined(ASMJIT_OS_POSIX) 21 | # include 22 | # include 23 | # include 24 | # include 25 | #endif // ASMJIT_OS_POSIX 26 | 27 | // [Api-Begin] 28 | #include "../apibegin.h" 29 | 30 | namespace asmjit { 31 | 32 | // ============================================================================ 33 | // [asmjit::CpuInfo - DetectHwThreadsCount] 34 | // ============================================================================ 35 | 36 | uint32_t CpuInfo::detectHwThreadsCount() { 37 | #if defined(ASMJIT_OS_WINDOWS) 38 | SYSTEM_INFO info; 39 | ::GetSystemInfo(&info); 40 | return info.dwNumberOfProcessors; 41 | #elif defined(ASMJIT_OS_POSIX) && defined(_SC_NPROCESSORS_ONLN) 42 | // It seems that sysconf returns the number of "logical" processors on both 43 | // mac and linux. So we get the number of "online logical" processors. 44 | long res = ::sysconf(_SC_NPROCESSORS_ONLN); 45 | if (res == -1) return 1; 46 | 47 | return static_cast(res); 48 | #else 49 | return 1; 50 | #endif 51 | } 52 | 53 | // ============================================================================ 54 | // [asmjit::CpuInfo - GetHost] 55 | // ============================================================================ 56 | 57 | #if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) 58 | struct AutoX86CpuInfo : public X86CpuInfo { 59 | ASMJIT_INLINE AutoX86CpuInfo() : X86CpuInfo() { 60 | X86CpuUtil::detect(this); 61 | } 62 | }; 63 | #else 64 | #error "AsmJit - Unsupported CPU." 65 | #endif // ASMJIT_HOST || ASMJIT_HOST_X64 66 | 67 | const CpuInfo* CpuInfo::getHost() { 68 | #if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) 69 | static AutoX86CpuInfo cpuInfo; 70 | #else 71 | #error "AsmJit - Unsupported CPU." 72 | #endif // ASMJIT_HOST || ASMJIT_HOST_X64 73 | return &cpuInfo; 74 | } 75 | 76 | } // asmjit namespace 77 | 78 | // [Api-End] 79 | #include "../apiend.h" 80 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/base/cputicks.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Dependencies - AsmJit] 11 | #include "../base/cputicks.h" 12 | 13 | // [Dependencies - Posix] 14 | #if defined(ASMJIT_OS_POSIX) 15 | # include 16 | # include 17 | #endif // ASMJIT_OS_POSIX 18 | 19 | // [Dependencies - Mac] 20 | #if defined(ASMJIT_OS_MAC) 21 | # include 22 | #endif // ASMJIT_OS_MAC 23 | 24 | // [Dependencies - Windows] 25 | #if defined(ASMJIT_OS_WINDOWS) 26 | // `_InterlockedCompareExchange` is only available as intrinsic (MS Compiler). 27 | # if defined(_MSC_VER) 28 | # include 29 | # pragma intrinsic(_InterlockedCompareExchange) 30 | # else 31 | # define _InterlockedCompareExchange InterlockedCompareExchange 32 | # endif // _MSC_VER 33 | #endif // ASMJIT_OS_WINDOWS 34 | 35 | // [Api-Begin] 36 | #include "../apibegin.h" 37 | 38 | namespace asmjit { 39 | 40 | // ============================================================================ 41 | // [asmjit::CpuTicks - Windows] 42 | // ============================================================================ 43 | 44 | #if defined(ASMJIT_OS_WINDOWS) 45 | static volatile uint32_t CpuTicks_hiResOk; 46 | static volatile double CpuTicks_hiResFreq; 47 | 48 | uint32_t CpuTicks::now() { 49 | do { 50 | uint32_t hiResOk = CpuTicks_hiResOk; 51 | 52 | if (hiResOk == 1) { 53 | LARGE_INTEGER now; 54 | if (!::QueryPerformanceCounter(&now)) 55 | break; 56 | return (int64_t)(double(now.QuadPart) / CpuTicks_hiResFreq); 57 | } 58 | 59 | if (hiResOk == 0) { 60 | LARGE_INTEGER qpf; 61 | if (!::QueryPerformanceFrequency(&qpf)) { 62 | _InterlockedCompareExchange((LONG*)&CpuTicks_hiResOk, 0xFFFFFFFF, 0); 63 | break; 64 | } 65 | 66 | LARGE_INTEGER now; 67 | if (!::QueryPerformanceCounter(&now)) { 68 | _InterlockedCompareExchange((LONG*)&CpuTicks_hiResOk, 0xFFFFFFFF, 0); 69 | break; 70 | } 71 | 72 | double freqDouble = double(qpf.QuadPart) / 1000.0; 73 | 74 | CpuTicks_hiResFreq = freqDouble; 75 | _InterlockedCompareExchange((LONG*)&CpuTicks_hiResOk, 1, 0); 76 | 77 | return static_cast( 78 | static_cast(double(now.QuadPart) / freqDouble) & 0xFFFFFFFF); 79 | } 80 | } while (0); 81 | 82 | // Bail to a less precise GetTickCount(). 83 | return ::GetTickCount(); 84 | } 85 | 86 | // ============================================================================ 87 | // [asmjit::CpuTicks - Mac] 88 | // ============================================================================ 89 | 90 | #elif defined(ASMJIT_OS_MAC) 91 | static mach_timebase_info_data_t CpuTicks_machTime; 92 | 93 | uint32_t CpuTicks::now() { 94 | // Initialize the first time CpuTicks::now() is called (See Apple's QA1398). 95 | if (CpuTicks_machTime.denom == 0) { 96 | if (mach_timebase_info(&CpuTicks_machTime) != KERN_SUCCESS); 97 | return 0; 98 | } 99 | 100 | // mach_absolute_time() returns nanoseconds, we need just milliseconds. 101 | uint64_t t = mach_absolute_time() / 1000000; 102 | 103 | t = t * CpuTicks_machTime.numer / CpuTicks_machTime.denom; 104 | return static_cast(t & 0xFFFFFFFFU); 105 | } 106 | 107 | // ============================================================================ 108 | // [asmjit::CpuTicks - Posix] 109 | // ============================================================================ 110 | 111 | #else 112 | uint32_t CpuTicks::now() { 113 | #if defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 114 | struct timespec ts; 115 | 116 | if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) 117 | return 0; 118 | 119 | uint64_t t = (uint64_t(ts.tv_sec ) * 1000) + (uint64_t(ts.tv_nsec) / 1000000); 120 | return static_cast(t & 0xFFFFFFFFU); 121 | #else // _POSIX_MONOTONIC_CLOCK 122 | #error "AsmJit - Unsupported OS." 123 | return 0; 124 | #endif // _POSIX_MONOTONIC_CLOCK 125 | } 126 | #endif // ASMJIT_OS 127 | 128 | } // asmjit namespace 129 | 130 | // [Api-End] 131 | #include "../apiend.h" 132 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/base/cputicks.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_BASE_CPUTICKS_H 9 | #define _ASMJIT_BASE_CPUTICKS_H 10 | 11 | // [Dependencies - AsmJit] 12 | #include "../base/globals.h" 13 | 14 | // [Api-Begin] 15 | #include "../apibegin.h" 16 | 17 | namespace asmjit { 18 | 19 | //! \addtogroup asmjit_base_util 20 | //! \{ 21 | 22 | // ============================================================================ 23 | // [asmjit::CpuTicks] 24 | // ============================================================================ 25 | 26 | //! CPU ticks utilities. 27 | struct CpuTicks { 28 | //! Get the current CPU ticks for benchmarking (1ms resolution). 29 | static ASMJIT_API uint32_t now(); 30 | }; 31 | 32 | //! \} 33 | 34 | } // asmjit namespace 35 | 36 | // [Api-End] 37 | #include "../apiend.h" 38 | 39 | // [Guard] 40 | #endif // _ASMJIT_BASE_CPUTICKS_H 41 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/base/error.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Dependencies - AsmJit] 11 | #include "../base/error.h" 12 | #include "../base/intutil.h" 13 | 14 | // [Api-Begin] 15 | #include "../apibegin.h" 16 | 17 | namespace asmjit { 18 | 19 | // ============================================================================ 20 | // [asmjit::ErrorHandler - Construction / Destruction] 21 | // ============================================================================ 22 | 23 | ErrorHandler::ErrorHandler() {} 24 | ErrorHandler::~ErrorHandler() {} 25 | 26 | // ============================================================================ 27 | // [asmjit::ErrorHandler - Interface] 28 | // ============================================================================ 29 | 30 | ErrorHandler* ErrorHandler::addRef() const { 31 | return const_cast(this); 32 | } 33 | 34 | void ErrorHandler::release() {} 35 | 36 | // ============================================================================ 37 | // [asmjit::ErrorUtil - AsString] 38 | // ============================================================================ 39 | 40 | #if !defined(ASMJIT_DISABLE_NAMES) 41 | static const char errorMessages[] = { 42 | "Ok\0" 43 | "No heap memory\0" 44 | "No virtual memory\0" 45 | "Invalid argument\0" 46 | "Invalid state\0" 47 | "No code generated\0" 48 | "Code too large\0" 49 | "Label already bound\0" 50 | "Unknown instruction\0" 51 | "Illegal instruction\0" 52 | "Illegal addressing\0" 53 | "Illegal displacement\0" 54 | "Overlapped arguments\0" 55 | "Unknown error\0" 56 | }; 57 | 58 | static const char* findPackedString(const char* p, uint32_t id, uint32_t maxId) { 59 | uint32_t i = 0; 60 | 61 | if (id > maxId) 62 | id = maxId; 63 | 64 | while (i < id) { 65 | while (p[0]) 66 | p++; 67 | 68 | p++; 69 | i++; 70 | } 71 | 72 | return p; 73 | } 74 | 75 | const char* ErrorUtil::asString(Error e) { 76 | return findPackedString(errorMessages, e, kErrorCount); 77 | } 78 | #endif // ASMJIT_DISABLE_NAMES 79 | 80 | } // asmjit namespace 81 | 82 | // [Api-End] 83 | #include "../apiend.h" 84 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/base/globals.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Dependencies - AsmJit] 11 | #include "../base/globals.h" 12 | 13 | // [Api-Begin] 14 | #include "../apibegin.h" 15 | 16 | namespace asmjit { 17 | 18 | // ============================================================================ 19 | // [asmjit::Assert] 20 | // ============================================================================ 21 | 22 | void assertionFailed(const char* exp, const char* file, int line) { 23 | ::fprintf(stderr, "Assertion failed: %s\n, file %s, line %d\n", exp, file, line); 24 | ::abort(); 25 | } 26 | 27 | } // asmjit namespace 28 | 29 | // [Api-End] 30 | #include "../apiend.h" 31 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/base/lock.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_BASE_LOCK_H 9 | #define _ASMJIT_BASE_LOCK_H 10 | 11 | // [Dependencies - AsmJit] 12 | #include "../build.h" 13 | 14 | // [Dependencies - Posix] 15 | #if defined(ASMJIT_OS_POSIX) 16 | # include 17 | #endif // ASMJIT_OS_POSIX 18 | 19 | // [Api-Begin] 20 | #include "../apibegin.h" 21 | 22 | namespace asmjit { 23 | 24 | //! \addtogroup asmjit_base_util 25 | //! \{ 26 | 27 | // ============================================================================ 28 | // [asmjit::Lock] 29 | // ============================================================================ 30 | 31 | //! Lock - used in thread-safe code for locking. 32 | struct Lock { 33 | ASMJIT_NO_COPY(Lock) 34 | 35 | // -------------------------------------------------------------------------- 36 | // [Windows] 37 | // -------------------------------------------------------------------------- 38 | 39 | #if defined(ASMJIT_OS_WINDOWS) 40 | typedef CRITICAL_SECTION Handle; 41 | 42 | //! Create a new `Lock` instance. 43 | ASMJIT_INLINE Lock() { InitializeCriticalSection(&_handle); } 44 | //! Destroy the `Lock` instance. 45 | ASMJIT_INLINE ~Lock() { DeleteCriticalSection(&_handle); } 46 | 47 | //! Lock. 48 | ASMJIT_INLINE void lock() { EnterCriticalSection(&_handle); } 49 | //! Unlock. 50 | ASMJIT_INLINE void unlock() { LeaveCriticalSection(&_handle); } 51 | 52 | #endif // ASMJIT_OS_WINDOWS 53 | 54 | // -------------------------------------------------------------------------- 55 | // [Posix] 56 | // -------------------------------------------------------------------------- 57 | 58 | #if defined(ASMJIT_OS_POSIX) 59 | typedef pthread_mutex_t Handle; 60 | 61 | //! Create a new `Lock` instance. 62 | ASMJIT_INLINE Lock() { pthread_mutex_init(&_handle, NULL); } 63 | //! Destroy the `Lock` instance. 64 | ASMJIT_INLINE ~Lock() { pthread_mutex_destroy(&_handle); } 65 | 66 | //! Lock. 67 | ASMJIT_INLINE void lock() { pthread_mutex_lock(&_handle); } 68 | //! Unlock. 69 | ASMJIT_INLINE void unlock() { pthread_mutex_unlock(&_handle); } 70 | #endif // ASMJIT_OS_POSIX 71 | 72 | // -------------------------------------------------------------------------- 73 | // [Accessors] 74 | // -------------------------------------------------------------------------- 75 | 76 | //! Get handle. 77 | ASMJIT_INLINE Handle& getHandle() { 78 | return _handle; 79 | } 80 | //! \overload 81 | ASMJIT_INLINE const Handle& getHandle() const { 82 | return _handle; 83 | } 84 | 85 | // -------------------------------------------------------------------------- 86 | // [Members] 87 | // -------------------------------------------------------------------------- 88 | 89 | //! Handle. 90 | Handle _handle; 91 | }; 92 | 93 | // ============================================================================ 94 | // [asmjit::AutoLock] 95 | // ============================================================================ 96 | 97 | //! Scoped lock. 98 | struct AutoLock { 99 | ASMJIT_NO_COPY(AutoLock) 100 | 101 | // -------------------------------------------------------------------------- 102 | // [Construction / Destruction] 103 | // -------------------------------------------------------------------------- 104 | 105 | //! Autolock `target`, scoped. 106 | ASMJIT_INLINE AutoLock(Lock& target) : _target(target) { 107 | _target.lock(); 108 | } 109 | 110 | //! Autounlock `target`. 111 | ASMJIT_INLINE ~AutoLock() { 112 | _target.unlock(); 113 | } 114 | 115 | // -------------------------------------------------------------------------- 116 | // [Members] 117 | // -------------------------------------------------------------------------- 118 | 119 | //! Pointer to target (lock). 120 | Lock& _target; 121 | }; 122 | 123 | //! \} 124 | 125 | } // asmjit namespace 126 | 127 | // [Api-End] 128 | #include "../apiend.h" 129 | 130 | // [Guard] 131 | #endif // _ASMJIT_BASE_LOCK_H 132 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/base/operand.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Dependencies - AsmJit] 11 | #include "../base/globals.h" 12 | 13 | // [Api-Begin] 14 | #include "../apibegin.h" 15 | 16 | namespace asmjit { 17 | 18 | // ============================================================================ 19 | // [asmjit::Operand] 20 | // ============================================================================ 21 | 22 | // Prevent static initialization. 23 | struct Operand { 24 | uint8_t op; 25 | uint8_t size; 26 | uint8_t reserved_2_1; 27 | uint8_t reserved_3_1; 28 | uint32_t id; 29 | uint64_t reserved_8_8; 30 | }; 31 | 32 | ASMJIT_VAR const Operand noOperand; 33 | const Operand noOperand = { 0, 0, 0, 0, kInvalidValue, 0 }; 34 | 35 | } // asmjit namespace 36 | 37 | // [Api-End] 38 | #include "../apiend.h" 39 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/host.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_HOST_H 9 | #define _ASMJIT_HOST_H 10 | 11 | // [Dependencies - Core] 12 | #include "base.h" 13 | 14 | // ============================================================================ 15 | // [asmjit::host - X86 / X64] 16 | // ============================================================================ 17 | 18 | #if defined(ASMJIT_HOST_X86) || defined(ASMJIT_HOST_X64) 19 | #include "x86.h" 20 | 21 | namespace asmjit { 22 | 23 | // Define `asmjit::host` namespace wrapping `asmjit::x86`. 24 | namespace host { using namespace ::asmjit::x86; } 25 | 26 | // Define host assembler. 27 | typedef X86Assembler HostAssembler; 28 | 29 | // Define host operands. 30 | typedef X86GpReg GpReg; 31 | typedef X86FpReg FpReg; 32 | typedef X86MmReg MmReg; 33 | typedef X86XmmReg XmmReg; 34 | typedef X86YmmReg YmmReg; 35 | typedef X86SegReg SegReg; 36 | typedef X86Mem Mem; 37 | 38 | // Define host utilities. 39 | typedef X86CpuInfo HostCpuInfo; 40 | 41 | // Define host compiler and related. 42 | #if !defined(ASMJIT_DISABLE_COMPILER) 43 | typedef X86Compiler HostCompiler; 44 | typedef X86CallNode HostCallNode; 45 | typedef X86FuncDecl HostFuncDecl; 46 | typedef X86FuncNode HostFuncNode; 47 | 48 | typedef X86GpVar GpVar; 49 | typedef X86MmVar MmVar; 50 | typedef X86XmmVar XmmVar; 51 | typedef X86YmmVar YmmVar; 52 | #endif // !ASMJIT_DISABLE_COMPILER 53 | 54 | } // asmjit namespace 55 | 56 | #endif // ASMJIT_HOST_X86 || ASMJIT_HOST_X64 57 | 58 | // [Guard] 59 | #endif // _ASMJIT_HOST_H 60 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/x86.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_X86_H 9 | #define _ASMJIT_X86_H 10 | 11 | // [Dependencies - AsmJit] 12 | #include "base.h" 13 | 14 | #include "x86/x86assembler.h" 15 | #include "x86/x86compiler.h" 16 | #include "x86/x86cpuinfo.h" 17 | #include "x86/x86inst.h" 18 | #include "x86/x86operand.h" 19 | 20 | // [Guard] 21 | #endif // _ASMJIT_X86_H 22 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/x86/x86operand.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Guard] 11 | #include "../build.h" 12 | #if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64) 13 | 14 | // [Dependencies - AsmJit] 15 | #include "../x86/x86operand.h" 16 | 17 | // [Api-Begin] 18 | #include "../apibegin.h" 19 | 20 | namespace asmjit { 21 | namespace x86 { 22 | 23 | // ============================================================================ 24 | // [asmjit::X86Mem - abs[]] 25 | // ============================================================================ 26 | 27 | X86Mem ptr_abs(Ptr pAbs, int32_t disp, uint32_t size) { 28 | X86Mem m(NoInit); 29 | 30 | m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, 0, kInvalidValue); 31 | m._vmem.index = kInvalidValue; 32 | m._vmem.displacement = static_cast((intptr_t)(pAbs + disp)); 33 | 34 | return m; 35 | } 36 | 37 | X86Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift, int32_t disp, uint32_t size) { 38 | X86Mem m(NoInit); 39 | uint32_t flags = shift << kX86MemShiftIndex; 40 | 41 | if (index.isGp()) 42 | flags |= X86Mem::_getGpdFlags(index); 43 | else if (index.isXmm()) 44 | flags |= kX86MemVSibXmm << kX86MemVSibIndex; 45 | else if (index.isYmm()) 46 | flags |= kX86MemVSibYmm << kX86MemVSibIndex; 47 | 48 | m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, flags, kInvalidValue); 49 | m._vmem.index = index.getRegIndex(); 50 | m._vmem.displacement = static_cast((intptr_t)(pAbs + disp)); 51 | 52 | return m; 53 | } 54 | 55 | #if !defined(ASMJIT_DISABLE_COMPILER) 56 | X86Mem ptr_abs(Ptr pAbs, const X86Var& index, uint32_t shift, int32_t disp, uint32_t size) { 57 | X86Mem m(NoInit); 58 | uint32_t flags = shift << kX86MemShiftIndex; 59 | 60 | const Var& index_ = reinterpret_cast(index); 61 | uint32_t indexRegType = index_.getRegType(); 62 | 63 | if (indexRegType <= kX86RegTypeGpq) 64 | flags |= X86Mem::_getGpdFlags(reinterpret_cast(index)); 65 | else if (indexRegType == kX86RegTypeXmm) 66 | flags |= kX86MemVSibXmm << kX86MemVSibIndex; 67 | else if (indexRegType == kX86RegTypeYmm) 68 | flags |= kX86MemVSibYmm << kX86MemVSibIndex; 69 | 70 | m._init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeAbsolute, flags, kInvalidValue); 71 | m._vmem.index = index_.getId(); 72 | m._vmem.displacement = static_cast((intptr_t)(pAbs + disp)); 73 | 74 | return m; 75 | } 76 | #endif // !ASMJIT_DISABLE_COMPILER 77 | 78 | } // x86 namespace 79 | } // asmjit namespace 80 | 81 | // [Api-End] 82 | #include "../apiend.h" 83 | 84 | // [Guard] 85 | #endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64 86 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/x86/x86scheduler.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Export] 8 | #define ASMJIT_EXPORTS 9 | 10 | // [Guard] 11 | #include "../build.h" 12 | #if !defined(ASMJIT_DISABLE_COMPILER) && (defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)) 13 | 14 | // [Dependencies - AsmJit] 15 | #include "../base/containers.h" 16 | #include "../x86/x86scheduler_p.h" 17 | 18 | // [Api-Begin] 19 | #include "../apibegin.h" 20 | 21 | namespace asmjit { 22 | 23 | // ============================================================================ 24 | // [Internals] 25 | // ============================================================================ 26 | 27 | //! \internal 28 | struct X86ScheduleData { 29 | //! Registers read by the instruction. 30 | X86RegMask regsIn; 31 | //! Registers written by the instruction. 32 | X86RegMask regsOut; 33 | 34 | //! Flags read by the instruction. 35 | uint8_t flagsIn; 36 | //! Flags written by the instruction. 37 | uint8_t flagsOut; 38 | 39 | //! How many `uops` or `cycles` the instruction takes. 40 | uint8_t ops; 41 | //! Instruction latency. 42 | uint8_t latency; 43 | 44 | //! Which ports the instruction can run at. 45 | uint16_t ports; 46 | //! \internal 47 | uint16_t reserved; 48 | 49 | //! All instructions that this instruction depends on. 50 | PodList::Link* dependsOn; 51 | //! All instructions that use the result of this instruction. 52 | PodList::Link* usedBy; 53 | }; 54 | 55 | // ============================================================================ 56 | // [asmjit::X86Scheduler - Construction / Destruction] 57 | // ============================================================================ 58 | 59 | X86Scheduler::X86Scheduler(X86Compiler* compiler, const X86CpuInfo* cpuInfo) : 60 | _compiler(compiler), 61 | _cpuInfo(cpuInfo) {} 62 | X86Scheduler::~X86Scheduler() {} 63 | 64 | // ============================================================================ 65 | // [asmjit::X86Scheduler - Run] 66 | // ============================================================================ 67 | 68 | Error X86Scheduler::run(Node* start, Node* stop) { 69 | /* 70 | ASMJIT_TLOG("[Schedule] === Begin ==="); 71 | 72 | Zone zone(8096 - kZoneOverhead); 73 | Node* node_ = start; 74 | 75 | while (node_ != stop) { 76 | Node* next = node_->getNext(); 77 | ASMJIT_ASSERT(node_->getType() == kNodeTypeInst); 78 | 79 | printf(" %s\n", X86Util::getInstInfo(static_cast(node_)->getInstId()).getInstName()); 80 | node_ = next; 81 | } 82 | 83 | ASMJIT_TLOG("[Schedule] === End ==="); 84 | */ 85 | return kErrorOk; 86 | } 87 | 88 | } // asmjit namespace 89 | 90 | // [Api-End] 91 | #include "../apiend.h" 92 | 93 | // [Guard] 94 | #endif // !ASMJIT_DISABLE_COMPILER && (ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64) 95 | -------------------------------------------------------------------------------- /src/3rd_party/AsmJit/x86/x86scheduler_p.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete x86/x64 JIT and Remote Assembler for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_X86_X86SCHEDULER_P_H 9 | #define _ASMJIT_X86_X86SCHEDULER_P_H 10 | 11 | #include "../build.h" 12 | #if !defined(ASMJIT_DISABLE_COMPILER) 13 | 14 | // [Dependencies - AsmJit] 15 | #include "../x86/x86compiler.h" 16 | #include "../x86/x86context_p.h" 17 | #include "../x86/x86cpuinfo.h" 18 | #include "../x86/x86inst.h" 19 | 20 | // [Api-Begin] 21 | #include "../apibegin.h" 22 | 23 | namespace asmjit { 24 | 25 | // ============================================================================ 26 | // [asmjit::X86Scheduler] 27 | // ============================================================================ 28 | 29 | //! \internal 30 | //! 31 | //! X86 scheduler. 32 | struct X86Scheduler { 33 | // -------------------------------------------------------------------------- 34 | // [Construction / Destruction] 35 | // -------------------------------------------------------------------------- 36 | 37 | X86Scheduler(X86Compiler* compiler, const X86CpuInfo* cpuInfo); 38 | ~X86Scheduler(); 39 | 40 | // -------------------------------------------------------------------------- 41 | // [Run] 42 | // -------------------------------------------------------------------------- 43 | 44 | Error run(Node* start, Node* stop); 45 | 46 | // -------------------------------------------------------------------------- 47 | // [Members] 48 | // -------------------------------------------------------------------------- 49 | 50 | //! Attached compiler. 51 | X86Compiler* _compiler; 52 | //! CPU information used for scheduling. 53 | const X86CpuInfo* _cpuInfo; 54 | }; 55 | 56 | } // asmjit namespace 57 | 58 | // [Api-End] 59 | #include "../apiend.h" 60 | 61 | // [Guard] 62 | #endif // !ASMJIT_DISABLE_COMPILER 63 | #endif // _ASMJIT_X86_X86SCHEDULER_P_H 64 | -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Warning_for_C_coders.txt: -------------------------------------------------------------------------------- 1 | The library included in this package has been compiled using the stdcall convention( to respect habits from previous versions). But, header file is now configured to use by default the DLL version in cdecl convention. 2 | 3 | If you want to use the static library BeaEngine.lib, just add this at the very beginning of your source code : 4 | 5 | #define BEA_ENGINE_STATIC 6 | #define BEA_USE_STDCALL 7 | #include "BeaEngine.h" 8 | -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win32/Dll/BeaEngine.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win32/Dll/BeaEngine.dll -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win32/Dll/BeaEngine.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win32/Dll/BeaEngine.exp -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win32/Dll/BeaEngine.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win32/Dll/BeaEngine.lib -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win32/Dll/BeaEngineCheetah.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win32/Dll/BeaEngineCheetah.dll -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win32/Dll/BeaEngineCheetah.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win32/Dll/BeaEngineCheetah.exp -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win32/Dll/BeaEngineCheetah.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win32/Dll/BeaEngineCheetah.lib -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win32/Lib/BeaEngine.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win32/Lib/BeaEngine.lib -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win32/Lib/BeaEngineCheetah.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win32/Lib/BeaEngineCheetah.lib -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win64/Dll/BeaEngine64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win64/Dll/BeaEngine64.dll -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win64/Dll/BeaEngine64.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win64/Dll/BeaEngine64.exp -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win64/Dll/BeaEngine64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win64/Dll/BeaEngine64.lib -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win64/Dll/BeaEngineCheetah64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win64/Dll/BeaEngineCheetah64.dll -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win64/Dll/BeaEngineCheetah64.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win64/Dll/BeaEngineCheetah64.exp -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win64/Dll/BeaEngineCheetah64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win64/Dll/BeaEngineCheetah64.lib -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win64/Lib/BeaEngine64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win64/Lib/BeaEngine64.lib -------------------------------------------------------------------------------- /src/3rd_party/BeaEngine/Win64/Lib/BeaEngineCheetah64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/BeaEngine/Win64/Lib/BeaEngineCheetah64.lib -------------------------------------------------------------------------------- /src/3rd_party/DIA/diacreate.h: -------------------------------------------------------------------------------- 1 | // diacreate.h - creation helper functions for DIA initialization 2 | //----------------------------------------------------------------- 3 | // 4 | // Copyright Microsoft Corporation. All Rights Reserved. 5 | // 6 | //--------------------------------------------------------------- 7 | #ifndef _DIACREATE_H_ 8 | #define _DIACREATE_H_ 9 | 10 | // 11 | // Create a dia data source object from the dia dll (by dll name - does not access the registry). 12 | // 13 | 14 | HRESULT STDMETHODCALLTYPE NoRegCoCreate( const __wchar_t *dllName, 15 | REFCLSID rclsid, 16 | REFIID riid, 17 | void **ppv); 18 | 19 | #ifndef _NATIVE_WCHAR_T_DEFINED 20 | #ifdef __cplusplus 21 | 22 | HRESULT STDMETHODCALLTYPE NoRegCoCreate( const wchar_t *dllName, 23 | REFCLSID rclsid, 24 | REFIID riid, 25 | void **ppv) 26 | { 27 | return NoRegCoCreate( (const __wchar_t *)dllName, rclsid, riid, ppv ); 28 | } 29 | 30 | #endif 31 | #endif 32 | 33 | 34 | 35 | // 36 | // Create a dia data source object from the dia dll (looks up the class id in the registry). 37 | // 38 | HRESULT STDMETHODCALLTYPE NoOleCoCreate( REFCLSID rclsid, 39 | REFIID riid, 40 | void **ppv); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/3rd_party/DIA/lib/amd64/diaguids.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/DIA/lib/amd64/diaguids.lib -------------------------------------------------------------------------------- /src/3rd_party/DIA/lib/diaguids.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/DIA/lib/diaguids.lib -------------------------------------------------------------------------------- /src/3rd_party/rewolf-wow64ext/.gitignore: -------------------------------------------------------------------------------- 1 | *.opensdf 2 | *.sdf 3 | *.suo 4 | *.obj 5 | *.ilk 6 | *.db 7 | *.user 8 | *.opendb 9 | *.pdb 10 | src/Release/* 11 | src/Debug/* 12 | sample/*.exe 13 | sample/*.dll 14 | sample/*.lib -------------------------------------------------------------------------------- /src/3rd_party/rewolf-wow64ext/.hgignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/rewolf-wow64ext/.hgignore -------------------------------------------------------------------------------- /src/3rd_party/rewolf-wow64ext/README.md: -------------------------------------------------------------------------------- 1 | # rewolf-wow64ext 2 | WOW64Ext is a helper library for x86 programs that runs under WOW64 layer on x64 versions of Microsoft Windows operating systems. It enables x86 applications to read, write and enumerate memory of a native x64 applications. There is also possibility to call any x64 function from 64-bits version of NTDLL through a special function called X64Call(). As a bonus, wow64ext.h contains definitions of some structures that might be useful for programs that want to access PEB, TEB, TIB etc. 3 | -------------------------------------------------------------------------------- /src/3rd_party/rewolf-wow64ext/sample/build.bat: -------------------------------------------------------------------------------- 1 | cl /Zi /D "UNICODE" ../bin/wow64ext.lib main.cpp 2 | -------------------------------------------------------------------------------- /src/3rd_party/rewolf-wow64ext/src/CMemPtr.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * WOW64Ext Library 4 | * 5 | * Copyright (c) 2014 ReWolf 6 | * http://blog.rewolf.pl/ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU Lesser General Public License as published 10 | * by the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | * 21 | */ 22 | #pragma once 23 | 24 | class CMemPtr 25 | { 26 | private: 27 | void** m_ptr; 28 | bool watchActive; 29 | 30 | public: 31 | CMemPtr(void** ptr) : m_ptr(ptr), watchActive(true) {} 32 | 33 | ~CMemPtr() 34 | { 35 | if (*m_ptr && watchActive) 36 | { 37 | free(*m_ptr); 38 | *m_ptr = 0; 39 | } 40 | } 41 | 42 | void disableWatch() { watchActive = false; } 43 | }; 44 | 45 | #define WATCH(ptr) \ 46 | CMemPtr watch_##ptr((void**)&ptr) 47 | 48 | #define DISABLE_WATCH(ptr) \ 49 | watch_##ptr.disableWatch() 50 | -------------------------------------------------------------------------------- /src/3rd_party/rewolf-wow64ext/src/internal.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * WOW64Ext Library 4 | * 5 | * Copyright (c) 2014 ReWolf 6 | * http://blog.rewolf.pl/ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU Lesser General Public License as published 10 | * by the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | * 21 | */ 22 | #pragma once 23 | 24 | #define EMIT(a) __asm __emit (a) 25 | 26 | #define X64_Start_with_CS(_cs) \ 27 | { \ 28 | EMIT(0x6A) EMIT(_cs) /* push _cs */ \ 29 | EMIT(0xE8) EMIT(0) EMIT(0) EMIT(0) EMIT(0) /* call $+5 */ \ 30 | EMIT(0x83) EMIT(4) EMIT(0x24) EMIT(5) /* add dword [esp], 5 */ \ 31 | EMIT(0xCB) /* retf */ \ 32 | } 33 | 34 | #define X64_End_with_CS(_cs) \ 35 | { \ 36 | EMIT(0xE8) EMIT(0) EMIT(0) EMIT(0) EMIT(0) /* call $+5 */ \ 37 | EMIT(0xC7) EMIT(0x44) EMIT(0x24) EMIT(4) EMIT(_cs) EMIT(0) EMIT(0) EMIT(0) /* mov dword [rsp + 4], _cs */ \ 38 | EMIT(0x83) EMIT(4) EMIT(0x24) EMIT(0xD) /* add dword [rsp], 0xD */ \ 39 | EMIT(0xCB) /* retf */ \ 40 | } 41 | 42 | #define X64_Start() X64_Start_with_CS(0x33) 43 | #define X64_End() X64_End_with_CS(0x23) 44 | 45 | #define _RAX 0 46 | #define _RCX 1 47 | #define _RDX 2 48 | #define _RBX 3 49 | #define _RSP 4 50 | #define _RBP 5 51 | #define _RSI 6 52 | #define _RDI 7 53 | #define _R8 8 54 | #define _R9 9 55 | #define _R10 10 56 | #define _R11 11 57 | #define _R12 12 58 | #define _R13 13 59 | #define _R14 14 60 | #define _R15 15 61 | 62 | #define X64_Push(r) EMIT(0x48 | ((r) >> 3)) EMIT(0x50 | ((r) & 7)) 63 | #define X64_Pop(r) EMIT(0x48 | ((r) >> 3)) EMIT(0x58 | ((r) & 7)) 64 | 65 | #define REX_W EMIT(0x48) __asm 66 | 67 | //to fool M$ inline asm compiler I'm using 2 DWORDs instead of DWORD64 68 | //use of DWORD64 will generate wrong 'pop word ptr[]' and it will break stack 69 | union reg64 70 | { 71 | DWORD64 v; 72 | DWORD dw[2]; 73 | }; 74 | -------------------------------------------------------------------------------- /src/3rd_party/rewolf-wow64ext/src/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by wow64ext.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /src/3rd_party/rewolf-wow64ext/src/wow64ext.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/3rd_party/rewolf-wow64ext/src/wow64ext.rc -------------------------------------------------------------------------------- /src/3rd_party/rewolf-wow64ext/src/wow64ext.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wow64ext", "wow64ext.vcxproj", "{9DA7F232-0096-45BC-A452-24C7F3AFA0F8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8}.Debug|Win32.Build.0 = Debug|Win32 16 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8}.Release|Win32.ActiveCfg = Release|Win32 17 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /src/3rd_party/winpackagefamily.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Module Name: 6 | 7 | winpackagefamily.h 8 | 9 | Abstract: 10 | 11 | API family partitioning based on packages. 12 | 13 | */ 14 | 15 | #ifndef _INC_WINPACKAGEFAMILY 16 | #define _INC_WINPACKAGEFAMILY 17 | 18 | #if defined(_MSC_VER) && !defined(MOFCOMP_PASS) 19 | #if _MSC_VER >= 1200 20 | #pragma warning(push) 21 | #pragma warning(disable:4001) /* nonstandard extension 'single line comment' was used */ 22 | #endif 23 | #pragma once 24 | #endif // defined(_MSC_VER) && !defined(MOFCOMP_PASS) 25 | 26 | #ifndef WINAPI_PARTITION_SERVER 27 | #define WINAPI_PARTITION_SERVER (WINAPI_FAMILY == WINAPI_FAMILY_SERVER) 28 | #endif 29 | 30 | /* 31 | * PARTITIONS based on packages are each #undef'ed below, and then will be #define-ed 32 | * to be either 1 or 0 or depending on the active WINAPI_FAMILY. 33 | */ 34 | #undef WINAPI_PARTITION_PKG_WINTRUST 35 | #undef WINAPI_PARTITION_PKG_WEBSERVICES 36 | #undef WINAPI_PARTITION_PKG_EVENTLOGSERVICE 37 | #undef WINAPI_PARTITION_PKG_VHD 38 | #undef WINAPI_PARTITION_PKG_PERFCOUNTER 39 | #undef WINAPI_PARTITION_PKG_SECURESTARTUP 40 | #undef WINAPI_PARTITION_PKG_REMOTEFS 41 | #undef WINAPI_PARTITION_PKG_BOOTABLESKU 42 | #undef WINAPI_PARTITION_PKG_CMDTOOLS 43 | #undef WINAPI_PARTITION_PKG_DISM 44 | #undef WINAPI_PARTITION_PKG_CORESETUP 45 | #undef WINAPI_PARTITION_PKG_APPRUNTIME 46 | #undef WINAPI_PARTITION_PKG_ESENT 47 | #undef WINAPI_PARTITION_PKG_WINMGMT 48 | #undef WINAPI_PARTITION_PKG_WNV 49 | #undef WINAPI_PARTITION_PKG_CLUSTER 50 | #undef WINAPI_PARTITION_PKG_VSS 51 | #undef WINAPI_PARTITION_PKG_TRAFFIC 52 | #undef WINAPI_PARTITION_PKG_ISCSI 53 | #undef WINAPI_PARTITION_PKG_STORAGE 54 | #undef WINAPI_PARTITION_PKG_MPSSVC 55 | #undef WINAPI_PARTITION_PKG_APPXDEPLOYMENT 56 | #undef WINAPI_PARTITION_PKG_WER 57 | 58 | /* 59 | * PARTITIONS for feature packages. Each package might be active for one or more editions 60 | */ 61 | #define WINAPI_PARTITION_PKG_WINTRUST (WINAPI_PARTITION_SERVER == 1) 62 | #define WINAPI_PARTITION_PKG_WEBSERVICES (WINAPI_PARTITION_SERVER == 1) 63 | #define WINAPI_PARTITION_PKG_EVENTLOGSERVICE (WINAPI_PARTITION_SERVER == 1) 64 | #define WINAPI_PARTITION_PKG_VHD (WINAPI_PARTITION_SERVER == 1) 65 | #define WINAPI_PARTITION_PKG_PERFCOUNTER (WINAPI_PARTITION_SERVER == 1) 66 | #define WINAPI_PARTITION_PKG_SECURESTARTUP (WINAPI_PARTITION_SERVER == 1) 67 | #define WINAPI_PARTITION_PKG_REMOTEFS (WINAPI_PARTITION_SERVER == 1) 68 | #define WINAPI_PARTITION_PKG_BOOTABLESKU (WINAPI_PARTITION_SERVER == 1) 69 | #define WINAPI_PARTITION_PKG_CMDTOOLS (WINAPI_PARTITION_SERVER == 1) 70 | #define WINAPI_PARTITION_PKG_DISM (WINAPI_PARTITION_SERVER == 1) 71 | #define WINAPI_PARTITION_PKG_CORESETUP (WINAPI_PARTITION_SERVER == 1) 72 | #define WINAPI_PARTITION_PKG_APPRUNTIME (WINAPI_PARTITION_SERVER == 1) 73 | #define WINAPI_PARTITION_PKG_ESENT (WINAPI_PARTITION_SERVER == 1) 74 | #define WINAPI_PARTITION_PKG_WINMGMT (WINAPI_PARTITION_SERVER == 1) 75 | #define WINAPI_PARTITION_PKG_WNV (WINAPI_PARTITION_SERVER == 1) 76 | #define WINAPI_PARTITION_PKG_CLUSTER (WINAPI_PARTITION_SERVER == 1) 77 | #define WINAPI_PARTITION_PKG_VSS (WINAPI_PARTITION_SERVER == 1) 78 | #define WINAPI_PARTITION_PKG_TRAFFIC (WINAPI_PARTITION_SERVER == 1) 79 | #define WINAPI_PARTITION_PKG_ISCSI (WINAPI_PARTITION_SERVER == 1) 80 | #define WINAPI_PARTITION_PKG_STORAGE (WINAPI_PARTITION_SERVER == 1) 81 | #define WINAPI_PARTITION_PKG_MPSSVC (WINAPI_PARTITION_SERVER == 1) 82 | #define WINAPI_PARTITION_PKG_APPXDEPLOYMENT (WINAPI_PARTITION_SERVER == 1) 83 | #define WINAPI_PARTITION_PKG_WER (WINAPI_PARTITION_SERVER == 1) 84 | 85 | #if defined(_MSC_VER) && !defined(MOFCOMP_PASS) 86 | #if _MSC_VER >= 1200 87 | #pragma warning(pop) 88 | #endif 89 | #endif 90 | 91 | #endif /* !_INC_WINPACKAGEFAMILY */ 92 | -------------------------------------------------------------------------------- /src/BlackBone/Asm/AsmFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Config.h" 3 | #include "../Include/Types.h" 4 | 5 | #include "AsmHelper64.h" 6 | #include "AsmHelper32.h" 7 | 8 | namespace blackbone 9 | { 10 | 11 | using AsmHelperPtr = std::unique_ptr; 12 | 13 | /// 14 | /// Get suitable asm generator 15 | /// 16 | class AsmFactory 17 | { 18 | public: 19 | enum eAsmArch 20 | { 21 | asm32, // x86 22 | asm64 // x86_64 23 | }; 24 | 25 | /// 26 | /// Get suitable asm generator 27 | /// 28 | /// Desired CPU architecture 29 | /// AsmHelperBase interface 30 | static AsmHelperPtr GetAssembler( eAsmArch arch ) 31 | { 32 | switch (arch) 33 | { 34 | case asm32: 35 | return std::make_unique(); 36 | case asm64: 37 | return std::make_unique(); 38 | default: 39 | return nullptr; 40 | } 41 | } 42 | 43 | /// 44 | /// Get suitable asm generator 45 | /// 46 | /// Desired PE module architecture 47 | /// AsmHelperBase interface 48 | static AsmHelperPtr GetAssembler( eModType mt ) 49 | { 50 | if (mt == mt_default) 51 | mt = sizeof( intptr_t ) > sizeof( int32_t ) ? mt_mod64 : mt_mod32; 52 | 53 | switch (mt) 54 | { 55 | case mt_mod32: 56 | return GetAssembler( asm32 ); 57 | case mt_mod64: 58 | return GetAssembler( asm64 ); 59 | default: 60 | return nullptr; 61 | } 62 | } 63 | 64 | /// 65 | /// Get suitable asm generator 66 | /// 67 | /// Target process CPU architecture 68 | /// AsmHelperBase interface 69 | static AsmHelperPtr GetAssembler( bool wow64process ) 70 | { 71 | return GetAssembler( wow64process ? asm32 : asm64 ); 72 | } 73 | 74 | 75 | /// 76 | /// Get default asm generator 77 | /// 78 | /// 79 | static AsmHelperPtr GetAssembler() 80 | { 81 | #ifdef USE64 82 | return std::make_unique(); 83 | #else 84 | return std::make_unique(); 85 | #endif 86 | } 87 | }; 88 | 89 | } -------------------------------------------------------------------------------- /src/BlackBone/Asm/AsmHelper32.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IAsmHelper.h" 4 | 5 | namespace blackbone 6 | { 7 | 8 | /// 9 | /// 32 bit assembler helper 10 | /// 11 | class AsmHelper32 : public IAsmHelper 12 | { 13 | public: 14 | BLACKBONE_API AsmHelper32( ); 15 | BLACKBONE_API ~AsmHelper32( void ); 16 | 17 | /// 18 | /// Generate function prologue code 19 | /// 20 | /// Unused 21 | virtual void GenPrologue( bool switchMode = false ); 22 | 23 | /// 24 | /// Generate function epilogue code 25 | /// 26 | /// Unused 27 | /// Stack change value 28 | virtual void GenEpilogue( bool switchMode = false, int retSize = -1 ); 29 | 30 | /// 31 | /// Generate function call 32 | /// 33 | /// Function pointer 34 | /// Function arguments 35 | /// Calling convention 36 | virtual void GenCall( const AsmFunctionPtr& pFN, const std::vector& args, eCalligConvention cc = cc_stdcall ); 37 | 38 | /// 39 | /// Save eax value and terminate current thread 40 | /// 41 | /// NtTerminateThread address 42 | /// Memory where eax value will be saved 43 | virtual void ExitThreadWithStatus( uint64_t pExitThread, uint64_t resultPtr ); 44 | 45 | /// 46 | /// Save return value and signal thread return event 47 | /// 48 | /// NtSetEvent address 49 | /// Result value memory location 50 | /// Event memory location 51 | /// Error code memory location 52 | /// Return type 53 | virtual void SaveRetValAndSignalEvent( 54 | uint64_t pSetEvent, 55 | uint64_t ResultPtr, 56 | uint64_t EventPtr, 57 | uint64_t errPtr, 58 | eReturnType rtype = rt_int32 59 | ); 60 | 61 | /// 62 | /// Does nothing under x86 63 | /// 64 | /// Unused 65 | virtual void EnableX64CallStack( bool ) { } 66 | 67 | private: 68 | AsmHelper32( const AsmHelper32& ) = delete; 69 | AsmHelper32& operator = (const AsmHelper32&) = delete; 70 | 71 | /// 72 | /// Push function argument 73 | /// 74 | /// Argument. 75 | /// Push type(register or stack) 76 | void PushArg( const AsmVariant& arg, eArgType regidx = at_stack ); 77 | 78 | /// 79 | /// Push argument into function 80 | /// 81 | /// Argument 82 | /// Argument location 83 | template 84 | void PushArgp( _Type arg, eArgType index ); 85 | }; 86 | 87 | } 88 | 89 | -------------------------------------------------------------------------------- /src/BlackBone/Asm/AsmHelper64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IAsmHelper.h" 4 | #include "../Include/Macro.h" 5 | 6 | namespace blackbone 7 | { 8 | 9 | class AsmHelper64 : public IAsmHelper 10 | { 11 | public: 12 | BLACKBONE_API AsmHelper64(); 13 | BLACKBONE_API ~AsmHelper64( void ); 14 | 15 | /// 16 | /// Generate function prologue code 17 | /// 18 | /// true if execution must be swithed to x64 mode 19 | virtual void GenPrologue( bool switchMode = false ); 20 | 21 | /// 22 | /// Generate function epilogue code 23 | /// 24 | /// true if execution must be swithed to x86 mode 25 | /// Stack change value 26 | virtual void GenEpilogue( bool switchMode = false, int retSize = -1 ); 27 | 28 | /// 29 | /// Generate function call 30 | /// 31 | /// Function pointer 32 | /// Function arguments 33 | /// Ignored 34 | virtual void GenCall( const AsmFunctionPtr& pFN, const std::vector& args, eCalligConvention cc = cc_stdcall ); 35 | 36 | /// 37 | /// Save rax value and terminate current thread 38 | /// 39 | /// NtTerminateThread address 40 | /// Memory where rax value will be saved 41 | virtual void ExitThreadWithStatus( uint64_t pExitThread, uint64_t resultPtr ); 42 | 43 | /// 44 | /// Save return value and signal thread return event 45 | /// 46 | /// NtSetEvent address 47 | /// Result value memory location 48 | /// Event memory location 49 | /// Error code memory location 50 | /// Return type 51 | virtual void SaveRetValAndSignalEvent( 52 | uint64_t pSetEvent, 53 | uint64_t ResultPtr, 54 | uint64_t EventPtr, 55 | uint64_t lastStatusPtr, 56 | eReturnType rtype = rt_int32 57 | ); 58 | 59 | /// 60 | /// Set stack reservation policy on call generation 61 | /// 62 | /// 63 | /// If true - stack space will be reserved during each call generation 64 | /// If false - no automatic stack reservation, user must allocate stack by hand 65 | /// 66 | virtual void EnableX64CallStack( bool state ); 67 | 68 | private: 69 | AsmHelper64( const AsmHelper64& ) = delete; 70 | AsmHelper64& operator = (const AsmHelper64&) = delete; 71 | 72 | /// 73 | /// Push function argument 74 | /// 75 | /// Argument. 76 | /// Push type(register or stack) 77 | void PushArg( const AsmVariant& arg, int32_t index ); 78 | 79 | /// 80 | /// Push function argument 81 | /// 82 | /// Argument 83 | /// Argument index 84 | /// true if argument is a floating point value 85 | template 86 | void PushArgp( const _Type& arg, int32_t index, bool fpu = false ); 87 | 88 | private: 89 | bool _stackEnabled; // if true - GenCall will allocate shadow stack space 90 | }; 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/BlackBone/Asm/AsmStack.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma warning(push) 4 | #pragma warning(disable : 4100) 5 | #include "../../3rd_party/AsmJit/AsmJit.h" 6 | #pragma warning(pop) 7 | 8 | #include "../Include/Macro.h" 9 | 10 | #include 11 | 12 | namespace blackbone 13 | { 14 | 15 | class AsmStackAllocator 16 | { 17 | public: 18 | BLACKBONE_API AsmStackAllocator( asmjit::X86Assembler* pAsm, int32_t baseval = 0x28 ) 19 | : _pAsm( pAsm ) 20 | , disp_ofst( pAsm->getArch() == asmjit::kArch::kArchX64 ? baseval : sizeof( uint64_t ) ) 21 | { 22 | } 23 | 24 | /// 25 | /// Allocate stack variable 26 | /// 27 | /// Variable size 28 | /// Variable memory object 29 | BLACKBONE_API asmjit::Mem AllocVar( int32_t size ) 30 | { 31 | bool x64 = _pAsm->getArch() == asmjit::kArch::kArchX64; 32 | 33 | // Align on word length 34 | size = static_cast(Align( size, x64 ? sizeof( uint64_t ) : sizeof( uint32_t ) )); 35 | 36 | asmjit::Mem val; 37 | if (x64) 38 | val = asmjit::Mem( _pAsm->zsp, disp_ofst, size ); 39 | else 40 | val = asmjit::Mem( _pAsm->zbp, -disp_ofst - size, size ); 41 | 42 | disp_ofst += size; 43 | return val; 44 | } 45 | 46 | /// 47 | /// Allocate array of stack variables 48 | /// 49 | /// Output array 50 | /// Array elements count. 51 | /// Element size. 52 | /// true on success 53 | BLACKBONE_API bool AllocArray( asmjit::Mem arr[], int count, int32_t size ) 54 | { 55 | for (int i = 0; i < count; i++) 56 | { 57 | if (_pAsm->getArch() == asmjit::kArch::kArchX64) 58 | arr[i] = asmjit::Mem( _pAsm->zsp, disp_ofst, size ); 59 | else 60 | arr[i] = asmjit::Mem( _pAsm->zbp, -disp_ofst - size, size ); 61 | 62 | disp_ofst += size; 63 | } 64 | 65 | return true; 66 | } 67 | 68 | /// 69 | /// Get total size of all stack variables 70 | /// 71 | /// 72 | BLACKBONE_API inline intptr_t getTotalSize() const { return disp_ofst; }; 73 | 74 | private: 75 | asmjit::X86Assembler* _pAsm; // Underlying assembler 76 | int32_t disp_ofst; // Next variable stack offset 77 | }; 78 | 79 | // 80 | // Helpers 81 | // 82 | #define ALLOC_STACK_VAR(worker, name, type) asmjit::Mem name( worker.AllocVar( sizeof(type) ) ); 83 | #define ALLOC_STACK_VAR_S(worker, name, size) asmjit::Mem name( worker.AllocVar( size ) ); 84 | 85 | #define ALLOC_STACK_ARRAY(worker, name, type, count) \ 86 | asmjit::Mem name[count]; \ 87 | worker.AllocArray( name, count, sizeof(type) ); 88 | 89 | } -------------------------------------------------------------------------------- /src/BlackBone/Asm/IAsmHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AsmVariant.hpp" 4 | #include "AsmStack.hpp" 5 | #include "../Include/Macro.h" 6 | 7 | #include 8 | #include 9 | 10 | namespace blackbone 11 | { 12 | // 13 | // Function calling convention 14 | // 15 | enum eCalligConvention 16 | { 17 | cc_cdecl, // cdecl 18 | cc_stdcall, // stdcall 19 | cc_thiscall, // thiscall 20 | cc_fastcall // fastcall 21 | }; 22 | 23 | // 24 | // Function return type 25 | // Do not change numeric values! 26 | // 27 | enum eReturnType 28 | { 29 | rt_int32 = 4, // 32bit value 30 | rt_int64 = 8, // 64bit value 31 | rt_float = 1, // float value 32 | rt_double = 2, // double value 33 | rt_struct = 3, // structure returned by value 34 | }; 35 | 36 | // Argument pass method 37 | enum eArgType 38 | { 39 | at_ecx = 0, // In ecx 40 | at_edx = 1, // In edx 41 | at_stack = 2, // On stack 42 | }; 43 | 44 | 45 | /// 46 | /// Assembly generation helper 47 | /// 48 | class IAsmHelper 49 | { 50 | public: 51 | BLACKBONE_API IAsmHelper( uint32_t arch = asmjit::kArchHost ) 52 | : _assembler( &_runtime, arch ) { } 53 | 54 | virtual ~IAsmHelper() { } 55 | 56 | virtual void GenPrologue( bool switchMode = false ) = 0; 57 | virtual void GenEpilogue( bool switchMode = false, int retSize = -1) = 0; 58 | virtual void GenCall( const AsmFunctionPtr&, const std::vector& args, eCalligConvention cc = cc_stdcall ) = 0; 59 | virtual void ExitThreadWithStatus( uint64_t pExitThread, uint64_t resultPtr ) = 0; 60 | virtual void SaveRetValAndSignalEvent( uint64_t pSetEvent, uint64_t ResultPtr, uint64_t EventPtr, uint64_t errPtr, eReturnType rtype = rt_int32 ) = 0; 61 | virtual void EnableX64CallStack( bool state ) = 0; 62 | 63 | /// 64 | /// Switch processor into WOW64 emulation mode 65 | /// 66 | BLACKBONE_API void SwitchTo86() 67 | { 68 | asmjit::Label l = _assembler.newLabel(); 69 | 70 | _assembler.call( l ); _assembler.bind( l ); 71 | _assembler.mov( asmjit::host::dword_ptr( asmjit::host::esp, 4 ), 0x23 ); 72 | _assembler.add( asmjit::host::dword_ptr( asmjit::host::esp ), 0xD ); 73 | _assembler.db( 0xCB ); // retf 74 | } 75 | 76 | /// 77 | /// Switch processor into x64 mode (long mode) 78 | /// 79 | BLACKBONE_API void SwitchTo64() 80 | { 81 | asmjit::Label l = _assembler.newLabel(); 82 | 83 | _assembler.push( 0x33 ); 84 | _assembler.call( l ); _assembler.bind( l ); 85 | //_assembler.add( asmjit::host::dword_ptr( asmjit::host::esp ), 5 ); 86 | _assembler.dd( '\x83\x04\x24\x05' ); 87 | _assembler.db( 0xCB ); // retf 88 | } 89 | 90 | BLACKBONE_API inline asmjit::X86Assembler* assembler() { return &_assembler; } 91 | BLACKBONE_API inline asmjit::X86Assembler* operator ->() { return &_assembler; } 92 | 93 | private: 94 | IAsmHelper( const IAsmHelper& ) = delete; 95 | IAsmHelper& operator =(const IAsmHelper&) = delete; 96 | 97 | protected: 98 | asmjit::JitRuntime _runtime; 99 | asmjit::X86Assembler _assembler; 100 | }; 101 | } -------------------------------------------------------------------------------- /src/BlackBone/Asm/LDasm.h: -------------------------------------------------------------------------------- 1 | #ifndef _LDASM_ 2 | #define _LDASM_ 3 | 4 | #include "../Config.h" 5 | #include 6 | #include 7 | 8 | #ifdef USE64 9 | #define is_x64 1 10 | #else 11 | #define is_x64 0 12 | #endif//USE64 13 | 14 | #ifdef __cplusplus 15 | extern "C" 16 | { 17 | #endif 18 | 19 | #define F_INVALID 0x01 20 | #define F_PREFIX 0x02 21 | #define F_REX 0x04 22 | #define F_MODRM 0x08 23 | #define F_SIB 0x10 24 | #define F_DISP 0x20 25 | #define F_IMM 0x40 26 | #define F_RELATIVE 0x80 27 | 28 | typedef struct _ldasm_data 29 | { 30 | uint8_t flags; 31 | uint8_t rex; 32 | uint8_t modrm; 33 | uint8_t sib; 34 | uint8_t opcd_offset; 35 | uint8_t opcd_size; 36 | uint8_t disp_offset; 37 | uint8_t disp_size; 38 | uint8_t imm_offset; 39 | uint8_t imm_size; 40 | } ldasm_data; 41 | 42 | BLACKBONE_API unsigned int __fastcall ldasm( void *code, ldasm_data *ld, uint32_t is64 ); 43 | BLACKBONE_API unsigned long __fastcall SizeOfProc( void *Proc ); 44 | BLACKBONE_API void* __fastcall ResolveJmp( void *Proc ); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif//_LDASM_ -------------------------------------------------------------------------------- /src/BlackBone/Config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Lib/Dll switch 4 | #if !defined(BLACKBONE_EXPORTS) && !defined(BLACKBONE_IMPORTS) && !defined(BLACKBONE_STATIC) 5 | #define BLACKBONE_STATIC 6 | #endif 7 | 8 | #if defined(_MSC_VER) 9 | 10 | #ifndef COMPILER_MSVC 11 | #define COMPILER_MSVC 1 12 | #endif 13 | 14 | #if defined(BLACKBONE_IMPORTS) 15 | #define BLACKBONE_API __declspec(dllimport) 16 | #elif defined(BLACKBONE_EXPORTS) 17 | #define BLACKBONE_API __declspec(dllexport) 18 | #else 19 | #define BLACKBONE_API 20 | #endif 21 | 22 | #elif defined(__GNUC__) 23 | #define COMPILER_GCC 24 | #define BLACKBONE_API 25 | #else 26 | #error "Unknown or unsupported compiler" 27 | #endif 28 | 29 | // No IA64 support 30 | #if defined (_M_AMD64) || defined (__x86_64__) 31 | #define USE64 32 | #elif defined (_M_IX86) || defined (__i386__) 33 | #define USE32 34 | #else 35 | #error "Unknown or unsupported platform" 36 | #endif 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/BlackBone/DllMain.cpp: -------------------------------------------------------------------------------- 1 | #include "Config.h" 2 | #include "Include/Winheaders.h" 3 | 4 | DWORD WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved ) 5 | { 6 | switch (dwReason) 7 | { 8 | case DLL_PROCESS_ATTACH: 9 | case DLL_PROCESS_DETACH: 10 | case DLL_THREAD_ATTACH: 11 | case DLL_THREAD_DETACH: 12 | break; 13 | } 14 | 15 | return TRUE; 16 | } -------------------------------------------------------------------------------- /src/BlackBone/Exports.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | syscall_stub -------------------------------------------------------------------------------- /src/BlackBone/Include/CallResult.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #if _MSC_VER >= 1910 3 | 4 | #include 5 | #include 6 | 7 | namespace blackbone 8 | { 9 | /// 10 | /// Function result or failure status 11 | /// 12 | template 13 | struct call_result_t 14 | { 15 | NTSTATUS status = STATUS_UNSUCCESSFUL; // Execution status 16 | std::optional result_data = std::nullopt; // Returned value 17 | 18 | call_result_t() = default; 19 | 20 | call_result_t( T result_, NTSTATUS status_ = STATUS_SUCCESS ) 21 | : status ( status_ ) 22 | , result_data ( std::move( result_ ) ) 23 | { 24 | assert( result_data.has_value() ); 25 | } 26 | 27 | call_result_t( NTSTATUS status_ ) 28 | : status ( status_ ) 29 | { 30 | assert( status_ != STATUS_SUCCESS ); 31 | } 32 | 33 | inline bool success() const { return NT_SUCCESS( status ); } 34 | inline T& result() { return result_data.value(); } 35 | inline const T& result() const { return result_data.value(); } 36 | inline T result( const T& def_val ) const { return result_data.value_or( def_val ); } 37 | 38 | inline explicit operator bool() const { return NT_SUCCESS( status ); } 39 | inline explicit operator T() const { return result_data.value(); } 40 | 41 | inline T* operator ->() { return &result_data.value(); } 42 | inline T& operator *() { return result_data.value(); } 43 | }; 44 | } 45 | 46 | #else 47 | 48 | #include 49 | #include 50 | 51 | namespace blackbone 52 | { 53 | /// 54 | /// Function result or failure status 55 | /// 56 | template 57 | struct call_result_t 58 | { 59 | NTSTATUS status = STATUS_UNSUCCESSFUL; // Execution status 60 | std::unique_ptr result_data; // Returned value 61 | 62 | call_result_t() = default; 63 | 64 | call_result_t(T result_, NTSTATUS status_ = STATUS_SUCCESS) 65 | : status(status_) 66 | , result_data(std::make_unique(std::move(result_))) 67 | { 68 | assert(result_data.get()); 69 | } 70 | 71 | call_result_t(NTSTATUS status_) 72 | : status(status_) 73 | { 74 | assert(status_ != STATUS_SUCCESS); 75 | } 76 | 77 | 78 | private: 79 | inline T* value() { 80 | if (!result_data) { 81 | throw std::logic_error("bad optional access."); 82 | } 83 | return result_data.get(); 84 | } 85 | public: 86 | 87 | inline bool success() const { return NT_SUCCESS( status ); } 88 | inline T& result() { return *value(); } 89 | inline const T& result() const { return *value(); } 90 | inline T result(const T& def_val) const { return result_data ? *result_data.get() : def_val; } 91 | 92 | inline explicit operator bool() const { return NT_SUCCESS( status ); } 93 | inline explicit operator T() const { return *value(); } 94 | 95 | inline T* operator ->() { return value(); } 96 | inline T& operator *() { return *value(); } 97 | }; 98 | } 99 | #endif -------------------------------------------------------------------------------- /src/BlackBone/Include/HandleGuard.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Winheaders.h" 3 | #include 4 | 5 | namespace blackbone 6 | { 7 | 8 | template 9 | struct non_zero 10 | { 11 | static bool call( T handle ) noexcept 12 | { 13 | return intptr_t( handle ) != 0; 14 | } 15 | }; 16 | 17 | template 18 | struct non_negative 19 | { 20 | static bool call( T handle ) noexcept 21 | { 22 | return intptr_t( handle ) > 0; 23 | } 24 | }; 25 | 26 | template typename wrapped_t, typename T> 27 | struct with_pseudo_t 28 | { 29 | static bool call( T handle ) noexcept 30 | { 31 | if (wrapped_t::call( handle )) 32 | return true; 33 | 34 | // Check if it's a pseudo handle 35 | auto h = (HANDLE)(uintptr_t)handle; 36 | return h == GetCurrentProcess() || h == GetCurrentThread(); 37 | } 38 | }; 39 | 40 | template typename wrapped_t> 41 | struct with_pseudo 42 | { 43 | template 44 | using type = with_pseudo_t; 45 | }; 46 | 47 | /// 48 | /// Strong exception guarantee 49 | /// 50 | template typename is_valid = non_negative> 51 | class HandleGuard 52 | { 53 | public: 54 | static constexpr handle_t zero_handle = handle_t( 0 ); 55 | 56 | public: 57 | explicit HandleGuard( handle_t handle = zero_handle ) noexcept 58 | : _handle( handle ) 59 | { 60 | } 61 | 62 | HandleGuard( HandleGuard&& rhs ) noexcept 63 | : _handle( rhs._handle ) 64 | { 65 | rhs._handle = zero_handle; 66 | } 67 | 68 | ~HandleGuard() 69 | { 70 | if (non_negative::call( _handle )) 71 | close( _handle ); 72 | } 73 | 74 | HandleGuard( const HandleGuard& ) = delete; 75 | HandleGuard& operator =( const HandleGuard& ) = delete; 76 | 77 | HandleGuard& operator =( HandleGuard&& rhs ) noexcept 78 | { 79 | if (std::addressof( rhs ) == this) 80 | return *this; 81 | 82 | reset( rhs._handle ); 83 | rhs._handle = zero_handle; 84 | 85 | return *this; 86 | } 87 | 88 | HandleGuard& operator =( handle_t handle ) noexcept 89 | { 90 | reset( handle ); 91 | return *this; 92 | } 93 | 94 | void reset( handle_t handle = zero_handle ) noexcept 95 | { 96 | if (handle == _handle) 97 | return; 98 | 99 | if (non_negative::call( _handle )) 100 | close( _handle ); 101 | 102 | _handle = handle; 103 | } 104 | 105 | handle_t release() noexcept 106 | { 107 | auto tmp = _handle; 108 | _handle = zero_handle; 109 | return tmp; 110 | } 111 | 112 | handle_t get() const noexcept { return _handle; } 113 | bool valid() const noexcept { return is_valid::call( _handle ); } 114 | 115 | operator handle_t() const noexcept { return _handle; } 116 | explicit operator bool() const noexcept { return valid(); } 117 | 118 | handle_t* operator &() noexcept { return &_handle; } 119 | 120 | bool operator ==( const HandleGuard& rhs ) const noexcept { return _handle == rhs._handle; } 121 | bool operator <( const HandleGuard& rhs ) const noexcept { return _handle < rhs._handle; } 122 | 123 | private: 124 | handle_t _handle; 125 | }; 126 | 127 | 128 | using Handle = HandleGuard; 129 | using ProcessHandle = HandleGuard::type>; 130 | using ACtxHandle = HandleGuard; 131 | using RegHandle = HandleGuard; 132 | using Mapping = HandleGuard; 133 | 134 | } -------------------------------------------------------------------------------- /src/BlackBone/Include/Macro.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Config.h" 3 | #include 4 | 5 | // Architecture-dependent pointer size 6 | #define BlackBoneWordSize sizeof(void*) 7 | 8 | // Rebase address 9 | #define MAKE_PTR(T, pRVA, base) (T)((ptr_t)pRVA + (ptr_t)base) 10 | #define REBASE(pRVA, baseOld, baseNew) ((ptr_t)pRVA - (ptr_t)baseOld + (ptr_t)baseNew) 11 | 12 | // Field offset info 13 | #define FIELD_OFFSET2(type, field) ((LONG)(LONG_PTR)&(((type)0)->field)) 14 | #define GET_FIELD_PTR(entry, field) (uintptr_t)((uint8_t*)entry + FIELD_OFFSET2(decltype(entry), field)) 15 | 16 | #define CALL_64_86(b, f, ...) (b ? f(__VA_ARGS__) : f(__VA_ARGS__)) 17 | #define FIELD_PTR_64_86(b, e, t, f) (b ? fieldPtr( e, &t::f ) : fieldPtr( e, &t::f )) 18 | 19 | #define LODWORD(l) ((uint32_t)(((uint64_t)(l)) & 0xffffffff)) 20 | #define HIDWORD(l) ((uint32_t)((((uint64_t)(l)) >> 32) & 0xffffffff)) 21 | 22 | // Set or reset particular bit 23 | #define SET_BIT(v, b) v |= (1ull << b) 24 | #define RESET_BIT(v, b) v &= ~(1ull << b) 25 | 26 | // Register aliases 27 | #ifdef USE64 28 | #define NAX Rax 29 | #define NSP Rsp 30 | #define NIP Rip 31 | #define NDI Rdi 32 | 33 | #define BitScanForwardT _BitScanForward64 34 | #define BitScanReverseT _BitScanReverse64 35 | #define BitTestAndSetT _bittestandset64 36 | #define BitTestAndResetT _bittestandreset64 37 | 38 | #define SET_JUMP(_src,_dst) *(uintptr_t*)(_src) = 0x25FF; *(uintptr_t*)((_src) + 6) = (uintptr_t)_dst; 39 | #else 40 | #define NAX Eax 41 | #define NSP Esp 42 | #define NIP Eip 43 | #define NDI Edi 44 | 45 | #define BitScanForwardT _BitScanForward 46 | #define BitScanReverseT _BitScanReverse 47 | #define BitTestAndSetT _bittestandset 48 | #define BitTestAndResetT _bittestandreset 49 | 50 | #define SET_JUMP(_src,_dst) *(uint8_t*)(_src) = 0xE9; *(uintptr_t*)((_src) + 1) = (uintptr_t)(_dst) - (uintptr_t)(_src) - 5 51 | #endif 52 | 53 | #define ENUM_OPS(e) \ 54 | inline e operator |(e a1, e a2) { \ 55 | return static_cast(static_cast(a1) | static_cast(a2)); \ 56 | } \ 57 | \ 58 | inline e operator |= (e& a1, e a2) { \ 59 | return a1 = a1 | a2; \ 60 | } \ 61 | \ 62 | inline e operator &(e a1, e a2) { \ 63 | return static_cast(static_cast(a1)& static_cast(a2)); \ 64 | } \ 65 | \ 66 | inline e operator &= (e& a1, e a2) { \ 67 | return a1 = a1 & a2; \ 68 | } \ 69 | \ 70 | inline e operator ~(e a1) { \ 71 | return static_cast(~static_cast(a1)); \ 72 | } 73 | 74 | 75 | template 76 | struct CompileTimeSizeOf; 77 | 78 | // offsetof alternative 79 | template 80 | constexpr size_t offsetOf( U T::*member ) 81 | { 82 | return reinterpret_cast(&(reinterpret_cast(nullptr)->*member)); 83 | } 84 | 85 | template 86 | constexpr uint64_t fieldPtr( uint64_t base, U T::*member ) 87 | { 88 | return base + offsetOf( member ); 89 | } 90 | 91 | // CONTAINING_RECORD alternative 92 | template 93 | constexpr uint64_t structBase( uint64_t ptr, U T::*member ) 94 | { 95 | return ptr - offsetOf( member ); 96 | } 97 | 98 | // Type-unsafe cast. 99 | template 100 | inline _Tgt brutal_cast( const _Src& src ) 101 | { 102 | static_assert(sizeof( _Tgt ) == sizeof( _Src ), "Operand size mismatch"); 103 | union _u { _Src s; _Tgt t; } u; 104 | u.s = src; 105 | return u.t; 106 | } 107 | 108 | // Align value 109 | inline size_t Align( size_t val, size_t alignment ) 110 | { 111 | return (val % alignment == 0) ? val : (val / alignment + 1) * alignment; 112 | } 113 | 114 | // Offset of 'LastStatus' field in TEB 115 | #define LAST_STATUS_OFS (0x598 + 0x197 * BlackBoneWordSize) 116 | 117 | using NTSTATUS = long; 118 | 119 | /// 120 | /// Get last NT status 121 | /// 122 | /// 123 | inline NTSTATUS LastNtStatus() 124 | { 125 | return *(NTSTATUS*)((unsigned char*)NtCurrentTeb() + LAST_STATUS_OFS); 126 | } 127 | 128 | /// 129 | /// Set last NT status 130 | /// 131 | /// The status. 132 | /// 133 | inline NTSTATUS SetLastNtStatus( NTSTATUS status ) 134 | { 135 | return *(NTSTATUS*)((unsigned char*)NtCurrentTeb() + LAST_STATUS_OFS) = status; 136 | } 137 | 138 | #define SharedUserData32 ((KUSER_SHARED_DATA* const)0x7FFE0000) 139 | -------------------------------------------------------------------------------- /src/BlackBone/Include/NativeEnums.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | namespace blackbone 3 | { 4 | 5 | enum MEMORY_INFORMATION_CLASS 6 | { 7 | MemoryBasicInformation = 0, 8 | MemoryWorkingSetList, 9 | MemorySectionName, 10 | MemoryBasicVlmInformation, 11 | MemoryWorkingSetExList 12 | }; 13 | 14 | enum SECTION_INFORMATION_CLASS 15 | { 16 | SectionBasicInformation, 17 | SectionImageInformation 18 | }; 19 | 20 | enum POOL_TYPE 21 | { 22 | NonPagedPool, 23 | PagedPool, 24 | NonPagedPoolMustSucceed, 25 | DontUseThisType, 26 | NonPagedPoolCacheAligned, 27 | PagedPoolCacheAligned, 28 | NonPagedPoolCacheAlignedMustS 29 | }; 30 | 31 | // 32 | // Loader related 33 | // 34 | enum _LDR_DDAG_STATE 35 | { 36 | LdrModulesMerged = -5, 37 | LdrModulesInitError = -4, 38 | LdrModulesSnapError = -3, 39 | LdrModulesUnloaded = -2, 40 | LdrModulesUnloading = -1, 41 | LdrModulesPlaceHolder = 0, 42 | LdrModulesMapping = 1, 43 | LdrModulesMapped = 2, 44 | LdrModulesWaitingForDependencies = 3, 45 | LdrModulesSnapping = 4, 46 | LdrModulesSnapped = 5, 47 | LdrModulesCondensed = 6, 48 | LdrModulesReadyToInit = 7, 49 | LdrModulesInitializing = 8, 50 | LdrModulesReadyToRun = 9 51 | }; 52 | 53 | enum _LDR_DLL_LOAD_REASON 54 | { 55 | LoadReasonStaticDependency = 0, 56 | LoadReasonStaticForwarderDependency = 1, 57 | LoadReasonDynamicForwarderDependency = 2, 58 | LoadReasonDelayloadDependency = 3, 59 | LoadReasonDynamicLoad = 4, 60 | LoadReasonAsImageLoad = 5, 61 | LoadReasonAsDataLoad = 6, 62 | LoadReasonUnknown = -1 63 | }; 64 | 65 | } -------------------------------------------------------------------------------- /src/BlackBone/Include/Types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NativeStructures.h" 4 | #include "FunctionTypes.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace blackbone 11 | { 12 | 13 | using ptr_t = uint64_t; // Generic pointer in remote process 14 | using module_t = ptr_t; // Module base pointer 15 | 16 | // Type of barrier 17 | enum eBarrier 18 | { 19 | wow_32_32 = 0, // Both processes are WoW64 20 | wow_64_64, // Both processes are x64 21 | wow_32_64, // Managing x64 process from WoW64 process 22 | wow_64_32, // Managing WOW64 process from x64 process 23 | }; 24 | 25 | struct Wow64Barrier 26 | { 27 | eBarrier type = wow_32_32; 28 | bool sourceWow64 = false; 29 | bool targetWow64 = false; 30 | bool x86OS = false; 31 | bool mismatch = false; 32 | }; 33 | 34 | // Module type 35 | enum eModType 36 | { 37 | mt_mod32, // 32 bit module 38 | mt_mod64, // 64 bit module 39 | mt_default, // type is deduced from target process 40 | mt_unknown // Failed to detect type 41 | }; 42 | 43 | // Module search method 44 | enum eModSeachType 45 | { 46 | LdrList, // InLoadOrder list 47 | Sections, // Scan for section objects 48 | PEHeaders, // Scan for PE headers in memory 49 | }; 50 | 51 | // Switch created wow64 thread to long mode 52 | enum eThreadModeSwitch 53 | { 54 | NoSwitch, // Never switch 55 | ForceSwitch, // Always switch 56 | AutoSwitch // Switch depending on wow64 barrier 57 | }; 58 | 59 | // Module info 60 | struct ModuleData 61 | { 62 | module_t baseAddress; // Base image address 63 | std::wstring name; // File name 64 | std::wstring fullPath; // Full file path 65 | uint32_t size; // Size of image 66 | eModType type; // Module type 67 | ptr_t ldrPtr; // LDR_DATA_TABLE_ENTRY_BASE_T address 68 | bool manual; // Image is manually mapped 69 | 70 | 71 | bool operator ==(const ModuleData& other) const 72 | { 73 | return (baseAddress == other.baseAddress); 74 | } 75 | 76 | bool operator <(const ModuleData& other) 77 | { 78 | return baseAddress < other.baseAddress; 79 | } 80 | }; 81 | 82 | using ModuleDataPtr = std::shared_ptr; 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/BlackBone/Include/Win7Specific.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Winheaders.h" 4 | 5 | namespace blackbone 6 | { 7 | template 8 | struct _LDR_DATA_TABLE_ENTRY_W7 : _LDR_DATA_TABLE_ENTRY_BASE_T 9 | { 10 | _LIST_ENTRY_T ForwarderLinks; 11 | _LIST_ENTRY_T ServiceTagLinks; 12 | _LIST_ENTRY_T StaticLinks; 13 | T ContextInformation; 14 | uint32_t OriginalBase; 15 | LARGE_INTEGER LoadTime; 16 | }; 17 | 18 | template 19 | struct _RTL_INVERTED_FUNCTION_TABLE7 20 | { 21 | uint32_t Count; 22 | uint32_t MaxCount; 23 | uint32_t Epoch; 24 | _RTL_INVERTED_FUNCTION_TABLE_ENTRY Entries[0x200]; 25 | }; 26 | 27 | } -------------------------------------------------------------------------------- /src/BlackBone/Include/Win8Specific.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Winheaders.h" 4 | 5 | namespace blackbone 6 | { 7 | 8 | template 9 | struct _RTL_RB_TREE 10 | { 11 | T Root; 12 | T Min; 13 | }; 14 | 15 | template 16 | struct _RTL_BALANCED_NODE 17 | { 18 | T Left; 19 | T Right; 20 | T ParentValue; 21 | }; 22 | 23 | template 24 | struct _LDR_DDAG_NODE 25 | { 26 | _LIST_ENTRY_T Modules; 27 | T ServiceTagList; 28 | uint32_t LoadCount; 29 | uint32_t ReferenceCount; 30 | uint32_t DependencyCount; 31 | T RemovalLink; 32 | T IncomingDependencies; 33 | _LDR_DDAG_STATE State; 34 | T CondenseLink; 35 | uint32_t PreorderNumber; 36 | uint32_t LowestLink; 37 | }; 38 | 39 | template 40 | struct _LDR_DATA_TABLE_ENTRY_W8 : _LDR_DATA_TABLE_ENTRY_BASE_T 41 | { 42 | T DdagNode; // _LDR_DDAG_NODE* 43 | _LIST_ENTRY_T NodeModuleLink; 44 | T SnapContext; 45 | T ParentDllBase; 46 | T SwitchBackContext; 47 | _RTL_BALANCED_NODE BaseAddressIndexNode; 48 | _RTL_BALANCED_NODE MappingInfoIndexNode; 49 | T OriginalBase; 50 | LARGE_INTEGER LoadTime; 51 | uint32_t BaseNameHashValue; 52 | _LDR_DLL_LOAD_REASON LoadReason; 53 | uint32_t ImplicitPathOptions; 54 | }; 55 | 56 | template 57 | struct _RTL_INVERTED_FUNCTION_TABLE8 58 | { 59 | ULONG Count; 60 | ULONG MaxCount; 61 | ULONG Epoch; 62 | UCHAR Overflow; 63 | _RTL_INVERTED_FUNCTION_TABLE_ENTRY Entries[0x200]; 64 | }; 65 | 66 | using _LDR_DATA_TABLE_ENTRY_W832 = _LDR_DATA_TABLE_ENTRY_W8; 67 | using _LDR_DATA_TABLE_ENTRY_W864 = _LDR_DATA_TABLE_ENTRY_W8; 68 | using LDR_DATA_TABLE_ENTRY_W8T = _LDR_DATA_TABLE_ENTRY_W8; 69 | 70 | using _LDR_DDAG_NODE_32 = _LDR_DDAG_NODE; 71 | using _LDR_DDAG_NODE_64 = _LDR_DDAG_NODE; 72 | using LDR_DDAG_NODE_T = _LDR_DDAG_NODE; 73 | 74 | } -------------------------------------------------------------------------------- /src/BlackBone/Include/WinXPSpecific.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Winheaders.h" 4 | 5 | namespace blackbone 6 | { 7 | 8 | #pragma warning(push) 9 | #pragma warning(disable : 4201) 10 | typedef struct _IMAGE_DELAYLOAD_DESCRIPTOR 11 | { 12 | union 13 | { 14 | DWORD AllAttributes; 15 | struct { 16 | DWORD RvaBased : 1; // Delay load version 2 17 | DWORD ReservedAttributes : 31; 18 | }; 19 | } Attributes; 20 | 21 | DWORD DllNameRVA; // RVA to the name of the target library (NULL-terminate ASCII string) 22 | DWORD ModuleHandleRVA; // RVA to the HMODULE caching location (PHMODULE) 23 | DWORD ImportAddressTableRVA; // RVA to the start of the IAT (PIMAGE_THUNK_DATA) 24 | DWORD ImportNameTableRVA; // RVA to the start of the name table (PIMAGE_THUNK_DATA::AddressOfData) 25 | DWORD BoundImportAddressTableRVA; // RVA to an optional bound IAT 26 | DWORD UnloadInformationTableRVA; // RVA to an optional unload info table 27 | DWORD TimeDateStamp; // 0 if not bound, Otherwise, date/time of the target DLL 28 | } IMAGE_DELAYLOAD_DESCRIPTOR, *PIMAGE_DELAYLOAD_DESCRIPTOR; 29 | #pragma warning(pop) 30 | 31 | typedef struct _EXCEPTION_REGISTRATION_RECORD 32 | { 33 | _EXCEPTION_REGISTRATION_RECORD *Next; 34 | PEXCEPTION_ROUTINE Handler; 35 | } EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD; 36 | 37 | } -------------------------------------------------------------------------------- /src/BlackBone/Include/Winheaders.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef WIN32_LEAN_AND_MEAN 4 | #define WIN32_LEAN_AND_MEAN 5 | #endif 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #pragma warning(push) 14 | #pragma warning(disable : 4005) 15 | #include 16 | #pragma warning(pop) -------------------------------------------------------------------------------- /src/BlackBone/LocalHook/HookHandlerCdecl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace blackbone 4 | { 5 | 6 | template 7 | struct HookHandler : public DetourBase 8 | { 9 | using ReturnType = std::conditional_t, int, R>; 10 | 11 | using type = R( __cdecl* )(Args...); 12 | using hktype = R( __cdecl* )(Args&...); 13 | using hktypeC = R( C::* )(Args&...); 14 | 15 | // 16 | // Workaround for void return type 17 | // 18 | using typeR = ReturnType( __cdecl* )(Args...); 19 | using hktypeR = ReturnType( __cdecl* )(Args&...); 20 | using hktypeCR = ReturnType( C::* )(Args&...); 21 | 22 | static __declspec(noinline) ReturnType __cdecl Handler( Args... args ) 23 | { 24 | HookHandler* pInst = (HookHandler*)((_NT_TIB*)NtCurrentTeb())->ArbitraryUserPointer; 25 | return pInst->HandlerP( std::forward( args )... ); 26 | } 27 | 28 | ReturnType HandlerP( Args&&... args ) 29 | { 30 | ReturnType val_new, val_original; 31 | 32 | DisableHook(); 33 | 34 | if (_order == CallOrder::HookFirst) 35 | { 36 | val_new = CallCallback( std::forward( args )... ); 37 | val_original = CallOriginal( std::forward( args )... ); 38 | } 39 | else if (_order == CallOrder::HookLast) 40 | { 41 | val_original = CallOriginal( std::forward( args )... ); 42 | val_new = CallCallback( std::forward( args )... ); 43 | } 44 | else 45 | { 46 | val_original = val_new = CallCallback( std::forward( args )... ); 47 | } 48 | 49 | if (this->_hooked) 50 | EnableHook(); 51 | 52 | return (_retType == ReturnMethod::UseOriginal ? val_original : val_new); 53 | } 54 | 55 | inline ReturnType CallOriginal( Args&&... args ) 56 | { 57 | return (reinterpret_cast(_callOriginal))(args...); 58 | } 59 | 60 | inline ReturnType CallCallback( Args&&... args ) 61 | { 62 | if (_callbackClass != nullptr) 63 | return (reinterpret_cast(_callbackClass)->*brutal_cast(_callback))(args...); 64 | else 65 | return (reinterpret_cast(_callback))(args...); 66 | } 67 | }; 68 | 69 | } -------------------------------------------------------------------------------- /src/BlackBone/LocalHook/HookHandlerFastcall.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace blackbone 4 | { 5 | 6 | template 7 | struct HookHandler : public DetourBase 8 | { 9 | using ReturnType = std::conditional_t, int, R>; 10 | 11 | using type = R( __fastcall* )(Args...); 12 | using hktype = R( __fastcall* )(Args&...); 13 | using hktypeC = R( C::* )(Args&...); 14 | 15 | // 16 | // Workaround for void return type 17 | // 18 | using typeR = ReturnType( __fastcall* )(Args...); 19 | using hktypeR = ReturnType( __fastcall* )(Args&...); 20 | using hktypeCR = ReturnType( C::* )(Args&...); 21 | 22 | static __declspec(noinline) ReturnType __fastcall Handler( Args... args ) 23 | { 24 | HookHandler* pInst = (HookHandler*)((_NT_TIB*)NtCurrentTeb())->ArbitraryUserPointer; 25 | return pInst->HandlerP( std::forward( args )... ); 26 | } 27 | 28 | ReturnType HandlerP( Args&&... args ) 29 | { 30 | ReturnType val_new, val_original; 31 | 32 | DisableHook(); 33 | 34 | if (_order == CallOrder::HookFirst) 35 | { 36 | val_new = CallCallback( std::forward( args )... ); 37 | val_original = CallOriginal( std::forward( args )... ); 38 | } 39 | else if (_order == CallOrder::HookLast) 40 | { 41 | val_original = CallOriginal( std::forward( args )... ); 42 | val_new = CallCallback( std::forward( args )... ); 43 | } 44 | else 45 | { 46 | val_original = val_new = CallCallback( std::forward( args )... ); 47 | } 48 | 49 | if (this->_hooked) 50 | EnableHook(); 51 | 52 | return (_retType == ReturnMethod::UseOriginal ? val_original : val_new); 53 | } 54 | 55 | inline ReturnType CallOriginal( Args&&... args ) 56 | { 57 | return (reinterpret_cast(_callOriginal))(args...); 58 | } 59 | 60 | inline ReturnType CallCallback( Args&&... args ) 61 | { 62 | if (_callbackClass != nullptr) 63 | return ((C*)_callbackClass->*brutal_cast(_callback))(args...); 64 | else 65 | return (reinterpret_cast(_callback))(args...); 66 | } 67 | }; 68 | 69 | } -------------------------------------------------------------------------------- /src/BlackBone/LocalHook/HookHandlerStdcall.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace blackbone 4 | { 5 | 6 | template 7 | struct HookHandler : public DetourBase 8 | { 9 | using ReturnType = std::conditional_t, int, R>; 10 | 11 | using type = R( __stdcall* )(Args...); 12 | using hktype = R( __stdcall* )(Args&...); 13 | using hktypeC = R( C::* )(Args&...); 14 | 15 | // 16 | // Workaround for void return type 17 | // 18 | using typeR = ReturnType( __stdcall* )(Args...); 19 | using hktypeR = ReturnType( __stdcall* )(Args&...); 20 | using hktypeCR = ReturnType( C::* )(Args&...); 21 | 22 | static __declspec(noinline) ReturnType __stdcall Handler( Args... args ) 23 | { 24 | HookHandler* pInst = (HookHandler*)((_NT_TIB*)NtCurrentTeb())->ArbitraryUserPointer; 25 | return pInst->HandlerP( std::forward( args )... ); 26 | } 27 | 28 | ReturnType HandlerP( Args&&... args ) 29 | { 30 | ReturnType val_new, val_original; 31 | 32 | DisableHook(); 33 | 34 | if (_order == CallOrder::HookFirst) 35 | { 36 | val_new = CallCallback( std::forward( args )... ); 37 | val_original = CallOriginal( std::forward( args )... ); 38 | } 39 | else if (_order == CallOrder::HookLast) 40 | { 41 | val_original = CallOriginal( std::forward( args )... ); 42 | val_new = CallCallback( std::forward( args )... ); 43 | } 44 | else 45 | { 46 | val_original = val_new = CallCallback( std::forward( args )... ); 47 | } 48 | 49 | if (this->_hooked) 50 | EnableHook(); 51 | 52 | return (_retType == ReturnMethod::UseOriginal ? val_original : val_new); 53 | } 54 | 55 | inline ReturnType CallOriginal( Args&&... args ) 56 | { 57 | return (reinterpret_cast(_callOriginal))(args...); 58 | } 59 | 60 | inline ReturnType CallCallback( Args&&... args ) 61 | { 62 | if (_callbackClass != nullptr) 63 | return ((C*)_callbackClass->*brutal_cast(_callback))(args...); 64 | else 65 | return (reinterpret_cast(_callback))(args...); 66 | } 67 | }; 68 | 69 | } -------------------------------------------------------------------------------- /src/BlackBone/LocalHook/HookHandlerThiscall.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace blackbone 4 | { 5 | 6 | template 7 | struct HookHandler : public DetourBase 8 | { 9 | using ReturnType = std::conditional_t, int, R>; 10 | 11 | using type = R( __thiscall* )(Args...); 12 | using hktype = R( __stdcall* )(Args&...); 13 | using hktypeC = R( C::* )(Args&...); 14 | 15 | // 16 | // Workaround for void return type 17 | // 18 | using typeR = ReturnType( __thiscall* )(Args...); 19 | using hktypeR = ReturnType( __stdcall* )(Args&...); 20 | using hktypeCR = ReturnType( C::* )(Args&...); 21 | 22 | static __declspec(noinline) ReturnType __thiscall Handler( Args... args ) 23 | { 24 | HookHandler* pInst = (HookHandler*)((_NT_TIB*)NtCurrentTeb())->ArbitraryUserPointer; 25 | return pInst->HandlerP( std::forward( args )... ); 26 | } 27 | 28 | ReturnType HandlerP( Args&&... args ) 29 | { 30 | ReturnType val_new, val_original; 31 | 32 | DisableHook(); 33 | 34 | if (_order == CallOrder::HookFirst) 35 | { 36 | val_new = CallCallback( std::forward( args )... ); 37 | val_original = CallOriginal( std::forward( args )... ); 38 | } 39 | else if (_order == CallOrder::HookLast) 40 | { 41 | val_original = CallOriginal( std::forward( args )... ); 42 | val_new = CallCallback( std::forward( args )... ); 43 | } 44 | else 45 | { 46 | val_original = val_new = CallCallback( std::forward( args )... ); 47 | } 48 | 49 | if (this->_hooked) 50 | EnableHook(); 51 | 52 | return (_retType == ReturnMethod::UseOriginal ? val_original : val_new); 53 | } 54 | 55 | inline ReturnType CallOriginal( Args&&... args ) 56 | { 57 | return (reinterpret_cast(_callOriginal))( args...); 58 | } 59 | 60 | inline ReturnType CallCallback( Args&&... args ) 61 | { 62 | if (_callbackClass != nullptr) 63 | return ((C*)_callbackClass->*brutal_cast(_callback))( args...); 64 | else 65 | return (reinterpret_cast(_callback))( args...); 66 | } 67 | }; 68 | 69 | } -------------------------------------------------------------------------------- /src/BlackBone/LocalHook/HookHandlers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "LocalHookBase.h" 4 | 5 | namespace blackbone 6 | { 7 | class BLACKBONE_API NoClass { }; 8 | 9 | template 10 | struct HookHandler; 11 | } 12 | 13 | #include "HookHandlerCdecl.h" 14 | 15 | #ifndef USE64 16 | #include "HookHandlerStdcall.h" 17 | #include "HookHandlerThiscall.h" 18 | #include "HookHandlerFastcall.h" 19 | #endif -------------------------------------------------------------------------------- /src/BlackBone/LocalHook/LocalHookBase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Config.h" 4 | #include "../Include/Winheaders.h" 5 | #include "../Asm/AsmFactory.h" 6 | #include "../Asm/LDasm.h" 7 | #include "../Include/Macro.h" 8 | 9 | #include 10 | #include 11 | 12 | namespace blackbone 13 | { 14 | 15 | namespace CallOrder 16 | { 17 | enum e 18 | { 19 | HookFirst, // Hook called before original function 20 | HookLast, // Hook called after original function 21 | NoOriginal, // Original function doesn't get called 22 | }; 23 | } 24 | 25 | namespace HookType 26 | { 27 | enum e 28 | { 29 | Inline, // Patch first few bytes 30 | Int3, // Place Int3 breakpoint 31 | HWBP, // Set hardware breakpoint 32 | 33 | // Reserved for internal use 34 | VTable, 35 | InternalInline 36 | }; 37 | } 38 | 39 | namespace ReturnMethod 40 | { 41 | enum e 42 | { 43 | UseNew, // Return value returned by hook 44 | UseOriginal // Return original function value 45 | }; 46 | } 47 | 48 | class DetourBase 49 | { 50 | using mapIdx = std::unordered_map; 51 | 52 | public: 53 | BLACKBONE_API DetourBase(); 54 | BLACKBONE_API ~DetourBase(); 55 | 56 | protected: 57 | 58 | /// 59 | /// Allocate detour buffer as close to target as possible 60 | /// 61 | /// Target address 62 | /// true on success 63 | BLACKBONE_API bool AllocateBuffer( uint8_t* nearest ); 64 | 65 | /// 66 | /// Temporarily disable hook 67 | /// 68 | /// true on success 69 | BLACKBONE_API bool DisableHook(); 70 | 71 | /// 72 | /// Enable disabled hook 73 | /// 74 | /// true on success 75 | BLACKBONE_API bool EnableHook(); 76 | 77 | /// 78 | /// Toggle hardware breakpoint for current thread 79 | /// 80 | /// Breakpoint index ( 0-4 ) 81 | /// true to enable, false to disable 82 | /// true on success 83 | BLACKBONE_API bool ToggleHBP( int index, bool enable ); 84 | 85 | /// 86 | /// Copy original function bytes 87 | /// 88 | /// Origianl function address 89 | BLACKBONE_API void CopyOldCode( uint8_t* Ptr ); 90 | 91 | /// 92 | /// Exception handlers 93 | /// 94 | /// Exception information 95 | /// Exception disposition 96 | BLACKBONE_API static LONG NTAPI VectoredHandler ( PEXCEPTION_POINTERS excpt ); 97 | BLACKBONE_API static LONG NTAPI Int3Handler ( PEXCEPTION_POINTERS excpt ); 98 | BLACKBONE_API static LONG NTAPI AVHandler ( PEXCEPTION_POINTERS excpt ); 99 | BLACKBONE_API static LONG NTAPI StepHandler ( PEXCEPTION_POINTERS excpt ); 100 | 101 | protected: 102 | bool _hooked = false; // Hook is installed 103 | 104 | void* _callback = nullptr; // User supplied hook function 105 | void* _callbackClass = nullptr; // Class pointer for user hook 106 | void* _original = nullptr; // Original function address 107 | void* _internalHandler = nullptr; // Pointer to hook handler 108 | void* _callOriginal = nullptr; // Pointer to original function 109 | 110 | mapIdx _hwbpIdx; // Thread HWBP index 111 | size_t _origSize = 0; // Original code size 112 | uint8_t* _buf = nullptr; // Trampoline buffer 113 | uint8_t* _origCode = nullptr; // Original function bytes 114 | uint8_t* _origThunk = nullptr; // Original bytes adjusted for relocation 115 | uint8_t* _newCode = nullptr; // Trampoline bytes 116 | 117 | HookType::e _type = HookType::Inline; 118 | CallOrder::e _order = CallOrder::HookFirst; 119 | ReturnMethod::e _retType = ReturnMethod::UseOriginal; 120 | 121 | // Global hook instances relationship 122 | BLACKBONE_API static std::unordered_map _breakpoints; 123 | 124 | // Exception handler 125 | BLACKBONE_API static void* _vecHandler; 126 | }; 127 | 128 | } -------------------------------------------------------------------------------- /src/BlackBone/ManualMap/MExcept.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Include/Winheaders.h" 4 | #include "../Process/MemBlock.h" 5 | 6 | namespace blackbone 7 | { 8 | 9 | /// 10 | /// x64 exception module info 11 | /// 12 | struct ExceptionModule 13 | { 14 | ptr_t base; 15 | ptr_t size; 16 | }; 17 | 18 | 19 | /// 20 | /// x64 module table 21 | /// 22 | struct ModuleTable 23 | { 24 | ptr_t count; // Number of used entries 25 | ExceptionModule entry[250]; // Module data 26 | }; 27 | 28 | /// 29 | /// Exception handling support for arbitrary code 30 | /// 31 | class MExcept 32 | { 33 | public: 34 | BLACKBONE_API MExcept() = default; 35 | BLACKBONE_API ~MExcept() = default; 36 | 37 | MExcept( const MExcept& ) = delete; 38 | MExcept& operator =( const MExcept& ) = delete; 39 | 40 | /// 41 | /// Inject VEH wrapper into process 42 | /// Used to enable execution of SEH handlers out of image 43 | /// 44 | /// Target process 45 | /// Target module 46 | /// Partial exception support 47 | /// Error code 48 | BLACKBONE_API NTSTATUS CreateVEH( class Process& proc, ModuleData& mod, bool partial ); 49 | 50 | /// 51 | /// Removes VEH from target process 52 | /// 53 | /// Target process 54 | /// Partial exception support 55 | /// Module type 56 | /// Status code 57 | BLACKBONE_API NTSTATUS RemoveVEH( class Process& proc, bool partial, eModType mt ); 58 | 59 | /// 60 | /// Reset data 61 | /// 62 | BLACKBONE_API void reset() { _pModTable.Free(); } 63 | 64 | private: 65 | MemBlock _pVEHCode; // VEH function codecave 66 | MemBlock _pModTable; // x64 module address range table 67 | uint64_t _hVEH = 0; // VEH handle 68 | 69 | static uint8_t _handler32[]; 70 | static uint8_t _handler64[]; 71 | }; 72 | } 73 | -------------------------------------------------------------------------------- /src/BlackBone/Misc/DynImport.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Include/Types.h" 4 | #include "../Include/Winheaders.h" 5 | #include "Utils.h" 6 | #include "InitOnce.h" 7 | 8 | #include 9 | 10 | namespace blackbone 11 | { 12 | 13 | /// 14 | /// Dynamic import 15 | /// 16 | class DynImport 17 | { 18 | public: 19 | BLACKBONE_API static DynImport& Instance() 20 | { 21 | static DynImport instance; 22 | return instance; 23 | } 24 | 25 | DynImport() = default; 26 | DynImport( const DynImport& ) = delete; 27 | 28 | /// 29 | /// Get dll function 30 | /// 31 | /// Function name 32 | /// Function pointer 33 | template 34 | T get( const std::string& name ) 35 | { 36 | InitializeOnce(); 37 | 38 | CSLock lck( _mapGuard ); 39 | 40 | auto iter = _funcs.find( name ); 41 | if (iter != _funcs.end()) 42 | return reinterpret_cast(iter->second); 43 | 44 | return nullptr; 45 | } 46 | 47 | /// 48 | /// Safely call import 49 | /// If import not found - return STATUS_ORDINAL_NOT_FOUND 50 | /// 51 | /// Import name. 52 | /// Function args 53 | /// Function result or STATUS_ORDINAL_NOT_FOUND if import not found 54 | template 55 | NTSTATUS safeNativeCall( const std::string& name, Args&&... args ) 56 | { 57 | auto pfn = DynImport::get( name ); 58 | return pfn ? pfn( std::forward( args )... ) : STATUS_ORDINAL_NOT_FOUND; 59 | } 60 | 61 | /// 62 | /// Safely call import 63 | /// If import not found - return 0 64 | /// 65 | /// Import name. 66 | /// Function args 67 | /// Function result or 0 if import not found 68 | template 69 | auto safeCall( const std::string& name, Args&&... args ) 70 | { 71 | auto pfn = DynImport::get( name ); 72 | return pfn ? pfn( std::forward( args )... ) : std::invoke_result_t(); 73 | } 74 | 75 | /// 76 | /// Load function into database 77 | /// 78 | /// Function name 79 | /// Module name 80 | /// true on success 81 | BLACKBONE_API FARPROC load( const std::string& name, const std::wstring& modName ) 82 | { 83 | auto mod = GetModuleHandleW( modName.c_str() ); 84 | return load( name, mod ); 85 | } 86 | 87 | /// 88 | /// Load function into database 89 | /// 90 | /// Function name 91 | /// Module base 92 | /// true on success 93 | BLACKBONE_API FARPROC load( const std::string& name, HMODULE hMod ) 94 | { 95 | CSLock lck( _mapGuard ); 96 | 97 | auto proc = GetProcAddress( hMod, name.c_str() ); 98 | if (proc) 99 | { 100 | _funcs.insert( std::make_pair( name, proc ) ); 101 | return proc; 102 | } 103 | 104 | return nullptr; 105 | } 106 | 107 | private: 108 | std::unordered_map _funcs; // function database 109 | CriticalSection _mapGuard; // function database guard 110 | }; 111 | 112 | // Syntax sugar 113 | #define LOAD_IMPORT(name, mod) (DynImport::Instance().load( name, mod )) 114 | #define GET_IMPORT(name) (DynImport::Instance().get( #name )) 115 | #define SAFE_NATIVE_CALL(name, ...) (DynImport::Instance().safeNativeCall( #name, __VA_ARGS__ )) 116 | #define SAFE_CALL(name, ...) (DynImport::Instance().safeCall( #name, __VA_ARGS__ )) 117 | 118 | } -------------------------------------------------------------------------------- /src/BlackBone/Misc/InitOnce.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Config.h" 3 | 4 | namespace blackbone 5 | { 6 | BLACKBONE_API bool InitializeOnce(); 7 | } -------------------------------------------------------------------------------- /src/BlackBone/Misc/NameResolve.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Include/Winheaders.h" 4 | #include "../Include/Types.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace blackbone 11 | { 12 | 13 | class NameResolve 14 | { 15 | using mapApiSchema = std::unordered_map>; 16 | 17 | public: 18 | enum eResolveFlag 19 | { 20 | Default = 0, // Full resolve 21 | ApiSchemaOnly = 1, // Resolve only Api schema dlls 22 | EnsureFullPath = 2, // Make sure resulting path is full-qualified 23 | NoSearch = 4, // Don't perform file search, only resolve name 24 | Wow64 = 8, // Redirect System32 files to SysWow64 25 | }; 26 | 27 | public: 28 | BLACKBONE_API ~NameResolve() = default; 29 | 30 | BLACKBONE_API static NameResolve& Instance(); 31 | 32 | /// 33 | /// Initialize api set map 34 | /// 35 | /// 36 | BLACKBONE_API bool Initialize(); 37 | 38 | /// 39 | /// Resolve image path. 40 | /// 41 | /// Image to resolve 42 | /// Name of parent image. Used only when resolving import images 43 | /// Directory where source image is located 44 | /// Resolve flags 45 | /// Process. Used to search process executable directory 46 | /// Activation context 47 | /// Status 48 | BLACKBONE_API NTSTATUS ResolvePath( 49 | std::wstring& path, 50 | const std::wstring& baseName, 51 | const std::wstring& searchDir, 52 | eResolveFlag flags, 53 | class Process& proc, 54 | HANDLE actx = INVALID_HANDLE_VALUE 55 | ); 56 | 57 | /// 58 | /// Try SxS redirection 59 | /// 60 | /// Image path. 61 | /// Process. Used to search process executable directory 62 | /// Activation context 63 | /// 64 | BLACKBONE_API NTSTATUS ProbeSxSRedirect( std::wstring& path, class Process& proc, HANDLE actx = INVALID_HANDLE_VALUE ); 65 | 66 | private: 67 | // Ensure singleton 68 | NameResolve() = default; 69 | NameResolve( const NameResolve& ) = delete; 70 | NameResolve& operator =( const NameResolve& ) = delete; 71 | 72 | /// 73 | /// Gets the process executable directory 74 | /// 75 | /// Process ID 76 | /// Process executable directory 77 | std::wstring GetProcessDirectory( DWORD pid ); 78 | 79 | /// 80 | /// OS dependent api set initialization 81 | /// 82 | /// true on success 83 | template 84 | bool InitializeP(); 85 | 86 | private: 87 | mapApiSchema _apiSchema; // Api schema table 88 | }; 89 | 90 | 91 | } -------------------------------------------------------------------------------- /src/BlackBone/Misc/Thunk.hpp: -------------------------------------------------------------------------------- 1 | #include "../Config.h" 2 | #include 3 | #include 4 | 5 | // Thunk code 6 | #pragma pack(push, 1) 7 | struct ThunkData 8 | { 9 | #ifndef USE64 10 | /* 11 | mov eax, pInstance 12 | mov fs:[0x14], eax 13 | mov eax, pMethod 14 | jmp eax 15 | */ 16 | uint8_t mov1 = 0xB8; 17 | void* pInst = nullptr; 18 | uint16_t fs1 = '\x64\xA3'; 19 | uint8_t fs2 = FIELD_OFFSET( NT_TIB, ArbitraryUserPointer ); 20 | uint8_t fs3 = 0; 21 | uint16_t fs4 = 0; 22 | uint8_t mov2 = 0xB8; 23 | void* pFn = nullptr; 24 | uint16_t jmp1 = '\xFF\xE0'; 25 | #else 26 | /* 27 | mov rax, pInstance 28 | mov gs:[0x28], rax 29 | mov rax, pMethod 30 | jmp rax 31 | */ 32 | uint16_t mov1 = '\x48\xB8'; 33 | void* pInst = nullptr; 34 | uint32_t fs1 = '\x65\x48\x89\x04'; 35 | uint8_t fs2 = 0x25; 36 | uint8_t fs3 = FIELD_OFFSET( NT_TIB, ArbitraryUserPointer ); 37 | uint8_t fs4 = 0; 38 | uint16_t fs5 = 0; 39 | uint16_t mov2 = '\x48\xB8'; 40 | void* pFn = nullptr; 41 | uint16_t jmp1 = '\xFF\xE0'; 42 | #endif 43 | 44 | void setup( void* pInstance, void* pMethod ) 45 | { 46 | pInst = pInstance; 47 | pFn = pMethod; 48 | } 49 | }; 50 | #pragma pack(pop) 51 | 52 | 53 | template 54 | class Win32Thunk; 55 | 56 | template 57 | class Win32Thunk < R( __stdcall* )(Args...), C > 58 | { 59 | public: 60 | using TypeMember = R( C::* )(Args...); 61 | using TypeFree = R( __stdcall* )(Args...); 62 | 63 | public: 64 | Win32Thunk( TypeMember pfn, C* pInstance ) 65 | : _pMethod( pfn ) 66 | , _pInstance( pInstance ) 67 | { 68 | DWORD dwOld = 0; 69 | VirtualProtect( &_thunk, sizeof( _thunk ), PAGE_EXECUTE_READWRITE, &dwOld ); 70 | _thunk.setup( this, &Win32Thunk::WrapHandler ); 71 | } 72 | 73 | /// 74 | /// Redirect call 75 | /// 76 | /// Arguments 77 | /// Call result 78 | static R __stdcall WrapHandler( Args... args ) 79 | { 80 | auto _this = reinterpret_cast(((PNT_TIB)NtCurrentTeb())->ArbitraryUserPointer); 81 | return (_this->_pInstance->*_this->_pMethod)(args...); 82 | } 83 | 84 | /// 85 | /// Get thunk 86 | /// 87 | /// 88 | TypeFree GetThunk() 89 | { 90 | return reinterpret_cast(&_thunk); 91 | } 92 | 93 | private: 94 | TypeMember _pMethod = nullptr; // Member function to call 95 | C* _pInstance = nullptr; // Bound instance 96 | ThunkData _thunk; // Thunk code 97 | }; -------------------------------------------------------------------------------- /src/BlackBone/Misc/Trace.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #pragma warning(push) 7 | #pragma warning(disable : 4091) 8 | #include 9 | #pragma warning(pop) 10 | 11 | namespace blackbone 12 | { 13 | #ifndef BLACKBONE_NO_TRACE 14 | 15 | inline void DoTraceV( const char* fmt, va_list va_args ) 16 | { 17 | char buf[2048], userbuf[1024]; 18 | vsprintf_s( userbuf, fmt, va_args ); 19 | sprintf_s( buf, "BlackBone: %s\r\n", userbuf ); 20 | OutputDebugStringA( buf ); 21 | 22 | #ifdef CONSOLE_TRACE 23 | printf_s( buf ); 24 | #endif 25 | } 26 | 27 | inline void DoTraceV( const wchar_t* fmt, va_list va_args ) 28 | { 29 | wchar_t buf[2048], userbuf[1024]; 30 | vswprintf_s( userbuf, fmt, va_args ); 31 | swprintf_s( buf, L"BlackBone: %ls\r\n", userbuf ); 32 | OutputDebugStringW( buf ); 33 | 34 | #ifdef CONSOLE_TRACE 35 | wprintf_s( buf ); 36 | #endif 37 | } 38 | 39 | template 40 | inline void DoTrace( const Ch* fmt, ... ) 41 | { 42 | va_list va_args; 43 | va_start( va_args, fmt ); 44 | DoTraceV( fmt, va_args ); 45 | va_end( va_args ); 46 | } 47 | 48 | #define BLACKBONE_TRACE(fmt, ...) DoTrace(fmt, ##__VA_ARGS__) 49 | 50 | #else 51 | #define BLACKBONE_TRACE(...) 52 | #endif 53 | 54 | } -------------------------------------------------------------------------------- /src/BlackBone/PE/ImageNET.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Config.h" 3 | #ifdef COMPILER_MSVC 4 | 5 | #include "../Include/Winheaders.h" 6 | 7 | #include 8 | 9 | #if _MSC_VER >= 1920 10 | #include 11 | #endif 12 | 13 | #pragma warning(push) 14 | #pragma warning(disable : 4091) 15 | #include "cor.h" 16 | #include 17 | #pragma warning(pop) 18 | 19 | namespace blackbone 20 | { 21 | 22 | /// 23 | /// .NET metadata parser 24 | /// 25 | class ImageNET 26 | { 27 | public: 28 | using mapMethodRVA = std::map, uintptr_t>; 29 | 30 | public: 31 | BLACKBONE_API ImageNET(void); 32 | BLACKBONE_API ~ImageNET(void); 33 | 34 | /// 35 | /// Initialize COM classes 36 | /// 37 | /// Image file path 38 | /// true on success 39 | BLACKBONE_API bool Init( const std::wstring& path ); 40 | 41 | /// 42 | /// Extract methods from image 43 | /// 44 | /// Found Methods 45 | /// true on success 46 | BLACKBONE_API bool Parse( mapMethodRVA* methods = nullptr ); 47 | 48 | /// 49 | /// Get image .NET runtime version 50 | /// 51 | /// runtime version, "n/a" if nothing found 52 | BLACKBONE_API static std::wstring GetImageRuntimeVer( const wchar_t* ImagePath ); 53 | 54 | private: 55 | std::wstring _path; // Image path 56 | mapMethodRVA _methods; // Image methods 57 | 58 | // COM helpers 59 | CComPtr _pMetaDisp; 60 | CComPtr _pMetaImport; 61 | CComPtr _pAssemblyImport; 62 | }; 63 | 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/BlackBone/Patterns/PatternSearch.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/BlackBone/Patterns/PatternSearch.cpp -------------------------------------------------------------------------------- /src/BlackBone/Patterns/PatternSearch.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/BlackBone/Patterns/PatternSearch.h -------------------------------------------------------------------------------- /src/BlackBone/Process/ProcessCore.cpp: -------------------------------------------------------------------------------- 1 | #include "../Config.h" 2 | #include "ProcessCore.h" 3 | #include "../Misc/DynImport.h" 4 | #include "../Include/Macro.h" 5 | #include <3rd_party/VersionApi.h> 6 | 7 | namespace blackbone 8 | { 9 | 10 | #ifdef COMPILER_GCC 11 | #define PROCESS_DEP_ENABLE 0x00000001 12 | #endif 13 | 14 | ProcessCore::ProcessCore() 15 | : _native( nullptr ) 16 | { 17 | } 18 | 19 | ProcessCore::~ProcessCore() 20 | { 21 | Close(); 22 | } 23 | 24 | /// 25 | /// Attach to existing process 26 | /// 27 | /// Process ID 28 | /// Access mask 29 | /// Status 30 | NTSTATUS ProcessCore::Open( DWORD pid, DWORD access ) 31 | { 32 | // Handle current process differently 33 | _hProcess = (pid == GetCurrentProcessId()) ? GetCurrentProcess() : OpenProcess( access, false, pid ); 34 | 35 | // Some routines in win10 do not support pseudo handle 36 | if (IsWindows10OrGreater() && pid == GetCurrentProcessId()) 37 | _hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid ); 38 | 39 | if (_hProcess) 40 | { 41 | _pid = pid; 42 | return Init(); 43 | } 44 | 45 | return LastNtStatus(); 46 | } 47 | 48 | /// 49 | /// Attach to existing process 50 | /// 51 | /// Process ID 52 | /// Access mask 53 | /// Status 54 | NTSTATUS ProcessCore::Open( HANDLE handle ) 55 | { 56 | _hProcess = handle; 57 | _pid = GetProcessId( _hProcess ); 58 | 59 | // Some routines in win10 do not support pseudo handle 60 | if (IsWindows10OrGreater() && _pid == GetCurrentProcessId()) 61 | _hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, _pid ); 62 | 63 | return Init(); 64 | } 65 | 66 | 67 | /// 68 | /// Initialize some internal data 69 | /// 70 | /// Status code 71 | NTSTATUS ProcessCore::Init() 72 | { 73 | // Detect x86 OS 74 | SYSTEM_INFO info = { { 0 } }; 75 | GetNativeSystemInfo( &info ); 76 | 77 | if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) 78 | { 79 | _native = std::make_unique( _hProcess ); 80 | } 81 | else 82 | { 83 | // Detect wow64 barrier 84 | BOOL wowSrc = FALSE; 85 | IsWow64Process( GetCurrentProcess(), &wowSrc ); 86 | 87 | if (wowSrc == TRUE) 88 | _native = std::make_unique( _hProcess ); 89 | else 90 | _native = std::make_unique( _hProcess ); 91 | } 92 | 93 | // Get DEP info 94 | // For native x64 processes DEP is always enabled 95 | if (_native->GetWow64Barrier().targetWow64 == false) 96 | { 97 | _dep = true; 98 | } 99 | else 100 | { 101 | DWORD flags = 0; 102 | BOOL perm = 0; 103 | 104 | if (SAFE_CALL( GetProcessDEPPolicy, _hProcess, &flags, &perm )) 105 | _dep = (flags & PROCESS_DEP_ENABLE) != 0; 106 | } 107 | 108 | return STATUS_SUCCESS; 109 | } 110 | 111 | /// 112 | /// Close current process handle 113 | /// 114 | void ProcessCore::Close() 115 | { 116 | _hProcess.reset(); 117 | _native.reset(); 118 | _pid = 0; 119 | } 120 | 121 | bool ProcessCore::isProtected() 122 | { 123 | if (_hProcess) 124 | { 125 | _PROCESS_EXTENDED_BASIC_INFORMATION_T info = { 0 }; 126 | info.Size = sizeof( info ); 127 | 128 | _native->QueryProcessInfoT( ProcessBasicInformation, &info, sizeof( info ) ); 129 | return info.Flags.IsProtectedProcess; 130 | } 131 | 132 | return false; 133 | } 134 | 135 | } -------------------------------------------------------------------------------- /src/BlackBone/Process/ProcessCore.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Include/NativeStructures.h" 4 | #include "../Include/HandleGuard.h" 5 | #include "../Subsystem/Wow64Subsystem.h" 6 | #include "../Subsystem/x86Subsystem.h" 7 | 8 | #include 9 | #include 10 | 11 | namespace blackbone 12 | { 13 | 14 | class ProcessCore 15 | { 16 | public: 17 | 18 | /// 19 | /// Check if target process is running in WOW64 mode 20 | /// 21 | /// true if process is WOW64 22 | BLACKBONE_API inline bool isWow64() const { return _native->GetWow64Barrier().targetWow64; } 23 | 24 | /// 25 | /// Get process handle 26 | /// 27 | /// Process handle 28 | BLACKBONE_API inline HANDLE handle() const { return _hProcess; } 29 | 30 | /// 31 | /// Get process ID 32 | /// 33 | /// Process ID 34 | BLACKBONE_API inline DWORD pid() const { return _pid; } 35 | 36 | /// 37 | /// Get process data execution prevention state 38 | /// 39 | /// true if DEP is enabled for process 40 | BLACKBONE_API inline bool DEP() const { return _dep; }; 41 | 42 | /// 43 | /// Get system routines 44 | /// 45 | /// 46 | BLACKBONE_API inline Native* native() { return _native.get(); } 47 | 48 | /// 49 | /// Get WOW64 PEB 50 | /// 51 | /// Retrieved PEB32 52 | /// PEB pointer 53 | BLACKBONE_API inline ptr_t peb32( _PEB32* ppeb = nullptr ) { return _native->getPEB( ppeb ); } 54 | 55 | /// 56 | /// Get native PEB 57 | /// 58 | /// Retrieved PEB64 59 | /// PEB pointer 60 | BLACKBONE_API inline ptr_t peb64( _PEB64* ppeb = nullptr ) { return _native->getPEB( ppeb ); } 61 | 62 | /// 63 | /// Get PEB 64 | /// 65 | /// Retrieved PEB 66 | /// PEB pointer 67 | template 68 | BLACKBONE_API inline ptr_t peb( _PEB_T* ppeb = nullptr ) { return _native->getPEB( ppeb ); } 69 | 70 | /// 71 | /// Check if process is a protected process 72 | /// 73 | /// true if protected 74 | BLACKBONE_API bool isProtected(); 75 | 76 | private: 77 | friend class Process; 78 | using ptrNative = std::unique_ptr; 79 | 80 | private: 81 | ProcessCore(); 82 | ProcessCore( const ProcessCore& ) = delete; 83 | ~ProcessCore(); 84 | 85 | /// 86 | /// Attach to existing process 87 | /// 88 | /// Process ID 89 | /// Access mask 90 | /// Status 91 | NTSTATUS Open( DWORD pid, DWORD access ); 92 | 93 | /// 94 | /// Attach to existing process by handle 95 | /// 96 | /// Process handle 97 | /// Status 98 | NTSTATUS Open( HANDLE handle ); 99 | 100 | /// 101 | /// Initialize some internal data 102 | /// 103 | /// Status code 104 | NTSTATUS Init(); 105 | 106 | /// 107 | /// Close current process handle 108 | /// 109 | void Close(); 110 | 111 | private: 112 | ProcessHandle _hProcess; // Process handle 113 | DWORD _pid = 0; // Process ID 114 | ptrNative _native; // Api wrapper 115 | bool _dep = true; // DEP state for process 116 | }; 117 | 118 | } -------------------------------------------------------------------------------- /src/BlackBone/Process/RPC/RemoteLocalHook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../Config.h" 4 | #include "../../Asm/AsmFactory.h" 5 | #include "../../Include/Types.h" 6 | #include "../MemBlock.h" 7 | 8 | 9 | 10 | namespace blackbone 11 | { 12 | 13 | 14 | /// 15 | /// In-process remote hook 16 | /// 17 | class RemoteLocalHook 18 | { 19 | public: 20 | // Must be large enough to hold ANY jump this code uses 21 | static const size_t MaxHookJumpCodeLen = 14; 22 | 23 | // The displaced code should be at most 1 hook length + 1 instruction - 1 byte (if the hook jump overlaps with only the 24 | // first byte of the following instruction), and x86_64 instructions can be at most 15 bytes. 25 | static const size_t MaxOriginalCodeLen = MaxHookJumpCodeLen + 14; 26 | 27 | static const size_t MaxPatchedOriginalCodeLen = MaxOriginalCodeLen; 28 | 29 | enum eJumpStrategy 30 | { 31 | JumpPushMovRet, 32 | JumpMovRegRet 33 | }; 34 | 35 | private: 36 | /// 37 | /// Hook data 38 | /// 39 | #pragma pack(push, 1) 40 | struct HookCtx 41 | { 42 | ptr_t address; // Hooked address in original code 43 | ptr_t thunkAddr; 44 | uint8_t origCodeSize; // Size of displaced original code 45 | uint8_t origCode[MaxOriginalCodeLen]; // Copy of displaced original code 46 | uint8_t patchedOrigCode[MaxPatchedOriginalCodeLen]; 47 | uint8_t hookJumpCode[MaxHookJumpCodeLen]; 48 | uint8_t hookJumpCodeSize; 49 | }; 50 | #pragma pack(pop) 51 | 52 | public: 53 | RemoteLocalHook( class Process& process ); 54 | ~RemoteLocalHook(); 55 | 56 | void SetJumpStrategy(eJumpStrategy strategy); 57 | void SetJumpRegister(const asmjit::X86GpReg& reg); 58 | 59 | NTSTATUS SetHook( ptr_t address, asmjit::Assembler& hook ); 60 | NTSTATUS Restore(); 61 | 62 | NTSTATUS PrepareHook( ptr_t address, size_t maxHookSize ); 63 | 64 | size_t GetDisplacedOriginalCode( uint8_t* code = nullptr ); 65 | 66 | bool isHooked() const { return _hooked; } 67 | 68 | private: 69 | RemoteLocalHook( const RemoteLocalHook& ) = delete; 70 | RemoteLocalHook& operator = (const RemoteLocalHook&) = delete; 71 | 72 | NTSTATUS AllocateMem( ptr_t address, size_t hookCodeSize ); 73 | 74 | NTSTATUS CopyOldCode( bool x64 ); 75 | 76 | uint8_t GenerateJump( uint8_t* code, ptr_t toAddr, ptr_t fromAddr, bool x64 ) const; 77 | 78 | private: 79 | class Process& _process; 80 | HookCtx _ctx; 81 | MemBlock _hookData; 82 | eJumpStrategy _jumpStrategy = JumpPushMovRet; 83 | const asmjit::X86GpReg* _jumpRegister = &asmjit::host::rax; 84 | 85 | bool _prepared = false; 86 | bool _hooked = false; 87 | }; 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/BlackBone/Process/Threads/Threads.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../Include/Winheaders.h" 4 | #include "Thread.h" 5 | 6 | #include 7 | #include 8 | 9 | namespace blackbone 10 | { 11 | 12 | class ProcessThreads 13 | { 14 | public: 15 | BLACKBONE_API ProcessThreads( class ProcessCore& core ); 16 | BLACKBONE_API ~ProcessThreads(); 17 | 18 | ProcessThreads( const ProcessThreads& ) = delete; 19 | ProcessThreads& operator =( const ProcessThreads& ) = delete; 20 | 21 | /// 22 | /// Create the thread. 23 | /// 24 | /// Thread enty point 25 | /// Thread argument. 26 | /// Thread creation flags 27 | /// New thread object 28 | BLACKBONE_API call_result_t CreateNew( 29 | ptr_t threadProc, 30 | ptr_t arg, 31 | enum CreateThreadFlags flags = static_cast(0) 32 | ); 33 | 34 | /// 35 | /// Gets all process threads 36 | /// 37 | /// Threads collection 38 | BLACKBONE_API std::vector getAll() const; 39 | 40 | /// 41 | /// Get main process thread 42 | /// 43 | /// Pointer to thread object, nullptr if failed 44 | BLACKBONE_API ThreadPtr getMain() const; 45 | 46 | /// 47 | /// Get least executed thread 48 | /// 49 | /// Pointer to thread object, nullptr if failed 50 | BLACKBONE_API ThreadPtr getLeastExecuted() const; 51 | 52 | /// 53 | /// Get most executed thread 54 | /// 55 | /// Pointer to thread object, nullptr if failed 56 | BLACKBONE_API ThreadPtr getMostExecuted() const; 57 | 58 | /// 59 | /// Get random thread 60 | /// 61 | /// Pointer to thread object, nullptr if failed 62 | BLACKBONE_API ThreadPtr getRandom() const; 63 | 64 | /// 65 | /// Get thread by ID 66 | /// 67 | /// Thread ID 68 | /// Pointer to thread object, nullptr if failed 69 | BLACKBONE_API ThreadPtr get( DWORD id ) const; 70 | 71 | private: 72 | class ProcessCore& _core; // Core process functions 73 | }; 74 | 75 | } -------------------------------------------------------------------------------- /src/BlackBone/Subsystem/x86Subsystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "NativeSubsystem.h" 4 | 5 | namespace blackbone 6 | { 7 | 8 | /// 9 | /// X86 OS subsystem. Used 10 | /// 11 | class x86Native : public Native 12 | { 13 | public: 14 | BLACKBONE_API x86Native( HANDLE hProcess ); 15 | BLACKBONE_API ~x86Native(); 16 | 17 | /// 18 | /// Query virtual memory 19 | /// 20 | /// Address to query 21 | /// Retrieved memory info 22 | /// Status code 23 | virtual NTSTATUS VirtualQueryExT( ptr_t lpAddress, PMEMORY_BASIC_INFORMATION64 lpBuffer ); 24 | 25 | /// 26 | /// Get WOW64 thread context 27 | /// 28 | /// Thread handle. 29 | /// Thread context 30 | /// Status code 31 | virtual NTSTATUS GetThreadContextT( HANDLE hThread, _CONTEXT32& ctx ); 32 | 33 | /// 34 | /// Get native thread context 35 | /// 36 | /// Thread handle. 37 | /// Thread context 38 | /// Status code 39 | virtual NTSTATUS GetThreadContextT( HANDLE hThread, _CONTEXT64& ctx ); 40 | 41 | /// 42 | /// Set WOW64 thread context 43 | /// 44 | /// Thread handle. 45 | /// Thread context 46 | /// Status code 47 | virtual NTSTATUS SetThreadContextT( HANDLE hThread, _CONTEXT32& ctx ); 48 | 49 | /// 50 | /// Set native thread context 51 | /// 52 | /// Thread handle. 53 | /// Thread context 54 | /// Status code 55 | virtual NTSTATUS SetThreadContextT( HANDLE hThread, _CONTEXT64& ctx ); 56 | 57 | /// 58 | /// Gets WOW64 PEB 59 | /// 60 | /// Retrieved PEB 61 | /// PEB pointer 62 | virtual ptr_t getPEB( _PEB32* ppeb ); 63 | 64 | /// 65 | /// Get native PEB 66 | /// 67 | /// Retrieved PEB 68 | /// PEB pointer 69 | virtual ptr_t getPEB( _PEB64* ppeb ); 70 | 71 | /// 72 | /// Get WOW64 TEB 73 | /// 74 | /// Retrieved TEB 75 | /// TEB pointer 76 | virtual ptr_t getTEB( HANDLE hThread, _TEB32* pteb ); 77 | 78 | /// 79 | /// Get native TEB 80 | /// 81 | /// Retrieved TEB 82 | /// TEB pointer 83 | virtual ptr_t getTEB( HANDLE hThread, _TEB64* pteb ); 84 | 85 | private: 86 | }; 87 | 88 | } -------------------------------------------------------------------------------- /src/BlackBone/Symbols/PDBHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../include/Types.h" 3 | #include <3rd_party/DIA/dia2.h> 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace blackbone 10 | { 11 | 12 | class PDBHelper 13 | { 14 | public: 15 | PDBHelper(); 16 | ~PDBHelper(); 17 | 18 | /// 19 | /// Initialize symbols for target file 20 | /// 21 | /// Fully qualified path to target PE file 22 | /// Base ptr to add to RVAs 23 | /// Status code 24 | HRESULT Init( const std::wstring& file, ptr_t base = 0 ); 25 | 26 | /// 27 | /// Get symbol RVA 28 | /// 29 | /// Symbol name 30 | /// Resulting RVA 31 | /// Status code 32 | HRESULT GetSymAddress( const std::wstring& symName, ptr_t& result ); 33 | 34 | private: 35 | /// 36 | /// Initialize DIA 37 | /// 38 | /// Status code 39 | HRESULT CoCreateDiaDataSource(); 40 | 41 | /// 42 | /// Build module symbol map 43 | /// 44 | /// Status code 45 | HRESULT PopulateSymbols(); 46 | 47 | private: 48 | // DIA interfaces 49 | CComPtr _source; 50 | CComPtr _session; 51 | CComPtr _global; 52 | 53 | uint64_t _base = 0; // Base ptr to add to RVAs 54 | std::wstring _sympath; // Symbol cache directory 55 | std::unordered_map _cache; // Symbol name <--> RVA map 56 | }; 57 | 58 | } -------------------------------------------------------------------------------- /src/BlackBone/Symbols/PatternLoader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Symbols/SymbolData.h" 3 | #include "../PE/PEImage.h" 4 | 5 | namespace blackbone 6 | { 7 | 8 | /// 9 | /// Scan ntdll for internal loader data 10 | /// 11 | /// Mapped x86 ntdll 12 | /// Mapped x64 ntdll 13 | /// Result 14 | /// Status code 15 | NTSTATUS ScanSymbolPatterns( const pe::PEImage& ntdll32, const pe::PEImage& ntdll64, SymbolData& result ); 16 | 17 | } -------------------------------------------------------------------------------- /src/BlackBone/Symbols/SymbolData.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "SymbolData.h" 3 | 4 | namespace blackbone 5 | { 6 | SymbolData g_symbols; 7 | } -------------------------------------------------------------------------------- /src/BlackBone/Symbols/SymbolData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../include/Types.h" 3 | 4 | namespace blackbone 5 | { 6 | 7 | /// 8 | /// Ntdll internal pointers 9 | /// 10 | struct SymbolData 11 | { 12 | ptr_t LdrKernel32PatchAddress = 0; // Address to patch to enable kernel32 loading under win7 13 | ptr_t APC64PatchAddress = 0; // Address to patch for x64->WOW64 APC dispatching under win7 14 | ptr_t LdrpHandleTlsData32 = 0; // LdrpHandleTlsData address 15 | ptr_t LdrpHandleTlsData64 = 0; // LdrpHandleTlsData address 16 | ptr_t LdrpInvertedFunctionTable32 = 0; // LdrpInvertedFunctionTable address 17 | ptr_t LdrpInvertedFunctionTable64 = 0; // LdrpInvertedFunctionTable address 18 | ptr_t RtlInsertInvertedFunctionTable32 = 0; // RtlInsertInvertedFunctionTable address 19 | ptr_t RtlInsertInvertedFunctionTable64 = 0; // RtlInsertInvertedFunctionTable address 20 | ptr_t LdrpReleaseTlsEntry32 = 0; // LdrpReleaseTlsEntry address 21 | ptr_t LdrpReleaseTlsEntry64 = 0; // LdrpReleaseTlsEntry address 22 | ptr_t LdrProtectMrdata = 0; // LdrProtectMrdata address 23 | }; 24 | 25 | extern SymbolData g_symbols; 26 | 27 | } -------------------------------------------------------------------------------- /src/BlackBone/Symbols/SymbolLoader.cpp: -------------------------------------------------------------------------------- 1 | #include "SymbolLoader.h" 2 | #include "PDBHelper.h" 3 | #include "../Symbols/PatternLoader.h" 4 | #include "../PE/PEImage.h" 5 | 6 | namespace blackbone 7 | { 8 | 9 | SymbolLoader::SymbolLoader() 10 | : _x86OS( false ) 11 | , _wow64Process( false ) 12 | { 13 | SYSTEM_INFO info = { }; 14 | GetNativeSystemInfo( &info ); 15 | 16 | if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) 17 | { 18 | _x86OS = true; 19 | } 20 | else 21 | { 22 | BOOL wowSrc = FALSE; 23 | IsWow64Process( GetCurrentProcess(), &wowSrc ); 24 | _wow64Process = wowSrc != 0; 25 | } 26 | } 27 | 28 | /// 29 | /// Load symbol addresses from PDB or and pattern scans 30 | /// 31 | /// Found symbols 32 | /// Status code 33 | NTSTATUS SymbolLoader::Load( SymbolData& result ) 34 | { 35 | auto [ntdll32, ntdll64] = LoadImages(); 36 | 37 | // Get addresses from pdb 38 | LoadFromSymbols( ntdll32, ntdll64, result ); 39 | 40 | // Fill missing symbols from patterns 41 | return LoadFromPatterns( ntdll32, ntdll64, result ); 42 | } 43 | 44 | /// 45 | /// Load symbol addresses from PDBs 46 | /// 47 | /// Loaded x86 ntdll image 48 | /// Loaded x64 ntdll image 49 | /// Found symbols 50 | /// Status code 51 | NTSTATUS SymbolLoader::LoadFromSymbols( const pe::PEImage& ntdll32, const pe::PEImage& ntdll64, SymbolData& result ) 52 | { 53 | PDBHelper sym32, sym64; 54 | HRESULT hr = sym32.Init( ntdll32.path(), ntdll32.imageBase() ); 55 | if (!_x86OS && SUCCEEDED( hr )) 56 | { 57 | FsRedirector fsr( _wow64Process ); 58 | hr = sym64.Init( ntdll64.path(), ntdll64.imageBase() ); 59 | } 60 | 61 | if (SUCCEEDED( hr )) 62 | { 63 | sym32.GetSymAddress( L"LdrpHandleTlsData", result.LdrpHandleTlsData32 ); 64 | sym64.GetSymAddress( L"LdrpHandleTlsData", result.LdrpHandleTlsData64 ); 65 | 66 | sym32.GetSymAddress( L"LdrpInvertedFunctionTable", result.LdrpInvertedFunctionTable32 ); 67 | sym64.GetSymAddress( L"LdrpInvertedFunctionTable", result.LdrpInvertedFunctionTable64 ); 68 | 69 | sym32.GetSymAddress( L"RtlInsertInvertedFunctionTable", result.RtlInsertInvertedFunctionTable32 ); 70 | sym64.GetSymAddress( L"RtlInsertInvertedFunctionTable", result.RtlInsertInvertedFunctionTable64 ); 71 | 72 | sym32.GetSymAddress( L"LdrpReleaseTlsEntry", result.LdrpReleaseTlsEntry32 ); 73 | sym64.GetSymAddress( L"LdrpReleaseTlsEntry", result.LdrpReleaseTlsEntry64 ); 74 | 75 | sym32.GetSymAddress( L"LdrProtectMrdata", result.LdrProtectMrdata ); 76 | 77 | return STATUS_SUCCESS; 78 | } 79 | 80 | return STATUS_UNSUCCESSFUL; 81 | } 82 | 83 | /// 84 | /// Load symbol addresses from pattern scans 85 | /// 86 | /// Loaded x86 ntdll image 87 | /// Loaded x64 ntdll image 88 | /// Found symbols 89 | /// Status code 90 | NTSTATUS SymbolLoader::LoadFromPatterns( const pe::PEImage& ntdll32, const pe::PEImage& ntdll64, SymbolData& result ) 91 | { 92 | return ScanSymbolPatterns( ntdll32, ntdll64, result ); 93 | } 94 | 95 | /// 96 | /// Load ntdll images from the disk 97 | /// 98 | /// Loaded x86 and x64 ntdll 99 | std::pair SymbolLoader::LoadImages() 100 | { 101 | pe::PEImage ntdll32, ntdll64; 102 | 103 | wchar_t buf[MAX_PATH] = { 0 }; 104 | GetWindowsDirectoryW( buf, MAX_PATH ); 105 | std::wstring windir( buf ); 106 | 107 | if (_x86OS) 108 | { 109 | ntdll32.Load( std::wstring( windir + L"\\System32\\ntdll.dll" ), true ); 110 | } 111 | else 112 | { 113 | FsRedirector fsr( _wow64Process ); 114 | 115 | ntdll64.Load( std::wstring( windir + L"\\System32\\ntdll.dll" ), true ); 116 | ntdll32.Load( std::wstring( windir + L"\\SysWOW64\\ntdll.dll" ), true ); 117 | } 118 | 119 | return std::make_pair( std::move( ntdll32 ), std::move( ntdll64 ) ); 120 | } 121 | 122 | } -------------------------------------------------------------------------------- /src/BlackBone/Symbols/SymbolLoader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "SymbolData.h" 3 | 4 | namespace blackbone 5 | { 6 | 7 | namespace pe 8 | { 9 | class PEImage; 10 | } 11 | 12 | class SymbolLoader 13 | { 14 | public: 15 | BLACKBONE_API SymbolLoader(); 16 | 17 | /// 18 | /// Load symbol addresses from PDB or and pattern scans 19 | /// 20 | /// Found symbols 21 | /// Status code 22 | BLACKBONE_API NTSTATUS Load( SymbolData& result ); 23 | 24 | /// 25 | /// Load symbol addresses from PDBs 26 | /// 27 | /// Loaded x86 ntdll image 28 | /// Loaded x64 ntdll image 29 | /// Found symbols 30 | /// Status code 31 | BLACKBONE_API NTSTATUS LoadFromSymbols( const pe::PEImage& ntdll32, const pe::PEImage& ntdll64, SymbolData& result ); 32 | 33 | /// 34 | /// Load symbol addresses from pattern scans 35 | /// 36 | /// Loaded x86 ntdll image 37 | /// Loaded x64 ntdll image 38 | /// Found symbols 39 | /// Status code 40 | BLACKBONE_API NTSTATUS LoadFromPatterns( const pe::PEImage& ntdll32, const pe::PEImage& ntdll64, SymbolData& result ); 41 | 42 | /// 43 | /// Load ntdll images from the disk 44 | /// 45 | /// Loaded x86 and x64 ntdll 46 | BLACKBONE_API std::pair LoadImages(); 47 | 48 | private: 49 | bool _x86OS; // x86 OS 50 | bool _wow64Process; // Current process is wow64 process 51 | }; 52 | 53 | } -------------------------------------------------------------------------------- /src/BlackBone/Syscalls/Syscall.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Config.h" 3 | #include "../Include/Winheaders.h" 4 | #include 5 | #include 6 | 7 | extern "C" void* syscall_stub(); 8 | 9 | namespace blackbone 10 | { 11 | namespace syscall 12 | { 13 | template 14 | using to_int64 = std::conditional_t; 15 | 16 | #pragma warning(push) 17 | #pragma warning(disable : 4100) 18 | 19 | template 20 | R syscall( int index, Args... args ) 21 | { 22 | auto error = []( NTSTATUS status ) 23 | { 24 | if constexpr (std::is_same_v) 25 | return status; 26 | else 27 | return R(); 28 | }; 29 | 30 | #ifdef USE32 31 | return error( STATUS_NOT_SUPPORTED ); 32 | #else 33 | static_assert(sizeof( R ) <= sizeof( void* ), "Return types larger than void* aren't supported"); 34 | if (index == -1) 35 | return error( STATUS_INVALID_PARAMETER_1 ); 36 | 37 | // Cast types that otherwise will be only half-initialized 38 | auto pfn = reinterpret_cast... )>(syscall_stub); 39 | return pfn( index, sizeof...( Args ), to_int64( args )... ); 40 | #endif 41 | } 42 | 43 | template 44 | NTSTATUS nt_syscall( int index, Args&&... args ) 45 | { 46 | return syscall( index, std::forward( args )... ); 47 | } 48 | 49 | inline int get_index( const wchar_t* modName, const char* func ) 50 | { 51 | #ifdef USE32 52 | // Doesn't work for x86 53 | return -1; 54 | #else 55 | const auto pfn = reinterpret_cast(GetProcAddress( 56 | GetModuleHandleW( modName ), 57 | func 58 | )); 59 | 60 | return pfn ? *reinterpret_cast(pfn + 4) : -1; 61 | #endif 62 | } 63 | 64 | inline int get_index( const char* func ) 65 | { 66 | return get_index( L"ntdll.dll", func ); 67 | } 68 | 69 | #pragma warning(pop) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/BlackBone/Syscalls/Syscall32.asm: -------------------------------------------------------------------------------- 1 | .MODEL flat 2 | .code 3 | 4 | x64_enter proc 5 | retf 6 | x64_enter endp 7 | 8 | x64_exit proc 9 | mov dword ptr [esp + 4], 23h 10 | retf 11 | x64_exit endp 12 | 13 | 14 | _syscall_stub proc 15 | push ebp 16 | mov ebp, esp 17 | sub esp, 20h 18 | 19 | push 33h 20 | call x64_enter 21 | 22 | db 48h 23 | mov eax, 0DEADBEEFh 24 | 25 | call x64_exit 26 | 27 | mov dx, ds 28 | mov ss, dx 29 | 30 | mov esp, ebp 31 | pop ebp 32 | ret 33 | _syscall_stub endp 34 | 35 | end -------------------------------------------------------------------------------- /src/BlackBone/Syscalls/Syscall64.asm: -------------------------------------------------------------------------------- 1 | .code 2 | 3 | syscall_stub proc 4 | mov eax, ecx 5 | 6 | ; validate number of arguments 7 | cmp edx, 1 8 | jl skip 9 | 10 | mov r10, r8 11 | cmp edx, 2 12 | jl skip 13 | 14 | xchg rdx, r9 15 | cmp r9d, 3 16 | jl skip 17 | 18 | mov r8, [rsp + 28h] 19 | cmp r9d, 4 20 | jl skip 21 | 22 | mov r9, [rsp + 30h] 23 | 24 | skip: 25 | add rsp, 10h ; skip first 2 args 26 | syscall 27 | sub rsp, 10h 28 | ret 29 | syscall_stub endp 30 | 31 | end -------------------------------------------------------------------------------- /src/BlackBoneDrv/BlackBoneDrv.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _M_IX86 4 | #error "x86 systems are not supported" 5 | #endif 6 | 7 | #include 8 | 9 | #include "BlackBoneDef.h" 10 | #include "Routines.h" 11 | #include "Remap.h" 12 | 13 | #define DEVICE_NAME L"\\Device\\" ## BLACKBONE_DEVICE_NAME 14 | #define DOS_DEVICE_NAME L"\\DosDevices\\" ## BLACKBONE_DEVICE_NAME 15 | 16 | /// 17 | /// CTL dispatcher 18 | /// 19 | /// Device object 20 | /// IRP 21 | /// Status code 22 | NTSTATUS BBDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); 23 | -------------------------------------------------------------------------------- /src/BlackBoneDrv/BlackBoneDrv.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.26403.3 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BlackBoneDrv", "BlackBoneDrv.vcxproj", "{50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Win10Debug|x64 = Win10Debug|x64 10 | Win10Release|x64 = Win10Release|x64 11 | Win7 Debug|x64 = Win7 Debug|x64 12 | Win7 Release|x64 = Win7 Release|x64 13 | Win8 Debug|x64 = Win8 Debug|x64 14 | Win8 Release|x64 = Win8 Release|x64 15 | Win8.1 Debug|x64 = Win8.1 Debug|x64 16 | Win8.1 Release|x64 = Win8.1 Release|x64 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win10Debug|x64.ActiveCfg = Win10Debug|x64 20 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win10Debug|x64.Build.0 = Win10Debug|x64 21 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win10Debug|x64.Deploy.0 = Win10Debug|x64 22 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win10Release|x64.ActiveCfg = Win10Release|x64 23 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win10Release|x64.Build.0 = Win10Release|x64 24 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win10Release|x64.Deploy.0 = Win10Release|x64 25 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64 26 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Debug|x64.Build.0 = Win7 Debug|x64 27 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64 28 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Release|x64.ActiveCfg = Win7 Release|x64 29 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Release|x64.Build.0 = Win7 Release|x64 30 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Release|x64.Deploy.0 = Win7 Release|x64 31 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 32 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 33 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 34 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 35 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Release|x64.Build.0 = Win8 Release|x64 36 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 37 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64 38 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64 39 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8.1 Debug|x64.Deploy.0 = Win8.1 Debug|x64 40 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64 41 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64 42 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8.1 Release|x64.Deploy.0 = Win8.1 Release|x64 43 | EndGlobalSection 44 | GlobalSection(SolutionProperties) = preSolution 45 | HideSolutionNode = FALSE 46 | EndGlobalSection 47 | EndGlobal 48 | -------------------------------------------------------------------------------- /src/BlackBoneDrv/BlackBoneDrv.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | ImageLoader 6 | 7 | 8 | ImageLoader 9 | 10 | 11 | ImageLoader 12 | 13 | 14 | ImageLoader 15 | 16 | 17 | Core 18 | 19 | 20 | Core 21 | 22 | 23 | Core 24 | 25 | 26 | Helpers 27 | 28 | 29 | Helpers 30 | 31 | 32 | Core 33 | 34 | 35 | Core 36 | 37 | 38 | Helpers 39 | 40 | 41 | Core 42 | 43 | 44 | 45 | 46 | Include 47 | 48 | 49 | Include\Native 50 | 51 | 52 | Include\Native 53 | 54 | 55 | Include\Native 56 | 57 | 58 | Include\Native 59 | 60 | 61 | Include 62 | 63 | 64 | Include 65 | 66 | 67 | Include 68 | 69 | 70 | Include 71 | 72 | 73 | Include\Native 74 | 75 | 76 | Include 77 | 78 | 79 | Include 80 | 81 | 82 | Include\Native 83 | 84 | 85 | Include\Native 86 | 87 | 88 | Include 89 | 90 | 91 | Include\Native 92 | 93 | 94 | Include 95 | 96 | 97 | 98 | 99 | {b7e17437-db3c-4555-9fd0-40e3b20f6b54} 100 | 101 | 102 | {1777770d-b977-4802-9b7d-a2c21fcfed88} 103 | 104 | 105 | {8be939a3-549a-412d-a84a-7412ef2ad186} 106 | 107 | 108 | {5f2d2fea-d59d-40a3-a70f-9d75f5fdedf4} 109 | 110 | 111 | {2ad9b16d-24eb-4a97-bb5b-d815b83b78c7} 112 | 113 | 114 | -------------------------------------------------------------------------------- /src/BlackBoneDrv/NotifyRoutine.c: -------------------------------------------------------------------------------- 1 | #include "Remap.h" 2 | #include "BlackBoneDrv.h" 3 | #include "Routines.h" 4 | 5 | #pragma alloc_text(PAGE, BBProcessNotify) 6 | 7 | 8 | /// 9 | /// Process termination handler 10 | /// 11 | /// Parent PID 12 | /// PID 13 | /// TRUE if process was created 14 | VOID BBProcessNotify( IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create ) 15 | { 16 | UNREFERENCED_PARAMETER( ParentId ); 17 | PPROCESS_MAP_ENTRY pProcessEntry = NULL; 18 | PMEM_PHYS_PROCESS_ENTRY pPhysProcessEntry = NULL; 19 | 20 | if (Create == FALSE) 21 | { 22 | pPhysProcessEntry = BBLookupPhysProcessEntry( ProcessId ); 23 | if (pPhysProcessEntry != NULL) 24 | { 25 | DPRINT( "BlackBone: %s: Target process %u shutdown. Physical memory Cleanup\n", __FUNCTION__, ProcessId ); 26 | BBCleanupProcessPhysEntry( pPhysProcessEntry, TRUE ); 27 | } 28 | 29 | KeAcquireGuardedMutex( &g_globalLock ); 30 | 31 | pProcessEntry = BBLookupProcessEntry( ProcessId, FALSE ); 32 | 33 | // Target process shutdown 34 | if (pProcessEntry != NULL) 35 | { 36 | DPRINT( "BlackBone: %s: Target process %u shutdown. Cleanup\n", __FUNCTION__, pProcessEntry->target.pid ); 37 | BBCleanupProcessEntry( pProcessEntry ); 38 | } 39 | else 40 | { 41 | pProcessEntry = BBLookupProcessEntry( ProcessId, TRUE ); 42 | 43 | // Host process shutdown 44 | if (pProcessEntry != NULL) 45 | BBCleanupHostProcess( pProcessEntry ); 46 | } 47 | 48 | KeReleaseGuardedMutex( &g_globalLock ); 49 | } 50 | } -------------------------------------------------------------------------------- /src/BlackBoneDrv/Utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | /// 5 | /// Allocate new Unicode string from Paged pool 6 | /// 7 | /// Resulting string 8 | /// Buffer size in bytes to alloacate 9 | /// Status code 10 | NTSTATUS BBSafeAllocateString( OUT PUNICODE_STRING result, IN USHORT size ); 11 | 12 | /// 13 | /// Allocate and copy string 14 | /// 15 | /// Resulting string 16 | /// Source string 17 | /// Status code 18 | NTSTATUS BBSafeInitString( OUT PUNICODE_STRING result, IN PUNICODE_STRING source ); 19 | 20 | /// 21 | /// Search for substring 22 | /// 23 | /// Source string 24 | /// Target string 25 | /// Case insensitive search 26 | /// Found position or -1 if not found 27 | LONG BBSafeSearchString( IN PUNICODE_STRING source, IN PUNICODE_STRING target, IN BOOLEAN CaseInSensitive ); 28 | 29 | /// 30 | /// Get file name from full path 31 | /// 32 | /// Path. 33 | /// Resulting name 34 | /// Status code 35 | NTSTATUS BBStripPath( IN PUNICODE_STRING path, OUT PUNICODE_STRING name ); 36 | 37 | /// 38 | /// Get directory path name from full path 39 | /// 40 | /// Path 41 | /// Resulting directory path 42 | /// Status code 43 | NTSTATUS BBStripFilename( IN PUNICODE_STRING path, OUT PUNICODE_STRING dir ); 44 | 45 | /// 46 | /// Check if file exists 47 | /// 48 | /// Fully qualifid path to a file 49 | /// Status code 50 | NTSTATUS BBFileExists( IN PUNICODE_STRING path ); 51 | 52 | /// 53 | /// Search for pattern 54 | /// 55 | /// Pattern to search for 56 | /// Used wildcard 57 | /// Pattern length 58 | /// Base address for searching 59 | /// Address range to search in 60 | /// Found location 61 | /// Status code 62 | NTSTATUS BBSearchPattern( IN PCUCHAR pattern, IN UCHAR wildcard, IN ULONG_PTR len, IN const VOID* base, IN ULONG_PTR size, OUT PVOID* ppFound ); 63 | 64 | /// 65 | /// Setup image security cookie 66 | /// 67 | /// Image base 68 | /// Status code 69 | NTSTATUS BBCreateCookie( IN PVOID imageBase ); 70 | 71 | /// 72 | /// Check if process is terminating 73 | /// 74 | /// Process 75 | /// If TRUE - terminating 76 | BOOLEAN BBCheckProcessTermination( PEPROCESS pProcess ); 77 | 78 | // 79 | // Machine code generation routines 80 | // 81 | ULONG GenPrologue32( IN PUCHAR pBuf ); 82 | ULONG GenEpilogue32( IN PUCHAR pBuf, IN INT retSize ); 83 | ULONG GenCall32( IN PUCHAR pBuf, IN PVOID pFn, IN INT argc, ... ); 84 | ULONG GenCall32V( IN PUCHAR pBuf, IN PVOID pFn, IN INT argc, IN va_list vl ); 85 | ULONG GenSync32( IN PUCHAR pBuf, IN PNTSTATUS pStatus, IN PVOID pSetEvent, IN HANDLE hEvent ); 86 | 87 | 88 | ULONG GenPrologue64( IN PUCHAR pBuf ); 89 | ULONG GenEpilogue64( IN PUCHAR pBuf, IN INT retSize ); 90 | ULONG GenCall64( IN PUCHAR pBuf, IN PVOID pFn, IN INT argc, ... ); 91 | ULONG GenCall64V( IN PUCHAR pBuf, IN PVOID pFn, IN INT argc, IN va_list vl ); 92 | ULONG GenSync64( IN PUCHAR pBuf, IN PNTSTATUS pStatus, IN PVOID pSetEvent, IN HANDLE hEvent ); 93 | 94 | 95 | ULONG GenPrologueT( IN BOOLEAN wow64, IN PUCHAR pBuf ); 96 | ULONG GenEpilogueT( IN BOOLEAN wow64, IN PUCHAR pBuf, IN INT retSize ); 97 | ULONG GenCallT( IN BOOLEAN wow64, IN PUCHAR pBuf, IN PVOID pFn, IN INT argc, ... ); 98 | ULONG GenCallTV( IN BOOLEAN wow64, IN PUCHAR pBuf, IN PVOID pFn, IN INT argc, IN va_list vl ); 99 | ULONG GenSyncT( IN BOOLEAN wow64, IN PUCHAR pBuf, IN PNTSTATUS pStatus, IN PVOID pSetEvent, IN HANDLE hEvent ); 100 | -------------------------------------------------------------------------------- /src/BlackBoneDrv/VadHelpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define SANITIZE_PARENT_NODE(Parent) ((PMMADDRESS_NODE)(((ULONG_PTR)(Parent)) & ~0x3)) 4 | 5 | // 6 | // Various Rtl macros that reference Parent use private versions here since 7 | // Parent is overloaded with Balance. 8 | // 9 | 10 | // 11 | // The macro function Parent takes as input a pointer to a splay link in a 12 | // tree and returns a pointer to the splay link of the parent of the input 13 | // node. If the input node is the root of the tree the return value is 14 | // equal to the input value. 15 | // 16 | // PRTL_SPLAY_LINKS 17 | // MiParent ( 18 | // PRTL_SPLAY_LINKS Links 19 | // ); 20 | // 21 | 22 | #define MiParent(Links) ( \ 23 | (PRTL_SPLAY_LINKS)(SANITIZE_PARENT_NODE((Links)->u1.Parent)) \ 24 | ) 25 | 26 | // 27 | // The macro function IsLeftChild takes as input a pointer to a splay link 28 | // in a tree and returns TRUE if the input node is the left child of its 29 | // parent, otherwise it returns FALSE. 30 | // 31 | // BOOLEAN 32 | // MiIsLeftChild ( 33 | // PRTL_SPLAY_LINKS Links 34 | // ); 35 | // 36 | 37 | #define MiIsLeftChild(Links) ( \ 38 | (RtlLeftChild(MiParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) \ 39 | ) 40 | 41 | // 42 | // The macro function IsRightChild takes as input a pointer to a splay link 43 | // in a tree and returns TRUE if the input node is the right child of its 44 | // parent, otherwise it returns FALSE. 45 | // 46 | // BOOLEAN 47 | // MiIsRightChild ( 48 | // PRTL_SPLAY_LINKS Links 49 | // ); 50 | // 51 | 52 | #define MiIsRightChild(Links) ( \ 53 | (RtlRightChild(MiParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) \ 54 | ) 55 | 56 | #define MI_MAKE_PARENT(ParentNode, ExistingBalance) \ 57 | (PMMADDRESS_NODE)((ULONG_PTR)(ParentNode) | (((ULONG_PTR)ExistingBalance) & 0x3)) 58 | 59 | #define COUNT_BALANCE_MAX(a) 60 | 61 | 62 | TABLE_SEARCH_RESULT MiFindNodeOrParent( IN PMM_AVL_TABLE Table, IN ULONG_PTR StartingVpn, OUT PMMADDRESS_NODE *NodeOrParent ); 63 | VOID MiPromoteNode( IN PMMADDRESS_NODE C ); 64 | ULONG MiRebalanceNode( IN PMMADDRESS_NODE S ); 65 | VOID MiRemoveNode( IN PMMADDRESS_NODE NodeToDelete, IN PMM_AVL_TABLE Table ); -------------------------------------------------------------------------------- /src/BlackBoneDrv/VadRoutines.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Private.h" 4 | 5 | /// 6 | /// Change VAD protection flags 7 | /// 8 | /// Target process object 9 | /// target address 10 | /// New protection flags 11 | /// Status code 12 | NTSTATUS BBProtectVAD( IN PEPROCESS pProcess, IN ULONG_PTR address, IN ULONG prot ); 13 | 14 | /// 15 | /// Hide memory from NtQueryVirtualMemory 16 | /// 17 | /// Target process object 18 | /// Target address 19 | /// Status code 20 | NTSTATUS BBUnlinkVAD( IN PEPROCESS pProcess, IN ULONG_PTR address ); 21 | 22 | /// 23 | /// Get region VAD type 24 | /// 25 | /// Target process object 26 | /// Target address 27 | /// Resulting VAD type 28 | /// Status code 29 | NTSTATUS BBGetVadType( IN PEPROCESS pProcess, IN ULONG_PTR address, OUT PMI_VAD_TYPE pType ); 30 | 31 | /// 32 | /// Find VAD that describes target address 33 | /// 34 | /// Target process object 35 | /// Address to find 36 | /// Found VAD. NULL if not found 37 | /// Status code 38 | NTSTATUS BBFindVAD( IN PEPROCESS pProcess, IN ULONG_PTR address, OUT PMMVAD_SHORT* pResult ); 39 | 40 | /// 41 | /// Convert protection flags 42 | /// 43 | /// Protection flags. 44 | /// If TRUE - convert to PTE protection, if FALSE - convert to Win32 protection 45 | /// Resulting protection flags 46 | ULONG BBConvertProtection( IN ULONG prot, IN BOOLEAN fromPTE ); -------------------------------------------------------------------------------- /src/BlackBoneDrv/bin/x64/Win10Release/BlackBoneDrv10.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/BlackBoneDrv/bin/x64/Win10Release/BlackBoneDrv10.sys -------------------------------------------------------------------------------- /src/BlackBoneDrv/bin/x64/Win7Release/BlackBoneDrv7.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/BlackBoneDrv/bin/x64/Win7Release/BlackBoneDrv7.sys -------------------------------------------------------------------------------- /src/BlackBoneDrv/bin/x64/Win8.1Release/BlackBoneDrv81.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/BlackBoneDrv/bin/x64/Win8.1Release/BlackBoneDrv81.sys -------------------------------------------------------------------------------- /src/BlackBoneDrv/bin/x64/Win8Release/BlackBoneDrv8.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/BlackBoneDrv/bin/x64/Win8Release/BlackBoneDrv8.sys -------------------------------------------------------------------------------- /src/BlackBoneTest/BlackBoneTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Tests 6 | 7 | 8 | Tests 9 | 10 | 11 | Tests 12 | 13 | 14 | Tests 15 | 16 | 17 | Tests 18 | 19 | 20 | Tests 21 | 22 | 23 | Tests 24 | 25 | 26 | Tests 27 | 28 | 29 | Tests 30 | 31 | 32 | Tests 33 | 34 | 35 | Tests 36 | 37 | 38 | Tests 39 | 40 | 41 | Tests 42 | 43 | 44 | Tests 45 | 46 | 47 | Tests 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {b5cc080f-5ea5-4f14-b732-c1aaf61443c8} 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/BlackBoneTest/Common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | using namespace Microsoft::VisualStudio::CppUnitTestFramework; 19 | using namespace blackbone; 20 | 21 | constexpr wchar_t ModuleName[] = L"BlackBoneTest.dll"; 22 | 23 | /// 24 | /// Some extensions for Assert 25 | /// 26 | class AssertEx : public Assert 27 | { 28 | public: 29 | template 30 | static void IsZero( const T& actual, const wchar_t* message = nullptr, const __LineInfo* pLineInfo = nullptr ) 31 | { 32 | AssertEx::AreEqual( T( 0 ), actual, message, pLineInfo ); 33 | } 34 | 35 | template 36 | static void IsNotZero( const T& actual, const wchar_t* message = nullptr, const __LineInfo* pLineInfo = nullptr ) 37 | { 38 | AssertEx::AreNotEqual( T( 0 ), actual, message, pLineInfo ); 39 | } 40 | 41 | static void NtSuccess( NTSTATUS status, const wchar_t* message = nullptr, const __LineInfo* pLineInfo = nullptr ) 42 | { 43 | AssertEx::IsTrue( status >= 0, message, pLineInfo ); 44 | } 45 | }; 46 | 47 | namespace Microsoft::VisualStudio::CppUnitTestFramework { 48 | template<> inline std::wstring ToString( const AsmVariant::eType& t ) { RETURN_WIDE_STRING( t ); } 49 | } 50 | 51 | inline std::wstring GetTestHelperDir() 52 | { 53 | wchar_t buf[MAX_PATH] = { }; 54 | GetModuleFileNameW( GetModuleHandle( ModuleName ), buf, _countof( buf ) ); 55 | std::wstring path = buf; 56 | if (path.empty()) 57 | return path; 58 | 59 | // Get project root path 60 | for (int i = 0; i < 4; i++) 61 | path = Utils::GetParent( path ); 62 | 63 | return path + L"\\Testing"; 64 | } 65 | 66 | inline std::wstring GetTestHelperHost32() 67 | { 68 | return GetTestHelperDir() + L"\\TestHelper32.exe"; 69 | } 70 | 71 | inline std::wstring GetTestHelperHost64() 72 | { 73 | return GetTestHelperDir() + L"\\TestHelper64.exe"; 74 | } 75 | 76 | inline std::wstring GetTestHelperHost() 77 | { 78 | #ifdef USE64 79 | return GetTestHelperHost64(); 80 | #else 81 | return GetTestHelperHost32(); 82 | #endif 83 | } 84 | 85 | inline std::wstring GetTestHelperDll32() 86 | { 87 | return GetTestHelperDir() + L"\\TestDll32.dll"; 88 | } 89 | 90 | inline std::wstring GetTestHelperDll64() 91 | { 92 | return GetTestHelperDir() + L"\\TestDll64.dll"; 93 | } 94 | 95 | inline std::wstring GetTestHelperDll() 96 | { 97 | #ifdef USE64 98 | return GetTestHelperDll64(); 99 | #else 100 | return GetTestHelperDll32(); 101 | #endif 102 | } 103 | -------------------------------------------------------------------------------- /src/BlackBoneTest/TestAsmJit.cpp: -------------------------------------------------------------------------------- 1 | #include "Common.h" 2 | 3 | namespace Testing 4 | { 5 | TEST_CLASS( AsmJIT ) 6 | { 7 | public: 8 | TEST_METHOD( Add ) 9 | { 10 | auto asmPtr = AsmFactory::GetAssembler(); 11 | auto& a = *asmPtr; 12 | 13 | a.GenPrologue(); 14 | a->add( a->zcx, a->zdx ); 15 | a->mov( a->zax, a->zcx ); 16 | a.GenEpilogue(); 17 | 18 | auto func = reinterpret_cast(a->make()); 19 | 20 | AssertEx::AreEqual( intptr_t( 15 ), func( 10, 5 ) ); 21 | AssertEx::AreEqual( intptr_t( 5 ), func( 10, -5 ) ); 22 | } 23 | 24 | TEST_METHOD( Call ) 25 | { 26 | auto asmPtr = AsmFactory::GetAssembler(); 27 | auto& a = *asmPtr; 28 | 29 | wchar_t buf[MAX_PATH] = { }; 30 | 31 | a.GenPrologue(); 32 | a.GenCall( reinterpret_cast(&GetModuleHandle), { ModuleName } ); 33 | a.GenCall( reinterpret_cast(&GetModuleFileNameW), { a->zax, buf, _countof( buf ) } ); 34 | a.GenEpilogue(); 35 | 36 | auto func = reinterpret_cast(a->make()); 37 | func(); 38 | 39 | std::wstring name = Utils::ToLower( buf ); 40 | AssertEx::AreNotEqual( name.npos, name.rfind( Utils::ToLower( ModuleName ) ) ); 41 | } 42 | 43 | TEST_METHOD( MultiCall ) 44 | { 45 | auto asmPtr = AsmFactory::GetAssembler(); 46 | auto& a = *asmPtr; 47 | 48 | a.EnableX64CallStack( false ); 49 | auto skip = a->newLabel(); 50 | 51 | uint8_t writeBuf[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; 52 | auto filePath = L"DummyFile_MultiCall.dat"; 53 | DWORD bytes = 0; 54 | 55 | AsmStackAllocator stack( a.assembler() ); 56 | ALLOC_STACK_VAR( stack, handle, HANDLE ); 57 | 58 | a.GenPrologue(); 59 | a->sub( a->zsp, 0x48 ); 60 | a.GenCall( reinterpret_cast(&CreateFileW), { a->zcx, GENERIC_WRITE, 0x7, nullptr, CREATE_ALWAYS, 0, nullptr } ); 61 | a->mov( handle, a->zax ); 62 | a->cmp( a->zax, reinterpret_cast(INVALID_HANDLE_VALUE) ); 63 | a->je( skip ); 64 | a.GenCall( reinterpret_cast(&WriteFile), { handle, writeBuf, sizeof( writeBuf ), &bytes, nullptr } ); 65 | a->test( a->zax, a->zax ); 66 | a->jz( skip ); 67 | a.GenCall( reinterpret_cast(&CloseHandle), { handle } ); 68 | a->bind( skip ); 69 | a->add( a->zsp, 0x48 ); 70 | a.GenEpilogue(); 71 | 72 | auto func = reinterpret_cast(a->make()); 73 | BOOL b = func( filePath ); 74 | AssertEx::IsTrue( b ); 75 | 76 | // Check locally 77 | auto hFile = Handle( CreateFileW( filePath, GENERIC_READ, 0x7, nullptr, OPEN_EXISTING, FILE_DELETE_ON_CLOSE, nullptr ) ); 78 | AssertEx::IsTrue( hFile ); 79 | 80 | uint8_t readBuf[sizeof( writeBuf )] = { }; 81 | b = ReadFile( hFile, readBuf, sizeof( readBuf ), &bytes, nullptr ); 82 | 83 | AssertEx::IsTrue( b ); 84 | AssertEx::AreEqual( static_cast(sizeof( readBuf )), bytes ); 85 | AssertEx::IsZero( memcmp( writeBuf, readBuf, sizeof( readBuf ) ) ); 86 | } 87 | }; 88 | } -------------------------------------------------------------------------------- /src/BlackBoneTest/TestBasic.cpp: -------------------------------------------------------------------------------- 1 | #include "Common.h" 2 | 3 | namespace Testing 4 | { 5 | TEST_MODULE_INITIALIZE( ModuleInit ) 6 | { 7 | InitializeOnce(); 8 | } 9 | 10 | TEST_CLASS( Generic ) 11 | { 12 | public: 13 | TEST_METHOD_INITIALIZE( ClassInitialize ) 14 | { 15 | AssertEx::NtSuccess( _proc.Attach( GetCurrentProcessId() ) ); 16 | } 17 | 18 | TEST_METHOD( PEB ) 19 | { 20 | _PEB32 peb32 = { }; 21 | _PEB64 peb64 = { }; 22 | 23 | auto ppeb32 = _proc.core().peb32( &peb32 ); 24 | auto ppeb64 = _proc.core().peb64( &peb64 ); 25 | 26 | AssertEx::IsNotZero( ppeb64 ); 27 | AssertEx::IsNotZero( peb64.Ldr ); 28 | 29 | if (_proc.barrier().targetWow64) 30 | { 31 | AssertEx::IsNotZero( ppeb32 ); 32 | AssertEx::IsNotZero( peb32.Ldr ); 33 | } 34 | } 35 | 36 | TEST_METHOD( TEB ) 37 | { 38 | _TEB32 teb32 = { }; 39 | _TEB64 teb64 = { }; 40 | 41 | auto pteb32 = _proc.threads().getMain()->teb( &teb32 ); 42 | auto pteb64 = _proc.threads().getMain()->teb( &teb64 ); 43 | 44 | AssertEx::IsNotZero( pteb64 ); 45 | AssertEx::IsNotZero( teb64.ClientId.UniqueThread ); 46 | 47 | if (_proc.barrier().targetWow64) 48 | { 49 | AssertEx::IsNotZero( pteb32 ); 50 | AssertEx::IsNotZero( teb32.ClientId.UniqueThread ); 51 | AssertEx::IsNotZero( teb32.ClientId.UniqueThread ); 52 | } 53 | } 54 | 55 | static DWORD CALLBACK VoidFn( void* ) 56 | { 57 | return 0; 58 | } 59 | 60 | TEST_METHOD( InvalidHandles ) 61 | { 62 | Process baseProc; 63 | baseProc.CreateAndAttach( GetTestHelperHost32() ); 64 | 65 | Process proc1; 66 | AssertEx::NtSuccess( proc1.Attach( baseProc.pid(), PROCESS_ALL_ACCESS & ~PROCESS_CREATE_THREAD ) ); 67 | AssertEx::AreEqual( STATUS_ACCESS_DENIED, proc1.threads().CreateNew( reinterpret_cast(&VoidFn), 0 ).status ); 68 | 69 | Process proc2; 70 | AssertEx::NtSuccess( proc2.Attach( baseProc.pid(), PROCESS_ALL_ACCESS & ~PROCESS_VM_READ ) ); 71 | 72 | PEB_T peb = { }; 73 | AssertEx::IsNotZero( proc2.core().peb( &peb ) ); 74 | AssertEx::IsZero( peb.ImageBaseAddress ); 75 | AssertEx::AreEqual( STATUS_ACCESS_DENIED, LastNtStatus() ); 76 | 77 | baseProc.Terminate(); 78 | } 79 | 80 | private: 81 | Process _proc; 82 | }; 83 | } -------------------------------------------------------------------------------- /src/BlackBoneTest/TestModules.cpp: -------------------------------------------------------------------------------- 1 | #include "Common.h" 2 | 3 | namespace Testing 4 | { 5 | 6 | TEST_CLASS( Modules ) 7 | { 8 | public: 9 | TEST_METHOD_INITIALIZE( ClassInitialize ) 10 | { 11 | AssertEx::NtSuccess( _proc.Attach( GetCurrentProcessId() ) ); 12 | } 13 | 14 | TEST_METHOD( MainModule ) 15 | { 16 | auto mod = _proc.modules().GetMainModule(); 17 | ValidateModule( *mod, (module_t)GetModuleHandleW( nullptr ) ); 18 | } 19 | 20 | TEST_METHOD( EnumModules ) 21 | { 22 | auto name = L"kernel32.dll"; 23 | 24 | auto manuals = _proc.modules().GetManualModules(); 25 | AssertEx::IsTrue( manuals.empty() ); 26 | 27 | auto byLdrList = _proc.modules().GetModule( name, LdrList ); 28 | 29 | _proc.modules().reset(); 30 | auto byHeaders = _proc.modules().GetModule( name, Sections ); 31 | 32 | ValidateModule( *byLdrList, reinterpret_cast(GetModuleHandleW( name )) ); 33 | ValidateModule( *byHeaders, reinterpret_cast(GetModuleHandleW( name )) ); 34 | 35 | AssertEx::AreEqual( byLdrList->baseAddress, byHeaders->baseAddress ); 36 | AssertEx::AreEqual( byLdrList->name, byHeaders->name ); 37 | } 38 | 39 | void ValidateModule( const ModuleData& mod, module_t expectedBase ) 40 | { 41 | AssertEx::AreEqual( expectedBase, mod.baseAddress ); 42 | AssertEx::IsNotZero( mod.size ); 43 | AssertEx::IsFalse( mod.manual ); 44 | AssertEx::IsFalse( mod.name.empty() ); 45 | AssertEx::IsFalse( mod.fullPath.empty() ); 46 | 47 | #ifdef USE64 48 | AssertEx::AreEqual( static_cast(mt_mod64), static_cast(mod.type) ); 49 | #else 50 | AssertEx::AreEqual( static_cast(mt_mod32), static_cast(mod.type) ); 51 | #endif 52 | } 53 | 54 | TEST_METHOD( Export ) 55 | { 56 | auto expected = GetProcAddress( GetModuleHandleW( L"kernel32.dll" ), "CreateFileW" ); 57 | AssertEx::IsNotNull( reinterpret_cast(expected) ); 58 | 59 | auto result = _proc.modules().GetExport( L"kernel32.dll", "CreateFileW" ); 60 | AssertEx::IsTrue( result.success() ); 61 | AssertEx::AreEqual( reinterpret_cast(expected), result->procAddress ); 62 | } 63 | 64 | private: 65 | Process _proc; 66 | }; 67 | } -------------------------------------------------------------------------------- /src/BlackBoneTest/TestMultiPtr.cpp: -------------------------------------------------------------------------------- 1 | #include "Common.h" 2 | 3 | namespace Testing 4 | { 5 | constexpr intptr_t off[] = { 0x10, 0x20, 0x30 }; 6 | 7 | struct s_end 8 | { 9 | int ival = 74; 10 | float fval = 12.0f; 11 | 12 | virtual int fn1() { return 1; } 13 | virtual int fn2() { return 2; } 14 | virtual int fn3() { return ival + static_cast(fval); } 15 | }; 16 | 17 | struct s1 18 | { 19 | uint8_t pad[off[2]]; 20 | s_end* pEnd = new s_end(); 21 | }; 22 | 23 | struct s2 24 | { 25 | uint8_t pad[off[1]]; 26 | s1* pS1 = new s1(); 27 | }; 28 | 29 | struct s3 30 | { 31 | uint8_t pad[off[0]]; 32 | s2* pS2 = new s2(); 33 | }; 34 | 35 | // stupid C3865 : "'__thiscall' : can only be used on native member functions", even for a type declaration 36 | typedef int( __fastcall* pfnClass )(s_end* _this, void* zdx); 37 | 38 | TEST_CLASS( MultiPtr ) 39 | { 40 | public: 41 | MultiPtr() 42 | : _object( new s3 ) 43 | , _guard( _object ) 44 | , _objectPtr( reinterpret_cast(&_object) ) 45 | { 46 | } 47 | 48 | TEST_METHOD_INITIALIZE( ClassInitialize ) 49 | { 50 | AssertEx::IsNotNull( _guard.get() ); 51 | 52 | auto orig = _guard->pS2->pS1->pEnd->fval; 53 | AssertEx::AreEqual( 12.0f, orig, 0.001f ); 54 | AssertEx::AreEqual( _guard->pS2->pS1->pEnd->ival + static_cast(_guard->pS2->pS1->pEnd->fval), _guard->pS2->pS1->pEnd->fn3() ); 55 | } 56 | 57 | TEST_METHOD( LocalStruct ) 58 | { 59 | multi_ptr struct_ptr( _objectPtr, { off[0], off[1], off[2] } ); 60 | s_end* pEnd = struct_ptr; 61 | 62 | AssertEx::AreEqual( reinterpret_cast(_guard->pS2->pS1->pEnd), reinterpret_cast(pEnd) ); 63 | } 64 | 65 | TEST_METHOD( LocalFloat ) 66 | { 67 | multi_ptr struct_ptr( _objectPtr, { off[0], off[1], off[2] } ); 68 | multi_ptr float_ptr( _objectPtr, { off[0], off[1], off[2], static_cast(offsetOf( &s_end::fval )) } ); 69 | 70 | s_end* pEnd = struct_ptr; 71 | 72 | const float newVal = 15.7f; 73 | *float_ptr = 15.7f; 74 | 75 | AssertEx::AreEqual( pEnd->fval, newVal, 0.001f ); 76 | } 77 | 78 | TEST_METHOD( LocalMethod ) 79 | { 80 | multi_ptr struct_ptr( _objectPtr, { off[0], off[1], off[2] } ); 81 | multi_ptr func_ptr( _objectPtr, { off[0], off[1], off[2], 0, 2 * sizeof( pfnClass ) } ); 82 | 83 | s_end* pEnd = struct_ptr; 84 | 85 | AssertEx::AreEqual( pEnd->ival + static_cast(pEnd->fval), func_ptr( pEnd, nullptr ) ); 86 | } 87 | 88 | TEST_METHOD( Remote ) 89 | { 90 | Process proc; 91 | AssertEx::NtSuccess( proc.Attach( GetCurrentProcessId() ) ); 92 | 93 | const float newVal = 25.0f; 94 | 95 | multi_ptr_ex ptr_ex( &proc, _objectPtr, { off[0], off[1], off[2] } ); 96 | auto pVal_ex = ptr_ex.get(); 97 | AssertEx::IsNotNull( pVal_ex ); 98 | AssertEx::IsNotZero( pVal_ex->fval ); 99 | 100 | pVal_ex->fval = 25.0; 101 | AssertEx::AreEqual( STATUS_SUCCESS, ptr_ex.commit() ); 102 | pVal_ex = ptr_ex.get(); 103 | 104 | AssertEx::IsNotNull( pVal_ex ); 105 | AssertEx::AreEqual( newVal, pVal_ex->fval, 0.001f ); 106 | } 107 | 108 | private: 109 | s3 * _object; 110 | std::unique_ptr _guard; 111 | uintptr_t _objectPtr; 112 | }; 113 | 114 | } -------------------------------------------------------------------------------- /src/BlackBoneTest/TestPatternScan.cpp: -------------------------------------------------------------------------------- 1 | #include "Common.h" 2 | 3 | namespace Testing 4 | { 5 | TEST_CLASS( PatternScan ) 6 | { 7 | public: 8 | TEST_METHOD_INITIALIZE( ClassInitialize ) 9 | { 10 | AssertEx::NtSuccess( _proc.Attach( L"explorer.exe" ) ); 11 | } 12 | 13 | // Scan all allocated process memory 14 | TEST_METHOD( Simple ) 15 | { 16 | PatternSearch ps1( "\x48\x89\xD0" ); 17 | 18 | std::vector results; 19 | ps1.SearchRemoteWhole( _proc, false, 0, results ); 20 | AssertEx::IsTrue( results.size() > 0 ); 21 | } 22 | 23 | // Scan only inside 'explorer.exe' module 24 | TEST_METHOD( WithWildcard ) 25 | { 26 | PatternSearch ps2{ 0x56, 0x57, 0xCC, 0x55 }; 27 | 28 | auto pMainMod = _proc.modules().GetMainModule(); 29 | AssertEx::IsNotNull( pMainMod.get() ); 30 | 31 | std::vector results; 32 | ps2.SearchRemote( _proc, 0xCC, pMainMod->baseAddress, pMainMod->size, results ); 33 | AssertEx::IsTrue( results.size() > 0 ); 34 | } 35 | 36 | private: 37 | Process _proc; 38 | }; 39 | } -------------------------------------------------------------------------------- /src/BlackBoneTest/TestRemoteMemory.cpp: -------------------------------------------------------------------------------- 1 | #include "Common.h" 2 | 3 | namespace Testing 4 | { 5 | TEST_CLASS( RemoteMem ) 6 | { 7 | #ifdef CI_BUILD 8 | BEGIN_TEST_CLASS_ATTRIBUTE() 9 | TEST_CLASS_ATTRIBUTE( L"Ignore", L"true" ) 10 | END_TEST_CLASS_ATTRIBUTE() 11 | #endif 12 | public: 13 | TEST_METHOD( Everything ) 14 | { 15 | Process proc; 16 | 17 | NTSTATUS status = Driver().EnsureLoaded(); 18 | if (!NT_SUCCESS( status )) 19 | { 20 | AssertEx::AreEqual( STATUS_OBJECT_NAME_NOT_FOUND, status ); 21 | return; 22 | } 23 | 24 | AssertEx::NtSuccess( proc.Attach( L"explorer.exe" ) ); 25 | AssertEx::NtSuccess( proc.memory().Map( false ) ); 26 | 27 | // Translate main module base address 28 | auto addr = proc.modules().GetMainModule()->baseAddress; 29 | auto translated = proc.memory().TranslateAddress( addr ); 30 | AssertEx::IsNotZero( translated ); 31 | 32 | AssertEx::NtSuccess( proc.memory().SetupHook( RemoteMemory::MemVirtualAlloc ) ); 33 | AssertEx::NtSuccess( proc.memory().SetupHook( RemoteMemory::MemVirtualFree ) ); 34 | AssertEx::NtSuccess( proc.memory().SetupHook( RemoteMemory::MemMapSection ) ); 35 | AssertEx::NtSuccess( proc.memory().SetupHook( RemoteMemory::MemUnmapSection ) ); 36 | } 37 | }; 38 | } -------------------------------------------------------------------------------- /src/BlackBoneTest/TestSymbols.cpp: -------------------------------------------------------------------------------- 1 | #include "Common.h" 2 | 3 | namespace Testing 4 | { 5 | TEST_CLASS( Symbols ) 6 | { 7 | public: 8 | TEST_METHOD( SymbolsMatch ) 9 | { 10 | SymbolLoader sl; 11 | SymbolData fromSymbols, fromPatterns; 12 | 13 | auto [ntdll32, ntdll64] = sl.LoadImages(); 14 | 15 | AssertEx::IsNotZero( ntdll32.imageBase() ); 16 | AssertEx::IsNotZero( ntdll64.imageBase() ); 17 | 18 | AssertEx::NtSuccess( sl.LoadFromPatterns( ntdll32, ntdll64, fromPatterns ) ); 19 | 20 | if (NT_SUCCESS( sl.LoadFromSymbols( ntdll32, ntdll64, fromSymbols ) )) 21 | { 22 | AssertEx::AreEqual( fromSymbols.LdrpHandleTlsData32, fromPatterns.LdrpHandleTlsData32 ); 23 | AssertEx::AreEqual( fromSymbols.LdrpHandleTlsData64, fromPatterns.LdrpHandleTlsData64 ); 24 | AssertEx::AreEqual( fromSymbols.LdrpInvertedFunctionTable32, fromPatterns.LdrpInvertedFunctionTable32 ); 25 | AssertEx::AreEqual( fromSymbols.LdrpInvertedFunctionTable64, fromPatterns.LdrpInvertedFunctionTable64 ); 26 | AssertEx::AreEqual( fromSymbols.LdrProtectMrdata, fromPatterns.LdrProtectMrdata ); 27 | AssertEx::AreEqual( fromSymbols.RtlInsertInvertedFunctionTable32, fromPatterns.RtlInsertInvertedFunctionTable32 ); 28 | AssertEx::AreEqual( fromSymbols.RtlInsertInvertedFunctionTable64, fromPatterns.RtlInsertInvertedFunctionTable64 ); 29 | 30 | AssertEx::IsNotZero( fromSymbols.LdrpReleaseTlsEntry32 ); 31 | AssertEx::IsNotZero( fromSymbols.LdrpReleaseTlsEntry64 ); 32 | } 33 | else 34 | { 35 | Logger::WriteMessage( "Failed to load symbols, aborting" ); 36 | } 37 | } 38 | }; 39 | } -------------------------------------------------------------------------------- /src/BlackBoneTest/TestSyscall.cpp: -------------------------------------------------------------------------------- 1 | #include "Common.h" 2 | #include <3rd_party/VersionApi.h> 3 | 4 | namespace Microsoft::VisualStudio::CppUnitTestFramework { 5 | template<> inline std::wstring ToString( HWND__* t ) { RETURN_WIDE_STRING( t ); } 6 | } 7 | 8 | namespace Testing 9 | { 10 | TEST_CLASS( Syscall ) 11 | { 12 | public: 13 | TEST_METHOD( NtAllocateVirtualMemory ) 14 | { 15 | constexpr SIZE_T requested = 0x3000; 16 | PVOID ptr = nullptr; 17 | SIZE_T size = requested; 18 | 19 | auto status = syscall::nt_syscall( 20 | syscall::get_index( "NtAllocateVirtualMemory" ), 21 | GetCurrentProcess(), 22 | &ptr, 23 | 0, 24 | &size, 25 | MEM_COMMIT, 26 | PAGE_EXECUTE_READWRITE 27 | ); 28 | 29 | #ifdef USE32 30 | // Not ready yet 31 | AssertEx::AreEqual( STATUS_NOT_SUPPORTED, status ); 32 | #else 33 | AssertEx::NtSuccess( status ); 34 | 35 | AssertEx::IsNotNull( ptr ); 36 | AssertEx::AreEqual( requested, size ); 37 | 38 | VirtualFree( ptr, 0, MEM_RELEASE ); 39 | #endif 40 | } 41 | 42 | TEST_METHOD( NtUserFindWindowEx ) 43 | { 44 | UNICODE_STRING empty = { }; 45 | UNICODE_STRING wndName = { }; 46 | 47 | constexpr wchar_t name[] = L"Program Manager"; 48 | SAFE_CALL( RtlInitUnicodeString, &wndName, name ); 49 | 50 | auto hwnd = syscall::syscall( 51 | syscall::get_index( IsWindows10OrGreater() ? L"win32u.dll" : L"user32.dll", "NtUserFindWindowEx" ), 52 | HWND_DESKTOP, 53 | nullptr, 54 | &empty, 55 | &wndName, 56 | 0 57 | ); 58 | 59 | #ifdef USE32 60 | // Not ready yet 61 | AssertEx::AreEqual( HWND{}, hwnd ); 62 | #else 63 | AssertEx::AreNotEqual( HWND_DESKTOP, hwnd ); 64 | 65 | wchar_t title[MAX_PATH] = { }; 66 | GetWindowTextW( hwnd, title, _countof( title ) ); 67 | 68 | AssertEx::AreEqual( name, title ); 69 | #endif 70 | } 71 | }; 72 | } -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.13) 2 | project (BlackBone) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 6 | 7 | add_subdirectory(BlackBone) 8 | add_subdirectory(Samples) -------------------------------------------------------------------------------- /src/PythonicBlackBone/BlackBone.py: -------------------------------------------------------------------------------- 1 | import ctypes as c 2 | from ctypes import wintypes as w 3 | import enum 4 | 5 | # Github : x544D 6 | 7 | class PythonicBlackBone(): 8 | 9 | class DataTypes(enum.Enum): 10 | BOOL = 0 11 | INT16 = 1 12 | INT32 = 2 13 | INT64 = 3 14 | FLOAT = 4 15 | DOUBLE = 5 16 | LONG = 6 17 | ULONG = 7 18 | LLONG = 8 19 | ULLONG = 9 20 | SIZE_T = 10 21 | CHAR = 11 22 | BYTE = 12 23 | WCHAR = 13 24 | VOIDP = 14 25 | 26 | 27 | def ParseType(self, i , value=None): 28 | _ = { 29 | 0:c.c_bool, 30 | 1:c.c_int16, 31 | 2:c.c_int32, 32 | 3:c.c_int64, 33 | 4:c.c_float, 34 | 5:c.c_double, 35 | 6:c.c_long, 36 | 7:c.c_ulong, 37 | 8:c.c_longlong, 38 | 9:c.c_ulonglong, 39 | 10:c.c_size_t, 40 | 11:c.c_char, 41 | 12:c.c_byte, 42 | 13:c.c_wchar, 43 | 14:c.c_void_p, 44 | } 45 | F=_[i] 46 | if value:return F(value=value) 47 | else: return F() 48 | 49 | 50 | 51 | def __init__(self, ProcessId , DesiredAccess=0x000F0000|0x00100000|0xFFF): 52 | if ProcessId is None: 53 | print("+ Please Give a valid PID .") 54 | exit(0) 55 | 56 | print("\t[ AN EASY WIN32API PYTHON WRAPPER CTYPE BASED ]\n\t- This is still under Dev .. !") 57 | self.pid = ProcessId 58 | self.access = DesiredAccess 59 | 60 | self.k32 = c.windll.kernel32 61 | self.OpenProcess = self.k32.OpenProcess 62 | self.OpenProcess.argtypes = [w.DWORD,w.BOOL,w.DWORD] 63 | self.OpenProcess.restype = w.HANDLE 64 | 65 | self.ReadProcessMemory = self.k32.ReadProcessMemory 66 | self.ReadProcessMemory.argtypes = [w.HANDLE,w.LPCVOID,w.LPVOID,c.c_size_t,c.POINTER(c.c_size_t)] 67 | self.ReadProcessMemory.restype = w.BOOL 68 | 69 | self.WriteProcessMemory = self.k32.WriteProcessMemory 70 | self.WriteProcessMemory.argtypes = [w.HANDLE,w.LPCVOID,w.LPVOID,c.c_size_t,c.POINTER(c.c_size_t)] 71 | self.WriteProcessMemory.restype = w.BOOL 72 | 73 | self.GetLastError = self.k32.GetLastError 74 | self.GetLastError.argtypes = None 75 | self.GetLastError.restype = w.DWORD 76 | 77 | self.CloseHandle = self.k32.CloseHandle 78 | self.CloseHandle.argtypes = [w.HANDLE] 79 | self.CloseHandle.restype = w.BOOL 80 | 81 | self.hProc = self.OpenProcess(self.access , False, self.pid) 82 | if not self.hProc: 83 | print('+ Failed To open a handle to the Target Process .') 84 | exit(0) 85 | 86 | def CheckLastError(self): 87 | return self.GetLastError() 88 | 89 | def DestroyHandle(self): 90 | self.CloseHandle(self.hProc) 91 | del self 92 | 93 | def RPM(self, address, data): 94 | ''' ReadProcessMemory''' 95 | return self.ReadProcessMemory(self.hProc, address, c.byref(data) , c.sizeof(data), None) 96 | 97 | def WPM(self, address, data): 98 | ''' WriteProcessMemory ''' 99 | return self.WriteProcessMemory(self.hProc, address, c.byref(data) , c.sizeof(data), None) 100 | 101 | def __del__(self): 102 | print(f"+ Instance {type(self).__name__} Destroyed .") 103 | 104 | 105 | 106 | if __name__ == "__main__": 107 | print('+ Please Intanciate the Class first .') 108 | exit(0) -------------------------------------------------------------------------------- /src/PythonicBlackBone/__pycache__/BlackBone.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarthTon/Blackbone/5ede6ce50cd8ad34178bfa6cae05768ff6b3859b/src/PythonicBlackBone/__pycache__/BlackBone.cpython-38.pyc -------------------------------------------------------------------------------- /src/PythonicBlackBone/test/ReadWriteProcMem.py: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.append("..") 3 | from BlackBone import PythonicBlackBone 4 | 5 | 6 | # Intance of BlackBone python Classs 7 | # Constructor Takes 2 Params ProcId and dwDesiredAccess (default = PROCESS_ALL_ACCESS ) 8 | bb=PythonicBlackBone(4284) 9 | 10 | # Address to read From 11 | addr = 0x0063DE0C 12 | 13 | # data is the Variable that will end up holding the Read Value from that address 14 | # Tho, we need to Parse it to a C_TYPE in this case 'Double' you can find more on DataTypes 15 | data = bb.ParseType(bb.DataTypes.DOUBLE.value) 16 | 17 | # Result of ReadProcessMemory (Bool) 18 | res = bb.RPM(addr , data) 19 | 20 | print('+ RPM result: {} - err code: {}'.format(res,bb.CheckLastError())) 21 | print('data: {}\n'.format(data.value)) 22 | 23 | # in Case of WriteProcessMemory we can directly parse our value as a C_Type , simply pass it as the second param 24 | # in this case we want to write 1.5 25 | _wdata = bb.ParseType(bb.DataTypes.FLOAT.value, 1.5) 26 | res = bb.WPM(addr, _wdata) 27 | 28 | print('+WPM result: {} - err code: {}'.format(res,bb.CheckLastError())) 29 | print('data: {}'.format(_wdata.value)) 30 | 31 | # This will CloseHandle , and Invoke the built in __del__ function . 32 | bb.DestroyHandle() -------------------------------------------------------------------------------- /src/Samples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.13) 2 | project (Samples) 3 | 4 | include_directories(..) 5 | 6 | cmake_policy(SET CMP0015 NEW) 7 | 8 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) 9 | link_directories(../3rd_party/DIA/lib/amd64) 10 | elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) 11 | link_directories(../3rd_party/DIA/lib) 12 | endif() 13 | 14 | add_executable(Samples Main.cpp ManualMap.cpp) 15 | 16 | target_link_libraries(Samples BlackBone diaguids.lib) -------------------------------------------------------------------------------- /src/Samples/ManualMap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include <3rd_party/VersionApi.h> 3 | 4 | #include 5 | #include 6 | using namespace blackbone; 7 | 8 | std::set nativeMods, modList; 9 | 10 | /* 11 | Try to map calc.exe into current process 12 | */ 13 | void MapCalcFromFile() 14 | { 15 | Process thisProc; 16 | thisProc.Attach( GetCurrentProcessId() ); 17 | 18 | nativeMods.clear(); 19 | modList.clear(); 20 | 21 | nativeMods.emplace( L"combase.dll" ); 22 | nativeMods.emplace( L"user32.dll" ); 23 | if (WinVer().ver == Win7) 24 | { 25 | nativeMods.emplace( L"gdi32.dll" ); 26 | nativeMods.emplace( L"msvcr120.dll" ); 27 | nativeMods.emplace( L"msvcp120.dll" ); 28 | } 29 | 30 | modList.emplace( L"windows.storage.dll" ); 31 | modList.emplace( L"shell32.dll" ); 32 | modList.emplace( L"shlwapi.dll" ); 33 | 34 | auto callback = []( CallbackType type, void* /*context*/, Process& /*process*/, const ModuleData& modInfo ) 35 | { 36 | if(type == PreCallback) 37 | { 38 | if(nativeMods.count(modInfo.name)) 39 | return LoadData( MT_Native, Ldr_None ); 40 | } 41 | else 42 | { 43 | if (modList.count( modInfo.name )) 44 | return LoadData( MT_Default, Ldr_ModList ); 45 | } 46 | 47 | return LoadData( MT_Default, Ldr_None ); 48 | }; 49 | 50 | std::wcout << L"Manual image mapping test" << std::endl; 51 | std::wcout << L"Trying to map C:\\windows\\system32\\calc.exe into current process" << std::endl; 52 | 53 | auto image = thisProc.mmap().MapImage( L"C:\\windows\\system32\\calc.exe", ManualImports | RebaseProcess, callback ); 54 | if (!image) 55 | { 56 | std::wcout << L"Mapping failed with error 0x" << std::hex << image.status 57 | << L". " << Utils::GetErrorDescription( image.status ) << std::endl << std::endl; 58 | } 59 | else 60 | std::wcout << L"Successfully mapped, unmapping\n"; 61 | 62 | thisProc.mmap().UnmapAllModules(); 63 | } 64 | 65 | /* 66 | Try to map cmd.exe into current process from buffer 67 | */ 68 | void MapCmdFromMem() 69 | { 70 | Process thisProc; 71 | thisProc.Attach( GetCurrentProcessId() ); 72 | 73 | void* buf = nullptr; 74 | auto size = 0; 75 | 76 | std::wcout << L"Manual image mapping from buffer test" << std::endl; 77 | std::wcout << L"Trying to map C:\\windows\\system32\\cmd.exe into current process" << std::endl; 78 | 79 | // Get image context 80 | HANDLE hFile = CreateFileW( L"C:\\windows\\system32\\cmd.exe", FILE_GENERIC_READ, 0x7, 0, OPEN_EXISTING, 0, 0 ); 81 | if (hFile != INVALID_HANDLE_VALUE) 82 | { 83 | DWORD bytes = 0; 84 | size = GetFileSize( hFile, NULL ); 85 | buf = VirtualAlloc( NULL, size, MEM_COMMIT, PAGE_READWRITE ); 86 | ReadFile( hFile, buf, size, &bytes, NULL ); 87 | CloseHandle( hFile ); 88 | } 89 | 90 | auto image = thisProc.mmap().MapImage( size, buf, false, CreateLdrRef | RebaseProcess | NoDelayLoad ); 91 | if (!image) 92 | { 93 | std::wcout << L"Mapping failed with error 0x" << std::hex << image.status 94 | << L". " << Utils::GetErrorDescription( image.status ) << std::endl << std::endl; 95 | } 96 | else 97 | std::wcout << L"Successfully mapped, unmapping\n"; 98 | 99 | VirtualFree( buf, 0, MEM_RELEASE ); 100 | 101 | thisProc.mmap().UnmapAllModules(); 102 | } 103 | -------------------------------------------------------------------------------- /src/Samples/Samples.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | --------------------------------------------------------------------------------