├── .gitignore ├── AsmHelper32.cpp ├── AsmHelper32.h ├── AsmHelper64.cpp ├── AsmHelper64.h ├── AsmHelperBase.cpp ├── AsmHelperBase.h ├── AsmJit ├── AsmJit.sln ├── AsmJit.vcxproj ├── AsmJit.vcxproj.filters ├── AsmJit.vcxproj.user ├── AsmJit │ ├── ApiBegin.h │ ├── ApiEnd.h │ ├── AsmJit.h │ ├── Assembler.h │ ├── AssemblerX86X64.cpp │ ├── AssemblerX86X64.h │ ├── Build.h │ ├── CodeGenerator.cpp │ ├── CodeGenerator.h │ ├── Compiler.cpp │ ├── Compiler.h │ ├── CompilerX86X64.cpp │ ├── CompilerX86X64.h │ ├── Config.h │ ├── CpuInfo.cpp │ ├── CpuInfo.h │ ├── Defs.cpp │ ├── Defs.h │ ├── DefsX86X64.cpp │ ├── DefsX86X64.h │ ├── Logger.cpp │ ├── Logger.h │ ├── MemoryManager.cpp │ ├── MemoryManager.h │ ├── MemoryMarker.cpp │ ├── MemoryMarker.h │ ├── Operand.h │ ├── OperandX86X64.cpp │ ├── OperandX86X64.h │ ├── Platform.cpp │ ├── Platform.h │ ├── Regenerate.py │ ├── Util.cpp │ ├── Util.h │ └── Util_p.h ├── CHANGELOG.txt ├── CMakeLists.txt ├── COPYING.txt ├── Documentation │ ├── Doxygen.conf │ └── Doxygen.css ├── Test │ ├── testcorecpu.cpp │ ├── testcoresize.cpp │ ├── testdummy.cpp │ ├── testfuncalign.cpp │ ├── testfunccall1.cpp │ ├── testfunccall2.cpp │ ├── testfunccall3.cpp │ ├── testfuncmanyargs.cpp │ ├── testfuncmemcpy.cpp │ ├── testfuncrecursive1.cpp │ ├── testfuncret.cpp │ ├── testjit.cpp │ ├── testjump1.cpp │ ├── testmem1.cpp │ ├── testopcode.cpp │ ├── testspecial1.cpp │ ├── testspecial2.cpp │ ├── testspecial3.cpp │ ├── testspecial4.cpp │ ├── testtrampoline.cpp │ ├── testvar2.cpp │ ├── testvar3.cpp │ ├── testvar4.cpp │ └── testvar5.cpp └── Util │ ├── code-fix.py │ ├── configure-borland-dbg.bat │ ├── configure-borland-rel.bat │ ├── configure-mac-xcode.sh │ ├── configure-unix-makefiles-dbg.sh │ ├── configure-unix-makefiles-rel.sh │ ├── configure-windows-mingw-dbg.bat │ ├── configure-windows-mingw-rel.bat │ ├── configure-windows-msvc6.bat │ ├── configure-windows-vs2005-x64.bat │ ├── configure-windows-vs2005-x86.bat │ ├── configure-windows-vs2008-x64.bat │ ├── configure-windows-vs2008-x86.bat │ ├── configure-windows-vs2010-x64.bat │ └── configure-windows-vs2010-x86.bat ├── DarkMMap.cpp ├── DarkMMap.h ├── DarkMMap.sln ├── DarkMMapLib.vcxproj ├── DarkMMapLib.vcxproj.filters ├── DarkMMapLib.vcxproj.user ├── DarkMMapTest ├── DarkMMapTest.vcxproj ├── DarkMMapTest.vcxproj.filters ├── DarkMMapTest.vcxproj.user ├── Main.cpp ├── stdafx.h └── targetver.h ├── Errors.cpp ├── Errors.h ├── FileProjection.cpp ├── FileProjection.h ├── ImageNET.cpp ├── ImageNET.h ├── LDasm.c ├── LDasm.h ├── License.txt ├── MemCore.cpp ├── MemCore.h ├── MemModules.cpp ├── MemModules.h ├── NativeLoaderHelper.cpp ├── NativeLoaderHelper.h ├── NtStructures.h ├── PEManger.cpp ├── PEManger.h ├── Process.cpp ├── Process.h ├── README.md ├── VADPurge ├── NativeStructs.h ├── NativeStructs7.h ├── NativeStructs8.h ├── PrivateRoutines.c ├── PrivateRoutines.h ├── VADPurge.c ├── VADPurge.filters ├── VADPurge.h ├── VADPurge.sln ├── VADPurge.user ├── VADPurge.vcxproj ├── VADPurge.vcxproj.filters ├── VADPurge.vcxproj.user └── VADPurgeDef.h ├── stdafx.h └── targetver.h /.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 | [Bb]in 34 | [Dd]ebug*/ 35 | [Rr]elease*/ 36 | Ankh.NoLoad 37 | 38 | #MonoDevelop 39 | *.pidb 40 | *.userprefs 41 | 42 | #Tooling 43 | _ReSharper*/ 44 | *.resharper 45 | [Tt]est[Rr]esult* 46 | *.sass-cache 47 | 48 | #Project files 49 | [Bb]uild/ 50 | 51 | #Subversion files 52 | .svn 53 | 54 | # Office Temp Files 55 | ~$* 56 | 57 | #NuGet 58 | packages/ 59 | 60 | #ncrunch 61 | *ncrunch* 62 | *crunch*.local.xml 63 | 64 | # visual studio database projects 65 | *.dbmdl 66 | 67 | #Test files 68 | *.testsettings 69 | 70 | #Generated libraries 71 | *.dll 72 | *.bin 73 | *.sys 74 | #and files 75 | GeneratedFiles*/ 76 | 77 | *.ggpk 78 | 79 | /VADPurge/export.h 80 | -------------------------------------------------------------------------------- /AsmHelper32.cpp: -------------------------------------------------------------------------------- 1 | #include "AsmHelper32.h" 2 | 3 | namespace ds_mmap 4 | { 5 | CAsmHelper32::CAsmHelper32( AsmJit::Assembler& _a ) 6 | : CAsmHelperBase(_a) 7 | { 8 | } 9 | 10 | CAsmHelper32::~CAsmHelper32(void) 11 | { 12 | } 13 | 14 | void CAsmHelper32::GenPrologue() 15 | { 16 | a.push (AsmJit::ebp); 17 | a.mov (AsmJit::ebp, AsmJit::esp); 18 | } 19 | 20 | void CAsmHelper32::GenEpilogue( int retSize /*= WordSize */ ) 21 | { 22 | a.mov (AsmJit::esp, AsmJit::ebp); 23 | a.pop (AsmJit::ebp); 24 | a.ret (retSize); 25 | } 26 | 27 | void CAsmHelper32::GenCall( void* pFN, std::initializer_list args, eCalligConvention cc /*= CC_stdcall*/ ) 28 | { 29 | int firsidx = 0; 30 | 31 | // first argument to be pushed on stack 32 | if(cc == CC_thiscall) 33 | firsidx = 1; 34 | else if(cc == CC_fastcall) 35 | firsidx = 2; 36 | 37 | // Push args on stack 38 | for(int i = (int)args.size() - 1; i >= firsidx; i--) 39 | { 40 | const GenVar& arg = *(args.begin() + i); 41 | PushArg(arg); 42 | } 43 | 44 | // Pass arguments in registers 45 | if((cc == CC_thiscall || cc == CC_fastcall) && args.size() > 0) 46 | { 47 | PushArg (*args.begin(), AT_ecx); 48 | 49 | if(args.size() > 1 && cc == CC_fastcall) 50 | PushArg (*(args.begin() + 1), AT_edx); 51 | } 52 | 53 | a.mov (AsmJit::eax, (size_t)pFN); 54 | a.call(AsmJit::eax); 55 | 56 | if(cc == CC_cdecl) 57 | a.add(AsmJit::esp, args.size() * WordSize); 58 | } 59 | 60 | void CAsmHelper32::ExitThreadWithStatus() 61 | { 62 | a.mov (AsmJit::edx, AsmJit::eax); 63 | 64 | // mov eax, fs:[0x18] 65 | a._emitWord(0xA164); 66 | a._emitDWord(0x18); 67 | 68 | a.mov (AsmJit::dword_ptr(AsmJit::eax, 0x14), AsmJit::edx); 69 | a.push (AsmJit::edx); 70 | a.mov (AsmJit::eax, (DWORD)&ExitThread); 71 | a.call (AsmJit::eax); 72 | } 73 | 74 | void CAsmHelper32::SaveRetValAndSignalEvent() 75 | { 76 | a.mov (AsmJit::edx, AsmJit::Mem(AsmJit::ebp, 8)); 77 | a.mov (AsmJit::dword_ptr(AsmJit::edx), AsmJit::eax); 78 | 79 | // SetEvent(hEvent) 80 | a.mov (AsmJit::eax, AsmJit::dword_ptr(AsmJit::edx, 4)); 81 | a.push (AsmJit::eax); 82 | a.mov (AsmJit::eax, (DWORD)&SetEvent); 83 | a.call (AsmJit::eax); 84 | } 85 | 86 | void CAsmHelper32::PushArg( const GenVar& arg, eArgType regidx /*= AT_stack*/ ) 87 | { 88 | if(arg.getType() == GenVar::imm) 89 | { 90 | PushArgp(arg.getImm(), regidx); 91 | } 92 | else if(arg.getType() == GenVar::imm_double) 93 | { 94 | PushArgp(arg.getImm_double(), regidx); 95 | } 96 | else if(arg.getType() == GenVar::imm_float) 97 | { 98 | PushArgp(arg.getImm_float(), regidx); 99 | } 100 | else if(arg.getType() == GenVar::mem_ptr) 101 | { 102 | a.lea(AsmJit::eax, arg.getMem()); 103 | PushArgp(AsmJit::eax, regidx); 104 | } 105 | else if(arg.getType() == GenVar::mem) 106 | { 107 | PushArgp(arg.getMem(), regidx); 108 | } 109 | else 110 | { 111 | PushArgp(arg.getReg(), regidx); 112 | } 113 | } 114 | 115 | } -------------------------------------------------------------------------------- /AsmHelper32.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AsmHelperBase.h" 4 | 5 | #define LODWORD(l) ((DWORD)(((ULONGLONG)(l)) & 0xffffffff)) 6 | #define HIDWORD(l) ((DWORD)((((ULONGLONG)(l)) >> 32) & 0xffffffff)) 7 | 8 | namespace ds_mmap 9 | { 10 | class CAsmHelper32 : public CAsmHelperBase 11 | { 12 | public: 13 | CAsmHelper32(AsmJit::Assembler& _a); 14 | ~CAsmHelper32(void); 15 | 16 | // Generate function prologue code 17 | virtual void GenPrologue(); 18 | 19 | // Generate function epilogue code 20 | virtual void GenEpilogue( int retSize = WordSize ); 21 | 22 | // Function call code (__stdcall convention) 23 | virtual void GenCall(void* pFN, std::initializer_list args, eCalligConvention cc = CC_stdcall); 24 | 25 | // Return from remote thread 26 | virtual void ExitThreadWithStatus(); 27 | 28 | // Return from remote thread 29 | virtual void SaveRetValAndSignalEvent(); 30 | 31 | private: 32 | CAsmHelper32& operator = (const CAsmHelper32& other); 33 | 34 | // Prepare argument to be passed into function 35 | void PushArg(const GenVar& arg, eArgType regidx = AT_stack); 36 | 37 | template 38 | void PushArgp(_Type arg, eArgType index) 39 | { 40 | static const AsmJit::GPReg regs[] = { AsmJit::ecx, AsmJit::edx }; 41 | 42 | // for __fastcall and __thiscall 43 | if( index < AT_stack ) 44 | a.mov(regs[index], arg); 45 | else 46 | a.push(arg); 47 | } 48 | 49 | }; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /AsmHelper64.cpp: -------------------------------------------------------------------------------- 1 | #include "AsmHelper64.h" 2 | 3 | namespace ds_mmap 4 | { 5 | CAsmHelper64::CAsmHelper64(AsmJit::Assembler& _a) 6 | : CAsmHelperBase(_a) 7 | { 8 | } 9 | 10 | CAsmHelper64::~CAsmHelper64(void) 11 | { 12 | } 13 | 14 | void CAsmHelper64::GenPrologue() 15 | { 16 | a.mov (AsmJit::qword_ptr(AsmJit::rsp, 1*WordSize), AsmJit::rcx); 17 | a.mov (AsmJit::qword_ptr(AsmJit::rsp, 2*WordSize), AsmJit::rdx); 18 | a.mov (AsmJit::qword_ptr(AsmJit::rsp, 3*WordSize), AsmJit::r8); 19 | a.mov (AsmJit::qword_ptr(AsmJit::rsp, 4*WordSize), AsmJit::r9); 20 | } 21 | 22 | void CAsmHelper64::GenEpilogue( int retSize /*= 0*/ ) 23 | { 24 | UNREFERENCED_PARAMETER(retSize); 25 | a.ret (); 26 | } 27 | 28 | void CAsmHelper64::GenCall( void* pFN, std::initializer_list args, eCalligConvention /*cc = CC_stdcall*/ ) 29 | { 30 | // 31 | // reserve stack size (0x28 - minimal size for 4 registers and return address) 32 | // after call, stack must be aligned on 16 bytes boundary 33 | // 34 | size_t rsp_dif = (args.size() > 4) ? 0x28 + (args.size() - 4) * WordSize: 0x28; 35 | 36 | // align on (16 bytes - sizeof(return address)) 37 | if((rsp_dif + WordSize) % 16 ) 38 | rsp_dif = ((rsp_dif >> 3) + 1) << 3 ; 39 | 40 | a.sub(AsmJit::rsp, rsp_dif); 41 | 42 | // Set args 43 | for(size_t i = 0; i < args.size(); i++) 44 | { 45 | const GenVar& arg = *(args.begin() + i); 46 | PushArg(arg, i); 47 | } 48 | 49 | a.mov (AsmJit::r13, (size_t)pFN); 50 | a.call (AsmJit::r13); 51 | a.add (AsmJit::rsp, rsp_dif); 52 | } 53 | 54 | void CAsmHelper64::ExitThreadWithStatus() 55 | { 56 | a.mov (AsmJit::rcx, AsmJit::rax); 57 | a.mov (AsmJit::r13, (DWORD64)&ExitThread); 58 | a.call (AsmJit::r13); 59 | } 60 | 61 | void CAsmHelper64::SaveRetValAndSignalEvent() 62 | { 63 | a.mov (AsmJit::rdx, AsmJit::qword_ptr(AsmJit::rsp, WordSize)); 64 | a.mov (AsmJit::qword_ptr(AsmJit::rdx), AsmJit::rax); 65 | 66 | // SetEvent(hEvent) 67 | a.mov (AsmJit::rcx, AsmJit::qword_ptr(AsmJit::rdx, WordSize)); 68 | a.mov (AsmJit::r13, (DWORD64)&SetEvent); 69 | a.call (AsmJit::r13); 70 | } 71 | 72 | void CAsmHelper64::PushArg( GenVar arg, size_t index ) 73 | { 74 | if(arg.getType() == GenVar::imm) 75 | { 76 | PushArgp(arg.getImm(), index); 77 | } 78 | else if(arg.getType() == GenVar::imm_double) 79 | { 80 | PushArgp(arg.getImm_double(), index, true); 81 | } 82 | else if(arg.getType() == GenVar::imm_float) 83 | { 84 | PushArgp(arg.getImm_float(), index, true); 85 | } 86 | else if(arg.getType() == GenVar::mem_ptr) 87 | { 88 | a.lea(AsmJit::rax, arg.getMem()); 89 | PushArgp(AsmJit::rax, index); 90 | } 91 | else if(arg.getType() == GenVar::mem) 92 | { 93 | PushArgp(arg.getMem(), index); 94 | } 95 | else 96 | { 97 | PushArgp(arg.getReg(), index); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /AsmHelper64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "AsmHelperBase.h" 4 | 5 | namespace ds_mmap 6 | { 7 | class CAsmHelper64 : public CAsmHelperBase 8 | { 9 | public: 10 | CAsmHelper64(AsmJit::Assembler& _a); 11 | ~CAsmHelper64(void); 12 | 13 | // Function prologue code 14 | virtual void GenPrologue(); 15 | 16 | // Function epilogue code (with return) 17 | virtual void GenEpilogue( int retSize = 0); 18 | 19 | // Function call code 20 | virtual void GenCall( void* pFN, std::initializer_list args, eCalligConvention cc = CC_stdcall ); 21 | 22 | // Return from remote thread 23 | virtual void ExitThreadWithStatus(); 24 | 25 | // Save rax value and raise completion event 26 | virtual void SaveRetValAndSignalEvent(); 27 | 28 | private: 29 | 30 | // Pass argument appropriately 31 | template 32 | void PushArgp(_Type arg, size_t index, bool fpu = false) 33 | { 34 | static const AsmJit::GPReg regs[] = { AsmJit::rcx, AsmJit::rdx, AsmJit::r8, AsmJit::r9 }; 35 | static const AsmJit::XMMReg xregs[] = { AsmJit::xmm0, AsmJit::xmm1, AsmJit::xmm2, AsmJit::xmm3 }; 36 | 37 | if( index < 4 ) 38 | { 39 | if(fpu) 40 | { 41 | a.mov(AsmJit::rax, arg); 42 | a.movq(xregs[index], AsmJit::rax); 43 | } 44 | else 45 | a.mov(regs[index], arg); 46 | } 47 | else 48 | { 49 | a.mov(AsmJit::r15, arg); 50 | a.mov(AsmJit::qword_ptr(AsmJit::rsp, index * WordSize), AsmJit::r15); 51 | } 52 | } 53 | 54 | // Prepare argument to be passed into function 55 | void PushArg(GenVar arg, size_t index); 56 | }; 57 | } 58 | -------------------------------------------------------------------------------- /AsmHelperBase.cpp: -------------------------------------------------------------------------------- 1 | #include "AsmHelperBase.h" 2 | 3 | namespace ds_mmap 4 | { 5 | CAsmHelperBase::CAsmHelperBase(AsmJit::Assembler& _a) 6 | : a(_a) 7 | { 8 | } 9 | 10 | CAsmHelperBase::~CAsmHelperBase(void) 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /AsmHelperBase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stdafx.h" 4 | 5 | #pragma warning( disable : 4100 4244 4245 4127 ) 6 | 7 | #include "AsmJit/AsmJit/Assembler.h" 8 | #include "AsmJit/AsmJit/MemoryManager.h" 9 | 10 | #pragma warning( default : 4100 4244 4245 4127 ) 11 | 12 | namespace ds_mmap 13 | { 14 | #define WordSize sizeof(size_t) 15 | 16 | // 17 | // General purpose asm variable 18 | // 19 | struct GenVar 20 | { 21 | enum eType 22 | { 23 | reg, 24 | imm, 25 | imm_double, 26 | imm_float, 27 | mem, 28 | mem_ptr 29 | }; 30 | 31 | eType type; // Variable type 32 | 33 | AsmJit::GPReg reg_val; // General purpose register 34 | AsmJit::Mem mem_val; // Memory pointer 35 | 36 | union 37 | { 38 | size_t imm_val; // Immediate value 39 | double imm_double_val; // Immediate floating point value, double 40 | float imm_float_val; // Immediate floating point value, float 41 | } ; 42 | 43 | GenVar(size_t _imm) 44 | : type(imm) 45 | , imm_val(_imm) 46 | { 47 | } 48 | 49 | explicit GenVar(double _imm_fpu) 50 | : type(imm_double) 51 | , imm_double_val(_imm_fpu) 52 | { 53 | } 54 | 55 | explicit GenVar(float _imm_fpu) 56 | : type(imm_float) 57 | , imm_float_val(_imm_fpu) 58 | { 59 | } 60 | 61 | GenVar(const AsmJit::GPReg& _reg) 62 | : type(reg) 63 | , reg_val(_reg) 64 | , imm_double_val(-1.0) 65 | { 66 | } 67 | 68 | GenVar(const AsmJit::Mem& _mem) 69 | : type(mem) 70 | , mem_val(_mem) 71 | , imm_double_val(-1.0) 72 | { 73 | } 74 | 75 | explicit GenVar(AsmJit::Mem* _mem) 76 | : type(mem_ptr) 77 | , mem_val(*_mem) 78 | , imm_double_val(-1.0) 79 | { 80 | } 81 | 82 | inline eType getType() const { return type; } 83 | inline size_t getImm() const { return imm_val; } 84 | inline size_t getImm_float() const { return *(uint32_t*)&imm_float_val; } 85 | inline size_t getImm_double() const { return *(size_t*)&imm_double_val; } 86 | 87 | inline const AsmJit::GPReg& getReg() const { return reg_val; } 88 | inline const AsmJit::Mem& getMem() const { return mem_val; } 89 | }; 90 | 91 | // 92 | // Function calling convention 93 | // 94 | enum eCalligConvention 95 | { 96 | CC_cdecl, 97 | CC_stdcall, 98 | CC_thiscall, 99 | CC_fastcall 100 | }; 101 | 102 | // Argument pass type 103 | enum eArgType 104 | { 105 | AT_ecx, 106 | AT_edx, 107 | AT_stack, 108 | }; 109 | 110 | // 111 | // Some helper functions for assembly code generation 112 | // 113 | class CAsmHelperBase 114 | { 115 | public: 116 | CAsmHelperBase(AsmJit::Assembler& _a); 117 | ~CAsmHelperBase(void); 118 | 119 | // Function prologue code 120 | virtual void GenPrologue() = 0; 121 | 122 | // Function epilogue code 123 | virtual void GenEpilogue( int retSize = WordSize ) = 0; 124 | 125 | // Function call code (__stdcall convention) 126 | virtual void GenCall(void* pFN, std::initializer_list args, eCalligConvention cc = CC_stdcall) = 0; 127 | 128 | // Return from remote thread 129 | virtual void ExitThreadWithStatus() = 0; 130 | 131 | // Return from remote thread 132 | virtual void SaveRetValAndSignalEvent() = 0; 133 | 134 | protected: 135 | AsmJit::Assembler& a; 136 | CAsmHelperBase& operator=(const CAsmHelperBase& other); 137 | }; 138 | 139 | #ifdef _M_AMD64 140 | #define AsmJitHelper CAsmHelper64 141 | #else 142 | #define AsmJitHelper CAsmHelper32 143 | #endif 144 | } -------------------------------------------------------------------------------- /AsmJit/AsmJit.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AsmJit", "AsmJit.vcxproj", "{64B9183C-038A-4B2B-BEAD-0A98F0A9A8F2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {64B9183C-038A-4B2B-BEAD-0A98F0A9A8F2}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {64B9183C-038A-4B2B-BEAD-0A98F0A9A8F2}.Debug|Win32.Build.0 = Debug|Win32 14 | {64B9183C-038A-4B2B-BEAD-0A98F0A9A8F2}.Debug|Win32.Deploy.0 = Debug|Win32 15 | {64B9183C-038A-4B2B-BEAD-0A98F0A9A8F2}.Release|Win32.ActiveCfg = Release|Win32 16 | {64B9183C-038A-4B2B-BEAD-0A98F0A9A8F2}.Release|Win32.Build.0 = Release|Win32 17 | {64B9183C-038A-4B2B-BEAD-0A98F0A9A8F2}.Release|Win32.Deploy.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /AsmJit/AsmJit.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /AsmJit/AsmJit.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/ApiBegin.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // MSVC 8 | #if defined(_MSC_VER) 9 | 10 | // Disable some warnings we know about 11 | #pragma warning(push) 12 | #pragma warning(disable: 4127) // conditional expression is constant 13 | #pragma warning(disable: 4251) // struct needs to have dll-interface to be used 14 | // by clients of struct ... 15 | #pragma warning(disable: 4275) // non dll-interface struct ... used as base for 16 | // dll-interface struct 17 | #pragma warning(disable: 4355) // this used in base member initializer list 18 | #pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' 19 | 20 | // Rename symbols. 21 | #define vsnprintf _vsnprintf 22 | #define snprintf _snprintf 23 | 24 | #endif // _MSC_VER 25 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/ApiEnd.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | #if defined(_MSC_VER) 8 | 9 | // Pop disabled warnings by ApiBegin.h 10 | #pragma warning(pop) 11 | 12 | // Rename symbols back. 13 | #undef vsnprintf 14 | #undef snprintf 15 | 16 | #endif // _MSC_VER 17 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/Assembler.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_ASSEMBLER_H 9 | #define _ASMJIT_ASSEMBLER_H 10 | 11 | // [Dependencies] 12 | #include "Build.h" 13 | 14 | namespace AsmJit { 15 | 16 | // ============================================================================ 17 | // [Forward Declarations] 18 | // ============================================================================ 19 | 20 | struct Logger; 21 | struct MemoryManager; 22 | struct EInstruction; 23 | 24 | } // AsmJit namespace 25 | 26 | // ============================================================================ 27 | // [Platform Specific] 28 | // ============================================================================ 29 | 30 | // [X86 / X64] 31 | #if defined(ASMJIT_X86) || defined(ASMJIT_X64) 32 | #include "AssemblerX86X64.h" 33 | #endif // ASMJIT_X86 || ASMJIT_X64 34 | 35 | // [Guard] 36 | #endif // _ASMJIT_ASSEMBLER_H 37 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/CodeGenerator.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Dependencies] 8 | #include "Assembler.h" 9 | #include "CodeGenerator.h" 10 | #include "Defs.h" 11 | #include "MemoryManager.h" 12 | #include "MemoryMarker.h" 13 | 14 | namespace AsmJit { 15 | 16 | // ============================================================================ 17 | // [AsmJit::CodeGenerator - Construction / Destruction] 18 | // ============================================================================ 19 | 20 | CodeGenerator::CodeGenerator() 21 | { 22 | } 23 | 24 | CodeGenerator::~CodeGenerator() 25 | { 26 | } 27 | 28 | // ============================================================================ 29 | // [AsmJit::CodeGenerator - GetGlobal] 30 | // ============================================================================ 31 | 32 | JitCodeGenerator* CodeGenerator::getGlobal() 33 | { 34 | static JitCodeGenerator global; 35 | return &global; 36 | } 37 | 38 | // ============================================================================ 39 | // [AsmJit::JitCodeGenerator - Construction / Destruction] 40 | // ============================================================================ 41 | 42 | JitCodeGenerator::JitCodeGenerator() : 43 | _memoryManager(NULL), 44 | _memoryMarker(NULL), 45 | _allocType(MEMORY_ALLOC_FREEABLE) 46 | { 47 | } 48 | 49 | JitCodeGenerator::~JitCodeGenerator() 50 | { 51 | } 52 | 53 | // ============================================================================ 54 | // [AsmJit::JitCodeGenerator - Generate] 55 | // ============================================================================ 56 | 57 | uint32_t JitCodeGenerator::generate(void** dest, Assembler* assembler) 58 | { 59 | // Disallow empty code generation. 60 | sysuint_t codeSize = assembler->getCodeSize(); 61 | if (codeSize == 0) 62 | { 63 | *dest = NULL; 64 | return AsmJit::ERROR_NO_FUNCTION; 65 | } 66 | 67 | // Switch to global memory manager if not provided. 68 | MemoryManager* memmgr = getMemoryManager(); 69 | 70 | if (memmgr == NULL) 71 | { 72 | memmgr = MemoryManager::getGlobal(); 73 | } 74 | 75 | void* p = memmgr->alloc(codeSize, getAllocType()); 76 | if (p == NULL) 77 | { 78 | *dest = NULL; 79 | return ERROR_NO_VIRTUAL_MEMORY; 80 | } 81 | 82 | // Relocate the code. 83 | sysuint_t relocatedSize = assembler->relocCode(p); 84 | 85 | // Return unused memory to MemoryManager. 86 | if (relocatedSize < codeSize) 87 | { 88 | memmgr->shrink(p, relocatedSize); 89 | } 90 | 91 | // Mark memory if MemoryMarker provided. 92 | if (_memoryMarker) 93 | { 94 | _memoryMarker->mark(p, relocatedSize); 95 | } 96 | 97 | // Return the code. 98 | *dest = p; 99 | return ERROR_NONE; 100 | } 101 | 102 | } // AsmJit namespace 103 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/CodeGenerator.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_CODEGENERATOR_H 9 | #define _ASMJIT_CODEGENERATOR_H 10 | 11 | // [Dependencies] 12 | #include "Build.h" 13 | 14 | namespace AsmJit { 15 | 16 | // ============================================================================ 17 | // [Forward Declarations] 18 | // ============================================================================ 19 | 20 | struct Assembler; 21 | struct JitCodeGenerator; 22 | struct MemoryManager; 23 | struct MemoryMarker; 24 | 25 | // ============================================================================ 26 | // [AsmJit::CodeGenerator] 27 | // ============================================================================ 28 | 29 | //! @brief Code generator is core class for changing behavior of code generated 30 | //! by @c Assembler or @c Compiler. 31 | struct ASMJIT_API CodeGenerator 32 | { 33 | // -------------------------------------------------------------------------- 34 | // [Construction / Destruction] 35 | // -------------------------------------------------------------------------- 36 | 37 | //! @brief Create a @c CodeGenerator instance. 38 | CodeGenerator(); 39 | //! @brief Destroy the @c CodeGenerator instance. 40 | virtual ~CodeGenerator(); 41 | 42 | // -------------------------------------------------------------------------- 43 | // [Interface] 44 | // -------------------------------------------------------------------------- 45 | 46 | //! @brief Allocate memory for code generated in @a assembler and reloc it 47 | //! to target location. 48 | //! 49 | //! This method is universal allowing any pre-process / post-process work 50 | //! with code generated by @c Assembler or @c Compiler. Because @c Compiler 51 | //! always uses @c Assembler it's allowed to access only the @c Assembler 52 | //! instance. 53 | //! 54 | //! This method is always last step when using code generation. You can use 55 | //! it to allocate memory for JIT code, saving code to remote process or a 56 | //! shared library. 57 | //! 58 | //! @retrurn Error value, see @c ERROR_CODE. 59 | virtual uint32_t generate(void** dest, Assembler* assembler) = 0; 60 | 61 | // -------------------------------------------------------------------------- 62 | // [Statics] 63 | // -------------------------------------------------------------------------- 64 | 65 | static JitCodeGenerator* getGlobal(); 66 | 67 | private: 68 | ASMJIT_DISABLE_COPY(CodeGenerator) 69 | }; 70 | 71 | // ============================================================================ 72 | // [AsmJit::JitCodeGenerator] 73 | // ============================================================================ 74 | 75 | struct JitCodeGenerator : public CodeGenerator 76 | { 77 | // -------------------------------------------------------------------------- 78 | // [Construction / Destruction] 79 | // -------------------------------------------------------------------------- 80 | 81 | //! @brief Create a @c JitCodeGenerator instance. 82 | JitCodeGenerator(); 83 | //! @brief Destroy the @c JitCodeGenerator instance. 84 | virtual ~JitCodeGenerator(); 85 | 86 | // -------------------------------------------------------------------------- 87 | // [Memory Manager and Alloc Type] 88 | // -------------------------------------------------------------------------- 89 | 90 | // Note: These members can be ignored by all derived classes. They are here 91 | // only to privide default implementation. All other implementations (remote 92 | // code patching or making dynamic loadable libraries/executables) ignore 93 | // members accessed by these accessors. 94 | 95 | //! @brief Get the @c MemoryManager instance. 96 | inline MemoryManager* getMemoryManager() const { return _memoryManager; } 97 | //! @brief Set the @c MemoryManager instance. 98 | inline void setMemoryManager(MemoryManager* memoryManager) { _memoryManager = memoryManager; } 99 | 100 | //! @brief Get the type of allocation. 101 | inline uint32_t getAllocType() const { return _allocType; } 102 | //! @brief Set the type of allocation. 103 | inline void setAllocType(uint32_t allocType) { _allocType = allocType; } 104 | 105 | // -------------------------------------------------------------------------- 106 | // [Memory Marker] 107 | // -------------------------------------------------------------------------- 108 | 109 | //! @brief Get the @c MemoryMarker instance. 110 | inline MemoryMarker* getMemoryMarker() const { return _memoryMarker; } 111 | //! @brief Set the @c MemoryMarker instance. 112 | inline void setMemoryMarker(MemoryMarker* memoryMarker) { _memoryMarker = memoryMarker; } 113 | 114 | // -------------------------------------------------------------------------- 115 | // [Interface] 116 | // -------------------------------------------------------------------------- 117 | 118 | virtual uint32_t generate(void** dest, Assembler* assembler); 119 | 120 | // -------------------------------------------------------------------------- 121 | // [Members] 122 | // -------------------------------------------------------------------------- 123 | 124 | protected: 125 | //! @brief Memory manager. 126 | MemoryManager* _memoryManager; 127 | //! @brief Memory marker. 128 | MemoryMarker* _memoryMarker; 129 | 130 | //! @brief Type of allocation. 131 | uint32_t _allocType; 132 | 133 | private: 134 | ASMJIT_DISABLE_COPY(JitCodeGenerator) 135 | }; 136 | 137 | } // AsmJit namespace 138 | 139 | // [Guard] 140 | #endif // _ASMJIT_CODEGENERATOR_H 141 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/Compiler.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // We are using sprintf() here. 8 | #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) 9 | #define _CRT_SECURE_NO_WARNINGS 10 | #endif // _MSC_VER 11 | 12 | // [Dependencies] 13 | #include "Assembler.h" 14 | #include "Compiler.h" 15 | #include "CpuInfo.h" 16 | #include "Logger.h" 17 | #include "Util.h" 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | // [Api-Begin] 24 | #include "ApiBegin.h" 25 | 26 | namespace AsmJit { 27 | 28 | // ============================================================================ 29 | // [AsmJit::Emittable] 30 | // ============================================================================ 31 | 32 | Emittable::Emittable(Compiler* c, uint32_t type) ASMJIT_NOTHROW : 33 | _compiler(c), 34 | _next(NULL), 35 | _prev(NULL), 36 | _comment(NULL), 37 | _type((uint8_t)type), 38 | _translated(false), 39 | _reserved0(0), 40 | _reserved1(0), 41 | _offset(INVALID_VALUE) 42 | { 43 | } 44 | 45 | Emittable::~Emittable() ASMJIT_NOTHROW 46 | { 47 | } 48 | 49 | void Emittable::prepare(CompilerContext& cc) ASMJIT_NOTHROW 50 | { 51 | _offset = cc._currentOffset; 52 | } 53 | 54 | Emittable* Emittable::translate(CompilerContext& cc) ASMJIT_NOTHROW 55 | { 56 | return translated(); 57 | } 58 | 59 | void Emittable::emit(Assembler& a) ASMJIT_NOTHROW 60 | { 61 | } 62 | 63 | void Emittable::post(Assembler& a) ASMJIT_NOTHROW 64 | { 65 | } 66 | 67 | int Emittable::getMaxSize() const ASMJIT_NOTHROW 68 | { 69 | // Default maximum size is -1 which means that it's not known. 70 | return -1; 71 | } 72 | 73 | bool Emittable::_tryUnuseVar(VarData* v) ASMJIT_NOTHROW 74 | { 75 | return false; 76 | } 77 | 78 | void Emittable::setComment(const char* str) ASMJIT_NOTHROW 79 | { 80 | _comment = _compiler->getZone().zstrdup(str); 81 | } 82 | 83 | void Emittable::setCommentF(const char* fmt, ...) ASMJIT_NOTHROW 84 | { 85 | // I'm really not expecting larger inline comments:) 86 | char buf[256]; 87 | 88 | va_list ap; 89 | va_start(ap, fmt); 90 | vsnprintf(buf, 255, fmt, ap); 91 | va_end(ap); 92 | 93 | // I don't know if vsnprintf can produce non-null terminated string, in case 94 | // it can, we terminate it here. 95 | buf[255] = '\0'; 96 | 97 | setComment(buf); 98 | } 99 | 100 | // ============================================================================ 101 | // [AsmJit::EDummy] 102 | // ============================================================================ 103 | 104 | EDummy::EDummy(Compiler* c) ASMJIT_NOTHROW : 105 | Emittable(c, EMITTABLE_DUMMY) 106 | { 107 | } 108 | 109 | EDummy::~EDummy() ASMJIT_NOTHROW 110 | { 111 | } 112 | 113 | int EDummy::getMaxSize() const ASMJIT_NOTHROW 114 | { 115 | return 0; 116 | } 117 | 118 | // ============================================================================ 119 | // [AsmJit::EFunctionEnd] 120 | // ============================================================================ 121 | 122 | EFunctionEnd::EFunctionEnd(Compiler* c) ASMJIT_NOTHROW : 123 | EDummy(c) 124 | { 125 | _type = EMITTABLE_FUNCTION_END; 126 | } 127 | 128 | EFunctionEnd::~EFunctionEnd() ASMJIT_NOTHROW 129 | { 130 | } 131 | 132 | Emittable* EFunctionEnd::translate(CompilerContext& cc) ASMJIT_NOTHROW 133 | { 134 | _translated = true; 135 | return NULL; 136 | } 137 | 138 | // ============================================================================ 139 | // [AsmJit::EComment] 140 | // ============================================================================ 141 | 142 | EComment::EComment(Compiler* c, const char* str) ASMJIT_NOTHROW : 143 | Emittable(c, EMITTABLE_COMMENT) 144 | { 145 | setComment(str); 146 | } 147 | 148 | EComment::~EComment() ASMJIT_NOTHROW 149 | { 150 | } 151 | 152 | void EComment::emit(Assembler& a) ASMJIT_NOTHROW 153 | { 154 | if (a.getLogger()) 155 | { 156 | a.getLogger()->logString(getComment()); 157 | } 158 | } 159 | 160 | int EComment::getMaxSize() const ASMJIT_NOTHROW 161 | { 162 | return 0; 163 | } 164 | 165 | // ============================================================================ 166 | // [AsmJit::EData] 167 | // ============================================================================ 168 | 169 | EData::EData(Compiler* c, const void* data, sysuint_t length) ASMJIT_NOTHROW : 170 | Emittable(c, EMITTABLE_EMBEDDED_DATA) 171 | { 172 | _length = length; 173 | memcpy(_data, data, length); 174 | } 175 | 176 | EData::~EData() ASMJIT_NOTHROW 177 | { 178 | } 179 | 180 | void EData::emit(Assembler& a) ASMJIT_NOTHROW 181 | { 182 | a.embed(_data, _length); 183 | } 184 | 185 | int EData::getMaxSize() const ASMJIT_NOTHROW 186 | { 187 | return (int)_length;; 188 | } 189 | 190 | // ============================================================================ 191 | // [AsmJit::EAlign] 192 | // ============================================================================ 193 | 194 | EAlign::EAlign(Compiler* c, uint32_t size) ASMJIT_NOTHROW : 195 | Emittable(c, EMITTABLE_ALIGN), _size(size) 196 | { 197 | } 198 | 199 | EAlign::~EAlign() ASMJIT_NOTHROW 200 | { 201 | } 202 | 203 | void EAlign::emit(Assembler& a) ASMJIT_NOTHROW 204 | { 205 | a.align(_size); 206 | } 207 | 208 | int EAlign::getMaxSize() const ASMJIT_NOTHROW 209 | { 210 | return (_size > 0) ? (int)_size - 1 : 0; 211 | } 212 | 213 | // ============================================================================ 214 | // [AsmJit::ETarget] 215 | // ============================================================================ 216 | 217 | ETarget::ETarget(Compiler* c, const Label& label) ASMJIT_NOTHROW : 218 | Emittable(c, EMITTABLE_TARGET), 219 | _label(label), 220 | _from(NULL), 221 | _state(NULL), 222 | _jumpsCount(0) 223 | { 224 | } 225 | 226 | ETarget::~ETarget() ASMJIT_NOTHROW 227 | { 228 | } 229 | 230 | void ETarget::prepare(CompilerContext& cc) ASMJIT_NOTHROW 231 | { 232 | _offset = cc._currentOffset++; 233 | } 234 | 235 | Emittable* ETarget::translate(CompilerContext& cc) ASMJIT_NOTHROW 236 | { 237 | // If this ETarget was already translated, it's needed to change the current 238 | // state and return NULL to tell CompilerContext to process next untranslated 239 | // emittable. 240 | if (_translated) 241 | { 242 | cc._restoreState(_state); 243 | return NULL; 244 | } 245 | 246 | if (cc._unreachable) 247 | { 248 | cc._unreachable = 0; 249 | 250 | // Assign state to the compiler context. 251 | ASMJIT_ASSERT(_state != NULL); 252 | cc._assignState(_state); 253 | } 254 | else 255 | { 256 | _state = cc._saveState(); 257 | } 258 | 259 | return translated(); 260 | } 261 | 262 | void ETarget::emit(Assembler& a) ASMJIT_NOTHROW 263 | { 264 | a.bind(_label); 265 | } 266 | 267 | int ETarget::getMaxSize() const ASMJIT_NOTHROW 268 | { 269 | return 0; 270 | } 271 | 272 | } // AsmJit namespace 273 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/Config.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is designed to be modifyable. Platform specific changes should 8 | // be applied to this file so it's guaranteed that never versions of AsmJit 9 | // library will never overwrite generated config files. 10 | // 11 | // So modify this file by your build system or by hand. 12 | 13 | // [Guard] 14 | #ifndef _ASMJIT_CONFIG_H 15 | #define _ASMJIT_CONFIG_H 16 | 17 | // ============================================================================ 18 | // [AsmJit - OS] 19 | // ============================================================================ 20 | 21 | // Provides definitions about your operating system. It's detected by default, 22 | // so override it if you have problems with automatic detection. 23 | // 24 | // #define ASMJIT_WINDOWS 1 25 | // #define ASMJIT_POSIX 2 26 | 27 | // ============================================================================ 28 | // [AsmJit - Architecture] 29 | // ============================================================================ 30 | 31 | // Provides definitions about your cpu architecture. It's detected by default, 32 | // so override it if you have problems with automatic detection. 33 | 34 | // #define ASMJIT_X86 35 | // #define ASMJIT_X64 36 | 37 | // ============================================================================ 38 | // [AsmJit - API] 39 | // ============================================================================ 40 | 41 | // If you are embedding AsmJit library into your project (statically), undef 42 | // ASMJIT_API macro. ASMJIT_HIDDEN macro can contain visibility (used by GCC) 43 | // to hide some AsmJit symbols that shouldn't be never exported. 44 | // 45 | // If you have problems with throw() in compilation time, undef ASMJIT_NOTHROW 46 | // to disable this feature. ASMJIT_NOTHROW marks functions that never throws 47 | // an exception. 48 | 49 | // #define ASMJIT_HIDDEN 50 | #define ASMJIT_API 51 | // #define ASMJIT_NOTHROW 52 | 53 | 54 | // ============================================================================ 55 | // [AsmJit - Memory Management] 56 | // ============================================================================ 57 | 58 | // #define ASMJIT_MALLOC ::malloc 59 | // #define ASMJIT_REALLOC ::realloc 60 | // #define ASMJIT_FREE ::free 61 | 62 | // ============================================================================ 63 | // [AsmJit - Debug] 64 | // ============================================================================ 65 | 66 | // Turn debug on/off (to bypass autodetection) 67 | // #define ASMJIT_DEBUG 68 | // #define ASMJIT_NO_DEBUG 69 | 70 | // Setup custom assertion code. 71 | // #define ASMJIT_ASSERT(exp) do { if (!(exp)) ::AsmJit::assertionFailure(__FILE__, __LINE__, #exp); } while(0) 72 | 73 | // [Guard] 74 | #endif // _ASMJIT_CONFIG_H 75 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/Defs.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Dependencies] 8 | #include "Defs.h" 9 | 10 | // [Api-Begin] 11 | #include "ApiBegin.h" 12 | 13 | namespace AsmJit { 14 | 15 | const char* getErrorString(uint32_t error) ASMJIT_NOTHROW 16 | { 17 | static const char* errorMessage[] = { 18 | "No error", 19 | 20 | "No heap memory", 21 | "No virtual memory", 22 | 23 | "Unknown instruction", 24 | "Illegal instruction", 25 | "Illegal addressing", 26 | "Illegal short jump", 27 | 28 | "No function defined", 29 | "Incomplete function", 30 | 31 | "Not enough registers", 32 | "Registers overlap", 33 | 34 | "Incompatible argument", 35 | "Incompatible return value", 36 | 37 | "Unknown error" 38 | }; 39 | 40 | // Saturate error code to be able to use errorMessage[]. 41 | if (error > _ERROR_COUNT) error = _ERROR_COUNT; 42 | 43 | return errorMessage[error]; 44 | } 45 | 46 | } // AsmJit 47 | 48 | // [Api-End] 49 | #include "ApiEnd.h" 50 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/Logger.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // We are using sprintf() here. 8 | #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) 9 | #define _CRT_SECURE_NO_WARNINGS 10 | #endif // _MSC_VER 11 | 12 | // [Dependencies] 13 | #include "Logger.h" 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | // [Api-Begin] 20 | #include "ApiBegin.h" 21 | 22 | namespace AsmJit { 23 | 24 | // ============================================================================ 25 | // [AsmJit::Logger] 26 | // ============================================================================ 27 | 28 | Logger::Logger() ASMJIT_NOTHROW : 29 | _enabled(true), 30 | _used(true), 31 | _logBinary(false) 32 | { 33 | } 34 | 35 | Logger::~Logger() ASMJIT_NOTHROW 36 | { 37 | } 38 | 39 | void Logger::logFormat(const char* fmt, ...) ASMJIT_NOTHROW 40 | { 41 | char buf[1024]; 42 | sysuint_t len; 43 | 44 | va_list ap; 45 | va_start(ap, fmt); 46 | len = vsnprintf(buf, 1023, fmt, ap); 47 | va_end(ap); 48 | 49 | logString(buf, len); 50 | } 51 | 52 | void Logger::setEnabled(bool enabled) ASMJIT_NOTHROW 53 | { 54 | _enabled = enabled; 55 | _used = enabled; 56 | } 57 | 58 | // ============================================================================ 59 | // [AsmJit::FileLogger] 60 | // ============================================================================ 61 | 62 | FileLogger::FileLogger(FILE* stream) ASMJIT_NOTHROW 63 | : _stream(NULL) 64 | { 65 | setStream(stream); 66 | } 67 | 68 | void FileLogger::logString(const char* buf, sysuint_t len) ASMJIT_NOTHROW 69 | { 70 | if (!_used) return; 71 | 72 | if (len == (sysuint_t)-1) len = strlen(buf); 73 | fwrite(buf, 1, len, _stream); 74 | } 75 | 76 | void FileLogger::setEnabled(bool enabled) ASMJIT_NOTHROW 77 | { 78 | _enabled = enabled; 79 | _used = (_enabled == true) & (_stream != NULL); 80 | } 81 | 82 | //! @brief Set file stream. 83 | void FileLogger::setStream(FILE* stream) ASMJIT_NOTHROW 84 | { 85 | _stream = stream; 86 | _used = (_enabled == true) & (_stream != NULL); 87 | } 88 | 89 | } // AsmJit namespace 90 | 91 | // [Api-End] 92 | #include "ApiEnd.h" 93 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/Logger.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_LOGGER_H 9 | #define _ASMJIT_LOGGER_H 10 | 11 | // [Dependencies] 12 | #include "Defs.h" 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | // [Api-Begin] 19 | #include "ApiBegin.h" 20 | 21 | namespace AsmJit { 22 | 23 | //! @addtogroup AsmJit_Logging 24 | //! @{ 25 | 26 | //! @brief Abstract logging class. 27 | //! 28 | //! This class can be inherited and reimplemented to fit into your logging 29 | //! subsystem. When reimplementing use @c AsmJit::Logger::log() method to 30 | //! log into your stream. 31 | //! 32 | //! This class also contain @c _enabled member that can be used to enable 33 | //! or disable logging. 34 | struct ASMJIT_API Logger 35 | { 36 | // -------------------------------------------------------------------------- 37 | // [Construction / Destruction] 38 | // -------------------------------------------------------------------------- 39 | 40 | //! @brief Create logger. 41 | Logger() ASMJIT_NOTHROW; 42 | //! @brief Destroy logger. 43 | virtual ~Logger() ASMJIT_NOTHROW; 44 | 45 | // -------------------------------------------------------------------------- 46 | // [Logging] 47 | // -------------------------------------------------------------------------- 48 | 49 | //! @brief Abstract method to log output. 50 | //! 51 | //! Default implementation that is in @c AsmJit::Logger is to do nothing. 52 | //! It's virtual to fit to your logging system. 53 | virtual void logString(const char* buf, sysuint_t len = (sysuint_t)-1) ASMJIT_NOTHROW = 0; 54 | 55 | //! @brief Log formatter message (like sprintf) sending output to @c logString() method. 56 | virtual void logFormat(const char* fmt, ...) ASMJIT_NOTHROW; 57 | 58 | // -------------------------------------------------------------------------- 59 | // [Enabled] 60 | // -------------------------------------------------------------------------- 61 | 62 | //! @brief Return @c true if logging is enabled. 63 | inline bool isEnabled() const ASMJIT_NOTHROW { return _enabled; } 64 | 65 | //! @brief Set logging to enabled or disabled. 66 | virtual void setEnabled(bool enabled) ASMJIT_NOTHROW; 67 | 68 | // -------------------------------------------------------------------------- 69 | // [Used] 70 | // -------------------------------------------------------------------------- 71 | 72 | //! @brief Get whether the logger should be used. 73 | inline bool isUsed() const ASMJIT_NOTHROW { return _used; } 74 | 75 | // -------------------------------------------------------------------------- 76 | // [LogBinary] 77 | // -------------------------------------------------------------------------- 78 | 79 | //! @brief Get whether logging binary output. 80 | inline bool getLogBinary() const { return _logBinary; } 81 | //! @brief Get whether to log binary output. 82 | inline void setLogBinary(bool val) { _logBinary = val; } 83 | 84 | // -------------------------------------------------------------------------- 85 | // [Members] 86 | // -------------------------------------------------------------------------- 87 | 88 | protected: 89 | 90 | //! @brief Whether logger is enabled or disabled. 91 | //! 92 | //! Default @c true. 93 | bool _enabled; 94 | 95 | //! @brief Whether logger is enabled and can be used. 96 | //! 97 | //! This value can be set by inherited classes to inform @c Logger that 98 | //! assigned stream (or something that can log output) is invalid. If 99 | //! @c _used is false it means that there is no logging output and AsmJit 100 | //! shouldn't use this logger (because all messages will be lost). 101 | //! 102 | //! This is designed only to optimize cases that logger exists, but its 103 | //! configured not to output messages. The API inside Logging and AsmJit 104 | //! should only check this value when needed. The API outside AsmJit should 105 | //! check only whether logging is @c _enabled. 106 | //! 107 | //! Default @c true. 108 | bool _used; 109 | 110 | //! @brief Whether to log instruction in binary form. 111 | bool _logBinary; 112 | 113 | private: 114 | ASMJIT_DISABLE_COPY(Logger) 115 | }; 116 | 117 | //! @brief Logger that can log to standard C @c FILE* stream. 118 | struct ASMJIT_API FileLogger : public Logger 119 | { 120 | // -------------------------------------------------------------------------- 121 | // [Construction / Destruction] 122 | // -------------------------------------------------------------------------- 123 | 124 | //! @brief Create new @c FileLogger. 125 | //! @param stream FILE stream where logging will be sent (can be @c NULL 126 | //! to disable logging). 127 | FileLogger(FILE* stream = NULL) ASMJIT_NOTHROW; 128 | 129 | // -------------------------------------------------------------------------- 130 | // [Logging] 131 | // -------------------------------------------------------------------------- 132 | 133 | virtual void logString(const char* buf, sysuint_t len = (sysuint_t)-1) ASMJIT_NOTHROW; 134 | 135 | // -------------------------------------------------------------------------- 136 | // [Enabled] 137 | // -------------------------------------------------------------------------- 138 | 139 | virtual void setEnabled(bool enabled) ASMJIT_NOTHROW; 140 | 141 | // -------------------------------------------------------------------------- 142 | // [Stream] 143 | // -------------------------------------------------------------------------- 144 | 145 | //! @brief Get @c FILE* stream. 146 | //! 147 | //! @note Return value can be @c NULL. 148 | inline FILE* getStream() const ASMJIT_NOTHROW { return _stream; } 149 | 150 | //! @brief Set @c FILE* stream. 151 | //! 152 | //! @param stream @c FILE stream where to log output (can be @c NULL to 153 | //! disable logging). 154 | void setStream(FILE* stream) ASMJIT_NOTHROW; 155 | 156 | // -------------------------------------------------------------------------- 157 | // [Members] 158 | // -------------------------------------------------------------------------- 159 | 160 | protected: 161 | //! @brief C file stream. 162 | FILE* _stream; 163 | 164 | ASMJIT_DISABLE_COPY(FileLogger) 165 | }; 166 | 167 | //! @} 168 | 169 | } // AsmJit namespace 170 | 171 | // [Api-End] 172 | #include "ApiEnd.h" 173 | 174 | // [Guard] 175 | #endif // _ASMJIT_LOGGER_H 176 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/MemoryManager.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_MEMORYMANAGER_H 9 | #define _ASMJIT_MEMORYMANAGER_H 10 | 11 | // [Dependencies] 12 | #include "Build.h" 13 | #include "Defs.h" 14 | 15 | // [Api-Begin] 16 | #include "ApiBegin.h" 17 | 18 | // [Debug] 19 | // #define ASMJIT_MEMORY_MANAGER_DUMP 20 | 21 | namespace AsmJit { 22 | 23 | //! @addtogroup AsmJit_MemoryManagement 24 | //! @{ 25 | 26 | // ============================================================================ 27 | // [AsmJit::MemoryManager] 28 | // ============================================================================ 29 | 30 | //! @brief Virtual memory manager interface. 31 | //! 32 | //! This class is pure virtual. You can get default virtual memory manager using 33 | //! @c getGlobal() method. If you want to create more memory managers with same 34 | //! functionality as global memory manager use @c VirtualMemoryManager class. 35 | struct ASMJIT_API MemoryManager 36 | { 37 | // -------------------------------------------------------------------------- 38 | // [Construction / Destruction] 39 | // -------------------------------------------------------------------------- 40 | 41 | //! @brief Create memory manager instance. 42 | MemoryManager() ASMJIT_NOTHROW; 43 | //! @brief Destroy memory manager instance, this means also to free all memory 44 | //! blocks. 45 | virtual ~MemoryManager() ASMJIT_NOTHROW; 46 | 47 | // -------------------------------------------------------------------------- 48 | // [Interface] 49 | // -------------------------------------------------------------------------- 50 | 51 | //! @brief Allocate a @a size bytes of virtual memory. 52 | //! 53 | //! Note that if you are implementing your own virtual memory manager then you 54 | //! can quitly ignore type of allocation. This is mainly for AsmJit to memory 55 | //! manager that allocated memory will be never freed. 56 | virtual void* alloc(sysuint_t size, uint32_t type = MEMORY_ALLOC_FREEABLE) ASMJIT_NOTHROW = 0; 57 | //! @brief Free previously allocated memory at a given @a address. 58 | virtual bool free(void* address) ASMJIT_NOTHROW = 0; 59 | //! @brief Free some tail memory. 60 | virtual bool shrink(void* address, sysuint_t used) ASMJIT_NOTHROW = 0; 61 | //! @brief Free all allocated memory. 62 | virtual void freeAll() ASMJIT_NOTHROW = 0; 63 | 64 | //! @brief Get how many bytes are currently used. 65 | virtual sysuint_t getUsedBytes() ASMJIT_NOTHROW = 0; 66 | //! @brief Get how many bytes are currently allocated. 67 | virtual sysuint_t getAllocatedBytes() ASMJIT_NOTHROW = 0; 68 | 69 | //! @brief Get global memory manager instance. 70 | //! 71 | //! Global instance is instance of @c VirtualMemoryManager class. Global memory 72 | //! manager is used by default by @ref Assembler::make() and @ref Compiler::make() 73 | //! methods. 74 | static MemoryManager* getGlobal() ASMJIT_NOTHROW; 75 | }; 76 | 77 | //! @brief Reference implementation of memory manager that uses 78 | //! @ref AsmJit::VirtualMemory class to allocate chunks of virtual memory 79 | //! and bit arrays to manage it. 80 | struct ASMJIT_API VirtualMemoryManager : public MemoryManager 81 | { 82 | // -------------------------------------------------------------------------- 83 | // [Construction / Destruction] 84 | // -------------------------------------------------------------------------- 85 | 86 | //! @brief Create a @c VirtualMemoryManager instance. 87 | VirtualMemoryManager() ASMJIT_NOTHROW; 88 | 89 | #if defined(ASMJIT_WINDOWS) 90 | //! @brief Create a @c VirtualMemoryManager instance for process @a hProcess. 91 | //! 92 | //! This is specialized version of constructor available only for windows and 93 | //! usable to alloc/free memory of different process. 94 | VirtualMemoryManager(HANDLE hProcess) ASMJIT_NOTHROW; 95 | #endif // ASMJIT_WINDOWS 96 | 97 | //! @brief Destroy the @c VirtualMemoryManager instance, this means also to 98 | //! free all blocks. 99 | virtual ~VirtualMemoryManager() ASMJIT_NOTHROW; 100 | 101 | // -------------------------------------------------------------------------- 102 | // [Interface] 103 | // -------------------------------------------------------------------------- 104 | 105 | virtual void* alloc(sysuint_t size, uint32_t type = MEMORY_ALLOC_FREEABLE) ASMJIT_NOTHROW; 106 | virtual bool free(void* address) ASMJIT_NOTHROW; 107 | virtual bool shrink(void* address, sysuint_t used) ASMJIT_NOTHROW; 108 | virtual void freeAll() ASMJIT_NOTHROW; 109 | 110 | virtual sysuint_t getUsedBytes() ASMJIT_NOTHROW; 111 | virtual sysuint_t getAllocatedBytes() ASMJIT_NOTHROW; 112 | 113 | // -------------------------------------------------------------------------- 114 | // [Virtual Memory Manager Specific] 115 | // -------------------------------------------------------------------------- 116 | 117 | //! @brief Get whether to keep allocated memory after memory manager is 118 | //! destroyed. 119 | //! 120 | //! @sa @c setKeepVirtualMemory(). 121 | bool getKeepVirtualMemory() const ASMJIT_NOTHROW; 122 | 123 | //! @brief Set whether to keep allocated memory after memory manager is 124 | //! destroyed. 125 | //! 126 | //! This method is usable when patching code of remote process. You need to 127 | //! allocate process memory, store generated assembler into it and patch the 128 | //! method you want to redirect (into your code). This method affects only 129 | //! VirtualMemoryManager destructor. After destruction all internal 130 | //! structures are freed, only the process virtual memory remains. 131 | //! 132 | //! @note Memory allocated with MEMORY_ALLOC_PERMANENT is always kept. 133 | //! 134 | //! @sa @c getKeepVirtualMemory(). 135 | void setKeepVirtualMemory(bool keepVirtualMemory) ASMJIT_NOTHROW; 136 | 137 | // -------------------------------------------------------------------------- 138 | // [Debug] 139 | // -------------------------------------------------------------------------- 140 | 141 | #if defined(ASMJIT_MEMORY_MANAGER_DUMP) 142 | //! @brief Dump memory manager tree into file. 143 | //! 144 | //! Generated output is using DOT language (from graphviz package). 145 | void dump(const char* fileName); 146 | #endif // ASMJIT_MEMORY_MANAGER_DUMP 147 | 148 | // -------------------------------------------------------------------------- 149 | // [Members] 150 | // -------------------------------------------------------------------------- 151 | 152 | protected: 153 | //! @brief Pointer to private data hidden from the public API. 154 | void* _d; 155 | }; 156 | 157 | //! @} 158 | 159 | } // AsmJit namespace 160 | 161 | // [Api-End] 162 | #include "ApiEnd.h" 163 | 164 | // [Guard] 165 | #endif // _ASMJIT_MEMORYMANAGER_H 166 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/MemoryMarker.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Dependencies] 8 | #include "Build.h" 9 | #include "MemoryMarker.h" 10 | 11 | // [Api-Begin] 12 | #include "ApiBegin.h" 13 | 14 | namespace AsmJit { 15 | 16 | // ============================================================================ 17 | // [AsmJit::MemoryMarker] 18 | // ============================================================================ 19 | 20 | MemoryMarker::MemoryMarker() ASMJIT_NOTHROW {} 21 | MemoryMarker::~MemoryMarker() ASMJIT_NOTHROW {} 22 | 23 | } // AsmJit namespace 24 | 25 | // [Api-End] 26 | #include "ApiEnd.h" 27 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/MemoryMarker.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_MEMORYMARKER_H 9 | #define _ASMJIT_MEMORYMARKER_H 10 | 11 | // [Dependencies] 12 | #include "Build.h" 13 | #include "Defs.h" 14 | 15 | // [Api-Begin] 16 | #include "ApiBegin.h" 17 | 18 | namespace AsmJit { 19 | 20 | //! @addtogroup AsmJit_MemoryManagement 21 | //! @{ 22 | 23 | // ============================================================================ 24 | // [AsmJit::MemoryMarker] 25 | // ============================================================================ 26 | 27 | //! @brief Virtual memory marker interface. 28 | struct ASMJIT_API MemoryMarker 29 | { 30 | // -------------------------------------------------------------------------- 31 | // [Construction / Destruction] 32 | // -------------------------------------------------------------------------- 33 | 34 | MemoryMarker() ASMJIT_NOTHROW; 35 | virtual ~MemoryMarker() ASMJIT_NOTHROW; 36 | 37 | // -------------------------------------------------------------------------- 38 | // [Interface] 39 | // -------------------------------------------------------------------------- 40 | 41 | virtual void mark(const void* ptr, sysuint_t size) ASMJIT_NOTHROW = 0; 42 | 43 | private: 44 | ASMJIT_DISABLE_COPY(MemoryMarker) 45 | }; 46 | 47 | //! @} 48 | 49 | } // AsmJit namespace 50 | 51 | // [Api-End] 52 | #include "ApiEnd.h" 53 | 54 | // [Guard] 55 | #endif // _ASMJIT_MEMORYMARKER_H 56 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/Operand.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_OPERAND_H 9 | #define _ASMJIT_OPERAND_H 10 | 11 | // [Dependencies] 12 | #include "Build.h" 13 | 14 | namespace AsmJit { 15 | 16 | //! @addtogroup AsmJit_Core 17 | //! @{ 18 | 19 | // There is currently no platform independent code. 20 | 21 | //! @} 22 | 23 | } // AsmJit namespace 24 | 25 | // ============================================================================ 26 | // [Platform Specific] 27 | // ============================================================================ 28 | 29 | #if defined(ASMJIT_X86) || defined(ASMJIT_X64) 30 | #include "OperandX86X64.h" 31 | #endif // ASMJIT_X86 || ASMJIT_X64 32 | 33 | // [Guard] 34 | #endif // _ASMJIT_OPERAND_H 35 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/Platform.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Dependencies] 8 | #include 9 | 10 | #include "Platform.h" 11 | 12 | // [Api-Begin] 13 | #include "ApiBegin.h" 14 | 15 | // helpers 16 | namespace AsmJit { 17 | 18 | // ============================================================================ 19 | // [AsmJit::Assert] 20 | // ============================================================================ 21 | 22 | void assertionFailure(const char* file, int line, const char* exp) 23 | { 24 | fprintf(stderr, 25 | "*** ASSERTION FAILURE at %s (line %d)\n" 26 | "*** %s\n", file, line, exp); 27 | 28 | exit(1); 29 | } 30 | 31 | // ============================================================================ 32 | // [AsmJit::Helpers] 33 | // ============================================================================ 34 | 35 | static bool isAligned(sysuint_t base, sysuint_t alignment) 36 | { 37 | return base % alignment == 0; 38 | } 39 | 40 | static sysuint_t roundUp(sysuint_t base, sysuint_t pageSize) 41 | { 42 | sysuint_t over = base % pageSize; 43 | return base + (over > 0 ? pageSize - over : 0); 44 | } 45 | 46 | // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr., 47 | // figure 3-3, page 48, where the function is called clp2. 48 | static sysuint_t roundUpToPowerOf2(sysuint_t base) 49 | { 50 | base -= 1; 51 | 52 | base = base | (base >> 1); 53 | base = base | (base >> 2); 54 | base = base | (base >> 4); 55 | base = base | (base >> 8); 56 | base = base | (base >> 16); 57 | 58 | // I'm trying to make this portable and MSVC strikes me the warning C4293: 59 | // "Shift count negative or too big, undefined behavior" 60 | // Fixing... 61 | #if _MSC_VER 62 | # pragma warning(disable: 4293) 63 | #endif // _MSC_VER 64 | 65 | if (sizeof(sysuint_t) >= 8) 66 | base = base | (base >> 32); 67 | 68 | return base + 1; 69 | } 70 | 71 | } // AsmJit namespace 72 | 73 | // ============================================================================ 74 | // [AsmJit::VirtualMemory::Windows] 75 | // ============================================================================ 76 | 77 | #if defined(ASMJIT_WINDOWS) 78 | 79 | #include 80 | 81 | namespace AsmJit { 82 | 83 | struct ASMJIT_HIDDEN VirtualMemoryLocal 84 | { 85 | VirtualMemoryLocal() ASMJIT_NOTHROW 86 | { 87 | SYSTEM_INFO info; 88 | GetSystemInfo(&info); 89 | 90 | alignment = info.dwAllocationGranularity; 91 | pageSize = roundUpToPowerOf2(info.dwPageSize); 92 | } 93 | 94 | sysuint_t alignment; 95 | sysuint_t pageSize; 96 | }; 97 | 98 | static VirtualMemoryLocal& vm() ASMJIT_NOTHROW 99 | { 100 | static VirtualMemoryLocal vm; 101 | return vm; 102 | }; 103 | 104 | void* VirtualMemory::alloc(sysuint_t length, sysuint_t* allocated, bool canExecute) 105 | ASMJIT_NOTHROW 106 | { 107 | return allocProcessMemory(GetCurrentProcess(), length, allocated, canExecute); 108 | } 109 | 110 | void VirtualMemory::free(void* addr, sysuint_t length) 111 | ASMJIT_NOTHROW 112 | { 113 | return freeProcessMemory(GetCurrentProcess(), addr, length); 114 | } 115 | 116 | void* VirtualMemory::allocProcessMemory(HANDLE hProcess, sysuint_t length, sysuint_t* allocated, bool canExecute) ASMJIT_NOTHROW 117 | { 118 | // VirtualAlloc rounds allocated size to page size automatically. 119 | sysuint_t msize = roundUp(length, vm().pageSize); 120 | 121 | // Windows XP SP2 / Vista allow Data Excution Prevention (DEP). 122 | WORD protect = canExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; 123 | LPVOID mbase = VirtualAllocEx(hProcess, NULL, msize, MEM_COMMIT | MEM_RESERVE, protect); 124 | if (mbase == NULL) return NULL; 125 | 126 | ASMJIT_ASSERT(isAligned(reinterpret_cast(mbase), vm().alignment)); 127 | 128 | if (allocated) *allocated = msize; 129 | return mbase; 130 | } 131 | 132 | void VirtualMemory::freeProcessMemory(HANDLE hProcess, void* addr, sysuint_t /* length */) ASMJIT_NOTHROW 133 | { 134 | VirtualFreeEx(hProcess, addr, 0, MEM_RELEASE); 135 | } 136 | 137 | sysuint_t VirtualMemory::getAlignment() 138 | ASMJIT_NOTHROW 139 | { 140 | return vm().alignment; 141 | } 142 | 143 | sysuint_t VirtualMemory::getPageSize() 144 | ASMJIT_NOTHROW 145 | { 146 | return vm().pageSize; 147 | } 148 | 149 | } // AsmJit 150 | 151 | #endif // ASMJIT_WINDOWS 152 | 153 | // ============================================================================ 154 | // [AsmJit::VirtualMemory::Posix] 155 | // ============================================================================ 156 | 157 | #if defined(ASMJIT_POSIX) 158 | 159 | #include 160 | #include 161 | #include 162 | 163 | // MacOS uses MAP_ANON instead of MAP_ANONYMOUS 164 | #ifndef MAP_ANONYMOUS 165 | # define MAP_ANONYMOUS MAP_ANON 166 | #endif 167 | 168 | namespace AsmJit { 169 | 170 | struct ASMJIT_HIDDEN VirtualMemoryLocal 171 | { 172 | VirtualMemoryLocal() ASMJIT_NOTHROW 173 | { 174 | alignment = pageSize = getpagesize(); 175 | } 176 | 177 | sysuint_t alignment; 178 | sysuint_t pageSize; 179 | }; 180 | 181 | static VirtualMemoryLocal& vm() 182 | ASMJIT_NOTHROW 183 | { 184 | static VirtualMemoryLocal vm; 185 | return vm; 186 | } 187 | 188 | void* VirtualMemory::alloc(sysuint_t length, sysuint_t* allocated, bool canExecute) 189 | ASMJIT_NOTHROW 190 | { 191 | sysuint_t msize = roundUp(length, vm().pageSize); 192 | int protection = PROT_READ | PROT_WRITE | (canExecute ? PROT_EXEC : 0); 193 | void* mbase = mmap(NULL, msize, protection, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 194 | if (mbase == MAP_FAILED) return NULL; 195 | if (allocated) *allocated = msize; 196 | return mbase; 197 | } 198 | 199 | void VirtualMemory::free(void* addr, sysuint_t length) 200 | ASMJIT_NOTHROW 201 | { 202 | munmap(addr, length); 203 | } 204 | 205 | sysuint_t VirtualMemory::getAlignment() 206 | ASMJIT_NOTHROW 207 | { 208 | return vm().alignment; 209 | } 210 | 211 | sysuint_t VirtualMemory::getPageSize() 212 | ASMJIT_NOTHROW 213 | { 214 | return vm().pageSize; 215 | } 216 | 217 | } // AsmJit 218 | 219 | #endif // ASMJIT_POSIX 220 | 221 | // [Api-End] 222 | #include "ApiEnd.h" 223 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/Platform.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_PLATFORM_H 9 | #define _ASMJIT_PLATFORM_H 10 | 11 | // [Dependencies] 12 | #include "Build.h" 13 | 14 | #if defined(ASMJIT_WINDOWS) 15 | #include 16 | #endif // ASMJIT_WINDOWS 17 | 18 | #if defined(ASMJIT_POSIX) 19 | #include 20 | #endif // ASMJIT_POSIX 21 | 22 | // [Api-Begin] 23 | #include "ApiBegin.h" 24 | 25 | namespace AsmJit { 26 | 27 | //! @addtogroup AsmJit_Util 28 | //! @{ 29 | 30 | // ============================================================================ 31 | // [AsmJit::Assert] 32 | // ============================================================================ 33 | 34 | //! @brief Called in debug build on assertion failure. 35 | //! @param file Source file name where it happened. 36 | //! @param line Line in the source file. 37 | //! @param exp Expression what failed. 38 | //! 39 | //! If you have problems with assertions simply put a breakpoint into 40 | //! AsmJit::assertionFailure() method (see AsmJit/Platform.cpp file) and see 41 | //! call stack. 42 | ASMJIT_API void assertionFailure(const char* file, int line, const char* exp); 43 | 44 | // ============================================================================ 45 | // [AsmJit::Lock] 46 | // ============================================================================ 47 | 48 | //! @brief Lock - used in thread-safe code for locking. 49 | struct ASMJIT_HIDDEN Lock 50 | { 51 | #if defined(ASMJIT_WINDOWS) 52 | typedef CRITICAL_SECTION Handle; 53 | #endif // ASMJIT_WINDOWS 54 | #if defined(ASMJIT_POSIX) 55 | typedef pthread_mutex_t Handle; 56 | #endif // ASMJIT_POSIX 57 | 58 | //! @brief Create a new @ref Lock instance. 59 | inline Lock() ASMJIT_NOTHROW 60 | { 61 | #if defined(ASMJIT_WINDOWS) 62 | InitializeCriticalSection(&_handle); 63 | // InitializeLockAndSpinCount(&_handle, 2000); 64 | #endif // ASMJIT_WINDOWS 65 | #if defined(ASMJIT_POSIX) 66 | pthread_mutex_init(&_handle, NULL); 67 | #endif // ASMJIT_POSIX 68 | } 69 | 70 | //! @brief Destroy the @ref Lock instance. 71 | inline ~Lock() ASMJIT_NOTHROW 72 | { 73 | #if defined(ASMJIT_WINDOWS) 74 | DeleteCriticalSection(&_handle); 75 | #endif // ASMJIT_WINDOWS 76 | #if defined(ASMJIT_POSIX) 77 | pthread_mutex_destroy(&_handle); 78 | #endif // ASMJIT_POSIX 79 | } 80 | 81 | //! @brief Get handle. 82 | inline Handle& getHandle() ASMJIT_NOTHROW 83 | { 84 | return _handle; 85 | } 86 | 87 | //! @overload 88 | inline const Handle& getHandle() const ASMJIT_NOTHROW 89 | { 90 | return _handle; 91 | } 92 | 93 | //! @brief Lock. 94 | inline void lock() ASMJIT_NOTHROW 95 | { 96 | #if defined(ASMJIT_WINDOWS) 97 | EnterCriticalSection(&_handle); 98 | #endif // ASMJIT_WINDOWS 99 | #if defined(ASMJIT_POSIX) 100 | pthread_mutex_lock(&_handle); 101 | #endif // ASMJIT_POSIX 102 | } 103 | 104 | //! @brief Unlock. 105 | inline void unlock() ASMJIT_NOTHROW 106 | { 107 | #if defined(ASMJIT_WINDOWS) 108 | LeaveCriticalSection(&_handle); 109 | #endif // ASMJIT_WINDOWS 110 | #if defined(ASMJIT_POSIX) 111 | pthread_mutex_unlock(&_handle); 112 | #endif // ASMJIT_POSIX 113 | } 114 | 115 | private: 116 | //! @brief Handle. 117 | Handle _handle; 118 | 119 | // Disable copy. 120 | ASMJIT_DISABLE_COPY(Lock) 121 | }; 122 | 123 | // ============================================================================ 124 | // [AsmJit::AutoLock] 125 | // ============================================================================ 126 | 127 | //! @brief Scope auto locker. 128 | struct ASMJIT_HIDDEN AutoLock 129 | { 130 | //! @brief Locks @a target. 131 | inline AutoLock(Lock& target) ASMJIT_NOTHROW : _target(target) 132 | { 133 | _target.lock(); 134 | } 135 | 136 | //! @brief Unlocks target. 137 | inline ~AutoLock() ASMJIT_NOTHROW 138 | { 139 | _target.unlock(); 140 | } 141 | 142 | private: 143 | //! @brief Pointer to target (lock). 144 | Lock& _target; 145 | 146 | // Disable copy. 147 | ASMJIT_DISABLE_COPY(AutoLock) 148 | }; 149 | 150 | // ============================================================================ 151 | // [AsmJit::VirtualMemory] 152 | // ============================================================================ 153 | 154 | //! @brief Class that helps with allocating memory for executing code 155 | //! generated by JIT compiler. 156 | //! 157 | //! There are defined functions that provides facility to allocate and free 158 | //! memory where can be executed code. If processor and operating system 159 | //! supports execution protection then you can't run code from normally 160 | //! malloc()'ed memory. 161 | //! 162 | //! Functions are internally implemented by operating system dependent way. 163 | //! VirtualAlloc() function is used for Windows operating system and mmap() 164 | //! for posix ones. If you want to study or create your own functions, look 165 | //! at VirtualAlloc() or mmap() documentation (depends on you target OS). 166 | //! 167 | //! Under posix operating systems is also useable mprotect() function, that 168 | //! can enable execution protection to malloc()'ed memory block. 169 | struct ASMJIT_API VirtualMemory 170 | { 171 | //! @brief Allocate virtual memory. 172 | //! 173 | //! Pages are readable/writeable, but they are not guaranteed to be 174 | //! executable unless 'canExecute' is true. Returns the address of 175 | //! allocated memory, or NULL if failed. 176 | static void* alloc(sysuint_t length, sysuint_t* allocated, bool canExecute) ASMJIT_NOTHROW; 177 | 178 | //! @brief Free memory allocated by @c alloc() 179 | static void free(void* addr, sysuint_t length) ASMJIT_NOTHROW; 180 | 181 | #if defined(ASMJIT_WINDOWS) 182 | //! @brief Allocate virtual memory of @a hProcess. 183 | //! 184 | //! @note This function is windows specific and unportable. 185 | static void* allocProcessMemory(HANDLE hProcess, sysuint_t length, sysuint_t* allocated, bool canExecute) ASMJIT_NOTHROW; 186 | 187 | //! @brief Free virtual memory of @a hProcess. 188 | //! 189 | //! @note This function is windows specific and unportable. 190 | static void freeProcessMemory(HANDLE hProcess, void* addr, sysuint_t length) ASMJIT_NOTHROW; 191 | #endif // ASMJIT_WINDOWS 192 | 193 | //! @brief Get the alignment guaranteed by alloc(). 194 | static sysuint_t getAlignment() ASMJIT_NOTHROW; 195 | 196 | //! @brief Get size of single page. 197 | static sysuint_t getPageSize() ASMJIT_NOTHROW; 198 | }; 199 | 200 | //! @} 201 | 202 | } // AsmJit namespace 203 | 204 | // [Api-End] 205 | #include "ApiEnd.h" 206 | 207 | // [Guard] 208 | #endif // _ASMJIT_PLATFORM_H 209 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/Regenerate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # ============================================================================= 4 | # [Regenerate.py - Description] 5 | # 6 | # This Python script will regenerate instruction names in Assembler{$ARCH}.cpp 7 | # files. Idea is that there can be big instruction table and this script tries 8 | # to minimize runtime relocation data of AsmJit library. 9 | # ============================================================================= 10 | 11 | # ============================================================================= 12 | # [Configuration] 13 | # ============================================================================= 14 | 15 | # Files to process. 16 | FILES = [ 17 | "DefsX86X64.cpp" 18 | ] 19 | 20 | # ============================================================================= 21 | # [Imports] 22 | # ============================================================================= 23 | 24 | import os, re, string 25 | 26 | # ============================================================================= 27 | # [Helpers] 28 | # ============================================================================= 29 | 30 | def readFile(fileName): 31 | handle = open(fileName, "rb") 32 | data = handle.read() 33 | handle.close() 34 | return data 35 | 36 | def writeFile(fileName, data): 37 | handle = open(fileName, "wb") 38 | handle.truncate() 39 | handle.write(data) 40 | handle.close() 41 | 42 | # ============================================================================= 43 | # [Main] 44 | # ============================================================================= 45 | 46 | def processFile(fileName): 47 | data = readFile(fileName); 48 | 49 | din = data 50 | r = re.compile(r"instructionDescription\[\][\s]*=[\s]*{(?P[^}])*}") 51 | m = r.search(din) 52 | 53 | if not m: 54 | print "Cannot match instruction data in " + fileName 55 | exit(0) 56 | 57 | din = din[m.start():m.end()] 58 | dout = "" 59 | 60 | dinst = [] 61 | daddr = [] 62 | hinst = {} 63 | 64 | r = re.compile(r'\"(?P[A-Za-z0-9_ ]+)\"') 65 | dpos = 0 66 | for m in r.finditer(din): 67 | inst = m.group("INST") 68 | 69 | if not inst in hinst: 70 | dinst.append(inst) 71 | hinst[inst] = dpos 72 | 73 | daddr.append(dpos) 74 | dpos += len(inst) + 1 75 | 76 | dout += "const char instructionName[] =\n" 77 | for i in xrange(len(dinst)): 78 | dout += " \"" + dinst[i] + "\\0\"\n" 79 | dout += " ;\n" 80 | 81 | dout += "\n" 82 | 83 | for i in xrange(len(dinst)): 84 | dout += "#define INST_" + dinst[i].upper().replace(" ", "_") + "_INDEX" + " " + str(daddr[i]) + "\n" 85 | 86 | mb_string = "// ${INSTRUCTION_DATA_BEGIN}\n" 87 | me_string = "// ${INSTRUCTION_DATA_END}\n" 88 | 89 | mb = data.index(mb_string) 90 | me = data.index(me_string) 91 | 92 | data = data[:mb + len(mb_string)] + dout + data[me:] 93 | 94 | writeFile(fileName, data) 95 | 96 | for fileName in FILES: 97 | processFile(fileName) 98 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/Util.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Dependencies] 8 | #include "Build.h" 9 | #include "Util_p.h" 10 | 11 | // [Api-Begin] 12 | #include "ApiBegin.h" 13 | 14 | namespace AsmJit { 15 | 16 | // ============================================================================ 17 | // [AsmJit::Util] 18 | // ============================================================================ 19 | 20 | static const char letters[] = "0123456789ABCDEF"; 21 | 22 | char* Util::mycpy(char* dst, const char* src, sysuint_t len) ASMJIT_NOTHROW 23 | { 24 | if (src == NULL) return dst; 25 | 26 | if (len == (sysuint_t)-1) 27 | { 28 | while (*src) *dst++ = *src++; 29 | } 30 | else 31 | { 32 | memcpy(dst, src, len); 33 | dst += len; 34 | } 35 | 36 | return dst; 37 | } 38 | 39 | char* Util::myfill(char* dst, const int c, sysuint_t len) ASMJIT_NOTHROW 40 | { 41 | memset(dst, c, len); 42 | return dst + len; 43 | } 44 | 45 | char* Util::myhex(char* dst, const uint8_t* src, sysuint_t len) ASMJIT_NOTHROW 46 | { 47 | for (sysuint_t i = len; i; i--, dst += 2, src += 1) 48 | { 49 | dst[0] = letters[(src[0] >> 4) & 0xF]; 50 | dst[1] = letters[(src[0] ) & 0xF]; 51 | } 52 | 53 | return dst; 54 | } 55 | 56 | // Not too efficient, but this is mainly for debugging:) 57 | char* Util::myutoa(char* dst, sysuint_t i, sysuint_t base) ASMJIT_NOTHROW 58 | { 59 | ASMJIT_ASSERT(base <= 16); 60 | 61 | char buf[128]; 62 | char* p = buf + 128; 63 | 64 | do { 65 | sysint_t b = i % base; 66 | *--p = letters[b]; 67 | i /= base; 68 | } while (i); 69 | 70 | return Util::mycpy(dst, p, (sysuint_t)(buf + 128 - p)); 71 | } 72 | 73 | char* Util::myitoa(char* dst, sysint_t i, sysuint_t base) ASMJIT_NOTHROW 74 | { 75 | if (i < 0) 76 | { 77 | *dst++ = '-'; 78 | i = -i; 79 | } 80 | 81 | return Util::myutoa(dst, (sysuint_t)i, base); 82 | } 83 | 84 | // ============================================================================ 85 | // [AsmJit::Buffer] 86 | // ============================================================================ 87 | 88 | void Buffer::emitData(const void* dataPtr, sysuint_t dataLen) ASMJIT_NOTHROW 89 | { 90 | sysint_t max = getCapacity() - getOffset(); 91 | if ((sysuint_t)max < dataLen) 92 | { 93 | if (!realloc(getOffset() + dataLen)) return; 94 | } 95 | 96 | memcpy(_cur, dataPtr, dataLen); 97 | _cur += dataLen; 98 | } 99 | 100 | bool Buffer::realloc(sysint_t to) ASMJIT_NOTHROW 101 | { 102 | if (getCapacity() < to) 103 | { 104 | sysint_t len = getOffset(); 105 | 106 | uint8_t *newdata; 107 | if (_data) 108 | newdata = (uint8_t*)ASMJIT_REALLOC(_data, to); 109 | else 110 | newdata = (uint8_t*)ASMJIT_MALLOC(to); 111 | if (!newdata) return false; 112 | 113 | _data = newdata; 114 | _cur = newdata + len; 115 | _max = newdata + to; 116 | _max -= (to >= _growThreshold) ? _growThreshold : to; 117 | 118 | _capacity = to; 119 | } 120 | 121 | return true; 122 | } 123 | 124 | bool Buffer::grow() ASMJIT_NOTHROW 125 | { 126 | sysint_t to = _capacity; 127 | 128 | if (to < 512) 129 | to = 1024; 130 | else if (to > 65536) 131 | to += 65536; 132 | else 133 | to <<= 1; 134 | 135 | return realloc(to); 136 | } 137 | 138 | void Buffer::clear() ASMJIT_NOTHROW 139 | { 140 | _cur = _data; 141 | } 142 | 143 | void Buffer::free() ASMJIT_NOTHROW 144 | { 145 | if (!_data) return; 146 | ASMJIT_FREE(_data); 147 | 148 | _data = NULL; 149 | _cur = NULL; 150 | _max = NULL; 151 | _capacity = 0; 152 | } 153 | 154 | uint8_t* Buffer::take() ASMJIT_NOTHROW 155 | { 156 | uint8_t* data = _data; 157 | 158 | _data = NULL; 159 | _cur = NULL; 160 | _max = NULL; 161 | _capacity = 0; 162 | 163 | return data; 164 | } 165 | 166 | // ============================================================================ 167 | // [AsmJit::Zone] 168 | // ============================================================================ 169 | 170 | Zone::Zone(sysuint_t chunkSize) ASMJIT_NOTHROW 171 | { 172 | _chunks = NULL; 173 | _total = 0; 174 | _chunkSize = chunkSize; 175 | } 176 | 177 | Zone::~Zone() ASMJIT_NOTHROW 178 | { 179 | freeAll(); 180 | } 181 | 182 | void* Zone::zalloc(sysuint_t size) ASMJIT_NOTHROW 183 | { 184 | // Align to 4 or 8 bytes. 185 | size = (size + sizeof(sysint_t)-1) & ~(sizeof(sysint_t)-1); 186 | 187 | Chunk* cur = _chunks; 188 | 189 | if (!cur || cur->getRemainingBytes() < size) 190 | { 191 | sysuint_t chSize = _chunkSize; 192 | if (chSize < size) chSize = size; 193 | 194 | cur = (Chunk*)ASMJIT_MALLOC(sizeof(Chunk) - sizeof(void*) + chSize); 195 | if (!cur) return NULL; 196 | 197 | cur->prev = _chunks; 198 | cur->pos = 0; 199 | cur->size = _chunkSize; 200 | _chunks = cur; 201 | } 202 | 203 | uint8_t* p = cur->data + cur->pos; 204 | cur->pos += size; 205 | _total += size; 206 | return (void*)p; 207 | } 208 | 209 | char* Zone::zstrdup(const char* str) ASMJIT_NOTHROW 210 | { 211 | if (str == NULL) return NULL; 212 | 213 | sysuint_t len = strlen(str); 214 | if (len == 0) return NULL; 215 | 216 | // Include NULL terminator. 217 | len++; 218 | 219 | // Limit string length. 220 | if (len > 256) len = 256; 221 | 222 | char* m = reinterpret_cast(zalloc((len + 15) & ~15)); 223 | if (!m) return NULL; 224 | 225 | memcpy(m, str, len); 226 | m[len-1] = '\0'; 227 | return m; 228 | } 229 | 230 | void Zone::clear() ASMJIT_NOTHROW 231 | { 232 | Chunk* cur = _chunks; 233 | if (!cur) return; 234 | 235 | _chunks->pos = 0; 236 | _chunks->prev = NULL; 237 | _total = 0; 238 | 239 | cur = cur->prev; 240 | while (cur) 241 | { 242 | Chunk* prev = cur->prev; 243 | ASMJIT_FREE(cur); 244 | cur = prev; 245 | } 246 | } 247 | 248 | void Zone::freeAll() ASMJIT_NOTHROW 249 | { 250 | Chunk* cur = _chunks; 251 | 252 | _chunks = NULL; 253 | _total = 0; 254 | 255 | while (cur) 256 | { 257 | Chunk* prev = cur->prev; 258 | ASMJIT_FREE(cur); 259 | cur = prev; 260 | } 261 | } 262 | 263 | } // AsmJit namespace 264 | 265 | // [Api-End] 266 | #include "ApiEnd.h" 267 | -------------------------------------------------------------------------------- /AsmJit/AsmJit/Util_p.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // [Guard] 8 | #ifndef _ASMJIT_UTIL_P_H 9 | #define _ASMJIT_UTIL_P_H 10 | 11 | // [Dependencies] 12 | #include "Util.h" 13 | 14 | #include 15 | #include 16 | 17 | namespace AsmJit { 18 | 19 | //! @addtogroup AsmJit_Util 20 | //! @{ 21 | 22 | // ============================================================================ 23 | // [AsmJit::Util] 24 | // ============================================================================ 25 | 26 | namespace Util 27 | { 28 | // -------------------------------------------------------------------------- 29 | // [AsmJit::floatAsInt32, int32AsFloat] 30 | // -------------------------------------------------------------------------- 31 | 32 | //! @internal 33 | //! 34 | //! @brief used to cast from float to 32-bit integer and vica versa. 35 | union I32FPUnion 36 | { 37 | //! @brief 32-bit signed integer value. 38 | int32_t i; 39 | //! @brief 32-bit SP-FP value. 40 | float f; 41 | }; 42 | 43 | //! @internal 44 | //! 45 | //! @brief used to cast from double to 64-bit integer and vica versa. 46 | union I64FPUnion 47 | { 48 | //! @brief 64-bit signed integer value. 49 | int64_t i; 50 | //! @brief 64-bit DP-FP value. 51 | double f; 52 | }; 53 | 54 | //! @brief Binary cast from 32-bit integer to SP-FP value (@c float). 55 | static inline float int32AsFloat(int32_t i) ASMJIT_NOTHROW 56 | { 57 | I32FPUnion u; 58 | u.i = i; 59 | return u.f; 60 | } 61 | 62 | //! @brief Binary cast SP-FP value (@c float) to 32-bit integer. 63 | static inline int32_t floatAsInt32(float f) ASMJIT_NOTHROW 64 | { 65 | I32FPUnion u; 66 | u.f = f; 67 | return u.i; 68 | } 69 | 70 | //! @brief Binary cast from 64-bit integer to DP-FP value (@c double). 71 | static inline double int64AsDouble(int64_t i) ASMJIT_NOTHROW 72 | { 73 | I64FPUnion u; 74 | u.i = i; 75 | return u.f; 76 | } 77 | 78 | //! @brief Binary cast from DP-FP value (@c double) to 64-bit integer. 79 | static inline int64_t doubleAsInt64(double f) ASMJIT_NOTHROW 80 | { 81 | I64FPUnion u; 82 | u.f = f; 83 | return u.i; 84 | } 85 | 86 | // -------------------------------------------------------------------------- 87 | // [Str Utils] 88 | // -------------------------------------------------------------------------- 89 | 90 | ASMJIT_HIDDEN char* mycpy(char* dst, const char* src, sysuint_t len = (sysuint_t)-1) ASMJIT_NOTHROW; 91 | ASMJIT_HIDDEN char* myfill(char* dst, const int c, sysuint_t len) ASMJIT_NOTHROW; 92 | ASMJIT_HIDDEN char* myhex(char* dst, const uint8_t* src, sysuint_t len) ASMJIT_NOTHROW; 93 | ASMJIT_HIDDEN char* myutoa(char* dst, sysuint_t i, sysuint_t base = 10) ASMJIT_NOTHROW; 94 | ASMJIT_HIDDEN char* myitoa(char* dst, sysint_t i, sysuint_t base = 10) ASMJIT_NOTHROW; 95 | 96 | // -------------------------------------------------------------------------- 97 | // [Mem Utils] 98 | // -------------------------------------------------------------------------- 99 | 100 | static inline void memset32(uint32_t* p, uint32_t c, sysuint_t len) ASMJIT_NOTHROW 101 | { 102 | sysuint_t i; 103 | for (i = 0; i < len; i++) p[i] = c; 104 | } 105 | } // Util namespace 106 | 107 | //! @} 108 | 109 | } // AsmJit namespace 110 | 111 | #endif // _ASMJIT_UTIL_P_H 112 | -------------------------------------------------------------------------------- /AsmJit/CHANGELOG.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d366/DarkMMap/c4fd125c8936334348b80804c4bfbd9952981d18/AsmJit/CHANGELOG.txt -------------------------------------------------------------------------------- /AsmJit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Reguire minimum version of CMake 2 | CMake_Minimum_Required(VERSION 2.6) 3 | 4 | # AsmJit project - Need to use both C and C++ 5 | Project(AsmJit C CXX) 6 | 7 | # If ASMJIT_DIR is not specified, assume that we are building it from here 8 | If(NOT ASMJIT_DIR) 9 | Set(ASMJIT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) 10 | EndIf() 11 | 12 | # AsmJit C++ sources 13 | Set(ASMJIT_SOURCES 14 | AsmJit/AssemblerX86X64.cpp 15 | AsmJit/CodeGenerator.cpp 16 | AsmJit/Compiler.cpp 17 | AsmJit/CompilerX86X64.cpp 18 | AsmJit/CpuInfo.cpp 19 | AsmJit/Defs.cpp 20 | AsmJit/DefsX86X64.cpp 21 | AsmJit/Logger.cpp 22 | AsmJit/MemoryManager.cpp 23 | AsmJit/MemoryMarker.cpp 24 | AsmJit/OperandX86X64.cpp 25 | AsmJit/Platform.cpp 26 | AsmJit/Util.cpp 27 | ) 28 | 29 | # AsmJit C++ headers 30 | Set(ASMJIT_HEADERS 31 | AsmJit/ApiBegin.h 32 | AsmJit/ApiEnd.h 33 | AsmJit/AsmJit.h 34 | AsmJit/Assembler.h 35 | AsmJit/AssemblerX86X64.h 36 | AsmJit/Build.h 37 | AsmJit/CodeGenerator.h 38 | AsmJit/Compiler.h 39 | AsmJit/CompilerX86X64.h 40 | AsmJit/Config.h 41 | AsmJit/CpuInfo.h 42 | AsmJit/Defs.h 43 | AsmJit/DefsX86X64.h 44 | AsmJit/Logger.h 45 | AsmJit/MemoryManager.h 46 | AsmJit/MemoryMarker.h 47 | AsmJit/Operand.h 48 | AsmJit/OperandX86X64.h 49 | AsmJit/Platform.h 50 | AsmJit/Util.h 51 | AsmJit/Util_p.h 52 | ) 53 | 54 | # Include AsmJit to be able to use #include 55 | Include_Directories(${ASMJIT_DIR}) 56 | 57 | # pthread library is needed for non-windows OSes. 58 | If(NOT WIN32) 59 | Link_Libraries(pthread) 60 | EndIf() 61 | 62 | # Build-Type. 63 | If(${CMAKE_BUILD_TYPE}) 64 | If(${CMAKE_BUILD_TYPE} MATCHES "Debug") 65 | Add_Definitions(-DASMJIT_DEBUG) 66 | Else() 67 | Add_Definitions(-DASMJIT_NO_DEBUG) 68 | EndIf() 69 | EndIf() 70 | 71 | # Build AsmJit shared library? 72 | If(ASMJIT_BUILD_LIBRARY) 73 | Add_Library(AsmJit SHARED ${ASMJIT_SOURCES} ${ASMJIT_HEADERS}) 74 | Install(TARGETS AsmJit DESTINATION lib${LIB_SUFFIX}) 75 | 76 | # Install header files. 77 | ForEach(i ${ASMJIT_HEADERS}) 78 | Get_Filename_Component(path ${i} PATH) 79 | Install(FILES ${i} DESTINATION "include/${path}") 80 | EndForEach(i) 81 | EndIf() 82 | 83 | # Build AsmJit test executables? 84 | If(ASMJIT_BUILD_TEST) 85 | Set(ASMJIT_TEST_FILES 86 | testcorecpu 87 | testcoresize 88 | testdummy 89 | testfuncalign 90 | testfunccall1 91 | testfunccall2 92 | testfunccall3 93 | testfuncmanyargs 94 | testfuncmemcpy 95 | testfuncrecursive1 96 | testfuncret 97 | testjit 98 | testjump1 99 | testmem1 100 | testopcode 101 | testspecial1 102 | testspecial2 103 | testspecial3 104 | testspecial4 105 | testtrampoline 106 | testvar2 107 | testvar3 108 | testvar4 109 | testvar5 110 | ) 111 | 112 | ForEach(file ${ASMJIT_TEST_FILES}) 113 | Add_Executable(${file} Test/${file}.cpp) 114 | Target_Link_Libraries(${file} AsmJit) 115 | EndForEach(file) 116 | EndIf() 117 | -------------------------------------------------------------------------------- /AsmJit/COPYING.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008-2012, Petr Kobalicek 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | -------------------------------------------------------------------------------- /AsmJit/Test/testcorecpu.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // this file is used to test cpu detection. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | using namespace AsmJit; 16 | 17 | struct BitDescription 18 | { 19 | uint32_t mask; 20 | const char* description; 21 | }; 22 | 23 | static const BitDescription cFeatures[] = 24 | { 25 | { CPU_FEATURE_RDTSC , "RDTSC" }, 26 | { CPU_FEATURE_RDTSCP , "RDTSCP" }, 27 | { CPU_FEATURE_CMOV , "CMOV" }, 28 | { CPU_FEATURE_CMPXCHG8B , "CMPXCHG8B" }, 29 | { CPU_FEATURE_CMPXCHG16B , "CMPXCHG16B" }, 30 | { CPU_FEATURE_CLFLUSH , "CLFLUSH" }, 31 | { CPU_FEATURE_PREFETCH , "PREFETCH" }, 32 | { CPU_FEATURE_LAHF_SAHF , "LAHF/SAHF" }, 33 | { CPU_FEATURE_FXSR , "FXSAVE/FXRSTOR" }, 34 | { CPU_FEATURE_FFXSR , "FXSAVE/FXRSTOR Optimizations" }, 35 | { CPU_FEATURE_MMX , "MMX" }, 36 | { CPU_FEATURE_MMX_EXT , "MMX Extensions" }, 37 | { CPU_FEATURE_3DNOW , "3dNow!" }, 38 | { CPU_FEATURE_3DNOW_EXT , "3dNow! Extensions" }, 39 | { CPU_FEATURE_SSE , "SSE" }, 40 | { CPU_FEATURE_SSE2 , "SSE2" }, 41 | { CPU_FEATURE_SSE3 , "SSE3" }, 42 | { CPU_FEATURE_SSSE3 , "Suplemental SSE3 (SSSE3)" }, 43 | { CPU_FEATURE_SSE4_A , "SSE4A" }, 44 | { CPU_FEATURE_SSE4_1 , "SSE4.1" }, 45 | { CPU_FEATURE_SSE4_2 , "SSE4.2" }, 46 | { CPU_FEATURE_AVX , "AVX" }, 47 | { CPU_FEATURE_MSSE , "Misaligned SSE" }, 48 | { CPU_FEATURE_MONITOR_MWAIT , "MONITOR/MWAIT" }, 49 | { CPU_FEATURE_MOVBE , "MOVBE" }, 50 | { CPU_FEATURE_POPCNT , "POPCNT" }, 51 | { CPU_FEATURE_LZCNT , "LZCNT" }, 52 | { CPU_FEATURE_PCLMULDQ , "PCLMULDQ" }, 53 | { CPU_FEATURE_MULTI_THREADING , "Multi-Threading" }, 54 | { CPU_FEATURE_EXECUTE_DISABLE_BIT , "Execute Disable Bit" }, 55 | { CPU_FEATURE_64_BIT , "64 Bit Processor" }, 56 | { 0, NULL } 57 | }; 58 | 59 | static void printBits(const char* msg, uint32_t mask, const BitDescription* d) 60 | { 61 | for (; d->mask; d++) 62 | { 63 | if (mask & d->mask) printf("%s%s\n", msg, d->description); 64 | } 65 | } 66 | 67 | int main(int argc, char* argv[]) 68 | { 69 | CpuInfo *i = getCpuInfo(); 70 | 71 | printf("CPUID Detection\n"); 72 | printf("===============\n"); 73 | 74 | printf("\nBasic info\n"); 75 | printf(" Vendor string : %s\n", i->vendor); 76 | printf(" Brand string : %s\n", i->brand); 77 | printf(" Family : %u\n", i->family); 78 | printf(" Model : %u\n", i->model); 79 | printf(" Stepping : %u\n", i->stepping); 80 | printf(" Number of Processors : %u\n", i->numberOfProcessors); 81 | printf(" Features : 0x%0.8X\n", i->features); 82 | printf(" Bugs : 0x%0.8X\n", i->bugs); 83 | 84 | printf("\nExtended Info (X86/X64):\n"); 85 | printf(" Processor Type : %u\n", i->x86ExtendedInfo.processorType); 86 | printf(" Brand Index : %u\n", i->x86ExtendedInfo.brandIndex); 87 | printf(" CL Flush Cache Line : %u\n", i->x86ExtendedInfo.flushCacheLineSize); 88 | printf(" Max logical Processors: %u\n", i->x86ExtendedInfo.maxLogicalProcessors); 89 | printf(" APIC Physical ID : %u\n", i->x86ExtendedInfo.apicPhysicalId); 90 | 91 | printf("\nCpu Features:\n"); 92 | printBits(" ", i->features, cFeatures); 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /AsmJit/Test/testcoresize.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // this file is used to test cpu detection. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | using namespace AsmJit; 16 | 17 | int main(int argc, char* argv[]) 18 | { 19 | printf("AsmJit size test\n"); 20 | printf("================\n"); 21 | printf("\n"); 22 | 23 | printf("Variable sizes:\n"); 24 | printf(" uint8_t : %u\n", (uint32_t)sizeof(uint8_t)); 25 | printf(" uint16_t : %u\n", (uint32_t)sizeof(uint16_t)); 26 | printf(" uint32_t : %u\n", (uint32_t)sizeof(uint32_t)); 27 | printf(" uint64_t : %u\n", (uint32_t)sizeof(uint64_t)); 28 | printf(" sysuint_t : %u\n", (uint32_t)sizeof(sysuint_t)); 29 | printf(" void* : %u\n", (uint32_t)sizeof(void*)); 30 | printf("\n"); 31 | 32 | printf("Structure sizes:\n"); 33 | printf(" AsmJit::Operand : %u\n", (uint32_t)sizeof(Operand)); 34 | printf(" AsmJit::Operand::BaseData : %u\n", (uint32_t)sizeof(Operand::BaseData)); 35 | printf(" AsmJit::Operand::ImmData : %u\n", (uint32_t)sizeof(Operand::ImmData)); 36 | printf(" AsmJit::Operand::LblData : %u\n", (uint32_t)sizeof(Operand::LblData)); 37 | printf(" AsmJit::Operand::MemData : %u\n", (uint32_t)sizeof(Operand::MemData)); 38 | printf(" AsmJit::Operand::RegData : %u\n", (uint32_t)sizeof(Operand::RegData)); 39 | printf(" AsmJit::Operand::VarData : %u\n", (uint32_t)sizeof(Operand::VarData)); 40 | printf(" AsmJit::Operand::BinData : %u\n", (uint32_t)sizeof(Operand::BinData)); 41 | printf("\n"); 42 | 43 | printf(" AsmJit::Assembler : %u\n", (uint32_t)sizeof(Assembler)); 44 | printf(" AsmJit::Compiler : %u\n", (uint32_t)sizeof(Compiler)); 45 | printf(" AsmJit::FunctionDefinition: %u\n", (uint32_t)sizeof(FunctionDefinition)); 46 | printf("\n"); 47 | 48 | printf(" AsmJit::Emittable : %u\n", (uint32_t)sizeof(Emittable)); 49 | printf(" AsmJit::EAlign : %u\n", (uint32_t)sizeof(EAlign)); 50 | printf(" AsmJit::ECall : %u\n", (uint32_t)sizeof(ECall)); 51 | printf(" AsmJit::EComment : %u\n", (uint32_t)sizeof(EComment)); 52 | printf(" AsmJit::EData : %u\n", (uint32_t)sizeof(EData)); 53 | printf(" AsmJit::EEpilog : %u\n", (uint32_t)sizeof(EEpilog)); 54 | printf(" AsmJit::EFunction : %u\n", (uint32_t)sizeof(EFunction)); 55 | printf(" AsmJit::EFunctionEnd : %u\n", (uint32_t)sizeof(EFunctionEnd)); 56 | printf(" AsmJit::EInstruction : %u\n", (uint32_t)sizeof(EInstruction)); 57 | printf(" AsmJit::EJmp : %u\n", (uint32_t)sizeof(EJmp)); 58 | printf(" AsmJit::EProlog : %u\n", (uint32_t)sizeof(EProlog)); 59 | printf(" AsmJit::ERet : %u\n", (uint32_t)sizeof(ERet)); 60 | printf("\n"); 61 | 62 | printf(" AsmJit::VarData : %u\n", (uint32_t)sizeof(VarData)); 63 | printf(" AsmJit::VarAllocRecord : %u\n", (uint32_t)sizeof(VarAllocRecord)); 64 | printf(" AsmJit::StateData : %u\n", (uint32_t)sizeof(StateData)); 65 | printf("\n"); 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /AsmJit/Test/testdummy.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used as a dummy test. It's changed during development. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | // This is type of function we will generate 16 | typedef void (*MyFn)(void); 17 | 18 | static void dummyFunc(void) 19 | { 20 | 21 | } 22 | 23 | int main(int argc, char* argv[]) 24 | { 25 | using namespace AsmJit; 26 | 27 | // ========================================================================== 28 | // Log compiler output. 29 | FileLogger logger(stderr); 30 | logger.setLogBinary(true); 31 | 32 | // Create compiler. 33 | Compiler c; 34 | c.setLogger(&logger); 35 | 36 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder0()); 37 | c.getFunction()->setHint(FUNCTION_HINT_NAKED, true); 38 | 39 | ECall* ctx = c.call((void*)dummyFunc); 40 | ctx->setPrototype(CALL_CONV_DEFAULT, FunctionBuilder0()); 41 | 42 | c.endFunction(); 43 | // ========================================================================== 44 | 45 | // ========================================================================== 46 | // Make the function. 47 | MyFn fn = function_cast(c.make()); 48 | 49 | // Call it. 50 | // printf("Result %llu\n", (unsigned long long)fn()); 51 | 52 | // Free the generated function if it's not needed anymore. 53 | MemoryManager::getGlobal()->free((void*)fn); 54 | // ========================================================================== 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /AsmJit/Test/testfuncalign.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // Test function variables alignment (for sse2 code, 16-byte xmm variables). 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | using namespace AsmJit; 16 | 17 | // Generated functions prototypes. 18 | typedef sysint_t (*MyFn0)(); 19 | typedef sysint_t (*MyFn1)(sysint_t); 20 | typedef sysint_t (*MyFn2)(sysint_t, sysint_t); 21 | typedef sysint_t (*MyFn3)(sysint_t, sysint_t, sysint_t); 22 | 23 | static void* compileFunction(int args, int vars, bool naked, bool pushPopSequence) 24 | { 25 | Compiler c; 26 | 27 | // Not enabled by default... 28 | // FileLogger logger(stderr); 29 | // c.setLogger(&logger); 30 | 31 | switch (args) 32 | { 33 | case 0: 34 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder0()); 35 | break; 36 | case 1: 37 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder1()); 38 | break; 39 | case 2: 40 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder2()); 41 | break; 42 | case 3: 43 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder3()); 44 | break; 45 | } 46 | c.getFunction()->setHint(FUNCTION_HINT_NAKED, naked); 47 | c.getFunction()->setHint(FUNCTION_HINT_PUSH_POP_SEQUENCE, pushPopSequence); 48 | 49 | GPVar gvar(c.newGP()); 50 | XMMVar xvar(c.newXMM(VARIABLE_TYPE_XMM)); 51 | 52 | // Alloc, use and spill preserved registers. 53 | if (vars) 54 | { 55 | int var = 0; 56 | uint32_t index = 0; 57 | uint32_t mask = 1; 58 | uint32_t preserved = c.getFunction()->getPrototype().getPreservedGP(); 59 | 60 | do { 61 | if ((preserved & mask) != 0 && (index != REG_INDEX_ESP && index != REG_INDEX_EBP)) 62 | { 63 | GPVar somevar(c.newGP(VARIABLE_TYPE_GPD)); 64 | c.alloc(somevar, index); 65 | c.mov(somevar, imm(0)); 66 | c.spill(somevar); 67 | var++; 68 | } 69 | 70 | index++; 71 | mask <<= 1; 72 | } while (var < vars && index < REG_NUM_GP); 73 | } 74 | 75 | c.alloc(gvar, nax); 76 | c.lea(gvar, xvar.m()); 77 | c.and_(gvar, imm(15)); 78 | c.ret(gvar); 79 | c.endFunction(); 80 | 81 | return c.make(); 82 | } 83 | 84 | static bool testFunction(int args, int vars, bool naked, bool pushPopSequence) 85 | { 86 | void* fn = compileFunction(args, vars, naked, pushPopSequence); 87 | sysint_t result = 0; 88 | 89 | printf("Function (args=%d, vars=%d, naked=%d, pushPop=%d):", args, vars, naked, pushPopSequence); 90 | 91 | switch (args) 92 | { 93 | case 0: 94 | result = AsmJit::function_cast(fn)(); 95 | break; 96 | case 1: 97 | result = AsmJit::function_cast(fn)(1); 98 | break; 99 | case 2: 100 | result = AsmJit::function_cast(fn)(1, 2); 101 | break; 102 | case 3: 103 | result = AsmJit::function_cast(fn)(1, 2, 3); 104 | break; 105 | } 106 | 107 | printf(" result=%d (expected 0)\n", (int)result); 108 | 109 | MemoryManager::getGlobal()->free(fn); 110 | return result == 0; 111 | } 112 | 113 | #define TEST_FN(naked, pushPop) \ 114 | { \ 115 | for (int _args = 0; _args < 4; _args++) \ 116 | { \ 117 | for (int _vars = 0; _vars < 4; _vars++) \ 118 | { \ 119 | testFunction(_args, _vars, naked, pushPop); \ 120 | } \ 121 | } \ 122 | } 123 | 124 | int main(int argc, char* argv[]) 125 | { 126 | TEST_FN(false, false) 127 | TEST_FN(false, true ) 128 | 129 | if (CompilerUtil::isStack16ByteAligned()) 130 | { 131 | // If stack is 16-byte aligned by the operating system. 132 | TEST_FN(true , false) 133 | TEST_FN(true , true ) 134 | } 135 | 136 | return 0; 137 | } 138 | -------------------------------------------------------------------------------- /AsmJit/Test/testfunccall1.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used as a function call test (calling functions inside 8 | // the generated code). 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | // Type of generated function. 17 | typedef int (*MyFn)(int, int, int); 18 | 19 | // Function that is called inside the generated one. 20 | static int calledFn(int a, int b, int c) { return (a + b) * c; } 21 | 22 | int main(int argc, char* argv[]) 23 | { 24 | using namespace AsmJit; 25 | 26 | // ========================================================================== 27 | // Create compiler. 28 | Compiler c; 29 | 30 | // Log compiler output. 31 | FileLogger logger(stderr); 32 | c.setLogger(&logger); 33 | 34 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder3()); 35 | 36 | GPVar v0(c.argGP(0)); 37 | GPVar v1(c.argGP(1)); 38 | GPVar v2(c.argGP(2)); 39 | 40 | // Just do something;) 41 | c.shl(v0, imm(1)); 42 | c.shl(v1, imm(1)); 43 | c.shl(v2, imm(1)); 44 | 45 | // Call function. 46 | GPVar address(c.newGP()); 47 | c.mov(address, imm((sysint_t)(void*)calledFn)); 48 | 49 | ECall* ctx = c.call(address); 50 | ctx->setPrototype(CALL_CONV_DEFAULT, FunctionBuilder3()); 51 | ctx->setArgument(0, v2); 52 | ctx->setArgument(1, v1); 53 | ctx->setArgument(2, v0); 54 | 55 | //ctx->setReturn(v0); 56 | //c.ret(v0); 57 | 58 | c.endFunction(); 59 | // ========================================================================== 60 | 61 | // ========================================================================== 62 | // Make the function. 63 | MyFn fn = function_cast(c.make()); 64 | 65 | uint result = fn(3, 2, 1); 66 | bool success = result == 36; 67 | 68 | printf("Result %u (expected 36)\n", result); 69 | printf("Status: %s\n", success ? "Success" : "Failure"); 70 | 71 | // Free the generated function if it's not needed anymore. 72 | MemoryManager::getGlobal()->free((void*)fn); 73 | // ========================================================================== 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /AsmJit/Test/testfunccall2.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used as a function call test (calling functions inside 8 | // the generated code). 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | // Type of generated function. 17 | typedef void (*MyFn)(void); 18 | 19 | // Function that is called inside the generated one. Because this test is 20 | // mainly about register arguments, we need to use the fastcall calling 21 | // convention under 32-bit mode. 22 | static void ASMJIT_FASTCALL simpleFn(int a) {} 23 | 24 | int main(int argc, char* argv[]) 25 | { 26 | using namespace AsmJit; 27 | 28 | // ========================================================================== 29 | // Create compiler. 30 | Compiler c; 31 | 32 | // Log compiler output. 33 | FileLogger logger(stderr); 34 | c.setLogger(&logger); 35 | 36 | ECall* ctx; 37 | 38 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder0()); 39 | c.getFunction()->setHint(FUNCTION_HINT_NAKED, true); 40 | 41 | // Call a function. 42 | GPVar address(c.newGP()); 43 | GPVar argument(c.newGP(VARIABLE_TYPE_GPD)); 44 | 45 | c.mov(address, imm((sysint_t)(void*)simpleFn)); 46 | 47 | c.mov(argument, imm(1)); 48 | ctx = c.call(address); 49 | ctx->setPrototype(CALL_CONV_COMPAT_FASTCALL, FunctionBuilder1()); 50 | ctx->setArgument(0, argument); 51 | c.unuse(argument); 52 | 53 | c.mov(argument, imm(2)); 54 | ctx = c.call(address); 55 | ctx->setPrototype(CALL_CONV_COMPAT_FASTCALL, FunctionBuilder1()); 56 | ctx->setArgument(0, argument); 57 | 58 | c.endFunction(); 59 | // ========================================================================== 60 | 61 | // ========================================================================== 62 | // Make the function. 63 | MyFn fn = function_cast(c.make()); 64 | 65 | fn(); 66 | 67 | // Free the generated function if it's not needed anymore. 68 | MemoryManager::getGlobal()->free((void*)fn); 69 | // ========================================================================== 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /AsmJit/Test/testfunccall3.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used as a function call test (calling functions inside 8 | // the generated code). 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | // Type of generated function. 17 | typedef int (*MyFn)(void); 18 | 19 | // Function that is called inside the generated one. Because this test is 20 | // mainly about register arguments, we need to use the fastcall calling 21 | // convention under 32-bit mode. 22 | static int oneFunc(void) { return 1; } 23 | 24 | int main(int argc, char* argv[]) 25 | { 26 | using namespace AsmJit; 27 | 28 | // ========================================================================== 29 | // Create compiler. 30 | Compiler c; 31 | 32 | // Log compiler output. 33 | FileLogger logger(stderr); 34 | c.setLogger(&logger); 35 | 36 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder1()); 37 | c.getFunction()->setHint(FUNCTION_HINT_NAKED, true); 38 | Label L0(c.newLabel()); 39 | Label L1(c.newLabel()); 40 | GPVar x(c.newGP()); 41 | GPVar y(c.newGP()); 42 | c.mov(x, 0); 43 | c.jnz(L0); 44 | c.mov(y, c.argGP(0)); 45 | c.jmp(L1); 46 | c.bind(L0); 47 | ECall *ctx = c.call((void*)oneFunc); 48 | ctx->setPrototype(CALL_CONV_DEFAULT, FunctionBuilder1()); 49 | ctx->setArgument(0, c.argGP(0)); 50 | ctx->setReturn(y); 51 | c.bind(L1); 52 | c.add(x, y); 53 | c.endFunction(); 54 | 55 | // TODO: Remove 56 | #if 0 57 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder0()); 58 | c.getFunction()->setHint(FUNCTION_HINT_NAKED, true); 59 | GPVar x(c.newGP()); 60 | GPVar y(c.newGP()); 61 | ECall *ctx = c.call((void*)oneFunc); 62 | ctx->setPrototype(CALL_CONV_DEFAULT, FunctionBuilder0()); 63 | ctx->setReturn(y); 64 | c.mov(x, 0); 65 | c.add(x, y); 66 | c.ret(x); 67 | c.endFunction(); 68 | #endif 69 | // ========================================================================== 70 | 71 | // ========================================================================== 72 | // Make the function. 73 | MyFn fn = function_cast(c.make()); 74 | 75 | //uint result = fn(); 76 | //bool success = result == 1; 77 | 78 | //printf("Result %u (expected 1)\n", result); 79 | //printf("Status: %s\n", success ? "Success" : "Failure"); 80 | 81 | // Free the generated function if it's not needed anymore. 82 | MemoryManager::getGlobal()->free((void*)fn); 83 | // ========================================================================== 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /AsmJit/Test/testfuncmanyargs.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used to test function with many arguments. Bug originally 8 | // reported by Tilo Nitzsche for X64W and X64U calling conventions. 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | // This is type of function we will generate 17 | typedef void (*MyFn)(void*, void*, void*, void*, void*, void*, void*, void*); 18 | 19 | int main(int argc, char* argv[]) 20 | { 21 | using namespace AsmJit; 22 | 23 | // ========================================================================== 24 | // Create compiler. 25 | Compiler c; 26 | 27 | // Log compiler output. 28 | FileLogger logger(stderr); 29 | c.setLogger(&logger); 30 | 31 | c.newFunction(CALL_CONV_DEFAULT, 32 | FunctionBuilder8()); 33 | 34 | GPVar p1(c.argGP(0)); 35 | GPVar p2(c.argGP(1)); 36 | GPVar p3(c.argGP(2)); 37 | GPVar p4(c.argGP(3)); 38 | GPVar p5(c.argGP(4)); 39 | GPVar p6(c.argGP(5)); 40 | GPVar p7(c.argGP(6)); 41 | GPVar p8(c.argGP(7)); 42 | 43 | c.add(p1, 1); 44 | c.add(p2, 2); 45 | c.add(p3, 3); 46 | c.add(p4, 4); 47 | c.add(p5, 5); 48 | c.add(p6, 6); 49 | c.add(p7, 7); 50 | c.add(p8, 8); 51 | 52 | // Move some data into buffer provided by arguments so we can verify if it 53 | // really works without looking into assembler output. 54 | c.add(byte_ptr(p1), imm(1)); 55 | c.add(byte_ptr(p2), imm(2)); 56 | c.add(byte_ptr(p3), imm(3)); 57 | c.add(byte_ptr(p4), imm(4)); 58 | c.add(byte_ptr(p5), imm(5)); 59 | c.add(byte_ptr(p6), imm(6)); 60 | c.add(byte_ptr(p7), imm(7)); 61 | c.add(byte_ptr(p8), imm(8)); 62 | 63 | c.endFunction(); 64 | // ========================================================================== 65 | 66 | // ========================================================================== 67 | // Make the function. 68 | uint8_t var[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 69 | 70 | MyFn fn = function_cast(c.make()); 71 | fn(var, var, var, var, var, var, var, var); 72 | 73 | printf("Results: %d, %d, %d, %d, %d, %d, %d, %d, %d\n", 74 | var[0], var[1], var[2], var[3], 75 | var[4], var[5], var[6], var[7], 76 | var[8]); 77 | 78 | bool success = 79 | var[0] == 0 && var[1] == 1 && var[2] == 2 && var[3] == 3 && 80 | var[4] == 4 && var[5] == 5 && var[6] == 6 && var[7] == 7 && 81 | var[8] == 8; 82 | printf("Status: %s\n", success ? "Success" : "Failure"); 83 | 84 | // Free the generated function if it's not needed anymore. 85 | MemoryManager::getGlobal()->free((void*)fn); 86 | // ========================================================================== 87 | 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /AsmJit/Test/testfuncmemcpy.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // Create simple DWORD memory copy function for 32/64-bit x86 platform, this 8 | // is enchanced version that's using Compiler class: 9 | // 10 | // void memcpy32(uint32_t* dst, const uint32_t* src, sysuint_t len); 11 | 12 | // AsmJit library 13 | #include 14 | 15 | // C library - printf 16 | #include 17 | 18 | // It isn't needed to include namespace here, but when generating assembly it's 19 | // easier to use directly eax, rax, ... instead of AsmJit::eax, AsmJit::rax, ... 20 | using namespace AsmJit; 21 | 22 | // This is type of function we will generate. 23 | typedef void (*MemCpy32Fn)(uint32_t*, const uint32_t*, sysuint_t); 24 | 25 | int main(int argc, char* argv[]) 26 | { 27 | // ========================================================================== 28 | // Part 1: 29 | 30 | // Create Compiler. 31 | Compiler c; 32 | 33 | FileLogger logger(stderr); 34 | c.setLogger(&logger); 35 | 36 | // Tell compiler the function prototype we want. It allocates variables representing 37 | // function arguments that can be accessed through Compiler or Function instance. 38 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder3()); 39 | 40 | // Try to generate function without prolog/epilog code: 41 | c.getFunction()->setHint(FUNCTION_HINT_NAKED, true); 42 | 43 | // Create labels. 44 | Label L_Loop = c.newLabel(); 45 | Label L_Exit = c.newLabel(); 46 | 47 | // Function arguments. 48 | GPVar dst(c.argGP(0)); 49 | GPVar src(c.argGP(1)); 50 | GPVar cnt(c.argGP(2)); 51 | 52 | // Allocate loop variables registers (if they are not allocated already). 53 | c.alloc(dst); 54 | c.alloc(src); 55 | c.alloc(cnt); 56 | 57 | // Exit if length is zero. 58 | c.test(cnt, cnt); 59 | c.jz(L_Exit); 60 | 61 | // Loop. 62 | c.bind(L_Loop); 63 | 64 | // Copy DWORD (4 bytes). 65 | GPVar tmp(c.newGP(VARIABLE_TYPE_GPD)); 66 | c.mov(tmp, dword_ptr(src)); 67 | c.mov(dword_ptr(dst), tmp); 68 | 69 | // Increment dst/src pointers. 70 | c.add(src, 4); 71 | c.add(dst, 4); 72 | 73 | // Loop until cnt is not zero. 74 | c.dec(cnt); 75 | c.jnz(L_Loop); 76 | 77 | // Exit. 78 | c.bind(L_Exit); 79 | 80 | // Finish. 81 | c.endFunction(); 82 | // ========================================================================== 83 | 84 | // ========================================================================== 85 | // Part 2: 86 | 87 | // Make JIT function. 88 | MemCpy32Fn fn = function_cast(c.make()); 89 | 90 | // Ensure that everything is ok. 91 | if (!fn) 92 | { 93 | printf("Error making jit function (%u).\n", c.getError()); 94 | return 1; 95 | } 96 | 97 | // Create some data. 98 | uint32_t dstBuffer[128]; 99 | uint32_t srcBuffer[128]; 100 | 101 | // Call the JIT function. 102 | fn(dstBuffer, srcBuffer, 128); 103 | 104 | // Free the JIT function if it's not needed anymore. 105 | MemoryManager::getGlobal()->free((void*)fn); 106 | // ========================================================================== 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /AsmJit/Test/testfuncrecursive1.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // Recursive function call test. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | // Type of generated function. 16 | typedef int (*MyFn)(int); 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | using namespace AsmJit; 21 | 22 | // ========================================================================== 23 | // Create compiler. 24 | Compiler c; 25 | 26 | // Log compiler output. 27 | FileLogger logger(stderr); 28 | c.setLogger(&logger); 29 | 30 | ECall* ctx; 31 | Label skip(c.newLabel()); 32 | 33 | EFunction* func = c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder1()); 34 | func->setHint(FUNCTION_HINT_NAKED, true); 35 | 36 | GPVar var(c.argGP(0)); 37 | c.cmp(var, imm(1)); 38 | c.jle(skip); 39 | 40 | GPVar tmp(c.newGP(VARIABLE_TYPE_INT32)); 41 | c.mov(tmp, var); 42 | c.dec(tmp); 43 | 44 | ctx = c.call(func->getEntryLabel()); 45 | ctx->setPrototype(CALL_CONV_DEFAULT, FunctionBuilder1()); 46 | ctx->setArgument(0, tmp); 47 | ctx->setReturn(tmp); 48 | c.mul(c.newGP(VARIABLE_TYPE_INT32), var, tmp); 49 | 50 | c.bind(skip); 51 | c.ret(var); 52 | c.endFunction(); 53 | // ========================================================================== 54 | 55 | // ========================================================================== 56 | // Make the function. 57 | MyFn fn = function_cast(c.make()); 58 | 59 | printf("Factorial 5 == %d\n", fn(5)); 60 | 61 | // Free the generated function if it's not needed anymore. 62 | MemoryManager::getGlobal()->free((void*)fn); 63 | // ========================================================================== 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /AsmJit/Test/testfuncret.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used to test function with many arguments. Bug originally 8 | // reported by Tilo Nitzsche for X64W and X64U calling conventions. 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | // This is type of function we will generate. 16 | typedef int (*MyFn)(int, int, int); 17 | 18 | static int FuncA(int x, int y) { return x + y; } 19 | static int FuncB(int x, int y) { return x * y; } 20 | 21 | int main(int argc, char* argv[]) 22 | { 23 | using namespace AsmJit; 24 | 25 | // ========================================================================== 26 | // Create compiler. 27 | Compiler c; 28 | 29 | // Log compiler output. 30 | FileLogger logger(stderr); 31 | c.setLogger(&logger); 32 | 33 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder3()); 34 | { 35 | GPVar x(c.argGP(0)); 36 | GPVar y(c.argGP(1)); 37 | GPVar op(c.argGP(2)); 38 | 39 | Label opAdd(c.newLabel()); 40 | Label opMul(c.newLabel()); 41 | 42 | c.cmp(op, 0); 43 | c.jz(opAdd); 44 | 45 | c.cmp(op, 1); 46 | c.jz(opMul); 47 | 48 | { 49 | GPVar result(c.newGP()); 50 | c.mov(result, imm(0)); 51 | c.ret(result); 52 | } 53 | 54 | { 55 | c.bind(opAdd); 56 | 57 | GPVar result(c.newGP()); 58 | ECall* ctx = c.call((void*)FuncA); 59 | ctx->setPrototype(CALL_CONV_DEFAULT, FunctionBuilder2()); 60 | ctx->setArgument(0, x); 61 | ctx->setArgument(1, y); 62 | ctx->setReturn(result); 63 | c.ret(result); 64 | } 65 | 66 | { 67 | c.bind(opMul); 68 | 69 | GPVar result(c.newGP()); 70 | ECall* ctx = c.call((void*)FuncB); 71 | ctx->setPrototype(CALL_CONV_DEFAULT, FunctionBuilder2()); 72 | ctx->setArgument(0, x); 73 | ctx->setArgument(1, y); 74 | ctx->setReturn(result); 75 | c.ret(result); 76 | } 77 | } 78 | c.endFunction(); 79 | // ========================================================================== 80 | 81 | // ========================================================================== 82 | // Make the function. 83 | MyFn fn = function_cast(c.make()); 84 | int result = fn(4, 8, 1); 85 | 86 | printf("Result from JIT function: %d (Expected 32) \n", result); 87 | printf("Status: %s\n", result == 32 ? "Success" : "Failure"); 88 | 89 | // Free the generated function if it's not needed anymore. 90 | MemoryManager::getGlobal()->free((void*)fn); 91 | // ========================================================================== 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /AsmJit/Test/testjit.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is only included as an example and simple test if jit 8 | // compiler works. 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | // This is type of function we will generate 17 | typedef int (*MyFn)(); 18 | 19 | int main(int argc, char* argv[]) 20 | { 21 | using namespace AsmJit; 22 | 23 | // ========================================================================== 24 | // Create assembler. 25 | Assembler a; 26 | 27 | // Log assembler output. 28 | FileLogger logger(stderr); 29 | a.setLogger(&logger); 30 | 31 | // Prolog. 32 | a.push(nbp); 33 | a.mov(nbp, nsp); 34 | 35 | // Mov 1024 to EAX/RAX, EAX/RAX is also return value. 36 | a.mov(nax, 1024); 37 | 38 | // Epilog. 39 | a.mov(nsp, nbp); 40 | a.pop(nbp); 41 | a.ret(); 42 | // ========================================================================== 43 | 44 | // NOTE: 45 | // This function can be also completely rewritten to this form: 46 | // a.mov(nax, 1024); 47 | // a.ret(); 48 | // If you are interested in removing prolog and epilog, please 49 | // study calling conventions and check register preservations. 50 | 51 | // ========================================================================== 52 | // Make the function. 53 | MyFn fn = function_cast(a.make()); 54 | 55 | // Call it. 56 | int result = fn(); 57 | printf("Result from jit function: %d\n", result); 58 | printf("Status: %s\n", result == 1024 ? "Success" : "Failure"); 59 | 60 | // Free the generated function if it's not needed anymore. 61 | MemoryManager::getGlobal()->free((void*)fn); 62 | // ========================================================================== 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /AsmJit/Test/testjump1.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used to test crossed jumps. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | using namespace AsmJit; 16 | typedef void (*VoidFn)(); 17 | 18 | int main(int, char**) 19 | { 20 | Compiler c; 21 | 22 | FileLogger logger(stderr); 23 | c.setLogger(&logger); 24 | 25 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder0()); 26 | 27 | Label L_A = c.newLabel(); 28 | Label L_B = c.newLabel(); 29 | Label L_C = c.newLabel(); 30 | 31 | c.jmp(L_B); 32 | 33 | c.bind(L_A); 34 | c.jmp(L_C); 35 | 36 | c.bind(L_B); 37 | c.jmp(L_A); 38 | 39 | c.bind(L_C); 40 | 41 | c.ret(); 42 | c.endFunction(); 43 | 44 | VoidFn fn = function_cast(c.make()); 45 | 46 | // Ensure that everything is ok. 47 | if (!fn) 48 | { 49 | printf("Error making jit function (%u).\n", c.getError()); 50 | return 1; 51 | } 52 | 53 | // Free the JIT function if it's not needed anymore. 54 | MemoryManager::getGlobal()->free((void*)fn); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /AsmJit/Test/testmem1.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used to test AsmJit memory manager. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | static int problems = 0; 16 | 17 | static void gen(void* a, void* b, int i) 18 | { 19 | int pattern = rand() % 256; 20 | *(int *)a = i; 21 | *(int *)b = i; 22 | memset((char*)a + sizeof(int), pattern, i - sizeof(int)); 23 | memset((char*)b + sizeof(int), pattern, i - sizeof(int)); 24 | } 25 | 26 | static void verify(void* a, void* b) 27 | { 28 | int ai = *(int*)a; 29 | int bi = *(int*)b; 30 | if (ai != bi || memcmp(a, b, ai) != 0) 31 | { 32 | printf("Failed to verify %p\n", a); 33 | problems++; 34 | } 35 | } 36 | 37 | static void die() 38 | { 39 | printf("Couldn't allocate virtual memory, this test needs at least 100MB of free virtual memory.\n"); 40 | exit(1); 41 | } 42 | 43 | static void stats(const char* dumpFile) 44 | { 45 | AsmJit::MemoryManager* memmgr = AsmJit::MemoryManager::getGlobal(); 46 | 47 | printf("-- Used: %d\n", (int)memmgr->getUsedBytes()); 48 | printf("-- Allocated: %d\n", (int)memmgr->getAllocatedBytes()); 49 | 50 | #if defined(ASMJIT_MEMORY_MANAGER_DUMP) 51 | reinterpret_cast(memmgr)->dump(dumpFile); 52 | #endif // ASMJIT_MEMORY_MANAGER_DUMP 53 | } 54 | 55 | static void shuffle(void **a, void **b, sysuint_t count) 56 | { 57 | for (sysuint_t i = 0; i < count; ++i) 58 | { 59 | sysuint_t si = (sysuint_t)rand() % count; 60 | 61 | void *ta = a[i]; 62 | void *tb = b[i]; 63 | 64 | a[i] = a[si]; 65 | b[i] = b[si]; 66 | 67 | a[si] = ta; 68 | b[si] = tb; 69 | } 70 | } 71 | 72 | int main(int argc, char* argv[]) 73 | { 74 | AsmJit::MemoryManager* memmgr = AsmJit::MemoryManager::getGlobal(); 75 | 76 | sysuint_t i; 77 | sysuint_t count = 200000; 78 | 79 | printf("Memory alloc/free test - %d allocations\n\n", (int)count); 80 | 81 | void** a = (void**)malloc(sizeof(void*) * count); 82 | void** b = (void**)malloc(sizeof(void*) * count); 83 | if (!a || !b) die(); 84 | 85 | srand(100); 86 | printf("Allocating virtual memory..."); 87 | 88 | for (i = 0; i < count; i++) 89 | { 90 | int r = (rand() % 1000) + 4; 91 | 92 | a[i] = memmgr->alloc(r); 93 | if (a[i] == NULL) die(); 94 | 95 | memset(a[i], 0, r); 96 | } 97 | 98 | printf("done\n"); 99 | stats("dump0.dot"); 100 | 101 | printf("\n"); 102 | printf("Freeing virtual memory..."); 103 | 104 | for (i = 0; i < count; i++) 105 | { 106 | if (!memmgr->free(a[i])) 107 | { 108 | printf("Failed to free %p\n", b[i]); 109 | problems++; 110 | } 111 | } 112 | 113 | printf("done\n"); 114 | stats("dump1.dot"); 115 | 116 | printf("\n"); 117 | printf("Verified alloc/free test - %d allocations\n\n", (int)count); 118 | 119 | printf("Alloc..."); 120 | for (i = 0; i < count; i++) 121 | { 122 | int r = (rand() % 1000) + 4; 123 | 124 | a[i] = memmgr->alloc(r); 125 | b[i] = malloc(r); 126 | if (a[i] == NULL || b[i] == NULL) die(); 127 | 128 | gen(a[i], b[i], r); 129 | } 130 | printf("done\n"); 131 | stats("dump2.dot"); 132 | 133 | printf("\n"); 134 | printf("Shuffling..."); 135 | shuffle(a, b, count); 136 | printf("done\n"); 137 | 138 | printf("\n"); 139 | printf("Verify and free..."); 140 | for (i = 0; i < count/2; i++) 141 | { 142 | verify(a[i], b[i]); 143 | if (!memmgr->free(a[i])) 144 | { 145 | printf("Failed to free %p\n", b[i]); 146 | problems++; 147 | } 148 | free(b[i]); 149 | } 150 | printf("done\n"); 151 | stats("dump3.dot"); 152 | 153 | printf("\n"); 154 | printf("Alloc..."); 155 | for (i = 0; i < count/2; i++) 156 | { 157 | int r = (rand() % 1000) + 4; 158 | 159 | a[i] = memmgr->alloc(r); 160 | b[i] = malloc(r); 161 | if (a[i] == NULL || b[i] == NULL) die(); 162 | 163 | gen(a[i], b[i], r); 164 | } 165 | printf("done\n"); 166 | stats("dump4.dot"); 167 | 168 | printf("\n"); 169 | printf("Verify and free..."); 170 | for (i = 0; i < count; i++) 171 | { 172 | verify(a[i], b[i]); 173 | if (!memmgr->free(a[i])) 174 | { 175 | printf("Failed to free %p\n", b[i]); 176 | problems++; 177 | } 178 | free(b[i]); 179 | } 180 | printf("done\n"); 181 | stats("dump5.dot"); 182 | 183 | printf("\n"); 184 | if (problems) 185 | printf("Status: Failure: %d problems found\n", problems); 186 | else 187 | printf("Status: Success\n"); 188 | 189 | free(a); 190 | free(b); 191 | 192 | return 0; 193 | } 194 | -------------------------------------------------------------------------------- /AsmJit/Test/testspecial1.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // Test special instruction generation. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | // This is type of function we will generate 16 | typedef void (*MyFn)(int32_t*, int32_t*, int32_t, int32_t); 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | using namespace AsmJit; 21 | 22 | // ========================================================================== 23 | // Create compiler. 24 | Compiler c; 25 | 26 | // Log compiler output. 27 | FileLogger logger(stderr); 28 | c.setLogger(&logger); 29 | 30 | { 31 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder4()); 32 | c.getFunction()->setHint(FUNCTION_HINT_NAKED, true); 33 | 34 | GPVar dst0_hi(c.argGP(0)); 35 | GPVar dst0_lo(c.argGP(1)); 36 | 37 | GPVar v0_hi(c.newGP(VARIABLE_TYPE_GPD)); 38 | GPVar v0_lo(c.argGP(2)); 39 | 40 | GPVar src0(c.argGP(3)); 41 | c.imul(v0_hi, v0_lo, src0); 42 | 43 | c.mov(dword_ptr(dst0_hi), v0_hi); 44 | c.mov(dword_ptr(dst0_lo), v0_lo); 45 | c.endFunction(); 46 | } 47 | // ========================================================================== 48 | 49 | // ========================================================================== 50 | // Make the function. 51 | MyFn fn = function_cast(c.make()); 52 | 53 | { 54 | int32_t out_hi; 55 | int32_t out_lo; 56 | 57 | int32_t v0 = 4; 58 | int32_t v1 = 4; 59 | 60 | int32_t expected_hi = 0; 61 | int32_t expected_lo = v0 * v1; 62 | 63 | fn(&out_hi, &out_lo, v0, v1); 64 | 65 | printf("out_hi=%d (expected %d)\n", out_hi, expected_hi); 66 | printf("out_lo=%d (expected %d)\n", out_lo, expected_lo); 67 | 68 | printf("Status: %s\n", (out_hi == expected_hi && out_lo == expected_lo) 69 | ? "Success" 70 | : "Failure"); 71 | } 72 | 73 | // Free the generated function if it's not needed anymore. 74 | MemoryManager::getGlobal()->free((void*)fn); 75 | // ========================================================================== 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /AsmJit/Test/testspecial2.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // Test special instruction generation. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | // This is type of function we will generate 16 | typedef void (*MyFn)(int32_t*, int32_t, int32_t, int32_t); 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | using namespace AsmJit; 21 | 22 | // ========================================================================== 23 | // Create compiler. 24 | Compiler c; 25 | 26 | // Log compiler output. 27 | FileLogger logger(stderr); 28 | c.setLogger(&logger); 29 | 30 | { 31 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder4()); 32 | 33 | GPVar dst0(c.argGP(0)); 34 | GPVar v0(c.argGP(1)); 35 | 36 | c.shl(v0, c.argGP(2)); 37 | c.ror(v0, c.argGP(3)); 38 | 39 | c.mov(dword_ptr(dst0), v0); 40 | c.endFunction(); 41 | } 42 | // ========================================================================== 43 | 44 | // ========================================================================== 45 | // Make the function. 46 | MyFn fn = function_cast(c.make()); 47 | 48 | { 49 | int32_t out; 50 | int32_t v0 = 0x000000FF; 51 | int32_t expected = 0x0000FF00; 52 | 53 | fn(&out, v0, 16, 8); 54 | 55 | printf("out=%d (expected %d)\n", out, expected); 56 | printf("Status: %s\n", (out == expected) ? "Success" : "Failure"); 57 | } 58 | 59 | // Free the generated function if it's not needed anymore. 60 | MemoryManager::getGlobal()->free((void*)fn); 61 | // ========================================================================== 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /AsmJit/Test/testspecial3.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used as rep-test. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | // This is type of function we will generate 16 | typedef void (*MemCopy)(void* a, void* b, sysuint_t size); 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | using namespace AsmJit; 21 | 22 | // ========================================================================== 23 | // Create compiler. 24 | Compiler c; 25 | 26 | // Log compiler output. 27 | FileLogger logger(stderr); 28 | c.setLogger(&logger); 29 | 30 | { 31 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder3()); 32 | c.getFunction()->setHint(FUNCTION_HINT_NAKED, true); 33 | 34 | GPVar dst(c.argGP(0)); 35 | GPVar src(c.argGP(1)); 36 | GPVar cnt(c.argGP(2)); 37 | 38 | c.rep_movsb(dst, src, cnt); 39 | c.endFunction(); 40 | } 41 | // ========================================================================== 42 | 43 | // ========================================================================== 44 | { 45 | MemCopy copy = function_cast(c.make()); 46 | 47 | char src[20] = "Hello AsmJit"; 48 | char dst[20]; 49 | 50 | copy(dst, src, strlen(src) + 1); 51 | printf("src=%s\n", src); 52 | printf("dst=%s\n", dst); 53 | printf("Status: %s\n", strcmp(src, dst) == 0 ? "Success" : "Failure"); 54 | 55 | MemoryManager::getGlobal()->free((void*)copy); 56 | } 57 | // ========================================================================== 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /AsmJit/Test/testspecial4.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used to test setcc instruction generation. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | // This is type of function we will generate 16 | typedef void (*MyFn)(int, int, char*); 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | using namespace AsmJit; 21 | 22 | // ========================================================================== 23 | // Create compiler. 24 | Compiler c; 25 | 26 | // Log compiler output. 27 | FileLogger logger(stderr); 28 | c.setLogger(&logger); 29 | 30 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder3()); 31 | c.getFunction()->setHint(FUNCTION_HINT_NAKED, true); 32 | 33 | GPVar src0(c.argGP(0)); 34 | GPVar src1(c.argGP(1)); 35 | GPVar dst0(c.argGP(2)); 36 | 37 | c.cmp(src0, src1); 38 | c.setz(byte_ptr(dst0)); 39 | 40 | // Finish. 41 | c.endFunction(); 42 | // ========================================================================== 43 | 44 | // ========================================================================== 45 | // Make the function. 46 | MyFn fn = function_cast(c.make()); 47 | 48 | // Results storage. 49 | char r[4]; 50 | 51 | // Call it 52 | fn(0, 0, &r[0]); // We are expecting 1 (0 == 0). 53 | fn(0, 1, &r[1]); // We are expecting 0 (0 != 1). 54 | fn(1, 0, &r[2]); // We are expecting 0 (1 != 0). 55 | fn(1, 1, &r[3]); // We are expecting 1 (1 == 1). 56 | 57 | printf("Result from JIT function: %d %d %d %d\n", r[0], r[1], r[2], r[3]); 58 | printf("Status: %s\n", (r[0] == 1 && r[1] == 0 && r[2] == 0 && r[3] == 1) ? "Success" : "Failure"); 59 | 60 | // Free the generated function if it's not needed anymore. 61 | MemoryManager::getGlobal()->free((void*)fn); 62 | // ========================================================================== 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /AsmJit/Test/testtrampoline.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used to test trampoline generation (absolute addressing 8 | // in 64-bit mode). 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #if defined(ASMJIT_X86) 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | printf("Trampoline test can be only used in x64 mode.\n"); 21 | printf("Status: %s\n", "Success"); 22 | 23 | return 0; 24 | } 25 | 26 | #else 27 | 28 | // This is type of function we will generate 29 | typedef void (*MyFn)(void); 30 | 31 | static int i = 0; 32 | 33 | // Function that is called from JIT code. 34 | static void calledfn(void) 35 | { 36 | i++; 37 | } 38 | 39 | int main(int argc, char* argv[]) 40 | { 41 | using namespace AsmJit; 42 | 43 | // ========================================================================== 44 | // Create assembler. 45 | Assembler a; 46 | 47 | // Log compiler output. 48 | FileLogger logger(stderr); 49 | a.setLogger(&logger); 50 | 51 | a.call(imm((sysint_t)calledfn)); // First trampoline - call. 52 | a.jmp(imm((sysint_t)calledfn)); // Second trampoline - jump, will return. 53 | MyFn fn0 = function_cast(a.make()); 54 | 55 | a.clear(); // Purge assembler, we will reuse it. 56 | a.jmp(imm((sysint_t)fn0)); 57 | MyFn fn1 = function_cast(a.make()); 58 | 59 | // ========================================================================== 60 | 61 | // ========================================================================== 62 | fn0(); 63 | fn1(); 64 | 65 | printf("Status: %s\n", (i == 4) ? "Success" : "Failure"); 66 | 67 | // If functions are not needed again they should be freed. 68 | MemoryManager::getGlobal()->free((void*)fn0); 69 | MemoryManager::getGlobal()->free((void*)fn1); 70 | // ========================================================================== 71 | 72 | return 0; 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /AsmJit/Test/testvar2.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used to test function with many arguments. Bug originally 8 | // reported by Tilo Nitzsche for X64W and X64U calling conventions. 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | // This is type of function we will generate 17 | typedef sysint_t (*MyFn)(); 18 | 19 | int main(int argc, char* argv[]) 20 | { 21 | using namespace AsmJit; 22 | 23 | // ========================================================================== 24 | // Create compiler. 25 | Compiler c; 26 | 27 | // Log compiler output. 28 | FileLogger logger(stderr); 29 | c.setLogger(&logger); 30 | 31 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder0()); 32 | 33 | GPVar v0(c.newGP()); 34 | GPVar v1(c.newGP()); 35 | GPVar v2(c.newGP()); 36 | GPVar v3(c.newGP()); 37 | GPVar v4(c.newGP()); 38 | 39 | c.xor_(v0, v0); 40 | 41 | c.mov(v1, 1); 42 | c.mov(v2, 2); 43 | c.mov(v3, 3); 44 | c.mov(v4, 4); 45 | 46 | c.add(v0, v1); 47 | c.add(v0, v2); 48 | c.add(v0, v3); 49 | c.add(v0, v4); 50 | 51 | c.ret(v0); 52 | c.endFunction(); 53 | // ========================================================================== 54 | 55 | // ========================================================================== 56 | // Make the function. 57 | MyFn fn = function_cast(c.make()); 58 | int result = (int)fn(); 59 | 60 | printf("Result from JIT function: %d\n", result); 61 | printf("Status: %s\n", result == 10 ? "Success" : "Failure"); 62 | 63 | // Free the generated function if it's not needed anymore. 64 | MemoryManager::getGlobal()->free((void*)fn); 65 | // ========================================================================== 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /AsmJit/Test/testvar3.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // This file is used to test AsmJit register allocator. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | // This is type of function we will generate 16 | typedef void (*MyFn)(int*, int*); 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | using namespace AsmJit; 21 | 22 | // ========================================================================== 23 | // Create compiler. 24 | Compiler c; 25 | 26 | // Log assembler output. 27 | FileLogger logger(stderr); 28 | c.setLogger(&logger); 29 | 30 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder2()); 31 | 32 | // Function arguments. 33 | GPVar a1(c.argGP(0)); 34 | GPVar a2(c.argGP(1)); 35 | 36 | // Create some variables. 37 | GPVar x1(c.newGP(VARIABLE_TYPE_GPD)); 38 | GPVar x2(c.newGP(VARIABLE_TYPE_GPD)); 39 | GPVar x3(c.newGP(VARIABLE_TYPE_GPD)); 40 | GPVar x4(c.newGP(VARIABLE_TYPE_GPD)); 41 | GPVar x5(c.newGP(VARIABLE_TYPE_GPD)); 42 | GPVar x6(c.newGP(VARIABLE_TYPE_GPD)); 43 | GPVar x7(c.newGP(VARIABLE_TYPE_GPD)); 44 | GPVar x8(c.newGP(VARIABLE_TYPE_GPD)); 45 | 46 | GPVar t(c.newGP(VARIABLE_TYPE_GPD)); 47 | 48 | // Setup variables (use mov with reg/imm to se if register allocator works). 49 | c.mov(x1, 1); 50 | c.mov(x2, 2); 51 | c.mov(x3, 3); 52 | c.mov(x4, 4); 53 | c.mov(x5, 5); 54 | c.mov(x6, 6); 55 | c.mov(x7, 7); 56 | c.mov(x8, 8); 57 | 58 | // Make sum (addition) 59 | c.xor_(t, t); 60 | c.add(t, x1); 61 | c.add(t, x2); 62 | c.add(t, x3); 63 | c.add(t, x4); 64 | c.add(t, x5); 65 | c.add(t, x6); 66 | c.add(t, x7); 67 | c.add(t, x8); 68 | 69 | // Store result to a given pointer in first argument. 70 | c.mov(dword_ptr(a1), t); 71 | 72 | // Make sum (subtraction). 73 | c.xor_(t, t); 74 | c.sub(t, x1); 75 | c.sub(t, x2); 76 | c.sub(t, x3); 77 | c.sub(t, x4); 78 | c.sub(t, x5); 79 | c.sub(t, x6); 80 | c.sub(t, x7); 81 | c.sub(t, x8); 82 | 83 | // Store result to a given pointer in second argument. 84 | c.mov(dword_ptr(a2), t); 85 | 86 | // End of function. 87 | c.endFunction(); 88 | // ========================================================================== 89 | 90 | // ========================================================================== 91 | // Make the function. 92 | MyFn fn = function_cast(c.make()); 93 | 94 | // Call it. 95 | int x; 96 | int y; 97 | fn(&x, &y); 98 | 99 | printf("\nResults from JIT function: %d %d\n", x, y); 100 | printf("Status: %s\n", (x == 36 && y == -36) ? "Success" : "Failure"); 101 | 102 | // Free the generated function if it's not needed anymore. 103 | MemoryManager::getGlobal()->free((void*)fn); 104 | // ========================================================================== 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /AsmJit/Test/testvar4.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // Test variable scope detection in loop. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | // This is type of function we will generate 16 | typedef void (*MyFn)(uint32_t*); 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | using namespace AsmJit; 21 | 22 | // ========================================================================== 23 | // Create compiler. 24 | Compiler c; 25 | 26 | // Log compiler output. 27 | FileLogger logger(stderr); 28 | c.setLogger(&logger); 29 | 30 | { 31 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder1()); 32 | 33 | GPVar var[32]; 34 | int i; 35 | 36 | for (i = 0; i < ASMJIT_ARRAY_SIZE(var); i++) 37 | { 38 | var[i] = c.newGP(VARIABLE_TYPE_GPD); 39 | c.xor_(var[i], var[i]); 40 | } 41 | 42 | GPVar v0(c.newGP(VARIABLE_TYPE_GPD)); 43 | Label L(c.newLabel()); 44 | 45 | c.mov(v0, imm(32)); 46 | c.bind(L); 47 | 48 | for (i = 0; i < ASMJIT_ARRAY_SIZE(var); i++) 49 | { 50 | c.add(var[i], imm(i)); 51 | } 52 | 53 | c.dec(v0); 54 | c.jnz(L); 55 | 56 | GPVar a0(c.argGP(0)); 57 | for (i = 0; i < ASMJIT_ARRAY_SIZE(var); i++) 58 | { 59 | c.mov(dword_ptr(a0, i * 4), var[i]); 60 | } 61 | c.endFunction(); 62 | } 63 | // ========================================================================== 64 | 65 | // ========================================================================== 66 | // Make the function. 67 | MyFn fn = function_cast(c.make()); 68 | 69 | { 70 | uint32_t out[32]; 71 | int i; 72 | bool success = true; 73 | 74 | fn(out); 75 | 76 | for (i = 0; i < ASMJIT_ARRAY_SIZE(out); i++) 77 | { 78 | printf("out[%d]=%u (expected %d)\n", i, out[i], i * 32); 79 | if (out[i] != i * 32) success = false; 80 | } 81 | 82 | printf("Status: %s\n", (success) ? "Success" : "Failure"); 83 | } 84 | 85 | // Free the generated function if it's not needed anymore. 86 | MemoryManager::getGlobal()->free((void*)fn); 87 | // ========================================================================== 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /AsmJit/Test/testvar5.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Complete JIT Assembler for C++ Language. 3 | // 4 | // [License] 5 | // Zlib - See COPYING file in this package. 6 | 7 | // Test variable scope detection in loop. 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | // This is type of function we will generate 16 | typedef void (*MyFn)(uint32_t*); 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | using namespace AsmJit; 21 | 22 | // ========================================================================== 23 | // Create compiler. 24 | Compiler c; 25 | 26 | // Log compiler output. 27 | FileLogger logger(stderr); 28 | c.setLogger(&logger); 29 | 30 | { 31 | c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder1()); 32 | c.getFunction()->setHint(FUNCTION_HINT_NAKED, false); 33 | 34 | GPVar v0(c.newGP(VARIABLE_TYPE_GPD)); 35 | GPVar v1(c.newGP(VARIABLE_TYPE_GPD)); 36 | GPVar cnt(c.newGP(VARIABLE_TYPE_GPD)); 37 | 38 | c.xor_(v0, v0); 39 | c.xor_(v1, v1); 40 | c.spill(v0); 41 | c.spill(v1); 42 | 43 | Label L(c.newLabel()); 44 | c.mov(cnt, imm(32)); 45 | c.bind(L); 46 | 47 | c.inc(v1); 48 | c.add(v0, v1); 49 | 50 | c.dec(cnt); 51 | c.jnz(L); 52 | 53 | GPVar a0(c.argGP(0)); 54 | c.mov(dword_ptr(a0), v0); 55 | c.endFunction(); 56 | } 57 | // ========================================================================== 58 | 59 | // ========================================================================== 60 | // Make the function. 61 | MyFn fn = function_cast(c.make()); 62 | 63 | { 64 | uint32_t out; 65 | uint32_t expected = 0+ 1+ 2+ 3+ 4+ 5+ 6+ 7+ 8+ 9+ 66 | 10+11+12+13+14+15+16+17+18+19+ 67 | 20+21+22+23+24+25+26+27+28+29+ 68 | 30+31+32; 69 | 70 | fn(&out); 71 | 72 | printf("out=%u (should be %u)\n", out, expected); 73 | printf("Status: %s\n", (out == expected) ? "Success" : "Failure"); 74 | } 75 | 76 | // Free the generated function if it's not needed anymore. 77 | MemoryManager::getGlobal()->free((void*)fn); 78 | // ========================================================================== 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /AsmJit/Util/code-fix.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # This script will convert all TABs to SPACEs in the AsmJit root directory 4 | # and all sub-directories (recursive). 5 | # 6 | # Converted sequences: 7 | # - The \r\n sequence is converted to \n (To UNIX line-ending). 8 | # - The \t (TAB) sequence is converted to TAB_REPLACEMENT which should 9 | # be two spaces. 10 | # 11 | # Affected files: 12 | # - *.cmake 13 | # - *.cpp 14 | # - *.h 15 | 16 | import os 17 | 18 | TAB_REPLACEMENT = " " 19 | 20 | for root, dirs, files in os.walk("../"): 21 | for f in files: 22 | if f.lower().endswith(".cpp") or f.lower().endswith(".h") or f.lower().endswith(".cmake") or f.lower().endswith(".txt"): 23 | path = os.path.join(root, f) 24 | 25 | fh = open(path, "rb") 26 | data = fh.read() 27 | fh.close() 28 | 29 | fixed = False 30 | 31 | if "\r" in data: 32 | print "Fixing \\r\\n in: " + path 33 | data = data.replace("\r", "") 34 | fixed = True 35 | 36 | if "\t" in data: 37 | print "Fixing TABs in: " + path 38 | data = data.replace("\t", TAB_REPLACEMENT) 39 | fixed = True 40 | 41 | if fixed: 42 | fh = open(path, "wb") 43 | fh.truncate() 44 | fh.write(data) 45 | fh.close() 46 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-borland-dbg.bat: -------------------------------------------------------------------------------- 1 | mkdir ..\Build 2 | cd ..\Build 3 | cmake .. -G"Borland Makefiles" -DCMAKE_BUILD_TYPE=Debug -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 4 | cd ..\Util 5 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-borland-rel.bat: -------------------------------------------------------------------------------- 1 | mkdir ..\Build 2 | cd ..\Build 3 | cmake .. -G"Borland Makefiles" -DCMAKE_BUILD_TYPE=Release -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 4 | cd ..\Util 5 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-mac-xcode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir ../Build 3 | cd ../Build 4 | cmake .. -G"Xcode" -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 5 | cd ../Util 6 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-unix-makefiles-dbg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir ../Build 3 | cd ../Build 4 | cmake .. -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 5 | cd ../Util 6 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-unix-makefiles-rel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | mkdir ../Build 3 | cd ../Build 4 | cmake .. -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 5 | cd ../Util 6 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-windows-mingw-dbg.bat: -------------------------------------------------------------------------------- 1 | mkdir ..\Build 2 | cd ..\Build 3 | cmake .. -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 4 | cd ..\Util 5 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-windows-mingw-rel.bat: -------------------------------------------------------------------------------- 1 | mkdir ..\Build 2 | cd ..\Build 3 | cmake .. -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 4 | cd ..\Util 5 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-windows-msvc6.bat: -------------------------------------------------------------------------------- 1 | mkdir ..\Build 2 | cd ..\Build 3 | cmake .. -G"Visual Studio 6" -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 4 | cd ..\Util 5 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-windows-vs2005-x64.bat: -------------------------------------------------------------------------------- 1 | mkdir ..\Build 2 | cd ..\Build 3 | cmake .. -G"Visual Studio 8 2005 Win64" -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 4 | cd ..\Util 5 | pause 6 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-windows-vs2005-x86.bat: -------------------------------------------------------------------------------- 1 | mkdir ..\Build 2 | cd ..\Build 3 | cmake .. -G"Visual Studio 8 2005" -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 4 | cd ..\Util 5 | pause 6 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-windows-vs2008-x64.bat: -------------------------------------------------------------------------------- 1 | mkdir ..\Build 2 | cd ..\Build 3 | cmake .. -G"Visual Studio 9 2008 Win64" -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 4 | cd ..\Util 5 | pause 6 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-windows-vs2008-x86.bat: -------------------------------------------------------------------------------- 1 | mkdir ..\Build 2 | cd ..\Build 3 | cmake .. -G"Visual Studio 9 2008" -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 4 | cd ..\Util 5 | pause 6 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-windows-vs2010-x64.bat: -------------------------------------------------------------------------------- 1 | mkdir ..\Build 2 | cd ..\Build 3 | cmake .. -G"Visual Studio 10 Win64" -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 4 | cd ..\Util 5 | pause 6 | -------------------------------------------------------------------------------- /AsmJit/Util/configure-windows-vs2010-x86.bat: -------------------------------------------------------------------------------- 1 | mkdir ..\Build 2 | cd ..\Build 3 | cmake .. -G"Visual Studio 10" -DASMJIT_BUILD_LIBRARY=1 -DASMJIT_BUILD_TEST=1 4 | cd ..\Util 5 | pause 6 | -------------------------------------------------------------------------------- /DarkMMap.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DarkMMapLib", "DarkMMapLib.vcxproj", "{FC8D5B11-B1CF-41F2-9585-E7FD715B419B}" 5 | ProjectSection(ProjectDependencies) = postProject 6 | {2F2F6276-D084-4449-A37F-FA2850291582} = {2F2F6276-D084-4449-A37F-FA2850291582} 7 | EndProjectSection 8 | EndProject 9 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AsmJit", "AsmJit\AsmJit.vcxproj", "{2F2F6276-D084-4449-A37F-FA2850291582}" 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DarkMMapTest", "DarkMMapTest\DarkMMapTest.vcxproj", "{0A6A7D16-39F1-47CF-B399-40640CFDFF5A}" 12 | ProjectSection(ProjectDependencies) = postProject 13 | {FC8D5B11-B1CF-41F2-9585-E7FD715B419B} = {FC8D5B11-B1CF-41F2-9585-E7FD715B419B} 14 | EndProjectSection 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Win32 = Debug|Win32 19 | Debug|x64 = Debug|x64 20 | Release|Win32 = Release|Win32 21 | Release|x64 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {FC8D5B11-B1CF-41F2-9585-E7FD715B419B}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {FC8D5B11-B1CF-41F2-9585-E7FD715B419B}.Debug|Win32.Build.0 = Debug|Win32 26 | {FC8D5B11-B1CF-41F2-9585-E7FD715B419B}.Debug|x64.ActiveCfg = Debug|x64 27 | {FC8D5B11-B1CF-41F2-9585-E7FD715B419B}.Debug|x64.Build.0 = Debug|x64 28 | {FC8D5B11-B1CF-41F2-9585-E7FD715B419B}.Release|Win32.ActiveCfg = Release|Win32 29 | {FC8D5B11-B1CF-41F2-9585-E7FD715B419B}.Release|Win32.Build.0 = Release|Win32 30 | {FC8D5B11-B1CF-41F2-9585-E7FD715B419B}.Release|x64.ActiveCfg = Release|x64 31 | {FC8D5B11-B1CF-41F2-9585-E7FD715B419B}.Release|x64.Build.0 = Release|x64 32 | {2F2F6276-D084-4449-A37F-FA2850291582}.Debug|Win32.ActiveCfg = Debug|Win32 33 | {2F2F6276-D084-4449-A37F-FA2850291582}.Debug|Win32.Build.0 = Debug|Win32 34 | {2F2F6276-D084-4449-A37F-FA2850291582}.Debug|x64.ActiveCfg = Debug|x64 35 | {2F2F6276-D084-4449-A37F-FA2850291582}.Debug|x64.Build.0 = Debug|x64 36 | {2F2F6276-D084-4449-A37F-FA2850291582}.Release|Win32.ActiveCfg = Release|Win32 37 | {2F2F6276-D084-4449-A37F-FA2850291582}.Release|Win32.Build.0 = Release|Win32 38 | {2F2F6276-D084-4449-A37F-FA2850291582}.Release|x64.ActiveCfg = Release|x64 39 | {2F2F6276-D084-4449-A37F-FA2850291582}.Release|x64.Build.0 = Release|x64 40 | {0A6A7D16-39F1-47CF-B399-40640CFDFF5A}.Debug|Win32.ActiveCfg = Debug|Win32 41 | {0A6A7D16-39F1-47CF-B399-40640CFDFF5A}.Debug|Win32.Build.0 = Debug|Win32 42 | {0A6A7D16-39F1-47CF-B399-40640CFDFF5A}.Debug|x64.ActiveCfg = Debug|x64 43 | {0A6A7D16-39F1-47CF-B399-40640CFDFF5A}.Debug|x64.Build.0 = Debug|x64 44 | {0A6A7D16-39F1-47CF-B399-40640CFDFF5A}.Release|Win32.ActiveCfg = Release|Win32 45 | {0A6A7D16-39F1-47CF-B399-40640CFDFF5A}.Release|Win32.Build.0 = Release|Win32 46 | {0A6A7D16-39F1-47CF-B399-40640CFDFF5A}.Release|x64.ActiveCfg = Release|x64 47 | {0A6A7D16-39F1-47CF-B399-40640CFDFF5A}.Release|x64.Build.0 = Release|x64 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /DarkMMapLib.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {93e4251f-a3bb-49f4-998b-4d16eb2e1e19} 6 | 7 | 8 | {9a25ba64-75ca-4cc4-a275-a733593bdb77} 9 | 10 | 11 | {bdee8ac5-6f65-47ff-aef1-e9be5c2875b9} 12 | 13 | 14 | {7639ad6a-5c44-42f8-a5a2-05a939438413} 15 | 16 | 17 | {1866de54-d6bd-483d-b81c-074f03863c0c} 18 | 19 | 20 | {675b47c0-a2ee-4d3a-b5fa-74fa2c1d0a7b} 21 | 22 | 23 | {6edc42b6-7141-46a4-adc5-fedb04a8b611} 24 | 25 | 26 | 27 | 28 | !Common 29 | 30 | 31 | !Common 32 | 33 | 34 | Memory\Process 35 | 36 | 37 | Memory\Process 38 | 39 | 40 | Memory\LDAsm 41 | 42 | 43 | Memory\AsmHelpers 44 | 45 | 46 | Memory\AsmHelpers 47 | 48 | 49 | Memory\AsmHelpers 50 | 51 | 52 | 53 | Memory\Process 54 | 55 | 56 | 57 | Memory\Native 58 | 59 | 60 | Memory\Native 61 | 62 | 63 | Memory\File 64 | 65 | 66 | Memory\File 67 | 68 | 69 | Memory\File 70 | 71 | 72 | 73 | 74 | Memory\Process 75 | 76 | 77 | Memory\Process 78 | 79 | 80 | Memory\LDAsm 81 | 82 | 83 | Memory\AsmHelpers 84 | 85 | 86 | Memory\AsmHelpers 87 | 88 | 89 | Memory\AsmHelpers 90 | 91 | 92 | Memory\Process 93 | 94 | 95 | 96 | 97 | Memory\Native 98 | 99 | 100 | Memory\File 101 | 102 | 103 | Memory\File 104 | 105 | 106 | Memory\File 107 | 108 | 109 | -------------------------------------------------------------------------------- /DarkMMapLib.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WindowsLocalDebugger 5 | $(TargetDir) 6 | $(TargetPath) 7 | Auto 8 | 9 | -------------------------------------------------------------------------------- /DarkMMapTest/DarkMMapTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /DarkMMapTest/DarkMMapTest.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WindowsLocalDebugger 5 | NativeOnly 6 | 7 | 8 | 9 | 10 | NativeOnly 11 | WindowsLocalDebugger 12 | 13 | -------------------------------------------------------------------------------- /DarkMMapTest/Main.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "../DarkMMap.h" 3 | #include 4 | #include 5 | #include 6 | 7 | #pragma comment(lib, "mscoree.lib") 8 | 9 | #define TARGET_RUNTIME L'4' 10 | 11 | ICLRMetaHost *pClrHost = nullptr; 12 | ICLRRuntimeInfo *pRuntimeinfo = nullptr; 13 | ICLRRuntimeHost *pRuntimeHost = nullptr; 14 | 15 | DWORD InitRuntime( ) 16 | { 17 | DWORD dwRet = 0; 18 | HRESULT hr = S_OK; 19 | WCHAR ver[255] = {0}; 20 | IEnumUnknown *pRuntimes = nullptr; 21 | 22 | // MetaHost instance 23 | hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pClrHost); 24 | if(!SUCCEEDED(hr)) 25 | return 1; 26 | 27 | // Get available runtimes 28 | hr = pClrHost->EnumerateInstalledRuntimes(&pRuntimes); 29 | if(!SUCCEEDED(hr)) 30 | return 1; 31 | 32 | // Search for target runtime needed for managed dll to run 33 | while(pRuntimes->Next(1, (IUnknown**)&pRuntimeinfo, &dwRet) == S_OK && dwRet > 0) 34 | { 35 | dwRet = ARRAYSIZE(ver); 36 | 37 | hr = pRuntimeinfo->GetVersionString(ver, &dwRet); 38 | 39 | // ver - string "vA.B[.X]" 40 | if(ver[1] == TARGET_RUNTIME) 41 | break; 42 | 43 | pRuntimeinfo->Release(); 44 | pRuntimeinfo = nullptr; 45 | } 46 | 47 | // Found runtime 48 | if(pRuntimeinfo != nullptr) 49 | { 50 | BOOL started = FALSE; 51 | 52 | // Get CLR hosting interface 53 | hr = pRuntimeinfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pRuntimeHost); 54 | if(!SUCCEEDED(hr)) 55 | return 1; 56 | 57 | // Check if runtime is already running 58 | hr = pRuntimeinfo->IsStarted(&started, &dwRet); 59 | if(!SUCCEEDED(hr)) 60 | return 1; 61 | 62 | // Start .NET runtime if needed 63 | if(started == FALSE) 64 | { 65 | hr = pRuntimeHost->Start(); 66 | if(!SUCCEEDED(hr)) 67 | return 1; 68 | } 69 | } 70 | 71 | if(pRuntimes) 72 | pRuntimes->Release(); 73 | 74 | return 0; 75 | } 76 | 77 | int _tmain(int argc, _TCHAR* argv[]) 78 | { 79 | HMODULE mod = NULL; 80 | ds_mmap::CDarkMMap mapper(GetCurrentProcessId()); 81 | //ds_mmap::CDarkMMap mapper90(GetCurrentProcessId()); 82 | //ds_mmap::CDarkMMap mapperRemote(6356); 83 | 84 | #ifdef _M_AMD64 85 | wchar_t* path = L"C:\\Users\\Ton\\Documents\\Visual Studio 2012\\Projects\\DarkMMap\\DummyDll64.dll"; 86 | //wchar_t* path90 = L"C:\\Users\\Ton\\Documents\\Visual Studio 2012\\Projects\\DarkMMap\\DummyDll6490.dll"; 87 | //wchar_t* path = L"C:\\windows\\system32\\calc.exe"; 88 | #else 89 | wchar_t* path = L"C:\\Users\\Ton\\Documents\\Visual Studio 2012\\Projects\\DarkMMap\\DummyDll.dll"; 90 | //wchar_t *path90 = L"..\\DummyDll90.dll"; 91 | //wchar_t* path = L"C:\\Users\\Ton\\Documents\\Visual Studio 2012\\Projects\\ImgSearch\\Release\\ImgSearch.exe"; 92 | //wchar_t* path = L"C:\\Users\\Ton\\Documents\\Visual Studio 2012\\Projects\\DarkMMap\\ClrDummy.dll"; 93 | //wchar_t* path = L"C:\\windows\\system32\\cmd.exe"; 94 | #endif 95 | 96 | if(argc > 1) 97 | path = argv[1]; 98 | 99 | //InitRuntime(); 100 | 101 | ds_mmap::eLoadFlags flags = (ds_mmap::eLoadFlags)( ds_mmap::CreateLdrRef | 102 | ds_mmap::ManualImports | 103 | //ds_mmap::UnlinkVAD | 104 | //ds_mmap::NoExceptions | 105 | //ds_mmap::NoTLS | 106 | ds_mmap::RebaseProcess | 107 | ds_mmap::NoDelayLoad ); 108 | 109 | /*mod = LoadLibrary(path); 110 | FreeLibrary(mod);*/ 111 | 112 | if((mod = mapper.MapDll(path, flags)) != 0 /*&& mapper.MapDll(path90, flags) != 0*/) 113 | { 114 | //DebugBreak(); 115 | /*mod = GetModuleHandle(L"DummyDll.dll"); 116 | int (*proc)(char*) = (int (*)(char*))GetProcAddress(mod, "fnDummyDll"); 117 | 118 | if(proc) 119 | { 120 | size_t result = 0; 121 | mapper.CallFunction(proc, { (size_t)"TestString" }, result, ds_mmap::CC_cdecl); 122 | }*/ 123 | 124 | mapper.UnmapAllModules(); 125 | } 126 | else 127 | { 128 | std::cout << "Mapping failed with error " << GetLastError() << ": " << err::GetErrorDescription(GetLastError()) << std::endl; 129 | } 130 | 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /DarkMMapTest/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /DarkMMapTest/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /Errors.cpp: -------------------------------------------------------------------------------- 1 | #include "Errors.h" 2 | 3 | #include 4 | 5 | namespace err 6 | { 7 | std::string err::GetErrorDescription( int code ) 8 | { 9 | // 10 | // Custom error 11 | // 12 | for(int i = 0; i < ARRAYSIZE(ErrorDescription); i++) 13 | if(ErrorDescription[i].code == code) 14 | return ErrorDescription[i].description; 15 | 16 | // 17 | // Win32 Error 18 | // 19 | LPSTR lpMsgBuf = nullptr; 20 | 21 | if(FormatMessageA 22 | ( 23 | FORMAT_MESSAGE_ALLOCATE_BUFFER | 24 | FORMAT_MESSAGE_FROM_SYSTEM | 25 | FORMAT_MESSAGE_IGNORE_INSERTS, 26 | NULL, 27 | code, 28 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 29 | (LPSTR)&lpMsgBuf, 30 | 0, NULL 31 | ) != 0) 32 | { 33 | std::string ret(lpMsgBuf); 34 | 35 | LocalFree(lpMsgBuf); 36 | return ret; 37 | } 38 | 39 | return ""; 40 | } 41 | } -------------------------------------------------------------------------------- /Errors.h: -------------------------------------------------------------------------------- 1 | #ifndef _ERRORS_H_ 2 | #define _ERRORS_H_ 3 | 4 | #include 5 | 6 | // 7 | // Custom error codes 8 | // 9 | namespace err 10 | { 11 | const unsigned long base = 100000; 12 | 13 | namespace general 14 | { 15 | enum eCode 16 | { 17 | Success = 0, 18 | UnknownError = base + 1, 19 | 20 | end = base + 100, 21 | }; 22 | }; 23 | 24 | namespace pe 25 | { 26 | enum eCode 27 | { 28 | NoFile = general::end + 1, 29 | NoSignature = general::end + 2, 30 | 31 | end = general::end + 100, 32 | }; 33 | } 34 | 35 | namespace mapping 36 | { 37 | enum eCode 38 | { 39 | AlreayLoaded = pe::end + 1, 40 | CantMap = pe::end + 2, 41 | AbnormalRelocation = pe::end + 3, 42 | CantCreateActx = pe::end + 4, 43 | CantResolveImport = pe::end + 5, 44 | NoImportFunction = pe::end + 6, 45 | ResolutionSkipped = pe::end + 7, 46 | CantRelocate = pe::end + 8, 47 | 48 | end = pe::end + 100, 49 | }; 50 | } 51 | 52 | struct ErrDesc 53 | { 54 | int code; 55 | char *description; 56 | }; 57 | 58 | const ErrDesc ErrorDescription[] = 59 | { 60 | { general::Success, "Success" }, 61 | { general::UnknownError, "Unknown error" }, 62 | 63 | { pe::NoFile, "No file to map" }, 64 | { pe::NoSignature, "Invalid or absent PE signature" }, 65 | 66 | { mapping::AlreayLoaded, "Image is already present in process" }, 67 | { mapping::ResolutionSkipped, "Image name resolution was skipped" }, 68 | { mapping::CantMap, "Can't map image" }, 69 | { mapping::AbnormalRelocation, "Abnormal relocation encountered during image fix-up" }, 70 | { mapping::CantCreateActx, "Can't create Activation context" }, 71 | { mapping::CantResolveImport, "Failed to resolve one or more import libraries" }, 72 | { mapping::NoImportFunction, "Import function was not found in module" }, 73 | { mapping::CantRelocate, "Image can't be relocated. Relocation information is missing" } 74 | }; 75 | 76 | std::string GetErrorDescription(int code); 77 | }; 78 | 79 | #endif// _ERRORS_H_ -------------------------------------------------------------------------------- /FileProjection.cpp: -------------------------------------------------------------------------------- 1 | #include "FileProjection.h" 2 | 3 | namespace ds_mmap 4 | { 5 | CFileProjection::CFileProjection(void) 6 | : m_hMapping(NULL) 7 | , m_hFile(INVALID_HANDLE_VALUE) 8 | , m_pData(nullptr) 9 | , m_isPlainData(false) 10 | , m_hctx(INVALID_HANDLE_VALUE) 11 | { 12 | } 13 | 14 | CFileProjection::CFileProjection( const std::wstring& path ) 15 | : CFileProjection() 16 | { 17 | Project(path); 18 | } 19 | 20 | 21 | CFileProjection::~CFileProjection(void) 22 | { 23 | Release(); 24 | } 25 | 26 | /* 27 | Open file as memory-mapped PE image 28 | 29 | IN: 30 | path - file path 31 | 32 | RETURN: 33 | Address of file mapping 34 | */ 35 | void* CFileProjection::Project( const std::wstring& path ) 36 | { 37 | Release(); 38 | 39 | ACTCTX act = {0}; 40 | act.cbSize = sizeof(act); 41 | act.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; 42 | act.lpSource = path.c_str(); 43 | act.lpResourceName = MAKEINTRESOURCE(2); 44 | 45 | m_hctx = CreateActCtx(&act); 46 | 47 | if(m_hctx == INVALID_HANDLE_VALUE) 48 | { 49 | act.lpResourceName = MAKEINTRESOURCE(1); 50 | m_hctx = CreateActCtx(&act); 51 | } 52 | 53 | m_hFile = CreateFile(path.c_str(), FILE_GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); 54 | 55 | if(m_hFile != INVALID_HANDLE_VALUE) 56 | { 57 | // Try mapping as image 58 | m_hMapping = CreateFileMapping(m_hFile, NULL, SEC_IMAGE | PAGE_READONLY, 0, 0, NULL); 59 | 60 | if(m_hMapping && m_hMapping != INVALID_HANDLE_VALUE) 61 | { 62 | m_pData = MapViewOfFile(m_hMapping, FILE_MAP_READ, 0, 0, 0); 63 | } 64 | // Map as simple datafile 65 | else 66 | { 67 | m_isPlainData = true; 68 | m_hMapping = CreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL); 69 | 70 | if(m_hMapping && m_hMapping != INVALID_HANDLE_VALUE) 71 | m_pData = MapViewOfFile(m_hMapping, FILE_MAP_READ, 0, 0, 0); 72 | } 73 | } 74 | 75 | return m_pData; 76 | } 77 | 78 | /* 79 | Release mapping, if any 80 | */ 81 | void CFileProjection::Release() 82 | { 83 | if(m_hctx != INVALID_HANDLE_VALUE) 84 | { 85 | ReleaseActCtx(m_hctx); 86 | m_hctx = INVALID_HANDLE_VALUE; 87 | } 88 | 89 | if(m_pData) 90 | { 91 | UnmapViewOfFile(m_pData); 92 | m_pData = nullptr; 93 | } 94 | 95 | if(m_hMapping && m_hMapping != INVALID_HANDLE_VALUE) 96 | { 97 | CloseHandle(m_hMapping); 98 | m_hMapping = NULL; 99 | } 100 | 101 | if(m_hFile != INVALID_HANDLE_VALUE) 102 | { 103 | CloseHandle(m_hFile); 104 | m_hFile = INVALID_HANDLE_VALUE; 105 | } 106 | } 107 | 108 | /* 109 | Get mapping base 110 | 111 | RETURN: 112 | Address of file mapping 113 | */ 114 | void* CFileProjection::base() const 115 | { 116 | return m_pData; 117 | } 118 | 119 | /* 120 | Get activation context 121 | */ 122 | HANDLE CFileProjection::actx() const 123 | { 124 | return m_hctx; 125 | } 126 | 127 | /* 128 | Get mapping base 129 | 130 | RETURN: 131 | Address of file mapping 132 | */ 133 | CFileProjection::operator void*() const 134 | { 135 | return m_pData; 136 | } 137 | 138 | /* 139 | Is plain datafile 140 | */ 141 | bool CFileProjection::isPlainData() const 142 | { 143 | return m_isPlainData; 144 | } 145 | 146 | }; -------------------------------------------------------------------------------- /FileProjection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace ds_mmap 8 | { 9 | // 10 | // Load file as PE image 11 | // 12 | class CFileProjection 13 | { 14 | public: 15 | CFileProjection(void); 16 | CFileProjection(const std::wstring& path); 17 | ~CFileProjection(void); 18 | 19 | /* 20 | Open file as memory-mapped PE image 21 | 22 | IN: 23 | path - file path 24 | 25 | RETURN: 26 | Address of file mapping 27 | */ 28 | void* Project(const std::wstring& path); 29 | 30 | /* 31 | Release file mapping 32 | */ 33 | void Release(); 34 | 35 | /* 36 | Get mapping base 37 | 38 | RETURN: 39 | Address of file mapping 40 | */ 41 | void* base() const; 42 | 43 | /* 44 | Get activation context 45 | */ 46 | HANDLE actx() const; 47 | 48 | /* 49 | is plain data file 50 | */ 51 | bool isPlainData() const; 52 | 53 | /* 54 | Get mapping base 55 | 56 | RETURN: 57 | Address of file mapping 58 | */ 59 | operator void*() const; 60 | 61 | private: 62 | HANDLE m_hFile; // Target file HANDLE 63 | HANDLE m_hMapping; // Memory mapping object 64 | void* m_pData; // Mapping base 65 | bool m_isPlainData; // File mapped as plain data file 66 | HANDLE m_hctx; // Activation context 67 | }; 68 | }; 69 | -------------------------------------------------------------------------------- /ImageNET.cpp: -------------------------------------------------------------------------------- 1 | #include "ImageNET.h" 2 | 3 | 4 | CImageNET::CImageNET(void) 5 | : m_pMetaDisp(nullptr) 6 | , m_pMetaImport(nullptr) 7 | , m_pAssemblyImport(nullptr) 8 | { 9 | } 10 | 11 | 12 | CImageNET::~CImageNET(void) 13 | { 14 | // 15 | // release interfaces 16 | // 17 | if (m_pMetaDisp) 18 | { 19 | m_pMetaDisp->Release(); 20 | m_pMetaDisp = nullptr; 21 | } 22 | if (m_pMetaImport) 23 | { 24 | m_pMetaImport->Release(); 25 | m_pMetaImport = nullptr; 26 | } 27 | if (m_pAssemblyImport) 28 | { 29 | m_pAssemblyImport->Release(); 30 | m_pAssemblyImport = nullptr; 31 | } 32 | 33 | CoUninitialize(); 34 | } 35 | 36 | bool CImageNET::Init( const std::wstring& path ) 37 | { 38 | HRESULT hr; 39 | VARIANT value; 40 | 41 | m_path = path; 42 | 43 | hr = CoInitialize(0); 44 | 45 | hr = CoCreateInstance(CLSID_CorMetaDataDispenser, NULL, CLSCTX_INPROC_SERVER, IID_IMetaDataDispenserEx, (void**)&m_pMetaDisp); 46 | if(FAILED(hr)) 47 | { 48 | m_pMetaDisp = nullptr; 49 | return false; 50 | } 51 | 52 | // 53 | // query needed interfaces 54 | // 55 | hr = m_pMetaDisp->OpenScope(m_path.c_str(), 0, IID_IMetaDataImport, (IUnknown**)&m_pMetaImport); 56 | if (hr == CLDB_E_BADUPDATEMODE) 57 | { 58 | V_VT(&value) = VT_UI4; 59 | V_UI4(&value) = MDUpdateIncremental; 60 | 61 | if (FAILED(hr = m_pMetaDisp->SetOption(MetaDataSetUpdate, &value))) 62 | return false; 63 | 64 | hr = m_pMetaDisp->OpenScope(m_path.c_str(), 0, IID_IMetaDataImport, (IUnknown**)&m_pMetaImport); 65 | } 66 | 67 | if (FAILED(hr)) 68 | return false; 69 | 70 | hr = m_pMetaImport->QueryInterface(IID_IMetaDataAssemblyImport, (void**) &m_pAssemblyImport); 71 | if (FAILED(hr)) 72 | return false; 73 | 74 | return true; 75 | } 76 | 77 | bool CImageNET::Parse() 78 | { 79 | DWORD dwcTypeDefs, dwTypeDefFlags, dwcTokens, dwSigBlobSize; 80 | HCORENUM hceTypeDefs = 0; 81 | mdTypeRef rTypeDefs[10] = {0}; 82 | WCHAR wcName[1024] = {0}; 83 | mdToken tExtends = 0; 84 | HCORENUM hceMethods = 0; 85 | mdToken rTokens[10] = {0}; 86 | // 87 | // enumeration loop 88 | // 89 | while (SUCCEEDED(m_pMetaImport->EnumTypeDefs(&hceTypeDefs, rTypeDefs, ARRAYSIZE(rTypeDefs), &dwcTypeDefs)) 90 | && dwcTypeDefs > 0) 91 | { 92 | for (UINT i = 0; i < dwcTypeDefs; i++) 93 | { 94 | HRESULT hr = m_pMetaImport->GetTypeDefProps(rTypeDefs[i], wcName, ARRAYSIZE(wcName), NULL, &dwTypeDefFlags, &tExtends); 95 | if ( FAILED(hr) ) 96 | continue; 97 | 98 | while (SUCCEEDED(m_pMetaImport->EnumMethods(&hceMethods, rTypeDefs[i], rTokens, ARRAYSIZE(rTokens), &dwcTokens)) 99 | && dwcTokens > 0) 100 | { 101 | DWORD dwCodeRVA, dwAttr; 102 | WCHAR wmName[1024] = {0}; 103 | PCCOR_SIGNATURE pbySigBlob = nullptr; 104 | 105 | for (UINT j = 0; j < dwcTokens; j++) 106 | { 107 | // get method information 108 | HRESULT hr = m_pMetaImport->GetMemberProps( 109 | rTokens[j], 110 | NULL, 111 | wmName, ARRAYSIZE(wmName), NULL, 112 | &dwAttr, 113 | &pbySigBlob, &dwSigBlobSize, 114 | &dwCodeRVA, 115 | NULL, 116 | NULL, 117 | NULL, NULL); 118 | if ( FAILED(hr) ) 119 | continue; 120 | 121 | m_methods.emplace(std::make_pair(wcName, wmName), dwCodeRVA); 122 | } 123 | } 124 | } 125 | } 126 | 127 | return true; 128 | } 129 | 130 | -------------------------------------------------------------------------------- /ImageNET.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stdafx.h" 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | // .NET metadata parser 10 | class CImageNET 11 | { 12 | typedef std::map, size_t> mapMethodRVA; 13 | 14 | public: 15 | CImageNET(void); 16 | ~CImageNET(void); 17 | 18 | /* 19 | Initialize COM parser 20 | */ 21 | bool Init( const std::wstring& path ); 22 | 23 | /* 24 | Parse .NET metadata 25 | */ 26 | bool Parse(); 27 | 28 | private: 29 | std::wstring m_path; 30 | IMetaDataImport *m_pMetaImport; 31 | IMetaDataDispenserEx *m_pMetaDisp; 32 | IMetaDataAssemblyImport *m_pAssemblyImport; 33 | mapMethodRVA m_methods; 34 | }; 35 | 36 | -------------------------------------------------------------------------------- /LDasm.h: -------------------------------------------------------------------------------- 1 | #ifndef _LDASM_ 2 | #define _LDASM_ 3 | 4 | #include "string.h" 5 | 6 | #ifdef _M_AMD64 7 | #define is_x64 1 8 | #else 9 | #define is_x64 0 10 | #endif//_M_AMD64 11 | 12 | #ifdef __cplusplus 13 | extern "C" 14 | { 15 | #endif 16 | 17 | #define F_INVALID 0x01 18 | #define F_PREFIX 0x02 19 | #define F_REX 0x04 20 | #define F_MODRM 0x08 21 | #define F_SIB 0x10 22 | #define F_DISP 0x20 23 | #define F_IMM 0x40 24 | #define F_RELATIVE 0x80 25 | 26 | typedef unsigned char u8; 27 | typedef unsigned long u32; 28 | 29 | typedef struct _ldasm_data 30 | { 31 | u8 flags; 32 | u8 rex; 33 | u8 modrm; 34 | u8 sib; 35 | u8 opcd_offset; 36 | u8 opcd_size; 37 | u8 disp_offset; 38 | u8 disp_size; 39 | u8 imm_offset; 40 | u8 imm_size; 41 | } ldasm_data; 42 | 43 | unsigned int __fastcall ldasm(void *code, ldasm_data *ld, u32 is64); 44 | unsigned long __fastcall SizeOfProc(void *Proc); 45 | void* __fastcall ResolveJmp(void *Proc); 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif//_LDASM_ -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2013 DarthTon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /MemModules.h: -------------------------------------------------------------------------------- 1 | #ifndef _MEM_MODULES_H_ 2 | #define _MEM_MODULES_H_ 3 | 4 | #include "stdafx.h" 5 | #include "MemCore.h" 6 | #include "NativeLoaderHelper.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #pragma comment(lib, "ntdll.lib") 17 | 18 | namespace ds_mmap 19 | { 20 | namespace ds_process 21 | { 22 | 23 | // Resolve path flags 24 | enum eResolveFlag 25 | { 26 | Default = 0, 27 | ApiSchemaOnly = 1, 28 | EnsureFullPath = 2, 29 | }; 30 | 31 | class CMemModules 32 | { 33 | typedef std::map> mapApiSchema; 34 | 35 | public: 36 | CMemModules(CMemCore& mem); 37 | ~CMemModules(void); 38 | 39 | /* 40 | Inject Dll into process 41 | 42 | RETURN: 43 | Error code 44 | */ 45 | HMODULE SimpleInject( const std::string& dllName, void *pActx = nullptr ); 46 | 47 | /* 48 | Unload Dll from process 49 | 50 | RETURN: 51 | Error code 52 | */ 53 | DWORD SimpleUnload( const std::string& dllName ); 54 | 55 | /* 56 | Resolve dll path 57 | 58 | IN: 59 | path - dll path 60 | baseName - name of base import dll (API Schema resolve only) 61 | 62 | OUT: 63 | path - resolved path 64 | 65 | RETURN: 66 | Error code 67 | */ 68 | DWORD ResolvePath(std::string& path, eResolveFlag flags, const std::wstring& baseName = L""); 69 | DWORD ResolvePath(std::wstring& path, eResolveFlag flags, const std::wstring& baseName = L""); 70 | 71 | /* 72 | Get specific module address 73 | 74 | IN: 75 | modname - module name 76 | skipManualModules - don't search for manually mapped modules 77 | baseModule - name of base import dll (API Schema resolve only) 78 | 79 | OUT: 80 | void 81 | 82 | RETURN: 83 | Module address 84 | 0 - if not found 85 | */ 86 | HMODULE GetModuleAddress( const char* modname, bool skipManualModules = false, const wchar_t* baseModule = L"" ); 87 | HMODULE GetModuleAddress( const wchar_t* modname, bool skipManualModules = false, const wchar_t* baseModule = L"" ); 88 | 89 | /* 90 | Get address of function in another process 91 | 92 | IN: 93 | hMod - module base 94 | func - function name or ordinal 95 | baseModule - name of base import dll (API Schema resolve only) 96 | 97 | OUT: 98 | void 99 | 100 | RETURN: 101 | Function address 102 | 0 - if not found 103 | */ 104 | FARPROC GetProcAddressEx( HMODULE hMod, const char* name, const wchar_t* baseModule = L"" ); 105 | 106 | /* 107 | Add manually mapped module to list 108 | 109 | IN: 110 | name - module name 111 | base - module base address 112 | */ 113 | void AddManualModule(const std::wstring& name, HMODULE base); 114 | 115 | /* 116 | Remove manually mapped module from list 117 | 118 | IN: 119 | name - module name 120 | */ 121 | void RemoveManualModule(const std::wstring& name); 122 | 123 | /* 124 | Set active activation context 125 | */ 126 | void PushLocalActx(HANDLE hActx = INVALID_HANDLE_VALUE); 127 | 128 | /* 129 | Restore previous active activation context 130 | */ 131 | void PopLocalActx( ); 132 | 133 | /* 134 | */ 135 | CNtLdr& NtLoader() { return m_native; } 136 | 137 | private: 138 | CMemModules& operator = (const CMemModules&) { } 139 | 140 | /* 141 | Initialize Api schema from current process table 142 | */ 143 | bool InitApiSchema(); 144 | 145 | /* 146 | Try SxS redirection 147 | */ 148 | DWORD ProbeSxSRedirect(std::wstring& path); 149 | 150 | /* 151 | Get directory containing main process module 152 | 153 | RETURN: 154 | Directory path 155 | */ 156 | std::wstring GetProcessDirectory(); 157 | 158 | private: 159 | CMemCore& m_memory; // Process memory routines 160 | static mapApiSchema m_ApiSchemaMap; // Api schema map 161 | 162 | // List of manually mapped modules 163 | std::map ms_modules; 164 | 165 | // Activation context stack 166 | std::stack m_ActxStack; 167 | 168 | // Native loader routines 169 | CNtLdr m_native; 170 | }; 171 | } 172 | } 173 | #endif// _MEM_MODULES_H_ -------------------------------------------------------------------------------- /NtStructures.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #pragma warning(disable : 4201) 6 | 7 | enum _LDR_DDAG_STATE 8 | { 9 | LdrModulesMerged=-5, 10 | LdrModulesInitError=-4, 11 | LdrModulesSnapError=-3, 12 | LdrModulesUnloaded=-2, 13 | LdrModulesUnloading=-1, 14 | LdrModulesPlaceHolder=0, 15 | LdrModulesMapping=1, 16 | LdrModulesMapped=2, 17 | LdrModulesWaitingForDependencies=3, 18 | LdrModulesSnapping=4, 19 | LdrModulesSnapped=5, 20 | LdrModulesCondensed=6, 21 | LdrModulesReadyToInit=7, 22 | LdrModulesInitializing=8, 23 | LdrModulesReadyToRun=9 24 | }; 25 | 26 | enum _LDR_DLL_LOAD_REASON 27 | { 28 | LoadReasonStaticDependency=0, 29 | LoadReasonStaticForwarderDependency=1, 30 | LoadReasonDynamicForwarderDependency=2, 31 | LoadReasonDelayloadDependency=3, 32 | LoadReasonDynamicLoad=4, 33 | LoadReasonAsImageLoad=5, 34 | LoadReasonAsDataLoad=6, 35 | LoadReasonUnknown=-1 36 | }; 37 | 38 | struct _RTL_BALANCED_NODE 39 | { 40 | union 41 | { 42 | struct _RTL_BALANCED_NODE * Children[2]; 43 | struct 44 | { 45 | struct _RTL_BALANCED_NODE * Left; 46 | struct _RTL_BALANCED_NODE * Right; 47 | }; 48 | }; 49 | union 50 | { 51 | union 52 | { 53 | struct 54 | { 55 | unsigned char Red: 1; 56 | }; 57 | struct 58 | { 59 | unsigned char Balance: 2; 60 | }; 61 | }; 62 | 63 | size_t ParentValue; 64 | }; 65 | }; 66 | 67 | struct _LDR_DDAG_NODE 68 | { 69 | _LIST_ENTRY Modules; 70 | struct _LDR_SERVICE_TAG_RECORD * ServiceTagList; 71 | unsigned long LoadCount; 72 | unsigned long ReferenceCount; 73 | unsigned long DependencyCount; 74 | _SINGLE_LIST_ENTRY RemovalLink; 75 | void* IncomingDependencies; 76 | _LDR_DDAG_STATE State; 77 | struct _SINGLE_LIST_ENTRY CondenseLink; 78 | unsigned long PreorderNumber; 79 | unsigned long LowestLink; 80 | }; 81 | 82 | struct _PEB_LDR_DATA_W8 83 | { 84 | unsigned long Length; 85 | unsigned char Initialized; 86 | void * SsHandle; 87 | _LIST_ENTRY InLoadOrderModuleList; 88 | _LIST_ENTRY InMemoryOrderModuleList; 89 | _LIST_ENTRY InInitializationOrderModuleList; 90 | void * EntryInProgress; 91 | unsigned char ShutdownInProgress; 92 | void * ShutdownThreadId; 93 | }; 94 | 95 | struct _LDR_DATA_TABLE_ENTRY_W8 96 | { 97 | _LIST_ENTRY InLoadOrderLinks; 98 | _LIST_ENTRY InMemoryOrderLinks; 99 | union 100 | { 101 | _LIST_ENTRY InInitializationOrderLinks; 102 | _LIST_ENTRY InProgressLinks; 103 | }; 104 | void * DllBase; 105 | void * EntryPoint; 106 | unsigned long SizeOfImage; 107 | _UNICODE_STRING FullDllName; 108 | _UNICODE_STRING BaseDllName; 109 | unsigned long Flags; 110 | unsigned short ObsoleteLoadCount; 111 | unsigned short TlsIndex; 112 | struct _LIST_ENTRY HashLinks; 113 | unsigned long TimeDateStamp; 114 | struct _ACTIVATION_CONTEXT * EntryPointActivationContext; 115 | void * PatchInformation; 116 | _LDR_DDAG_NODE * DdagNode; 117 | _LIST_ENTRY NodeModuleLink; 118 | struct _LDRP_DLL_SNAP_CONTEXT * SnapContext; 119 | void * ParentDllBase; 120 | void * SwitchBackContext; 121 | _RTL_BALANCED_NODE BaseAddressIndexNode; 122 | _RTL_BALANCED_NODE MappingInfoIndexNode; 123 | unsigned long OriginalBase; 124 | union _LARGE_INTEGER LoadTime; 125 | unsigned long BaseNameHashValue; 126 | _LDR_DLL_LOAD_REASON LoadReason; 127 | }; 128 | 129 | struct _LDR_DATA_TABLE_ENTRY_W7 130 | { 131 | _LIST_ENTRY InLoadOrderLinks; 132 | _LIST_ENTRY InMemoryOrderLinks; 133 | _LIST_ENTRY InInitializationOrderLinks; 134 | void * DllBase; 135 | void * EntryPoint; 136 | unsigned long SizeOfImage; 137 | _UNICODE_STRING FullDllName; 138 | _UNICODE_STRING BaseDllName; 139 | unsigned long Flags; 140 | unsigned short LoadCount; 141 | unsigned short TlsIndex; 142 | union 143 | { 144 | _LIST_ENTRY HashLinks; 145 | struct 146 | { 147 | void * SectionPointer; 148 | unsigned long CheckSum; 149 | }; 150 | }; 151 | union 152 | { 153 | unsigned long TimeDateStamp; 154 | void * LoadedImports; 155 | }; 156 | struct _ACTIVATION_CONTEXT * EntryPointActivationContext; 157 | void * PatchInformation; 158 | _LIST_ENTRY ForwarderLinks; 159 | _LIST_ENTRY ServiceTagLinks; 160 | _LIST_ENTRY StaticLinks; 161 | void * ContextInformation; 162 | unsigned long OriginalBase; 163 | _LARGE_INTEGER LoadTime; 164 | }; 165 | 166 | 167 | #pragma warning(default : 4201) 168 | 169 | typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY 170 | { 171 | PIMAGE_RUNTIME_FUNCTION_ENTRY ExceptionDirectory; 172 | PVOID ImageBase; 173 | ULONG ImageSize; 174 | ULONG ExceptionDirectorySize; 175 | 176 | } RTL_INVERTED_FUNCTION_TABLE_ENTRY, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY; 177 | 178 | typedef struct _RTL_INVERTED_FUNCTION_TABLE7 179 | { 180 | ULONG Count; 181 | ULONG MaxCount; 182 | ULONG Pad[0x1]; 183 | RTL_INVERTED_FUNCTION_TABLE_ENTRY Entries[0x200]; 184 | 185 | } RTL_INVERTED_FUNCTION_TABLE7, * PRTL_INVERTED_FUNCTION_TABLE7; 186 | 187 | typedef struct _RTL_INVERTED_FUNCTION_TABLE8 188 | { 189 | ULONG Count; 190 | ULONG MaxCount; 191 | ULONG Pad[0x2]; 192 | RTL_INVERTED_FUNCTION_TABLE_ENTRY Entries[0x200]; 193 | 194 | } RTL_INVERTED_FUNCTION_TABLE8, * PRTL_INVERTED_FUNCTION_TABLE8; 195 | 196 | typedef struct _THREAD_BASIC_INFORMATION 197 | { 198 | NTSTATUS ExitStatus; 199 | PTEB TebBaseAddress; 200 | struct 201 | { 202 | PVOID p1; 203 | PVOID p2; 204 | }ClientId; 205 | KAFFINITY AffinityMask; 206 | LONG Priority; 207 | LONG BasePriority; 208 | 209 | } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; 210 | 211 | // 212 | // Api schema structures 213 | // 214 | struct ApiSchemaMapHeader 215 | { 216 | DWORD Version; 217 | DWORD NumModules; 218 | }; 219 | 220 | struct ApiSchemaModuleEntry 221 | { 222 | DWORD OffsetToName; 223 | WORD NameSize; 224 | DWORD OffsetOfHosts; 225 | }; 226 | 227 | struct ApiSchemaModuleHostsHeader 228 | { 229 | DWORD NumHosts; 230 | }; 231 | 232 | struct ApiSchemaModuleHost 233 | { 234 | DWORD OffsetOfImportingName; 235 | WORD ImportingNameSize; 236 | DWORD OffsetOfHostName; 237 | WORD HostNameSize; 238 | }; -------------------------------------------------------------------------------- /PEManger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stdafx.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #pragma comment(lib, "dbghelp.lib") 16 | namespace ds_mmap 17 | { 18 | namespace ds_pe 19 | { 20 | #define MAX_SECTIONS 10 21 | 22 | struct IMAGE_BASE_RELOCATION2 23 | { 24 | ULONG PageRVA; 25 | ULONG BlockSize; 26 | 27 | struct 28 | { 29 | WORD Offset : 12; 30 | WORD Type : 4; 31 | }Item[1]; 32 | }; 33 | 34 | // 35 | // Primitive PE parsing class 36 | // 37 | class CPEManger 38 | { 39 | typedef std::map> mapImports; 40 | 41 | public: 42 | CPEManger(void); 43 | ~CPEManger(void); 44 | 45 | /* 46 | Parse PE image from memory 47 | Image must be loaded with proper sections memory alignment 48 | 49 | IN: 50 | pFileBase - image base address 51 | 52 | RETURN: 53 | Status 54 | 55 | */ 56 | bool Parse(const void* pFileBase, bool isPlainData); 57 | 58 | /* 59 | Remap virtual address to file address 60 | */ 61 | size_t ResolveRvaToVA(size_t Rva) const; 62 | 63 | /* 64 | Size of image in memory 65 | */ 66 | size_t ImageSize() const; 67 | 68 | /* 69 | Size of headers 70 | */ 71 | size_t HeadersSize() const; 72 | 73 | /* 74 | Image base. ASLR is taken into account 75 | */ 76 | size_t ImageBase() const; 77 | 78 | /* 79 | Get image sections 80 | */ 81 | const std::vector& Sections() const; 82 | 83 | /* 84 | Get target entry point address 85 | 86 | IN: 87 | base - target image base 88 | 89 | RETURN: 90 | Calculated entry point 91 | */ 92 | const void* EntryPoint( const void* base ) const; 93 | 94 | /* 95 | Retrieve TLS callbacks 96 | Callbacks are rebased for target image 97 | 98 | IN: 99 | targetBase - target image base 100 | 101 | OUT: 102 | result - array of callbacks 103 | 104 | RETURN: 105 | Number of callbacks in image 106 | */ 107 | int GetTLSCallbacks(const void* targetBase, std::vector& result) const; 108 | 109 | /* 110 | Retrieve arbitrary directory address 111 | 112 | IN: 113 | index - directory index 114 | 115 | RETURN: 116 | Directory address in memory 117 | 0 - if directory is not present 118 | */ 119 | size_t DirectoryAddress(int index) const; 120 | 121 | /* 122 | Retrieve arbitrary directory size 123 | 124 | IN: 125 | index - directory index 126 | 127 | RETURN: 128 | Directory size 129 | 0 - if directory is not present 130 | */ 131 | size_t DirectorySize( int index ) const; 132 | 133 | /* 134 | Pure IL image 135 | */ 136 | bool IsPureManaged() const; 137 | 138 | /* 139 | Image is exe file and not a dynamic-link library 140 | */ 141 | bool IsExe() const; 142 | 143 | private: 144 | bool m_isPlainData; // File mapped as plain data file 145 | const void *m_pFileBase; // File mapping base address 146 | const IMAGE_NT_HEADERS *m_pImageHdr; // PE header info 147 | std::vector m_sections; // Section info 148 | }; 149 | } 150 | } 151 | 152 | 153 | -------------------------------------------------------------------------------- /Process.h: -------------------------------------------------------------------------------- 1 | #ifndef _PROCESS_H_ 2 | #define _PROCESS_H_ 3 | 4 | #include "stdafx.h" 5 | #include "MemCore.h" 6 | #include "MemModules.h" 7 | #include "VADPurge/VADPurgeDef.h" 8 | 9 | #include 10 | 11 | namespace ds_mmap 12 | { 13 | namespace ds_process 14 | { 15 | #define FILE_DEVICE_DARKDEP 0x00008006 16 | #define IOCTL_DARKDEP_DISABLE_DEP CTL_CODE(FILE_DEVICE_DARKDEP, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) 17 | #define IOCTL_DARKDEP_SET_PROTECTION CTL_CODE(FILE_DEVICE_DARKDEP, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) 18 | 19 | #define DRV_NAME L"VADPurge" 20 | #define DRV_FILE L"VADPurge.sys" 21 | #define DRV_REG_PATH L"\\registry\\machine\\SYSTEM\\CurrentControlSet\\Services\\VADPurge" 22 | #define STATUS_IMAGE_ALREADY_LOADED ((NTSTATUS)0xC000010EL) 23 | 24 | extern "C" NTSYSAPI NTSTATUS NTAPI NtLoadDriver (__in PUNICODE_STRING DriverServiceName); 25 | extern "C" NTSYSAPI NTSTATUS NTAPI NtUnloadDriver (__in PUNICODE_STRING DriverServiceName); 26 | 27 | // Provides operations with process memory 28 | class CProcess 29 | { 30 | public: 31 | CProcess(); 32 | ~CProcess(void); 33 | 34 | /* 35 | Set working process 36 | 37 | IN: 38 | hProcess - handle to process 39 | dwModuleBase - address of main module 40 | 41 | OUT: 42 | void 43 | 44 | RETURN: 45 | void 46 | */ 47 | void Attach(DWORD pid, HANDLE hProcess = NULL); 48 | 49 | /* 50 | Return current process PID 51 | */ 52 | DWORD Pid(); 53 | 54 | /* 55 | Checks if process is still valid. (crash detection) 56 | 57 | RETURN: 58 | Validity flag 59 | */ 60 | bool IsValid(); 61 | 62 | /* 63 | Disable DEP for target process 64 | 65 | RETURN: 66 | Error code 67 | */ 68 | DWORD DisabeDEP(); 69 | 70 | /* 71 | Inject VEH wrapper into process 72 | Used to enable execution of SEH handlers out of image 73 | 74 | RETURN: 75 | Error code 76 | */ 77 | DWORD CreateVEH(size_t pTargetBase = 0, size_t imageSize = 0); 78 | 79 | /* 80 | Remove VEH wrapper from process 81 | 82 | RETURN: 83 | Error code 84 | */ 85 | DWORD RemoveVEH(); 86 | 87 | /* 88 | Unlink memory region from process VAD list 89 | 90 | IN: 91 | pBase - region base address 92 | size - region size 93 | 94 | RETURN: 95 | Error code 96 | */ 97 | DWORD UnlinkVad(void* pBase, size_t size); 98 | 99 | // 100 | // VEH to inject 101 | // 102 | #ifdef _M_AMD64 103 | static LONG CALLBACK VectoredHandler64( _In_ PEXCEPTION_POINTERS ExceptionInfo ); 104 | #else 105 | static LONG CALLBACK VectoredHandler32( _In_ PEXCEPTION_POINTERS ExceptionInfo ); 106 | #endif 107 | 108 | private: 109 | /* 110 | Load driver by name. Driver must reside in current working directory 111 | 112 | IN: 113 | name - driver filename 114 | 115 | RETURN: 116 | Error code 117 | 118 | */ 119 | DWORD LoadDriver(const std::wstring& name); 120 | 121 | /* 122 | Grant current process arbitrary privilege 123 | 124 | IN: 125 | name - privilege name 126 | 127 | RETURN: 128 | Error code 129 | */ 130 | DWORD GrantPriviledge( const std::wstring& name ); 131 | 132 | /* 133 | Get Handle of oldest existing thread in process 134 | */ 135 | DWORD GetMainThreadID(); 136 | 137 | public: 138 | CMemCore Core; // Process core memory routines 139 | CMemModules Modules; // Module routines 140 | 141 | // For debug purposes only 142 | static void* pImageBase; 143 | static size_t imageSize; 144 | 145 | private: 146 | void *m_pVEHCode; // VEH function codecave 147 | void *m_hVEH; // VEH handle 148 | }; 149 | } 150 | } 151 | #endif//_PROCESS_H_ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DarkMMap 2 | ======== 3 | 4 | Manual PE image mapper 5 | 6 | Supported features: 7 | 8 | - x86 and x64 image support 9 | - Mapping into any arbitrary unprotected process 10 | - Section mapping with proper memory protection flags 11 | - Image relocations (only 2 types supported. I haven't seen a single PE image with some other relocation types) 12 | - Imports are resolved*** 13 | - Delayed imports can be resolved*** 14 | - Bound import is resolved as a side effect, I think 15 | - Module exports 16 | - Loading of forwarded export images 17 | - Api schema name redirection 18 | - SxS redirection and isolation 19 | - Activation context support 20 | - Dll path resolving similar to native load order 21 | - TLS callbacks* 22 | - Static TLS data, sort of** 23 | - Exception handling support (SEH and C++), needs more testing though, but seems reliable 24 | - Adding module to some native loader structures(for basic module api support: GetModuleHandle, GetProcAdress, etc.) 25 | - Security cookie initialization 26 | - C++/CLI images can be mapped (this needs adding module to native structures) 27 | - Image unloading 28 | - Increase reference counter for import libraries in case of manual import mapping*** 29 | - Unlink image VAD entry**** 30 | 31 | Things it can't do yet: 32 | 33 | - Trace module dependencies during unload 34 | - Remove module from native loader structures upon unload 35 | - Lots of other things I don't know about or forgot 36 | 37 | * TLS callback are only executed for one thread with DLL_PROCESS_ATTACH and DLL_PROCESS_DETACH reasons during image loading and unloading respectively. 38 | 39 | ** Implemented using native LdrpHandleTlsData call. Official documentation also says that you shouldn't load images with static TLS dynamically (LoadLibrary). 40 | 41 | *** Imports and all dependencies can be mapped either manually or by native loader. In case of manual mapping circular dependencies are handled properly. 42 | 43 | **** Ring 0, for fun only, supported Win7 and Win8. Win8 has floating BSOD bug upon target process exit(MmDeleteProcessAddressSpace); haven't figured it out yet. -------------------------------------------------------------------------------- /VADPurge/NativeStructs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define VAD_TAG ' daV' 4 | #define VAD_SHORT_TAG 'SdaV' 5 | #define VAD_LONG_TAG 'ldaV' 6 | 7 | #ifdef _WIN8_ 8 | #include "NativeStructs8.h" 9 | #elif _WIN7_ 10 | #include "NativeStructs7.h" 11 | #else 12 | #error Unsupported OS build version 13 | #endif -------------------------------------------------------------------------------- /VADPurge/PrivateRoutines.h: -------------------------------------------------------------------------------- 1 | #include "ntifs.h" 2 | #include "NativeStructs.h" 3 | 4 | // Debugging macro 5 | #ifdef DBG 6 | #define DPRINT(format, ...) DbgPrint(format, __VA_ARGS__)//VPTrace(__VA_ARGS__); 7 | #else 8 | #define DPRINT(...) 9 | #endif 10 | 11 | #define SANITIZE_PARENT_NODE(Parent) ((PMMADDRESS_NODE)(((ULONG_PTR)(Parent)) & ~0x3)) 12 | 13 | // 14 | // Various Rtl macros that reference Parent use private versions here since 15 | // Parent is overloaded with Balance. 16 | // 17 | 18 | // 19 | // The macro function Parent takes as input a pointer to a splay link in a 20 | // tree and returns a pointer to the splay link of the parent of the input 21 | // node. If the input node is the root of the tree the return value is 22 | // equal to the input value. 23 | // 24 | // PRTL_SPLAY_LINKS 25 | // MiParent ( 26 | // PRTL_SPLAY_LINKS Links 27 | // ); 28 | // 29 | 30 | #define MiParent(Links) ( \ 31 | (PRTL_SPLAY_LINKS)(SANITIZE_PARENT_NODE((Links)->u1.Parent)) \ 32 | ) 33 | 34 | // 35 | // The macro function IsLeftChild takes as input a pointer to a splay link 36 | // in a tree and returns TRUE if the input node is the left child of its 37 | // parent, otherwise it returns FALSE. 38 | // 39 | // BOOLEAN 40 | // MiIsLeftChild ( 41 | // PRTL_SPLAY_LINKS Links 42 | // ); 43 | // 44 | 45 | #define MiIsLeftChild(Links) ( \ 46 | (RtlLeftChild(MiParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) \ 47 | ) 48 | 49 | // 50 | // The macro function IsRightChild takes as input a pointer to a splay link 51 | // in a tree and returns TRUE if the input node is the right child of its 52 | // parent, otherwise it returns FALSE. 53 | // 54 | // BOOLEAN 55 | // MiIsRightChild ( 56 | // PRTL_SPLAY_LINKS Links 57 | // ); 58 | // 59 | 60 | #define MiIsRightChild(Links) ( \ 61 | (RtlRightChild(MiParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) \ 62 | ) 63 | 64 | #define MI_MAKE_PARENT(ParentNode, ExistingBalance) \ 65 | (PMMADDRESS_NODE)((ULONG_PTR)(ParentNode) | (((ULONG_PTR)ExistingBalance) & 0x3)) 66 | 67 | #define COUNT_BALANCE_MAX(a) 68 | 69 | VOID MiPromoteNode ( IN PMMADDRESS_NODE C ); 70 | ULONG MiRebalanceNode ( IN PMMADDRESS_NODE S ); 71 | VOID MiInsertNode ( IN PMMADDRESS_NODE NodeToInsert, IN PMM_AVL_TABLE Table ); 72 | VOID MiRemoveNode ( IN PMMADDRESS_NODE NodeToDelete, IN PMM_AVL_TABLE Table ); 73 | 74 | TABLE_SEARCH_RESULT MiFindNodeOrParent ( IN PMM_AVL_TABLE Table, IN ULONG_PTR StartingVpn, OUT PMMADDRESS_NODE *NodeOrParent ); 75 | -------------------------------------------------------------------------------- /VADPurge/VADPurge.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /VADPurge/VADPurge.h: -------------------------------------------------------------------------------- 1 | #ifndef _VAD_PURGE_H_ 2 | #define _VAD_PURGE_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "VADPurgeDef.h" 8 | #include "PrivateRoutines.h" 9 | 10 | #define DEVICE_NAME L"\\Device\\VadPurge" 11 | #define DOS_DEVICE_NAME L"\\DosDevices\\VADPURGE" 12 | 13 | 14 | typedef struct _OFST_DEF 15 | { 16 | ULONG ofsVadRoot; 17 | 18 | }OFST_DEF, *POFST_DEF; 19 | 20 | 21 | #endif// _VAD_PURGE_H_ -------------------------------------------------------------------------------- /VADPurge/VADPurge.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VADPurge", "VADPurge.vcxproj", "{50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Win7 Debug|Win32 = Win7 Debug|Win32 9 | Win7 Debug|x64 = Win7 Debug|x64 10 | Win7 Release|Win32 = Win7 Release|Win32 11 | Win7 Release|x64 = Win7 Release|x64 12 | Win8 Debug|Win32 = Win8 Debug|Win32 13 | Win8 Debug|x64 = Win8 Debug|x64 14 | Win8 Release|Win32 = Win8 Release|Win32 15 | Win8 Release|x64 = Win8 Release|x64 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32 19 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32 20 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Debug|Win32.Deploy.0 = Win7 Debug|Win32 21 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64 22 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Debug|x64.Build.0 = Win7 Debug|x64 23 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64 24 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32 25 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Release|Win32.Build.0 = Win7 Release|Win32 26 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Release|Win32.Deploy.0 = Win7 Release|Win32 27 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Release|x64.ActiveCfg = Win7 Release|x64 28 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Release|x64.Build.0 = Win7 Release|x64 29 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win7 Release|x64.Deploy.0 = Win7 Release|x64 30 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32 31 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32 32 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32 33 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 34 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 35 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 36 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32 37 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Release|Win32.Build.0 = Win8 Release|Win32 38 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32 39 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 40 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Release|x64.Build.0 = Win8 Release|x64 41 | {50429DDC-D8EC-4926-B913-D7ADE6A3DC9F}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | EndGlobal 47 | -------------------------------------------------------------------------------- /VADPurge/VADPurge.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WindowsLocalDebugger 5 | 127.0.0.1 6 | 7 | 8 | 127.0.0.1 9 | 10 | 11 | 127.0.0.1 12 | 13 | 14 | 127.0.0.1 15 | 16 | 17 | 127.0.0.1 18 | 19 | 20 | 127.0.0.1 21 | 22 | 23 | 127.0.0.1 24 | 25 | 26 | 127.0.0.1 27 | 28 | 29 | 127.0.0.1 30 | CN="WDKTestCert Ton,129965339864496255" | C09E6BCF77E9292204609B6EF8288506CE7B4CCC 31 | 32 | 33 | 127.0.0.1 34 | 35 | 36 | 127.0.0.1 37 | 38 | 39 | 127.0.0.1 40 | 41 | -------------------------------------------------------------------------------- /VADPurge/VADPurge.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Native 7 | 8 | 9 | 10 | 11 | 12 | 13 | Native 14 | 15 | 16 | Native 17 | 18 | 19 | Native 20 | 21 | 22 | Native 23 | 24 | 25 | 26 | 27 | {b4a40495-5f40-4e82-8d44-02a6e8a2a1f6} 28 | 29 | 30 | -------------------------------------------------------------------------------- /VADPurge/VADPurge.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | DbgengRemoteDebugger 5 | 10.0.2.15 6 | 7 | 8 | 10.0.2.15 9 | 10 | 11 | 10.0.2.15 12 | 13 | 14 | 10.0.2.15 15 | 16 | 17 | 10.0.2.15 18 | 19 | 20 | 10.0.2.15 21 | 22 | 23 | 10.0.2.15 24 | 25 | 26 | 10.0.2.15 27 | 28 | 29 | 10.0.2.15 30 | 31 | 32 | 10.0.2.15 33 | 34 | 35 | 10.0.2.15 36 | 37 | 38 | 10.0.2.15 39 | 40 | -------------------------------------------------------------------------------- /VADPurge/VADPurgeDef.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define FILE_DEVICE_VADPURGE 0x00008013 4 | #define IOCTL_VADPURGE_PURGE CTL_CODE(FILE_DEVICE_VADPURGE, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) 5 | 6 | typedef struct _VmRegionEntry 7 | { 8 | unsigned long long startAddr; 9 | unsigned long long size; 10 | 11 | } VmRegionEntry, PVmRegionEntry; 12 | 13 | typedef struct _PURGE_DATA 14 | { 15 | int procID; 16 | int numOfEntries; 17 | VmRegionEntry entries[1]; 18 | 19 | } PURGE_DATA, *PPURGE_DATA; -------------------------------------------------------------------------------- /stdafx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | 5 | #include "targetver.h" 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include "Errors.h" 17 | 18 | #define MAKE_PTR(T, pRVA, base) (T)((size_t)pRVA + (size_t)base) 19 | #define REBASE(pRVA, baseOld, baseNew) ((size_t)pRVA - (size_t)baseOld + (size_t)baseNew) 20 | 21 | -------------------------------------------------------------------------------- /targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // The following macros define the minimum required platform. The minimum required platform 4 | // is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run 5 | // your application. The macros work by enabling all features available on platform versions up to and 6 | // including the version specified. 7 | 8 | // Modify the following defines if you have to target a platform prior to the ones specified below. 9 | // Refer to MSDN for the latest info on corresponding values for different platforms. 10 | #ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. 11 | #define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. 12 | #endif 13 | 14 | --------------------------------------------------------------------------------