├── SelfHackingApp ├── SelfHackingApp.cpp ├── External │ ├── Readme.txt │ ├── asmtk │ │ ├── asmtk.h │ │ ├── globals.h │ │ ├── strtod.h │ │ ├── parserutils.h │ │ ├── asmparser.h │ │ ├── asmtokenizer.h │ │ └── elfdefs.h │ ├── asmjit │ │ ├── x86.h │ │ ├── core │ │ │ ├── target.cpp │ │ │ ├── type.cpp │ │ │ ├── callconv.cpp │ │ │ ├── misc_p.h │ │ │ ├── cpuinfo.cpp │ │ │ ├── osutils.h │ │ │ ├── osutils.cpp │ │ │ ├── zonetree.cpp │ │ │ ├── zonestring.h │ │ │ ├── jitruntime.h │ │ │ ├── operand.cpp │ │ │ ├── globals.cpp │ │ │ ├── func.cpp │ │ │ ├── inst.cpp │ │ │ ├── features.h │ │ │ ├── zonelist.cpp │ │ │ ├── cpuinfo.h │ │ │ ├── jitruntime.cpp │ │ │ ├── virtmem.h │ │ │ ├── rastack_p.h │ │ │ ├── codebufferwriter_p.h │ │ │ ├── zonelist.h │ │ │ ├── zonehash.cpp │ │ │ ├── arch.cpp │ │ │ ├── assembler.h │ │ │ ├── zonehash.h │ │ │ ├── zonestack.cpp │ │ │ └── rastack.cpp │ │ ├── x86 │ │ │ ├── x86callconv_p.h │ │ │ ├── x86instapi_p.h │ │ │ ├── x86logging_p.h │ │ │ ├── x86builder.h │ │ │ ├── x86builder.cpp │ │ │ ├── x86compiler.cpp │ │ │ ├── x86assembler.h │ │ │ ├── x86internal_p.h │ │ │ ├── x86rapass_p.h │ │ │ └── x86callconv.cpp │ │ ├── asmjit.h │ │ └── core.h │ └── libudis86 │ │ ├── udis86.h │ │ ├── syn.h │ │ ├── udint.h │ │ ├── extern.h │ │ ├── decode.h │ │ └── syn-att.c ├── StrUtils.h ├── HackUtils.h ├── StrUtils.cpp ├── HackableCode.h └── HackableCode.cpp ├── README.md ├── .gitattributes ├── .gitignore └── SelfHackingApp.sln /SelfHackingApp/SelfHackingApp.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Squalr/Self-Modifying-Code/HEAD/SelfHackingApp/SelfHackingApp.cpp -------------------------------------------------------------------------------- /SelfHackingApp/External/Readme.txt: -------------------------------------------------------------------------------- 1 | This folder contains repositories pulled in from source. While some of these could be managed via vcpkg, in our experience vcpkg is unreliable and finnicky. The less being managed by vcpkg, the better. 2 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmtk/asmtk.h: -------------------------------------------------------------------------------- 1 | // [AsmTk] 2 | // Assembler toolkit based on AsmJit. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMTK_ASMTK_H 8 | #define _ASMTK_ASMTK_H 9 | 10 | #include "./globals.h" 11 | 12 | #include "./asmparser.h" 13 | #include "./asmtokenizer.h" 14 | #include "./elfdefs.h" 15 | 16 | #endif // _ASMTK_ASMTK_H 17 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/x86.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_X86_H 8 | #define _ASMJIT_X86_H 9 | 10 | //! \defgroup asmjit_x86 X86 11 | //! 12 | //! \brief X86/X64 Backend. 13 | 14 | #include "./core.h" 15 | 16 | #include "./x86/x86assembler.h" 17 | #include "./x86/x86builder.h" 18 | #include "./x86/x86compiler.h" 19 | #include "./x86/x86emitter.h" 20 | #include "./x86/x86features.h" 21 | #include "./x86/x86globals.h" 22 | #include "./x86/x86instdb.h" 23 | #include "./x86/x86operand.h" 24 | 25 | #endif // _ASMJIT_X86_H 26 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/target.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/target.h" 10 | 11 | ASMJIT_BEGIN_NAMESPACE 12 | 13 | // ============================================================================ 14 | // [asmjit::Target - Construction / Destruction] 15 | // ============================================================================ 16 | 17 | Target::Target() noexcept 18 | : _targetType(kTargetNone), 19 | _codeInfo() {} 20 | Target::~Target() noexcept {} 21 | 22 | ASMJIT_END_NAMESPACE 23 | -------------------------------------------------------------------------------- /SelfHackingApp/StrUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class StrUtils 6 | { 7 | public: 8 | static bool isInteger(std::string str); 9 | static std::string ltrim(std::string str, std::string toRemove, bool ignoreCase = false); 10 | static std::string rtrim(std::string str, std::string toRemove, bool ignoreCase = false); 11 | static bool startsWith(std::string str, std::string prefix, bool ignoreCase); 12 | static bool endsWith(std::string str, std::string suffix, bool ignoreCase); 13 | static bool isRegexSubMatch(const std::string str, const std::string regex); 14 | static int hexToInt(std::string str); 15 | static bool isHexNumber(std::string str); 16 | static std::string replaceAll(std::string str, const std::string& from, const std::string& to); 17 | }; 18 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/type.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/misc_p.h" 10 | #include "../core/type.h" 11 | 12 | ASMJIT_BEGIN_NAMESPACE 13 | 14 | // ============================================================================ 15 | // [asmjit::Type] 16 | // ============================================================================ 17 | 18 | const Type::TypeData Type::_typeData = { 19 | #define VALUE(X) Type::BaseOfTypeId::kTypeId 20 | { ASMJIT_LOOKUP_TABLE_256(VALUE, 0) }, 21 | #undef VALUE 22 | 23 | #define VALUE(X) Type::SizeOfTypeId::kTypeSize 24 | { ASMJIT_LOOKUP_TABLE_256(VALUE, 0) } 25 | #undef VALUE 26 | }; 27 | 28 | ASMJIT_END_NAMESPACE 29 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/x86/x86callconv_p.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_X86_X86CALLCONV_P_H 8 | #define _ASMJIT_X86_X86CALLCONV_P_H 9 | 10 | #include "../core/callconv.h" 11 | 12 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 13 | 14 | //! \cond INTERNAL 15 | //! \addtogroup asmjit_x86 16 | //! \{ 17 | 18 | // ============================================================================ 19 | // [asmjit::x86::CallConvInternal] 20 | // ============================================================================ 21 | 22 | //! X86-specific function API (calling conventions and other utilities). 23 | namespace CallConvInternal { 24 | //! Initialize `CallConv` structure (X86 specific). 25 | Error init(CallConv& cc, uint32_t ccId) noexcept; 26 | } 27 | 28 | //! \} 29 | //! \endcond 30 | 31 | ASMJIT_END_SUB_NAMESPACE 32 | 33 | #endif // _ASMJIT_X86_X86CALLCONV_P_H 34 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/asmjit.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_ASMJIT_H 8 | #define _ASMJIT_ASMJIT_H 9 | 10 | //! \mainpage API Reference 11 | //! 12 | //! AsmJit C++ API reference documentation generated by Doxygen. 13 | //! 14 | //! Introduction provided by the project page at https://github.com/asmjit/asmjit. 15 | //! 16 | //! \section main_groups Groups 17 | //! 18 | //! The documentation is split into the following groups: 19 | //! 20 | //! $$DOCS_GROUP_OVERVIEW$$ 21 | //! 22 | //! \section main_other Other Pages 23 | //! 24 | //! - Class List - List of classes sorted alphabetically 25 | //! - AsmJit Namespace - List of symbols provided by `asmjit` namespace 26 | 27 | //! \namespace asmjit 28 | //! 29 | //! Root namespace used by AsmJit. 30 | 31 | #include "./core.h" 32 | 33 | #ifdef ASMJIT_BUILD_X86 34 | #include "./x86.h" 35 | #endif 36 | 37 | #ifdef ASMJIT_BUILD_ARM 38 | #include "./arm.h" 39 | #endif 40 | 41 | #endif // _ASMJIT_ASMJIT_H 42 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/callconv.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/arch.h" 10 | #include "../core/func.h" 11 | #include "../core/type.h" 12 | 13 | #ifdef ASMJIT_BUILD_X86 14 | #include "../x86/x86callconv_p.h" 15 | #endif 16 | 17 | #ifdef ASMJIT_BUILD_ARM 18 | #include "../arm/armcallconv_p.h" 19 | #endif 20 | 21 | ASMJIT_BEGIN_NAMESPACE 22 | 23 | // ============================================================================ 24 | // [asmjit::CallConv - Init / Reset] 25 | // ============================================================================ 26 | 27 | ASMJIT_FAVOR_SIZE Error CallConv::init(uint32_t ccId) noexcept { 28 | reset(); 29 | 30 | #ifdef ASMJIT_BUILD_X86 31 | if (CallConv::isX86Family(ccId)) 32 | return x86::CallConvInternal::init(*this, ccId); 33 | #endif 34 | 35 | #ifdef ASMJIT_BUILD_ARM 36 | if (CallConv::isArmFamily(ccId)) 37 | return arm::CallConvInternal::init(*this, ccId); 38 | #endif 39 | 40 | return DebugUtils::errored(kErrorInvalidArgument); 41 | } 42 | 43 | ASMJIT_END_NAMESPACE 44 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/misc_p.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_MISC_P_H 8 | #define _ASMJIT_CORE_MISC_P_H 9 | 10 | #include "../core/build.h" 11 | 12 | ASMJIT_BEGIN_NAMESPACE 13 | 14 | //! \cond INTERNAL 15 | //! \addtogroup asmjit_support 16 | //! \{ 17 | 18 | #define ASMJIT_LOOKUP_TABLE_8(T, I) T((I)), T((I+1)), T((I+2)), T((I+3)), T((I+4)), T((I+5)), T((I+6)), T((I+7)) 19 | #define ASMJIT_LOOKUP_TABLE_16(T, I) ASMJIT_LOOKUP_TABLE_8(T, I), ASMJIT_LOOKUP_TABLE_8(T, I + 8) 20 | #define ASMJIT_LOOKUP_TABLE_32(T, I) ASMJIT_LOOKUP_TABLE_16(T, I), ASMJIT_LOOKUP_TABLE_16(T, I + 16) 21 | #define ASMJIT_LOOKUP_TABLE_64(T, I) ASMJIT_LOOKUP_TABLE_32(T, I), ASMJIT_LOOKUP_TABLE_32(T, I + 32) 22 | #define ASMJIT_LOOKUP_TABLE_128(T, I) ASMJIT_LOOKUP_TABLE_64(T, I), ASMJIT_LOOKUP_TABLE_64(T, I + 64) 23 | #define ASMJIT_LOOKUP_TABLE_256(T, I) ASMJIT_LOOKUP_TABLE_128(T, I), ASMJIT_LOOKUP_TABLE_128(T, I + 128) 24 | #define ASMJIT_LOOKUP_TABLE_512(T, I) ASMJIT_LOOKUP_TABLE_256(T, I), ASMJIT_LOOKUP_TABLE_256(T, I + 256) 25 | #define ASMJIT_LOOKUP_TABLE_1024(T, I) ASMJIT_LOOKUP_TABLE_512(T, I), ASMJIT_LOOKUP_TABLE_512(T, I + 512) 26 | 27 | //! \} 28 | //! \endcond 29 | 30 | ASMJIT_END_NAMESPACE 31 | 32 | #endif // _ASMJIT_CORE_MISC_P_H 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SelfHackingApp 2 | This repo contains an example of how to create self-modifying code in C++. This works by allowing code to rewrite itself using injected x86/x64 assembly instructions. 3 | 4 | This code is 100% cross-platform, however this repo is currently only set up for Widows + Visual Studio. I wrote about this repo here: https://medium.com/squallygame/how-we-wrote-a-self-hacking-game-in-c-d8b9f97bfa99 5 | 6 | Feel free to submit a pull request with a CMake solution that works on Linux/OSX/Windows. 7 | 8 | ## Example: 9 | ```cpp 10 | NO_OPTIMIZE 11 | int hackableRoutineTakeDamage(int health, int damage) 12 | { 13 | // This is the code we want to be hackable by the user 14 | HACKABLE_CODE_BEGIN(); 15 | health -= damage; 16 | HACKABLE_CODE_END(); 17 | 18 | HACKABLES_STOP_SEARCH(); 19 | 20 | if (health < 0) 21 | { 22 | health = 0; 23 | } 24 | 25 | return health; 26 | } 27 | END_NO_OPTIMIZE 28 | ``` 29 | 30 | Which can be modified via: 31 | ```cpp 32 | auto funcPtr = &hackableRoutineTakeDamage; 33 | std::vector hackables = HackableCode::create((void*&)funcPtr); 34 | 35 | HackableCode* hackableCode = hackables[0]; 36 | 37 | // Disable taking damage by injecting a 'nop' over the original 'health -= damage;' code. Remaining bytes are filled with 'nops' 38 | hackableCode->applyCustomCode("nop") 39 | ``` 40 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/x86/x86instapi_p.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_X86_X86INSTAPI_P_H 8 | #define _ASMJIT_X86_X86INSTAPI_P_H 9 | 10 | #include "../core/inst.h" 11 | #include "../core/operand.h" 12 | 13 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 14 | 15 | //! \cond INTERNAL 16 | //! \addtogroup asmjit_x86 17 | //! \{ 18 | 19 | namespace InstInternal { 20 | 21 | #ifndef ASMJIT_NO_TEXT 22 | Error instIdToString(uint32_t archId, uint32_t instId, String& output) noexcept; 23 | uint32_t stringToInstId(uint32_t archId, const char* s, size_t len) noexcept; 24 | #endif // !ASMJIT_NO_TEXT 25 | 26 | #ifndef ASMJIT_NO_VALIDATION 27 | Error validate(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount) noexcept; 28 | #endif // !ASMJIT_NO_VALIDATION 29 | 30 | #ifndef ASMJIT_NO_INTROSPECTION 31 | Error queryRWInfo(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount, InstRWInfo& out) noexcept; 32 | Error queryFeatures(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount, BaseFeatures& out) noexcept; 33 | #endif // !ASMJIT_NO_INTROSPECTION 34 | 35 | } // {InstInternal} 36 | 37 | //! \} 38 | //! \endcond 39 | 40 | ASMJIT_END_SUB_NAMESPACE 41 | 42 | #endif // _ASMJIT_X86_X86INSTAPI_P_H 43 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/x86/x86logging_p.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_X86_X86LOGGING_P_H 8 | #define _ASMJIT_X86_X86LOGGING_P_H 9 | 10 | #include "../core/build.h" 11 | #ifndef ASMJIT_NO_LOGGING 12 | 13 | #include "../core/logging.h" 14 | #include "../core/string.h" 15 | #include "../x86/x86globals.h" 16 | 17 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 18 | 19 | //! \addtogroup asmjit_x86 20 | //! \{ 21 | 22 | // ============================================================================ 23 | // [asmjit::x86::LoggingInternal] 24 | // ============================================================================ 25 | 26 | namespace LoggingInternal { 27 | Error formatRegister( 28 | String& sb, 29 | uint32_t flags, 30 | const BaseEmitter* emitter, 31 | uint32_t archId, 32 | uint32_t regType, 33 | uint32_t regId) noexcept; 34 | 35 | Error formatOperand( 36 | String& sb, 37 | uint32_t flags, 38 | const BaseEmitter* emitter, 39 | uint32_t archId, 40 | const Operand_& op) noexcept; 41 | 42 | Error formatInstruction( 43 | String& sb, 44 | uint32_t flags, 45 | const BaseEmitter* emitter, 46 | uint32_t archId, 47 | const BaseInst& inst, const Operand_* operands, uint32_t opCount) noexcept; 48 | }; 49 | 50 | //! \} 51 | 52 | ASMJIT_END_SUB_NAMESPACE 53 | 54 | #endif // !ASMJIT_NO_LOGGING 55 | #endif // _ASMJIT_X86_X86LOGGING_P_H 56 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/x86/x86builder.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_X86_X86BUILDER_H 8 | #define _ASMJIT_X86_X86BUILDER_H 9 | 10 | #include "../core/build.h" 11 | #ifndef ASMJIT_NO_BUILDER 12 | 13 | #include "../core/builder.h" 14 | #include "../core/datatypes.h" 15 | #include "../x86/x86emitter.h" 16 | 17 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 18 | 19 | //! \addtogroup asmjit_x86 20 | //! \{ 21 | 22 | // ============================================================================ 23 | // [asmjit::x86::Builder] 24 | // ============================================================================ 25 | 26 | //! Architecture-dependent asm-builder (X86). 27 | class ASMJIT_VIRTAPI Builder 28 | : public BaseBuilder, 29 | public EmitterImplicitT { 30 | public: 31 | ASMJIT_NONCOPYABLE(Builder) 32 | typedef BaseBuilder Base; 33 | 34 | //! \name Construction & Destruction 35 | //! \{ 36 | 37 | ASMJIT_API explicit Builder(CodeHolder* code = nullptr) noexcept; 38 | ASMJIT_API virtual ~Builder() noexcept; 39 | 40 | //! \} 41 | 42 | //! \name Finalize 43 | //! \{ 44 | 45 | ASMJIT_API Error finalize() override; 46 | 47 | //! \} 48 | 49 | //! \name Events 50 | //! \{ 51 | 52 | ASMJIT_API Error onAttach(CodeHolder* code) noexcept override; 53 | 54 | //! \} 55 | }; 56 | 57 | //! \} 58 | 59 | ASMJIT_END_SUB_NAMESPACE 60 | 61 | #endif // !ASMJIT_NO_BUILDER 62 | #endif // _ASMJIT_X86_X86BUILDER_H 63 | -------------------------------------------------------------------------------- /SelfHackingApp/External/libudis86/udis86.h: -------------------------------------------------------------------------------- 1 | /* udis86 - udis86.h 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UDIS86_H 27 | #define UDIS86_H 28 | 29 | #include "types.h" 30 | #include "extern.h" 31 | #include "itab.h" 32 | 33 | #endif -------------------------------------------------------------------------------- /SelfHackingApp/External/asmtk/globals.h: -------------------------------------------------------------------------------- 1 | // [AsmTk] 2 | // Assembler toolkit based on AsmJit. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMTK_GLOBALS_H 8 | #define _ASMTK_GLOBALS_H 9 | 10 | #include "../asmjit/asmjit.h" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define ASMTK_STATIC 18 | 19 | // DEPRECATED: Will be removed in the future. 20 | #if defined(ASMTK_BUILD_STATIC) 21 | #pragma message("'ASMTK_BUILD_STATIC' is deprecated, use 'ASMTK_STATIC'") 22 | #if !defined(ASMTK_STATIC) 23 | #define ASMTK_STATIC 24 | #endif 25 | #endif 26 | 27 | // API (Export / Import). 28 | #if !defined(ASMTK_STATIC) 29 | #if defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__)) 30 | #if defined(ASMTK_EXPORTS) 31 | #define ASMTK_API __declspec(dllexport) 32 | #else 33 | #define ASMTK_API __declspec(dllimport) 34 | #endif 35 | #elif defined(_WIN32) && defined(__GNUC__) 36 | #if defined(ASMTK_EXPORTS) 37 | #define ASMTK_API __attribute__((__dllexport__)) 38 | #else 39 | #define ASMTK_API __attribute__((__dllimport__)) 40 | #endif 41 | #elif defined(__GNUC__) 42 | #define ASMTK_API __attribute__((__visibility__("default"))) 43 | #endif 44 | #endif 45 | 46 | #if !defined(ASMTK_API) 47 | #define ASMTK_API 48 | #endif 49 | 50 | namespace asmtk { 51 | 52 | // ============================================================================ 53 | // [asmtk::Types] 54 | // ============================================================================ 55 | 56 | using asmjit::Error; 57 | 58 | } // {asmtk} 59 | 60 | #endif // _ASMTK_GLOBALS_H 61 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/x86/x86builder.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/build.h" 10 | #if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_NO_COMPILER) 11 | 12 | #include "../x86/x86assembler.h" 13 | #include "../x86/x86builder.h" 14 | 15 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 16 | 17 | // ============================================================================ 18 | // [asmjit::x86::Builder - Construction / Destruction] 19 | // ============================================================================ 20 | 21 | Builder::Builder(CodeHolder* code) noexcept : BaseBuilder() { 22 | if (code) 23 | code->attach(this); 24 | } 25 | Builder::~Builder() noexcept {} 26 | 27 | // ============================================================================ 28 | // [asmjit::x86::Builder - Finalize] 29 | // ============================================================================ 30 | 31 | Error Builder::finalize() { 32 | ASMJIT_PROPAGATE(runPasses()); 33 | Assembler a(_code); 34 | return serialize(&a); 35 | } 36 | 37 | // ============================================================================ 38 | // [asmjit::x86::Builder - Events] 39 | // ============================================================================ 40 | 41 | Error Builder::onAttach(CodeHolder* code) noexcept { 42 | uint32_t archId = code->archId(); 43 | if (!ArchInfo::isX86Family(archId)) 44 | return DebugUtils::errored(kErrorInvalidArch); 45 | 46 | ASMJIT_PROPAGATE(Base::onAttach(code)); 47 | 48 | _gpRegInfo.setSignature(archId == ArchInfo::kIdX86 ? uint32_t(Gpd::kSignature) : uint32_t(Gpq::kSignature)); 49 | return kErrorOk; 50 | } 51 | 52 | ASMJIT_END_SUB_NAMESPACE 53 | 54 | #endif // ASMJIT_BUILD_X86 && !ASMJIT_NO_COMPILER 55 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmtk/strtod.h: -------------------------------------------------------------------------------- 1 | // [AsmTk] 2 | // Assembler toolkit based on AsmJit. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMTK_STRTOD_H 8 | #define _ASMTK_STRTOD_H 9 | 10 | #include "./globals.h" 11 | 12 | #if defined(_WIN32) 13 | #define ASMTK_STRTOD_MSLOCALE 14 | #include 15 | #include 16 | #else 17 | #define ASMTK_STRTOD_XLOCALE 18 | #include 19 | #include 20 | // xlocale.h is not available on Linux anymore, it uses . 21 | #if defined(__APPLE__ ) || \ 22 | defined(__bsdi__ ) || \ 23 | defined(__DragonFly__) || \ 24 | defined(__FreeBSD__ ) || \ 25 | defined(__NetBSD__ ) || \ 26 | defined(__OpenBSD__ ) 27 | #include 28 | #endif 29 | #endif 30 | 31 | namespace asmtk { 32 | 33 | // ============================================================================ 34 | // [asmtk::StrToD] 35 | // ============================================================================ 36 | 37 | class StrToD { 38 | public: 39 | #if defined(ASMTK_STRTOD_MSLOCALE) 40 | inline StrToD() { handle = _create_locale(LC_ALL, "C"); } 41 | inline ~StrToD() { _free_locale(handle); } 42 | 43 | inline bool isOk() const { return handle != NULL; } 44 | inline double conv(const char* s, char** end) const { return _strtod_l(s, end, handle); } 45 | 46 | _locale_t handle; 47 | #elif defined(ASMTK_STRTOD_XLOCALE) 48 | inline StrToD() { handle = newlocale(LC_ALL_MASK, "C", NULL); } 49 | inline ~StrToD() { freelocale(handle); } 50 | 51 | inline bool isOk() const { return handle != NULL; } 52 | inline double conv(const char* s, char** end) const { return strtod_l(s, end, handle); } 53 | 54 | locale_t handle; 55 | #else 56 | // Time bomb! 57 | inline bool isOk() const { return true; } 58 | inline double conv(const char* s, char** end) const { return strtod(s, end); } 59 | #endif 60 | }; 61 | 62 | } // {asmtk} 63 | 64 | #endif // _ASMTK_STRTOD_H 65 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/x86/x86compiler.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/build.h" 10 | #if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_NO_COMPILER) 11 | 12 | #include "../x86/x86assembler.h" 13 | #include "../x86/x86compiler.h" 14 | #include "../x86/x86rapass_p.h" 15 | 16 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 17 | 18 | // ============================================================================ 19 | // [asmjit::x86::Compiler - Construction / Destruction] 20 | // ============================================================================ 21 | 22 | Compiler::Compiler(CodeHolder* code) noexcept : BaseCompiler() { 23 | if (code) 24 | code->attach(this); 25 | } 26 | Compiler::~Compiler() noexcept {} 27 | 28 | // ============================================================================ 29 | // [asmjit::x86::Compiler - Finalize] 30 | // ============================================================================ 31 | 32 | Error Compiler::finalize() { 33 | ASMJIT_PROPAGATE(runPasses()); 34 | Assembler a(_code); 35 | return serialize(&a); 36 | } 37 | // ============================================================================ 38 | // [asmjit::x86::Compiler - Events] 39 | // ============================================================================ 40 | 41 | Error Compiler::onAttach(CodeHolder* code) noexcept { 42 | uint32_t archId = code->archId(); 43 | if (!ArchInfo::isX86Family(archId)) 44 | return DebugUtils::errored(kErrorInvalidArch); 45 | 46 | ASMJIT_PROPAGATE(Base::onAttach(code)); 47 | _gpRegInfo.setSignature(archId == ArchInfo::kIdX86 ? uint32_t(Gpd::kSignature) : uint32_t(Gpq::kSignature)); 48 | 49 | Error err = addPassT(); 50 | if (ASMJIT_UNLIKELY(err)) { 51 | onDetach(code); 52 | return err; 53 | } 54 | 55 | return kErrorOk; 56 | } 57 | 58 | ASMJIT_END_SUB_NAMESPACE 59 | 60 | #endif // ASMJIT_BUILD_X86 && !ASMJIT_NO_COMPILER 61 | -------------------------------------------------------------------------------- /SelfHackingApp/External/libudis86/syn.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/syn.h 2 | * 3 | * Copyright (c) 2002-2009 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_SYN_H 27 | #define UD_SYN_H 28 | 29 | #include "types.h" 30 | #ifndef __UD_STANDALONE__ 31 | # include 32 | #endif /* __UD_STANDALONE__ */ 33 | 34 | extern const char* ud_reg_tab[]; 35 | 36 | uint64_t ud_syn_rel_target(struct ud*, struct ud_operand*); 37 | 38 | #ifdef __GNUC__ 39 | int ud_asmprintf(struct ud *u, const char *fmt, ...) 40 | __attribute__((format(printf, 2, 3))); 41 | #else 42 | int ud_asmprintf(struct ud *u, const char *fmt, ...); 43 | #endif 44 | 45 | void ud_syn_print_addr(struct ud *u, uint64_t addr); 46 | void ud_syn_print_imm(struct ud* u, const struct ud_operand *op); 47 | void ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *, int sign); 48 | 49 | #endif /* UD_SYN_H */ 50 | 51 | /* 52 | vim: set ts=2 sw=2 expandtab 53 | */ -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/x86/x86assembler.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_X86_X86ASSEMBLER_H 8 | #define _ASMJIT_X86_X86ASSEMBLER_H 9 | 10 | #include "../core/assembler.h" 11 | #include "../x86/x86emitter.h" 12 | #include "../x86/x86operand.h" 13 | 14 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 15 | 16 | //! \addtogroup asmjit_x86 17 | //! \{ 18 | 19 | // ============================================================================ 20 | // [asmjit::Assembler] 21 | // ============================================================================ 22 | 23 | //! Assembler (X86). 24 | //! 25 | //! Emits X86 machine-code into buffers managed by `CodeHolder`. 26 | class ASMJIT_VIRTAPI Assembler 27 | : public BaseAssembler, 28 | public EmitterImplicitT { 29 | public: 30 | ASMJIT_NONCOPYABLE(Assembler) 31 | typedef BaseAssembler Base; 32 | 33 | //! \name Construction & Destruction 34 | //! \{ 35 | 36 | ASMJIT_API explicit Assembler(CodeHolder* code = nullptr) noexcept; 37 | ASMJIT_API virtual ~Assembler() noexcept; 38 | 39 | //! \} 40 | 41 | //! \cond INTERNAL 42 | //! \name Internal 43 | //! \{ 44 | 45 | // NOTE: x86::Assembler uses _privateData to store 'address-override' bit that 46 | // is used to decide whether to emit address-override (67H) prefix based on 47 | // the memory BASE+INDEX registers. It's either `kX86MemInfo_67H_X86` or 48 | // `kX86MemInfo_67H_X64`. 49 | inline uint32_t _addressOverrideMask() const noexcept { return _privateData; } 50 | inline void _setAddressOverrideMask(uint32_t m) noexcept { _privateData = m; } 51 | 52 | //! \} 53 | //! \endcond 54 | 55 | //! \cond INTERNAL 56 | //! \name Emit 57 | //! \{ 58 | 59 | using BaseEmitter::_emit; 60 | ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) override; 61 | 62 | //! \} 63 | //! \endcond 64 | 65 | //! \name Align 66 | //! \{ 67 | 68 | ASMJIT_API Error align(uint32_t alignMode, uint32_t alignment) override; 69 | 70 | //! \} 71 | 72 | //! \name Events 73 | //! \{ 74 | 75 | ASMJIT_API Error onAttach(CodeHolder* code) noexcept override; 76 | ASMJIT_API Error onDetach(CodeHolder* code) noexcept override; 77 | 78 | //! \} 79 | }; 80 | 81 | //! \} 82 | 83 | ASMJIT_END_SUB_NAMESPACE 84 | 85 | #endif // _ASMJIT_X86_X86ASSEMBLER_H 86 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/cpuinfo.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/cpuinfo.h" 10 | 11 | #if !defined(_WIN32) 12 | #include 13 | #include 14 | #include 15 | #endif 16 | 17 | ASMJIT_BEGIN_NAMESPACE 18 | 19 | // ============================================================================ 20 | // [asmjit::CpuInfo - Detect - CPU NumThreads] 21 | // ============================================================================ 22 | 23 | #if defined(_WIN32) 24 | static inline uint32_t detectHWThreadCount() noexcept { 25 | SYSTEM_INFO info; 26 | ::GetSystemInfo(&info); 27 | return info.dwNumberOfProcessors; 28 | } 29 | #elif defined(_SC_NPROCESSORS_ONLN) 30 | static inline uint32_t detectHWThreadCount() noexcept { 31 | long res = ::sysconf(_SC_NPROCESSORS_ONLN); 32 | return res <= 0 ? uint32_t(1) : uint32_t(res); 33 | } 34 | #else 35 | static inline uint32_t detectHWThreadCount() noexcept { 36 | return 1; 37 | } 38 | #endif 39 | 40 | // ============================================================================ 41 | // [asmjit::CpuInfo - Detect - CPU Features] 42 | // ============================================================================ 43 | 44 | #if defined(ASMJIT_BUILD_X86) && ASMJIT_ARCH_X86 45 | namespace x86 { void detectCpu(CpuInfo& cpu) noexcept; } 46 | #endif 47 | 48 | #if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM 49 | namespace arm { void detectCpu(CpuInfo& cpu) noexcept; } 50 | #endif 51 | 52 | // ============================================================================ 53 | // [asmjit::CpuInfo - Detect - Static Initializer] 54 | // ============================================================================ 55 | 56 | static uint32_t cpuInfoInitialized; 57 | static CpuInfo cpuInfoGlobal(Globals::NoInit); 58 | 59 | const CpuInfo& CpuInfo::host() noexcept { 60 | // This should never cause a problem as the resulting information should 61 | // always be the same. 62 | if (!cpuInfoInitialized) { 63 | CpuInfo cpuInfoLocal; 64 | 65 | #if defined(ASMJIT_BUILD_X86) && ASMJIT_ARCH_X86 66 | x86::detectCpu(cpuInfoLocal); 67 | #endif 68 | 69 | #if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM 70 | arm::detectCpu(cpuInfoLocal); 71 | #endif 72 | 73 | cpuInfoLocal._hwThreadCount = detectHWThreadCount(); 74 | cpuInfoGlobal = cpuInfoLocal; 75 | cpuInfoInitialized = 1; 76 | } 77 | 78 | return cpuInfoGlobal; 79 | } 80 | 81 | ASMJIT_END_NAMESPACE 82 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/osutils.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_OSUTILS_H 8 | #define _ASMJIT_CORE_OSUTILS_H 9 | 10 | #include "../core/globals.h" 11 | 12 | ASMJIT_BEGIN_NAMESPACE 13 | 14 | //! \addtogroup asmjit_support 15 | //! \{ 16 | 17 | // ============================================================================ 18 | // [asmjit::OSUtils] 19 | // ============================================================================ 20 | 21 | //! Operating system utilities. 22 | namespace OSUtils { 23 | //! Gets the current CPU tick count, used for benchmarking (1ms resolution). 24 | ASMJIT_API uint32_t getTickCount() noexcept; 25 | }; 26 | 27 | // ============================================================================ 28 | // [asmjit::Lock] 29 | // ============================================================================ 30 | 31 | //! \cond INTERNAL 32 | 33 | //! Lock. 34 | class Lock { 35 | public: 36 | ASMJIT_NONCOPYABLE(Lock) 37 | 38 | #if defined(_WIN32) 39 | 40 | typedef CRITICAL_SECTION Handle; 41 | Handle _handle; 42 | 43 | inline Lock() noexcept { InitializeCriticalSection(&_handle); } 44 | inline ~Lock() noexcept { DeleteCriticalSection(&_handle); } 45 | 46 | inline void lock() noexcept { EnterCriticalSection(&_handle); } 47 | inline void unlock() noexcept { LeaveCriticalSection(&_handle); } 48 | 49 | #elif !defined(__EMSCRIPTEN__) 50 | 51 | typedef pthread_mutex_t Handle; 52 | Handle _handle; 53 | 54 | inline Lock() noexcept { pthread_mutex_init(&_handle, nullptr); } 55 | inline ~Lock() noexcept { pthread_mutex_destroy(&_handle); } 56 | 57 | inline void lock() noexcept { pthread_mutex_lock(&_handle); } 58 | inline void unlock() noexcept { pthread_mutex_unlock(&_handle); } 59 | 60 | #else 61 | 62 | // Browser or other unsupported OS. 63 | inline Lock() noexcept {} 64 | inline ~Lock() noexcept {} 65 | 66 | inline void lock() noexcept {} 67 | inline void unlock() noexcept {} 68 | 69 | #endif 70 | }; 71 | 72 | //! \endcond 73 | 74 | // ============================================================================ 75 | // [asmjit::ScopedLock] 76 | // ============================================================================ 77 | 78 | //! \cond INTERNAL 79 | 80 | //! Scoped lock. 81 | struct ScopedLock { 82 | ASMJIT_NONCOPYABLE(ScopedLock) 83 | 84 | Lock& _target; 85 | 86 | inline ScopedLock(Lock& target) noexcept : _target(target) { _target.lock(); } 87 | inline ~ScopedLock() noexcept { _target.unlock(); } 88 | }; 89 | 90 | //! \endcond 91 | 92 | //! \} 93 | 94 | ASMJIT_END_NAMESPACE 95 | 96 | #endif // _ASMJIT_CORE_OSUTILS_H 97 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/x86/x86internal_p.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_X86_X86INTERNAL_P_H 8 | #define _ASMJIT_X86_X86INTERNAL_P_H 9 | 10 | #include "../core/build.h" 11 | 12 | #include "../core/func.h" 13 | #include "../x86/x86emitter.h" 14 | #include "../x86/x86operand.h" 15 | 16 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 17 | 18 | //! \cond INTERNAL 19 | //! \addtogroup asmjit_x86 20 | //! \{ 21 | 22 | // ============================================================================ 23 | // [asmjit::X86Internal] 24 | // ============================================================================ 25 | 26 | //! X86 utilities used at multiple places, not part of public API, not exported. 27 | struct X86Internal { 28 | //! Initialize `FuncDetail` (X86 specific). 29 | static Error initFuncDetail(FuncDetail& func, const FuncSignature& sign, uint32_t gpSize) noexcept; 30 | 31 | //! Initialize `FuncFrame` (X86 specific). 32 | static Error initFuncFrame(FuncFrame& frame, const FuncDetail& func) noexcept; 33 | 34 | //! Finalize `FuncFrame` (X86 specific). 35 | static Error finalizeFuncFrame(FuncFrame& frame) noexcept; 36 | 37 | static Error argsToFuncFrame(const FuncArgsAssignment& args, FuncFrame& frame) noexcept; 38 | 39 | //! Emit function prolog. 40 | static Error emitProlog(Emitter* emitter, const FuncFrame& frame); 41 | 42 | //! Emit function epilog. 43 | static Error emitEpilog(Emitter* emitter, const FuncFrame& frame); 44 | 45 | //! Emit a pure move operation between two registers or the same type or 46 | //! between a register and its home slot. This function does not handle 47 | //! register conversion. 48 | static Error emitRegMove(Emitter* emitter, 49 | const Operand_& dst_, 50 | const Operand_& src_, uint32_t typeId, bool avxEnabled, const char* comment = nullptr); 51 | 52 | //! Emit move from a function argument (either register or stack) to a register. 53 | //! 54 | //! This function can handle the necessary conversion from one argument to 55 | //! another, and from one register type to another, if it's possible. Any 56 | //! attempt of conversion that requires third register of a different group 57 | //! (for example conversion from K to MMX) will fail. 58 | static Error emitArgMove(Emitter* emitter, 59 | const Reg& dst_, uint32_t dstTypeId, 60 | const Operand_& src_, uint32_t srcTypeId, bool avxEnabled, const char* comment = nullptr); 61 | 62 | static Error emitArgsAssignment(Emitter* emitter, const FuncFrame& frame, const FuncArgsAssignment& args); 63 | }; 64 | 65 | //! \} 66 | //! \endcond 67 | 68 | ASMJIT_END_SUB_NAMESPACE 69 | 70 | #endif // _ASMJIT_X86_X86INTERNAL_P_H 71 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | ############################################################################### 6 | # Set default behavior for command prompt diff. 7 | # 8 | # This is need for earlier builds of msysgit that does not have it on by 9 | # default for csharp files. 10 | # Note: This is only used by command line 11 | ############################################################################### 12 | #*.cs diff=csharp 13 | ############################################################################### 14 | # Set the merge driver for project and solution files 15 | # 16 | # Merging from the command prompt will add diff markers to the files if there 17 | # are conflicts (Merging from VS is not affected by the settings below, in VS 18 | # the diff markers are never inserted). Diff markers may cause the following 19 | # file extensions to fail to load in VS. An alternative would be to treat 20 | # these files as binary and thus will always conflict and require user 21 | # intervention with every merge. To do so, just uncomment the entries below 22 | ############################################################################### 23 | #*.sln merge=binary 24 | #*.csproj merge=binary 25 | #*.vbproj merge=binary 26 | #*.vcxproj merge=binary 27 | #*.vcproj merge=binary 28 | #*.dbproj merge=binary 29 | #*.fsproj merge=binary 30 | #*.lsproj merge=binary 31 | #*.wixproj merge=binary 32 | #*.modelproj merge=binary 33 | #*.sqlproj merge=binary 34 | #*.wwaproj merge=binary 35 | ############################################################################### 36 | # behavior for image files 37 | # 38 | # image files are treated as binary by default. 39 | ############################################################################### 40 | #*.jpg binary 41 | #*.png binary 42 | #*.gif binary 43 | ############################################################################### 44 | # diff behavior for common document formats 45 | # 46 | # Convert binary document formats to text before diffing them. This feature 47 | # is only available from the command line. Turn it on by uncommenting the 48 | # entries below. 49 | ############################################################################### 50 | #*.doc diff=astextplain 51 | #*.DOC diff=astextplain 52 | #*.docx diff=astextplain 53 | #*.DOCX diff=astextplain 54 | #*.dot diff=astextplain 55 | #*.DOT diff=astextplain 56 | #*.pdf diff=astextplain 57 | #*.PDF diff=astextplain 58 | #*.rtf diff=astextplain 59 | #*.RTF diff=astextplain 60 | *.png filter=lfs diff=lfs merge=lfs -text 61 | *.psd filter=lfs diff=lfs merge=lfs -text 62 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_H 8 | #define _ASMJIT_CORE_H 9 | 10 | //! \defgroup asmjit_core Core 11 | //! \brief Core API. 12 | //! 13 | //! API that provides classes and functions not specific to any architecture. 14 | 15 | //! \defgroup asmjit_builder Builder 16 | //! \brief Builder API. 17 | //! 18 | //! Both Builder and Compiler are emitters that emit everything to a representation 19 | //! that allows further processing. The code stored in such representation is 20 | //! completely safe to be patched, simplified, reordered, obfuscated, removed, 21 | //! injected, analyzed, or processed some other way. Each instruction, label, 22 | //! directive, or other building block is stored as \ref BaseNode (or derived 23 | //! class like \ref InstNode or \ref LabelNode) and contains all the information 24 | //! necessary to pass that node later to the Assembler. 25 | 26 | //! \defgroup asmjit_compiler Compiler 27 | //! \brief Compiler API. 28 | //! 29 | //! Compiler tool is built on top of a \ref asmjit_builder API and adds register 30 | //! allocation and support for defining and calling functions into it. At the 31 | //! moment it's the easiest way to generate some code as most architecture and 32 | //! OS specific stuff is properly abstracted, however, abstractions also mean 33 | //! that not everything is possible with the Compiler. 34 | 35 | //! \defgroup asmjit_func Function 36 | //! \brief Function API. 37 | 38 | //! \defgroup asmjit_jit JIT 39 | //! \brief JIT API and Virtual Memory Management. 40 | 41 | //! \defgroup asmjit_zone Zone 42 | //! \brief Zone allocator and zone allocated containers. 43 | 44 | //! \defgroup asmjit_support Support 45 | //! \brief Support API. 46 | 47 | //! \cond INTERNAL 48 | //! \defgroup asmjit_ra RA 49 | //! \brief Register allocator internals. 50 | //! \endcond 51 | 52 | #include "./core/globals.h" 53 | 54 | #include "./core/arch.h" 55 | #include "./core/assembler.h" 56 | #include "./core/builder.h" 57 | #include "./core/callconv.h" 58 | #include "./core/codeholder.h" 59 | #include "./core/compiler.h" 60 | #include "./core/constpool.h" 61 | #include "./core/cpuinfo.h" 62 | #include "./core/datatypes.h" 63 | #include "./core/emitter.h" 64 | #include "./core/features.h" 65 | #include "./core/func.h" 66 | #include "./core/inst.h" 67 | #include "./core/jitallocator.h" 68 | #include "./core/jitruntime.h" 69 | #include "./core/logging.h" 70 | #include "./core/operand.h" 71 | #include "./core/osutils.h" 72 | #include "./core/string.h" 73 | #include "./core/support.h" 74 | #include "./core/target.h" 75 | #include "./core/type.h" 76 | #include "./core/virtmem.h" 77 | #include "./core/zone.h" 78 | #include "./core/zonehash.h" 79 | #include "./core/zonelist.h" 80 | #include "./core/zonetree.h" 81 | #include "./core/zonestack.h" 82 | #include "./core/zonestring.h" 83 | #include "./core/zonevector.h" 84 | 85 | #endif // _ASMJIT_CORE_H 86 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/osutils.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/osutils.h" 10 | #include "../core/support.h" 11 | 12 | #if defined(_WIN32) 13 | #include 14 | #elif defined(__APPLE__) 15 | #include 16 | #else 17 | #include 18 | #include 19 | #endif 20 | 21 | ASMJIT_BEGIN_NAMESPACE 22 | 23 | // ============================================================================ 24 | // [asmjit::OSUtils - GetTickCount] 25 | // ============================================================================ 26 | 27 | uint32_t OSUtils::getTickCount() noexcept { 28 | #if defined(_WIN32) 29 | enum HiResStatus : uint32_t { 30 | kHiResUnknown = 0, 31 | kHiResAvailable = 1, 32 | kHiResNotAvailable = 2 33 | }; 34 | 35 | static std::atomic _hiResStatus(kHiResUnknown); 36 | static volatile double _hiResFreq(0); 37 | 38 | uint32_t status = _hiResStatus.load(); 39 | LARGE_INTEGER now, qpf; 40 | 41 | if (status != kHiResNotAvailable && ::QueryPerformanceCounter(&now)) { 42 | double freq = _hiResFreq; 43 | if (status == kHiResUnknown) { 44 | // Detects the availability of high resolution counter. 45 | if (::QueryPerformanceFrequency(&qpf)) { 46 | freq = double(qpf.QuadPart) / 1000.0; 47 | _hiResFreq = freq; 48 | _hiResStatus.compare_exchange_strong(status, kHiResAvailable); 49 | status = kHiResAvailable; 50 | } 51 | else { 52 | // High resolution not available. 53 | _hiResStatus.compare_exchange_strong(status, kHiResNotAvailable); 54 | } 55 | } 56 | 57 | if (status == kHiResAvailable) 58 | return uint32_t(uint64_t(int64_t(double(now.QuadPart) / freq)) & 0xFFFFFFFFu); 59 | } 60 | 61 | // Bail to `GetTickCount()` if we cannot use high resolution. 62 | return ::GetTickCount(); 63 | #elif defined(__APPLE__) 64 | // See Apple's QA1398. 65 | static mach_timebase_info_data_t _machTime; 66 | 67 | uint32_t denom = _machTime.denom; 68 | if (ASMJIT_UNLIKELY(!denom)) { 69 | if (mach_timebase_info(&_machTime) != KERN_SUCCESS || !(denom = _machTime.denom)) 70 | return 0; 71 | } 72 | 73 | // `mach_absolute_time()` returns nanoseconds, we want milliseconds. 74 | uint64_t t = mach_absolute_time() / 1000000u; 75 | t = (t * _machTime.numer) / _machTime.denom; 76 | return uint32_t(t & 0xFFFFFFFFu); 77 | #elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 78 | struct timespec ts; 79 | if (ASMJIT_UNLIKELY(clock_gettime(CLOCK_MONOTONIC, &ts) != 0)) 80 | return 0; 81 | 82 | uint64_t t = (uint64_t(ts.tv_sec ) * 1000u) + (uint64_t(ts.tv_nsec) / 1000000u); 83 | return uint32_t(t & 0xFFFFFFFFu); 84 | #else 85 | #pragma message("asmjit::OSUtils::getTickCount() doesn't have implementation for the target OS.") 86 | return 0; 87 | #endif 88 | } 89 | 90 | ASMJIT_END_NAMESPACE 91 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmtk/parserutils.h: -------------------------------------------------------------------------------- 1 | // [AsmTk] 2 | // Assembler toolkit based on AsmJit. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMTK_PARSERUTILS_H 8 | #define _ASMTK_PARSERUTILS_H 9 | 10 | #include "../asmjit/asmjit.h" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace asmtk { 18 | namespace ParserUtils { 19 | 20 | // ============================================================================ 21 | // [asmtk::ParserUtils::WordParser] 22 | // ============================================================================ 23 | 24 | class WordParser { 25 | public: 26 | #if ASMJIT_ARCH_BITS == 32 27 | typedef uint32_t Value; 28 | #else 29 | typedef uint64_t Value; 30 | #endif 31 | 32 | static constexpr uint32_t kNumValues = 33 | uint32_t((8 + sizeof(Value) - 1) / sizeof(Value)); 34 | 35 | constexpr WordParser() noexcept 36 | : _value { 0 } {} 37 | 38 | inline void reset() noexcept { 39 | for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_value); i++) 40 | _value[i] = 0; 41 | } 42 | 43 | template 44 | inline void addChar(const T* input, size_t i) noexcept { 45 | size_t nIndex = i / sizeof(Value); 46 | size_t nByte = i % sizeof(Value); 47 | _value[nIndex] |= Value(uint8_t(input[i])) << (nByte * 8u); 48 | } 49 | 50 | template 51 | inline void addLowercasedChar(const T* input, size_t i) noexcept { 52 | size_t nIndex = i / sizeof(Value); 53 | size_t nByte = i % sizeof(Value); 54 | _value[nIndex] |= Value(asmjit::Support::asciiToLower(uint8_t(input[i]))) << (nByte * 8u); 55 | } 56 | 57 | inline bool test(char x0, char x1 = '\0', char x2 = '\0', char x3 = '\0') const noexcept { 58 | uint32_t pattern0 = (uint32_t(uint8_t(x0)) << 0) | 59 | (uint32_t(uint8_t(x1)) << 8) | 60 | (uint32_t(uint8_t(x2)) << 16) | 61 | (uint32_t(uint8_t(x3)) << 24) ; 62 | return uint32_t(_value[0] & 0xFFFFFFFFu) == pattern0; 63 | } 64 | 65 | inline bool test(char x0, char x1, char x2, char x3, 66 | char x4, char x5 = '\0', char x6 = '\0', char x7 = '\0') const noexcept { 67 | uint32_t pattern0 = (uint32_t(uint8_t(x0)) << 0) | 68 | (uint32_t(uint8_t(x1)) << 8) | 69 | (uint32_t(uint8_t(x2)) << 16) | 70 | (uint32_t(uint8_t(x3)) << 24) ; 71 | uint32_t pattern1 = (uint32_t(uint8_t(x4)) << 0) | 72 | (uint32_t(uint8_t(x5)) << 8) | 73 | (uint32_t(uint8_t(x6)) << 16) | 74 | (uint32_t(uint8_t(x7)) << 24) ; 75 | #if ASMJIT_ARCH_BITS == 32 76 | return (_value[0] == pattern0) & 77 | (_value[1] == pattern1) ; 78 | #else 79 | return (_value[0] == (uint64_t(pattern0) | (uint64_t(pattern1) << 32))); 80 | #endif 81 | } 82 | 83 | Value _value[kNumValues]; 84 | }; 85 | 86 | } // {ParserUtils} 87 | } // {asmtk} 88 | 89 | #endif // _ASMTK_PARSERUTILS_H 90 | -------------------------------------------------------------------------------- /SelfHackingApp/HackUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | class LocalizedString; 7 | 8 | class HackUtils 9 | { 10 | public: 11 | enum class DataType 12 | { 13 | Byte, 14 | SByte, 15 | Int16, 16 | UInt16, 17 | Int32, 18 | UInt32, 19 | Int64, 20 | UInt64, 21 | Single, 22 | Double, 23 | }; 24 | 25 | struct CompileResult 26 | { 27 | enum class ErrorId 28 | { 29 | Ok = 0, 30 | NoHeapMemory = 1, 31 | NoVirtualMemory = 2, 32 | InvalidArgument = 3, 33 | InvalidState = 4, 34 | InvalidArchitecture = 5, 35 | NotInitialized = 6, 36 | AlreadyInitialized = 7, 37 | FeatureNotEnabled = 8, 38 | SlotOccupied = 9, 39 | NoCodeGenerated = 10, 40 | CodeTooLarge = 11, 41 | InvalidLabel = 12, 42 | LabelIndexOverflow = 13, 43 | LabelAlreadyBound = 14, 44 | LabelAlreadyDefined = 15, 45 | LabelNameTooLong = 16, 46 | InvalidLabelName = 17, 47 | InvalidParentLabel = 18, 48 | NonLocalLabelCantHaveParent = 19, 49 | RelocationIndexOverflow = 20, 50 | InvalidRelocationEntry = 21, 51 | InvalidInstruction = 22, 52 | InvalidRegisterType = 23, 53 | InvalidRegisterKind = 24, 54 | InvalidRegisterPhysicalId = 25, 55 | InvalidRegisterVirtualId = 26, 56 | InvalidPrefixCombination = 27, 57 | InvalidLockPrefix = 28, 58 | InvalidXAcquirePrefix = 29, 59 | InvalidXReleasePrefix = 30, 60 | InvalidRepPrefix = 31, 61 | InvalidRexPrefix = 32, 62 | InvalidMask = 33, 63 | InvalidUseSingle = 34, 64 | InvalidUseDouble = 35, 65 | InvalidBroadcast = 36, 66 | InvalidOption = 37, 67 | InvalidAddress = 38, 68 | InvalidAddressIndex = 39, 69 | InvalidAddressScale = 40, 70 | InvalidUseOf64BitAddress = 41, 71 | InvalidDisplacement = 42, 72 | InvalidSegment = 43, 73 | InvalidImmediateValue = 44, 74 | InvalidOperandSize = 45, 75 | AmbiguousOperandSize = 46, 76 | OperandSizeMismatch = 47, 77 | InvalidTypeInfo = 48, 78 | InvalidUseOf8BitRegister = 49, 79 | InvalidUseOf64BitRegister = 50, 80 | InvalidUseOf80BitFloat = 51, 81 | NotConsecutiveRegisters = 52, 82 | NoPhysicalRegisters = 53, 83 | OverlappedRegisters = 54, 84 | OverlappingRegisterAndArgsRegister = 55, 85 | UnknownError = 56, 86 | }; 87 | 88 | struct ErrorData 89 | { 90 | int lineNumber; 91 | std::string message; 92 | }; 93 | 94 | ErrorData errorData; 95 | bool hasError; 96 | std::vector compiledBytes; 97 | int byteCount; 98 | }; 99 | 100 | static void setAllMemoryPermissions(void* address, int length); 101 | static void writeMemory(void* to, void* from, int length); 102 | static std::string preProcessAssembly(std::string assembly); 103 | static HackUtils::CompileResult assemble(std::string assembly, void* addressStart); 104 | static void* resolveVTableAddress(void* address); 105 | static std::string disassemble(void* address, int length); 106 | static std::string preProcess(std::string instructions); 107 | static std::string toHex(int value, bool prefix = false); 108 | static void* intToPointer(std::string intString, void* fallback = nullptr); 109 | }; 110 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/zonetree.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/support.h" 10 | #include "../core/zone.h" 11 | #include "../core/zonetree.h" 12 | 13 | ASMJIT_BEGIN_NAMESPACE 14 | 15 | // ============================================================================ 16 | // [asmjit::ZoneTree - Unit] 17 | // ============================================================================ 18 | 19 | #if defined(ASMJIT_TEST) 20 | template 21 | struct ZoneRBUnit { 22 | typedef ZoneTree Tree; 23 | 24 | static void verifyTree(Tree& tree) noexcept { 25 | EXPECT(checkHeight(static_cast(tree._root)) > 0); 26 | } 27 | 28 | // Check whether the Red-Black tree is valid. 29 | static int checkHeight(NodeT* node) noexcept { 30 | if (!node) return 1; 31 | 32 | NodeT* ln = node->left(); 33 | NodeT* rn = node->right(); 34 | 35 | // Invalid tree. 36 | EXPECT(ln == nullptr || *ln < *node); 37 | EXPECT(rn == nullptr || *rn > *node); 38 | 39 | // Red violation. 40 | EXPECT(!node->isRed() || 41 | (!ZoneTreeNode::_isValidRed(ln) && !ZoneTreeNode::_isValidRed(rn))); 42 | 43 | // Black violation. 44 | int lh = checkHeight(ln); 45 | int rh = checkHeight(rn); 46 | EXPECT(!lh || !rh || lh == rh); 47 | 48 | // Only count black links. 49 | return (lh && rh) ? lh + !node->isRed() : 0; 50 | } 51 | }; 52 | 53 | class MyRBNode : public ZoneTreeNodeT { 54 | public: 55 | ASMJIT_NONCOPYABLE(MyRBNode) 56 | 57 | inline explicit MyRBNode(uint32_t key) noexcept 58 | : _key(key) {} 59 | 60 | inline bool operator<(const MyRBNode& other) const noexcept { return _key < other._key; } 61 | inline bool operator>(const MyRBNode& other) const noexcept { return _key > other._key; } 62 | 63 | inline bool operator<(uint32_t queryKey) const noexcept { return _key < queryKey; } 64 | inline bool operator>(uint32_t queryKey) const noexcept { return _key > queryKey; } 65 | 66 | uint32_t _key; 67 | }; 68 | 69 | UNIT(asmjit_zone_rbtree) { 70 | uint32_t kCount = BrokenAPI::hasArg("--quick") ? 1000 : 10000; 71 | 72 | Zone zone(4096); 73 | ZoneTree rbTree; 74 | 75 | uint32_t key; 76 | INFO("Inserting %u elements to RBTree and validating each operation", unsigned(kCount)); 77 | for (key = 0; key < kCount; key++) { 78 | rbTree.insert(zone.newT(key)); 79 | ZoneRBUnit::verifyTree(rbTree); 80 | } 81 | 82 | uint32_t count = kCount; 83 | INFO("Removing %u elements from RBTree and validating each operation", unsigned(kCount)); 84 | do { 85 | MyRBNode* node; 86 | 87 | for (key = 0; key < count; key++) { 88 | node = rbTree.get(key); 89 | EXPECT(node != nullptr); 90 | EXPECT(node->_key == key); 91 | } 92 | 93 | node = rbTree.get(--count); 94 | rbTree.remove(node); 95 | ZoneRBUnit::verifyTree(rbTree); 96 | } while (count); 97 | 98 | EXPECT(rbTree.empty()); 99 | } 100 | #endif 101 | 102 | ASMJIT_END_NAMESPACE 103 | -------------------------------------------------------------------------------- /SelfHackingApp/External/libudis86/udint.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/udint.h -- definitions for internal use only 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef _UDINT_H_ 27 | #define _UDINT_H_ 28 | 29 | #include "types.h" 30 | 31 | #ifdef HAVE_CONFIG_H 32 | # include 33 | #endif /* HAVE_CONFIG_H */ 34 | 35 | #if defined(UD_DEBUG) && HAVE_ASSERT_H 36 | # include 37 | # define UD_ASSERT(_x) assert(_x) 38 | #else 39 | # define UD_ASSERT(_x) 40 | #endif /* !HAVE_ASSERT_H */ 41 | 42 | #if defined(UD_DEBUG) 43 | #define UDERR(u, msg) \ 44 | do { \ 45 | (u)->error = 1; \ 46 | fprintf(stderr, "decode-error: %s:%d: %s", \ 47 | __FILE__, __LINE__, (msg)); \ 48 | } while (0) 49 | #else 50 | #define UDERR(u, m) \ 51 | do { \ 52 | (u)->error = 1; \ 53 | } while (0) 54 | #endif /* !LOGERR */ 55 | 56 | #define UD_RETURN_ON_ERROR(u) \ 57 | do { \ 58 | if ((u)->error != 0) { \ 59 | return (u)->error; \ 60 | } \ 61 | } while (0) 62 | 63 | #define UD_RETURN_WITH_ERROR(u, m) \ 64 | do { \ 65 | UDERR(u, m); \ 66 | return (u)->error; \ 67 | } while (0) 68 | 69 | #ifndef __UD_STANDALONE__ 70 | # define UD_NON_STANDALONE(x) x 71 | #else 72 | # define UD_NON_STANDALONE(x) 73 | #endif 74 | 75 | /* printf formatting int64 specifier */ 76 | #ifdef FMT64 77 | # undef FMT64 78 | #endif 79 | #if defined(_MSC_VER) || defined(__BORLANDC__) 80 | # define FMT64 "I64" 81 | #else 82 | # if defined(__APPLE__) 83 | # define FMT64 "ll" 84 | # elif defined(__amd64__) || defined(__x86_64__) 85 | # define FMT64 "l" 86 | # else 87 | # define FMT64 "ll" 88 | # endif /* !x64 */ 89 | #endif 90 | 91 | /* define an inline macro */ 92 | #if defined(_MSC_VER) || defined(__BORLANDC__) 93 | # define UD_INLINE __inline /* MS Visual Studio requires __inline 94 | instead of inline for C code */ 95 | #else 96 | # define UD_INLINE inline 97 | #endif 98 | 99 | #endif /* _UDINT_H_ */ -------------------------------------------------------------------------------- /SelfHackingApp/External/asmtk/asmparser.h: -------------------------------------------------------------------------------- 1 | // [AsmTk] 2 | // Assembler toolkit based on AsmJit. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMTK_ASMPARSER_H 8 | #define _ASMTK_ASMPARSER_H 9 | 10 | #include "./strtod.h" 11 | #include "./asmtokenizer.h" 12 | 13 | namespace asmtk { 14 | 15 | // ============================================================================ 16 | // [asmtk::AsmParser] 17 | // ============================================================================ 18 | 19 | //! Asm parser. 20 | class AsmParser { 21 | public: 22 | typedef Error (ASMJIT_CDECL* UnknownSymbolHandler)( 23 | AsmParser* parser, asmjit::Operand* out, const char* name, size_t size); 24 | 25 | asmjit::BaseEmitter* _emitter; 26 | AsmTokenizer _tokenizer; 27 | 28 | size_t _currentCommandOffset; 29 | bool _endOfInput; 30 | 31 | UnknownSymbolHandler _unknownSymbolHandler; 32 | void* _unknownSymbolHandlerData; 33 | 34 | //! \name Construction & Destruction 35 | //! \{ 36 | 37 | ASMTK_API AsmParser(asmjit::BaseEmitter* emitter) noexcept; 38 | ASMTK_API ~AsmParser() noexcept; 39 | 40 | //! \} 41 | 42 | //! \name Accessors 43 | //! \{ 44 | 45 | inline asmjit::BaseEmitter* emitter() const noexcept { return _emitter; } 46 | 47 | //! \} 48 | 49 | //! \name Input Buffer 50 | //! \{ 51 | 52 | inline const char* input() const noexcept { 53 | return reinterpret_cast(_tokenizer._input); 54 | } 55 | 56 | inline bool setInput(const char* input, size_t size = SIZE_MAX) noexcept { 57 | if (size == SIZE_MAX) 58 | size = strlen(input); 59 | 60 | _tokenizer.setInput(reinterpret_cast(input), size); 61 | _currentCommandOffset = 0; 62 | _endOfInput = (size == 0); 63 | 64 | return _endOfInput; 65 | } 66 | 67 | inline bool isEndOfInput() const noexcept { return _endOfInput; } 68 | inline size_t currentCommandOffset() const noexcept { return _currentCommandOffset; } 69 | 70 | ASMTK_API uint32_t nextToken(AsmToken* token, uint32_t flags = 0) noexcept; 71 | ASMTK_API void putTokenBack(AsmToken* token) noexcept; 72 | 73 | //! \} 74 | 75 | //! \name Unknown Symbol Handler 76 | //! \{ 77 | 78 | inline UnknownSymbolHandler unknownSymbolHandler() const noexcept { return _unknownSymbolHandler; } 79 | inline void* unknownSymbolHandlerData() const noexcept { return _unknownSymbolHandlerData; } 80 | 81 | inline void setUnknownSymbolHandler(UnknownSymbolHandler handler, void* data = nullptr) noexcept { 82 | _unknownSymbolHandler = handler; 83 | _unknownSymbolHandlerData = data; 84 | } 85 | 86 | inline void resetUnknownSymbolHandler() noexcept { 87 | setUnknownSymbolHandler((UnknownSymbolHandler)nullptr, nullptr); 88 | } 89 | 90 | //! \} 91 | 92 | //! \name Parser 93 | //! \{ 94 | 95 | //! Universal method that setups the input and then calls `parseLine()` until 96 | //! the end is reached. It returns `kErrorOk` on success (which means that all 97 | //! commands were parsed successfully), otherwise and error code describing 98 | //! the problem. 99 | ASMTK_API Error parse(const char* input, size_t size = SIZE_MAX) noexcept; 100 | 101 | ASMTK_API Error parseCommand() noexcept; 102 | 103 | //! \} 104 | }; 105 | 106 | } // {asmtk} 107 | 108 | #endif // _ASMTK_ASMPARSER_H 109 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/zonestring.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_SMALLSTRING_H 8 | #define _ASMJIT_CORE_SMALLSTRING_H 9 | 10 | #include "../core/globals.h" 11 | #include "../core/zone.h" 12 | 13 | ASMJIT_BEGIN_NAMESPACE 14 | 15 | //! \addtogroup asmjit_zone 16 | //! \{ 17 | 18 | // ============================================================================ 19 | // [asmjit::ZoneStringBase] 20 | // ============================================================================ 21 | 22 | struct ZoneStringBase { 23 | union { 24 | struct { 25 | uint32_t _size; 26 | char _embedded[sizeof(void*) * 2 - 4]; 27 | }; 28 | struct { 29 | void* _dummy; 30 | char* _external; 31 | }; 32 | }; 33 | 34 | inline void reset() noexcept { 35 | _dummy = nullptr; 36 | _external = nullptr; 37 | } 38 | 39 | Error setData(Zone* zone, uint32_t maxEmbeddedSize, const char* str, size_t size) noexcept { 40 | if (size == SIZE_MAX) 41 | size = strlen(str); 42 | 43 | if (size <= maxEmbeddedSize) { 44 | memcpy(_embedded, str, size); 45 | _embedded[size] = '\0'; 46 | } 47 | else { 48 | char* external = static_cast(zone->dup(str, size, true)); 49 | if (ASMJIT_UNLIKELY(!external)) 50 | return DebugUtils::errored(kErrorOutOfMemory); 51 | _external = external; 52 | } 53 | 54 | _size = uint32_t(size); 55 | return kErrorOk; 56 | } 57 | }; 58 | 59 | // ============================================================================ 60 | // [asmjit::ZoneString] 61 | // ============================================================================ 62 | 63 | //! Small string is a template that helps to create strings that can be either 64 | //! statically allocated if they are small, or externally allocated in case 65 | //! their size exceeds the limit. The `N` represents the size of the whole 66 | //! `ZoneString` structure, based on that size the maximum size of the internal 67 | //! buffer is determined. 68 | template 69 | class ZoneString { 70 | public: 71 | static constexpr uint32_t kWholeSize = 72 | (N > sizeof(ZoneStringBase)) ? uint32_t(N) : uint32_t(sizeof(ZoneStringBase)); 73 | static constexpr uint32_t kMaxEmbeddedSize = kWholeSize - 5; 74 | 75 | union { 76 | ZoneStringBase _base; 77 | char _wholeData[kWholeSize]; 78 | }; 79 | 80 | //! \name Construction & Destruction 81 | //! \{ 82 | 83 | inline ZoneString() noexcept { reset(); } 84 | inline void reset() noexcept { _base.reset(); } 85 | 86 | //! \} 87 | 88 | //! \name Accessors 89 | //! \{ 90 | 91 | inline const char* data() const noexcept { return _base._size <= kMaxEmbeddedSize ? _base._embedded : _base._external; } 92 | inline bool empty() const noexcept { return _base._size == 0; } 93 | inline uint32_t size() const noexcept { return _base._size; } 94 | 95 | inline bool isEmbedded() const noexcept { return _base._size <= kMaxEmbeddedSize; } 96 | 97 | inline Error setData(Zone* zone, const char* data, size_t size) noexcept { 98 | return _base.setData(zone, kMaxEmbeddedSize, data, size); 99 | } 100 | 101 | //! \} 102 | }; 103 | 104 | //! \} 105 | 106 | ASMJIT_END_NAMESPACE 107 | 108 | #endif // _ASMJIT_CORE_SMALLSTRING_H 109 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/x86/x86rapass_p.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_X86_X86RAPASS_P_H 8 | #define _ASMJIT_X86_X86RAPASS_P_H 9 | 10 | #include "../core/build.h" 11 | #ifndef ASMJIT_NO_COMPILER 12 | 13 | #include "../core/compiler.h" 14 | #include "../core/rabuilders_p.h" 15 | #include "../core/rapass_p.h" 16 | #include "../x86/x86assembler.h" 17 | #include "../x86/x86compiler.h" 18 | 19 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 20 | 21 | //! \cond INTERNAL 22 | 23 | //! \defgroup asmjit_x86_ra X86 RA 24 | //! \ingroup asmjit_x86 25 | //! 26 | //! \brief X86/X64 register allocation. 27 | 28 | //! \addtogroup asmjit_x86_ra 29 | //! \{ 30 | 31 | // ============================================================================ 32 | // [asmjit::X86RAPass] 33 | // ============================================================================ 34 | 35 | //! X86 register allocation pass. 36 | //! 37 | //! Takes care of generating function prologs and epilogs, and also performs 38 | //! register allocation. 39 | class X86RAPass : public RAPass { 40 | public: 41 | ASMJIT_NONCOPYABLE(X86RAPass) 42 | typedef RAPass Base; 43 | 44 | bool _avxEnabled; 45 | 46 | // -------------------------------------------------------------------------- 47 | // [Construction / Destruction] 48 | // -------------------------------------------------------------------------- 49 | 50 | X86RAPass() noexcept; 51 | virtual ~X86RAPass() noexcept; 52 | 53 | // -------------------------------------------------------------------------- 54 | // [Accessors] 55 | // -------------------------------------------------------------------------- 56 | 57 | //! Returns the compiler casted to `x86::Compiler`. 58 | inline Compiler* cc() const noexcept { return static_cast(_cb); } 59 | 60 | // -------------------------------------------------------------------------- 61 | // [Utilities] 62 | // -------------------------------------------------------------------------- 63 | 64 | inline uint32_t choose(uint32_t sseInstId, uint32_t avxInstId) noexcept { 65 | return _avxEnabled ? avxInstId : sseInstId; 66 | } 67 | 68 | // -------------------------------------------------------------------------- 69 | // [OnInit / OnDone] 70 | // -------------------------------------------------------------------------- 71 | 72 | void onInit() noexcept override; 73 | void onDone() noexcept override; 74 | 75 | // -------------------------------------------------------------------------- 76 | // [CFG] 77 | // -------------------------------------------------------------------------- 78 | 79 | Error buildCFG() noexcept override; 80 | 81 | // -------------------------------------------------------------------------- 82 | // [Emit] 83 | // -------------------------------------------------------------------------- 84 | 85 | Error onEmitMove(uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept override; 86 | Error onEmitSwap(uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept override; 87 | 88 | Error onEmitLoad(uint32_t workId, uint32_t dstPhysId) noexcept override; 89 | Error onEmitSave(uint32_t workId, uint32_t srcPhysId) noexcept override; 90 | 91 | Error onEmitJump(const Label& label) noexcept override; 92 | Error onEmitPreCall(FuncCallNode* node) noexcept override; 93 | }; 94 | 95 | //! \} 96 | //! \endcond 97 | 98 | ASMJIT_END_SUB_NAMESPACE 99 | 100 | #endif // !ASMJIT_NO_COMPILER 101 | #endif // _ASMJIT_X86_X86RAPASS_P_H 102 | -------------------------------------------------------------------------------- /SelfHackingApp/StrUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "StrUtils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #ifndef WIN32 10 | extern "C" { 11 | #include 12 | } 13 | #endif 14 | 15 | bool StrUtils::isInteger(std::string str) 16 | { 17 | if (StrUtils::startsWith(str, "-", false)) 18 | { 19 | str = str.substr(1, str.size() - 1); 20 | } 21 | 22 | return !str.empty() && str.find_first_not_of("0123456789") == std::string::npos; 23 | } 24 | 25 | std::string StrUtils::ltrim(std::string str, std::string toRemove, bool ignoreCase) 26 | { 27 | while (StrUtils::startsWith(str, toRemove, ignoreCase)) 28 | { 29 | str = str.substr(toRemove.size()); 30 | } 31 | 32 | return str; 33 | } 34 | 35 | std::string StrUtils::rtrim(std::string str, std::string toRemove, bool ignoreCase) 36 | { 37 | while (StrUtils::endsWith(str, toRemove, ignoreCase)) 38 | { 39 | str = str.substr(0, str.size() - toRemove.size()); 40 | } 41 | 42 | return str; 43 | } 44 | 45 | int StrUtils::hexToInt(std::string str) 46 | { 47 | if (StrUtils::startsWith(str, "0x", false)) 48 | { 49 | str = str.substr(2, str.size() - 2); 50 | } 51 | 52 | int result; 53 | std::stringstream stream; 54 | 55 | stream << str; 56 | 57 | stream >> std::hex >> result; 58 | 59 | return result; 60 | } 61 | 62 | bool StrUtils::startsWith(std::string str, std::string prefix, bool ignoreCase) 63 | { 64 | if (str.size() >= prefix.size()) 65 | { 66 | std::string stringStart = str.substr(0, prefix.size()); 67 | 68 | if (ignoreCase) 69 | { 70 | #ifdef _WIN32 71 | if (_stricmp(stringStart.c_str(), prefix.c_str()) == 0) 72 | { 73 | return true; 74 | } 75 | #else 76 | if (strcasecmp(stringStart.c_str(), prefix.c_str()) == 0) 77 | { 78 | return true; 79 | } 80 | #endif 81 | } 82 | 83 | if (stringStart == prefix) 84 | { 85 | return true; 86 | } 87 | } 88 | 89 | return false; 90 | } 91 | 92 | bool StrUtils::endsWith(std::string str, std::string suffix, bool ignoreCase) 93 | { 94 | if (str.size() >= suffix.size()) 95 | { 96 | std::string stringEnd = str.substr(str.size() - suffix.size(), suffix.size()); 97 | 98 | if (ignoreCase) 99 | { 100 | #ifdef _WIN32 101 | if (_stricmp(stringEnd.c_str(), suffix.c_str()) == 0) 102 | { 103 | return true; 104 | } 105 | #else 106 | if (strcasecmp(stringEnd.c_str(), suffix.c_str()) == 0) 107 | { 108 | return true; 109 | } 110 | #endif 111 | } 112 | 113 | if (stringEnd == suffix) 114 | { 115 | return true; 116 | } 117 | } 118 | 119 | return false; 120 | } 121 | 122 | bool StrUtils::isRegexSubMatch(const std::string str, const std::string regex) 123 | { 124 | std::regex re = std::regex(regex); 125 | std::smatch match; 126 | 127 | if (std::regex_search(str, match, re)) 128 | { 129 | return true; 130 | } 131 | 132 | return false; 133 | } 134 | 135 | bool StrUtils::isHexNumber(std::string str) 136 | { 137 | if (StrUtils::startsWith(str, "0x", false)) 138 | { 139 | str = str.substr(2, str.size() - 2); 140 | return !str.empty() && str.find_first_not_of("0123456789abcdefABCDEF") == std::string::npos; 141 | } 142 | 143 | return false; 144 | } 145 | 146 | std::string StrUtils::replaceAll(std::string str, const std::string& from, const std::string& to) 147 | { 148 | size_t start_pos = 0; 149 | 150 | while ((start_pos = str.find(from, start_pos)) != std::string::npos) 151 | { 152 | str.replace(start_pos, from.length(), to); 153 | start_pos += to.length(); 154 | } 155 | 156 | return str; 157 | } 158 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/jitruntime.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_JITRUNTIME_H 8 | #define _ASMJIT_CORE_JITRUNTIME_H 9 | 10 | #include "../core/build.h" 11 | #ifndef ASMJIT_NO_JIT 12 | 13 | #include "../core/codeholder.h" 14 | #include "../core/jitallocator.h" 15 | #include "../core/target.h" 16 | 17 | ASMJIT_BEGIN_NAMESPACE 18 | 19 | class CodeHolder; 20 | 21 | //! \addtogroup asmjit_jit 22 | //! \{ 23 | 24 | // ============================================================================ 25 | // [asmjit::JitRuntime] 26 | // ============================================================================ 27 | 28 | //! JIT execution runtime is a special `Target` that is designed to store and 29 | //! execute the generated code. 30 | class ASMJIT_VIRTAPI JitRuntime : public Target { 31 | public: 32 | ASMJIT_NONCOPYABLE(JitRuntime) 33 | 34 | //! Virtual memory allocator. 35 | JitAllocator _allocator; 36 | 37 | //! \name Construction & Destruction 38 | //! \{ 39 | 40 | //! Creates a `JitRuntime` instance. 41 | explicit ASMJIT_API JitRuntime(const JitAllocator::CreateParams* params = nullptr) noexcept; 42 | //! Destroys the `JitRuntime` instance. 43 | ASMJIT_API virtual ~JitRuntime() noexcept; 44 | 45 | inline void reset(uint32_t resetPolicy = Globals::kResetSoft) noexcept { 46 | _allocator.reset(resetPolicy); 47 | } 48 | 49 | //! \} 50 | 51 | //! \name Accessors 52 | //! \{ 53 | 54 | //! Returns the associated `JitAllocator`. 55 | inline JitAllocator* allocator() const noexcept { return const_cast(&_allocator); } 56 | 57 | //! \} 58 | 59 | //! \name Utilities 60 | //! \{ 61 | 62 | // NOTE: To allow passing function pointers to `add()` and `release()` the 63 | // virtual methods are prefixed with `_` and called from templates instead. 64 | 65 | //! Allocates memory needed for a code stored in the `CodeHolder` and relocates 66 | //! the code to the pointer allocated. 67 | //! 68 | //! The beginning of the memory allocated for the function is returned in `dst`. 69 | //! If failed `Error` code is returned and `dst` is explicitly set to `nullptr` 70 | //! (this means that you don't have to set it to null before calling `add()`). 71 | template 72 | inline Error add(Func* dst, CodeHolder* code) noexcept { 73 | return _add(Support::ptr_cast_impl(dst), code); 74 | } 75 | 76 | //! Releases `p` which was obtained by calling `add()`. 77 | template 78 | inline Error release(Func p) noexcept { 79 | return _release(Support::ptr_cast_impl(p)); 80 | } 81 | 82 | //! Type-unsafe version of `add()`. 83 | ASMJIT_API virtual Error _add(void** dst, CodeHolder* code) noexcept; 84 | 85 | //! Type-unsafe version of `release()`. 86 | ASMJIT_API virtual Error _release(void* p) noexcept; 87 | 88 | //! Flushes an instruction cache. 89 | //! 90 | //! This member function is called after the code has been copied to the 91 | //! destination buffer. It is only useful for JIT code generation as it 92 | //! causes a flush of the processor's cache. 93 | //! 94 | //! Flushing is basically a NOP under X86, but is needed by architectures 95 | //! that do not have a transparent instruction cache like ARM. 96 | //! 97 | //! This function can also be overridden to improve compatibility with tools 98 | //! such as Valgrind, however, it's not an official part of AsmJit. 99 | ASMJIT_API virtual void flush(const void* p, size_t size) noexcept; 100 | 101 | //! \} 102 | }; 103 | 104 | //! \} 105 | 106 | ASMJIT_END_NAMESPACE 107 | 108 | #endif 109 | #endif 110 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/operand.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/operand.h" 10 | 11 | ASMJIT_BEGIN_NAMESPACE 12 | 13 | // ============================================================================ 14 | // [asmjit::Operand - Unit] 15 | // ============================================================================ 16 | 17 | #if defined(ASMJIT_TEST) 18 | UNIT(asmjit_core_operand) { 19 | INFO("Checking operand sizes"); 20 | EXPECT(sizeof(Operand) == 16); 21 | EXPECT(sizeof(BaseReg) == 16); 22 | EXPECT(sizeof(BaseMem) == 16); 23 | EXPECT(sizeof(Imm) == 16); 24 | EXPECT(sizeof(Label) == 16); 25 | 26 | INFO("Checking basic functionality of Operand"); 27 | Operand a, b; 28 | Operand dummy; 29 | 30 | EXPECT(a.isNone() == true); 31 | EXPECT(a.isReg() == false); 32 | EXPECT(a.isMem() == false); 33 | EXPECT(a.isImm() == false); 34 | EXPECT(a.isLabel() == false); 35 | EXPECT(a == b); 36 | EXPECT(a._data64 == 0); 37 | 38 | INFO("Checking basic functionality of Label"); 39 | Label label; 40 | EXPECT(label.isValid() == false); 41 | EXPECT(label.id() == Globals::kInvalidId); 42 | 43 | INFO("Checking basic functionality of BaseReg"); 44 | EXPECT(BaseReg().isReg() == true); 45 | EXPECT(BaseReg().isValid() == false); 46 | EXPECT(BaseReg()._data64 == 0); 47 | EXPECT(dummy.as().isValid() == false); 48 | 49 | // Create some register (not specific to any architecture). 50 | uint32_t rSig = Operand::kOpReg | (1 << Operand::kSignatureRegTypeShift ) | 51 | (2 << Operand::kSignatureRegGroupShift) | 52 | (8 << Operand::kSignatureSizeShift ) ; 53 | BaseReg r1(rSig, 5); 54 | 55 | EXPECT(r1.isValid() == true); 56 | EXPECT(r1.isReg() == true); 57 | EXPECT(r1.isReg(1) == true); 58 | EXPECT(r1.isPhysReg() == true); 59 | EXPECT(r1.isVirtReg() == false); 60 | EXPECT(r1.signature() == rSig); 61 | EXPECT(r1.type() == 1); 62 | EXPECT(r1.group() == 2); 63 | EXPECT(r1.size() == 8); 64 | EXPECT(r1.id() == 5); 65 | EXPECT(r1.isReg(1, 5) == true); // RegType and Id. 66 | EXPECT(r1._data64 == 0); 67 | 68 | // The same type of register having different id. 69 | BaseReg r2(r1, 6); 70 | EXPECT(r2.isValid() == true); 71 | EXPECT(r2.isReg() == true); 72 | EXPECT(r2.isReg(1) == true); 73 | EXPECT(r2.isPhysReg() == true); 74 | EXPECT(r2.isVirtReg() == false); 75 | EXPECT(r2.signature() == rSig); 76 | EXPECT(r2.type() == r1.type()); 77 | EXPECT(r2.group() == r1.group()); 78 | EXPECT(r2.size() == r1.size()); 79 | EXPECT(r2.id() == 6); 80 | EXPECT(r2.isReg(1, 6) == true); 81 | 82 | r1.reset(); 83 | EXPECT(!r1.isReg()); 84 | EXPECT(!r1.isValid()); 85 | 86 | INFO("Checking basic functionality of BaseMem"); 87 | BaseMem m; 88 | EXPECT(m.isMem()); 89 | EXPECT(m == BaseMem()); 90 | EXPECT(m.hasBase() == false); 91 | EXPECT(m.hasIndex() == false); 92 | EXPECT(m.hasOffset() == false); 93 | EXPECT(m.isOffset64Bit() == true); 94 | EXPECT(m.offset() == 0); 95 | 96 | m.setOffset(-1); 97 | EXPECT(m.offsetLo32() == -1); 98 | EXPECT(m.offset() == -1); 99 | 100 | int64_t x = int64_t(0xFF00FF0000000001u); 101 | int32_t xHi = int32_t(0xFF00FF00u); 102 | 103 | m.setOffset(x); 104 | EXPECT(m.offset() == x); 105 | EXPECT(m.offsetLo32() == 1); 106 | EXPECT(m.offsetHi32() == xHi); 107 | 108 | INFO("Checking basic functionality of Imm"); 109 | EXPECT(Imm(-1).i64() == int64_t(-1)); 110 | } 111 | #endif 112 | 113 | ASMJIT_END_NAMESPACE 114 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | .vs 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.sln.docstates 10 | 11 | # Build results 12 | [Dd]ebug/ 13 | [Dd]ebug.win32/ 14 | [Dd]ebugPublic/ 15 | [Rr]elease/ 16 | x64/ 17 | build/ 18 | bld/ 19 | [Bb]in/ 20 | [Oo]bj/ 21 | 22 | # Roslyn cache directories 23 | *.ide/ 24 | 25 | # MSTest test Results 26 | [Tt]est[Rr]esult*/ 27 | [Bb]uild[Ll]og.* 28 | 29 | #NUNIT 30 | *.VisualState.xml 31 | TestResult.xml 32 | 33 | # Build Results of an ATL Project 34 | [Dd]ebugPS/ 35 | [Rr]eleasePS/ 36 | dlldata.c 37 | 38 | *_i.c 39 | *_p.c 40 | *_i.h 41 | *.ilk 42 | *.meta 43 | *.obj 44 | *.pch 45 | *.pdb 46 | *.pgc 47 | *.pgd 48 | *.rsp 49 | *.sbr 50 | *.tlb 51 | *.tli 52 | *.tlh 53 | *.tmp 54 | *.tmp_proj 55 | *.log 56 | *.vspscc 57 | *.vssscc 58 | .builds 59 | *.pidb 60 | *.svclog 61 | *.scc 62 | 63 | # Chutzpah Test files 64 | _Chutzpah* 65 | 66 | # Visual C++ cache files 67 | ipch/ 68 | *.aps 69 | *.ncb 70 | *.opensdf 71 | *.sdf 72 | *.cachefile 73 | *.VC.db 74 | *.VC.opendb 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | *.vspx 80 | 81 | # TFS 2012 Local Workspace 82 | $tf/ 83 | 84 | # Guidance Automation Toolkit 85 | *.gpState 86 | 87 | # ReSharper is a .NET coding add-in 88 | _ReSharper*/ 89 | *.[Rr]e[Ss]harper 90 | *.DotSettings.user 91 | 92 | # JustCode is a .NET coding addin-in 93 | .JustCode 94 | 95 | # TeamCity is a build add-in 96 | _TeamCity* 97 | 98 | # DotCover is a Code Coverage Tool 99 | *.dotCover 100 | 101 | # NCrunch 102 | _NCrunch_* 103 | .*crunch*.local.xml 104 | 105 | # MightyMoose 106 | *.mm.* 107 | AutoTest.Net/ 108 | 109 | # Web workbench (sass) 110 | .sass-cache/ 111 | 112 | # Installshield output folder 113 | [Ee]xpress/ 114 | 115 | # DocProject is a documentation generator add-in 116 | DocProject/buildhelp/ 117 | DocProject/Help/*.HxT 118 | DocProject/Help/*.HxC 119 | DocProject/Help/*.hhc 120 | DocProject/Help/*.hhk 121 | DocProject/Help/*.hhp 122 | DocProject/Help/Html2 123 | DocProject/Help/html 124 | 125 | # Click-Once directory 126 | publish/ 127 | 128 | # Publish Web Output 129 | *.[Pp]ublish.xml 130 | *.azurePubxml 131 | ## TODO: Comment the next line if you want to checkin your 132 | ## web deploy settings but do note that will include unencrypted 133 | ## passwords 134 | #*.pubxml 135 | 136 | # NuGet Packages Directory 137 | packages/* 138 | ## TODO: If the tool you use requires repositories.config 139 | ## uncomment the next line 140 | #!packages/repositories.config 141 | 142 | # Enable "build/" folder in the NuGet Packages folder since 143 | # NuGet packages use it for MSBuild targets. 144 | # This line needs to be after the ignore of the build folder 145 | # (and the packages folder if the line above has been uncommented) 146 | !packages/build/ 147 | 148 | # Windows Azure Build Output 149 | csx/ 150 | *.build.csdef 151 | 152 | # Windows Store app package directory 153 | AppPackages/ 154 | 155 | # Others 156 | sql/ 157 | *.Cache 158 | ClientBin/ 159 | [Ss]tyle[Cc]op.* 160 | ~$* 161 | *~ 162 | *.dbmdl 163 | *.dbproj.schemaview 164 | *.pfx 165 | *.publishsettings 166 | node_modules/ 167 | bower_components/ 168 | 169 | # RIA/Silverlight projects 170 | Generated_Code/ 171 | 172 | # Backup & report files from converting an old project file 173 | # to a newer Visual Studio version. Backup files are not needed, 174 | # because we have git ;-) 175 | _UpgradeReport_Files/ 176 | Backup*/ 177 | UpgradeLog*.XML 178 | UpgradeLog*.htm 179 | 180 | # SQL Server files 181 | *.mdf 182 | *.ldf 183 | 184 | # Business Intelligence projects 185 | *.rdl.data 186 | *.bim.layout 187 | *.bim_*.settings 188 | 189 | # Microsoft Fakes 190 | FakesAssemblies/ 191 | 192 | # LightSwitch generated files 193 | GeneratedArtifacts/ 194 | _Pvt_Extensions/ 195 | ModelManifest.xml 196 | .idea/ 197 | cmake-build-debug/ 198 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/globals.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/globals.h" 10 | #include "../core/support.h" 11 | 12 | ASMJIT_BEGIN_NAMESPACE 13 | 14 | // ============================================================================ 15 | // [asmjit::DebugUtils] 16 | // ============================================================================ 17 | 18 | ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept { 19 | #ifndef ASMJIT_NO_TEXT 20 | static const char errorMessages[] = 21 | "Ok\0" 22 | "Out of memory\0" 23 | "Invalid argument\0" 24 | "Invalid state\0" 25 | "Invalid architecture\0" 26 | "Not initialized\0" 27 | "Already initialized\0" 28 | "Feature not enabled\0" 29 | "Too many handles or file descriptors\0" 30 | "Too large (code or memory request)\0" 31 | "No code generated\0" 32 | "Invalid directive\0" 33 | "Invalid label\0" 34 | "Too many labels\0" 35 | "Label already bound\0" 36 | "Label already defined\0" 37 | "Label name too long\0" 38 | "Invalid label name\0" 39 | "Invalid parent label\0" 40 | "Non-local label can't have parent\0" 41 | "Invalid section\0" 42 | "Too many sections\0" 43 | "Invalid section name\0" 44 | "Too many relocations\0" 45 | "Invalid relocation entry\0" 46 | "Relocation offset out of range\0" 47 | "Invalid assignment\0" 48 | "Invalid instruction\0" 49 | "Invalid register type\0" 50 | "Invalid register group\0" 51 | "Invalid register physical id\0" 52 | "Invalid register virtual id\0" 53 | "Invalid prefix combination\0" 54 | "Invalid lock prefix\0" 55 | "Invalid xacquire prefix\0" 56 | "Invalid xrelease prefix\0" 57 | "Invalid rep prefix\0" 58 | "Invalid rex prefix\0" 59 | "Invalid {...} register \0" 60 | "Invalid use of {k}\0" 61 | "Invalid use of {k}{z}\0" 62 | "Invalid broadcast {1tox}\0" 63 | "Invalid {er} or {sae} option\0" 64 | "Invalid address\0" 65 | "Invalid address index\0" 66 | "Invalid address scale\0" 67 | "Invalid use of 64-bit address or offset\0" 68 | "Invalid use of 64-bit address or offset that requires 32-bit zero-extension\0" 69 | "Invalid displacement\0" 70 | "Invalid segment\0" 71 | "Invalid immediate value\0" 72 | "Invalid operand size\0" 73 | "Ambiguous operand size\0" 74 | "Operand size mismatch\0" 75 | "Invalid option\0" 76 | "Option already defined\0" 77 | "Invalid type-info\0" 78 | "Invalid use of a low 8-bit GPB register\0" 79 | "Invalid use of a 64-bit GPQ register in 32-bit mode\0" 80 | "Invalid use of an 80-bit float\0" 81 | "Not consecutive registers\0" 82 | "No more physical registers\0" 83 | "Overlapped registers\0" 84 | "Overlapping register and arguments base-address register\0" 85 | "Unbound label cannot be evaluated by expression\0" 86 | "Arithmetic overflow during expression evaluation\0" 87 | "Unknown error\0"; 88 | return Support::findPackedString(errorMessages, Support::min(err, kErrorCount)); 89 | #else 90 | ASMJIT_UNUSED(err); 91 | static const char noMessage[] = ""; 92 | return noMessage; 93 | #endif 94 | } 95 | 96 | ASMJIT_FAVOR_SIZE void DebugUtils::debugOutput(const char* str) noexcept { 97 | #if defined(_WIN32) 98 | ::OutputDebugStringA(str); 99 | #else 100 | ::fputs(str, stderr); 101 | #endif 102 | } 103 | 104 | ASMJIT_FAVOR_SIZE void DebugUtils::assertionFailed(const char* file, int line, const char* msg) noexcept { 105 | char str[1024]; 106 | 107 | snprintf(str, 1024, 108 | "[asmjit] Assertion failed at %s (line %d):\n" 109 | "[asmjit] %s\n", file, line, msg); 110 | 111 | debugOutput(str); 112 | ::abort(); 113 | } 114 | 115 | ASMJIT_END_NAMESPACE 116 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmtk/asmtokenizer.h: -------------------------------------------------------------------------------- 1 | // [AsmTk] 2 | // Assembler toolkit based on AsmJit. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMTK_ASMTOKENIZER_H 8 | #define _ASMTK_ASMTOKENIZER_H 9 | 10 | #include "./globals.h" 11 | #include "./strtod.h" 12 | 13 | namespace asmtk { 14 | 15 | // ============================================================================ 16 | // [asmtk::AsmToken] 17 | // ============================================================================ 18 | 19 | //! Token. 20 | struct AsmToken { 21 | enum Type : uint32_t { 22 | kEnd, 23 | kNL, 24 | kSym, 25 | kNSym, 26 | kU64, 27 | kF64, 28 | kLCurl, 29 | kRCurl, 30 | kLBracket, 31 | kRBracket, 32 | kLParen, 33 | kRParen, 34 | kAdd, 35 | kSub, 36 | kMul, 37 | kDiv, 38 | kComma, 39 | kColon, 40 | kOther, 41 | kInvalid 42 | }; 43 | 44 | template 45 | inline bool _isImpl(size_t index, char c) noexcept { 46 | return data[index] == c; 47 | } 48 | 49 | template 50 | inline bool _isImpl(size_t index, char c, Args&&... args) noexcept { 51 | return data[index] == c && _isImpl(index + 1, args...); 52 | } 53 | 54 | template 55 | inline bool is(Args&&... args) noexcept { 56 | return size == sizeof...(args) && _isImpl(0, args...); 57 | } 58 | 59 | inline void reset() noexcept { 60 | type = kEnd; 61 | data = nullptr; 62 | size = 0; 63 | u64 = 0; 64 | } 65 | 66 | inline uint32_t setData(uint32_t type, const uint8_t* data, size_t size) noexcept { 67 | this->data = data; 68 | this->size = size; 69 | this->type = type; 70 | return type; 71 | } 72 | 73 | inline uint32_t setData(uint32_t type, const uint8_t* data, const uint8_t* end) noexcept { 74 | return setData(type, data, (size_t)(end - data)); 75 | } 76 | 77 | uint32_t type; 78 | const uint8_t* data; 79 | size_t size; 80 | 81 | union { 82 | double f64; 83 | int64_t i64; 84 | uint64_t u64; 85 | uint8_t valueBytes[8]; 86 | }; 87 | }; 88 | 89 | // ============================================================================ 90 | // [asmtk::AsmTokenizer] 91 | // ============================================================================ 92 | 93 | //! Tokenizer. 94 | class AsmTokenizer { 95 | public: 96 | //! Tokenizer options. 97 | enum ParseFlags : uint32_t { 98 | kParseSymbol = 0x00000001u, //!< Don't attempt to parse number (always parse symbol). 99 | kParseDashes = 0x00000002u //!< Consider dashes as text in a parsed symbol. 100 | }; 101 | 102 | //! Flags used during tokenization (cannot be used as options). 103 | enum StateFlags : uint32_t { 104 | kStateDotPrefix = 0x10000000u, //!< Parsed '.' prefix. 105 | kStateDollarPrefix = 0x20000000u, //!< Parsed '$' prefix. 106 | kStateNumberPrefix = 0x40000000u, //!< Parsed number prefix [0b|0x]. 107 | kStateNumberSuffix = 0x80000000u //!< Parsed number suffix [b|o|q|h]. 108 | }; 109 | 110 | //! Creates a tokanizer. 111 | ASMTK_API AsmTokenizer() noexcept; 112 | //! Destroys the tokanizer. 113 | ASMTK_API ~AsmTokenizer() noexcept; 114 | 115 | //! Parses a next `token` and advances. 116 | ASMTK_API uint32_t next(AsmToken* token, uint32_t flags = 0) noexcept; 117 | 118 | //! Puts a token back to the tokenizer so that `next()` would parse it again. 119 | inline void putBack(AsmToken* token) noexcept { 120 | _cur = token->data; 121 | } 122 | 123 | //! Sets the input of the tokenizer to `input` and `size`. The input doesn't 124 | //! have to be null terminated as the tokenizer would never go beyond the 125 | //! `size` specified. This means that the tokenizer can be used with string 126 | //! views. 127 | inline void setInput(const uint8_t* input, size_t size) noexcept { 128 | _input = input; 129 | _end = input + size; 130 | _cur = input; 131 | } 132 | 133 | const uint8_t* _input; 134 | const uint8_t* _end; 135 | const uint8_t* _cur; 136 | 137 | StrToD _stodctx; 138 | }; 139 | 140 | } // {asmtk} 141 | 142 | #endif // _ASMTK_ASMTOKENIZER_H 143 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/func.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/arch.h" 10 | #include "../core/func.h" 11 | #include "../core/type.h" 12 | 13 | #ifdef ASMJIT_BUILD_X86 14 | #include "../x86/x86internal_p.h" 15 | #include "../x86/x86operand.h" 16 | #endif 17 | 18 | #ifdef ASMJIT_BUILD_ARM 19 | #include "../arm/arminternal_p.h" 20 | #include "../arm/armoperand.h" 21 | #endif 22 | 23 | ASMJIT_BEGIN_NAMESPACE 24 | 25 | // ============================================================================ 26 | // [asmjit::FuncDetail - Init / Reset] 27 | // ============================================================================ 28 | 29 | ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& sign) { 30 | uint32_t ccId = sign.callConv(); 31 | CallConv& cc = _callConv; 32 | 33 | uint32_t argCount = sign.argCount(); 34 | if (ASMJIT_UNLIKELY(argCount > Globals::kMaxFuncArgs)) 35 | return DebugUtils::errored(kErrorInvalidArgument); 36 | 37 | ASMJIT_PROPAGATE(cc.init(ccId)); 38 | 39 | uint32_t gpSize = (cc.archId() == ArchInfo::kIdX86) ? 4 : 8; 40 | uint32_t deabstractDelta = Type::deabstractDeltaOfSize(gpSize); 41 | 42 | const uint8_t* args = sign.args(); 43 | for (uint32_t i = 0; i < argCount; i++) { 44 | FuncValue& arg = _args[i]; 45 | arg.initTypeId(Type::deabstract(args[i], deabstractDelta)); 46 | } 47 | _argCount = uint8_t(argCount); 48 | _vaIndex = uint8_t(sign.vaIndex()); 49 | 50 | uint32_t ret = sign.ret(); 51 | if (ret != Type::kIdVoid) { 52 | _rets[0].initTypeId(Type::deabstract(ret, deabstractDelta)); 53 | _retCount = 1; 54 | } 55 | 56 | #ifdef ASMJIT_BUILD_X86 57 | if (CallConv::isX86Family(ccId)) 58 | return x86::X86Internal::initFuncDetail(*this, sign, gpSize); 59 | #endif 60 | 61 | #ifdef ASMJIT_BUILD_ARM 62 | if (CallConv::isArmFamily(ccId)) 63 | return arm::ArmInternal::initFuncDetail(*this, sign, gpSize); 64 | #endif 65 | 66 | // We should never bubble here as if `cc.init()` succeeded then there has to 67 | // be an implementation for the current architecture. However, stay safe. 68 | return DebugUtils::errored(kErrorInvalidArgument); 69 | } 70 | 71 | // ============================================================================ 72 | // [asmjit::FuncFrame - Init / Reset / Finalize] 73 | // ============================================================================ 74 | 75 | ASMJIT_FAVOR_SIZE Error FuncFrame::init(const FuncDetail& func) noexcept { 76 | uint32_t ccId = func.callConv().id(); 77 | 78 | #ifdef ASMJIT_BUILD_X86 79 | if (CallConv::isX86Family(ccId)) 80 | return x86::X86Internal::initFuncFrame(*this, func); 81 | #endif 82 | 83 | #ifdef ASMJIT_BUILD_ARM 84 | if (CallConv::isArmFamily(ccId)) 85 | return arm::ArmInternal::initFuncFrame(*this, func); 86 | #endif 87 | 88 | return DebugUtils::errored(kErrorInvalidArgument); 89 | } 90 | 91 | ASMJIT_FAVOR_SIZE Error FuncFrame::finalize() noexcept { 92 | #ifdef ASMJIT_BUILD_X86 93 | if (ArchInfo::isX86Family(archId())) 94 | return x86::X86Internal::finalizeFuncFrame(*this); 95 | #endif 96 | 97 | #ifdef ASMJIT_BUILD_ARM 98 | if (ArchInfo::isArmFamily(archId())) 99 | return arm::ArmInternal::finalizeFuncFrame(*this); 100 | #endif 101 | 102 | return DebugUtils::errored(kErrorInvalidArgument); 103 | } 104 | 105 | // ============================================================================ 106 | // [asmjit::FuncArgsAssignment] 107 | // ============================================================================ 108 | 109 | ASMJIT_FAVOR_SIZE Error FuncArgsAssignment::updateFuncFrame(FuncFrame& frame) const noexcept { 110 | const FuncDetail* func = funcDetail(); 111 | if (!func) return DebugUtils::errored(kErrorInvalidState); 112 | 113 | uint32_t ccId = func->callConv().id(); 114 | 115 | #ifdef ASMJIT_BUILD_X86 116 | if (CallConv::isX86Family(ccId)) 117 | return x86::X86Internal::argsToFuncFrame(*this, frame); 118 | #endif 119 | 120 | #ifdef ASMJIT_BUILD_ARM 121 | if (CallConv::isArmFamily(ccId)) 122 | return arm::ArmInternal::argsToFuncFrame(*this, frame); 123 | #endif 124 | 125 | return DebugUtils::errored(kErrorInvalidArch); 126 | } 127 | 128 | ASMJIT_END_NAMESPACE 129 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/inst.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/build.h" 10 | #ifdef ASMJIT_BUILD_X86 11 | 12 | #include "../core/arch.h" 13 | #include "../core/inst.h" 14 | 15 | #ifdef ASMJIT_BUILD_X86 16 | #include "../x86/x86instapi_p.h" 17 | #endif 18 | 19 | #ifdef ASMJIT_BUILD_ARM 20 | #include "../arm/arminstapi_p.h" 21 | #endif 22 | 23 | ASMJIT_BEGIN_NAMESPACE 24 | 25 | // ============================================================================ 26 | // [asmjit::InstAPI - Text] 27 | // ============================================================================ 28 | 29 | #ifndef ASMJIT_NO_TEXT 30 | Error InstAPI::instIdToString(uint32_t archId, uint32_t instId, String& output) noexcept { 31 | #ifdef ASMJIT_BUILD_X86 32 | if (ArchInfo::isX86Family(archId)) 33 | return x86::InstInternal::instIdToString(archId, instId, output); 34 | #endif 35 | 36 | #ifdef ASMJIT_BUILD_ARM 37 | if (ArchInfo::isArmFamily(archId)) 38 | return arm::InstInternal::instIdToString(archId, instId, output); 39 | #endif 40 | 41 | return DebugUtils::errored(kErrorInvalidArch); 42 | } 43 | 44 | uint32_t InstAPI::stringToInstId(uint32_t archId, const char* s, size_t len) noexcept { 45 | #ifdef ASMJIT_BUILD_X86 46 | if (ArchInfo::isX86Family(archId)) 47 | return x86::InstInternal::stringToInstId(archId, s, len); 48 | #endif 49 | 50 | #ifdef ASMJIT_BUILD_ARM 51 | if (ArchInfo::isArmFamily(archId)) 52 | return arm::InstInternal::stringToInstId(archId, s, len); 53 | #endif 54 | 55 | return 0; 56 | } 57 | #endif // !ASMJIT_NO_TEXT 58 | 59 | // ============================================================================ 60 | // [asmjit::InstAPI - Validate] 61 | // ============================================================================ 62 | 63 | #ifndef ASMJIT_NO_VALIDATION 64 | Error InstAPI::validate(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount) noexcept { 65 | #ifdef ASMJIT_BUILD_X86 66 | if (ArchInfo::isX86Family(archId)) 67 | return x86::InstInternal::validate(archId, inst, operands, opCount); 68 | #endif 69 | 70 | #ifdef ASMJIT_BUILD_ARM 71 | if (ArchInfo::isArmFamily(archId)) 72 | return arm::InstInternal::validate(archId, inst, operands, opCount); 73 | #endif 74 | 75 | return DebugUtils::errored(kErrorInvalidArch); 76 | } 77 | #endif // !ASMJIT_NO_VALIDATION 78 | 79 | // ============================================================================ 80 | // [asmjit::InstAPI - QueryRWInfo] 81 | // ============================================================================ 82 | 83 | #ifndef ASMJIT_NO_INTROSPECTION 84 | Error InstAPI::queryRWInfo(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount, InstRWInfo& out) noexcept { 85 | if (ASMJIT_UNLIKELY(opCount > 6)) 86 | return DebugUtils::errored(kErrorInvalidArgument); 87 | 88 | #ifdef ASMJIT_BUILD_X86 89 | if (ArchInfo::isX86Family(archId)) 90 | return x86::InstInternal::queryRWInfo(archId, inst, operands, opCount, out); 91 | #endif 92 | 93 | #ifdef ASMJIT_BUILD_ARM 94 | if (ArchInfo::isArmFamily(archId)) 95 | return arm::InstInternal::queryRWInfo(archId, inst, operands, opCount, out); 96 | #endif 97 | 98 | return DebugUtils::errored(kErrorInvalidArch); 99 | } 100 | #endif // !ASMJIT_NO_INTROSPECTION 101 | 102 | // ============================================================================ 103 | // [asmjit::InstAPI - QueryFeatures] 104 | // ============================================================================ 105 | 106 | #ifndef ASMJIT_NO_INTROSPECTION 107 | Error InstAPI::queryFeatures(uint32_t archId, const BaseInst& inst, const Operand_* operands, uint32_t opCount, BaseFeatures& out) noexcept { 108 | #ifdef ASMJIT_BUILD_X86 109 | if (ArchInfo::isX86Family(archId)) 110 | return x86::InstInternal::queryFeatures(archId, inst, operands, opCount, out); 111 | #endif 112 | 113 | #ifdef ASMJIT_BUILD_ARM 114 | if (ArchInfo::isArmFamily(archId)) 115 | return arm::InstInternal::queryFeatures(archId, inst, operands, opCount, out); 116 | #endif 117 | 118 | return DebugUtils::errored(kErrorInvalidArch); 119 | } 120 | #endif // !ASMJIT_NO_INTROSPECTION 121 | 122 | ASMJIT_END_NAMESPACE 123 | 124 | #endif // ASMJIT_BUILD_X86 125 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/features.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_FEATURES_H 8 | #define _ASMJIT_CORE_FEATURES_H 9 | 10 | #include "../core/globals.h" 11 | #include "../core/support.h" 12 | 13 | ASMJIT_BEGIN_NAMESPACE 14 | 15 | //! \addtogroup asmjit_core 16 | //! \{ 17 | 18 | // ============================================================================ 19 | // [asmjit::BaseFeatures] 20 | // ============================================================================ 21 | 22 | class BaseFeatures { 23 | public: 24 | typedef Support::BitWord BitWord; 25 | 26 | enum : uint32_t { 27 | kMaxFeatures = 128, 28 | kNumBitWords = kMaxFeatures / Support::kBitWordSizeInBits 29 | }; 30 | 31 | BitWord _bits[kNumBitWords]; 32 | 33 | //! \name Construction & Destruction 34 | //! \{ 35 | 36 | inline BaseFeatures() noexcept { reset(); } 37 | inline BaseFeatures(const BaseFeatures& other) noexcept = default; 38 | inline explicit BaseFeatures(Globals::NoInit_) noexcept {} 39 | 40 | inline void reset() noexcept { 41 | for (size_t i = 0; i < kNumBitWords; i++) 42 | _bits[i] = 0; 43 | } 44 | 45 | //! \} 46 | 47 | //! \name Overloaded Operators 48 | //! \{ 49 | 50 | inline BaseFeatures& operator=(const BaseFeatures& other) noexcept = default; 51 | 52 | inline bool operator==(const BaseFeatures& other) noexcept { return eq(other); } 53 | inline bool operator!=(const BaseFeatures& other) noexcept { return !eq(other); } 54 | 55 | //! \} 56 | 57 | //! \name Cast 58 | //! \{ 59 | 60 | template 61 | inline T& as() noexcept { return static_cast(*this); } 62 | 63 | template 64 | inline const T& as() const noexcept { return static_cast(*this); } 65 | 66 | //! \} 67 | 68 | //! \name Accessors 69 | //! \{ 70 | 71 | //! Returns all features as `BitWord` array. 72 | inline BitWord* bits() noexcept { return _bits; } 73 | //! Returns all features as `BitWord` array (const). 74 | inline const BitWord* bits() const noexcept { return _bits; } 75 | 76 | //! Tests whether the feature `featureId` is present. 77 | inline bool has(uint32_t featureId) const noexcept { 78 | ASMJIT_ASSERT(featureId < kMaxFeatures); 79 | 80 | uint32_t idx = featureId / Support::kBitWordSizeInBits; 81 | uint32_t bit = featureId % Support::kBitWordSizeInBits; 82 | 83 | return bool((_bits[idx] >> bit) & 0x1); 84 | } 85 | 86 | //! Tests whether all features as defined by `other` are present. 87 | inline bool hasAll(const BaseFeatures& other) const noexcept { 88 | for (uint32_t i = 0; i < kNumBitWords; i++) 89 | if ((_bits[i] & other._bits[i]) != other._bits[i]) 90 | return false; 91 | return true; 92 | } 93 | 94 | //! \} 95 | 96 | //! \name Utilities 97 | //! \{ 98 | 99 | //! Adds the given CPU `featureId` to the list of features. 100 | inline void add(uint32_t featureId) noexcept { 101 | ASMJIT_ASSERT(featureId < kMaxFeatures); 102 | 103 | uint32_t idx = featureId / Support::kBitWordSizeInBits; 104 | uint32_t bit = featureId % Support::kBitWordSizeInBits; 105 | 106 | _bits[idx] |= BitWord(1) << bit; 107 | } 108 | 109 | template 110 | inline void add(uint32_t featureId, ArgsT... otherIds) noexcept { 111 | add(featureId); 112 | add(otherIds...); 113 | } 114 | 115 | //! Removes the given CPU `featureId` from the list of features. 116 | inline void remove(uint32_t featureId) noexcept { 117 | ASMJIT_ASSERT(featureId < kMaxFeatures); 118 | 119 | uint32_t idx = featureId / Support::kBitWordSizeInBits; 120 | uint32_t bit = featureId % Support::kBitWordSizeInBits; 121 | 122 | _bits[idx] &= ~(BitWord(1) << bit); 123 | } 124 | 125 | template 126 | inline void remove(uint32_t featureId, ArgsT... otherIds) noexcept { 127 | remove(featureId); 128 | remove(otherIds...); 129 | } 130 | 131 | inline bool eq(const BaseFeatures& other) const noexcept { 132 | for (size_t i = 0; i < kNumBitWords; i++) 133 | if (_bits[i] != other._bits[i]) 134 | return false; 135 | return true; 136 | } 137 | 138 | //! \} 139 | }; 140 | 141 | //! \} 142 | 143 | ASMJIT_END_NAMESPACE 144 | 145 | #endif // _ASMJIT_CORE_FEATURES_H 146 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/zonelist.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/zone.h" 10 | #include "../core/zonelist.h" 11 | 12 | ASMJIT_BEGIN_NAMESPACE 13 | 14 | // ============================================================================ 15 | // [asmjit::ZoneList - Unit] 16 | // ============================================================================ 17 | 18 | #if defined(ASMJIT_TEST) 19 | class MyListNode : public ZoneListNode {}; 20 | 21 | UNIT(asmjit_zone_list) { 22 | Zone zone(4096); 23 | ZoneList list; 24 | 25 | MyListNode* a = zone.newT(); 26 | MyListNode* b = zone.newT(); 27 | MyListNode* c = zone.newT(); 28 | MyListNode* d = zone.newT(); 29 | 30 | INFO("Append / Unlink"); 31 | 32 | // [] 33 | EXPECT(list.empty() == true); 34 | 35 | // [A] 36 | list.append(a); 37 | EXPECT(list.empty() == false); 38 | EXPECT(list.first() == a); 39 | EXPECT(list.last() == a); 40 | EXPECT(a->prev() == nullptr); 41 | EXPECT(a->next() == nullptr); 42 | 43 | // [A, B] 44 | list.append(b); 45 | EXPECT(list.first() == a); 46 | EXPECT(list.last() == b); 47 | EXPECT(a->prev() == nullptr); 48 | EXPECT(a->next() == b); 49 | EXPECT(b->prev() == a); 50 | EXPECT(b->next() == nullptr); 51 | 52 | // [A, B, C] 53 | list.append(c); 54 | EXPECT(list.first() == a); 55 | EXPECT(list.last() == c); 56 | EXPECT(a->prev() == nullptr); 57 | EXPECT(a->next() == b); 58 | EXPECT(b->prev() == a); 59 | EXPECT(b->next() == c); 60 | EXPECT(c->prev() == b); 61 | EXPECT(c->next() == nullptr); 62 | 63 | // [B, C] 64 | list.unlink(a); 65 | EXPECT(list.first() == b); 66 | EXPECT(list.last() == c); 67 | EXPECT(a->prev() == nullptr); 68 | EXPECT(a->next() == nullptr); 69 | EXPECT(b->prev() == nullptr); 70 | EXPECT(b->next() == c); 71 | EXPECT(c->prev() == b); 72 | EXPECT(c->next() == nullptr); 73 | 74 | // [B] 75 | list.unlink(c); 76 | EXPECT(list.first() == b); 77 | EXPECT(list.last() == b); 78 | EXPECT(b->prev() == nullptr); 79 | EXPECT(b->next() == nullptr); 80 | EXPECT(c->prev() == nullptr); 81 | EXPECT(c->next() == nullptr); 82 | 83 | // [] 84 | list.unlink(b); 85 | EXPECT(list.empty() == true); 86 | EXPECT(list.first() == nullptr); 87 | EXPECT(list.last() == nullptr); 88 | EXPECT(b->prev() == nullptr); 89 | EXPECT(b->next() == nullptr); 90 | 91 | INFO("Prepend / Unlink"); 92 | 93 | // [A] 94 | list.prepend(a); 95 | EXPECT(list.empty() == false); 96 | EXPECT(list.first() == a); 97 | EXPECT(list.last() == a); 98 | EXPECT(a->prev() == nullptr); 99 | EXPECT(a->next() == nullptr); 100 | 101 | // [B, A] 102 | list.prepend(b); 103 | EXPECT(list.first() == b); 104 | EXPECT(list.last() == a); 105 | EXPECT(b->prev() == nullptr); 106 | EXPECT(b->next() == a); 107 | EXPECT(a->prev() == b); 108 | EXPECT(a->next() == nullptr); 109 | 110 | INFO("InsertAfter / InsertBefore"); 111 | 112 | // [B, A, C] 113 | list.insertAfter(a, c); 114 | EXPECT(list.first() == b); 115 | EXPECT(list.last() == c); 116 | EXPECT(b->prev() == nullptr); 117 | EXPECT(b->next() == a); 118 | EXPECT(a->prev() == b); 119 | EXPECT(a->next() == c); 120 | EXPECT(c->prev() == a); 121 | EXPECT(c->next() == nullptr); 122 | 123 | // [B, D, A, C] 124 | list.insertBefore(a, d); 125 | EXPECT(list.first() == b); 126 | EXPECT(list.last() == c); 127 | EXPECT(b->prev() == nullptr); 128 | EXPECT(b->next() == d); 129 | EXPECT(d->prev() == b); 130 | EXPECT(d->next() == a); 131 | EXPECT(a->prev() == d); 132 | EXPECT(a->next() == c); 133 | EXPECT(c->prev() == a); 134 | EXPECT(c->next() == nullptr); 135 | 136 | INFO("PopFirst / Pop"); 137 | 138 | // [D, A, C] 139 | EXPECT(list.popFirst() == b); 140 | EXPECT(b->prev() == nullptr); 141 | EXPECT(b->next() == nullptr); 142 | 143 | EXPECT(list.first() == d); 144 | EXPECT(list.last() == c); 145 | EXPECT(d->prev() == nullptr); 146 | EXPECT(d->next() == a); 147 | EXPECT(a->prev() == d); 148 | EXPECT(a->next() == c); 149 | EXPECT(c->prev() == a); 150 | EXPECT(c->next() == nullptr); 151 | 152 | // [D, A] 153 | EXPECT(list.pop() == c); 154 | EXPECT(c->prev() == nullptr); 155 | EXPECT(c->next() == nullptr); 156 | 157 | EXPECT(list.first() == d); 158 | EXPECT(list.last() == a); 159 | EXPECT(d->prev() == nullptr); 160 | EXPECT(d->next() == a); 161 | EXPECT(a->prev() == d); 162 | EXPECT(a->next() == nullptr); 163 | } 164 | #endif 165 | 166 | ASMJIT_END_NAMESPACE 167 | -------------------------------------------------------------------------------- /SelfHackingApp/External/libudis86/extern.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/extern.h 2 | * 3 | * Copyright (c) 2002-2009, 2013 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_EXTERN_H 27 | #define UD_EXTERN_H 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | #include "types.h" 34 | 35 | #if defined(_MSC_VER) && defined(_USRDLL) 36 | # ifdef LIBUDIS86_EXPORTS 37 | # define LIBUDIS86_DLLEXTERN __declspec(dllexport) 38 | # else 39 | # define LIBUDIS86_DLLEXTERN __declspec(dllimport) 40 | # endif 41 | #else 42 | # define LIBUDIS86_DLLEXTERN 43 | #endif 44 | 45 | /* ============================= PUBLIC API ================================= */ 46 | 47 | extern LIBUDIS86_DLLEXTERN void ud_init(struct ud*); 48 | 49 | extern LIBUDIS86_DLLEXTERN void ud_set_mode(struct ud*, uint8_t); 50 | 51 | extern LIBUDIS86_DLLEXTERN void ud_set_pc(struct ud*, uint64_t); 52 | 53 | extern LIBUDIS86_DLLEXTERN void ud_set_input_hook(struct ud*, int(*)(struct ud*)); 54 | 55 | extern LIBUDIS86_DLLEXTERN void ud_set_input_buffer(struct ud*, const uint8_t*, size_t); 56 | 57 | #ifndef __UD_STANDALONE__ 58 | extern LIBUDIS86_DLLEXTERN void ud_set_input_file(struct ud*, FILE*); 59 | #endif /* __UD_STANDALONE__ */ 60 | 61 | extern LIBUDIS86_DLLEXTERN void ud_set_vendor(struct ud*, unsigned); 62 | 63 | extern LIBUDIS86_DLLEXTERN void ud_set_syntax(struct ud*, void(*)(struct ud*)); 64 | 65 | extern LIBUDIS86_DLLEXTERN void ud_input_skip(struct ud*, size_t); 66 | 67 | extern LIBUDIS86_DLLEXTERN int ud_input_end(const struct ud*); 68 | 69 | extern LIBUDIS86_DLLEXTERN unsigned int ud_decode(struct ud*); 70 | 71 | extern LIBUDIS86_DLLEXTERN unsigned int ud_disassemble(struct ud*); 72 | 73 | extern LIBUDIS86_DLLEXTERN void ud_translate_intel(struct ud*); 74 | 75 | extern LIBUDIS86_DLLEXTERN void ud_translate_att(struct ud*); 76 | 77 | extern LIBUDIS86_DLLEXTERN const char* ud_insn_asm(const struct ud* u); 78 | 79 | extern LIBUDIS86_DLLEXTERN const uint8_t* ud_insn_ptr(const struct ud* u); 80 | 81 | extern LIBUDIS86_DLLEXTERN uint64_t ud_insn_off(const struct ud*); 82 | 83 | extern LIBUDIS86_DLLEXTERN const char* ud_insn_hex(struct ud*); 84 | 85 | extern LIBUDIS86_DLLEXTERN unsigned int ud_insn_len(const struct ud* u); 86 | 87 | extern LIBUDIS86_DLLEXTERN const struct ud_operand* ud_insn_opr(const struct ud *u, unsigned int n); 88 | 89 | extern LIBUDIS86_DLLEXTERN int ud_opr_is_sreg(const struct ud_operand *opr); 90 | 91 | extern LIBUDIS86_DLLEXTERN int ud_opr_is_gpr(const struct ud_operand *opr); 92 | 93 | extern LIBUDIS86_DLLEXTERN enum ud_mnemonic_code ud_insn_mnemonic(const struct ud *u); 94 | 95 | extern LIBUDIS86_DLLEXTERN const char* ud_lookup_mnemonic(enum ud_mnemonic_code c); 96 | 97 | extern LIBUDIS86_DLLEXTERN void ud_set_user_opaque_data(struct ud*, void*); 98 | 99 | extern LIBUDIS86_DLLEXTERN void* ud_get_user_opaque_data(const struct ud*); 100 | 101 | extern LIBUDIS86_DLLEXTERN void ud_set_asm_buffer(struct ud *u, char *buf, size_t size); 102 | 103 | extern LIBUDIS86_DLLEXTERN void ud_set_sym_resolver(struct ud *u, 104 | const char* (*resolver)(struct ud*, 105 | uint64_t addr, 106 | int64_t *offset)); 107 | 108 | /* ========================================================================== */ 109 | 110 | #ifdef __cplusplus 111 | } 112 | #endif 113 | #endif /* UD_EXTERN_H */ -------------------------------------------------------------------------------- /SelfHackingApp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30011.22 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SelfHackingApp", "SelfHackingApp\SelfHackingApp.vcxproj", "{4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|Mixed Platforms = Debug|Mixed Platforms 12 | Debug|Win32 = Debug|Win32 13 | Debug|x64 = Debug|x64 14 | Debug|x86 = Debug|x86 15 | Debug-DLL|Any CPU = Debug-DLL|Any CPU 16 | Debug-DLL|Mixed Platforms = Debug-DLL|Mixed Platforms 17 | Debug-DLL|Win32 = Debug-DLL|Win32 18 | Debug-DLL|x64 = Debug-DLL|x64 19 | Debug-DLL|x86 = Debug-DLL|x86 20 | Release|Any CPU = Release|Any CPU 21 | Release|Mixed Platforms = Release|Mixed Platforms 22 | Release|Win32 = Release|Win32 23 | Release|x64 = Release|x64 24 | Release|x86 = Release|x86 25 | Release-DLL|Any CPU = Release-DLL|Any CPU 26 | Release-DLL|Mixed Platforms = Release-DLL|Mixed Platforms 27 | Release-DLL|Win32 = Release-DLL|Win32 28 | Release-DLL|x64 = Release-DLL|x64 29 | Release-DLL|x86 = Release-DLL|x86 30 | EndGlobalSection 31 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 32 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug|Any CPU.ActiveCfg = Debug|Win32 33 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 34 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug|Mixed Platforms.Build.0 = Debug|Win32 35 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug|Win32.ActiveCfg = Debug|Win32 36 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug|Win32.Build.0 = Debug|Win32 37 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug|x64.ActiveCfg = Debug|x64 38 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug|x64.Build.0 = Debug|x64 39 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug|x86.ActiveCfg = Debug|Win32 40 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug|x86.Build.0 = Debug|Win32 41 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug-DLL|Any CPU.ActiveCfg = Release|x64 42 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug-DLL|Any CPU.Build.0 = Release|x64 43 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug-DLL|Mixed Platforms.ActiveCfg = Debug|Win32 44 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug-DLL|Mixed Platforms.Build.0 = Debug|Win32 45 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 46 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug-DLL|Win32.Build.0 = Debug|Win32 47 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug-DLL|x64.ActiveCfg = Debug|x64 48 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug-DLL|x64.Build.0 = Debug|x64 49 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug-DLL|x86.ActiveCfg = Debug|Win32 50 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Debug-DLL|x86.Build.0 = Debug|Win32 51 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release|Any CPU.ActiveCfg = Release|Win32 52 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release|Mixed Platforms.ActiveCfg = Release|Win32 53 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release|Mixed Platforms.Build.0 = Release|Win32 54 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release|Win32.ActiveCfg = Release|Win32 55 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release|Win32.Build.0 = Release|Win32 56 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release|x64.ActiveCfg = Release|x64 57 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release|x64.Build.0 = Release|x64 58 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release|x86.ActiveCfg = Release|Win32 59 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release|x86.Build.0 = Release|Win32 60 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release-DLL|Any CPU.ActiveCfg = Release|x64 61 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release-DLL|Any CPU.Build.0 = Release|x64 62 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release-DLL|Mixed Platforms.ActiveCfg = Release|Win32 63 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release-DLL|Mixed Platforms.Build.0 = Release|Win32 64 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release-DLL|Win32.ActiveCfg = Release|Win32 65 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release-DLL|Win32.Build.0 = Release|Win32 66 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release-DLL|x64.ActiveCfg = Release|x64 67 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release-DLL|x64.Build.0 = Release|x64 68 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release-DLL|x86.ActiveCfg = Release|Win32 69 | {4D63A5FC-1BFB-4AA4-8A48-00223BC2C822}.Release-DLL|x86.Build.0 = Release|Win32 70 | EndGlobalSection 71 | GlobalSection(SolutionProperties) = preSolution 72 | HideSolutionNode = FALSE 73 | EndGlobalSection 74 | GlobalSection(ExtensibilityGlobals) = postSolution 75 | SolutionGuid = {35A231B7-B8D3-48E3-A17A-264304ECB04E} 76 | EndGlobalSection 77 | EndGlobal 78 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/cpuinfo.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_CPUINFO_H 8 | #define _ASMJIT_CORE_CPUINFO_H 9 | 10 | #include "../core/arch.h" 11 | #include "../core/features.h" 12 | #include "../core/globals.h" 13 | #include "../core/string.h" 14 | 15 | ASMJIT_BEGIN_NAMESPACE 16 | 17 | //! \addtogroup asmjit_support 18 | //! \{ 19 | 20 | // ============================================================================ 21 | // [asmjit::CpuInfo] 22 | // ============================================================================ 23 | 24 | //! CPU information. 25 | class CpuInfo { 26 | public: 27 | //! CPU architecture information. 28 | ArchInfo _archInfo; 29 | //! CPU family ID. 30 | uint32_t _familyId; 31 | //! CPU model ID. 32 | uint32_t _modelId; 33 | //! CPU brand ID. 34 | uint32_t _brandId; 35 | //! CPU stepping. 36 | uint32_t _stepping; 37 | //! Processor type. 38 | uint32_t _processorType; 39 | //! Maximum number of addressable IDs for logical processors. 40 | uint32_t _maxLogicalProcessors; 41 | //! Cache line size (in bytes). 42 | uint32_t _cacheLineSize; 43 | //! Number of hardware threads. 44 | uint32_t _hwThreadCount; 45 | 46 | //! CPU vendor string. 47 | FixedString<16> _vendor; 48 | //! CPU brand string. 49 | FixedString<64> _brand; 50 | //! CPU features. 51 | BaseFeatures _features; 52 | 53 | //! \name Construction & Destruction 54 | //! \{ 55 | 56 | inline CpuInfo() noexcept { reset(); } 57 | inline CpuInfo(const CpuInfo& other) noexcept = default; 58 | 59 | inline explicit CpuInfo(Globals::NoInit_) noexcept 60 | : _archInfo(Globals::NoInit), 61 | _features(Globals::NoInit) {}; 62 | 63 | //! Returns the host CPU information. 64 | ASMJIT_API static const CpuInfo& host() noexcept; 65 | 66 | //! Initializes CpuInfo to the given architecture, see `ArchInfo`. 67 | inline void initArch(uint32_t archId, uint32_t archMode = 0) noexcept { 68 | _archInfo.init(archId, archMode); 69 | } 70 | 71 | inline void reset() noexcept { memset(this, 0, sizeof(*this)); } 72 | 73 | //! \} 74 | 75 | //! \name Overloaded Operators 76 | //! \{ 77 | 78 | inline CpuInfo& operator=(const CpuInfo& other) noexcept = default; 79 | 80 | //! \} 81 | 82 | //! \name Accessors 83 | //! \{ 84 | 85 | //! Returns the CPU architecture information. 86 | inline const ArchInfo& archInfo() const noexcept { return _archInfo; } 87 | //! Returns the CPU architecture id, see `ArchInfo::Id`. 88 | inline uint32_t archId() const noexcept { return _archInfo.archId(); } 89 | //! Returns the CPU architecture sub-id, see `ArchInfo::SubId`. 90 | inline uint32_t archSubId() const noexcept { return _archInfo.archSubId(); } 91 | 92 | //! Returns the CPU family ID. 93 | inline uint32_t familyId() const noexcept { return _familyId; } 94 | //! Returns the CPU model ID. 95 | inline uint32_t modelId() const noexcept { return _modelId; } 96 | //! Returns the CPU brand id. 97 | inline uint32_t brandId() const noexcept { return _brandId; } 98 | //! Returns the CPU stepping. 99 | inline uint32_t stepping() const noexcept { return _stepping; } 100 | //! Returns the processor type. 101 | inline uint32_t processorType() const noexcept { return _processorType; } 102 | //! Returns the number of maximum logical processors. 103 | inline uint32_t maxLogicalProcessors() const noexcept { return _maxLogicalProcessors; } 104 | 105 | //! Returns the size of a cache line flush. 106 | inline uint32_t cacheLineSize() const noexcept { return _cacheLineSize; } 107 | //! Returns number of hardware threads available. 108 | inline uint32_t hwThreadCount() const noexcept { return _hwThreadCount; } 109 | 110 | //! Returns the CPU vendor. 111 | inline const char* vendor() const noexcept { return _vendor.str; } 112 | //! Tests whether the CPU vendor is equal to `s`. 113 | inline bool isVendor(const char* s) const noexcept { return _vendor.eq(s); } 114 | 115 | //! Returns the CPU brand string. 116 | inline const char* brand() const noexcept { return _brand.str; } 117 | 118 | //! Returns all CPU features as `BaseFeatures`, cast to your arch-specific class 119 | //! if needed. 120 | template 121 | inline const T& features() const noexcept { return _features.as(); } 122 | 123 | //! Tests whether the CPU has the given `feature`. 124 | inline bool hasFeature(uint32_t featureId) const noexcept { return _features.has(featureId); } 125 | //! Adds the given CPU `feature` to the list of this CpuInfo features. 126 | inline CpuInfo& addFeature(uint32_t featureId) noexcept { _features.add(featureId); return *this; } 127 | 128 | //! \} 129 | }; 130 | 131 | //! \} 132 | 133 | ASMJIT_END_NAMESPACE 134 | 135 | #endif // _ASMJIT_CORE_CPUINFO_H 136 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/jitruntime.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/build.h" 10 | #ifndef ASMJIT_NO_JIT 11 | 12 | #include "../core/cpuinfo.h" 13 | #include "../core/jitruntime.h" 14 | 15 | ASMJIT_BEGIN_NAMESPACE 16 | 17 | // ============================================================================ 18 | // [asmjit::JitRuntime - Utilities] 19 | // ============================================================================ 20 | 21 | // Only useful on non-x86 architectures. 22 | static inline void JitRuntime_flushInstructionCache(const void* p, size_t size) noexcept { 23 | #if defined(_WIN32) && !ASMJIT_ARCH_X86 24 | // Windows has a built-in support in `kernel32.dll`. 25 | ::FlushInstructionCache(::GetCurrentProcess(), p, size); 26 | #else 27 | ASMJIT_UNUSED(p); 28 | ASMJIT_UNUSED(size); 29 | #endif 30 | } 31 | 32 | // X86 Target 33 | // ---------- 34 | // 35 | // - 32-bit - Linux, OSX, BSD, and apparently also Haiku guarantee 16-byte 36 | // stack alignment. Other operating systems are assumed to have 37 | // 4-byte alignment by default for safety reasons. 38 | // - 64-bit - stack must be aligned to 16 bytes. 39 | // 40 | // ARM Target 41 | // ---------- 42 | // 43 | // - 32-bit - Stack must be aligned to 8 bytes. 44 | // - 64-bit - Stack must be aligned to 16 bytes (hardware requirement). 45 | static inline uint32_t JitRuntime_detectNaturalStackAlignment() noexcept { 46 | #if ASMJIT_ARCH_BITS == 64 || \ 47 | defined(__APPLE__ ) || \ 48 | defined(__DragonFly__) || \ 49 | defined(__HAIKU__ ) || \ 50 | defined(__FreeBSD__ ) || \ 51 | defined(__NetBSD__ ) || \ 52 | defined(__OpenBSD__ ) || \ 53 | defined(__bsdi__ ) || \ 54 | defined(__linux__ ) 55 | return 16; 56 | #elif ASMJIT_ARCH_ARM 57 | return 8; 58 | #else 59 | return uint32_t(sizeof(uintptr_t)); 60 | #endif 61 | } 62 | 63 | // ============================================================================ 64 | // [asmjit::JitRuntime - Construction / Destruction] 65 | // ============================================================================ 66 | 67 | JitRuntime::JitRuntime(const JitAllocator::CreateParams* params) noexcept 68 | : _allocator(params) { 69 | 70 | // Setup target properties. 71 | _targetType = kTargetJit; 72 | _codeInfo._archInfo = CpuInfo::host().archInfo(); 73 | _codeInfo._stackAlignment = uint8_t(JitRuntime_detectNaturalStackAlignment()); 74 | _codeInfo._cdeclCallConv = CallConv::kIdHostCDecl; 75 | _codeInfo._stdCallConv = CallConv::kIdHostStdCall; 76 | _codeInfo._fastCallConv = CallConv::kIdHostFastCall; 77 | } 78 | JitRuntime::~JitRuntime() noexcept {} 79 | 80 | // ============================================================================ 81 | // [asmjit::JitRuntime - Interface] 82 | // ============================================================================ 83 | 84 | Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept { 85 | *dst = nullptr; 86 | 87 | ASMJIT_PROPAGATE(code->flatten()); 88 | ASMJIT_PROPAGATE(code->resolveUnresolvedLinks()); 89 | 90 | size_t estimatedCodeSize = code->codeSize(); 91 | if (ASMJIT_UNLIKELY(estimatedCodeSize == 0)) 92 | return DebugUtils::errored(kErrorNoCodeGenerated); 93 | 94 | uint8_t* ro; 95 | uint8_t* rw; 96 | ASMJIT_PROPAGATE(_allocator.alloc((void**)&ro, (void**)&rw, estimatedCodeSize)); 97 | 98 | // Relocate the code. 99 | Error err = code->relocateToBase(uintptr_t((void*)ro)); 100 | if (ASMJIT_UNLIKELY(err)) { 101 | _allocator.release(ro); 102 | return err; 103 | } 104 | 105 | // Recalculate the final code size and shrink the memory we allocated for it 106 | // in case that some relocations didn't require records in an address table. 107 | size_t codeSize = code->codeSize(); 108 | 109 | for (Section* section : code->_sections) { 110 | size_t offset = size_t(section->offset()); 111 | size_t bufferSize = size_t(section->bufferSize()); 112 | size_t virtualSize = size_t(section->virtualSize()); 113 | 114 | ASMJIT_ASSERT(offset + bufferSize <= codeSize); 115 | memcpy(rw + offset, section->data(), bufferSize); 116 | 117 | if (virtualSize > bufferSize) { 118 | ASMJIT_ASSERT(offset + virtualSize <= codeSize); 119 | memset(rw + offset + bufferSize, 0, virtualSize - bufferSize); 120 | } 121 | } 122 | 123 | if (codeSize < estimatedCodeSize) 124 | _allocator.shrink(ro, codeSize); 125 | 126 | flush(ro, codeSize); 127 | *dst = ro; 128 | 129 | return kErrorOk; 130 | } 131 | 132 | Error JitRuntime::_release(void* p) noexcept { 133 | return _allocator.release(p); 134 | } 135 | 136 | void JitRuntime::flush(const void* p, size_t size) noexcept { 137 | JitRuntime_flushInstructionCache(p, size); 138 | } 139 | 140 | ASMJIT_END_NAMESPACE 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/virtmem.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_VIRTMEM_H 8 | #define _ASMJIT_CORE_VIRTMEM_H 9 | 10 | #include "../core/build.h" 11 | #ifndef ASMJIT_NO_JIT 12 | 13 | #include "../core/globals.h" 14 | 15 | ASMJIT_BEGIN_NAMESPACE 16 | 17 | //! \addtogroup asmjit_jit 18 | //! \{ 19 | 20 | // ============================================================================ 21 | // [asmjit::VirtMem] 22 | // ============================================================================ 23 | 24 | //! Virtual memory management. 25 | namespace VirtMem { 26 | 27 | //! Virtual memory and memory mapping flags. 28 | enum Flags : uint32_t { 29 | //! No access flags. 30 | kAccessNone = 0x00000000u, 31 | //! Memory is readable. 32 | kAccessRead = 0x00000001u, 33 | //! Memory is writable (implies read access). 34 | kAccessWrite = 0x00000002u, 35 | //! Memory is executable (implies read access). 36 | kAccessExecute = 0x00000004u, 37 | 38 | //! A combination of `kAccessRead | kAccessWrite` 39 | kAccessReadWrite = 0x00000003u, 40 | 41 | //! Not an access flag, only used by `allocDualMapping()` to override the 42 | //! default allocation strategy to always use a temporary directory instead 43 | //! on "/dev/shm" (on POSIX systems). Please note that this flag will be 44 | //! ignored if the operating system allows to allocate an executable memory 45 | //! by a different API than `open()` or `shm_open()`. For example on Linux 46 | //! `memfd_create()` is preferred and on BSDs `shm_open(SHM_ANON, ...)` is 47 | //! used if SHM_ANON is defined. 48 | kMappingPreferTmp = 0x80000000u 49 | }; 50 | 51 | //! Virtual memory information. 52 | struct Info { 53 | //! Virtual memory page size. 54 | uint32_t pageSize; 55 | //! Virtual memory page granularity. 56 | uint32_t pageGranularity; 57 | }; 58 | 59 | //! Dual memory mapping used to map an anonymous memory into two memory regions 60 | //! where one region is read-only, but executable, and the second region is 61 | //! read+write, but not executable. Please see \ref VirtMem::allocDualMapping() 62 | //! for more details. 63 | struct DualMapping { 64 | //! Pointer to data with 'Read' or 'Read+Execute' access. 65 | void* ro; 66 | //! Pointer to data with 'Read-Write' access, but never 'Write+Execute'. 67 | void* rw; 68 | }; 69 | 70 | //! Returns virtual memory information, see `VirtMem::Info` for more details. 71 | ASMJIT_API Info info() noexcept; 72 | 73 | //! Allocates virtual memory by either using `VirtualAlloc()` (Windows) 74 | //! or `mmap()` (POSIX). 75 | //! 76 | //! \note `size` should be aligned to a page size, use \ref VirtMem::info() 77 | //! to obtain it. Invalid size will not be corrected by the implementation 78 | //! and the allocation would not succeed in such case. 79 | ASMJIT_API Error alloc(void** p, size_t size, uint32_t flags) noexcept; 80 | 81 | //! Releases virtual memory previously allocated by \ref VirtMem::alloc() or 82 | //! \ref VirtMem::allocDualMapping(). 83 | //! 84 | //! \note The size must be the same as used by \ref VirtMem::alloc(). If the 85 | //! size is not the same value the call will fail on any POSIX system, but 86 | //! pass on Windows, because of the difference of the implementation. 87 | ASMJIT_API Error release(void* p, size_t size) noexcept; 88 | 89 | //! A cross-platform wrapper around `mprotect()` (POSIX) and `VirtualProtect` 90 | //! (Windows). 91 | ASMJIT_API Error protect(void* p, size_t size, uint32_t flags) noexcept; 92 | 93 | //! Allocates virtual memory and creates two views of it where the first view 94 | //! has no write access. This is an addition to the API that should be used 95 | //! in cases in which the operating system either enforces W^X security policy 96 | //! or the application wants to use this policy by default to improve security 97 | //! and prevent an accidental (or purposed) self-modifying code. 98 | //! 99 | //! The memory returned in the `dm` are two independent mappings of the same 100 | //! shared memory region. You must use \ref VirtMem::releaseDualMapping() to 101 | //! release it when it's no longer needed. Never use `VirtMem::release()` to 102 | //! release the memory returned by `allocDualMapping()` as that would fail on 103 | //! Windows. 104 | //! 105 | //! \remarks Both pointers in `dm` would be set to `nullptr` if the function fails. 106 | ASMJIT_API Error allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) noexcept; 107 | 108 | //! Releases the virtual memory mapping previously allocated by 109 | //! \ref VirtMem::allocDualMapping(). 110 | //! 111 | //! \remarks Both pointers in `dm` would be set to `nullptr` if the function succeeds. 112 | ASMJIT_API Error releaseDualMapping(DualMapping* dm, size_t size) noexcept; 113 | 114 | } // VirtMem 115 | 116 | //! \} 117 | 118 | ASMJIT_END_NAMESPACE 119 | 120 | #endif 121 | #endif // _ASMJIT_CORE_VIRTMEM_H 122 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/rastack_p.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_RASTACK_P_H 8 | #define _ASMJIT_CORE_RASTACK_P_H 9 | 10 | #include "../core/build.h" 11 | #ifndef ASMJIT_NO_COMPILER 12 | 13 | #include "../core/radefs_p.h" 14 | 15 | ASMJIT_BEGIN_NAMESPACE 16 | 17 | //! \cond INTERNAL 18 | //! \addtogroup asmjit_ra 19 | //! \{ 20 | 21 | // ============================================================================ 22 | // [asmjit::RAStackSlot] 23 | // ============================================================================ 24 | 25 | //! Stack slot. 26 | struct RAStackSlot { 27 | enum Flags : uint32_t { 28 | // TODO: kFlagRegHome is apparently not used, but isRegHome() is. 29 | kFlagRegHome = 0x00000001u, //!< Stack slot is register home slot. 30 | kFlagStackArg = 0x00000002u //!< Stack slot position matches argument passed via stack. 31 | }; 32 | 33 | enum ArgIndex : uint32_t { 34 | kNoArgIndex = 0xFF 35 | }; 36 | 37 | //! Base register used to address the stack. 38 | uint8_t _baseRegId; 39 | //! Minimum alignment required by the slot. 40 | uint8_t _alignment; 41 | //! Reserved for future use. 42 | uint8_t _reserved[2]; 43 | //! Size of memory required by the slot. 44 | uint32_t _size; 45 | //! Slot flags. 46 | uint32_t _flags; 47 | 48 | //! Usage counter (one unit equals one memory access). 49 | uint32_t _useCount; 50 | //! Weight of the slot (calculated by `calculateStackFrame()`). 51 | uint32_t _weight; 52 | //! Stack offset (calculated by `calculateStackFrame()`). 53 | int32_t _offset; 54 | 55 | //! \name Accessors 56 | //! \{ 57 | 58 | inline uint32_t baseRegId() const noexcept { return _baseRegId; } 59 | inline void setBaseRegId(uint32_t id) noexcept { _baseRegId = uint8_t(id); } 60 | 61 | inline uint32_t size() const noexcept { return _size; } 62 | inline uint32_t alignment() const noexcept { return _alignment; } 63 | 64 | inline uint32_t flags() const noexcept { return _flags; } 65 | inline void addFlags(uint32_t flags) noexcept { _flags |= flags; } 66 | inline bool isRegHome() const noexcept { return (_flags & kFlagRegHome) != 0; } 67 | inline bool isStackArg() const noexcept { return (_flags & kFlagStackArg) != 0; } 68 | 69 | inline uint32_t useCount() const noexcept { return _useCount; } 70 | inline void addUseCount(uint32_t n = 1) noexcept { _useCount += n; } 71 | 72 | inline uint32_t weight() const noexcept { return _weight; } 73 | inline void setWeight(uint32_t weight) noexcept { _weight = weight; } 74 | 75 | inline int32_t offset() const noexcept { return _offset; } 76 | inline void setOffset(int32_t offset) noexcept { _offset = offset; } 77 | 78 | //! \} 79 | }; 80 | 81 | typedef ZoneVector RAStackSlots; 82 | 83 | // ============================================================================ 84 | // [asmjit::RAStackAllocator] 85 | // ============================================================================ 86 | 87 | //! Stack allocator. 88 | class RAStackAllocator { 89 | public: 90 | ASMJIT_NONCOPYABLE(RAStackAllocator) 91 | 92 | enum Size : uint32_t { 93 | kSize1 = 0, 94 | kSize2 = 1, 95 | kSize4 = 2, 96 | kSize8 = 3, 97 | kSize16 = 4, 98 | kSize32 = 5, 99 | kSize64 = 6, 100 | kSizeCount = 7 101 | }; 102 | 103 | //! Allocator used to allocate internal data. 104 | ZoneAllocator* _allocator; 105 | //! Count of bytes used by all slots. 106 | uint32_t _bytesUsed; 107 | //! Calculated stack size (can be a bit greater than `_bytesUsed`). 108 | uint32_t _stackSize; 109 | //! Minimum stack alignment. 110 | uint32_t _alignment; 111 | //! Stack slots vector. 112 | RAStackSlots _slots; 113 | 114 | //! \name Construction / Destruction 115 | //! \{ 116 | 117 | inline RAStackAllocator() noexcept 118 | : _allocator(nullptr), 119 | _bytesUsed(0), 120 | _stackSize(0), 121 | _alignment(1), 122 | _slots() {} 123 | 124 | inline void reset(ZoneAllocator* allocator) noexcept { 125 | _allocator = allocator; 126 | _bytesUsed = 0; 127 | _stackSize = 0; 128 | _alignment = 1; 129 | _slots.reset(); 130 | } 131 | 132 | //! \} 133 | 134 | //! \name Accessors 135 | //! \{ 136 | 137 | inline ZoneAllocator* allocator() const noexcept { return _allocator; } 138 | 139 | inline uint32_t bytesUsed() const noexcept { return _bytesUsed; } 140 | inline uint32_t stackSize() const noexcept { return _stackSize; } 141 | inline uint32_t alignment() const noexcept { return _alignment; } 142 | 143 | inline RAStackSlots& slots() noexcept { return _slots; } 144 | inline const RAStackSlots& slots() const noexcept { return _slots; } 145 | inline uint32_t slotCount() const noexcept { return _slots.size(); } 146 | 147 | //! \} 148 | 149 | //! \name Utilities 150 | //! \{ 151 | 152 | RAStackSlot* newSlot(uint32_t baseRegId, uint32_t size, uint32_t alignment, uint32_t flags = 0) noexcept; 153 | 154 | Error calculateStackFrame() noexcept; 155 | Error adjustSlotOffsets(int32_t offset) noexcept; 156 | 157 | //! \} 158 | }; 159 | 160 | //! \} 161 | //! \endcond 162 | 163 | ASMJIT_END_NAMESPACE 164 | 165 | #endif // !ASMJIT_NO_COMPILER 166 | #endif // _ASMJIT_CORE_RASTACK_P_H 167 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/codebufferwriter_p.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_CODEBUFFERWRITER_P_H 8 | #define _ASMJIT_CORE_CODEBUFFERWRITER_P_H 9 | 10 | #include "../core/assembler.h" 11 | #include "../core/support.h" 12 | 13 | ASMJIT_BEGIN_NAMESPACE 14 | 15 | //! \cond INTERNAL 16 | //! \addtogroup asmjit_core 17 | //! \{ 18 | 19 | // ============================================================================ 20 | // [asmjit::CodeBufferWriter] 21 | // ============================================================================ 22 | 23 | //! Helper that is used to write into a `CodeBuffer` held by `BaseAssembler`. 24 | class CodeBufferWriter { 25 | public: 26 | uint8_t* _cursor; 27 | 28 | ASMJIT_INLINE explicit CodeBufferWriter(BaseAssembler* a) noexcept 29 | : _cursor(a->_bufferPtr) {} 30 | 31 | ASMJIT_INLINE Error ensureSpace(BaseAssembler* a, size_t n) noexcept { 32 | size_t remainingSpace = (size_t)(a->_bufferEnd - _cursor); 33 | if (ASMJIT_UNLIKELY(remainingSpace < n)) { 34 | CodeBuffer& buffer = a->_section->_buffer; 35 | Error err = a->_code->growBuffer(&buffer, n); 36 | if (ASMJIT_UNLIKELY(err)) 37 | return a->reportError(err); 38 | _cursor = a->_bufferPtr; 39 | } 40 | return kErrorOk; 41 | } 42 | 43 | ASMJIT_INLINE uint8_t* cursor() const noexcept { return _cursor; } 44 | ASMJIT_INLINE void setCursor(uint8_t* cursor) noexcept { _cursor = cursor; } 45 | ASMJIT_INLINE void advance(size_t n) noexcept { _cursor += n; } 46 | 47 | ASMJIT_INLINE size_t offsetFrom(uint8_t* from) const noexcept { 48 | ASMJIT_ASSERT(_cursor >= from); 49 | return (size_t)(_cursor - from); 50 | } 51 | 52 | template 53 | ASMJIT_INLINE void emit8(T val) noexcept { 54 | typedef typename std::make_unsigned::type U; 55 | _cursor[0] = uint8_t(U(val) & U(0xFF)); 56 | _cursor++; 57 | } 58 | 59 | template 60 | ASMJIT_INLINE void emit8If(T val, Y cond) noexcept { 61 | typedef typename std::make_unsigned::type U; 62 | ASMJIT_ASSERT(size_t(cond) <= 1u); 63 | 64 | _cursor[0] = uint8_t(U(val) & U(0xFF)); 65 | _cursor += size_t(cond); 66 | } 67 | 68 | template 69 | ASMJIT_INLINE void emit16uLE(T val) noexcept { 70 | typedef typename std::make_unsigned::type U; 71 | Support::writeU16uLE(_cursor, uint32_t(U(val) & 0xFFFFu)); 72 | _cursor += 2; 73 | } 74 | 75 | template 76 | ASMJIT_INLINE void emit16uBE(T val) noexcept { 77 | typedef typename std::make_unsigned::type U; 78 | Support::writeU16uBE(_cursor, uint32_t(U(val) & 0xFFFFu)); 79 | _cursor += 2; 80 | } 81 | 82 | template 83 | ASMJIT_INLINE void emit32uLE(T val) noexcept { 84 | typedef typename std::make_unsigned::type U; 85 | Support::writeU32uLE(_cursor, uint32_t(U(val) & 0xFFFFFFFFu)); 86 | _cursor += 4; 87 | } 88 | 89 | template 90 | ASMJIT_INLINE void emit32uBE(T val) noexcept { 91 | typedef typename std::make_unsigned::type U; 92 | Support::writeU32uBE(_cursor, uint32_t(U(val) & 0xFFFFFFFFu)); 93 | _cursor += 4; 94 | } 95 | 96 | ASMJIT_INLINE void emitData(const void* data, size_t size) noexcept { 97 | ASMJIT_ASSERT(size != 0); 98 | memcpy(_cursor, data, size); 99 | _cursor += size; 100 | } 101 | 102 | template 103 | ASMJIT_INLINE void emitValueLE(const T& value, size_t size) noexcept { 104 | typedef typename std::make_unsigned::type U; 105 | ASMJIT_ASSERT(size <= sizeof(T)); 106 | 107 | U v = U(value); 108 | for (uint32_t i = 0; i < size; i++) { 109 | _cursor[i] = uint8_t(v & 0xFFu); 110 | v >>= 8; 111 | } 112 | _cursor += size; 113 | } 114 | 115 | template 116 | ASMJIT_INLINE void emitValueBE(const T& value, size_t size) noexcept { 117 | typedef typename std::make_unsigned::type U; 118 | ASMJIT_ASSERT(size <= sizeof(T)); 119 | 120 | U v = U(value); 121 | for (uint32_t i = 0; i < size; i++) { 122 | _cursor[i] = uint8_t(v >> (sizeof(T) - 8)); 123 | v <<= 8; 124 | } 125 | _cursor += size; 126 | } 127 | 128 | ASMJIT_INLINE void emitZeros(size_t size) noexcept { 129 | ASMJIT_ASSERT(size != 0); 130 | memset(_cursor, 0, size); 131 | _cursor += size; 132 | } 133 | 134 | ASMJIT_INLINE void remove8(uint8_t* where) noexcept { 135 | ASMJIT_ASSERT(where < _cursor); 136 | 137 | uint8_t* p = where; 138 | while (++p != _cursor) 139 | p[-1] = p[0]; 140 | _cursor--; 141 | } 142 | 143 | template 144 | ASMJIT_INLINE void insert8(uint8_t* where, T val) noexcept { 145 | uint8_t* p = _cursor; 146 | 147 | while (p != where) { 148 | p[0] = p[-1]; 149 | p--; 150 | } 151 | 152 | *p = uint8_t(val & 0xFF); 153 | _cursor++; 154 | } 155 | 156 | ASMJIT_INLINE void done(BaseAssembler* a) noexcept { 157 | CodeBuffer& buffer = a->_section->_buffer; 158 | size_t newSize = (size_t)(_cursor - a->_bufferData); 159 | ASMJIT_ASSERT(newSize <= buffer.capacity()); 160 | 161 | a->_bufferPtr = _cursor; 162 | buffer._size = Support::max(buffer._size, newSize); 163 | } 164 | }; 165 | 166 | //! \} 167 | //! \endcond 168 | 169 | ASMJIT_END_NAMESPACE 170 | 171 | #endif // _ASMJIT_CORE_CODEBUFFERWRITER_P_H 172 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/zonelist.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_ZONELIST_H 8 | #define _ASMJIT_CORE_ZONELIST_H 9 | 10 | #include "../core/support.h" 11 | 12 | ASMJIT_BEGIN_NAMESPACE 13 | 14 | //! \addtogroup asmjit_zone 15 | //! \{ 16 | 17 | // ============================================================================ 18 | // [asmjit::ZoneListNode] 19 | // ============================================================================ 20 | 21 | template 22 | class ZoneListNode { 23 | public: 24 | ASMJIT_NONCOPYABLE(ZoneListNode) 25 | 26 | NodeT* _listNodes[Globals::kLinkCount]; 27 | 28 | //! \name Construction & Destruction 29 | //! \{ 30 | 31 | inline ZoneListNode() noexcept 32 | : _listNodes { nullptr, nullptr } {} 33 | 34 | inline ZoneListNode(ZoneListNode&& other) noexcept 35 | : _listNodes { other._listNodes[0], other._listNodes[1] } {} 36 | 37 | //! \} 38 | 39 | //! \name Accessors 40 | //! \{ 41 | 42 | inline bool hasPrev() const noexcept { return _listNodes[Globals::kLinkPrev] != nullptr; } 43 | inline bool hasNext() const noexcept { return _listNodes[Globals::kLinkNext] != nullptr; } 44 | 45 | inline NodeT* prev() const noexcept { return _listNodes[Globals::kLinkPrev]; } 46 | inline NodeT* next() const noexcept { return _listNodes[Globals::kLinkNext]; } 47 | 48 | //! \} 49 | }; 50 | 51 | // ============================================================================ 52 | // [asmjit::ZoneList] 53 | // ============================================================================ 54 | 55 | template 56 | class ZoneList { 57 | public: 58 | ASMJIT_NONCOPYABLE(ZoneList) 59 | 60 | NodeT* _bounds[Globals::kLinkCount]; 61 | 62 | //! \name Construction & Destruction 63 | //! \{ 64 | 65 | inline ZoneList() noexcept 66 | : _bounds { nullptr, nullptr } {} 67 | 68 | inline ZoneList(ZoneList&& other) noexcept 69 | : _bounds { other._bounds[0], other._bounds[1] } {} 70 | 71 | inline void reset() noexcept { 72 | _bounds[0] = nullptr; 73 | _bounds[1] = nullptr; 74 | } 75 | 76 | //! \} 77 | 78 | //! \name Accessors 79 | //! \{ 80 | 81 | inline bool empty() const noexcept { return _bounds[0] == nullptr; } 82 | inline NodeT* first() const noexcept { return _bounds[Globals::kLinkFirst]; } 83 | inline NodeT* last() const noexcept { return _bounds[Globals::kLinkLast]; } 84 | 85 | //! \} 86 | 87 | //! \name Utilities 88 | //! \{ 89 | 90 | inline void swap(ZoneList& other) noexcept { 91 | std::swap(_bounds[0], other._bounds[0]); 92 | std::swap(_bounds[1], other._bounds[1]); 93 | } 94 | 95 | // Can be used to both prepend and append. 96 | inline void _addNode(NodeT* node, size_t dir) noexcept { 97 | NodeT* prev = _bounds[dir]; 98 | 99 | node->_listNodes[!dir] = prev; 100 | _bounds[dir] = node; 101 | if (prev) 102 | prev->_listNodes[dir] = node; 103 | else 104 | _bounds[!dir] = node; 105 | } 106 | 107 | // Can be used to both prepend and append. 108 | inline void _insertNode(NodeT* ref, NodeT* node, size_t dir) noexcept { 109 | ASMJIT_ASSERT(ref != nullptr); 110 | 111 | NodeT* prev = ref; 112 | NodeT* next = ref->_listNodes[dir]; 113 | 114 | prev->_listNodes[dir] = node; 115 | if (next) 116 | next->_listNodes[!dir] = node; 117 | else 118 | _bounds[dir] = node; 119 | 120 | node->_listNodes[!dir] = prev; 121 | node->_listNodes[ dir] = next; 122 | } 123 | 124 | inline void append(NodeT* node) noexcept { _addNode(node, Globals::kLinkLast); } 125 | inline void prepend(NodeT* node) noexcept { _addNode(node, Globals::kLinkFirst); } 126 | 127 | inline void insertAfter(NodeT* ref, NodeT* node) noexcept { _insertNode(ref, node, Globals::kLinkNext); } 128 | inline void insertBefore(NodeT* ref, NodeT* node) noexcept { _insertNode(ref, node, Globals::kLinkPrev); } 129 | 130 | inline NodeT* unlink(NodeT* node) noexcept { 131 | NodeT* prev = node->prev(); 132 | NodeT* next = node->next(); 133 | 134 | if (prev) { prev->_listNodes[1] = next; node->_listNodes[0] = nullptr; } else { _bounds[0] = next; } 135 | if (next) { next->_listNodes[0] = prev; node->_listNodes[1] = nullptr; } else { _bounds[1] = prev; } 136 | 137 | node->_listNodes[0] = nullptr; 138 | node->_listNodes[1] = nullptr; 139 | 140 | return node; 141 | } 142 | 143 | inline NodeT* popFirst() noexcept { 144 | NodeT* node = _bounds[0]; 145 | ASMJIT_ASSERT(node != nullptr); 146 | 147 | NodeT* next = node->next(); 148 | _bounds[0] = next; 149 | 150 | if (next) { 151 | next->_listNodes[0] = nullptr; 152 | node->_listNodes[1] = nullptr; 153 | } 154 | else { 155 | _bounds[1] = nullptr; 156 | } 157 | 158 | return node; 159 | } 160 | 161 | inline NodeT* pop() noexcept { 162 | NodeT* node = _bounds[1]; 163 | ASMJIT_ASSERT(node != nullptr); 164 | 165 | NodeT* prev = node->prev(); 166 | _bounds[1] = prev; 167 | 168 | if (prev) { 169 | prev->_listNodes[1] = nullptr; 170 | node->_listNodes[0] = nullptr; 171 | } 172 | else { 173 | _bounds[0] = nullptr; 174 | } 175 | 176 | return node; 177 | } 178 | 179 | //! \} 180 | }; 181 | 182 | //! \} 183 | 184 | ASMJIT_END_NAMESPACE 185 | 186 | #endif // _ASMJIT_CORE_ZONELIST_H 187 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmtk/elfdefs.h: -------------------------------------------------------------------------------- 1 | // [AsmTk] 2 | // Assembler toolkit based on AsmJit. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMTK_ELFDEFS_H 8 | #define _ASMTK_ELFDEFS_H 9 | 10 | #include "./globals.h" 11 | 12 | namespace asmtk { 13 | 14 | enum ElfFileType : uint32_t { 15 | kElfFileType_NONE = 0, 16 | kElfFileType_REL = 1, 17 | kElfFileType_EXEC = 2, 18 | kElfFileType_DYN = 3, 19 | kElfFileType_CORE = 4, 20 | kElfFileType_LOPROC = 0xFF00, 21 | kElfFileType_HIPROC = 0xFFFF 22 | }; 23 | 24 | enum ElfFileVersion : uint32_t { 25 | kElfFileVersion_NONE = 0, 26 | kElfFileVersion_CURRENT = 1 27 | }; 28 | 29 | enum ElfFileClass : uint32_t { 30 | kElfFileClass_NONE = 0, 31 | kElfFileClass_32 = 1, 32 | kElfFileClass_64 = 2 33 | }; 34 | 35 | enum ElfFileEncoding : uint32_t { 36 | ElfFileEncoding_NONE = 0, 37 | ElfFileEncoding_LE = 1, 38 | ElfFileEncoding_BE = 2 39 | }; 40 | 41 | enum ElfMachineType : uint32_t { 42 | kElfMachineType_NONE = 0, 43 | kElfMachineType_X86 = 3, 44 | kElfMachineType_ARM = 40, 45 | kElfMachineType_X86_64 = 62 46 | }; 47 | 48 | enum ElfOSABI : uint32_t { 49 | kElfOSABI_NONE = 0, //!< UNIX System V ABI. 50 | kElfOSABI_HPUX = 1, 51 | kElfOSABI_NETBSD = 2, 52 | kElfOSABI_GNU = 3, //!< GNU/Linux. 53 | kElfOSABI_HURD = 4, 54 | kElfOSABI_SOLARIS = 6, 55 | kElfOSABI_AIX = 7, 56 | kElfOSABI_IRIX = 8, 57 | kElfOSABI_FREEBSD = 9, 58 | kElfOSABI_TRU64 = 10, 59 | kElfOSABI_MODESTO = 11, 60 | kElfOSABI_OPENBSD = 12, 61 | kElfOSABI_OPENVMS = 13, 62 | kElfOSABI_NSK = 14, 63 | kElfOSABI_AROS = 15, 64 | kElfOSABI_FENIXOS = 16, 65 | kElfOSABI_CLOUDABI = 17, 66 | kElfOSABI_ARM = 97, 67 | kElfOSABI_STANDALONE = 255 68 | }; 69 | 70 | struct ElfIdentData { 71 | uint8_t magic[4]; 72 | uint8_t classType; 73 | uint8_t dataType; 74 | uint8_t version; 75 | uint8_t abi; 76 | uint8_t abiVersion; 77 | uint8_t reserved[7]; 78 | }; 79 | 80 | template 81 | struct ElfFileData { 82 | ElfIdentData ident; 83 | uint16_t type; 84 | uint16_t machine; 85 | uint32_t version; 86 | ElfPtrT entry; 87 | ElfPtrT phOffset; 88 | ElfPtrT shOffset; 89 | uint32_t flags; 90 | uint16_t ehSize; 91 | uint16_t phEntSize; 92 | uint16_t phNum; 93 | uint16_t shEndSize; 94 | uint16_t shNum; 95 | uint16_t shStrNdx; 96 | }; 97 | 98 | typedef ElfFileData ElfFileData32; 99 | typedef ElfFileData ElfFileData64; 100 | 101 | template 102 | struct ElfProgramData {}; 103 | 104 | template<> 105 | struct ElfProgramData { 106 | uint32_t type; //!< Segment type. 107 | uint32_t offset; //!< Segment offset. 108 | uint32_t vaddr; //!< Virtual address. 109 | uint32_t paddr; //!< Physical address. 110 | uint32_t fileSize; //!< Size of file image (or zero). 111 | uint32_t memSize; //!< Size of memory image (or zero). 112 | uint32_t flags; //!< Segment flags. 113 | uint32_t align; //!< Segment alignment. 114 | }; 115 | 116 | template<> 117 | struct ElfProgramData { 118 | uint32_t type; //!< Segment type. 119 | uint32_t flags; //!< Segment flags. 120 | uint64_t offset; //!< Segment offset. 121 | uint64_t vaddr; //!< Virtual address. 122 | uint64_t paddr; //!< Physical address. 123 | uint64_t fileSize; //!< Size of file image (or zero). 124 | uint64_t memSize; //!< Size of memory image (or zero). 125 | uint64_t align; //!< Segment alignment. 126 | }; 127 | 128 | typedef ElfProgramData ElfProgramData32; 129 | typedef ElfProgramData ElfProgramData64; 130 | 131 | template 132 | struct ElfSectionData { 133 | uint32_t name; //!< Section name (index). 134 | uint32_t type; //!< Section type. 135 | ElfPtrT flags; //!< Section flags. 136 | ElfPtrT addr; //!< Section address. 137 | ElfPtrT offset; //!< Section file-offset. 138 | ElfPtrT size; //!< Section size. 139 | uint32_t link; 140 | uint32_t info; 141 | ElfPtrT addrAlign; 142 | ElfPtrT entSize; 143 | }; 144 | typedef ElfSectionData ElfSectionData32; 145 | typedef ElfSectionData ElfSectionData64; 146 | 147 | template 148 | struct ElfSymbolData {}; 149 | 150 | template<> 151 | struct ElfSymbolData { 152 | uint32_t name; //!< Symbol name (index). 153 | uint32_t value; //!< Symbol address. 154 | uint32_t size; //!< Symbol size. 155 | uint8_t info; //!< Symbol information. 156 | uint8_t reserved; //!< Reserved (zero). 157 | uint16_t shndx; //!< Section index. 158 | }; 159 | 160 | template<> 161 | struct ElfSymbolData { 162 | uint32_t name; //!< Symbol name (index). 163 | uint8_t info; //!< Symbol information. 164 | uint8_t other; //!< Reserved (zero). 165 | uint16_t shndx; //!< Section index. 166 | uint64_t value; //!< Symbol address. 167 | uint64_t size; //!< Symbol size. 168 | }; 169 | 170 | typedef ElfSymbolData ElfSymbolData32; 171 | typedef ElfSymbolData ElfSymbolData64; 172 | 173 | } // {asmtk} 174 | 175 | #endif // _ASMTK_ELFDEFS_H 176 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/zonehash.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/support.h" 10 | #include "../core/zone.h" 11 | #include "../core/zonehash.h" 12 | 13 | ASMJIT_BEGIN_NAMESPACE 14 | 15 | // ============================================================================ 16 | // [asmjit::ZoneHashBase - Helpers] 17 | // ============================================================================ 18 | 19 | static uint32_t ZoneHash_getClosestPrime(uint32_t x) noexcept { 20 | static const uint32_t primeTable[] = { 21 | 23, 53, 193, 389, 769, 1543, 3079, 6151, 12289, 24593 22 | }; 23 | 24 | size_t i = 0; 25 | uint32_t p; 26 | 27 | do { 28 | if ((p = primeTable[i]) > x) 29 | break; 30 | } while (++i < ASMJIT_ARRAY_SIZE(primeTable)); 31 | 32 | return p; 33 | } 34 | 35 | // ============================================================================ 36 | // [asmjit::ZoneHashBase - Rehash] 37 | // ============================================================================ 38 | 39 | void ZoneHashBase::_rehash(ZoneAllocator* allocator, uint32_t newCount) noexcept { 40 | ZoneHashNode** oldData = _data; 41 | ZoneHashNode** newData = reinterpret_cast( 42 | allocator->allocZeroed(size_t(newCount) * sizeof(ZoneHashNode*))); 43 | 44 | // We can still store nodes into the table, but it will degrade. 45 | if (ASMJIT_UNLIKELY(newData == nullptr)) 46 | return; 47 | 48 | uint32_t i; 49 | uint32_t oldCount = _bucketsCount; 50 | 51 | for (i = 0; i < oldCount; i++) { 52 | ZoneHashNode* node = oldData[i]; 53 | while (node) { 54 | ZoneHashNode* next = node->_hashNext; 55 | uint32_t hMod = node->_hashCode % newCount; 56 | 57 | node->_hashNext = newData[hMod]; 58 | newData[hMod] = node; 59 | node = next; 60 | } 61 | } 62 | 63 | // 90% is the maximum occupancy, can't overflow since the maximum capacity 64 | // is limited to the last prime number stored in the prime table. 65 | if (oldData != _embedded) 66 | allocator->release(oldData, _bucketsCount * sizeof(ZoneHashNode*)); 67 | 68 | _bucketsCount = newCount; 69 | _bucketsGrow = newCount * 9 / 10; 70 | _data = newData; 71 | } 72 | 73 | // ============================================================================ 74 | // [asmjit::ZoneHashBase - Ops] 75 | // ============================================================================ 76 | 77 | ZoneHashNode* ZoneHashBase::_insert(ZoneAllocator* allocator, ZoneHashNode* node) noexcept { 78 | uint32_t hMod = node->_hashCode % _bucketsCount; 79 | ZoneHashNode* next = _data[hMod]; 80 | 81 | node->_hashNext = next; 82 | _data[hMod] = node; 83 | 84 | if (++_size >= _bucketsGrow && next) { 85 | uint32_t newCapacity = ZoneHash_getClosestPrime(_bucketsCount); 86 | if (newCapacity != _bucketsCount) 87 | _rehash(allocator, newCapacity); 88 | } 89 | 90 | return node; 91 | } 92 | 93 | ZoneHashNode* ZoneHashBase::_remove(ZoneAllocator* allocator, ZoneHashNode* node) noexcept { 94 | ASMJIT_UNUSED(allocator); 95 | uint32_t hMod = node->_hashCode % _bucketsCount; 96 | 97 | ZoneHashNode** pPrev = &_data[hMod]; 98 | ZoneHashNode* p = *pPrev; 99 | 100 | while (p) { 101 | if (p == node) { 102 | *pPrev = p->_hashNext; 103 | _size--; 104 | return node; 105 | } 106 | 107 | pPrev = &p->_hashNext; 108 | p = *pPrev; 109 | } 110 | 111 | return nullptr; 112 | } 113 | 114 | // ============================================================================ 115 | // [asmjit::ZoneHash - Unit] 116 | // ============================================================================ 117 | 118 | #if defined(ASMJIT_TEST) 119 | struct MyHashNode : public ZoneHashNode { 120 | inline MyHashNode(uint32_t key) noexcept 121 | : ZoneHashNode(key), 122 | _key(key) {} 123 | 124 | uint32_t _key; 125 | }; 126 | 127 | struct MyKeyMatcher { 128 | inline MyKeyMatcher(uint32_t key) noexcept 129 | : _key(key) {} 130 | 131 | inline uint32_t hashCode() const noexcept { return _key; } 132 | inline bool matches(const MyHashNode* node) const noexcept { return node->_key == _key; } 133 | 134 | uint32_t _key; 135 | }; 136 | 137 | UNIT(asmjit_zone_hash) { 138 | uint32_t kCount = BrokenAPI::hasArg("--quick") ? 1000 : 10000; 139 | 140 | Zone zone(4096); 141 | ZoneAllocator allocator(&zone); 142 | 143 | ZoneHash hashTable; 144 | 145 | uint32_t key; 146 | INFO("Inserting %u elements to HashTable", unsigned(kCount)); 147 | for (key = 0; key < kCount; key++) { 148 | hashTable.insert(&allocator, zone.newT(key)); 149 | } 150 | 151 | uint32_t count = kCount; 152 | INFO("Removing %u elements from HashTable and validating each operation", unsigned(kCount)); 153 | do { 154 | MyHashNode* node; 155 | 156 | for (key = 0; key < count; key++) { 157 | node = hashTable.get(MyKeyMatcher(key)); 158 | EXPECT(node != nullptr); 159 | EXPECT(node->_key == key); 160 | } 161 | 162 | { 163 | count--; 164 | node = hashTable.get(MyKeyMatcher(count)); 165 | hashTable.remove(&allocator, node); 166 | 167 | node = hashTable.get(MyKeyMatcher(count)); 168 | EXPECT(node == nullptr); 169 | } 170 | } while (count); 171 | 172 | EXPECT(hashTable.empty()); 173 | } 174 | #endif 175 | 176 | ASMJIT_END_NAMESPACE 177 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/arch.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/arch.h" 10 | #include "../core/support.h" 11 | #include "../core/type.h" 12 | 13 | #ifdef ASMJIT_BUILD_X86 14 | #include "../x86/x86operand.h" 15 | #endif 16 | 17 | #ifdef ASMJIT_BUILD_ARM 18 | #include "../arm/armoperand.h" 19 | #endif 20 | 21 | ASMJIT_BEGIN_NAMESPACE 22 | 23 | // ============================================================================ 24 | // [asmjit::ArchInfo] 25 | // ============================================================================ 26 | 27 | // NOTE: Keep `const constexpr` otherwise MSC would not compile this code correctly. 28 | static const constexpr uint32_t archInfoTable[] = { 29 | // <--------------------+---------------------+-------------------+-------+ 30 | // | Type | SubType | GPInfo| 31 | // <--------------------+---------------------+-------------------+-------+ 32 | Support::bytepack32_4x8(ArchInfo::kIdNone , ArchInfo::kSubIdNone, 0, 0), 33 | Support::bytepack32_4x8(ArchInfo::kIdX86 , ArchInfo::kSubIdNone, 4, 8), 34 | Support::bytepack32_4x8(ArchInfo::kIdX64 , ArchInfo::kSubIdNone, 8, 16), 35 | Support::bytepack32_4x8(ArchInfo::kIdA32 , ArchInfo::kSubIdNone, 4, 16), 36 | Support::bytepack32_4x8(ArchInfo::kIdA64 , ArchInfo::kSubIdNone, 8, 32) 37 | }; 38 | 39 | ASMJIT_FAVOR_SIZE void ArchInfo::init(uint32_t id, uint32_t subId) noexcept { 40 | uint32_t index = id < ASMJIT_ARRAY_SIZE(archInfoTable) ? id : uint32_t(0); 41 | 42 | // Make sure the `archInfoTable` array is correctly indexed. 43 | _signature = archInfoTable[index]; 44 | ASMJIT_ASSERT(_id == index); 45 | 46 | // Even if the architecture is not known we setup its id and sub-id, 47 | // however, such architecture is not really useful. 48 | _id = uint8_t(id); 49 | _subId = uint8_t(subId); 50 | } 51 | 52 | // ============================================================================ 53 | // [asmjit::ArchUtils] 54 | // ============================================================================ 55 | 56 | ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t archId, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept { 57 | uint32_t typeId = typeIdInOut; 58 | 59 | // Zero the signature so it's clear in case that typeId is not invalid. 60 | regInfo._signature = 0; 61 | 62 | // TODO: Move to X86 backend. 63 | #ifdef ASMJIT_BUILD_X86 64 | if (ArchInfo::isX86Family(archId)) { 65 | // Passed RegType instead of TypeId? 66 | if (typeId <= BaseReg::kTypeMax) 67 | typeId = x86::opData.archRegs.regTypeToTypeId[typeId]; 68 | 69 | if (ASMJIT_UNLIKELY(!Type::isValid(typeId))) 70 | return DebugUtils::errored(kErrorInvalidTypeId); 71 | 72 | // First normalize architecture dependent types. 73 | if (Type::isAbstract(typeId)) { 74 | if (typeId == Type::kIdIntPtr) 75 | typeId = (archId == ArchInfo::kIdX86) ? Type::kIdI32 : Type::kIdI64; 76 | else 77 | typeId = (archId == ArchInfo::kIdX86) ? Type::kIdU32 : Type::kIdU64; 78 | } 79 | 80 | // Type size helps to construct all groupss of registers. If the size is zero 81 | // then the TypeId is invalid. 82 | uint32_t size = Type::sizeOf(typeId); 83 | if (ASMJIT_UNLIKELY(!size)) 84 | return DebugUtils::errored(kErrorInvalidTypeId); 85 | 86 | if (ASMJIT_UNLIKELY(typeId == Type::kIdF80)) 87 | return DebugUtils::errored(kErrorInvalidUseOfF80); 88 | 89 | uint32_t regType = 0; 90 | 91 | switch (typeId) { 92 | case Type::kIdI8: 93 | case Type::kIdU8: 94 | regType = x86::Reg::kTypeGpbLo; 95 | break; 96 | 97 | case Type::kIdI16: 98 | case Type::kIdU16: 99 | regType = x86::Reg::kTypeGpw; 100 | break; 101 | 102 | case Type::kIdI32: 103 | case Type::kIdU32: 104 | regType = x86::Reg::kTypeGpd; 105 | break; 106 | 107 | case Type::kIdI64: 108 | case Type::kIdU64: 109 | if (archId == ArchInfo::kIdX86) 110 | return DebugUtils::errored(kErrorInvalidUseOfGpq); 111 | 112 | regType = x86::Reg::kTypeGpq; 113 | break; 114 | 115 | // F32 and F64 are always promoted to use vector registers. 116 | case Type::kIdF32: 117 | typeId = Type::kIdF32x1; 118 | regType = x86::Reg::kTypeXmm; 119 | break; 120 | 121 | case Type::kIdF64: 122 | typeId = Type::kIdF64x1; 123 | regType = x86::Reg::kTypeXmm; 124 | break; 125 | 126 | // Mask registers {k}. 127 | case Type::kIdMask8: 128 | case Type::kIdMask16: 129 | case Type::kIdMask32: 130 | case Type::kIdMask64: 131 | regType = x86::Reg::kTypeKReg; 132 | break; 133 | 134 | // MMX registers. 135 | case Type::kIdMmx32: 136 | case Type::kIdMmx64: 137 | regType = x86::Reg::kTypeMm; 138 | break; 139 | 140 | // XMM|YMM|ZMM registers. 141 | default: 142 | if (size <= 16) 143 | regType = x86::Reg::kTypeXmm; 144 | else if (size == 32) 145 | regType = x86::Reg::kTypeYmm; 146 | else 147 | regType = x86::Reg::kTypeZmm; 148 | break; 149 | } 150 | 151 | typeIdInOut = typeId; 152 | regInfo._signature = x86::opData.archRegs.regInfo[regType].signature(); 153 | return kErrorOk; 154 | } 155 | #endif 156 | 157 | return DebugUtils::errored(kErrorInvalidArch); 158 | } 159 | 160 | ASMJIT_END_NAMESPACE 161 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/x86/x86callconv.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/build.h" 10 | #ifdef ASMJIT_BUILD_X86 11 | 12 | #include "../x86/x86callconv_p.h" 13 | #include "../x86/x86operand.h" 14 | 15 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 16 | 17 | // ============================================================================ 18 | // [asmjit::x86::CallConvInternal - Init] 19 | // ============================================================================ 20 | 21 | static inline void CallConv_initX86Common(CallConv& cc) noexcept { 22 | cc.setNaturalStackAlignment(4); 23 | cc.setArchType(ArchInfo::kIdX86); 24 | cc.setPreservedRegs(Reg::kGroupGp, Support::bitMask(Gp::kIdBx, Gp::kIdSp, Gp::kIdBp, Gp::kIdSi, Gp::kIdDi)); 25 | } 26 | 27 | ASMJIT_FAVOR_SIZE Error CallConvInternal::init(CallConv& cc, uint32_t ccId) noexcept { 28 | constexpr uint32_t kGroupGp = Reg::kGroupGp; 29 | constexpr uint32_t kGroupVec = Reg::kGroupVec; 30 | constexpr uint32_t kGroupMm = Reg::kGroupMm; 31 | constexpr uint32_t kGroupKReg = Reg::kGroupKReg; 32 | 33 | constexpr uint32_t kZax = Gp::kIdAx; 34 | constexpr uint32_t kZbx = Gp::kIdBx; 35 | constexpr uint32_t kZcx = Gp::kIdCx; 36 | constexpr uint32_t kZdx = Gp::kIdDx; 37 | constexpr uint32_t kZsp = Gp::kIdSp; 38 | constexpr uint32_t kZbp = Gp::kIdBp; 39 | constexpr uint32_t kZsi = Gp::kIdSi; 40 | constexpr uint32_t kZdi = Gp::kIdDi; 41 | 42 | switch (ccId) { 43 | case CallConv::kIdX86StdCall: 44 | cc.setFlags(CallConv::kFlagCalleePopsStack); 45 | CallConv_initX86Common(cc); 46 | break; 47 | 48 | case CallConv::kIdX86MsThisCall: 49 | cc.setFlags(CallConv::kFlagCalleePopsStack); 50 | cc.setPassedOrder(kGroupGp, kZcx); 51 | CallConv_initX86Common(cc); 52 | break; 53 | 54 | case CallConv::kIdX86MsFastCall: 55 | case CallConv::kIdX86GccFastCall: 56 | cc.setFlags(CallConv::kFlagCalleePopsStack); 57 | cc.setPassedOrder(kGroupGp, kZcx, kZdx); 58 | CallConv_initX86Common(cc); 59 | break; 60 | 61 | case CallConv::kIdX86GccRegParm1: 62 | cc.setPassedOrder(kGroupGp, kZax); 63 | CallConv_initX86Common(cc); 64 | break; 65 | 66 | case CallConv::kIdX86GccRegParm2: 67 | cc.setPassedOrder(kGroupGp, kZax, kZdx); 68 | CallConv_initX86Common(cc); 69 | break; 70 | 71 | case CallConv::kIdX86GccRegParm3: 72 | cc.setPassedOrder(kGroupGp, kZax, kZdx, kZcx); 73 | CallConv_initX86Common(cc); 74 | break; 75 | 76 | case CallConv::kIdX86CDecl: 77 | CallConv_initX86Common(cc); 78 | break; 79 | 80 | case CallConv::kIdX86Win64: 81 | cc.setArchType(ArchInfo::kIdX64); 82 | cc.setStrategy(CallConv::kStrategyWin64); 83 | cc.setFlags(CallConv::kFlagPassFloatsByVec | CallConv::kFlagIndirectVecArgs); 84 | cc.setNaturalStackAlignment(16); 85 | cc.setSpillZoneSize(32); 86 | cc.setPassedOrder(kGroupGp, kZcx, kZdx, 8, 9); 87 | cc.setPassedOrder(kGroupVec, 0, 1, 2, 3); 88 | cc.setPreservedRegs(kGroupGp, Support::bitMask(kZbx, kZsp, kZbp, kZsi, kZdi, 12, 13, 14, 15)); 89 | cc.setPreservedRegs(kGroupVec, Support::bitMask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15)); 90 | break; 91 | 92 | case CallConv::kIdX86SysV64: 93 | cc.setArchType(ArchInfo::kIdX64); 94 | cc.setFlags(CallConv::kFlagPassFloatsByVec); 95 | cc.setNaturalStackAlignment(16); 96 | cc.setRedZoneSize(128); 97 | cc.setPassedOrder(kGroupGp, kZdi, kZsi, kZdx, kZcx, 8, 9); 98 | cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5, 6, 7); 99 | cc.setPreservedRegs(kGroupGp, Support::bitMask(kZbx, kZsp, kZbp, 12, 13, 14, 15)); 100 | break; 101 | 102 | case CallConv::kIdX86LightCall2: 103 | case CallConv::kIdX86LightCall3: 104 | case CallConv::kIdX86LightCall4: { 105 | uint32_t n = (ccId - CallConv::kIdX86LightCall2) + 2; 106 | 107 | cc.setArchType(ArchInfo::kIdX86); 108 | cc.setFlags(CallConv::kFlagPassFloatsByVec); 109 | cc.setNaturalStackAlignment(16); 110 | cc.setPassedOrder(kGroupGp, kZax, kZdx, kZcx, kZsi, kZdi); 111 | cc.setPassedOrder(kGroupMm, 0, 1, 2, 3, 4, 5, 6, 7); 112 | cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5, 6, 7); 113 | cc.setPassedOrder(kGroupKReg, 0, 1, 2, 3, 4, 5, 6, 7); 114 | 115 | cc.setPreservedRegs(kGroupGp , Support::lsbMask(8)); 116 | cc.setPreservedRegs(kGroupVec , Support::lsbMask(8) & ~Support::lsbMask(n)); 117 | break; 118 | } 119 | 120 | case CallConv::kIdX64LightCall2: 121 | case CallConv::kIdX64LightCall3: 122 | case CallConv::kIdX64LightCall4: { 123 | uint32_t n = (ccId - CallConv::kIdX64LightCall2) + 2; 124 | 125 | cc.setArchType(ArchInfo::kIdX64); 126 | cc.setFlags(CallConv::kFlagPassFloatsByVec); 127 | cc.setNaturalStackAlignment(16); 128 | cc.setPassedOrder(kGroupGp, kZax, kZdx, kZcx, kZsi, kZdi); 129 | cc.setPassedOrder(kGroupMm, 0, 1, 2, 3, 4, 5, 6, 7); 130 | cc.setPassedOrder(kGroupVec, 0, 1, 2, 3, 4, 5, 6, 7); 131 | cc.setPassedOrder(kGroupKReg, 0, 1, 2, 3, 4, 5, 6, 7); 132 | 133 | cc.setPreservedRegs(kGroupGp , Support::lsbMask(16)); 134 | cc.setPreservedRegs(kGroupVec ,~Support::lsbMask(n)); 135 | break; 136 | } 137 | 138 | default: 139 | return DebugUtils::errored(kErrorInvalidArgument); 140 | } 141 | 142 | cc.setId(ccId); 143 | return kErrorOk; 144 | } 145 | 146 | ASMJIT_END_SUB_NAMESPACE 147 | 148 | #endif // ASMJIT_BUILD_X86 149 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/assembler.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_ASSEMBLER_H 8 | #define _ASMJIT_CORE_ASSEMBLER_H 9 | 10 | #include "../core/codeholder.h" 11 | #include "../core/datatypes.h" 12 | #include "../core/emitter.h" 13 | #include "../core/operand.h" 14 | 15 | ASMJIT_BEGIN_NAMESPACE 16 | 17 | //! \addtogroup asmjit_core 18 | //! \{ 19 | 20 | // ============================================================================ 21 | // [asmjit::BaseAssembler] 22 | // ============================================================================ 23 | 24 | //! Base encoder (assembler). 25 | class ASMJIT_VIRTAPI BaseAssembler : public BaseEmitter { 26 | public: 27 | ASMJIT_NONCOPYABLE(BaseAssembler) 28 | typedef BaseEmitter Base; 29 | 30 | //! Current section where the assembling happens. 31 | Section* _section; 32 | //! Start of the CodeBuffer of the current section. 33 | uint8_t* _bufferData; 34 | //! End (first invalid byte) of the current section. 35 | uint8_t* _bufferEnd; 36 | //! Pointer in the CodeBuffer of the current section. 37 | uint8_t* _bufferPtr; 38 | //! 5th operand data, used only temporarily. 39 | Operand_ _op4; 40 | //! 6th operand data, used only temporarily. 41 | Operand_ _op5; 42 | 43 | //! \name Construction & Destruction 44 | //! \{ 45 | 46 | //! Creates a new `BaseAssembler` instance. 47 | ASMJIT_API BaseAssembler() noexcept; 48 | //! Destroys the `BaseAssembler` instance. 49 | ASMJIT_API virtual ~BaseAssembler() noexcept; 50 | 51 | //! \} 52 | 53 | //! \name Code-Buffer Management 54 | //! \{ 55 | 56 | //! Returns the capacity of the current CodeBuffer. 57 | inline size_t bufferCapacity() const noexcept { return (size_t)(_bufferEnd - _bufferData); } 58 | //! Returns the number of remaining bytes in the current CodeBuffer. 59 | inline size_t remainingSpace() const noexcept { return (size_t)(_bufferEnd - _bufferPtr); } 60 | 61 | //! Returns the current position in the CodeBuffer. 62 | inline size_t offset() const noexcept { return (size_t)(_bufferPtr - _bufferData); } 63 | //! Sets the current position in the CodeBuffer to `offset`. 64 | //! 65 | //! \note The `offset` cannot be outside of the buffer size (even if it's 66 | //! within buffer's capacity). 67 | ASMJIT_API Error setOffset(size_t offset); 68 | 69 | //! Returns the start of the CodeBuffer in the current section. 70 | inline uint8_t* bufferData() const noexcept { return _bufferData; } 71 | //! Returns the end (first invalid byte) in the current section. 72 | inline uint8_t* bufferEnd() const noexcept { return _bufferEnd; } 73 | //! Returns the current pointer in the CodeBuffer in the current section. 74 | inline uint8_t* bufferPtr() const noexcept { return _bufferPtr; } 75 | 76 | //! \} 77 | 78 | //! \name Section Management 79 | //! \{ 80 | 81 | inline Section* currentSection() const noexcept { return _section; } 82 | 83 | ASMJIT_API Error section(Section* section) override; 84 | 85 | //! \} 86 | 87 | //! \name Label Management 88 | //! \{ 89 | 90 | ASMJIT_API Label newLabel() override; 91 | ASMJIT_API Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, uint32_t type = Label::kTypeGlobal, uint32_t parentId = Globals::kInvalidId) override; 92 | ASMJIT_API Error bind(const Label& label) override; 93 | 94 | //! \} 95 | 96 | //! \cond INTERNAL 97 | //! \name Emit 98 | //! \{ 99 | 100 | using BaseEmitter::_emit; 101 | 102 | ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) override; 103 | ASMJIT_API Error _emitOpArray(uint32_t instId, const Operand_* operands, size_t count) override; 104 | 105 | protected: 106 | #ifndef ASMJIT_NO_LOGGING 107 | void _emitLog( 108 | uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, 109 | uint32_t relSize, uint32_t immSize, uint8_t* afterCursor); 110 | 111 | Error _emitFailed( 112 | Error err, 113 | uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3); 114 | #else 115 | inline Error _emitFailed( 116 | uint32_t err, 117 | uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) { 118 | 119 | ASMJIT_UNUSED(instId); 120 | ASMJIT_UNUSED(options); 121 | ASMJIT_UNUSED(o0); 122 | ASMJIT_UNUSED(o1); 123 | ASMJIT_UNUSED(o2); 124 | ASMJIT_UNUSED(o3); 125 | 126 | resetInstOptions(); 127 | resetInlineComment(); 128 | return reportError(err); 129 | } 130 | #endif 131 | public: 132 | //! \} 133 | //! \endcond 134 | 135 | //! \name Embed 136 | //! \{ 137 | 138 | ASMJIT_API Error embed(const void* data, uint32_t dataSize) override; 139 | ASMJIT_API Error embedLabel(const Label& label) override; 140 | ASMJIT_API Error embedLabelDelta(const Label& label, const Label& base, uint32_t dataSize) override; 141 | ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override; 142 | 143 | //! \} 144 | 145 | //! \name Comment 146 | //! \{ 147 | 148 | ASMJIT_API Error comment(const char* data, size_t size = SIZE_MAX) override; 149 | 150 | //! \} 151 | 152 | //! \name Events 153 | //! \{ 154 | 155 | ASMJIT_API Error onAttach(CodeHolder* code) noexcept override; 156 | ASMJIT_API Error onDetach(CodeHolder* code) noexcept override; 157 | 158 | //! \} 159 | }; 160 | 161 | //! \} 162 | 163 | ASMJIT_END_NAMESPACE 164 | 165 | #endif // _ASMJIT_CORE_ASSEMBLER_H 166 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/zonehash.h: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #ifndef _ASMJIT_CORE_ZONEHASH_H 8 | #define _ASMJIT_CORE_ZONEHASH_H 9 | 10 | #include "../core/zone.h" 11 | 12 | ASMJIT_BEGIN_NAMESPACE 13 | 14 | //! \addtogroup asmjit_zone 15 | //! \{ 16 | 17 | // ============================================================================ 18 | // [asmjit::ZoneHashNode] 19 | // ============================================================================ 20 | 21 | //! Node used by `ZoneHash<>` template. 22 | //! 23 | //! You must provide function `bool eq(const Key& key)` in order to make 24 | //! `ZoneHash::get()` working. 25 | class ZoneHashNode { 26 | public: 27 | ASMJIT_NONCOPYABLE(ZoneHashNode) 28 | 29 | inline ZoneHashNode(uint32_t hashCode = 0) noexcept 30 | : _hashNext(nullptr), 31 | _hashCode(hashCode), 32 | _customData(0) {} 33 | 34 | //! Next node in the chain, null if it terminates the chain. 35 | ZoneHashNode* _hashNext; 36 | //! Precalculated hash-code of key. 37 | uint32_t _hashCode; 38 | //! Padding, can be reused by any Node that inherits `ZoneHashNode`. 39 | uint32_t _customData; 40 | }; 41 | 42 | // ============================================================================ 43 | // [asmjit::ZoneHashBase] 44 | // ============================================================================ 45 | 46 | class ZoneHashBase { 47 | public: 48 | ASMJIT_NONCOPYABLE(ZoneHashBase) 49 | 50 | //! Count of records inserted into the hash table. 51 | size_t _size; 52 | //! Count of hash buckets. 53 | uint32_t _bucketsCount; 54 | //! When buckets array should grow. 55 | uint32_t _bucketsGrow; 56 | 57 | //! Buckets data. 58 | ZoneHashNode** _data; 59 | //! Embedded data, used by empty hash tables. 60 | ZoneHashNode* _embedded[1]; 61 | 62 | //! \name Construction & Destruction 63 | //! \{ 64 | 65 | inline ZoneHashBase() noexcept { 66 | _size = 0; 67 | _bucketsCount = 1; 68 | _bucketsGrow = 1; 69 | _data = _embedded; 70 | _embedded[0] = nullptr; 71 | } 72 | 73 | inline ZoneHashBase(ZoneHashBase&& other) noexcept { 74 | _size = other._size; 75 | _bucketsCount = other._bucketsCount; 76 | _bucketsGrow = other._bucketsGrow; 77 | _data = other._data; 78 | _embedded[0] = other._embedded[0]; 79 | 80 | if (_data == other._embedded) _data = _embedded; 81 | } 82 | 83 | inline void reset() noexcept { 84 | _size = 0; 85 | _bucketsCount = 1; 86 | _bucketsGrow = 1; 87 | _data = _embedded; 88 | _embedded[0] = nullptr; 89 | } 90 | 91 | inline void release(ZoneAllocator* allocator) noexcept { 92 | ZoneHashNode** oldData = _data; 93 | if (oldData != _embedded) 94 | allocator->release(oldData, _bucketsCount * sizeof(ZoneHashNode*)); 95 | reset(); 96 | } 97 | 98 | //! \} 99 | 100 | //! \name Accessors 101 | //! \{ 102 | 103 | inline bool empty() const noexcept { return _size == 0; } 104 | inline size_t size() const noexcept { return _size; } 105 | 106 | //! \} 107 | 108 | //! \name Utilities 109 | //! \{ 110 | 111 | inline void _swap(ZoneHashBase& other) noexcept { 112 | std::swap(_size, other._size); 113 | std::swap(_bucketsCount, other._bucketsCount); 114 | std::swap(_bucketsGrow, other._bucketsGrow); 115 | std::swap(_data, other._data); 116 | std::swap(_embedded[0], other._embedded[0]); 117 | 118 | if (_data == other._embedded) _data = _embedded; 119 | if (other._data == _embedded) other._data = other._embedded; 120 | } 121 | 122 | //! \cond INTERNAL 123 | ASMJIT_API void _rehash(ZoneAllocator* allocator, uint32_t newCount) noexcept; 124 | ASMJIT_API ZoneHashNode* _insert(ZoneAllocator* allocator, ZoneHashNode* node) noexcept; 125 | ASMJIT_API ZoneHashNode* _remove(ZoneAllocator* allocator, ZoneHashNode* node) noexcept; 126 | //! \endcond 127 | 128 | //! \} 129 | }; 130 | 131 | // ============================================================================ 132 | // [asmjit::ZoneHash] 133 | // ============================================================================ 134 | 135 | //! Low-level hash table specialized for storing string keys and POD values. 136 | //! 137 | //! This hash table allows duplicates to be inserted (the API is so low 138 | //! level that it's up to you if you allow it or not, as you should first 139 | //! `get()` the node and then modify it or insert a new node by using `insert()`, 140 | //! depending on the intention). 141 | template 142 | class ZoneHash : public ZoneHashBase { 143 | public: 144 | ASMJIT_NONCOPYABLE(ZoneHash) 145 | 146 | typedef NodeT Node; 147 | 148 | //! \name Construction & Destruction 149 | //! \{ 150 | 151 | inline ZoneHash() noexcept 152 | : ZoneHashBase() {} 153 | 154 | inline ZoneHash(ZoneHash&& other) noexcept 155 | : ZoneHash(other) {} 156 | 157 | //! \} 158 | 159 | //! \name Utilities 160 | //! \{ 161 | 162 | inline void swap(ZoneHash& other) noexcept { ZoneHashBase::_swap(other); } 163 | 164 | template 165 | inline NodeT* get(const KeyT& key) const noexcept { 166 | uint32_t hMod = key.hashCode() % _bucketsCount; 167 | NodeT* node = static_cast(_data[hMod]); 168 | 169 | while (node && !key.matches(node)) 170 | node = static_cast(node->_hashNext); 171 | return node; 172 | } 173 | 174 | inline NodeT* insert(ZoneAllocator* allocator, NodeT* node) noexcept { return static_cast(_insert(allocator, node)); } 175 | inline NodeT* remove(ZoneAllocator* allocator, NodeT* node) noexcept { return static_cast(_remove(allocator, node)); } 176 | 177 | //! \} 178 | }; 179 | 180 | //! \} 181 | 182 | ASMJIT_END_NAMESPACE 183 | 184 | #endif // _ASMJIT_CORE_ZONEHASH_H 185 | -------------------------------------------------------------------------------- /SelfHackingApp/HackableCode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | #ifndef _WIN32 7 | #include 8 | #endif 9 | 10 | // These allow for MACRO overloading 11 | #define GET_MACRO(_1,_2,_3,NAME,...) NAME 12 | #define ASM(...) GET_MACRO(__VA_ARGS__, ASM3, ASM2, ASM1)(__VA_ARGS__) 13 | 14 | #define QUOTE(str) #str 15 | #define EXPAND_AND_QUOTE(str) QUOTE(str) 16 | 17 | #define COMMENT(str) Strings::Common_ConstantNewline::create()->setStringReplacementVariables( \ 18 | Strings::Common_Comment::create()->setStringReplacementVariables(str))->getString() 19 | 20 | #if (_WIN64 || (__GNUC__ && (__x86_64__ || __ppc64__))) 21 | #define ZAX rax 22 | #define ZBX rbx 23 | #define ZCX rcx 24 | #define ZDX rdx 25 | #define ZSI rsi 26 | #define ZDI rdi 27 | #define ZBP rbp 28 | #define ZSP rsp 29 | #define DIV_CONVERT cqo 30 | #else 31 | #define ZAX eax 32 | #define ZBX ebx 33 | #define ZCX ecx 34 | #define ZDX edx 35 | #define ZSI esi 36 | #define ZDI edi 37 | #define ZBP ebp 38 | #define ZSP esp 39 | #define DIV_CONVERT cdq 40 | #endif 41 | 42 | // Define macros for inlining x86 assembly in a compiler-independent way 43 | #ifdef _MSC_VER 44 | #define NO_OPTIMIZE \ 45 | __pragma(optimize("", off)) 46 | #define END_NO_OPTIMIZE \ 47 | __pragma(optimize("", on)) 48 | #define ASM1(asm_literal) \ 49 | __asm asm_literal 50 | #define ASM2(asm_literal1, asm_literal2) \ 51 | __asm asm_literal1, asm_literal2 52 | #define ASM3(asm_literal1, asm_literal2, asm_literal3) \ 53 | __asm asm_literal1, asm_literal2, asm_literal3 54 | 55 | #define ASM_MOV_REG_VAR(register, variable) \ 56 | ASM(mov register, variable) 57 | 58 | #define ASM_MOV_VAR_REG(variable, register) \ 59 | ASM(mov variable, register) 60 | 61 | #elif __GNUC__ || __clang__ 62 | #ifdef __clang__ 63 | #define NO_OPTIMIZE \ 64 | __attribute__((optnone)) 65 | #define END_NO_OPTIMIZE 66 | #elif __GNUC__ 67 | #define NO_OPTIMIZE \ 68 | _Pragma("GCC push_options") \ 69 | _Pragma("GCC optimize (\"O0\")") \ 70 | __attribute__((optimize("O0"))) 71 | #define END_NO_OPTIMIZE \ 72 | _Pragma("GCC pop_options") 73 | #endif 74 | 75 | #define ASM1(asm_literal) \ 76 | ASM_GCC(#asm_literal) 77 | #define ASM2(asm_literal1, asm_literal2) \ 78 | ASM_GCC(#asm_literal1 ", " #asm_literal2) 79 | #define ASM3(asm_literal1, asm_literal2, asm_literal3) \ 80 | ASM_GCC(#asm_literal1 ", " #asm_literal2 ", " #asm_literal3) 81 | 82 | #ifdef __x86_64__ 83 | #define ASM_MOV_REG_VAR(register, variable) \ 84 | __asm__ __volatile__("movq %0, %%" EXPAND_AND_QUOTE(register) : /* no outputs */ : "m"(variable) : ) 85 | 86 | #define ASM_MOV_VAR_REG(variable, register) \ 87 | __asm__ __volatile__("movq %%" EXPAND_AND_QUOTE(register) ", %0" : "=m"(variable) : /* no inputs */ : ) 88 | #else 89 | #define ASM_MOV_REG_VAR(register, variable) \ 90 | __asm__ __volatile__("mov %0, %%" EXPAND_AND_QUOTE(register) : /* no outputs */ : "m"(variable) : ) 91 | 92 | #define ASM_MOV_VAR_REG(variable, register) \ 93 | __asm__ __volatile__("mov %%" EXPAND_AND_QUOTE(register) ", %0" : "=m"(variable) : /* no inputs */ : ) 94 | #endif 95 | 96 | #define ASM_GCC(asm_string) \ 97 | __asm__ __volatile__(".intel_syntax noprefix;" asm_string ";.att_syntax prefix"); \ 98 | 99 | #endif 100 | 101 | // This is used to mark the beginning of an editable section of code 102 | // 56 6A 45 BE DE C0 ED FE 5E 5E 103 | #define HACKABLE_CODE_BEGIN() \ 104 | ASM(push ZDI) \ 105 | ASM(push 69) \ 106 | ASM(mov edi, 0xFEEDC0DE) \ 107 | ASM(pop ZDI) \ 108 | ASM(pop ZDI) 109 | 110 | // This is used to mark the end of an editable section of code 111 | // 56 6A 45 BE DE C0 AD DE 5E 5E 112 | #define HACKABLE_CODE_END() \ 113 | ASM(push ZSI) \ 114 | ASM(push 69) \ 115 | ASM(mov esi, 0xDEADC0DE) \ 116 | ASM(pop ZSI) \ 117 | ASM(pop ZSI) 118 | 119 | // This is used to stop searching for hackable sections 120 | // 56 6A 45 BE 5E EA 5E D1 5E 5E 121 | #define HACKABLES_STOP_SEARCH() \ 122 | ASM(push ZDX) \ 123 | ASM(push 69) \ 124 | ASM(mov edx, 0x0D15EA5E) \ 125 | ASM(pop ZDX) \ 126 | ASM(pop ZDX) 127 | 128 | #define ASM_NOP1() ASM(nop) 129 | #define ASM_NOP2() ASM_NOP1() ASM_NOP1() 130 | #define ASM_NOP3() ASM_NOP2() ASM_NOP1() 131 | #define ASM_NOP4() ASM_NOP3() ASM_NOP1() 132 | #define ASM_NOP5() ASM_NOP4() ASM_NOP1() 133 | #define ASM_NOP6() ASM_NOP5() ASM_NOP1() 134 | #define ASM_NOP7() ASM_NOP6() ASM_NOP1() 135 | #define ASM_NOP8() ASM_NOP7() ASM_NOP1() 136 | #define ASM_NOP9() ASM_NOP8() ASM_NOP1() 137 | #define ASM_NOP10() ASM_NOP9() ASM_NOP1() 138 | #define ASM_NOP11() ASM_NOP10() ASM_NOP1() 139 | #define ASM_NOP12() ASM_NOP11() ASM_NOP1() 140 | #define ASM_NOP13() ASM_NOP12() ASM_NOP1() 141 | #define ASM_NOP14() ASM_NOP13() ASM_NOP1() 142 | #define ASM_NOP15() ASM_NOP14() ASM_NOP1() 143 | #define ASM_NOP16() ASM_NOP15() ASM_NOP1() 144 | 145 | class HackableCode 146 | { 147 | public: 148 | static std::vector create(void* functionStart); 149 | 150 | std::string getAssemblyString(); 151 | std::string getOriginalAssemblyString(); 152 | void* getPointer(); 153 | int getOriginalLength(); 154 | bool applyCustomCode(std::string newAssembly); 155 | void restoreState(); 156 | 157 | protected: 158 | HackableCode(void* codeStart, void* codeEnd); 159 | virtual ~HackableCode(); 160 | 161 | private: 162 | struct HackableCodeMarkers 163 | { 164 | void* start; 165 | void* end; 166 | 167 | HackableCodeMarkers() : start(nullptr), end(nullptr) { } 168 | HackableCodeMarkers(void* start, void* end) : start(start), end(end) { } 169 | }; 170 | 171 | typedef std::map> MarkerMap; 172 | 173 | static std::vector parseHackables(void* functionStart); 174 | static std::vector& parseHackableMarkers(void* functionStart); 175 | 176 | std::string assemblyString; 177 | std::string originalAssemblyString; 178 | void* codePointer; 179 | void* codeEndPointer; 180 | std::vector originalCodeCopy; 181 | int originalCodeLength; 182 | 183 | static MarkerMap MarkerCache; 184 | static const unsigned char StartTagSignature[]; 185 | static const unsigned char EndTagSignature[]; 186 | static const unsigned char StopSearchTagSignature[]; 187 | }; 188 | -------------------------------------------------------------------------------- /SelfHackingApp/External/libudis86/decode.h: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/decode.h 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #ifndef UD_DECODE_H 27 | #define UD_DECODE_H 28 | 29 | #include "types.h" 30 | #include "udint.h" 31 | #include "itab.h" 32 | 33 | #define MAX_INSN_LENGTH 15 34 | 35 | /* itab prefix bits */ 36 | #define P_none ( 0 ) 37 | 38 | #define P_inv64 ( 1 << 0 ) 39 | #define P_INV64(n) ( ( n >> 0 ) & 1 ) 40 | #define P_def64 ( 1 << 1 ) 41 | #define P_DEF64(n) ( ( n >> 1 ) & 1 ) 42 | 43 | #define P_oso ( 1 << 2 ) 44 | #define P_OSO(n) ( ( n >> 2 ) & 1 ) 45 | #define P_aso ( 1 << 3 ) 46 | #define P_ASO(n) ( ( n >> 3 ) & 1 ) 47 | 48 | #define P_rexb ( 1 << 4 ) 49 | #define P_REXB(n) ( ( n >> 4 ) & 1 ) 50 | #define P_rexw ( 1 << 5 ) 51 | #define P_REXW(n) ( ( n >> 5 ) & 1 ) 52 | #define P_rexr ( 1 << 6 ) 53 | #define P_REXR(n) ( ( n >> 6 ) & 1 ) 54 | #define P_rexx ( 1 << 7 ) 55 | #define P_REXX(n) ( ( n >> 7 ) & 1 ) 56 | 57 | #define P_seg ( 1 << 8 ) 58 | #define P_SEG(n) ( ( n >> 8 ) & 1 ) 59 | 60 | #define P_vexl ( 1 << 9 ) 61 | #define P_VEXL(n) ( ( n >> 9 ) & 1 ) 62 | #define P_vexw ( 1 << 10 ) 63 | #define P_VEXW(n) ( ( n >> 10 ) & 1 ) 64 | 65 | #define P_str ( 1 << 11 ) 66 | #define P_STR(n) ( ( n >> 11 ) & 1 ) 67 | #define P_strz ( 1 << 12 ) 68 | #define P_STR_ZF(n) ( ( n >> 12 ) & 1 ) 69 | 70 | /* operand type constants -- order is important! */ 71 | 72 | enum ud_operand_code { 73 | OP_NONE, 74 | 75 | OP_A, OP_E, OP_M, OP_G, 76 | OP_I, OP_F, 77 | 78 | OP_R0, OP_R1, OP_R2, OP_R3, 79 | OP_R4, OP_R5, OP_R6, OP_R7, 80 | 81 | OP_AL, OP_CL, OP_DL, 82 | OP_AX, OP_CX, OP_DX, 83 | OP_eAX, OP_eCX, OP_eDX, 84 | OP_rAX, OP_rCX, OP_rDX, 85 | 86 | OP_ES, OP_CS, OP_SS, OP_DS, 87 | OP_FS, OP_GS, 88 | 89 | OP_ST0, OP_ST1, OP_ST2, OP_ST3, 90 | OP_ST4, OP_ST5, OP_ST6, OP_ST7, 91 | 92 | OP_J, OP_S, OP_O, 93 | OP_I1, OP_I3, OP_sI, 94 | 95 | OP_V, OP_W, OP_Q, OP_P, 96 | OP_U, OP_N, OP_MU, OP_H, 97 | OP_L, 98 | 99 | OP_R, OP_C, OP_D, 100 | 101 | OP_MR 102 | } UD_ATTR_PACKED; 103 | 104 | 105 | /* 106 | * Operand size constants 107 | * 108 | * Symbolic constants for various operand sizes. Some of these constants 109 | * are given a value equal to the width of the data (SZ_B == 8), such 110 | * that they maybe used interchangeably in the internals. Modifying them 111 | * will most certainly break things! 112 | */ 113 | typedef uint16_t ud_operand_size_t; 114 | 115 | #define SZ_NA 0 116 | #define SZ_Z 1 117 | #define SZ_V 2 118 | #define SZ_Y 3 119 | #define SZ_X 4 120 | #define SZ_RDQ 7 121 | #define SZ_B 8 122 | #define SZ_W 16 123 | #define SZ_D 32 124 | #define SZ_Q 64 125 | #define SZ_T 80 126 | #define SZ_O 12 127 | #define SZ_DQ 128 /* double quad */ 128 | #define SZ_QQ 256 /* quad quad */ 129 | 130 | /* 131 | * Complex size types; that encode sizes for operands of type MR (memory or 132 | * register); for internal use only. Id space above 256. 133 | */ 134 | #define SZ_BD ((SZ_B << 8) | SZ_D) 135 | #define SZ_BV ((SZ_B << 8) | SZ_V) 136 | #define SZ_WD ((SZ_W << 8) | SZ_D) 137 | #define SZ_WV ((SZ_W << 8) | SZ_V) 138 | #define SZ_WY ((SZ_W << 8) | SZ_Y) 139 | #define SZ_DY ((SZ_D << 8) | SZ_Y) 140 | #define SZ_WO ((SZ_W << 8) | SZ_O) 141 | #define SZ_DO ((SZ_D << 8) | SZ_O) 142 | #define SZ_QO ((SZ_Q << 8) | SZ_O) 143 | 144 | 145 | /* resolve complex size type. 146 | */ 147 | static UD_INLINE ud_operand_size_t 148 | Mx_mem_size(ud_operand_size_t size) 149 | { 150 | return (size >> 8) & 0xff; 151 | } 152 | 153 | static UD_INLINE ud_operand_size_t 154 | Mx_reg_size(ud_operand_size_t size) 155 | { 156 | return size & 0xff; 157 | } 158 | 159 | /* A single operand of an entry in the instruction table. 160 | * (internal use only) 161 | */ 162 | struct ud_itab_entry_operand 163 | { 164 | enum ud_operand_code type; 165 | ud_operand_size_t size; 166 | }; 167 | 168 | 169 | /* A single entry in an instruction table. 170 | *(internal use only) 171 | */ 172 | struct ud_itab_entry 173 | { 174 | enum ud_mnemonic_code mnemonic; 175 | struct ud_itab_entry_operand operand1; 176 | struct ud_itab_entry_operand operand2; 177 | struct ud_itab_entry_operand operand3; 178 | struct ud_itab_entry_operand operand4; 179 | uint32_t prefix; 180 | }; 181 | 182 | struct ud_lookup_table_list_entry { 183 | const uint16_t *table; 184 | enum ud_table_type type; 185 | const char *meta; 186 | }; 187 | 188 | extern struct ud_itab_entry ud_itab[]; 189 | extern struct ud_lookup_table_list_entry ud_lookup_table_list[]; 190 | 191 | #endif /* UD_DECODE_H */ 192 | 193 | /* vim:cindent 194 | * vim:expandtab 195 | * vim:ts=4 196 | * vim:sw=4 197 | */ -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/zonestack.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/zone.h" 10 | #include "../core/zonestack.h" 11 | 12 | ASMJIT_BEGIN_NAMESPACE 13 | 14 | // ============================================================================ 15 | // [asmjit::ZoneStackBase - Init / Reset] 16 | // ============================================================================ 17 | 18 | Error ZoneStackBase::_init(ZoneAllocator* allocator, size_t middleIndex) noexcept { 19 | ZoneAllocator* oldAllocator = _allocator; 20 | 21 | if (oldAllocator) { 22 | Block* block = _block[Globals::kLinkFirst]; 23 | while (block) { 24 | Block* next = block->next(); 25 | oldAllocator->release(block, kBlockSize); 26 | block = next; 27 | } 28 | 29 | _allocator = nullptr; 30 | _block[Globals::kLinkLeft] = nullptr; 31 | _block[Globals::kLinkRight] = nullptr; 32 | } 33 | 34 | if (allocator) { 35 | Block* block = static_cast(allocator->alloc(kBlockSize)); 36 | if (ASMJIT_UNLIKELY(!block)) 37 | return DebugUtils::errored(kErrorOutOfMemory); 38 | 39 | block->_link[Globals::kLinkLeft] = nullptr; 40 | block->_link[Globals::kLinkRight] = nullptr; 41 | block->_start = (uint8_t*)block + middleIndex; 42 | block->_end = (uint8_t*)block + middleIndex; 43 | 44 | _allocator = allocator; 45 | _block[Globals::kLinkLeft] = block; 46 | _block[Globals::kLinkRight] = block; 47 | } 48 | 49 | return kErrorOk; 50 | } 51 | 52 | // ============================================================================ 53 | // [asmjit::ZoneStackBase - Ops] 54 | // ============================================================================ 55 | 56 | Error ZoneStackBase::_prepareBlock(uint32_t side, size_t initialIndex) noexcept { 57 | ASMJIT_ASSERT(isInitialized()); 58 | 59 | Block* prev = _block[side]; 60 | ASMJIT_ASSERT(!prev->empty()); 61 | 62 | Block* block = _allocator->allocT(kBlockSize); 63 | if (ASMJIT_UNLIKELY(!block)) 64 | return DebugUtils::errored(kErrorOutOfMemory); 65 | 66 | block->_link[ side] = nullptr; 67 | block->_link[!side] = prev; 68 | block->_start = (uint8_t*)block + initialIndex; 69 | block->_end = (uint8_t*)block + initialIndex; 70 | 71 | prev->_link[side] = block; 72 | _block[side] = block; 73 | 74 | return kErrorOk; 75 | } 76 | 77 | void ZoneStackBase::_cleanupBlock(uint32_t side, size_t middleIndex) noexcept { 78 | Block* block = _block[side]; 79 | ASMJIT_ASSERT(block->empty()); 80 | 81 | Block* prev = block->_link[!side]; 82 | if (prev) { 83 | ASMJIT_ASSERT(prev->_link[side] == block); 84 | _allocator->release(block, kBlockSize); 85 | 86 | prev->_link[side] = nullptr; 87 | _block[side] = prev; 88 | } 89 | else if (_block[!side] == block) { 90 | // If the container becomes empty center both pointers in the remaining block. 91 | block->_start = (uint8_t*)block + middleIndex; 92 | block->_end = (uint8_t*)block + middleIndex; 93 | } 94 | } 95 | 96 | // ============================================================================ 97 | // [asmjit::ZoneStack - Unit] 98 | // ============================================================================ 99 | 100 | #if defined(ASMJIT_TEST) 101 | template 102 | static void test_zone_stack(ZoneAllocator* allocator, const char* typeName) { 103 | ZoneStack stack; 104 | 105 | INFO("Testing ZoneStack<%s>", typeName); 106 | INFO(" (%d items per one Block)", ZoneStack::kNumBlockItems); 107 | 108 | EXPECT(stack.init(allocator) == kErrorOk); 109 | EXPECT(stack.empty(), "Stack must be empty after `init()`"); 110 | 111 | EXPECT(stack.append(42) == kErrorOk); 112 | EXPECT(!stack.empty() , "Stack must not be empty after an item has been appended"); 113 | EXPECT(stack.pop() == 42 , "Stack.pop() must return the item that has been appended last"); 114 | EXPECT(stack.empty() , "Stack must be empty after the last item has been removed"); 115 | 116 | EXPECT(stack.prepend(43) == kErrorOk); 117 | EXPECT(!stack.empty() , "Stack must not be empty after an item has been prepended"); 118 | EXPECT(stack.popFirst() == 43, "Stack.popFirst() must return the item that has been prepended last"); 119 | EXPECT(stack.empty() , "Stack must be empty after the last item has been removed"); 120 | 121 | int i; 122 | int iMin =-100000; 123 | int iMax = 100000; 124 | 125 | INFO("Validating prepend() & popFirst()"); 126 | for (i = iMax; i >= 0; i--) stack.prepend(T(i)); 127 | for (i = 0; i <= iMax; i++) { 128 | T item = stack.popFirst(); 129 | EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item); 130 | if (!stack.empty()) { 131 | item = stack.popFirst(); 132 | EXPECT(i + 1 == item, "Item '%d' didn't match the item '%lld' popped", i + 1, (long long)item); 133 | stack.prepend(item); 134 | } 135 | } 136 | EXPECT(stack.empty()); 137 | 138 | INFO("Validating append() & pop()"); 139 | for (i = 0; i <= iMax; i++) stack.append(T(i)); 140 | for (i = iMax; i >= 0; i--) { 141 | T item = stack.pop(); 142 | EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item); 143 | if (!stack.empty()) { 144 | item = stack.pop(); 145 | EXPECT(i - 1 == item, "Item '%d' didn't match the item '%lld' popped", i - 1, (long long)item); 146 | stack.append(item); 147 | } 148 | } 149 | EXPECT(stack.empty()); 150 | 151 | INFO("Validating append()/prepend() & popFirst()"); 152 | for (i = 1; i <= iMax; i++) stack.append(T(i)); 153 | for (i = 0; i >= iMin; i--) stack.prepend(T(i)); 154 | 155 | for (i = iMin; i <= iMax; i++) { 156 | T item = stack.popFirst(); 157 | EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item); 158 | } 159 | EXPECT(stack.empty()); 160 | 161 | INFO("Validating append()/prepend() & pop()"); 162 | for (i = 0; i >= iMin; i--) stack.prepend(T(i)); 163 | for (i = 1; i <= iMax; i++) stack.append(T(i)); 164 | 165 | for (i = iMax; i >= iMin; i--) { 166 | T item = stack.pop(); 167 | EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item); 168 | } 169 | EXPECT(stack.empty()); 170 | } 171 | 172 | UNIT(asmjit_zone_stack) { 173 | Zone zone(8096 - Zone::kBlockOverhead); 174 | ZoneAllocator allocator(&zone); 175 | 176 | test_zone_stack(&allocator, "int"); 177 | test_zone_stack(&allocator, "int64_t"); 178 | } 179 | #endif 180 | 181 | ASMJIT_END_NAMESPACE 182 | -------------------------------------------------------------------------------- /SelfHackingApp/External/asmjit/core/rastack.cpp: -------------------------------------------------------------------------------- 1 | // [AsmJit] 2 | // Machine Code Generation for C++. 3 | // 4 | // [License] 5 | // Zlib - See LICENSE.md file in the package. 6 | 7 | #define ASMJIT_EXPORTS 8 | 9 | #include "../core/build.h" 10 | #ifndef ASMJIT_NO_COMPILER 11 | 12 | #include "../core/rastack_p.h" 13 | #include "../core/support.h" 14 | 15 | ASMJIT_BEGIN_NAMESPACE 16 | 17 | // ============================================================================ 18 | // [asmjit::RAStackAllocator - Slots] 19 | // ============================================================================ 20 | 21 | RAStackSlot* RAStackAllocator::newSlot(uint32_t baseRegId, uint32_t size, uint32_t alignment, uint32_t flags) noexcept { 22 | if (ASMJIT_UNLIKELY(_slots.willGrow(allocator(), 1) != kErrorOk)) 23 | return nullptr; 24 | 25 | RAStackSlot* slot = allocator()->allocT(); 26 | if (ASMJIT_UNLIKELY(!slot)) 27 | return nullptr; 28 | 29 | slot->_baseRegId = uint8_t(baseRegId); 30 | slot->_alignment = uint8_t(Support::max(alignment, 1)); 31 | slot->_reserved[0] = 0; 32 | slot->_reserved[1] = 0; 33 | slot->_useCount = 0; 34 | slot->_size = size; 35 | slot->_flags = flags; 36 | 37 | slot->_weight = 0; 38 | slot->_offset = 0; 39 | 40 | _alignment = Support::max(_alignment, alignment); 41 | _slots.appendUnsafe(slot); 42 | return slot; 43 | } 44 | 45 | // ============================================================================ 46 | // [asmjit::RAStackAllocator - Utilities] 47 | // ============================================================================ 48 | 49 | struct RAStackGap { 50 | inline RAStackGap() noexcept 51 | : offset(0), 52 | size(0) {} 53 | 54 | inline RAStackGap(uint32_t offset, uint32_t size) noexcept 55 | : offset(offset), 56 | size(size) {} 57 | 58 | inline RAStackGap(const RAStackGap& other) noexcept 59 | : offset(other.offset), 60 | size(other.size) {} 61 | 62 | uint32_t offset; 63 | uint32_t size; 64 | }; 65 | 66 | Error RAStackAllocator::calculateStackFrame() noexcept { 67 | // Base weight added to all registers regardless of their size and alignment. 68 | uint32_t kBaseRegWeight = 16; 69 | 70 | // STEP 1: 71 | // 72 | // Update usage based on the size of the slot. We boost smaller slots in a way 73 | // that 32-bit register has higher priority than a 128-bit register, however, 74 | // if one 128-bit register is used 4 times more than some other 32-bit register 75 | // it will overweight it. 76 | for (RAStackSlot* slot : _slots) { 77 | uint32_t alignment = slot->alignment(); 78 | ASMJIT_ASSERT(alignment > 0); 79 | 80 | uint32_t power = Support::ctz(alignment); 81 | uint64_t weight; 82 | 83 | if (slot->isRegHome()) 84 | weight = kBaseRegWeight + (uint64_t(slot->useCount()) * (7 - power)); 85 | else 86 | weight = power; 87 | 88 | // If overflown, which has less chance of winning a lottery, just use max 89 | // possible weight. In such case it probably doesn't matter at all. 90 | if (weight > 0xFFFFFFFFu) 91 | weight = 0xFFFFFFFFu; 92 | 93 | slot->setWeight(uint32_t(weight)); 94 | } 95 | 96 | // STEP 2: 97 | // 98 | // Sort stack slots based on their newly calculated weight (in descending order). 99 | _slots.sort([](const RAStackSlot* a, const RAStackSlot* b) noexcept { 100 | return a->weight() > b->weight() ? 1 : 101 | a->weight() == b->weight() ? 0 : -1; 102 | }); 103 | 104 | // STEP 3: 105 | // 106 | // Calculate offset of each slot. We start from the slot that has the highest 107 | // weight and advance to slots with lower weight. It could look that offsets 108 | // start from the first slot in our list and then simply increase, but it's 109 | // not always the case as we also try to fill all gaps introduced by the fact 110 | // that slots are sorted by weight and not by size & alignment, so when we need 111 | // to align some slot we distribute the gap caused by the alignment to `gaps`. 112 | uint32_t offset = 0; 113 | ZoneVector gaps[kSizeCount - 1]; 114 | 115 | for (RAStackSlot* slot : _slots) { 116 | if (slot->isStackArg()) continue; 117 | 118 | uint32_t slotAlignment = slot->alignment(); 119 | uint32_t alignedOffset = Support::alignUp(offset, slotAlignment); 120 | 121 | // Try to find a slot within gaps first, before advancing the `offset`. 122 | bool foundGap = false; 123 | uint32_t gapSize = 0; 124 | uint32_t gapOffset = 0; 125 | 126 | { 127 | uint32_t slotSize = slot->size(); 128 | if (slotSize < (1u << uint32_t(ASMJIT_ARRAY_SIZE(gaps)))) { 129 | // Iterate from the lowest to the highest possible. 130 | uint32_t index = Support::ctz(slotSize); 131 | do { 132 | if (!gaps[index].empty()) { 133 | RAStackGap gap = gaps[index].pop(); 134 | 135 | ASMJIT_ASSERT(Support::isAligned(gap.offset, slotAlignment)); 136 | slot->setOffset(int32_t(gap.offset)); 137 | 138 | gapSize = gap.size - slotSize; 139 | gapOffset = gap.offset - slotSize; 140 | 141 | foundGap = true; 142 | break; 143 | } 144 | } while (++index < uint32_t(ASMJIT_ARRAY_SIZE(gaps))); 145 | } 146 | } 147 | 148 | // No gap found, we may create a new one(s) if the current offset is not aligned. 149 | if (!foundGap && offset != alignedOffset) { 150 | gapSize = alignedOffset - offset; 151 | gapOffset = alignedOffset; 152 | 153 | offset = alignedOffset; 154 | } 155 | 156 | // True if we have found a gap and not filled all of it or we aligned the current offset. 157 | if (gapSize) { 158 | uint32_t gapEnd = gapSize + gapOffset; 159 | while (gapOffset < gapEnd) { 160 | uint32_t index = Support::ctz(gapOffset); 161 | uint32_t slotSize = 1u << index; 162 | 163 | // Weird case, better to bail... 164 | if (gapEnd - gapOffset < slotSize) 165 | break; 166 | 167 | ASMJIT_PROPAGATE(gaps[index].append(allocator(), RAStackGap(gapOffset, slotSize))); 168 | gapOffset += slotSize; 169 | } 170 | } 171 | 172 | if (!foundGap) { 173 | ASMJIT_ASSERT(Support::isAligned(offset, slotAlignment)); 174 | slot->setOffset(int32_t(offset)); 175 | offset += slot->size(); 176 | } 177 | } 178 | 179 | _stackSize = Support::alignUp(offset, _alignment); 180 | return kErrorOk; 181 | } 182 | 183 | Error RAStackAllocator::adjustSlotOffsets(int32_t offset) noexcept { 184 | for (RAStackSlot* slot : _slots) 185 | if (!slot->isStackArg()) 186 | slot->_offset += offset; 187 | return kErrorOk; 188 | } 189 | 190 | ASMJIT_END_NAMESPACE 191 | 192 | #endif // !ASMJIT_NO_COMPILER 193 | -------------------------------------------------------------------------------- /SelfHackingApp/HackableCode.cpp: -------------------------------------------------------------------------------- 1 | #include "HackableCode.h" 2 | 3 | #include 4 | 5 | #include "HackUtils.h" 6 | 7 | HackableCode::MarkerMap HackableCode::MarkerCache = HackableCode::MarkerMap(); 8 | 9 | // Note: all tags are assumed to start with a different byte and have the same length 10 | const unsigned char HackableCode::StartTagSignature[] = { 0x57, 0x6A, 0x45, 0xBF, 0xDE, 0xC0, 0xED, 0xFE, 0x5F, 0x5F }; 11 | const unsigned char HackableCode::EndTagSignature[] = { 0x56, 0x6A, 0x45, 0xBE, 0xDE, 0xC0, 0xAD, 0xDE, 0x5E, 0x5E }; 12 | const unsigned char HackableCode::StopSearchTagSignature[] = { 0x52, 0x6A, 0x45, 0xBA, 0x5E, 0xEA, 0x15, 0x0D, 0x5A, 0x5A }; 13 | 14 | std::vector HackableCode::create(void* functionStart) 15 | { 16 | return HackableCode::parseHackables(functionStart); 17 | } 18 | 19 | HackableCode::HackableCode(void* codeStart, void* codeEnd) 20 | { 21 | this->codePointer = (unsigned char*)codeStart; 22 | this->codeEndPointer = (unsigned char*)codeEnd; 23 | this->originalCodeLength = (int)((unsigned long)codeEnd - (unsigned long)codeStart); 24 | this->originalCodeCopy = std::vector(); 25 | this->originalAssemblyString = HackUtils::disassemble(codeStart, this->originalCodeLength); 26 | this->assemblyString = this->originalAssemblyString; 27 | } 28 | 29 | HackableCode::~HackableCode() 30 | { 31 | } 32 | 33 | std::string HackableCode::getAssemblyString() 34 | { 35 | return this->assemblyString; 36 | } 37 | 38 | std::string HackableCode::getOriginalAssemblyString() 39 | { 40 | return this->originalAssemblyString; 41 | } 42 | 43 | void* HackableCode::getPointer() 44 | { 45 | return this->codePointer; 46 | } 47 | 48 | int HackableCode::getOriginalLength() 49 | { 50 | return this->originalCodeLength; 51 | } 52 | 53 | bool HackableCode::applyCustomCode(std::string newAssembly) 54 | { 55 | this->assemblyString = newAssembly; 56 | 57 | if (this->codePointer == nullptr) 58 | { 59 | return false; 60 | } 61 | 62 | HackUtils::CompileResult compileResult = HackUtils::assemble(this->assemblyString, this->codePointer); 63 | 64 | // Try to compile code 65 | if (compileResult.hasError || compileResult.byteCount > this->originalCodeLength) 66 | { 67 | std::cout << compileResult.errorData.message << std::endl; 68 | 69 | // Fail the activation 70 | return false; 71 | } 72 | 73 | int unfilledBytes = this->originalCodeLength - compileResult.byteCount; 74 | 75 | // Fill remaining bytes with NOPs 76 | for (int index = 0; index < unfilledBytes; index++) 77 | { 78 | const unsigned char nop = 0x90; 79 | compileResult.compiledBytes.push_back(nop); 80 | } 81 | 82 | HackUtils::writeMemory(this->codePointer, compileResult.compiledBytes.data(), compileResult.compiledBytes.size()); 83 | 84 | return true; 85 | } 86 | 87 | void HackableCode::restoreState() 88 | { 89 | HackUtils::writeMemory(this->codePointer, this->originalCodeCopy.data(), this->originalCodeCopy.size()); 90 | } 91 | 92 | std::vector HackableCode::parseHackables(void* functionStart) 93 | { 94 | // Parse the HACKABLE_CODE_BEGIN/END pairs from the function. There may be multiple. 95 | std::vector markerList = HackableCode::parseHackableMarkers(functionStart); 96 | std::vector extractedHackableCode = std::vector(); 97 | 98 | // Bind the code info to each of the BEGIN/END markers to create a HackableCode object. 99 | for (auto marker : markerList) 100 | { 101 | extractedHackableCode.push_back(new HackableCode(marker.start, marker.end)); 102 | } 103 | 104 | return extractedHackableCode; 105 | } 106 | 107 | std::vector& HackableCode::parseHackableMarkers(void* functionStart) 108 | { 109 | if (HackableCode::MarkerCache.find(functionStart) != HackableCode::MarkerCache.end()) 110 | { 111 | return HackableCode::MarkerCache[functionStart]; 112 | } 113 | 114 | void* resolvedFunctionStart = HackUtils::resolveVTableAddress(functionStart); 115 | std::vector extractedMarkers = std::vector(); 116 | 117 | const int tagSize = sizeof(HackableCode::StartTagSignature) / sizeof((HackableCode::StartTagSignature)[0]); 118 | const int stopSearchingAfterXBytesFailSafe = 4096; 119 | 120 | unsigned char* currentBase = (unsigned char*)resolvedFunctionStart; 121 | unsigned char* currentSeek = (unsigned char*)resolvedFunctionStart; 122 | const unsigned char* targetArray = nullptr; 123 | void* nextHackableCodeStart = nullptr; 124 | 125 | while (true) 126 | { 127 | int signatureIndex = (int)((unsigned long)currentSeek - (unsigned long)currentBase); 128 | 129 | if (signatureIndex > stopSearchingAfterXBytesFailSafe) 130 | { 131 | std::cout << "Potentially fatal error: unable to find end signature in hackable code!" << std::endl; 132 | break; 133 | } 134 | 135 | if (targetArray == nullptr) 136 | { 137 | if (*currentSeek == HackableCode::StartTagSignature[0]) 138 | { 139 | targetArray = HackableCode::StartTagSignature; 140 | } 141 | else if (*currentSeek == HackableCode::EndTagSignature[0]) 142 | { 143 | targetArray = HackableCode::EndTagSignature; 144 | } 145 | else if (*currentSeek == HackableCode::StopSearchTagSignature[0]) 146 | { 147 | targetArray = HackableCode::StopSearchTagSignature; 148 | } 149 | else 150 | { 151 | // Next byte does not match the start of any signature 152 | currentBase++; 153 | currentSeek = currentBase; 154 | continue; 155 | } 156 | 157 | currentSeek++; 158 | continue; 159 | } 160 | 161 | // Check if we match the next expected character 162 | if (*currentSeek == targetArray[signatureIndex]) 163 | { 164 | currentSeek++; 165 | 166 | if (signatureIndex == tagSize - 1) 167 | { 168 | if (targetArray == HackableCode::StartTagSignature) 169 | { 170 | nextHackableCodeStart = (void*)currentSeek; 171 | } 172 | else if (targetArray == HackableCode::EndTagSignature) 173 | { 174 | if (nextHackableCodeStart != nullptr) 175 | { 176 | void* nextHackableCodeEnd = (void*)currentBase; 177 | 178 | extractedMarkers.push_back(HackableCodeMarkers(nextHackableCodeStart, nextHackableCodeEnd)); 179 | 180 | nextHackableCodeStart = nullptr; 181 | } 182 | } 183 | else if (targetArray == HackableCode::StopSearchTagSignature) 184 | { 185 | break; 186 | } 187 | } 188 | else 189 | { 190 | // Keep searching this signature 191 | continue; 192 | } 193 | } 194 | 195 | // Reset search state 196 | targetArray = nullptr; 197 | currentBase++; 198 | currentSeek = currentBase; 199 | } 200 | 201 | HackableCode::MarkerCache[functionStart] = extractedMarkers; 202 | 203 | return HackableCode::MarkerCache[functionStart]; 204 | } 205 | -------------------------------------------------------------------------------- /SelfHackingApp/External/libudis86/syn-att.c: -------------------------------------------------------------------------------- 1 | /* udis86 - libudis86/syn-att.c 2 | * 3 | * Copyright (c) 2002-2009 Vivek Thampi 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without modification, 7 | * are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | #include "types.h" 27 | #include "extern.h" 28 | #include "decode.h" 29 | #include "itab.h" 30 | #include "syn.h" 31 | #include "udint.h" 32 | 33 | /* ----------------------------------------------------------------------------- 34 | * opr_cast() - Prints an operand cast. 35 | * ----------------------------------------------------------------------------- 36 | */ 37 | static void 38 | opr_cast(struct ud* u, struct ud_operand* op) 39 | { 40 | switch (op->size) { 41 | case 16: case 32: 42 | ud_asmprintf(u, "*"); break; 43 | default: break; 44 | } 45 | } 46 | 47 | /* ----------------------------------------------------------------------------- 48 | * gen_operand() - Generates assembly output for each operand. 49 | * ----------------------------------------------------------------------------- 50 | */ 51 | static void 52 | gen_operand(struct ud* u, struct ud_operand* op) 53 | { 54 | switch (op->type) { 55 | case UD_OP_CONST: 56 | ud_asmprintf(u, "$0x%x", op->lval.udword); 57 | break; 58 | 59 | case UD_OP_REG: 60 | ud_asmprintf(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]); 61 | break; 62 | 63 | case UD_OP_MEM: 64 | if (u->br_far) { 65 | opr_cast(u, op); 66 | } 67 | if (u->pfx_seg) { 68 | ud_asmprintf(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); 69 | } 70 | if (op->offset != 0) { 71 | ud_syn_print_mem_disp(u, op, 0); 72 | } 73 | if (op->base) { 74 | ud_asmprintf(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]); 75 | } 76 | if (op->index) { 77 | if (op->base) { 78 | ud_asmprintf(u, ","); 79 | } 80 | else { 81 | ud_asmprintf(u, "("); 82 | } 83 | ud_asmprintf(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]); 84 | } 85 | if (op->scale) { 86 | ud_asmprintf(u, ",%d", op->scale); 87 | } 88 | if (op->base || op->index) { 89 | ud_asmprintf(u, ")"); 90 | } 91 | break; 92 | 93 | case UD_OP_IMM: 94 | ud_asmprintf(u, "$"); 95 | ud_syn_print_imm(u, op); 96 | break; 97 | 98 | case UD_OP_JIMM: 99 | ud_syn_print_addr(u, ud_syn_rel_target(u, op)); 100 | break; 101 | 102 | case UD_OP_PTR: 103 | switch (op->size) { 104 | case 32: 105 | ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg, 106 | op->lval.ptr.off & 0xFFFF); 107 | break; 108 | case 48: 109 | ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg, 110 | op->lval.ptr.off); 111 | break; 112 | } 113 | break; 114 | 115 | default: return; 116 | } 117 | } 118 | 119 | /* ============================================================================= 120 | * translates to AT&T syntax 121 | * ============================================================================= 122 | */ 123 | extern void 124 | ud_translate_att(struct ud *u) 125 | { 126 | int size = 0; 127 | int star = 0; 128 | 129 | /* check if P_OSO prefix is used */ 130 | if (!P_OSO(u->itab_entry->prefix) && u->pfx_opr) { 131 | switch (u->dis_mode) { 132 | case 16: 133 | ud_asmprintf(u, "o32 "); 134 | break; 135 | case 32: 136 | case 64: 137 | ud_asmprintf(u, "o16 "); 138 | break; 139 | } 140 | } 141 | 142 | /* check if P_ASO prefix was used */ 143 | if (!P_ASO(u->itab_entry->prefix) && u->pfx_adr) { 144 | switch (u->dis_mode) { 145 | case 16: 146 | ud_asmprintf(u, "a32 "); 147 | break; 148 | case 32: 149 | ud_asmprintf(u, "a16 "); 150 | break; 151 | case 64: 152 | ud_asmprintf(u, "a32 "); 153 | break; 154 | } 155 | } 156 | 157 | if (u->pfx_lock) 158 | ud_asmprintf(u, "lock "); 159 | if (u->pfx_rep) { 160 | ud_asmprintf(u, "rep "); 161 | } 162 | else if (u->pfx_repe) { 163 | ud_asmprintf(u, "repe "); 164 | } 165 | else if (u->pfx_repne) { 166 | ud_asmprintf(u, "repne "); 167 | } 168 | 169 | /* special instructions */ 170 | switch (u->mnemonic) { 171 | case UD_Iretf: 172 | ud_asmprintf(u, "lret "); 173 | break; 174 | case UD_Idb: 175 | ud_asmprintf(u, ".byte 0x%x", u->operand[0].lval.ubyte); 176 | return; 177 | case UD_Ijmp: 178 | case UD_Icall: 179 | if (u->br_far) ud_asmprintf(u, "l"); 180 | if (u->operand[0].type == UD_OP_REG) { 181 | star = 1; 182 | } 183 | ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic)); 184 | break; 185 | case UD_Ibound: 186 | case UD_Ienter: 187 | if (u->operand[0].type != UD_NONE) 188 | gen_operand(u, &u->operand[0]); 189 | if (u->operand[1].type != UD_NONE) { 190 | ud_asmprintf(u, ","); 191 | gen_operand(u, &u->operand[1]); 192 | } 193 | return; 194 | default: 195 | ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic)); 196 | } 197 | 198 | if (size == 8) { 199 | ud_asmprintf(u, "b"); 200 | } 201 | else if (size == 16) { 202 | ud_asmprintf(u, "w"); 203 | } 204 | else if (size == 64) { 205 | ud_asmprintf(u, "q"); 206 | } 207 | 208 | if (star) { 209 | ud_asmprintf(u, " *"); 210 | } 211 | else { 212 | ud_asmprintf(u, " "); 213 | } 214 | 215 | if (u->operand[3].type != UD_NONE) { 216 | gen_operand(u, &u->operand[3]); 217 | ud_asmprintf(u, ", "); 218 | } 219 | if (u->operand[2].type != UD_NONE) { 220 | gen_operand(u, &u->operand[2]); 221 | ud_asmprintf(u, ", "); 222 | } 223 | if (u->operand[1].type != UD_NONE) { 224 | gen_operand(u, &u->operand[1]); 225 | ud_asmprintf(u, ", "); 226 | } 227 | if (u->operand[0].type != UD_NONE) { 228 | gen_operand(u, &u->operand[0]); 229 | } 230 | } 231 | 232 | /* 233 | vim: set ts=2 sw=2 expandtab 234 | */ --------------------------------------------------------------------------------