├── libs ├── dobby │ ├── external │ │ ├── logging │ │ │ ├── logging_kern.cc │ │ │ └── CMakeLists.txt │ │ ├── TINYSTL │ │ │ ├── algorithm.h │ │ │ ├── README │ │ │ ├── tinystl.h │ │ │ └── function.h │ │ └── osbase │ │ │ └── CMakeLists.txt │ ├── source │ │ ├── core │ │ │ ├── emulator │ │ │ │ └── dummy.cc │ │ │ ├── assembler │ │ │ │ ├── assembler-x64.cc │ │ │ │ ├── assembler-x86-shared.cc │ │ │ │ ├── assembler-arch.h │ │ │ │ ├── assembler-ia32.cc │ │ │ │ ├── assembler-arm.cc │ │ │ │ └── assembler.h │ │ │ ├── arch │ │ │ │ ├── x86 │ │ │ │ │ ├── cpu-x86.cc │ │ │ │ │ └── constants-x86.h │ │ │ │ ├── x64 │ │ │ │ │ └── constants-x64.h │ │ │ │ ├── CpuRegister.h │ │ │ │ └── arm │ │ │ │ │ └── registers-arm.h │ │ │ └── codegen │ │ │ │ ├── codegen.h │ │ │ │ ├── codegen-ia32.h │ │ │ │ ├── codegen-arm.h │ │ │ │ ├── codegen-arm.cc │ │ │ │ ├── codegen-ia32.cc │ │ │ │ ├── codegen-arm64.h │ │ │ │ └── codegen-x64.h │ │ ├── Backend │ │ │ ├── KernelMode │ │ │ │ ├── ExecMemory │ │ │ │ │ ├── code-patch-tool-darwin.cc │ │ │ │ │ └── clear-cache-tool-all.c │ │ │ │ ├── UnifiedInterface │ │ │ │ │ └── platform-darwin.cc │ │ │ │ └── PlatformUtil │ │ │ │ │ └── Darwin │ │ │ │ │ └── ProcessRuntimeUtility.cc │ │ │ └── UserMode │ │ │ │ ├── Thread │ │ │ │ ├── platform-thread-windows.cc │ │ │ │ ├── PlatformThread.cc │ │ │ │ └── PlatformThread.h │ │ │ │ ├── MultiThreadSupport │ │ │ │ └── ThreadSupport.cpp │ │ │ │ └── ExecMemory │ │ │ │ ├── code-patch-tool-windows.cc │ │ │ │ ├── substrated │ │ │ │ └── mach_interface_support │ │ │ │ │ └── substrated.defs │ │ │ │ └── code-patch-tool-posix.cc │ │ ├── PlatformUnifiedInterface │ │ │ └── ExecMemory │ │ │ │ ├── CodePatchTool.h │ │ │ │ └── ClearCacheTool.h │ │ ├── dobby │ │ │ ├── kernel_mode_header.h │ │ │ ├── types.h │ │ │ ├── common.h │ │ │ ├── dobby_internal.h │ │ │ ├── platform_detect_macro.h │ │ │ └── platform_features.h │ │ ├── InstructionRelocation │ │ │ ├── InstructionRelocation.h │ │ │ ├── x64 │ │ │ │ └── InstructionRelocationX64.h │ │ │ ├── x86 │ │ │ │ ├── InstructionRelocationX86.h │ │ │ │ ├── X86DecodeKit.h │ │ │ │ └── InstructionRelocationX86Shared.h │ │ │ └── arm64 │ │ │ │ ├── InstructionRelocationARM64.h │ │ │ │ └── inst_constants.h │ │ ├── TrampolineBridge │ │ │ ├── ClosureTrampolineBridge │ │ │ │ ├── x64 │ │ │ │ │ ├── helper_x64.cc │ │ │ │ │ └── closure_trampoline_x64.asm │ │ │ │ ├── arm │ │ │ │ │ ├── helper_arm.cc │ │ │ │ │ └── dummy │ │ │ │ │ │ └── closure-trampoline-template-arm.S │ │ │ │ ├── arm64 │ │ │ │ │ ├── helper_arm64.cc │ │ │ │ │ └── closure_trampoline_arm64.asm │ │ │ │ ├── x86 │ │ │ │ │ └── helper_x86.cc │ │ │ │ ├── common_bridge_handler.h │ │ │ │ └── ClosureTrampoline.h │ │ │ └── Trampoline │ │ │ │ ├── trampoline_x86.cc │ │ │ │ └── Trampoline.h │ │ ├── InterceptRouting │ │ │ ├── NearBranchTrampoline │ │ │ │ └── NearBranchTrampoline.h │ │ │ ├── InstrumentRouting │ │ │ │ └── instrument_routing_handler.cpp │ │ │ ├── RoutingPlugin.h │ │ │ └── deprecated.Routing │ │ │ │ └── FunctionWrapper │ │ │ │ ├── FunctionWrapperExport.cc │ │ │ │ ├── intercept_routing_handler.h │ │ │ │ └── function-wrapper.h │ │ ├── PlatformUtil │ │ │ └── ProcessRuntime.h │ │ └── MemoryAllocator │ │ │ └── AssemblerCodeBuilder.h │ ├── README_zh-cn.md │ ├── builtin-plugin │ │ ├── SupervisorCallMonitor │ │ │ ├── README │ │ │ ├── test_supervisor_call_monitor.cc │ │ │ ├── CMakeLists.txt │ │ │ ├── supervisor_call_monitor.h │ │ │ ├── misc_utility.h │ │ │ └── misc_utility.cc │ │ ├── ImportTableReplace │ │ │ ├── CMakeLists.txt │ │ │ └── dobby_import_replace.h │ │ ├── SymbolResolver │ │ │ ├── macho │ │ │ │ ├── dobby_symbol_resolver_priv.h │ │ │ │ └── macho_file_symbol_resolver.h │ │ │ ├── dobby_symbol_resolver.h │ │ │ └── pe │ │ │ │ └── dobby_symbol_resolver.cc │ │ ├── ObjcRuntimeReplace │ │ │ ├── CMakeLists.txt │ │ │ └── dobby_objc_message_hook.mm │ │ ├── BionicLinkerUtil │ │ │ ├── bionic_linker_util.h │ │ │ └── bionic_linker_demo.cc │ │ ├── CMakeLists.txt │ │ └── ApplicationEventMonitor │ │ │ └── MGCopyAnswerMonitor.cc │ ├── cmake │ │ ├── Macros.cmake │ │ ├── xcode_generator_helper.cmake │ │ ├── Util.cmake │ │ ├── platform │ │ │ └── platform-darwin.cmake │ │ └── auto_source_group.cmake │ ├── examples │ │ ├── main.cc │ │ └── CMakeLists.txt │ ├── scripts │ │ ├── Dockerfile │ │ └── setup_macos_cross_compile.sh │ ├── common │ │ ├── hex_log.h │ │ ├── os_arch_features.h │ │ └── pac_kit.h │ ├── README.md │ └── tests │ │ └── test_insn_relo_x64.cpp ├── .clang-format ├── Catch2 │ ├── catch.hpp │ └── LICENSE.txt ├── efsw │ ├── src │ │ └── efsw │ │ │ ├── Mutex.hpp │ │ │ ├── Lock.hpp │ │ │ ├── Watcher.cpp │ │ │ ├── WatcherInotify.cpp │ │ │ ├── System.cpp │ │ │ ├── WatcherInotify.hpp │ │ │ ├── platform │ │ │ ├── posix │ │ │ │ ├── SystemImpl.hpp │ │ │ │ └── FileSystemImpl.hpp │ │ │ ├── win │ │ │ │ ├── SystemImpl.hpp │ │ │ │ ├── FileSystemImpl.hpp │ │ │ │ └── SystemImpl.cpp │ │ │ └── platformimpl.hpp │ │ │ ├── System.hpp │ │ │ ├── Watcher.hpp │ │ │ ├── DirectorySnapshotDiff.cpp │ │ │ ├── WatcherGeneric.hpp │ │ │ ├── Atomic.hpp │ │ │ ├── Thread.hpp │ │ │ ├── DirectorySnapshotDiff.hpp │ │ │ ├── WatcherGeneric.cpp │ │ │ ├── DirectorySnapshot.hpp │ │ │ ├── FileWatcherImpl.cpp │ │ │ ├── FileSystem.hpp │ │ │ ├── Log.cpp │ │ │ ├── Debug.hpp │ │ │ ├── FileInfo.hpp │ │ │ └── DirWatcherGeneric.hpp │ └── LICENSE ├── ELFIO │ ├── elfio │ │ └── elfio_version.hpp │ └── LICENSE.txt ├── argh │ ├── include │ │ └── argh.h │ └── LICENSE ├── utils │ ├── utils.hpp │ └── small_vector │ │ └── LICENSE.txt ├── whereami │ └── LICENSE.MIT ├── json │ └── LICENSE.MIT ├── teenypath │ └── LICENSE ├── tiny-process-library │ ├── LICENSE │ └── README.md └── xxHash │ └── LICENSE ├── .gitignore ├── tests ├── .clang-format └── src │ ├── Stacktrace.hpp │ ├── utility │ ├── OneFrameCompileReload.hpp │ ├── UndefinedSymbol.hpp │ ├── ReloadOnSignal.hpp │ ├── StaticFunctionLocalVariable.hpp │ ├── LostModification.hpp │ ├── ReloadAfterFailedCompilation1.hpp │ ├── ReloadAfterFailedCompilation2.hpp │ ├── UndefinedSymbolDeep.hpp │ ├── GlobalFreeFunction.hpp │ ├── GlobalVariableAddress.hpp │ ├── MultipleDefinitions.hpp │ ├── StaticVariableAddress.hpp │ ├── LostModification2.hpp │ ├── ModifyFileDuringReload.hpp │ ├── ExternGlobalVariableAddress.hpp │ ├── StaticVariable.hpp │ ├── FailedCompilationCrash.hpp │ ├── NewCompilationUnit.hpp │ ├── NewHeaderDependency.hpp │ ├── StaticInternalVariableAddress.hpp │ ├── CommonSection.h │ ├── GlobalVariable.hpp │ ├── StaticInternalVariable.hpp │ ├── ExternGlobalVariable.hpp │ ├── MacosFunctionOutOfScope.hpp │ ├── MultipleDefinitions │ │ ├── MultipleDefinitions2.hpp │ │ ├── MultipleDefinitions1.hpp │ │ ├── MultipleDefinitions2.cpp │ │ └── MultipleDefinitions1.cpp │ ├── StaticFunctionLocalVariableAddress.hpp │ ├── UndefinedSymbolDeep │ │ ├── UndefinedSymbolDeep2.hpp │ │ ├── UndefinedSymbolDeep1.hpp │ │ ├── UndefinedSymbolDeep1.cpp │ │ └── UndefinedSymbolDeep2.cpp │ ├── StaticVariableSameName1.hpp │ ├── StaticVariableSameName2.hpp │ ├── NewCompilationUnit │ │ ├── NewCompilationUnit2.hpp │ │ └── NewCompilationUnit2.cpp │ ├── InternalLinkageFunction.hpp │ ├── LambdaFunction.hpp │ ├── LostModification2.cpp │ ├── ClassInstanceMethod.hpp │ ├── ClassStaticMethod.hpp │ ├── UndefinedSymbol2.cpp │ ├── LambdaFunctionWithCaptures.hpp │ ├── LambdaFunctionWithCapturesBadCase.hpp │ ├── LambdaFunctionWithCapturesBadCase2.hpp │ ├── LambdaFunctionWithCapturesGoodCase.hpp │ ├── UndefinedSymbol2.hpp │ ├── IClassVirtualMethod.hpp │ ├── GlobalFreeFunction.cpp │ ├── ClassVirtualMethod.hpp │ ├── ClassStaticMethod.cpp │ ├── ClassVirtualMethod.cpp │ ├── ClassInstanceMethod.cpp │ ├── NewHeaderDependency │ │ └── NewHeaderDependency2.hpp │ ├── ReloadAfterFailedCompilation1.cpp │ ├── ReloadAfterFailedCompilation2.cpp │ ├── LambdaFunction.cpp │ ├── LostModification.cpp │ ├── ModifyFileDuringReload.cpp │ ├── StaticFunctionLocalVariable.cpp │ ├── NewCompilationUnit.cpp │ ├── StaticVariable.cpp │ ├── MacosFunctionOutOfScope.cpp │ ├── GlobalVariable.cpp │ ├── OneFrameCompileReload.cpp │ ├── FailedCompilationCrash.cpp │ ├── UndefinedSymbol.cpp │ ├── NewHeaderDependency.cpp │ ├── MacosGotRelocations.hpp │ ├── StaticFunctionLocalVariableAddress.cpp │ ├── StaticInternalVariable.cpp │ ├── ExternGlobalVariable.cpp │ ├── MultipleDefinitions.cpp │ ├── StaticVariableAddress.cpp │ ├── UndefinedSymbolDeep.cpp │ ├── GlobalVariableAddress.cpp │ ├── MacosGotRelocations.cpp │ ├── LambdaFunctionWithCaptures.cpp │ ├── ExternGlobalVariableAddress.cpp │ ├── StaticInternalVariableAddress.cpp │ ├── ReloadOnSignal.cpp │ ├── SeveralReloads.hpp │ ├── StaticVariableSameName2.cpp │ ├── StaticVariableSameName1.cpp │ ├── InternalLinkageFunction.cpp │ ├── CommonSection.c │ ├── LambdaFunctionWithCapturesGoodCase.cpp │ ├── LambdaFunctionWithCapturesBadCase.cpp │ └── LambdaFunctionWithCapturesBadCase2.cpp │ ├── Globals.hpp │ ├── WaitForReload.hpp │ ├── good │ ├── StaticFunctionLocalVariable_test.cpp │ ├── UndefinedSymbol_test.cpp │ ├── GlobalVariableAddress_test.cpp │ ├── StaticVariableAddress_test.cpp │ ├── ReloadOnSignal_test.cpp │ ├── GlobalFreeFunction_test.cpp │ ├── UndefinedSymbolDeep_test.cpp │ ├── StaticInternalVariableAddress_test.cpp │ ├── ClassStaticMethod_test.cpp │ ├── MacosGotRelocations_test.cpp │ ├── MultipleDefinitions_test.cpp │ ├── StaticFunctionLocalVariableAddress_test.cpp │ ├── LambdaFunction_test.cpp │ ├── StaticVariable_test.cpp │ ├── ClassInstanceMethod_test.cpp │ ├── GlobalVariable_test.cpp │ ├── LambdaFunctionWithCaptures_test.cpp │ ├── StaticInternalVariable_test.cpp │ ├── ExternGlobalVariableAddress_test.cpp │ ├── ClassVirtualMethod_test.cpp │ ├── ExternGlobalVariable_test.cpp │ ├── LambdaFunctionWithCapturesGoodCase_test.cpp │ ├── MacosFunctionOutOfScope_test.cpp │ ├── OneFrameCompileReload_test.cpp │ ├── LostModification_test.cpp │ ├── NewCompilationUnit_test.cpp │ ├── NewHeaderDependency_test.cpp │ ├── InternalLinkageFunction_test.cpp │ ├── CommonSection_test.cpp │ ├── ReloadAfterFailedCompilation_test.cpp │ ├── StaticVariableSameName_test.cpp │ └── FailedCompilationCrash_test.cpp │ ├── TestListener.hpp │ ├── bad │ ├── LambdaFunctionWithCapturesBadCase2_test.cpp │ └── LambdaFunctionWithCapturesBadCase_test.cpp │ ├── WaitForReload.cpp │ └── main.cpp ├── .dir-locals.el ├── src └── jet │ └── live │ ├── SignalReloader.hpp │ ├── BuildConfig.hpp │ ├── Status.hpp │ ├── StaticsCopyStep.hpp │ ├── FunctionsHookingStep.hpp │ ├── LinkTimeRelocationsStep.hpp │ ├── ICodeReloadPipelineStep.hpp │ ├── events │ ├── TryReloadEvent.hpp │ ├── FileChangedEvent.hpp │ └── LogEvent.hpp │ ├── DefaultProgramInfoLoader.hpp │ ├── DepfileDependenciesHandler.hpp │ ├── CodeReloadPipeline.cpp │ ├── CodeReloadPipeline.hpp │ ├── IEvent.hpp │ ├── LiveConfig.hpp │ ├── SignalReloader.cpp │ ├── IDependenciesHandler.hpp │ ├── DefaultSymbolsFilter.hpp │ ├── BuildConfig.cpp │ ├── ILiveListener.hpp │ ├── _linux │ └── ElfProgramInfoLoader.hpp │ ├── _macos │ └── MachoProgramInfoLoader.hpp │ ├── AsyncEventQueue.hpp │ ├── AsyncEventQueue.cpp │ └── ICompilationUnitsParser.hpp ├── .vscode ├── tasks.json ├── launch.json ├── c_cpp_properties.json └── settings.json ├── tools └── format │ └── format.sh ├── example ├── src │ ├── SimpleCommandInterpreter.hpp │ ├── ExampleListener.hpp │ ├── SimpleCommandInterpreter.cpp │ └── ExampleListener.cpp └── CMakeLists.txt └── LICENSE /libs/dobby/external/logging/logging_kern.cc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /libs/dobby/source/core/emulator/dummy.cc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /libs/dobby/README_zh-cn.md: -------------------------------------------------------------------------------- 1 | ## Dobby 2 | 3 | **待更新** -------------------------------------------------------------------------------- /libs/dobby/external/TINYSTL/algorithm.h: -------------------------------------------------------------------------------- 1 | #pragma once -------------------------------------------------------------------------------- /libs/dobby/source/Backend/KernelMode/ExecMemory/code-patch-tool-darwin.cc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /libs/dobby/source/Backend/KernelMode/UnifiedInterface/platform-darwin.cc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /libs/dobby/external/TINYSTL/README: -------------------------------------------------------------------------------- 1 | ref: https://github.com/mendsley/tinystl -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | tidy_report 3 | build 4 | compile_commands.json 5 | .cache -------------------------------------------------------------------------------- /libs/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | DisableFormat: true 3 | SortIncludes: false 4 | ... 5 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/SupervisorCallMonitor/README: -------------------------------------------------------------------------------- 1 | Monitor all supervisor call -------------------------------------------------------------------------------- /libs/dobby/source/Backend/KernelMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | DisableFormat: true 3 | SortIncludes: false 4 | ... 5 | -------------------------------------------------------------------------------- /tests/src/Stacktrace.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | void setupSignalHandlers(); 5 | -------------------------------------------------------------------------------- /libs/Catch2/catch.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "catch_amalgamated.hpp" 5 | -------------------------------------------------------------------------------- /tests/src/utility/OneFrameCompileReload.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int ofcrGetNext(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/UndefinedSymbol.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int undefinedGetValue(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/ReloadOnSignal.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int reloadOnSignalGetValue(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/StaticFunctionLocalVariable.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int getNext2(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/LostModification.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int lostModificationGetValue(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/ReloadAfterFailedCompilation1.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int rafcGetValue1(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/ReloadAfterFailedCompilation2.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int rafcGetValue2(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/UndefinedSymbolDeep.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int undefinedDeepGetValue(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/GlobalFreeFunction.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int computeResult(int v1, int v2); 5 | -------------------------------------------------------------------------------- /tests/src/utility/GlobalVariableAddress.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | void* getGlobalVariableAddress(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/MultipleDefinitions.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int multipleDefinitionsGetValue(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/StaticVariableAddress.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | void* getStaticVariableAddress(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/LostModification2.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int lostModificationGetAnotherValue(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/ModifyFileDuringReload.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int mfdrComputeResult(int v1, int v2); 5 | -------------------------------------------------------------------------------- /tests/src/utility/ExternGlobalVariableAddress.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | void* getExternGlobalVariableAddress(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/StaticVariable.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::pair getNext(); 7 | -------------------------------------------------------------------------------- /tests/src/utility/FailedCompilationCrash.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int failedCompilationComputeResult(int v1, int v2); 5 | -------------------------------------------------------------------------------- /tests/src/utility/NewCompilationUnit.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int newCompilationUnitComputeResult(int v1, int v2); 5 | -------------------------------------------------------------------------------- /tests/src/utility/NewHeaderDependency.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int newHeaderDependencyComputeResult(int v1, int v2); 5 | -------------------------------------------------------------------------------- /tests/src/utility/StaticInternalVariableAddress.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | void* getStaticInternalVariableAddress(); 5 | -------------------------------------------------------------------------------- /libs/dobby/cmake/Macros.cmake: -------------------------------------------------------------------------------- 1 | macro(SET_OPTION option value) 2 | set(${option} ${value} CACHE INTERNAL "" FORCE) 3 | endmacro() -------------------------------------------------------------------------------- /libs/dobby/external/TINYSTL/tinystl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "new.h" 4 | #include "vector.h" 5 | 6 | namespace stl = tinystl; -------------------------------------------------------------------------------- /tests/src/utility/CommonSection.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int getCommonSectionVar(); 5 | void* getCommonSectionVarAddress(); 6 | -------------------------------------------------------------------------------- /tests/src/utility/GlobalVariable.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::pair getNextGlobal1(); 7 | -------------------------------------------------------------------------------- /tests/src/utility/StaticInternalVariable.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::pair getNext1(); 7 | -------------------------------------------------------------------------------- /libs/dobby/source/Backend/KernelMode/ExecMemory/clear-cache-tool-all.c: -------------------------------------------------------------------------------- 1 | void ClearCache(void *start, void *end) { 2 | return; 3 | } 4 | -------------------------------------------------------------------------------- /tests/src/utility/ExternGlobalVariable.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::pair getNextGlobal(); 7 | -------------------------------------------------------------------------------- /tests/src/utility/MacosFunctionOutOfScope.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::string getStdStringValue(); 7 | -------------------------------------------------------------------------------- /tests/src/utility/MultipleDefinitions/MultipleDefinitions2.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int multipleDefinitionsAnotherGetValue(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/StaticFunctionLocalVariableAddress.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | void* getStaticFunctionLocalVariableAddress(); 5 | -------------------------------------------------------------------------------- /tests/src/utility/UndefinedSymbolDeep/UndefinedSymbolDeep2.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int undefinedDeepGetValueFromSomeFunction(); 5 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/ImportTableReplace/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(dobby_import_replace INTERFACE 2 | dobby_import_replace.cc 3 | ) -------------------------------------------------------------------------------- /tests/src/utility/StaticVariableSameName1.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::pair getNextSameName1(); 7 | -------------------------------------------------------------------------------- /tests/src/utility/StaticVariableSameName2.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::pair getNextSameName2(); 7 | -------------------------------------------------------------------------------- /tests/src/utility/NewCompilationUnit/NewCompilationUnit2.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int newCompilationUnit2ComputeResult(int v1, int v2); 5 | -------------------------------------------------------------------------------- /tests/src/utility/InternalLinkageFunction.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | void* getInternalFunctionAddress(); 5 | int computeResult1(int v1, int v2); 6 | -------------------------------------------------------------------------------- /tests/src/utility/LambdaFunction.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::function createLambdaFunction(); 7 | -------------------------------------------------------------------------------- /libs/dobby/external/osbase/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(osbase STATIC 2 | ${PROJECT_SOURCE_DIR}/source/Backend/UserMode/UnifiedInterface/platform-posix.cc 3 | ) -------------------------------------------------------------------------------- /tests/src/utility/LostModification2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "LostModification2.hpp" 3 | 4 | int lostModificationGetAnotherValue() 5 | { 6 | return 34; 7 | } 8 | -------------------------------------------------------------------------------- /libs/dobby/source/PlatformUnifiedInterface/ExecMemory/CodePatchTool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | int DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size); -------------------------------------------------------------------------------- /tests/src/utility/ClassInstanceMethod.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | class ClassInstanceMethod 5 | { 6 | public: 7 | int computeResult(int v1, int v2); 8 | }; 9 | -------------------------------------------------------------------------------- /tests/src/utility/ClassStaticMethod.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | class ClassStaticMethod 5 | { 6 | public: 7 | static int computeResult(int v1, int v2); 8 | }; 9 | -------------------------------------------------------------------------------- /tests/src/utility/UndefinedSymbol2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "UndefinedSymbol2.hpp" 3 | 4 | int UndefinedSomeClass::undefinedGetValue2() 5 | { 6 | return m_value++; 7 | } 8 | -------------------------------------------------------------------------------- /tests/src/utility/LambdaFunctionWithCaptures.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::function createLambdaFunctionWithCaptures(); 7 | -------------------------------------------------------------------------------- /.dir-locals.el: -------------------------------------------------------------------------------- 1 | ;;; Directory Local Variables 2 | ;;; For more information see (info "(emacs) Directory Variables") 3 | 4 | ((nil 5 | (my/project-app-name . "example"))) 6 | 7 | -------------------------------------------------------------------------------- /libs/dobby/source/dobby/kernel_mode_header.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include -------------------------------------------------------------------------------- /tests/src/utility/UndefinedSymbolDeep/UndefinedSymbolDeep1.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | class UndefinedDeepSomeClass 5 | { 6 | public: 7 | int undefinedDeepGetValue2(); 8 | }; 9 | -------------------------------------------------------------------------------- /tests/src/Globals.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | #include "TestListener.hpp" 6 | 7 | extern TestListener* g_testListenerPtr; 8 | extern jet::Live* g_live; 9 | -------------------------------------------------------------------------------- /tests/src/utility/LambdaFunctionWithCapturesBadCase.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::function createLambdaFunctionWithCapturesBadCase(); 7 | -------------------------------------------------------------------------------- /tests/src/utility/LambdaFunctionWithCapturesBadCase2.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::function createLambdaFunctionWithCapturesBadCase2(); 7 | -------------------------------------------------------------------------------- /tests/src/utility/LambdaFunctionWithCapturesGoodCase.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::function createLambdaFunctionWithCapturesGoodCase(); 7 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver_priv.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "macho_ctx.h" 6 | 7 | -------------------------------------------------------------------------------- /libs/dobby/source/dobby/types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef unsigned char byte_t; 6 | typedef unsigned int uint; 7 | 8 | #ifndef NULL 9 | #define NULL 0 10 | #endif 11 | -------------------------------------------------------------------------------- /tests/src/utility/UndefinedSymbol2.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | class UndefinedSomeClass 5 | { 6 | public: 7 | int undefinedGetValue2(); 8 | 9 | private: 10 | int m_value = 42; 11 | }; 12 | -------------------------------------------------------------------------------- /libs/dobby/source/core/assembler/assembler-x64.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_X64) 3 | 4 | #include "core/assembler/assembler-x64.h" 5 | 6 | using namespace zz::x64; 7 | 8 | #endif -------------------------------------------------------------------------------- /src/jet/live/SignalReloader.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | namespace jet 5 | { 6 | class Live; 7 | 8 | void onLiveCreated(Live* live, bool reloadOnSignal); 9 | void onLiveDestroyed(); 10 | } 11 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/ObjcRuntimeReplace/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(objc_runtime_replace 2 | dobby_objc_message_hook.mm 3 | ) 4 | 5 | target_link_libraries(objc_runtime_replace 6 | "-framework Foundation" 7 | ) -------------------------------------------------------------------------------- /libs/efsw/src/efsw/Mutex.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_MUTEX_HPP 2 | #define EFSW_MUTEX_HPP 3 | 4 | #include 5 | 6 | namespace efsw { 7 | using Mutex = std::recursive_mutex; 8 | } // namespace efsw 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/jet/live/BuildConfig.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | namespace jet 7 | { 8 | const std::string& getCmakeGenerator(); 9 | const std::string& getCmakeBuildDirectory(); 10 | } 11 | -------------------------------------------------------------------------------- /libs/ELFIO/elfio/elfio_version.hpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | //! \def ELFIO_VERSION 3 | //! \brief Defines the version of the ELFIO library 4 | #define ELFIO_VERSION "3.14" 5 | -------------------------------------------------------------------------------- /tests/src/utility/IClassVirtualMethod.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | class IClassVirtualMethod 5 | { 6 | public: 7 | virtual ~IClassVirtualMethod() {} 8 | 9 | virtual int computeResult(int v1, int v2) = 0; 10 | }; 11 | -------------------------------------------------------------------------------- /libs/dobby/source/core/arch/x86/cpu-x86.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) 3 | 4 | #include "cpu-x86.h" 5 | 6 | X86CpuInfo::X86CpuInfo() { 7 | 8 | } 9 | 10 | #endif -------------------------------------------------------------------------------- /libs/dobby/source/PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | void ClearCache(void *start, void *end); 8 | 9 | #ifdef __cplusplus 10 | } 11 | #endif -------------------------------------------------------------------------------- /tests/src/utility/MultipleDefinitions/MultipleDefinitions1.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | class MulDefSomeClass 5 | { 6 | public: 7 | int multipleDefinitionsGetValue2(); 8 | }; 9 | 10 | int multipleDefinitionsCircularGetValue(); 11 | -------------------------------------------------------------------------------- /tests/src/utility/GlobalFreeFunction.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "GlobalFreeFunction.hpp" 3 | 4 | int computeResult(int v1, int v2) 5 | { 6 | return v1 + v2; // 7 | // return v1 * v2; // 8 | } 9 | -------------------------------------------------------------------------------- /tests/src/utility/MultipleDefinitions/MultipleDefinitions2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "utility/MultipleDefinitions/MultipleDefinitions1.hpp" 3 | 4 | int multipleDefinitionsAnotherGetValue() 5 | { 6 | return multipleDefinitionsCircularGetValue(); 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "type": "shell", 7 | "command": "cd ${workspaceFolder}/build && make -j4" 8 | } 9 | ] 10 | } -------------------------------------------------------------------------------- /libs/efsw/src/efsw/Lock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_LOCK_HPP 2 | #define EFSW_LOCK_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace efsw { 8 | using Lock = std::unique_lock; 9 | } // namespace efsw 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /tests/src/utility/ClassVirtualMethod.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "IClassVirtualMethod.hpp" 5 | 6 | class ClassVirtualMethod : public IClassVirtualMethod 7 | { 8 | public: 9 | int computeResult(int v1, int v2) override; 10 | }; 11 | -------------------------------------------------------------------------------- /tests/src/utility/ClassStaticMethod.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ClassStaticMethod.hpp" 3 | 4 | int ClassStaticMethod::computeResult(int v1, int v2) 5 | { 6 | return v1 + v2; // 7 | // return v1 * v2; // 8 | } 9 | -------------------------------------------------------------------------------- /tests/src/utility/ClassVirtualMethod.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ClassVirtualMethod.hpp" 3 | 4 | int ClassVirtualMethod::computeResult(int v1, int v2) 5 | { 6 | return v1 + v2; // 7 | // return v1 * v2; // 8 | } 9 | -------------------------------------------------------------------------------- /tests/src/utility/ClassInstanceMethod.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ClassInstanceMethod.hpp" 3 | 4 | int ClassInstanceMethod::computeResult(int v1, int v2) 5 | { 6 | return v1 + v2; // 7 | // return v1 * v2; // 8 | } 9 | -------------------------------------------------------------------------------- /tests/src/utility/NewHeaderDependency/NewHeaderDependency2.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | int newHeaderDependency2ComputeResult(int v1, int v2) 5 | { 6 | return v1 * v2; // 7 | // return v1 * v2 + v1 + v2; // 8 | } 9 | -------------------------------------------------------------------------------- /tests/src/utility/UndefinedSymbolDeep/UndefinedSymbolDeep1.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "UndefinedSymbolDeep1.hpp" 3 | #include "UndefinedSymbolDeep2.hpp" 4 | 5 | int UndefinedDeepSomeClass::undefinedDeepGetValue2() 6 | { 7 | return undefinedDeepGetValueFromSomeFunction(); 8 | } 9 | -------------------------------------------------------------------------------- /tests/src/utility/ReloadAfterFailedCompilation1.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ReloadAfterFailedCompilation1.hpp" 3 | 4 | int rafcGetValue1() 5 | { 6 | return 15; // 7 | // return 17; // 8 | // return 19; // 9 | } 10 | -------------------------------------------------------------------------------- /tests/src/WaitForReload.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | void runAfterDelayAndWaitForReload(std::function&& func, int milliseconds = 1000); 7 | void waitForReload(int milliseconds = 1000); 8 | void waitForReloadWithSignal(int milliseconds = 1000); 9 | -------------------------------------------------------------------------------- /tests/src/utility/NewCompilationUnit/NewCompilationUnit2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "NewCompilationUnit2.hpp" 3 | 4 | int newCompilationUnit2ComputeResult(int v1, int v2) 5 | { 6 | return v1 * v2; // 7 | // return v1 * v2 + v1 + v2; // 8 | } 9 | -------------------------------------------------------------------------------- /tests/src/utility/ReloadAfterFailedCompilation2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ReloadAfterFailedCompilation2.hpp" 3 | 4 | int rafcGetValue2() 5 | { 6 | return 56; // 7 | // does not compile // 8 | // return 69; // 9 | } 10 | -------------------------------------------------------------------------------- /tests/src/utility/UndefinedSymbolDeep/UndefinedSymbolDeep2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "UndefinedSymbolDeep2.hpp" 3 | 4 | static int undefinedDeeptaticVarForSomeFunction = 55; 5 | 6 | int undefinedDeepGetValueFromSomeFunction() 7 | { 8 | return ++undefinedDeeptaticVarForSomeFunction; 9 | } 10 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | // int DobbyImportTableReplace(char *image_name, char *symbol_name, void *fake_func, void **orig_func); 8 | 9 | #ifdef __cplusplus 10 | } 11 | #endif -------------------------------------------------------------------------------- /libs/dobby/source/InstructionRelocation/InstructionRelocation.h: -------------------------------------------------------------------------------- 1 | #include "dobby/dobby_internal.h" 2 | 3 | void GenRelocateCode(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch); 4 | 5 | void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated); 6 | -------------------------------------------------------------------------------- /libs/dobby/source/core/codegen/codegen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "core/assembler/assembler.h" 4 | 5 | using namespace zz; 6 | 7 | struct CodeGenBase { 8 | CodeGenBase(AssemblerBase *assembler) : assembler_(assembler) { 9 | } 10 | 11 | protected: 12 | AssemblerBase *assembler_; 13 | }; 14 | -------------------------------------------------------------------------------- /libs/dobby/source/InstructionRelocation/x64/InstructionRelocationX64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/common.h" 4 | 5 | #include "core/arch/x64/constants-x64.h" 6 | 7 | #include "MemoryAllocator/AssemblerCodeBuilder.h" 8 | 9 | #include "InstructionRelocation/x86/InstructionRelocationX86Shared.h" 10 | -------------------------------------------------------------------------------- /libs/dobby/source/InstructionRelocation/x86/InstructionRelocationX86.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/common.h" 4 | 5 | #include "core/arch/x86/constants-x86.h" 6 | 7 | #include "MemoryAllocator/AssemblerCodeBuilder.h" 8 | 9 | #include "InstructionRelocation/x86/InstructionRelocationX86Shared.h" 10 | -------------------------------------------------------------------------------- /tests/src/utility/LambdaFunction.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "LambdaFunction.hpp" 3 | 4 | std::function createLambdaFunction() 5 | { 6 | return [] (int v1, int v2) { 7 | return v1 + v2; // 8 | // return v1 * v2; // 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /libs/dobby/examples/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(int argc, char const *argv[]) { 9 | 10 | std::cout << "Start..." << std::endl; 11 | 12 | sleep(100); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /tests/src/utility/LostModification.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "LostModification.hpp" 3 | // #include "LostModification2.hpp" // 4 | 5 | int lostModificationGetValue() 6 | { 7 | return 12; // 8 | // return lostModificationGetAnotherValue(); // 9 | } 10 | -------------------------------------------------------------------------------- /src/jet/live/Status.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | #include 6 | 7 | namespace jet 8 | { 9 | struct Status 10 | { 11 | std::set compilingFiles; 12 | std::set successfulFiles; 13 | std::set failedFiles; 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /src/jet/live/StaticsCopyStep.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "jet/live/ICodeReloadPipelineStep.hpp" 5 | 6 | namespace jet 7 | { 8 | class StaticsCopyStep : public ICodeReloadPipelineStep 9 | { 10 | public: 11 | void reload(LiveContext* context, Program* newProgram) override; 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /src/jet/live/FunctionsHookingStep.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "jet/live/ICodeReloadPipelineStep.hpp" 5 | 6 | namespace jet 7 | { 8 | class FunctionsHookingStep : public ICodeReloadPipelineStep 9 | { 10 | public: 11 | void reload(LiveContext* context, Program* newProgram) override; 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /tools/format/format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dirpath=$(python -c "import os,sys; print os.path.realpath(sys.argv[1])" $1) 4 | pushd $dirpath > /dev/null 5 | find . -type f -not -path "*/build/*" \( -name \*.h -o -name \*.hpp -o -name \*.inl -o -name \*.mm -o -name \*.m -o -name \*.cpp \) -print | xargs clang-format -i 6 | popd > /dev/null 7 | -------------------------------------------------------------------------------- /src/jet/live/LinkTimeRelocationsStep.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "jet/live/ICodeReloadPipelineStep.hpp" 5 | 6 | namespace jet 7 | { 8 | class LinkTimeRelocationsStep : public ICodeReloadPipelineStep 9 | { 10 | public: 11 | void reload(LiveContext* context, Program* newProgram) override; 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /tests/src/utility/ModifyFileDuringReload.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ModifyFileDuringReload.hpp" 3 | 4 | int mfdrComputeResult(int v1, int v2) 5 | { 6 | return v1 + v2; // 7 | // return v1 * v2; // 8 | // return v1 - v2; // 9 | // return v1 / v2; // 10 | } 11 | 12 | -------------------------------------------------------------------------------- /libs/dobby/examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(socket_example 2 | main.cc 3 | socket_example.cc 4 | ) 5 | 6 | target_link_libraries(socket_example 7 | dobby 8 | logging 9 | ) 10 | 11 | 12 | add_library(socket_example_lib SHARED 13 | socket_example.cc 14 | ) 15 | 16 | target_link_libraries(socket_example_lib 17 | dobby 18 | ) -------------------------------------------------------------------------------- /tests/src/utility/StaticFunctionLocalVariable.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "StaticFunctionLocalVariable.hpp" 3 | 4 | int getNext2() 5 | { 6 | static int variable = 0; 7 | variable += 4; 8 | variable += 1; 9 | variable -= 1; 10 | // Just to touch the file 11 | (void)variable; // 12 | return variable; 13 | } 14 | -------------------------------------------------------------------------------- /src/jet/live/ICodeReloadPipelineStep.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | namespace jet 5 | { 6 | struct LiveContext; 7 | struct Program; 8 | class ICodeReloadPipelineStep 9 | { 10 | public: 11 | virtual ~ICodeReloadPipelineStep() {} 12 | virtual void reload(LiveContext* context, Program* newProgram) = 0; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/SymbolResolver/dobby_symbol_resolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(BUILDING_INTERNAL) 4 | #include "macho/dobby_symbol_resolver_priv.h" 5 | #endif 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | void *DobbySymbolResolver(const char *image_name, const char *symbol_name); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif -------------------------------------------------------------------------------- /tests/src/utility/NewCompilationUnit.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "NewCompilationUnit.hpp" 3 | //#include "NewCompilationUnit/NewCompilationUnit2.hpp" // 4 | 5 | int newCompilationUnitComputeResult(int v1, int v2) 6 | { 7 | return v1 + v2; // 8 | // return newCompilationUnit2ComputeResult(v1, v2); // 9 | } 10 | -------------------------------------------------------------------------------- /tests/src/utility/StaticVariable.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "StaticVariable.hpp" 3 | 4 | static int staticVariable = 10; 5 | 6 | std::pair getNext() 7 | { 8 | staticVariable += 1; 9 | staticVariable -= 1; 10 | return {0, staticVariable++}; // 11 | // return {1, staticVariable++}; // 12 | } 13 | -------------------------------------------------------------------------------- /tests/src/utility/MacosFunctionOutOfScope.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "MacosFunctionOutOfScope.hpp" 3 | 4 | std::string getStdStringValue() 5 | { 6 | std::string stringValue = "some "; // 7 | // std::string stringValue = "some another "; // 8 | stringValue += "string"; 9 | return stringValue; 10 | } 11 | -------------------------------------------------------------------------------- /tests/src/utility/GlobalVariable.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "GlobalVariable.hpp" 3 | 4 | int someGlobalVariable = 10; 5 | 6 | std::pair getNextGlobal1() 7 | { 8 | someGlobalVariable += 1; 9 | someGlobalVariable -= 1; 10 | return {0, someGlobalVariable++}; // 11 | // return {1, someGlobalVariable++}; // 12 | } 13 | -------------------------------------------------------------------------------- /tests/src/utility/OneFrameCompileReload.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "OneFrameCompileReload.hpp" 3 | 4 | int ofcrGetNext() 5 | { 6 | static int ofctVariable = 0; 7 | ofctVariable += 4; 8 | ofctVariable += 1; 9 | ofctVariable -= 1; 10 | // Just to touch the file 11 | (void)ofctVariable; // 12 | return ofctVariable; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /tests/src/utility/FailedCompilationCrash.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "FailedCompilationCrash.hpp" 3 | 4 | int failedCompilationComputeResult(int v1, int v2) 5 | { 6 | return v1 + v2; // 7 | // return v1 + v2; // 8 | // not compilable code // 9 | // return v1 * v2; // 10 | } 11 | -------------------------------------------------------------------------------- /tests/src/utility/UndefinedSymbol.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "UndefinedSymbol.hpp" 3 | #include "UndefinedSymbol2.hpp" 4 | 5 | static int undefinedSomeStaticVariable = 21; 6 | 7 | int undefinedGetValue() 8 | { 9 | return undefinedSomeStaticVariable++; // 10 | // return UndefinedSomeClass{}.undefinedGetValue2(); // 11 | } 12 | -------------------------------------------------------------------------------- /tests/src/utility/NewHeaderDependency.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "NewHeaderDependency.hpp" 3 | //#include "NewHeaderDependency/NewHeaderDependency2.hpp" // 4 | 5 | int newHeaderDependencyComputeResult(int v1, int v2) 6 | { 7 | return v1 + v2; // 8 | // return newHeaderDependency2ComputeResult(v1, v2); // 9 | } 10 | -------------------------------------------------------------------------------- /libs/dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/dobby_internal.h" 4 | 5 | #include "core/arch/arm64/constants-arm64.h" 6 | 7 | #if 0 8 | namespace zz { 9 | namespace arm64 { 10 | void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated); 11 | } // namespace arm64 12 | } // namespace zz 13 | #endif -------------------------------------------------------------------------------- /src/jet/live/events/TryReloadEvent.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "jet/live/IEvent.hpp" 5 | 6 | namespace jet 7 | { 8 | class TryReloadEvent : public IEvent 9 | { 10 | public: 11 | TryReloadEvent() 12 | : IEvent(EventType::kTryReload) 13 | { 14 | } 15 | 16 | int getPriority() const override { return 10; } 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /example/src/SimpleCommandInterpreter.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | class SimpleCommandInterpreter 7 | { 8 | public: 9 | explicit SimpleCommandInterpreter(int currentCommandsCounter = 0); 10 | int getCurrentCommandsCounter() const; 11 | std::string runCommand(const std::string& command); 12 | 13 | private: 14 | int m_currentCommandsCounter = 0; 15 | }; 16 | -------------------------------------------------------------------------------- /tests/src/utility/MacosGotRelocations.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | namespace some_ns 7 | { 8 | template 9 | intptr_t typeOf() 10 | { 11 | static char dummy; 12 | return reinterpret_cast(&dummy); 13 | } 14 | } 15 | 16 | intptr_t getIntTypeOf(); 17 | intptr_t getFloatTypeOf(); 18 | intptr_t getStringTypeOf(); 19 | 20 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/Watcher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace efsw { 4 | 5 | Watcher::Watcher() : ID( 0 ), Directory( "" ), Listener( NULL ), Recursive( false ) {} 6 | 7 | Watcher::Watcher( WatchID id, std::string directory, FileWatchListener* listener, bool recursive ) : 8 | ID( id ), Directory( directory ), Listener( listener ), Recursive( recursive ) {} 9 | 10 | } // namespace efsw 11 | -------------------------------------------------------------------------------- /libs/dobby/external/logging/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(.) 2 | 3 | set(SOURCE_FILE_LIST 4 | logging.cc 5 | ) 6 | 7 | if (DOBBY_BUILD_KERNEL_MODE) 8 | set(SOURCE_FILE_LIST 9 | logging_kern.cc 10 | ) 11 | endif () 12 | 13 | get_absolute_path_list(SOURCE_FILE_LIST SOURCE_FILE_LIST_) 14 | set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST_}) 15 | 16 | add_library(logging 17 | ${SOURCE_FILE_LIST} 18 | ) -------------------------------------------------------------------------------- /tests/src/utility/StaticFunctionLocalVariableAddress.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "utility/StaticFunctionLocalVariableAddress.hpp" 3 | 4 | void* getStaticFunctionLocalVariableAddress() 5 | { 6 | static int variable = 0; 7 | variable += 1; 8 | variable -= 1; 9 | // Just to touch the file 10 | (void)variable; // 11 | return reinterpret_cast(&variable); 12 | } 13 | -------------------------------------------------------------------------------- /tests/src/utility/StaticInternalVariable.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "StaticInternalVariable.hpp" 3 | 4 | namespace 5 | { 6 | static int staticVariable = 0; 7 | } 8 | 9 | std::pair getNext1() 10 | { 11 | staticVariable += 1; 12 | staticVariable -= 1; 13 | return {0, staticVariable++}; // 14 | // return {1, staticVariable++}; // 15 | } 16 | -------------------------------------------------------------------------------- /libs/dobby/source/core/arch/x86/constants-x86.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_ARCH_CONSTANTS_X86_H 2 | #define CORE_ARCH_CONSTANTS_X86_H 3 | 4 | namespace zz { 5 | namespace x86 { 6 | 7 | enum ScaleFactor { 8 | TIMES_1 = 0, 9 | TIMES_2 = 1, 10 | TIMES_4 = 2, 11 | TIMES_8 = 3, 12 | TIMES_16 = 4, 13 | TIMES_HALF_WORD_SIZE = sizeof(void *) / 2 - 1 14 | }; 15 | 16 | } // namespace x86 17 | } // namespace zz 18 | 19 | #endif -------------------------------------------------------------------------------- /libs/dobby/source/dobby/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby.h" 4 | #include "dobby/types.h" 5 | #include "dobby/platform_features.h" 6 | #include "dobby/platform_detect_macro.h" 7 | #include "dobby/utility_macro.h" 8 | 9 | #include "logging/logging.h" 10 | #include "logging/check_logging.h" 11 | 12 | #include "common/os_arch_features.h" 13 | #include "common/hex_log.h" 14 | #include "common/pac_kit.h" 15 | -------------------------------------------------------------------------------- /libs/dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/helper_x64.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_X64) 3 | 4 | #include "dobby/dobby_internal.h" 5 | 6 | void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { 7 | ctx->ret = (uint64_t)address; 8 | } 9 | 10 | void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { 11 | } 12 | 13 | #endif -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "lldb", 6 | "request": "launch", 7 | "terminal" : "integrated", 8 | "name": "Debug", 9 | "program": "${workspaceFolder}/build/example/example", 10 | "cwd": "${workspaceFolder}/build", 11 | "preLaunchTask": "build" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/SymbolResolver/macho/macho_file_symbol_resolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "macho_ctx.h" 4 | 5 | uintptr_t macho_file_memory_symbol_resolve(cpu_type_t cpu, cpu_subtype_t subtype, const uint8_t *file_mem, 6 | char *symbol_name_pattern); 7 | 8 | uintptr_t macho_file_symbol_resolve(cpu_type_t cpu, cpu_subtype_t subtype, const char *file, char *symbol_name_pattern); 9 | -------------------------------------------------------------------------------- /tests/src/utility/ExternGlobalVariable.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ExternGlobalVariable.hpp" 3 | 4 | extern int someExternGlobalVariable; 5 | 6 | std::pair getNextGlobal() 7 | { 8 | someExternGlobalVariable += 1; 9 | someExternGlobalVariable -= 1; 10 | return {0, someExternGlobalVariable++};; // 11 | // return {1, someExternGlobalVariable++};; // 12 | } 13 | -------------------------------------------------------------------------------- /tests/src/utility/MultipleDefinitions.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "MultipleDefinitions.hpp" 3 | #include "MultipleDefinitions/MultipleDefinitions1.hpp" 4 | 5 | static int multipleDefinitionsSomeStaticVariable = 11; 6 | 7 | int multipleDefinitionsGetValue() 8 | { 9 | return ++multipleDefinitionsSomeStaticVariable; // 10 | // return MulDefSomeClass{}.multipleDefinitionsGetValue2(); // 11 | } 12 | -------------------------------------------------------------------------------- /tests/src/utility/StaticVariableAddress.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "StaticVariableAddress.hpp" 3 | 4 | static int staticVariableCheckingAddress = 10; 5 | 6 | void* getStaticVariableAddress() 7 | { 8 | staticVariableCheckingAddress += 1; 9 | staticVariableCheckingAddress -= 1; 10 | (void)staticVariableCheckingAddress; // 11 | return reinterpret_cast(&staticVariableCheckingAddress); 12 | } 13 | -------------------------------------------------------------------------------- /tests/src/utility/UndefinedSymbolDeep.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "UndefinedSymbolDeep.hpp" 3 | #include "UndefinedSymbolDeep/UndefinedSymbolDeep1.hpp" 4 | 5 | static int undefinedDeepSomeStaticVariable = 32; 6 | 7 | int undefinedDeepGetValue() 8 | { 9 | return ++undefinedDeepSomeStaticVariable; // 10 | // return UndefinedDeepSomeClass{}.undefinedDeepGetValue2(); // 11 | } 12 | -------------------------------------------------------------------------------- /libs/dobby/source/InterceptRouting/NearBranchTrampoline/NearBranchTrampoline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/dobby_internal.h" 4 | 5 | #include "InterceptRouting/RoutingPlugin.h" 6 | 7 | class NearBranchTrampolinePlugin : public RoutingPluginInterface {}; 8 | 9 | inline bool g_enable_near_trampoline = false; 10 | 11 | PUBLIC extern "C" inline void dobby_set_near_trampoline(bool enable) { 12 | g_enable_near_trampoline = enable; 13 | } -------------------------------------------------------------------------------- /libs/dobby/source/dobby/dobby_internal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/common.h" 4 | 5 | #include "PlatformUnifiedInterface/platform.h" 6 | 7 | #include "PlatformUnifiedInterface/ExecMemory/CodePatchTool.h" 8 | #include "PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h" 9 | 10 | #include "MemoryAllocator/AssemblerCodeBuilder.h" 11 | #include "MemoryAllocator/MemoryAllocator.h" 12 | 13 | #include "InterceptRouting/InterceptRouting.h" -------------------------------------------------------------------------------- /tests/src/utility/GlobalVariableAddress.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "GlobalVariableAddress.hpp" 3 | 4 | int someGlobalVariableCheckingAddress = 10; 5 | 6 | void* getGlobalVariableAddress() 7 | { 8 | someGlobalVariableCheckingAddress += 1; 9 | someGlobalVariableCheckingAddress -= 1; 10 | (void)someGlobalVariableCheckingAddress; // 11 | return reinterpret_cast(&someGlobalVariableCheckingAddress); 12 | } 13 | -------------------------------------------------------------------------------- /libs/dobby/scripts/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:focal 2 | 3 | ARG DEBIAN_FRONTEND='noninteractive' 4 | 5 | RUN apt-key adv --keyserver 'keyserver.ubuntu.com' --recv-key 'C99B11DEB97541F0' && 6 | apt-add-repository -y -u 'https://cli.github.com/packages' && 7 | apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' 8 | 9 | ADD setup_linux_cross_compile.sh /root/setup_linux_cross_compile.sh 10 | RUN sh /root/setup_linux_cross_compile.sh 11 | -------------------------------------------------------------------------------- /libs/dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/helper_arm.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_ARM) 3 | 4 | #include "dobby/dobby_internal.h" 5 | 6 | void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { 7 | *reinterpret_cast(&ctx->general.regs.r12) = address; 8 | } 9 | 10 | void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { 11 | } 12 | 13 | #endif -------------------------------------------------------------------------------- /tests/src/utility/MacosGotRelocations.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "MacosGotRelocations.hpp" 3 | #include 4 | 5 | intptr_t getIntTypeOf() 6 | { 7 | return some_ns::typeOf(); 8 | } 9 | 10 | intptr_t getFloatTypeOf() 11 | { 12 | return some_ns::typeOf(); 13 | } 14 | 15 | intptr_t getStringTypeOf() 16 | { 17 | // Just to touch the file 18 | int a = 0; // 19 | return some_ns::typeOf(); 20 | } 21 | -------------------------------------------------------------------------------- /tests/src/utility/MultipleDefinitions/MultipleDefinitions1.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "MultipleDefinitions1.hpp" 3 | #include "MultipleDefinitions2.hpp" 4 | 5 | static int multipleDefinitionsSomeStaticVariable2 = 87; 6 | 7 | int MulDefSomeClass::multipleDefinitionsGetValue2() 8 | { 9 | return multipleDefinitionsAnotherGetValue(); 10 | } 11 | 12 | int multipleDefinitionsCircularGetValue() 13 | { 14 | return ++multipleDefinitionsSomeStaticVariable2; 15 | } 16 | -------------------------------------------------------------------------------- /tests/src/utility/LambdaFunctionWithCaptures.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "LambdaFunctionWithCaptures.hpp" 3 | 4 | std::function createLambdaFunctionWithCaptures() 5 | { 6 | int dummyInt1 = 45; 7 | int dummyInt2 = -45; 8 | 9 | return [dummyInt1, dummyInt2] (int v1, int v2) { 10 | return v1 + v2 + dummyInt1 + dummyInt2; // 11 | // return v1 * v2 + dummyInt1 + dummyInt2; // 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /libs/argh/include/argh.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #if defined(__clang__) 5 | # pragma clang diagnostic push 6 | # pragma clang diagnostic ignored "-Wsign-conversion" 7 | #elif defined(__GNUC__) 8 | # pragma GCC diagnostic push 9 | # pragma GCC diagnostic ignored "-Wsign-conversion" 10 | #endif 11 | 12 | #include "../argh.h" 13 | 14 | #if defined(__clang__) 15 | # pragma clang diagnostic pop 16 | #elif defined(__GNUC__) 17 | # pragma GCC diagnostic pop 18 | #endif 19 | -------------------------------------------------------------------------------- /tests/src/utility/ExternGlobalVariableAddress.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ExternGlobalVariableAddress.hpp" 3 | 4 | extern int externGlobalVariableCheckingAddress; 5 | 6 | void* getExternGlobalVariableAddress() 7 | { 8 | externGlobalVariableCheckingAddress += 1; 9 | externGlobalVariableCheckingAddress -= 1; 10 | (void)externGlobalVariableCheckingAddress; // 11 | return reinterpret_cast(&externGlobalVariableCheckingAddress); 12 | } 13 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/WatcherInotify.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace efsw { 4 | 5 | WatcherInotify::WatcherInotify() : Watcher(), Parent( NULL ) {} 6 | 7 | bool WatcherInotify::inParentTree( WatcherInotify* parent ) { 8 | WatcherInotify* tNext = Parent; 9 | 10 | while ( NULL != tNext ) { 11 | if ( tNext == parent ) { 12 | return true; 13 | } 14 | 15 | tNext = tNext->Parent; 16 | } 17 | 18 | return false; 19 | } 20 | 21 | } // namespace efsw 22 | -------------------------------------------------------------------------------- /src/jet/live/DefaultProgramInfoLoader.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #ifdef __linux__ 5 | #include "jet/live/_linux/ElfProgramInfoLoader.hpp" 6 | namespace jet 7 | { 8 | using DefaultProgramInfoLoader = ElfProgramInfoLoader; 9 | } 10 | 11 | #elif __APPLE__ 12 | #include "jet/live/_macos/MachoProgramInfoLoader.hpp" 13 | namespace jet 14 | { 15 | using DefaultProgramInfoLoader = MachoProgramInfoLoader; 16 | } 17 | 18 | #else 19 | #error "Platform is not supported" 20 | #endif 21 | -------------------------------------------------------------------------------- /tests/src/utility/StaticInternalVariableAddress.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "StaticInternalVariableAddress.hpp" 3 | 4 | namespace 5 | { 6 | static int staticVariableCheckingAddress = 0; 7 | } 8 | 9 | void* getStaticInternalVariableAddress() 10 | { 11 | staticVariableCheckingAddress += 1; 12 | staticVariableCheckingAddress -= 1; 13 | (void)staticVariableCheckingAddress; // 14 | return reinterpret_cast(&staticVariableCheckingAddress); 15 | } 16 | -------------------------------------------------------------------------------- /tests/src/utility/ReloadOnSignal.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ReloadOnSignal.hpp" 3 | 4 | namespace 5 | { 6 | int get42Value() 7 | { 8 | static int res = 42; 9 | return res; 10 | } 11 | 12 | int get64Value() 13 | { 14 | static int res = 64; 15 | return res; 16 | } 17 | } 18 | 19 | int reloadOnSignalGetValue() 20 | { 21 | return ::get42Value(); // 22 | // return ::get64Value(); // 23 | } 24 | -------------------------------------------------------------------------------- /libs/dobby/source/InstructionRelocation/x86/X86DecodeKit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct x86_insn_t {}; 4 | 5 | struct x86_insn_decoder_t { 6 | uint8_t *buffer; 7 | uint32_t buffer_size; 8 | 9 | uint8_t mode = 64; 10 | 11 | x86_insn_t insn; 12 | explicit x86_insn_decoder_t(uint8_t *buffer, uint32_t buffer_size) : buffer(buffer), buffer_size(buffer_size) { 13 | } 14 | 15 | uint8_t peak_byte() const { 16 | return *buffer; 17 | } 18 | 19 | void decode_prefix() { 20 | } 21 | }; -------------------------------------------------------------------------------- /libs/dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper_arm64.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_ARM64) 3 | 4 | #include "core/assembler/assembler-arm64.h" 5 | 6 | using namespace zz::arm64; 7 | 8 | void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { 9 | *(void **)(&ctx->general.x[TMP_REG_0.code()]) = address; 10 | } 11 | 12 | void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { 13 | } 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /libs/dobby/source/core/assembler/assembler-x86-shared.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32) 3 | 4 | #include "core/assembler/assembler-x86-shared.h" 5 | 6 | using namespace zz::x86shared; 7 | 8 | void Assembler::jmp(Immediate imm) { 9 | buffer_->Emit(0xE9); 10 | buffer_->Emit((int)imm.value()); 11 | } 12 | 13 | uint64_t TurboAssembler::CurrentIP() { 14 | return pc_offset() + (addr_t)realized_addr_; 15 | } 16 | 17 | #endif -------------------------------------------------------------------------------- /libs/dobby/source/dobby/platform_detect_macro.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if !defined(DISABLE_ARCH_DETECT) 4 | #if defined(__arm__) 5 | #define TARGET_ARCH_ARM 1 6 | #elif defined(__arm64__) || defined(__aarch64__) 7 | #define TARGET_ARCH_ARM64 1 8 | #elif defined(_M_IX86) || defined(__i386__) 9 | #define TARGET_ARCH_IA32 1 10 | #elif defined(_M_X64) || defined(__x86_64__) 11 | #define TARGET_ARCH_X64 1 12 | #else 13 | #error Target architecture was not detected as supported by Dobby 14 | #endif 15 | #endif 16 | -------------------------------------------------------------------------------- /libs/dobby/common/hex_log.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "logging/logging.h" 4 | #include 5 | 6 | inline void debug_hex_log_buffer(const uint8_t *buffer, uint32_t buffer_size) { 7 | char print_buf[1024] = {0}; 8 | for (int i = 0; i < buffer_size && i < sizeof(print_buf); i++) { 9 | snprintf(print_buf + strlen(print_buf), sizeof(print_buf) - strlen(print_buf), "%02x ", *((uint8_t *)buffer + i)); 10 | } 11 | print_buf[sizeof(print_buf) - 1] = 0; 12 | DEBUG_LOG("%s", print_buf); 13 | }; -------------------------------------------------------------------------------- /tests/src/utility/SeveralReloads.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | std::pair severalGetGlobalVar(); 7 | std::pair severalGetExternGlobalVar(); 8 | std::pair severalGetStaticVar(); 9 | std::pair severalGetInternalStaticVar(); 10 | 11 | void* severalGetGlobalVarAddress(); 12 | void* severalGetExternGlobalVarAddress(); 13 | void* severalGetStaticVarAddress(); 14 | void* severalGetInternalStaticAddress(); 15 | void* severalGetFunctionLocalStaticVarAddress(); 16 | -------------------------------------------------------------------------------- /tests/src/utility/StaticVariableSameName2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "StaticVariableSameName2.hpp" 3 | 4 | static int staticVariableWithTheSameName = 110; 5 | 6 | std::pair getNextSameName2() 7 | { 8 | staticVariableWithTheSameName += 1; 9 | staticVariableWithTheSameName -= 1; 10 | // Ensuring that this file was reloaded 11 | return {10, staticVariableWithTheSameName++}; // 12 | // return {11, staticVariableWithTheSameName++}; // 13 | } 14 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/System.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace efsw { 5 | 6 | void System::sleep( const unsigned long& ms ) { 7 | Platform::System::sleep( ms ); 8 | } 9 | 10 | std::string System::getProcessPath() { 11 | return Platform::System::getProcessPath(); 12 | } 13 | 14 | void System::maxFD() { 15 | Platform::System::maxFD(); 16 | } 17 | 18 | Uint64 System::getMaxFD() { 19 | return Platform::System::getMaxFD(); 20 | } 21 | 22 | } // namespace efsw 23 | -------------------------------------------------------------------------------- /tests/src/utility/StaticVariableSameName1.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "StaticVariableSameName1.hpp" 3 | 4 | static int staticVariableWithTheSameName = 10; 5 | 6 | std::pair getNextSameName1() 7 | { 8 | staticVariableWithTheSameName += 1; 9 | staticVariableWithTheSameName -= 1; 10 | // Ensuring that this file was reloaded 11 | return {0, staticVariableWithTheSameName++}; // 12 | // return {1, staticVariableWithTheSameName++}; // 13 | } 14 | 15 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/WatcherInotify.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_WATCHERINOTIFY_HPP 2 | #define EFSW_WATCHERINOTIFY_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace efsw { 8 | 9 | class WatcherInotify : public Watcher { 10 | public: 11 | WatcherInotify(); 12 | 13 | bool inParentTree( WatcherInotify* parent ); 14 | 15 | WatcherInotify* Parent; 16 | WatchID InotifyID; 17 | 18 | FileInfo DirInfo; 19 | bool syntheticEvents{ false }; 20 | }; 21 | 22 | } // namespace efsw 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /libs/dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/helper_x86.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_IA32) 3 | 4 | #include "dobby/dobby_internal.h" 5 | 6 | void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { 7 | addr_t esp = ctx->esp; 8 | 9 | addr_t entry_placeholder_stack_addr = esp - 4; 10 | *(addr_t *)entry_placeholder_stack_addr = (addr_t)address; 11 | } 12 | 13 | void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { 14 | } 15 | 16 | #endif -------------------------------------------------------------------------------- /libs/dobby/source/core/arch/x64/constants-x64.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_ARCH_CONSTANTS_X64_H 2 | #define CORE_ARCH_CONSTANTS_X64_H 3 | 4 | namespace zz { 5 | namespace x64 { 6 | 7 | enum ScaleFactor { 8 | TIMES_1 = 0, 9 | TIMES_2 = 1, 10 | TIMES_4 = 2, 11 | TIMES_8 = 3, 12 | TIMES_16 = 4, 13 | TIMES_HALF_WORD_SIZE = sizeof(void *) / 2 - 1 14 | }; 15 | 16 | enum RexBits { REX_NONE = 0, REX_B = 1 << 0, REX_X = 1 << 1, REX_R = 1 << 2, REX_W = 1 << 3, REX_PREFIX = 1 << 6 }; 17 | 18 | } // namespace x64 19 | } // namespace zz 20 | 21 | #endif -------------------------------------------------------------------------------- /libs/efsw/src/efsw/platform/posix/SystemImpl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_SYSTEMIMPLPOSIX_HPP 2 | #define EFSW_SYSTEMIMPLPOSIX_HPP 3 | 4 | #include 5 | 6 | #if defined( EFSW_PLATFORM_POSIX ) 7 | 8 | namespace efsw { namespace Platform { 9 | 10 | class System { 11 | public: 12 | static void sleep( const unsigned long& ms ); 13 | 14 | static std::string getProcessPath(); 15 | 16 | static void maxFD(); 17 | 18 | static Uint64 getMaxFD(); 19 | }; 20 | 21 | }} // namespace efsw::Platform 22 | 23 | #endif 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/platform/win/SystemImpl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_SYSTEMIMPLWIN_HPP 2 | #define EFSW_SYSTEMIMPLWIN_HPP 3 | 4 | #include 5 | 6 | #if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 7 | 8 | namespace efsw { namespace Platform { 9 | 10 | class System { 11 | public: 12 | static void sleep( const unsigned long& ms ); 13 | 14 | static std::string getProcessPath(); 15 | 16 | static void maxFD(); 17 | 18 | static Uint64 getMaxFD(); 19 | }; 20 | 21 | }} // namespace efsw::Platform 22 | 23 | #endif 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /tests/src/utility/InternalLinkageFunction.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "InternalLinkageFunction.hpp" 3 | 4 | namespace 5 | { 6 | int internalComputeResult(int v1, int v2) 7 | { 8 | return v1 + v2; // 9 | // return v1 * v2; // 10 | } 11 | } 12 | 13 | void* getInternalFunctionAddress() 14 | { 15 | return reinterpret_cast(::internalComputeResult); 16 | } 17 | 18 | int computeResult1(int v1, int v2) 19 | { 20 | return ::internalComputeResult(v1, v2); 21 | } 22 | -------------------------------------------------------------------------------- /libs/dobby/source/core/codegen/codegen-ia32.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_CODEGEN_X86_H 2 | #define CORE_CODEGEN_X86_H 3 | 4 | #include "core/codegen/codegen.h" 5 | #include "core/assembler/assembler.h" 6 | #include "core/assembler/assembler-ia32.h" 7 | 8 | namespace zz { 9 | namespace x86 { 10 | 11 | class CodeGen : public CodeGenBase { 12 | public: 13 | CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { 14 | } 15 | 16 | void JmpNear(uint32_t address); 17 | }; 18 | 19 | } // namespace x86 20 | } // namespace zz 21 | 22 | #endif -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "ddovod", 5 | "includePath": [ 6 | "${workspaceFolder}/**" 7 | ], 8 | "defines": [], 9 | "compilerPath": "/usr/bin/c++", 10 | "cStandard": "c11", 11 | "cppStandard": "c++17", 12 | "intelliSenseMode": "clang-x64", 13 | "compileCommands": "${workspaceFolder}/build/compile_commands.json" 14 | } 15 | ], 16 | "version": 4 17 | } 18 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | typedef void *soinfo_t; 10 | 11 | soinfo_t linker_dlopen(const char *filename, int flag); 12 | 13 | char *linker_soinfo_get_realpath(soinfo_t soinfo); 14 | 15 | uintptr_t linker_soinfo_to_handle(soinfo_t soinfo); 16 | 17 | void linker_iterate_soinfo(int (*cb)(soinfo_t soinfo)); 18 | 19 | void linker_disable_namespace_restriction(); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif -------------------------------------------------------------------------------- /libs/efsw/src/efsw/platform/platformimpl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_PLATFORMIMPL_HPP 2 | #define EFSW_PLATFORMIMPL_HPP 3 | 4 | #include 5 | 6 | #if defined( EFSW_PLATFORM_POSIX ) 7 | #include 8 | #include 9 | #elif EFSW_PLATFORM == EFSW_PLATFORM_WIN32 10 | #include 11 | #include 12 | #else 13 | #error Thread, Mutex, and System not implemented for this platform. 14 | #endif 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /libs/dobby/source/core/codegen/codegen-arm.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_CODEGEN_ARM_H 2 | #define CORE_CODEGEN_ARM_H 3 | 4 | #include "core/codegen/codegen.h" 5 | #include "core/assembler/assembler.h" 6 | #include "core/assembler/assembler-arm.h" 7 | 8 | namespace zz { 9 | namespace arm { 10 | 11 | class CodeGen : public CodeGenBase { 12 | public: 13 | CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { 14 | } 15 | 16 | void LiteralLdrBranch(uint32_t address); 17 | }; 18 | 19 | } // namespace arm 20 | } // namespace zz 21 | 22 | #endif -------------------------------------------------------------------------------- /src/jet/live/DepfileDependenciesHandler.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "jet/live/IDependenciesHandler.hpp" 5 | 6 | namespace jet 7 | { 8 | /** 9 | * Dependencies handler implementation based on compiler generated depfiles. 10 | * For more info please refer to `-MD` compiler option. 11 | */ 12 | class DepfileDependenciesHandler : public IDependenciesHandler 13 | { 14 | public: 15 | std::unordered_set getDependencies(const LiveContext* context, CompilationUnit& cu) override; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "cctype": "cpp", 4 | "cmath": "cpp", 5 | "cstdint": "cpp", 6 | "cstdio": "cpp", 7 | "cstdlib": "cpp", 8 | "cwchar": "cpp", 9 | "cwctype": "cpp", 10 | "type_traits": "cpp", 11 | "__config": "cpp", 12 | "cstddef": "cpp", 13 | "exception": "cpp", 14 | "initializer_list": "cpp", 15 | "new": "cpp", 16 | "stdexcept": "cpp", 17 | "typeinfo": "cpp", 18 | "iosfwd": "cpp" 19 | } 20 | } -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/SupervisorCallMonitor/test_supervisor_call_monitor.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "dobby/dobby_internal.h" 3 | 4 | #include "SupervisorCallMonitor/supervisor_call_monitor.h" 5 | 6 | #if 1 7 | __attribute__((constructor)) static void ctor() { 8 | log_set_level(2); 9 | log_switch_to_syslog(); 10 | 11 | supervisor_call_monitor_init(); 12 | supervisor_call_monitor_register_main_app(); 13 | supervisor_call_monitor_register_syscall_call_log_handler(); 14 | supervisor_call_monitor_register_mach_syscall_call_log_handler(); 15 | } 16 | #endif -------------------------------------------------------------------------------- /src/jet/live/CodeReloadPipeline.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CodeReloadPipeline.hpp" 3 | #include 4 | 5 | namespace jet 6 | { 7 | void CodeReloadPipeline::addStep(std::unique_ptr&& step) 8 | { 9 | m_steps.emplace_back(std::move(step)); 10 | } 11 | 12 | void CodeReloadPipeline::reload(LiveContext* context, Program* newProgram) 13 | { 14 | assert(newProgram); 15 | 16 | for (const auto& step : m_steps) { 17 | step->reload(context, newProgram); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/jet/live/CodeReloadPipeline.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | #include 6 | #include "jet/live/ICodeReloadPipelineStep.hpp" 7 | 8 | namespace jet 9 | { 10 | struct LiveContext; 11 | struct Program; 12 | class CodeReloadPipeline 13 | { 14 | public: 15 | void addStep(std::unique_ptr&& step); 16 | void reload(LiveContext* context, Program* newProgram); 17 | 18 | private: 19 | std::vector> m_steps; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /libs/dobby/source/core/arch/CpuRegister.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct RegisterBase { 4 | int reg_id; 5 | 6 | static constexpr RegisterBase from_code(int reg_id) { 7 | return RegisterBase{reg_id}; 8 | } 9 | 10 | static constexpr RegisterBase no_reg() { 11 | return RegisterBase{0}; 12 | } 13 | 14 | explicit constexpr RegisterBase(int code) : reg_id(code) { 15 | } 16 | 17 | bool operator==(const RegisterBase &other) const { 18 | return reg_id == other.reg_id; 19 | } 20 | 21 | int code() const { 22 | return reg_id; 23 | }; 24 | }; -------------------------------------------------------------------------------- /libs/dobby/source/core/codegen/codegen-arm.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_ARM) 3 | 4 | #include "core/codegen/codegen-arm.h" 5 | 6 | namespace zz { 7 | namespace arm { 8 | 9 | void CodeGen::LiteralLdrBranch(uint32_t address) { 10 | TurboAssembler *turbo_assembler_ = reinterpret_cast(this->assembler_); 11 | #define _ turbo_assembler_-> 12 | _ ldr(pc, MemOperand(pc, -4)); 13 | turbo_assembler_->code_buffer()->Emit((addr_t)address); 14 | } 15 | 16 | } // namespace arm 17 | } // namespace zz 18 | 19 | #endif -------------------------------------------------------------------------------- /tests/src/good/StaticFunctionLocalVariable_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/StaticFunctionLocalVariable.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Relocation of function local static variable", "[variable]") 10 | { 11 | auto beforeReload = getNext2(); 12 | REQUIRE(beforeReload == 4); 13 | 14 | std::cout << "JET_TEST: disable(st_func_loc_var:1)" << std::endl; 15 | waitForReload(); 16 | 17 | auto afterReload = getNext2(); 18 | REQUIRE(afterReload == 8); 19 | } 20 | -------------------------------------------------------------------------------- /tests/src/good/UndefinedSymbol_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/UndefinedSymbol.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Undefined symbols after reload", "[common]") 10 | { 11 | auto beforeReload = undefinedGetValue(); 12 | REQUIRE(beforeReload == 21); 13 | 14 | std::cout << "JET_TEST: disable(undefined_sym:1); enable(undefined_sym:2)" << std::endl; 15 | waitForReload(); 16 | 17 | auto afterReload = undefinedGetValue(); 18 | REQUIRE(afterReload == 42); 19 | } 20 | -------------------------------------------------------------------------------- /libs/dobby/source/Backend/UserMode/Thread/platform-thread-windows.cc: -------------------------------------------------------------------------------- 1 | #include "PlatformThread.h" 2 | 3 | using namespace zz; 4 | 5 | int OSThread::GetCurrentProcessId() { 6 | return 0; 7 | } 8 | 9 | int OSThread::GetCurrentThreadId() { 10 | return 0; 11 | } 12 | 13 | OSThread::LocalStorageKey OSThread::CreateThreadLocalKey() { 14 | return 0; 15 | } 16 | 17 | void OSThread::DeleteThreadLocalKey(LocalStorageKey key) { 18 | } 19 | 20 | void *OSThread::GetThreadLocal(LocalStorageKey key) { 21 | return NULL; 22 | } 23 | 24 | void OSThread::SetThreadLocal(LocalStorageKey key, void *value) { 25 | } 26 | -------------------------------------------------------------------------------- /src/jet/live/IEvent.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | namespace jet 5 | { 6 | enum class EventType 7 | { 8 | kUnknown, 9 | kLog, 10 | kFileChanged, 11 | kTryReload, 12 | }; 13 | 14 | class IEvent 15 | { 16 | public: 17 | explicit IEvent(EventType type) 18 | : m_type(type) 19 | { 20 | } 21 | virtual ~IEvent() {} 22 | EventType getType() const { return m_type; } 23 | virtual int getPriority() const = 0; 24 | 25 | private: 26 | EventType m_type = EventType::kUnknown; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /example/src/ExampleListener.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | #include 6 | 7 | class ExampleListener : public jet::ILiveListener 8 | { 9 | public: 10 | ExampleListener(std::function&& codePreLoadCallback, std::function&& codePostLoadCallback); 11 | void onLog(jet::LogSeverity severity, const std::string& message) override; 12 | void onCodePreLoad() override; 13 | void onCodePostLoad() override; 14 | 15 | private: 16 | std::function m_codePreLoadCallback; 17 | std::function m_codePostLoadCallback; 18 | }; 19 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/SupervisorCallMonitor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(supervisor_call_monitor STATIC 2 | mach_system_call_log_handler.cc 3 | system_call_log_handler.cc 4 | supervisor_call_monitor.cc 5 | sensitive_api_monitor.cc 6 | misc_utility.cc 7 | ) 8 | target_link_libraries(supervisor_call_monitor 9 | misc_helper 10 | dobby 11 | ) 12 | 13 | add_library(test_supervisor_call_monitor SHARED 14 | test_supervisor_call_monitor.cc 15 | ) 16 | target_link_libraries(test_supervisor_call_monitor 17 | supervisor_call_monitor 18 | ) 19 | 20 | include_directories( 21 | . 22 | ) 23 | 24 | -------------------------------------------------------------------------------- /tests/src/TestListener.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | #include 6 | 7 | class TestListener : public jet::ILiveListener 8 | { 9 | public: 10 | void onLog(jet::LogSeverity severity, const std::string& message) override; 11 | void onCodePreLoad() override; 12 | void onCodePostLoad() override; 13 | 14 | void setCallbacks(std::function&& codePreLoadCallback, std::function&& codePostLoadCallback); 15 | 16 | private: 17 | std::function m_codePreLoadCallback; 18 | std::function m_codePostLoadCallback; 19 | }; 20 | -------------------------------------------------------------------------------- /src/jet/live/events/FileChangedEvent.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | #include "jet/live/IEvent.hpp" 6 | 7 | namespace jet 8 | { 9 | class FileChangedEvent : public IEvent 10 | { 11 | public: 12 | FileChangedEvent(const std::string& filepath) 13 | : IEvent(EventType::kFileChanged) 14 | , m_filepath(filepath) 15 | { 16 | } 17 | const std::string& getFilepath() const { return m_filepath; } 18 | int getPriority() const override { return 20; } 19 | 20 | private: 21 | std::string m_filepath; 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /tests/src/good/GlobalVariableAddress_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/GlobalVariableAddress.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Relocation of global variable, comparing address", "[variable]") 10 | { 11 | auto oldVariableAddress = getGlobalVariableAddress(); 12 | 13 | std::cout << "JET_TEST: disable(glob_var_addr:1)" << std::endl; 14 | waitForReload(); 15 | 16 | auto newVariableAddress = getGlobalVariableAddress(); 17 | REQUIRE(oldVariableAddress == newVariableAddress); 18 | } 19 | -------------------------------------------------------------------------------- /tests/src/good/StaticVariableAddress_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/StaticVariableAddress.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Relocation of static variable, comparing address", "[variable]") 10 | { 11 | auto oldVariableAddress = getStaticVariableAddress(); 12 | 13 | std::cout << "JET_TEST: disable(st_var_addr:1)" << std::endl; 14 | waitForReload(); 15 | 16 | auto newVariableAddress = getStaticVariableAddress(); 17 | REQUIRE(oldVariableAddress == newVariableAddress); 18 | } 19 | -------------------------------------------------------------------------------- /src/jet/live/LiveConfig.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | #include 6 | 7 | namespace jet 8 | { 9 | /** 10 | * Configuration parameters. 11 | */ 12 | struct LiveConfig 13 | { 14 | /** 15 | * The maximum amount of possible worker threads used by the library. 16 | * Usually all these threads are busy compiling new code. 17 | */ 18 | size_t workerThreadsCount = 4; 19 | 20 | /** 21 | * If `true`, also reload code when app receives `SIGUSR1`. 22 | */ 23 | bool reloadOnSignal = true; 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /libs/dobby/cmake/xcode_generator_helper.cmake: -------------------------------------------------------------------------------- 1 | if(CMAKE_GENERATOR STREQUAL Xcode) 2 | message(STATUS "[*] Detect Xcode Project") 3 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/build/Debug) 4 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/build/Release) 5 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/build/Debug) 6 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/build/Release) 7 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/build/Debug) 8 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/build/Release) 9 | endif() -------------------------------------------------------------------------------- /tests/src/good/ReloadOnSignal_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/ReloadOnSignal.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Reloading code when SIGUSR1 is received", "[common]") 10 | { 11 | auto beforeReload = reloadOnSignalGetValue(); 12 | REQUIRE(beforeReload == 42); 13 | 14 | std::cout << "JET_TEST: disable(reload_signal:1); enable(reload_signal:2)" << std::endl; 15 | waitForReloadWithSignal(); 16 | 17 | auto afterReload = reloadOnSignalGetValue(); 18 | REQUIRE(afterReload == 64); 19 | } 20 | -------------------------------------------------------------------------------- /tests/src/good/GlobalFreeFunction_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/GlobalFreeFunction.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Reload of global free function", "[function]") 10 | { 11 | int v1 = 23; 12 | int v2 = 45; 13 | int sum = v1 + v2; 14 | int mul = v1 * v2; 15 | 16 | REQUIRE(computeResult(v1, v2) == sum); 17 | 18 | std::cout << "JET_TEST: disable(glob_free_func:1); enable(glob_free_func:2)" << std::endl; 19 | waitForReload(); 20 | 21 | REQUIRE(computeResult(v1, v2) == mul); 22 | } 23 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/System.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_SYSTEM_HPP 2 | #define EFSW_SYSTEM_HPP 3 | 4 | #include 5 | 6 | namespace efsw { 7 | 8 | class System { 9 | public: 10 | /// Sleep for x milliseconds 11 | static void sleep( const unsigned long& ms ); 12 | 13 | /// @return The process binary path 14 | static std::string getProcessPath(); 15 | 16 | /// Maximize the number of file descriptors allowed per process in the current OS 17 | static void maxFD(); 18 | 19 | /// @return The number of supported file descriptors for the process 20 | static Uint64 getMaxFD(); 21 | }; 22 | 23 | } // namespace efsw 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/Watcher.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_WATCHERIMPL_HPP 2 | #define EFSW_WATCHERIMPL_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace efsw { 8 | 9 | /** @brief Base Watcher class */ 10 | class Watcher { 11 | public: 12 | Watcher(); 13 | 14 | Watcher( WatchID id, std::string directory, FileWatchListener* listener, bool recursive ); 15 | 16 | virtual ~Watcher() {} 17 | 18 | virtual void watch() {} 19 | 20 | WatchID ID; 21 | std::string Directory; 22 | FileWatchListener* Listener; 23 | bool Recursive; 24 | std::string OldFileName; 25 | }; 26 | 27 | } // namespace efsw 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /libs/dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/closure_trampoline_x64.asm: -------------------------------------------------------------------------------- 1 | #if defined(__x86_64__) 2 | #if defined(__WIN32__) || defined(__APPLE__) 3 | #define cdecl(s) _##s 4 | #else 5 | #define cdecl(s) s 6 | #endif 7 | 8 | .intel_syntax noprefix 9 | .align 4 10 | 11 | .globl cdecl(closure_trampoline_asm) 12 | 13 | // tip: rip mean next instruction address 14 | cdecl(closure_trampoline_asm): 15 | push [rip + 6] 16 | jmp [rip + 8] 17 | 18 | closure_tramp_entry_addr: 19 | .quad 0 20 | 21 | closure_bridge_addr: 22 | .quad 0 23 | 24 | .globl cdecl(closure_trampoline_asm_end) 25 | cdecl(closure_trampoline_asm_end): 26 | #endif -------------------------------------------------------------------------------- /src/jet/live/SignalReloader.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "SignalReloader.hpp" 3 | #include 4 | #include 5 | #include "jet/live/Live.hpp" 6 | 7 | namespace 8 | { 9 | jet::Live* livePtr = nullptr; 10 | } 11 | 12 | void signalHandler(int) 13 | { 14 | if (livePtr) { 15 | livePtr->tryReload(); 16 | } 17 | } 18 | 19 | namespace jet 20 | { 21 | void onLiveCreated(Live* live, bool reloadOnSignal) 22 | { 23 | ::livePtr = live; 24 | if (reloadOnSignal) { 25 | signal(SIGUSR1, signalHandler); 26 | } 27 | } 28 | 29 | void onLiveDestroyed() { ::livePtr = nullptr; } 30 | } 31 | -------------------------------------------------------------------------------- /tests/src/good/UndefinedSymbolDeep_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/UndefinedSymbolDeep.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Undefined symbols after reload, deep symbols dependency", "[common]") 10 | { 11 | auto beforeReload = undefinedDeepGetValue(); 12 | REQUIRE(beforeReload == 33); 13 | 14 | std::cout << "JET_TEST: disable(undefined_sym_deep:1); enable(undefined_sym_deep:2)" << std::endl; 15 | waitForReload(); 16 | 17 | auto afterReload = undefinedDeepGetValue(); 18 | REQUIRE(afterReload == 56); 19 | } 20 | -------------------------------------------------------------------------------- /tests/src/utility/CommonSection.c: -------------------------------------------------------------------------------- 1 | 2 | #include "CommonSection.h" 3 | 4 | int commonSectionVariable; 5 | char initialized = 0; 6 | 7 | int getCommonSectionVar() 8 | { 9 | if (initialized == 0) { 10 | commonSectionVariable = 10; 11 | initialized = 1; 12 | } 13 | // (void)initialized; // 14 | commonSectionVariable += 1; 15 | commonSectionVariable -= 1; 16 | return commonSectionVariable++; 17 | } 18 | 19 | void* getCommonSectionVarAddress() 20 | { 21 | commonSectionVariable += 1; 22 | commonSectionVariable -= 1; 23 | return (void*)(&commonSectionVariable); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (Plugin.ImportTableReplace AND SYSTEM.Darwin) 2 | message(STATUS "[Dobby] Enable got hook") 3 | include_directories(builtin-plugin/ImportTableReplace) 4 | add_subdirectory(builtin-plugin/ImportTableReplace) 5 | endif () 6 | 7 | if (Plugin.Android.BionicLinkerUtil) 8 | if (NOT SYSTEM.Android) 9 | message(FATAL_ERROR "[!] Plugin.Android.BionicLinkerUtil only works on Android.") 10 | endif () 11 | message(STATUS "[Dobby] Enable Plugin.Android.BionicLinkerUtil") 12 | set(dobby.plugin.SOURCE_FILE_LIST ${dobby.plugin.SOURCE_FILE_LIST} 13 | BionicLinkerUtil/bionic_linker_util.cc 14 | ) 15 | endif () -------------------------------------------------------------------------------- /tests/src/good/StaticInternalVariableAddress_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/StaticInternalVariableAddress.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Relocation of static internal variable, comparing address", "[variable]") 10 | { 11 | auto oldVariableAddress = getStaticInternalVariableAddress(); 12 | 13 | std::cout << "JET_TEST: disable(st_intern_var_addr:1)" << std::endl; 14 | waitForReload(); 15 | 16 | auto newVariableAddress = getStaticInternalVariableAddress(); 17 | REQUIRE(oldVariableAddress == newVariableAddress); 18 | } 19 | -------------------------------------------------------------------------------- /libs/dobby/source/Backend/UserMode/Thread/PlatformThread.cc: -------------------------------------------------------------------------------- 1 | #include "./PlatformThread.h" 2 | 3 | namespace zz { 4 | int OSThread::GetThreadLocalInt(LocalStorageKey key) { 5 | return static_cast(reinterpret_cast(GetThreadLocal(key))); 6 | } 7 | 8 | void OSThread::SetThreadLocalInt(LocalStorageKey key, int value) { 9 | SetThreadLocal(key, reinterpret_cast(static_cast(value))); 10 | } 11 | 12 | bool OSThread::HasThreadLocal(LocalStorageKey key) { 13 | return GetThreadLocal(key) != nullptr; 14 | } 15 | 16 | void *OSThread::GetExistingThreadLocal(LocalStorageKey key) { 17 | return GetThreadLocal(key); 18 | } 19 | } // namespace zz -------------------------------------------------------------------------------- /tests/src/good/ClassStaticMethod_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/ClassStaticMethod.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Reload of class static method", "[function]") 10 | { 11 | int v1 = 23; 12 | int v2 = 45; 13 | int sum = v1 + v2; 14 | int mul = v1 * v2; 15 | 16 | REQUIRE(ClassStaticMethod::computeResult(v1, v2) == sum); 17 | 18 | std::cout << "JET_TEST: disable(cls_st_meth:1); enable(cls_st_meth:2)" << std::endl; 19 | waitForReload(); 20 | 21 | REQUIRE(ClassStaticMethod::computeResult(v1, v2) == mul); 22 | } 23 | -------------------------------------------------------------------------------- /tests/src/good/MacosGotRelocations_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "WaitForReload.hpp" 5 | #include "catch_amalgamated.hpp" 6 | #include "utility/MacosGotRelocations.hpp" 7 | 8 | TEST_CASE("GOT relocations on macOS", "[common]") 9 | { 10 | auto intTypeOf = getIntTypeOf(); 11 | auto floatTypeOf = getFloatTypeOf(); 12 | auto stringTypeOf = getStringTypeOf(); 13 | 14 | std::cout << "JET_TEST: disable(mgreloc:1)" << std::endl; 15 | waitForReload(); 16 | 17 | REQUIRE(getIntTypeOf() == intTypeOf); 18 | REQUIRE(getFloatTypeOf() == floatTypeOf); 19 | REQUIRE(getStringTypeOf() == stringTypeOf); 20 | } 21 | -------------------------------------------------------------------------------- /tests/src/good/MultipleDefinitions_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/MultipleDefinitions.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Multiple definitions of symbols after reload, circular symbols dependency", "[common]") 10 | { 11 | auto beforeReload = multipleDefinitionsGetValue(); 12 | REQUIRE(beforeReload == 12); 13 | 14 | std::cout << "JET_TEST: disable(mul_def:1); enable(mul_def:2)" << std::endl; 15 | waitForReload(5000); 16 | 17 | auto afterReload = multipleDefinitionsGetValue(); 18 | REQUIRE(afterReload == 88); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /tests/src/good/StaticFunctionLocalVariableAddress_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/StaticFunctionLocalVariableAddress.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Relocation of function local static variable, comparing address", "[variable]") 10 | { 11 | auto beforeReload = getStaticFunctionLocalVariableAddress(); 12 | 13 | std::cout << "JET_TEST: disable(st_func_loc_var_addr:1)" << std::endl; 14 | waitForReload(); 15 | 16 | auto afterReload = getStaticFunctionLocalVariableAddress(); 17 | REQUIRE(beforeReload == afterReload); 18 | } 19 | -------------------------------------------------------------------------------- /tests/src/good/LambdaFunction_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/LambdaFunction.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Reload of lambda function with no captured data", "[function]") 10 | { 11 | int v1 = 23; 12 | int v2 = 45; 13 | int sum = v1 + v2; 14 | int mul = v1 * v2; 15 | auto lambda = createLambdaFunction(); 16 | 17 | REQUIRE(lambda(v1, v2) == sum); 18 | 19 | std::cout << "JET_TEST: disable(lamb_nocapt:1); enable(lamb_nocapt:2)" << std::endl; 20 | waitForReload(); 21 | 22 | REQUIRE(lambda(v1, v2) == mul); 23 | } 24 | -------------------------------------------------------------------------------- /tests/src/good/StaticVariable_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/StaticVariable.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Relocation of static variable", "[variable]") 10 | { 11 | auto beforeReload = getNext(); 12 | REQUIRE(beforeReload.first == 0); 13 | REQUIRE(beforeReload.second == 10); 14 | 15 | std::cout << "JET_TEST: disable(rel_stat_var:1); enable(rel_stat_var:2)" << std::endl; 16 | waitForReload(); 17 | 18 | auto afterReload = getNext(); 19 | REQUIRE(afterReload.first == 1); 20 | REQUIRE(afterReload.second == 11); 21 | } 22 | -------------------------------------------------------------------------------- /src/jet/live/IDependenciesHandler.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | #include "jet/live/DataTypes.hpp" 6 | 7 | namespace jet 8 | { 9 | struct LiveContext; 10 | /** 11 | * Dependencies handler interface. 12 | */ 13 | class IDependenciesHandler 14 | { 15 | public: 16 | virtual ~IDependenciesHandler() {} 17 | 18 | /** 19 | * Finds dependencies of given cu (files which cu depends on). 20 | * \return A set of dependencies file paths. 21 | */ 22 | virtual std::unordered_set getDependencies(const LiveContext* context, CompilationUnit& cu) = 0; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /tests/src/good/ClassInstanceMethod_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/ClassInstanceMethod.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Reload of class instance method", "[function]") 10 | { 11 | int v1 = 23; 12 | int v2 = 45; 13 | int sum = v1 + v2; 14 | int mul = v1 * v2; 15 | ClassInstanceMethod ins; 16 | 17 | REQUIRE(ins.computeResult(v1, v2) == sum); 18 | 19 | std::cout << "JET_TEST: disable(cls_ins_meth:1); enable(cls_ins_meth:2)" << std::endl; 20 | waitForReload(); 21 | 22 | REQUIRE(ins.computeResult(v1, v2) == mul); 23 | } 24 | -------------------------------------------------------------------------------- /libs/utils/utils.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #if defined(__clang__) 5 | # pragma clang diagnostic push 6 | # pragma clang diagnostic ignored "-Wsign-conversion" 7 | #elif defined(__GNUC__) 8 | # pragma GCC diagnostic push 9 | # pragma GCC diagnostic ignored "-Wsign-conversion" 10 | #endif 11 | 12 | #define ITLIB_SMALL_VECTOR_ERROR_HANDLING ITLIB_SMALL_VECTOR_ERROR_HANDLING_NONE 13 | #include 14 | #include "small_vector/small_vector.hpp" 15 | 16 | #if defined(__clang__) 17 | # pragma clang diagnostic pop 18 | #elif defined(__GNUC__) 19 | # pragma GCC diagnostic pop 20 | #endif 21 | 22 | namespace jet 23 | { 24 | using namespace itlib; 25 | } 26 | -------------------------------------------------------------------------------- /tests/src/good/GlobalVariable_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/GlobalVariable.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Relocation of global variable", "[variable]") 10 | { 11 | auto beforeReload = getNextGlobal1(); 12 | REQUIRE(beforeReload.first == 0); 13 | REQUIRE(beforeReload.second == 10); 14 | 15 | std::cout << "JET_TEST: disable(glob_var:1); enable(glob_var:2)" << std::endl; 16 | waitForReload(); 17 | 18 | auto afterReload = getNextGlobal1(); 19 | REQUIRE(afterReload.first == 1); 20 | REQUIRE(afterReload.second == 11); 21 | } 22 | -------------------------------------------------------------------------------- /libs/dobby/source/core/codegen/codegen-ia32.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_IA32) 3 | 4 | #include "core/codegen/codegen-ia32.h" 5 | 6 | namespace zz { 7 | namespace x86 { 8 | 9 | void CodeGen::JmpNear(uint32_t address) { 10 | TurboAssembler *turbo_assembler_ = reinterpret_cast(this->assembler_); 11 | #define _ turbo_assembler_-> 12 | #define __ turbo_assembler_->code_buffer()-> 13 | uint32_t currIP = turbo_assembler_->CurrentIP() + 5; 14 | int32_t offset = (int32_t)(address - currIP); 15 | 16 | __ Emit(0xe9); 17 | __ Emit(offset); 18 | } 19 | 20 | } // namespace x86 21 | } // namespace zz 22 | 23 | #endif -------------------------------------------------------------------------------- /libs/efsw/src/efsw/DirectorySnapshotDiff.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace efsw { 4 | 5 | void DirectorySnapshotDiff::clear() { 6 | FilesCreated.clear(); 7 | FilesModified.clear(); 8 | FilesMoved.clear(); 9 | FilesDeleted.clear(); 10 | DirsCreated.clear(); 11 | DirsModified.clear(); 12 | DirsMoved.clear(); 13 | DirsDeleted.clear(); 14 | } 15 | 16 | bool DirectorySnapshotDiff::changed() { 17 | return !FilesCreated.empty() || !FilesModified.empty() || !FilesMoved.empty() || 18 | !FilesDeleted.empty() || !DirsCreated.empty() || !DirsModified.empty() || 19 | !DirsMoved.empty() || !DirsDeleted.empty(); 20 | } 21 | 22 | } // namespace efsw 23 | -------------------------------------------------------------------------------- /tests/src/utility/LambdaFunctionWithCapturesGoodCase.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "LambdaFunctionWithCapturesGoodCase.hpp" 3 | 4 | std::function createLambdaFunctionWithCapturesGoodCase() 5 | { 6 | int dummyInt1 = 45; 7 | int dummyInt2 = -45; 8 | auto dummyLambda = [dummyInt1, dummyInt2] (int v1, int v2) { 9 | return v1 + v2 - 123 + dummyInt1 - dummyInt2; 10 | }; 11 | volatile int res = dummyLambda(55, 44); 12 | 13 | return [dummyInt1, dummyInt2] (int v1, int v2) { 14 | return v1 + v2 + dummyInt1 + dummyInt2; // 15 | // return v1 * v2 + dummyInt1 + dummyInt2; // 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /tests/src/good/LambdaFunctionWithCaptures_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/LambdaFunctionWithCaptures.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Reload of lambda function with captured data", "[function]") 10 | { 11 | int v1 = 23; 12 | int v2 = 45; 13 | int sum = v1 + v2; 14 | int mul = v1 * v2; 15 | auto lambda = createLambdaFunctionWithCaptures(); 16 | 17 | REQUIRE(lambda(v1, v2) == sum); 18 | 19 | std::cout << "JET_TEST: disable(lamb_capt:1); enable(lamb_capt:2)" << std::endl; 20 | waitForReload(); 21 | 22 | REQUIRE(lambda(v1, v2) == mul); 23 | } 24 | -------------------------------------------------------------------------------- /tests/src/good/StaticInternalVariable_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/StaticInternalVariable.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Relocation of static internal variable", "[variable]") 10 | { 11 | auto beforeReload = getNext1(); 12 | REQUIRE(beforeReload.first == 0); 13 | REQUIRE(beforeReload.second == 0); 14 | 15 | std::cout << "JET_TEST: disable(st_intern_var:1); enable(st_intern_var:2)" << std::endl; 16 | waitForReload(); 17 | 18 | auto afterReload = getNext1(); 19 | REQUIRE(afterReload.first == 1); 20 | REQUIRE(afterReload.second == 1); 21 | } 22 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/WatcherGeneric.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_WATCHERGENERIC_HPP 2 | #define EFSW_WATCHERGENERIC_HPP 3 | 4 | #include 5 | 6 | namespace efsw { 7 | 8 | class DirWatcherGeneric; 9 | 10 | class WatcherGeneric : public Watcher { 11 | public: 12 | FileWatcherImpl* WatcherImpl; 13 | DirWatcherGeneric* DirWatch; 14 | 15 | WatcherGeneric( WatchID id, const std::string& directory, FileWatchListener* fwl, 16 | FileWatcherImpl* fw, bool recursive ); 17 | 18 | ~WatcherGeneric(); 19 | 20 | void watch() override; 21 | 22 | void watchDir( std::string dir ); 23 | 24 | bool pathInWatches( std::string path ); 25 | }; 26 | 27 | } // namespace efsw 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /tests/src/good/ExternGlobalVariableAddress_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/ExternGlobalVariableAddress.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | int externGlobalVariableCheckingAddress = 10; 10 | 11 | TEST_CASE("Relocation of extern global variable, comparing address", "[variable]") 12 | { 13 | auto oldVariableAddress = getExternGlobalVariableAddress(); 14 | 15 | std::cout << "JET_TEST: disable(extern_glob_var_addr:1)" << std::endl; 16 | waitForReload(); 17 | 18 | auto newVariableAddress = getExternGlobalVariableAddress(); 19 | REQUIRE(oldVariableAddress == newVariableAddress); 20 | } 21 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/Atomic.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_ATOMIC_BOOL_HPP 2 | #define EFSW_ATOMIC_BOOL_HPP 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace efsw { 9 | 10 | template class Atomic { 11 | public: 12 | explicit Atomic( T set = false ) : set_( set ) {} 13 | 14 | Atomic& operator=( T set ) { 15 | set_.store( set, std::memory_order_release ); 16 | return *this; 17 | } 18 | 19 | explicit operator T() const { 20 | return set_.load( std::memory_order_acquire ); 21 | } 22 | 23 | T load() const { 24 | return set_.load( std::memory_order_acquire ); 25 | } 26 | 27 | private: 28 | std::atomic set_; 29 | }; 30 | 31 | } // namespace efsw 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /libs/dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/common.h" 4 | 5 | #include "MemoryAllocator/AssemblerCodeBuilder.h" 6 | 7 | #include "x86_insn_decode/x86_insn_decode.h" 8 | 9 | #include "X86DecodeKit.h" 10 | 11 | int GenRelocateCodeFixed(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch); 12 | 13 | void GenRelocateCodeX86Shared(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch); 14 | 15 | int GenRelocateSingleX86Insn(addr_t curr_orig_ip, addr_t curr_relo_ip, uint8_t *buffer_cursor, AssemblerBase *assembler, 16 | CodeMemBuffer *code_buffer, x86_insn_decode_t &insn, int8_t mode); -------------------------------------------------------------------------------- /src/jet/live/DefaultSymbolsFilter.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "jet/live/ISymbolsFilter.hpp" 5 | 6 | namespace jet 7 | { 8 | /** 9 | * Default implementation of symbols filter. 10 | */ 11 | class DefaultSymbolsFilter : public ISymbolsFilter 12 | { 13 | public: 14 | bool shouldReloadMachoSymbol(const MachoContext& context, const MachoSymbol& symbol) override; 15 | bool shouldReloadElfSymbol(const ElfContext& context, const ElfSymbol& symbol) override; 16 | bool shouldTransferMachoSymbol(const MachoContext& context, const MachoSymbol& symbol) override; 17 | bool shouldTransferElfSymbol(const ElfContext& context, const ElfSymbol& symbol) override; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /libs/dobby/source/PlatformUtil/ProcessRuntime.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryAllocator/MemoryAllocator.h" 4 | #include "PlatformUnifiedInterface/platform.h" 5 | 6 | struct RuntimeModule { 7 | void *base; 8 | char path[1024]; 9 | }; 10 | 11 | #define MEM_PERM_R 0x1 12 | #define MEM_PERM_W 0x2 13 | #define MEM_PERM_X 0x4 14 | struct MemRegion : MemRange { 15 | int perm; 16 | 17 | MemRegion(addr_t addr, size_t size, int perm) : MemRange(addr, size), perm(perm) { 18 | } 19 | }; 20 | 21 | class ProcessRuntime { 22 | public: 23 | static const stl::vector &getMemoryLayout(); 24 | 25 | static const stl::vector &getModuleMap(); 26 | 27 | static RuntimeModule getModule(const char *name); 28 | }; -------------------------------------------------------------------------------- /libs/dobby/source/core/codegen/codegen-arm64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "core/codegen/codegen.h" 4 | #include "core/assembler/assembler.h" 5 | #include "core/assembler/assembler-arm64.h" 6 | 7 | namespace zz { 8 | namespace arm64 { 9 | 10 | struct CodeGen : CodeGenBase { 11 | CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { 12 | } 13 | void LiteralLdrBranch(uint64_t address) { 14 | auto turbo_assembler_ = reinterpret_cast(this->assembler_); 15 | #undef _ 16 | #define _ turbo_assembler_-> // NOLINT: clang-tidy 17 | 18 | auto label = _ createDataLabel(address); 19 | _ Ldr(TMP_REG_0, label); 20 | _ br(TMP_REG_0); 21 | } 22 | }; 23 | 24 | } // namespace arm64 25 | } // namespace zz -------------------------------------------------------------------------------- /tests/src/good/ClassVirtualMethod_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/ClassVirtualMethod.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | #include 9 | 10 | TEST_CASE("Reload of class instance virtual method", "[function]") 11 | { 12 | int v1 = 23; 13 | int v2 = 45; 14 | int sum = v1 + v2; 15 | int mul = v1 * v2; 16 | auto ins = jet::make_unique(); 17 | 18 | REQUIRE(ins->computeResult(v1, v2) == sum); 19 | 20 | std::cout << "JET_TEST: disable(cls_virt_meth:1); enable(cls_virt_meth:2)" << std::endl; 21 | waitForReload(); 22 | 23 | REQUIRE(ins->computeResult(v1, v2) == mul); 24 | } 25 | -------------------------------------------------------------------------------- /tests/src/good/ExternGlobalVariable_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/ExternGlobalVariable.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | int someExternGlobalVariable = 10; 10 | 11 | TEST_CASE("Relocation of extern global variable", "[variable]") 12 | { 13 | auto beforeReload = getNextGlobal(); 14 | REQUIRE(beforeReload.first == 0); 15 | REQUIRE(beforeReload.second == 10); 16 | 17 | std::cout << "JET_TEST: disable(extern_glob_var:1); enable(extern_glob_var:2)" << std::endl; 18 | waitForReload(); 19 | 20 | auto afterReload = getNextGlobal(); 21 | REQUIRE(afterReload.first == 1); 22 | REQUIRE(afterReload.second == 11); 23 | } 24 | -------------------------------------------------------------------------------- /src/jet/live/events/LogEvent.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "jet/live/IEvent.hpp" 5 | #include "jet/live/ILiveListener.hpp" 6 | 7 | namespace jet 8 | { 9 | class LogEvent : public IEvent 10 | { 11 | public: 12 | LogEvent(LogSeverity severity, std::string&& message) 13 | : IEvent(EventType::kLog) 14 | , m_severity(severity) 15 | , m_message(std::move(message)) 16 | { 17 | } 18 | 19 | LogSeverity getSeverity() const { return m_severity; } 20 | const std::string& getMessage() const { return m_message; } 21 | int getPriority() const override { return 0; } 22 | 23 | private: 24 | LogSeverity m_severity; 25 | std::string m_message; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /tests/src/good/LambdaFunctionWithCapturesGoodCase_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/LambdaFunctionWithCapturesGoodCase.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Reload of lambda function with captured data and another lamda in this file, good case", "[function]") 10 | { 11 | int v1 = 23; 12 | int v2 = 45; 13 | int sum = v1 + v2; 14 | int mul = v1 * v2; 15 | auto lambda = createLambdaFunctionWithCapturesGoodCase(); 16 | 17 | REQUIRE(lambda(v1, v2) == sum); 18 | 19 | std::cout << "JET_TEST: disable(lamb_capt_good:1); enable(lamb_capt_good:2)" << std::endl; 20 | waitForReload(); 21 | 22 | REQUIRE(lambda(v1, v2) == mul); 23 | } 24 | -------------------------------------------------------------------------------- /tests/src/good/MacosFunctionOutOfScope_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/MacosFunctionOutOfScope.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Function address is out of readable memory", "[function]") 10 | { 11 | REQUIRE(getStdStringValue() == "some string"); 12 | 13 | std::cout << "JET_TEST: disable(fun_out_of_scope:1); enable(fun_out_of_scope:2)" << std::endl; 14 | waitForReload(); 15 | 16 | REQUIRE(getStdStringValue() == "some another string"); 17 | 18 | std::cout << "JET_TEST: disable(fun_out_of_scope:2); enable(fun_out_of_scope:1)" << std::endl; 19 | waitForReload(); 20 | 21 | REQUIRE(getStdStringValue() == "some string"); 22 | } 23 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | typedef uintptr_t addr_t; 5 | 6 | #include "dobby.h" 7 | 8 | void supervisor_call_monitor_init(); 9 | 10 | void supervisor_call_monitor_register_handler(DBICallTy handler); 11 | 12 | void supervisor_call_monitor_register_svc(addr_t svc_addr); 13 | 14 | void supervisor_call_monitor_register_image(void *header); 15 | 16 | void supervisor_call_monitor_register_main_app(); 17 | 18 | void supervisor_call_monitor_register_system_kernel(); 19 | 20 | void supervisor_call_monitor_register_syscall_call_log_handler(); 21 | 22 | void supervisor_call_monitor_register_mach_syscall_call_log_handler(); 23 | 24 | void supervisor_call_monitor_register_sensitive_api_handler(); -------------------------------------------------------------------------------- /libs/efsw/src/efsw/platform/posix/FileSystemImpl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_FILESYSTEMIMPLPOSIX_HPP 2 | #define EFSW_FILESYSTEMIMPLPOSIX_HPP 3 | 4 | #include 5 | #include 6 | 7 | #if defined( EFSW_PLATFORM_POSIX ) 8 | 9 | namespace efsw { namespace Platform { 10 | 11 | class FileSystem { 12 | public: 13 | static FileInfoMap filesInfoFromPath( const std::string& path ); 14 | 15 | static char getOSSlash(); 16 | 17 | static bool isDirectory( const std::string& path ); 18 | 19 | static bool isRemoteFS( const std::string& directory ); 20 | 21 | static bool changeWorkingDirectory( const std::string& path ); 22 | 23 | static std::string getCurrentWorkingDirectory(); 24 | }; 25 | 26 | }} // namespace efsw::Platform 27 | 28 | #endif 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /libs/dobby/source/core/assembler/assembler-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_ASSEMBLER_ARCH_H 2 | #define CORE_ASSEMBLER_ARCH_H 3 | 4 | #include "src/assembler.h" 5 | 6 | #if 0 7 | #if TARGET_ARCH_IA32 8 | #include "src/ia32/assembler-ia32.h" 9 | #elif TARGET_ARCH_X64 10 | #include "src/x64/assembler-x64.h" 11 | #elif TARGET_ARCH_ARM64 12 | #include "src/arm64/assembler-arm64.h" 13 | #elif TARGET_ARCH_ARM 14 | #include "src/arm/assembler-arm.h" 15 | #elif TARGET_ARCH_PPC 16 | #include "src/ppc/assembler-ppc.h" 17 | #elif TARGET_ARCH_MIPS 18 | #include "src/mips/assembler-mips.h" 19 | #elif TARGET_ARCH_MIPS64 20 | #include "src/mips64/assembler-mips64.h" 21 | #elif TARGET_ARCH_S390 22 | #include "src/s390/assembler-s390.h" 23 | #else 24 | #error Unknown architecture. 25 | #endif 26 | #endif 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/jet/live/BuildConfig.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "BuildConfig.hpp" 3 | 4 | namespace jet 5 | { 6 | const std::string& getCmakeGenerator() 7 | { 8 | #ifdef JET_LIVE_CMAKE_GENERATOR 9 | static const std::string cmakeGenerator = JET_LIVE_CMAKE_GENERATOR; 10 | #else 11 | #error JET_LIVE_CMAKE_GENERATOR is not defined 12 | static const std::string cmakeGenerator; 13 | #endif 14 | return cmakeGenerator; 15 | } 16 | 17 | const std::string& getCmakeBuildDirectory() 18 | { 19 | #ifdef JET_LIVE_CMAKE_BUILD_DIR 20 | static const std::string cmakeBuildDir = JET_LIVE_CMAKE_BUILD_DIR; 21 | #else 22 | #error JET_LIVE_CMAKE_BUILD_DIR is not defined 23 | static const std::string cmakeBuildDir; 24 | #endif 25 | return cmakeBuildDir; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/src/good/OneFrameCompileReload_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "utility/OneFrameCompileReload.hpp" 7 | #include "Globals.hpp" 8 | #include "WaitForReload.hpp" 9 | 10 | TEST_CASE("Checking crash if compilation and reload request appear in the same frame", "[common]") 11 | { 12 | auto beforeReload = ofcrGetNext(); 13 | REQUIRE(beforeReload == 4); 14 | 15 | std::cout << "JET_TEST: disable(ofcr_crash:1)" << std::endl; 16 | std::this_thread::sleep_for(std::chrono::milliseconds{50}); 17 | g_live->tryReload(); 18 | std::this_thread::sleep_for(std::chrono::milliseconds{50}); 19 | waitForReload(); 20 | 21 | auto afterReload = ofcrGetNext(); 22 | REQUIRE(afterReload == 8); 23 | } 24 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/SymbolResolver/pe/dobby_symbol_resolver.cc: -------------------------------------------------------------------------------- 1 | #include "SymbolResolver/dobby_symbol_resolver.h" 2 | #include "dobby/common.h" 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "PlatformUtil/ProcessRuntime.h" 10 | 11 | #include 12 | 13 | #undef LOG_TAG 14 | #define LOG_TAG "DobbySymbolResolver" 15 | 16 | PUBLIC void *DobbySymbolResolver(const char *image_name, const char *symbol_name_pattern) { 17 | void *result = NULL; 18 | 19 | HMODULE hMod = LoadLibraryExA(image_name, NULL, DONT_RESOLVE_DLL_REFERENCES); 20 | result = GetProcAddress(hMod, symbol_name_pattern); 21 | if (result) 22 | return result; 23 | 24 | //result = resolve_elf_internal_symbol(image_name, symbol_name_pattern); 25 | return result; 26 | } -------------------------------------------------------------------------------- /tests/src/good/LostModification_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "utility/LostModification.hpp" 5 | #include "WaitForReload.hpp" 6 | 7 | TEST_CASE("Lost modifications when adding new file", "[common]") 8 | { 9 | auto beforeReload = lostModificationGetValue(); 10 | REQUIRE(beforeReload == 12); 11 | 12 | std::cout << "JET_TEST: disable(lost_mod:1); enable(lost_mod:2)" << std::endl; 13 | waitForReload(); // Load time error 14 | auto afterReload1 = lostModificationGetValue(); 15 | REQUIRE(afterReload1 == 12); 16 | 17 | std::cout << "JET_TEST: enable(lost_mod:3)" << std::endl; 18 | waitForReload(5000); // 2 files should be reloaded 19 | auto afterReload2 = lostModificationGetValue(); 20 | REQUIRE(afterReload2 == 34); 21 | } 22 | -------------------------------------------------------------------------------- /tests/src/utility/LambdaFunctionWithCapturesBadCase.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "LambdaFunctionWithCapturesBadCase.hpp" 3 | 4 | std::function createLambdaFunctionWithCapturesBadCase() 5 | { 6 | int dummyInt1 = 45; 7 | int dummyInt2 = -45; 8 | // auto dummyLambda = [dummyInt1, dummyInt2] (int v1, int v2) { // 9 | // return v1 + v2 - 123 + dummyInt1 - dummyInt2; // 10 | // }; // 11 | // volatile int res = dummyLambda(55, 44); // 12 | 13 | return [dummyInt1, dummyInt2] (int v1, int v2) { 14 | return v1 + v2 + dummyInt1 + dummyInt2; // 15 | // return v1 * v2 + dummyInt1 + dummyInt2; // 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /libs/dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.cpp: -------------------------------------------------------------------------------- 1 | #include "MultiThreadSupport/ThreadSupport.h" 2 | 3 | using namespace zz; 4 | 5 | OSThread::LocalStorageKey ThreadSupport::thread_callstack_key_ = 0; 6 | 7 | // Get current CallStack 8 | CallStack *ThreadSupport::CurrentThreadCallStack() { 9 | 10 | // TODO: __attribute__((destructor)) is better ? 11 | if (!thread_callstack_key_) { 12 | thread_callstack_key_ = OSThread::CreateThreadLocalKey(); 13 | } 14 | 15 | if (OSThread::HasThreadLocal(thread_callstack_key_)) { 16 | return static_cast(OSThread::GetThreadLocal(thread_callstack_key_)); 17 | } else { 18 | CallStack *callstack = new CallStack(); 19 | OSThread::SetThreadLocal(thread_callstack_key_, callstack); 20 | return callstack; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/platform/win/FileSystemImpl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_FILESYSTEMIMPLWIN_HPP 2 | #define EFSW_FILESYSTEMIMPLWIN_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 9 | 10 | namespace efsw { namespace Platform { 11 | 12 | class FileSystem { 13 | public: 14 | static FileInfoMap filesInfoFromPath( const std::string& path ); 15 | 16 | static char getOSSlash(); 17 | 18 | static bool isDirectory( const std::string& path ); 19 | 20 | static bool isRemoteFS( const std::string& directory ); 21 | 22 | static bool changeWorkingDirectory( const std::string& path ); 23 | 24 | static std::string getCurrentWorkingDirectory(); 25 | }; 26 | 27 | }} // namespace efsw::Platform 28 | 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /libs/dobby/source/InterceptRouting/InstrumentRouting/instrument_routing_handler.cpp: -------------------------------------------------------------------------------- 1 | #include "dobby/dobby_internal.h" 2 | #include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" 3 | #include "InterceptRouting/InstrumentRouting.h" 4 | #include "logging/logging.h" 5 | 6 | void instrument_forward_handler(Interceptor::Entry *entry, DobbyRegisterContext *ctx); 7 | 8 | extern "C" void instrument_routing_dispatch(Interceptor::Entry *entry, DobbyRegisterContext *ctx) { 9 | // __FUNC_CALL_TRACE__(); 10 | auto instrument_callback_fn = (dobby_instrument_callback_t)entry->pre_handler; 11 | if (instrument_callback_fn) { 12 | instrument_callback_fn((void *)entry->addr, ctx); 13 | } 14 | 15 | // set TMP_REG_0 to next hop 16 | set_routing_bridge_next_hop(ctx, (void *)entry->relocated.addr()); 17 | } 18 | -------------------------------------------------------------------------------- /libs/dobby/source/InterceptRouting/RoutingPlugin.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/common.h" 4 | 5 | struct InterceptRouting; 6 | struct RoutingPluginInterface { 7 | char name_[256]; 8 | 9 | virtual bool Prepare(InterceptRouting *routing) = 0; 10 | 11 | virtual bool Active(InterceptRouting *routing) = 0; 12 | 13 | virtual bool GenerateTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) = 0; 14 | }; 15 | 16 | struct RoutingPluginManager { 17 | static void registerPlugin(const char *name, RoutingPluginInterface *plugin) { 18 | DEBUG_LOG("register %s plugin", name); 19 | RoutingPluginManager::plugins.push_back(plugin); 20 | } 21 | 22 | inline static stl::vector plugins; 23 | 24 | inline static RoutingPluginInterface *near_branch_trampoline; 25 | }; 26 | -------------------------------------------------------------------------------- /libs/dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-windows.cc: -------------------------------------------------------------------------------- 1 | #include "dobby/dobby_internal.h" 2 | 3 | #include 4 | 5 | using namespace zz; 6 | 7 | PUBLIC int DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { 8 | DWORD oldProtect; 9 | int page_size; 10 | 11 | // Get page size 12 | SYSTEM_INFO si; 13 | GetSystemInfo(&si); 14 | page_size = si.dwPageSize; 15 | 16 | void *addressPageAlign = (void *)ALIGN(address, page_size); 17 | 18 | if (!VirtualProtect(addressPageAlign, page_size, PAGE_EXECUTE_READWRITE, &oldProtect)) 19 | return kMemoryOperationError; 20 | 21 | memcpy(address, buffer, buffer_size); 22 | 23 | if (!VirtualProtect(addressPageAlign, page_size, oldProtect, &oldProtect)) 24 | return kMemoryOperationError; 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /tests/src/good/NewCompilationUnit_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/NewCompilationUnit.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Adding new compilation unit in runtime", "[common]") 10 | { 11 | int v1 = 23; 12 | int v2 = 45; 13 | int sum = v1 + v2; 14 | int mul = v1 * v2; 15 | 16 | REQUIRE(newCompilationUnitComputeResult(v1, v2) == sum); 17 | 18 | std::cout << "JET_TEST: disable(new_cu:1); enable(new_cu:2)" << std::endl; 19 | waitForReload(5000); 20 | REQUIRE(newCompilationUnitComputeResult(v1, v2) == mul); 21 | 22 | std::cout << "JET_TEST: disable(new_cu:3); enable(new_cu:4)" << std::endl; 23 | waitForReload(); 24 | REQUIRE(newCompilationUnitComputeResult(v1, v2) == mul + sum); 25 | } 26 | -------------------------------------------------------------------------------- /libs/dobby/source/Backend/UserMode/Thread/PlatformThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/common.h" 4 | 5 | namespace zz { 6 | 7 | class OSThread { 8 | public: 9 | typedef int LocalStorageKey; 10 | 11 | static int GetCurrentProcessId(); 12 | 13 | static int GetCurrentThreadId(); 14 | 15 | static LocalStorageKey CreateThreadLocalKey(); 16 | 17 | static void DeleteThreadLocalKey(LocalStorageKey key); 18 | 19 | static void *GetThreadLocal(LocalStorageKey key); 20 | 21 | static int GetThreadLocalInt(LocalStorageKey key); 22 | 23 | static void SetThreadLocal(LocalStorageKey key, void *value); 24 | 25 | static void SetThreadLocalInt(LocalStorageKey key, int value); 26 | 27 | static bool HasThreadLocal(LocalStorageKey key); 28 | 29 | static void *GetExistingThreadLocal(LocalStorageKey key); 30 | }; 31 | 32 | } // namespace zz -------------------------------------------------------------------------------- /libs/dobby/scripts/setup_macos_cross_compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -x 4 | set -e 5 | 6 | mkdir -p ~/opt 7 | 8 | cd ~/opt 9 | CMAKE_VERSION=3.25.2 10 | CMAKE_DOWNLOAD_PACKAGE=cmake-$CMAKE_VERSION-macos-universal 11 | wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/$CMAKE_DOWNLOAD_PACKAGE.tar.gz && 12 | tar -zxf $CMAKE_DOWNLOAD_PACKAGE.tar.gz >/dev/null && 13 | mv $CMAKE_DOWNLOAD_PACKAGE cmake-$CMAKE_VERSION 14 | CMAKE_HOME=~/opt/cmake-$CMAKE_VERSION 15 | 16 | cd ~/opt 17 | LLVM_VERSION=15.0.6 18 | LLVM_DOWNLOAD_PACKAGE=clang+llvm-$LLVM_VERSION-x86_64-apple-darwin 19 | wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/$LLVM_DOWNLOAD_PACKAGE.tar.xz && 20 | tar -xf $LLVM_DOWNLOAD_PACKAGE.tar.xz >/dev/null && 21 | mv $LLVM_DOWNLOAD_PACKAGE llvm-$LLVM_VERSION 22 | LLVM_HOME=~/opt/llvm-$LLVM_VERSION 23 | -------------------------------------------------------------------------------- /tests/src/good/NewHeaderDependency_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/NewHeaderDependency.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Adding new header dependency in runtime", "[common]") 10 | { 11 | int v1 = 52; 12 | int v2 = 65; 13 | int sum = v1 + v2; 14 | int mul = v1 * v2; 15 | 16 | REQUIRE(newHeaderDependencyComputeResult(v1, v2) == sum); 17 | 18 | std::cout << "JET_TEST: disable(new_header:1); enable(new_header:2)" << std::endl; 19 | waitForReload(); 20 | REQUIRE(newHeaderDependencyComputeResult(v1, v2) == mul); 21 | 22 | std::cout << "JET_TEST: disable(new_header:3); enable(new_header:4)" << std::endl; 23 | waitForReload(); 24 | REQUIRE(newHeaderDependencyComputeResult(v1, v2) == mul + sum); 25 | } 26 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/Thread.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_THREAD_HPP 2 | #define EFSW_THREAD_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace efsw { 10 | 11 | /** @brief Thread manager class */ 12 | class Thread { 13 | public: 14 | 15 | Thread(std::function fun) 16 | : mFun{std::move(fun)} 17 | { 18 | } 19 | 20 | ~Thread() 21 | { 22 | wait(); 23 | } 24 | 25 | /** Launch the thread */ 26 | void launch() 27 | { 28 | if (!mThread) 29 | mThread.reset(new std::thread{std::move(mFun)}); 30 | } 31 | 32 | /** Wait the thread until end */ 33 | void wait() 34 | { 35 | if (mThread) 36 | { 37 | mThread->join(); 38 | mThread.reset(); 39 | } 40 | } 41 | private: 42 | 43 | std::unique_ptr mThread; 44 | std::function mFun; 45 | }; 46 | 47 | } // namespace efsw 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /tests/src/utility/LambdaFunctionWithCapturesBadCase2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "LambdaFunctionWithCapturesBadCase2.hpp" 3 | 4 | std::function createLambdaFunctionWithCapturesBadCase2() 5 | { 6 | int dummyInt1 = 45; 7 | int dummyInt2 = -45; 8 | // auto dummyLambda = [dummyInt1, dummyInt2] (int v1, int v2, float v3) { // 9 | // return v1 + v2 - 123 + dummyInt1 - dummyInt2 + static_cast(v3); // 10 | // }; // 11 | // volatile int res = dummyLambda(55, 44, 33.3f); // 12 | 13 | return [dummyInt1, dummyInt2] (int v1, int v2) { 14 | return v1 + v2 + dummyInt1 + dummyInt2; // 15 | // return v1 * v2 + dummyInt1 + dummyInt2; // 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /tests/src/good/InternalLinkageFunction_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/InternalLinkageFunction.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Reload of function with internal linkage", "[function]") 10 | { 11 | int v1 = 23; 12 | int v2 = 45; 13 | int sum = v1 + v2; 14 | int mul = v1 * v2; 15 | using InternalFunctionPtrT = int (*)(int,int); 16 | auto internalFunctionPtr = reinterpret_cast(getInternalFunctionAddress()); 17 | 18 | REQUIRE(computeResult1(v1, v2) == sum); 19 | REQUIRE((*internalFunctionPtr)(v1, v2) == sum); 20 | 21 | std::cout << "JET_TEST: disable(intern_func:1); enable(intern_func:2)" << std::endl; 22 | waitForReload(); 23 | 24 | REQUIRE(computeResult1(v1, v2) == mul); 25 | REQUIRE((*internalFunctionPtr)(v1, v2) == mul); 26 | } 27 | -------------------------------------------------------------------------------- /libs/dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/dobby_internal.h" 4 | 5 | #include "Interceptor.h" 6 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 7 | 8 | inline asm_func_t closure_bridge_addr = nullptr; 9 | 10 | void closure_bridge_init(); 11 | 12 | void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address); 13 | 14 | void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address); 15 | 16 | PUBLIC extern "C" inline void common_closure_bridge_handler(DobbyRegisterContext *ctx, ClosureTrampoline *tramp) { 17 | typedef void (*routing_handler_t)(Interceptor::Entry *, DobbyRegisterContext *); 18 | auto routing_handler = (routing_handler_t)features::apple::arm64e_pac_strip_and_sign(tramp->carry_handler); 19 | routing_handler((Interceptor::Entry *)tramp->carry_data, ctx); 20 | return; 21 | } 22 | -------------------------------------------------------------------------------- /libs/dobby/source/TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/dobby_internal.h" 4 | 5 | extern "C" void instrument_routing_dispatch(Interceptor::Entry *entry, DobbyRegisterContext *ctx); 6 | 7 | struct ClosureTrampoline : Trampoline { 8 | void *carry_data; 9 | void *carry_handler; 10 | 11 | ClosureTrampoline(int type, CodeMemBlock buffer, void *carry_data, void *carry_handler) : Trampoline(type, buffer) { 12 | this->carry_data = carry_data; 13 | this->carry_handler = carry_handler; 14 | } 15 | }; 16 | 17 | ClosureTrampoline *GenerateClosureTrampoline(void *carry_data, void *carry_handler); 18 | 19 | inline ClosureTrampoline *GenerateInstrumentClosureTrampoline(Interceptor::Entry *entry) { 20 | auto handler = (void *)instrument_routing_dispatch; 21 | features::apple::arm64e_pac_strip(handler); 22 | return GenerateClosureTrampoline(entry, handler); 23 | } -------------------------------------------------------------------------------- /libs/dobby/source/core/codegen/codegen-x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "core/codegen/codegen.h" 4 | #include "core/assembler/assembler.h" 5 | #include "core/assembler/assembler-x64.h" 6 | 7 | namespace zz { 8 | namespace x64 { 9 | 10 | struct CodeGen : CodeGenBase { 11 | CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { 12 | } 13 | 14 | void JmpNearIndirect(addr_t forward_stub_addr) { 15 | auto turbo_assembler_ = reinterpret_cast(this->assembler_); 16 | #define _ turbo_assembler_-> 17 | #define __ turbo_assembler_->code_buffer_. 18 | uint64_t currIP = turbo_assembler_->CurrentIP() + 6; 19 | int32_t offset = (int32_t)(forward_stub_addr - currIP); 20 | 21 | // jmp *(rip + disp32) 22 | __ Emit(0xff); 23 | __ Emit(0x25); // ModR/M: 00 100 101 24 | __ Emit(offset); 25 | } 26 | }; 27 | 28 | } // namespace x64 29 | } // namespace zz -------------------------------------------------------------------------------- /libs/efsw/src/efsw/DirectorySnapshotDiff.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_DIRECTORYSNAPSHOTDIFF_HPP 2 | #define EFSW_DIRECTORYSNAPSHOTDIFF_HPP 3 | 4 | #include 5 | 6 | namespace efsw { 7 | 8 | class DirectorySnapshotDiff { 9 | public: 10 | FileInfoList FilesDeleted; 11 | FileInfoList FilesCreated; 12 | FileInfoList FilesModified; 13 | MovedList FilesMoved; 14 | FileInfoList DirsDeleted; 15 | FileInfoList DirsCreated; 16 | FileInfoList DirsModified; 17 | MovedList DirsMoved; 18 | bool DirChanged; 19 | 20 | void clear(); 21 | 22 | bool changed(); 23 | }; 24 | 25 | #define DiffIterator( FileInfoListName ) \ 26 | it = Diff.FileInfoListName.begin(); \ 27 | for ( ; it != Diff.FileInfoListName.end(); it++ ) 28 | 29 | #define DiffMovedIterator( MovedListName ) \ 30 | mit = Diff.MovedListName.begin(); \ 31 | for ( ; mit != Diff.MovedListName.end(); mit++ ) 32 | 33 | } // namespace efsw 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /example/src/SimpleCommandInterpreter.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "SimpleCommandInterpreter.hpp" 3 | 4 | SimpleCommandInterpreter::SimpleCommandInterpreter(int currentCommandsCounter) 5 | : m_currentCommandsCounter(currentCommandsCounter) 6 | { 7 | } 8 | 9 | int SimpleCommandInterpreter::getCurrentCommandsCounter() const 10 | { 11 | return m_currentCommandsCounter; 12 | } 13 | 14 | std::string SimpleCommandInterpreter::runCommand(const std::string& command) 15 | { 16 | auto totalCommands = std::to_string(++m_currentCommandsCounter); 17 | std::string result; 18 | 19 | // Implement your commands here 20 | if (command == "Hello") { 21 | result = "Hi there!"; 22 | } else { 23 | result = "Sorry, I don't know what '" + command 24 | + "' means. Fix it in runtime in 'SimpleCommandInterpreter::runCommand'"; 25 | } 26 | 27 | return "ttl: " + totalCommands + " > " + result; 28 | } 29 | -------------------------------------------------------------------------------- /src/jet/live/ILiveListener.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | namespace jet 7 | { 8 | enum class LogSeverity 9 | { 10 | kDebug, 11 | kInfo, 12 | kWarning, 13 | kError 14 | }; 15 | 16 | /** 17 | * Base class for custom delegate. 18 | */ 19 | class ILiveListener 20 | { 21 | public: 22 | virtual ~ILiveListener() {} 23 | 24 | /** 25 | * Called on each log message from the library. 26 | */ 27 | virtual void onLog(LogSeverity, const std::string&) {} 28 | 29 | /** 30 | * Called right before shared library with new code is loaded into the process address space. 31 | */ 32 | virtual void onCodePreLoad() {} 33 | 34 | /** 35 | * Called right after all functions are hooked and state is transferred. 36 | */ 37 | virtual void onCodePostLoad() {} 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /tests/src/good/CommonSection_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | extern "C" { 6 | #include "utility/CommonSection.h" 7 | } 8 | #include "Globals.hpp" 9 | #include "WaitForReload.hpp" 10 | 11 | TEST_CASE("Relocation of global variable from *COM* (__DATA.__common) section", "[variable]") 12 | { 13 | auto beforeReload = getCommonSectionVar(); 14 | auto beforeReloadAddress = getCommonSectionVarAddress(); 15 | REQUIRE(beforeReload == 10); 16 | 17 | std::cout << "JET_TEST: enable(common_sect:1)" << std::endl; 18 | waitForReload(); 19 | 20 | auto afterReload = getCommonSectionVar(); 21 | auto afterReloadAddress = getCommonSectionVarAddress(); 22 | REQUIRE(afterReload == 11); 23 | REQUIRE(beforeReloadAddress == afterReloadAddress); 24 | 25 | *reinterpret_cast(afterReloadAddress) = 20; 26 | auto afterModify = getCommonSectionVar(); 27 | REQUIRE(afterModify == 20); 28 | } 29 | -------------------------------------------------------------------------------- /tests/src/good/ReloadAfterFailedCompilation_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utility/ReloadAfterFailedCompilation1.hpp" 4 | #include "utility/ReloadAfterFailedCompilation2.hpp" 5 | #include "WaitForReload.hpp" 6 | 7 | TEST_CASE("Reload after compilation error", "[common]") 8 | { 9 | auto beforeReload1 = rafcGetValue1(); 10 | auto beforeReload2 = rafcGetValue2(); 11 | REQUIRE(beforeReload1 == 15); 12 | REQUIRE(beforeReload2 == 56); 13 | 14 | std::cout << "JET_TEST: disable(rafc:1); enable(rafc:2)" << std::endl; 15 | waitForReload(); // Getting compilation error, should not reload anything 16 | REQUIRE(beforeReload1 == rafcGetValue1()); 17 | REQUIRE(beforeReload2 == rafcGetValue2()); 18 | 19 | std::cout << "JET_TEST: disable(rafc:2); enable(rafc:3)" << std::endl; 20 | waitForReload(); // Now reload everything 21 | REQUIRE(rafcGetValue1() == 19); 22 | REQUIRE(rafcGetValue2() == 69); 23 | } 24 | -------------------------------------------------------------------------------- /libs/dobby/source/Backend/UserMode/ExecMemory/substrated/mach_interface_support/substrated.defs: -------------------------------------------------------------------------------- 1 | /* 2 | * Regenerate with: 3 | * 4 | * $(xcrun --sdk macosx -f mig) \ 5 | * -isysroot $(xcrun --sdk macosx --show-sdk-path) \ 6 | * -sheader substratedserver.h \ 7 | * -server substratedserver.c \ 8 | * -header substratedclient.h \ 9 | * -user substratedclient.c \ 10 | * substrated.defs 11 | */ 12 | 13 | subsystem substrated 9000; 14 | 15 | #include 16 | #include 17 | 18 | routine substrated_mark(server 19 | : mach_port_t; 20 | task 21 | : vm_task_entry_t; 22 | source_address 23 | : mach_vm_address_t; 24 | source_size 25 | : mach_vm_size_t; 26 | inout target_address 27 | : mach_vm_address_t); 28 | -------------------------------------------------------------------------------- /libs/dobby/source/InterceptRouting/deprecated.Routing/FunctionWrapper/FunctionWrapperExport.cc: -------------------------------------------------------------------------------- 1 | #include "dobby/dobby_internal.h" 2 | 3 | #include "logging/logging.h" 4 | 5 | #include "Interceptor.h" 6 | #include "InterceptRouting/InterceptRouting.h" 7 | 8 | #include "function-wrapper.h" 9 | 10 | PUBLIC int DobbyWrap(void *function_address, PreCallTy pre_call, PostCallTy post_call) { 11 | DEBUG_LOG("Initialize 'DobbyWrap' hook at %p", function_address); 12 | 13 | Interceptor *interceptor = Interceptor::SharedInstance(); 14 | 15 | InterceptEntry *entry = new InterceptEntry(); 16 | entry->id = interceptor->entries->getCount(); 17 | entry->type = kFunctionWrapper; 18 | entry->function_address = function_address; 19 | 20 | FunctionWrapperRouting *routing = new FunctionWrapperRouting(entry); 21 | routing->DispatchRouting(); 22 | interceptor->addHookEntry(entry); 23 | routing->Commit(); 24 | 25 | DEBUG_LOG("Finalize %p", function_address); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /src/jet/live/_linux/ElfProgramInfoLoader.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "jet/live/IProgramInfoLoader.hpp" 5 | 6 | namespace jet 7 | { 8 | /** 9 | * Program info loader implementation for elf. 10 | */ 11 | class ElfProgramInfoLoader : public IProgramInfoLoader 12 | { 13 | public: 14 | std::vector getAllLoadedProgramsPaths(const LiveContext* context) const override; 15 | Symbols getProgramSymbols(const LiveContext* context, const std::string& filepath) const override; 16 | std::vector getLinkTimeRelocations(const LiveContext* context, 17 | const std::vector& objFilePaths) override; 18 | std::vector getUndefinedSymbolNames(const LiveContext* context, 19 | const std::string filepath) override; 20 | std::vector getExportedSymbolNames(const LiveContext* context, 21 | const std::string filepath) override; 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /libs/dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure_trampoline_arm64.asm: -------------------------------------------------------------------------------- 1 | #if defined(__arm64__) || defined(__aarch64__) 2 | #if defined(__WIN32__) || defined(__APPLE__) 3 | #define cdecl(s) _##s 4 | #else 5 | #define cdecl(s) s 6 | #endif 7 | 8 | #define TMP_REG_0 x17 9 | 10 | .align 4 11 | 12 | .globl cdecl(closure_trampoline_asm) 13 | 14 | cdecl(closure_trampoline_asm): 15 | // prologue: alloc stack, store lr 16 | sub sp, sp, #(2 * 8) 17 | str x30, [sp, #8] 18 | 19 | // store data at stack 20 | ldr TMP_REG_0, #closure_tramp_entry_addr 21 | str TMP_REG_0, [sp, #0] 22 | 23 | ldr TMP_REG_0, #closure_bridge_addr 24 | blr TMP_REG_0 25 | 26 | // epilogue: release stack(won't restore lr) 27 | ldr x30, [sp, #8] 28 | add sp, sp, #(2 * 8) 29 | 30 | // branch to next hop 31 | br TMP_REG_0 32 | 33 | closure_tramp_entry_addr: 34 | .quad 0 35 | 36 | closure_bridge_addr: 37 | .quad 0 38 | 39 | .globl cdecl(closure_trampoline_asm_end) 40 | cdecl(closure_trampoline_asm_end): 41 | #endif -------------------------------------------------------------------------------- /src/jet/live/_macos/MachoProgramInfoLoader.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "jet/live/IProgramInfoLoader.hpp" 5 | 6 | namespace jet 7 | { 8 | /** 9 | * Program info loader implementation for mach-o. 10 | */ 11 | class MachoProgramInfoLoader : public IProgramInfoLoader 12 | { 13 | public: 14 | std::vector getAllLoadedProgramsPaths(const LiveContext* context) const override; 15 | Symbols getProgramSymbols(const LiveContext* context, const std::string& filepath) const override; 16 | std::vector getLinkTimeRelocations(const LiveContext* context, 17 | const std::vector& objFilePaths) override; 18 | std::vector getUndefinedSymbolNames(const LiveContext* context, 19 | const std::string filepath) override; 20 | std::vector getExportedSymbolNames(const LiveContext* context, 21 | const std::string filepath) override; 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/WatcherGeneric.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace efsw { 6 | 7 | WatcherGeneric::WatcherGeneric( WatchID id, const std::string& directory, FileWatchListener* fwl, 8 | FileWatcherImpl* fw, bool recursive ) : 9 | Watcher( id, directory, fwl, recursive ), WatcherImpl( fw ), DirWatch( NULL ) { 10 | FileSystem::dirAddSlashAtEnd( Directory ); 11 | 12 | DirWatch = new DirWatcherGeneric( NULL, this, directory, recursive, false ); 13 | 14 | DirWatch->addChilds( false ); 15 | } 16 | 17 | WatcherGeneric::~WatcherGeneric() { 18 | efSAFE_DELETE( DirWatch ); 19 | } 20 | 21 | void WatcherGeneric::watch() { 22 | DirWatch->watch(); 23 | } 24 | 25 | void WatcherGeneric::watchDir( std::string dir ) { 26 | DirWatch->watchDir( dir ); 27 | } 28 | 29 | bool WatcherGeneric::pathInWatches( std::string path ) { 30 | return DirWatch->pathInWatches( path ); 31 | } 32 | 33 | } // namespace efsw 34 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/DirectorySnapshot.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_DIRECTORYSNAPSHOT_HPP 2 | #define EFSW_DIRECTORYSNAPSHOT_HPP 3 | 4 | #include 5 | 6 | namespace efsw { 7 | 8 | class DirectorySnapshot { 9 | public: 10 | FileInfo DirectoryInfo; 11 | FileInfoMap Files; 12 | 13 | void setDirectoryInfo( std::string directory ); 14 | 15 | DirectorySnapshot(); 16 | 17 | DirectorySnapshot( std::string directory ); 18 | 19 | ~DirectorySnapshot(); 20 | 21 | void init( std::string directory ); 22 | 23 | bool exists(); 24 | 25 | DirectorySnapshotDiff scan(); 26 | 27 | FileInfoMap::iterator nodeInFiles( FileInfo& fi ); 28 | 29 | void addFile( std::string path ); 30 | 31 | void removeFile( std::string path ); 32 | 33 | void moveFile( std::string oldPath, std::string newPath ); 34 | 35 | void updateFile( std::string path ); 36 | 37 | protected: 38 | void initFiles(); 39 | 40 | void deleteAll( DirectorySnapshotDiff& Diff ); 41 | }; 42 | 43 | } // namespace efsw 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /libs/dobby/README.md: -------------------------------------------------------------------------------- 1 | ## Dobby 2 | 3 | [![Contact me Telegram](https://img.shields.io/badge/Contact%20me-Telegram-blue.svg)](https://t.me/IOFramebuffer) [![Join group Telegram](https://img.shields.io/badge/Join%20group-Telegram-brightgreen.svg)](https://t.me/dobby_group) 4 | 5 | Dobby a lightweight, multi-platform, multi-architecture exploit hook framework. 6 | 7 | - Minimal and modular library 8 | - Multi-platform support(Windows/macOS/iOS/Android/Linux) 9 | - Multiple architecture support(X86, X86-64, ARM, ARM64) 10 | 11 | ## Compile 12 | 13 | [docs/compile.md](docs/compile.md) 14 | 15 | ## Download 16 | 17 | [download latest library](https://github.com/jmpews/Dobby/releases/tag/latest) 18 | 19 | ## Credits 20 | 21 | 1. [frida-gum](https://github.com/frida/frida-gum) 22 | 2. [minhook](https://github.com/TsudaKageyu/minhook) 23 | 3. [substrate](https://github.com/jevinskie/substrate). 24 | 4. [v8](https://github.com/v8/v8) 25 | 5. [dart](https://github.com/dart-lang/sdk) 26 | 6. [vixl](https://git.linaro.org/arm/vixl.git) 27 | -------------------------------------------------------------------------------- /tests/src/bad/LambdaFunctionWithCapturesBadCase2_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/LambdaFunctionWithCapturesBadCase2.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Reload of lambda function with captured data and another lambda in the file with different signature", "[function]") 10 | { 11 | int v1 = 23; 12 | int v2 = 45; 13 | int sum = v1 + v2; 14 | int mul = v1 * v2; 15 | auto lambda = createLambdaFunctionWithCapturesBadCase2(); 16 | 17 | REQUIRE(lambda(v1, v2) == sum); 18 | 19 | std::cout << "JET_TEST: disable(lamb_capt_diff_sign_bad:1); enable(lamb_capt_diff_sign_bad:2)" << std::endl; 20 | waitForReload(); 21 | 22 | // Acts different on different platform, unreliable in general 23 | #if defined(__APPLE__) && defined(__aarch64__) 24 | REQUIRE_FALSE(lambda(v1, v2) == mul); // note REQUIRE_FALSE 25 | #else 26 | REQUIRE(lambda(v1, v2) == mul); // note REQUIRE 27 | #endif 28 | } 29 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_demo.cc: -------------------------------------------------------------------------------- 1 | #include "dobby.h" 2 | 3 | #include "bionic_linker_util.h" 4 | 5 | #include "logging/logging.h" 6 | 7 | #include 8 | 9 | #define LOG_TAG "BionicLinkerUtil" 10 | 11 | __attribute__((constructor)) static void ctor() { 12 | const char *lib = NULL; 13 | 14 | #if defined(__LP64__) 15 | lib = "/system/lib64/libandroid_runtime.so"; 16 | #else 17 | lib = "/system/lib/libandroid_runtime.so"; 18 | #endif 19 | 20 | void *vm = NULL; 21 | 22 | vm = DobbySymbolResolver(lib, "_ZN7android14AndroidRuntime7mJavaVME"); 23 | INFO_LOG("DobbySymbolResolver::vm %p", vm); 24 | 25 | #if 0 26 | linker_disable_namespace_restriction(); 27 | void *handle = NULL; 28 | handle = dlopen(lib, RTLD_LAZY); 29 | vm = dlsym(handle, "_ZN7android14AndroidRuntime7mJavaVME"); 30 | #else 31 | void *handle = NULL; 32 | handle = linker_dlopen(lib, RTLD_LAZY); 33 | vm = dlsym(handle, "_ZN7android14AndroidRuntime7mJavaVME"); 34 | #endif 35 | INFO_LOG("vm %p", vm); 36 | } 37 | -------------------------------------------------------------------------------- /libs/dobby/source/TrampolineBridge/Trampoline/trampoline_x86.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_IA32) 3 | 4 | #include "dobby/dobby_internal.h" 5 | 6 | #include "core/assembler/assembler-ia32.h" 7 | #include "core/codegen/codegen-ia32.h" 8 | 9 | #include "InstructionRelocation/x86/InstructionRelocationX86.h" 10 | 11 | #include "MemoryAllocator/NearMemoryAllocator.h" 12 | #include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" 13 | 14 | using namespace zz::x86; 15 | 16 | CodeMemBuffer *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { 17 | TurboAssembler turbo_assembler_((void *)from); 18 | #define _ turbo_assembler_. 19 | 20 | CodeGen codegen(&turbo_assembler_); 21 | codegen.JmpNear((uint32_t)to); 22 | 23 | CodeMemBuffer *result = NULL; 24 | result = turbo_assembler_.code_buffer()->Copy(); 25 | return result; 26 | } 27 | 28 | CodeMemBuffer *GenerateNearTrampolineBuffer(addr_t src, addr_t dst) { 29 | DEBUG_LOG("x86 near branch trampoline enable default"); 30 | return NULL; 31 | } 32 | 33 | #endif -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | typedef uintptr_t addr_t; 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #if defined(__LP64__) 11 | typedef struct mach_header_64 mach_header_t; 12 | typedef struct segment_command_64 segment_command_t; 13 | typedef struct section_64 section_t; 14 | typedef struct nlist_64 nlist_t; 15 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 16 | #else 17 | typedef struct mach_header mach_header_t; 18 | typedef struct segment_command segment_command_t; 19 | typedef struct section section_t; 20 | typedef struct nlist nlist_t; 21 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT 22 | #endif 23 | 24 | // get macho segment by segment name 25 | segment_command_t *macho_kit_get_segment_by_name(mach_header_t *mach_header, const char *segname); 26 | 27 | // get macho section by segment name and section name 28 | section_t *macho_kit_get_section_by_name(mach_header_t *mach_header, const char *segname, const char *sectname); 29 | -------------------------------------------------------------------------------- /libs/dobby/cmake/Util.cmake: -------------------------------------------------------------------------------- 1 | # Check files list exist 2 | function(check_files_exist CHECK_FILES) 3 | foreach (file ${CHECK_FILES}) 4 | if (NOT EXISTS "${file}") 5 | message(FATAL_ERROR "${file} NOT EXISTS!") 6 | endif () 7 | endforeach () 8 | endfunction(check_files_exist CHECK_FILES) 9 | 10 | # Search suffix files 11 | function(search_suffix_files suffix INPUT_VARIABLE OUTPUT_VARIABLE) 12 | set(ResultFiles) 13 | foreach (filePath ${${INPUT_VARIABLE}}) 14 | # message(STATUS "[*] searching *.${suffix} from ${filePath}") 15 | file(GLOB files ${filePath}/*.${suffix}) 16 | set(ResultFiles ${ResultFiles} ${files}) 17 | endforeach () 18 | set(${OUTPUT_VARIABLE} ${ResultFiles} PARENT_SCOPE) 19 | endfunction() 20 | 21 | 22 | function(get_absolute_path_list input_list output_list) 23 | set(absolute_list) 24 | foreach (file ${${input_list}}) 25 | get_filename_component(absolute_file ${file} ABSOLUTE) 26 | list(APPEND absolute_list ${absolute_file}) 27 | endforeach () 28 | set(${output_list} ${absolute_list} PARENT_SCOPE) 29 | endfunction() -------------------------------------------------------------------------------- /libs/dobby/source/InterceptRouting/deprecated.Routing/FunctionWrapper/intercept_routing_handler.h: -------------------------------------------------------------------------------- 1 | #ifndef FUNCTION_WRAPPER_INTERCEPT_ROUTING_HANDLER_H 2 | #define FUNCTION_WRAPPER_INTERCEPT_ROUTING_HANDLER_H 3 | 4 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 5 | #include "Interceptor.h" 6 | #include "dobby/dobby_internal.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif //__cplusplus 11 | 12 | // Dispatch the routing befor running the origin function 13 | void prologue_routing_dispatch(DobbyRegisterContext *ctx, ClosureTrampolineEntry *entry); 14 | 15 | // Dispatch the routing before the function return . (as it's implementation by relpace `return address` in the stack 16 | // ,or LR register) 17 | void epilogue_routing_dispatch(DobbyRegisterContext *ctx, ClosureTrampolineEntry *entry); 18 | 19 | void pre_call_forward_handler(DobbyRegisterContext *ctx, InterceptEntry *entry); 20 | 21 | void post_call_forward_handler(DobbyRegisterContext *ctx, InterceptEntry *entry); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif //__cplusplus 26 | 27 | #endif -------------------------------------------------------------------------------- /tests/src/good/StaticVariableSameName_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/StaticVariableSameName1.hpp" 6 | #include "utility/StaticVariableSameName2.hpp" 7 | #include "Globals.hpp" 8 | #include "WaitForReload.hpp" 9 | 10 | TEST_CASE("Relocation of static variables with same names in different compilation units", "[variable]") 11 | { 12 | auto beforeReload1 = getNextSameName1(); 13 | auto beforeReload2 = getNextSameName2(); 14 | REQUIRE(beforeReload1.first == 0); 15 | REQUIRE(beforeReload1.second == 10); 16 | REQUIRE(beforeReload2.first == 10); 17 | REQUIRE(beforeReload2.second == 110); 18 | 19 | std::cout << "JET_TEST: disable(st_var_same_name:1); enable(st_var_same_name:2)" << std::endl; 20 | waitForReload(); 21 | 22 | auto afterReload1 = getNextSameName1(); 23 | auto afterReload2 = getNextSameName2(); 24 | REQUIRE(afterReload1.first == 1); 25 | REQUIRE(afterReload1.second == 11); 26 | REQUIRE(afterReload2.first == 11); 27 | REQUIRE(afterReload2.second == 111); 28 | } 29 | -------------------------------------------------------------------------------- /libs/dobby/source/core/assembler/assembler-ia32.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if TARGET_ARCH_IA32 3 | 4 | #include "core/assembler/assembler-ia32.h" 5 | 6 | using namespace zz::x86; 7 | 8 | void Assembler::jmp(Immediate imm) { 9 | buffer_->Emit(0xE9); 10 | buffer_->Emit((int)imm.value()); 11 | } 12 | 13 | addr32_t TurboAssembler::CurrentIP() { 14 | return pc_offset() + (addr_t)realized_addr_; 15 | } 16 | 17 | void PseudoLabel::link_confused_instructions(CodeMemBuffer *buffer) { 18 | auto _buffer = (CodeBuffer *)buffer; 19 | 20 | for (auto &ref_label_insn : ref_insts) { 21 | int64_t new_offset = pos() - ref_label_insn.pc_offset; 22 | 23 | if (ref_label_insn.link_type == kDisp32_off_7) { 24 | // why 7 ? 25 | // use `call` and `pop` get the runtime ip register 26 | // but the ip register not the real call next insn 27 | // it need add two insn length == 7 28 | int disp32_fix_pos = ref_label_insn.pc_offset - sizeof(int32_t); 29 | _buffer->FixBindLabel(disp32_fix_pos, new_offset + 7); 30 | } 31 | } 32 | } 33 | 34 | #endif -------------------------------------------------------------------------------- /libs/efsw/src/efsw/FileWatcherImpl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace efsw { 6 | 7 | FileWatcherImpl::FileWatcherImpl( FileWatcher* parent ) : 8 | mFileWatcher( parent ), mInitOK( false ), mIsGeneric( false ) { 9 | System::maxFD(); 10 | } 11 | 12 | FileWatcherImpl::~FileWatcherImpl() {} 13 | 14 | bool FileWatcherImpl::initOK() { 15 | return static_cast( mInitOK ); 16 | } 17 | 18 | bool FileWatcherImpl::linkAllowed( const std::string& curPath, const std::string& link ) { 19 | return ( mFileWatcher->followSymlinks() && mFileWatcher->allowOutOfScopeLinks() ) || 20 | -1 != String::strStartsWith( curPath, link ); 21 | } 22 | 23 | int FileWatcherImpl::getOptionValue( const std::vector& options, Option option, 24 | int defaultValue ) { 25 | for ( size_t i = 0; i < options.size(); i++ ) { 26 | if ( options[i].mOption == option ) { 27 | return options[i].mValue; 28 | } 29 | } 30 | 31 | return defaultValue; 32 | } 33 | 34 | } // namespace efsw 35 | -------------------------------------------------------------------------------- /libs/dobby/source/InterceptRouting/deprecated.Routing/FunctionWrapper/function-wrapper.h: -------------------------------------------------------------------------------- 1 | #ifndef FUNCTION_WRAPPER_H 2 | #define FUNCTION_WRAPPER_H 3 | 4 | #include "dobby/dobby_internal.h" 5 | 6 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 7 | #include "InterceptRouting/InterceptRouting.h" 8 | #include "Interceptor.h" 9 | 10 | #if TARGET_ARCH_IA32 11 | #elif TARGET_ARCH_X64 12 | #include "InterceptRouting/x64/X64InterceptRouting.h" 13 | #elif TARGET_ARCH_ARM64 14 | #include "InterceptRouting/arm64/ARM64InterceptRouting.h" 15 | #elif TARGET_ARCH_ARM 16 | #else 17 | #error "unsupported architecture" 18 | #endif 19 | 20 | class FunctionWrapperRouting : public InterceptRouting { 21 | public: 22 | FunctionWrapperRouting(InterceptEntry *entry) : InterceptRouting(entry) { 23 | } 24 | 25 | void DispatchRouting(); 26 | 27 | void *GetTrampolineTarget(); 28 | 29 | private: 30 | void BuildPreCallRouting(); 31 | 32 | void BuildPostCallRouting(); 33 | 34 | private: 35 | void *prologue_dispatch_bridge; 36 | 37 | void *epilogue_dispatch_bridge; 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /tests/src/WaitForReload.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "WaitForReload.hpp" 3 | #include "Globals.hpp" 4 | #include 5 | #include 6 | 7 | void runAfterDelayAndWaitForReload(std::function&& func, int milliseconds) 8 | { 9 | bool cont = true; 10 | int updatesCount = 0; 11 | g_testListenerPtr->setCallbacks(nullptr, [&cont] { 12 | cont = false; 13 | }); 14 | while (cont) { 15 | if (updatesCount == milliseconds / 100) { 16 | func(); 17 | } 18 | g_live->update(); 19 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 20 | updatesCount++; 21 | if (updatesCount > 100) { 22 | break; 23 | } 24 | } 25 | g_testListenerPtr->setCallbacks(nullptr, nullptr); 26 | } 27 | 28 | void waitForReload(int milliseconds) 29 | { 30 | runAfterDelayAndWaitForReload([] { 31 | g_live->tryReload(); 32 | }, milliseconds); 33 | } 34 | 35 | void waitForReloadWithSignal(int milliseconds) 36 | { 37 | runAfterDelayAndWaitForReload([] { 38 | kill(getpid(), SIGUSR1); 39 | }, milliseconds); 40 | } 41 | -------------------------------------------------------------------------------- /example/src/ExampleListener.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ExampleListener.hpp" 3 | #include 4 | 5 | ExampleListener::ExampleListener(std::function&& codePreLoadCallback, 6 | std::function&& codePostLoadCallback) 7 | : m_codePreLoadCallback(std::move(codePreLoadCallback)) 8 | , m_codePostLoadCallback(std::move(codePostLoadCallback)) 9 | { 10 | } 11 | 12 | void ExampleListener::onLog(jet::LogSeverity severity, const std::string& message) 13 | { 14 | std::string severityString; 15 | switch (severity) { 16 | case jet::LogSeverity::kInfo: severityString.append("[I]"); break; 17 | case jet::LogSeverity::kWarning: severityString.append("[W]"); break; 18 | case jet::LogSeverity::kError: severityString.append("[E]"); break; 19 | default: return; // Skipping debug messages, they are too verbose 20 | } 21 | std::cout << severityString << ": " << message << std::endl; 22 | } 23 | 24 | void ExampleListener::onCodePreLoad() 25 | { 26 | m_codePreLoadCallback(); 27 | } 28 | 29 | void ExampleListener::onCodePostLoad() 30 | { 31 | m_codePostLoadCallback(); 32 | } 33 | -------------------------------------------------------------------------------- /libs/whereami/LICENSE.MIT: -------------------------------------------------------------------------------- 1 | Copyright Gregory Pakosz 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /tests/src/bad/LambdaFunctionWithCapturesBadCase_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/LambdaFunctionWithCapturesBadCase.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Reload of lambda function with captured data and another lambda in the file, bad case", "[function]") 10 | { 11 | int v1 = 23; 12 | int v2 = 45; 13 | int sum = v1 + v2; 14 | int mul = v1 * v2; 15 | auto lambda = createLambdaFunctionWithCapturesBadCase(); 16 | 17 | REQUIRE(lambda(v1, v2) == sum); 18 | 19 | std::cout << "JET_TEST: disable(lamb_capt_bad:1); enable(lamb_capt_bad:2)" << std::endl; 20 | waitForReload(); 21 | 22 | // Acts different on different platforms, compilers etc., unreliable in general 23 | #if defined(__APPLE__) && defined(__aarch64__) 24 | REQUIRE_FALSE(lambda(v1, v2) == mul); // note REQUIRE_FALSE 25 | #else 26 | # if defined(__clang__) 27 | REQUIRE(lambda(v1, v2) == mul); // note REQUIRE 28 | # else 29 | REQUIRE_FALSE(lambda(v1, v2) == mul); // note REQUIRE_FALSE 30 | #endif 31 | #endif 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 David Dovodov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /libs/dobby/common/os_arch_features.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "pac_kit.h" 6 | 7 | #include "PlatformUnifiedInterface/platform.h" 8 | 9 | namespace features { 10 | 11 | template inline T arm_thumb_fix_addr(T &addr) { 12 | #if defined(__arm__) || defined(__aarch64__) 13 | addr = (T)((uintptr_t)addr & ~1); 14 | #endif 15 | return addr; 16 | } 17 | 18 | namespace apple { 19 | template inline T arm64e_pac_strip(T &addr) { 20 | return pac_strip(addr); 21 | } 22 | 23 | template inline T arm64e_pac_sign(T &addr) { 24 | return pac_sign(addr); 25 | } 26 | 27 | template inline T arm64e_pac_strip_and_sign(T &addr) { 28 | return pac_strip_and_sign(addr); 29 | } 30 | } // namespace apple 31 | 32 | namespace android { 33 | inline void make_memory_readable(void *address, size_t size) { 34 | #if defined(ANDROID) 35 | auto page = (void *)ALIGN_FLOOR(address, OSMemory::PageSize()); 36 | if (!OSMemory::SetPermission(page, OSMemory::PageSize(), kReadExecute)) { 37 | return; 38 | } 39 | #endif 40 | } 41 | } // namespace android 42 | } // namespace features -------------------------------------------------------------------------------- /libs/dobby/source/MemoryAllocator/AssemblerCodeBuilder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryAllocator.h" 4 | 5 | #include "core/assembler/assembler.h" 6 | 7 | using namespace zz; 8 | 9 | struct AssemblerCodeBuilder { 10 | static MemBlock FinalizeFromTurboAssembler(AssemblerBase *assembler) { 11 | auto code_buffer = assembler->code_buffer(); 12 | auto fixed_addr = (addr_t)assembler->fixed_addr; 13 | 14 | #if defined(TEST_WITH_UNICORN) 15 | // impl: unicorn emulator map memory 16 | fixed_addr = 0; 17 | #endif 18 | 19 | if (!fixed_addr) { 20 | size_t buffer_size = 0; 21 | buffer_size = code_buffer->size(); 22 | 23 | #if TARGET_ARCH_ARM 24 | // extra bytes for align needed 25 | buffer_size += 4; 26 | #endif 27 | 28 | auto block = gMemoryAllocator.allocExecBlock(buffer_size); 29 | if (block.addr() == 0) 30 | return MemBlock{}; 31 | 32 | fixed_addr = block.addr(); 33 | assembler->set_fixed_addr(fixed_addr); 34 | } 35 | 36 | DobbyCodePatch((void *)fixed_addr, code_buffer->data(), code_buffer->size()); 37 | 38 | return MemBlock(fixed_addr, code_buffer->size()); 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /libs/json/LICENSE.MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-2025 Niels Lohmann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /libs/teenypath/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Tableau 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /libs/ELFIO/LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (C) 2001-present by Serge Lamikhov-Center 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /libs/dobby/source/core/assembler/assembler-arm.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if TARGET_ARCH_ARM 3 | 4 | #include "core/assembler/assembler-arm.h" 5 | 6 | void PseudoLabel::link_confused_instructions(CodeMemBuffer *buffer) { 7 | CodeBuffer *_buffer = (CodeBuffer *)buffer; 8 | 9 | for (auto &ref_label_insn : ref_insts) { 10 | arm_inst_t inst = _buffer->LoadARMInst(ref_label_insn.pc_offset); 11 | if (ref_label_insn.link_type == kLdrLiteral) { 12 | int64_t pc = ref_label_insn.pc_offset + ARM_PC_OFFSET; 13 | assert(pc % 4 == 0); 14 | int32_t imm12 = pos() - pc; 15 | if (imm12 > 0) { 16 | set_bit(inst, 23, 1); 17 | } else { 18 | set_bit(inst, 23, 0); 19 | imm12 = -imm12; 20 | } 21 | set_bits(inst, 0, 11, imm12); 22 | } 23 | _buffer->RewriteARMInst(ref_label_insn.pc_offset, inst); 24 | } 25 | } 26 | 27 | namespace zz { 28 | namespace arm { 29 | 30 | void Assembler::EmitARMInst(arm_inst_t instr) { 31 | buffer_->EmitARMInst(instr); 32 | } 33 | 34 | void Assembler::EmitAddress(uint32_t value) { 35 | buffer_->Emit(value); 36 | } 37 | 38 | } // namespace arm 39 | } // namespace zz 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /libs/tiny-process-library/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2020 Ole Christian Eidheim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /libs/dobby/source/TrampolineBridge/Trampoline/Trampoline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryAllocator/CodeMemBuffer.h" 4 | 5 | enum trampoline_type_t { 6 | TRAMPOLINE_UNKNOWN = 0, 7 | TRAMPOLINE_ARM64_B_XXX, 8 | TRAMPOLINE_ARM64_B_XXX_AND_FORWARD_TRAMP, 9 | TRAMPOLINE_ARM64_ADRP_ADD_BR, 10 | TRAMPOLINE_ARM64_LDR_BR, 11 | 12 | 13 | CLOSURE_TRAMPOLINE_ARM64, 14 | FORWARD_TRAMPOLINE_ARM64, 15 | 16 | TRAMPOLINE_X64_JMP, 17 | CLOSEURE_TRAMPOLINE_X64, 18 | }; 19 | 20 | struct Trampoline { 21 | int type; 22 | CodeMemBlock buffer; 23 | 24 | Trampoline *forward_trampoline; 25 | 26 | Trampoline() : type(0), buffer() { 27 | } 28 | 29 | Trampoline(int type, CodeMemBlock buffer) : type(type), buffer(buffer) { 30 | } 31 | 32 | Trampoline(int type, CodeMemBlock buffer, Trampoline *forward) 33 | : type(type), buffer(buffer), forward_trampoline(forward) { 34 | } 35 | 36 | addr_t addr() { 37 | return buffer.addr(); 38 | } 39 | 40 | addr_t size() { 41 | return buffer.size; 42 | } 43 | 44 | addr_t forward_addr() { 45 | return forward_trampoline->addr(); 46 | } 47 | 48 | addr_t forward_size() { 49 | return forward_trampoline->size(); 50 | } 51 | }; -------------------------------------------------------------------------------- /libs/efsw/src/efsw/FileSystem.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_FILESYSTEM_HPP 2 | #define EFSW_FILESYSTEM_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace efsw { 8 | 9 | class FileSystem { 10 | public: 11 | static bool isDirectory( const std::string& path ); 12 | 13 | static FileInfoMap filesInfoFromPath( std::string path ); 14 | 15 | static char getOSSlash(); 16 | 17 | static bool slashAtEnd( std::string& dir ); 18 | 19 | static void dirAddSlashAtEnd( std::string& dir ); 20 | 21 | static void dirRemoveSlashAtEnd( std::string& dir ); 22 | 23 | static std::string fileNameFromPath( std::string filepath ); 24 | 25 | static std::string pathRemoveFileName( std::string filepath ); 26 | 27 | static std::string getLinkRealPath( std::string dir, std::string& curPath ); 28 | 29 | static std::string precomposeFileName( const std::string& name ); 30 | 31 | static bool isRemoteFS( const std::string& directory ); 32 | 33 | static bool changeWorkingDirectory( const std::string& path ); 34 | 35 | static std::string getCurrentWorkingDirectory(); 36 | 37 | static std::string getRealPath( const std::string& path ); 38 | 39 | }; 40 | 41 | } // namespace efsw 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/jet/live/AsyncEventQueue.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | #include 6 | #include 7 | #include "jet/live/IEvent.hpp" 8 | #include "jet/live/ILiveListener.hpp" 9 | #include "jet/live/events/LogEvent.hpp" 10 | 11 | namespace jet 12 | { 13 | class AsyncEventQueue 14 | { 15 | public: 16 | void addLog(LogSeverity severity, std::string&& message); 17 | LogEvent* getLogEvent(); 18 | void popLogEvent(); 19 | 20 | void addEvent(std::unique_ptr&& event); 21 | IEvent* getEvent(); 22 | void popEvent(); 23 | 24 | private: 25 | struct QueueComparator 26 | { 27 | bool operator()(const std::unique_ptr& l, const std::unique_ptr& r) 28 | { 29 | return l->getPriority() < r->getPriority(); 30 | } 31 | }; 32 | template 33 | using queue_t = std::priority_queue, QueueComparator>; 34 | 35 | std::mutex m_logQueueMutex; 36 | std::queue> m_logQueue; 37 | 38 | std::mutex m_queueMutex; 39 | queue_t> m_queue; 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /libs/dobby/cmake/platform/platform-darwin.cmake: -------------------------------------------------------------------------------- 1 | # set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR TRUE) 2 | set(CMAKE_INSTALL_NAME_DIR "@rpath") 3 | set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") 4 | add_library(DobbyX ${DOBBY_LIBRARY_TYPE} ${dobby.HEADER_FILE_LIST} ${dobby.SOURCE_FILE_LIST} ${logging.SOURCE_FILE_LIST} ${misc_helper.SOURCE_FILE_LIST} ${dobby.plugin.SOURCE_FILE_LIST}) 5 | 6 | set_target_properties(DobbyX 7 | PROPERTIES 8 | LINK_FLAGS "${linker_flags}" 9 | COMPILE_FLAGS "${compiler_flags}" 10 | ) 11 | 12 | # set framework property 13 | set_target_properties(DobbyX PROPERTIES 14 | FRAMEWORK TRUE 15 | FRAMEWORK_VERSION A 16 | MACOSX_FRAMEWORK_IDENTIFIER "com.dobby.dobby" 17 | # MACOSX_FRAMEWORK_INFO_PLIST Info.plist 18 | VERSION 1.0.0 # current version 19 | SOVERSION 1.0.0 # compatibility version 20 | PUBLIC_HEADER include/dobby.h 21 | XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Development" 22 | ) 23 | 24 | if ((SYSTEM.Darwin AND BUILDING_PLUGIN) AND (NOT DOBBY_BUILD_KERNEL_MODE)) 25 | add_subdirectory(builtin-plugin/Dyld2HideLibrary) 26 | add_subdirectory(builtin-plugin/ObjcRuntimeHook) 27 | if (PROCESSOR.AARCH64) 28 | add_subdirectory(builtin-plugin/SupervisorCallMonitor) 29 | endif () 30 | endif() -------------------------------------------------------------------------------- /libs/utils/small_vector/LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016-2019 Chobolabs Inc. 4 | Copyright (c) 2020-2025 Borislav Stanimirov 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /libs/dobby/external/TINYSTL/function.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace tinystl { 4 | 5 | template class function; 6 | 7 | template class function { 8 | public: 9 | function() { 10 | } 11 | 12 | template function(T functor) { 13 | m_func = [](const void *user, Args... args) -> Return { 14 | const T &func = *static_cast(user); 15 | return func(static_cast(args)...); 16 | }; 17 | 18 | m_dtor = [](void *user) { 19 | T &func = *static_cast(user); 20 | func.~T(); 21 | }; 22 | 23 | new (tinystl::placeholder(), m_storage) T(static_cast(functor)); 24 | } 25 | 26 | ~function() { 27 | if (m_dtor) 28 | m_dtor(m_storage); 29 | } 30 | 31 | Return operator()(Args... args) const { 32 | return m_func(m_storage, static_cast(args)...); 33 | } 34 | 35 | explicit operator bool() { 36 | return m_func != nullptr; 37 | } 38 | 39 | using Func = Return (*)(const void *, Args...); 40 | Func m_func = nullptr; 41 | using Dtor = void (*)(void *); 42 | Dtor m_dtor = nullptr; 43 | union { 44 | void *m_storage[8]; 45 | }; 46 | }; 47 | 48 | } // namespace tinystl -------------------------------------------------------------------------------- /libs/dobby/tests/test_insn_relo_x64.cpp: -------------------------------------------------------------------------------- 1 | #include "InstructionRelocation/InstructionRelocation.h" 2 | 3 | #include "UniconEmulator.h" 4 | 5 | int main() { 6 | log_set_level(0); 7 | set_global_arch("x86_64"); 8 | 9 | 10 | // cmp eax, eax 11 | // jz -0x20 12 | check_insn_relo("\x39\xc0\x74\xdc", 4, false, UC_X86_REG_IP, nullptr); 13 | // cmp eax, eax 14 | // jz 0x20 15 | check_insn_relo("\x39\xc0\x74\x1c", 4, false, UC_X86_REG_IP, nullptr); 16 | 17 | // jmp -0x20 18 | check_insn_relo("\xeb\xde", 2, false, UC_X86_REG_IP, nullptr); 19 | // jmp 0x20 20 | check_insn_relo("\xeb\x1e", 2, false, UC_X86_REG_IP, nullptr); 21 | 22 | 23 | // jmp -0x4000 24 | check_insn_relo("\xe9\xfb\xbf\xff\xff", 4, false, UC_X86_REG_IP, nullptr); 25 | // jmp 0x4000 26 | check_insn_relo("\xe9\xfb\x3f\x00\x00", 4, false, UC_X86_REG_IP, nullptr); 27 | 28 | // lea rax, [rip] 29 | check_insn_relo("\x48\x8d\x05\x00\x00\x00\x00", 7, false, UC_X86_REG_RAX, nullptr); 30 | 31 | // lea rax, [rip + 0x4000] 32 | check_insn_relo("\x48\x8d\x05\x00\x40\x00\x00", 7, false, UC_X86_REG_RAX, nullptr); 33 | 34 | // mov rax, [rip + 0x4000] 35 | check_insn_relo("\x48\x8b\x05\x00\x40\x00\x00", 7, true, -1, nullptr); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/platform/win/SystemImpl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 5 | 6 | #ifndef WIN32_LEAN_AND_MEAN 7 | #define WIN32_LEAN_AND_MEAN 8 | #endif 9 | #include 10 | #include 11 | 12 | namespace efsw { namespace Platform { 13 | 14 | void System::sleep( const unsigned long& ms ) { 15 | ::Sleep( ms ); 16 | } 17 | 18 | std::string System::getProcessPath() { 19 | // Get path to executable: 20 | WCHAR szDrive[_MAX_DRIVE]; 21 | WCHAR szDir[_MAX_DIR]; 22 | WCHAR szFilename[_MAX_DIR]; 23 | WCHAR szExt[_MAX_DIR]; 24 | std::wstring dllName( _MAX_DIR, 0 ); 25 | 26 | GetModuleFileNameW( 0, &dllName[0], _MAX_PATH ); 27 | 28 | #ifdef EFSW_COMPILER_MSVC 29 | _wsplitpath_s( dllName.c_str(), szDrive, _MAX_DRIVE, szDir, _MAX_DIR, szFilename, _MAX_DIR, 30 | szExt, _MAX_DIR ); 31 | #else 32 | _wsplitpath( dllName.c_str(), szDrive, szDir, szFilename, szExt ); 33 | #endif 34 | 35 | return String( szDrive ).toUtf8() + String( szDir ).toUtf8(); 36 | } 37 | 38 | void System::maxFD() {} 39 | 40 | Uint64 System::getMaxFD() { // Number of ReadDirectory per thread 41 | return 60; 42 | } 43 | 44 | }} // namespace efsw::Platform 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /tests/src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define CATCH_CONFIG_RUNNER 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "TestListener.hpp" 9 | #include 10 | #include "Stacktrace.hpp" 11 | 12 | TestListener* g_testListenerPtr = nullptr; 13 | jet::Live* g_live = nullptr; 14 | 15 | int main(int argc, char* argv[]) 16 | { 17 | setupSignalHandlers(); 18 | 19 | std::cout.setf(std::ios::unitbuf); 20 | std::cout << "Running tests" << std::endl; 21 | 22 | auto testListener = jet::make_unique(); 23 | g_testListenerPtr = testListener.get(); 24 | 25 | auto live = jet::make_unique(std::move(testListener)); 26 | g_live = live.get(); 27 | 28 | while (!g_live->isInitialized()) { 29 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 30 | } 31 | 32 | auto res = Catch::Session().run(argc, argv); 33 | 34 | for (int i = 0; i < 10; i++) { 35 | g_live->update(); 36 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 37 | } 38 | 39 | live.reset(); 40 | g_live = nullptr; 41 | testListener.reset(); 42 | g_testListenerPtr = nullptr; 43 | 44 | return res; 45 | } 46 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/Log.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace efsw { namespace Errors { 5 | 6 | static std::string LastError = ""; 7 | static Error LastErrorCode = NoError; 8 | 9 | std::string Log::getLastErrorLog() { 10 | return LastError; 11 | } 12 | 13 | Error Log::getLastErrorCode() { 14 | return LastErrorCode; 15 | } 16 | 17 | void Log::clearLastError() { 18 | LastErrorCode = NoError; 19 | LastError = ""; 20 | } 21 | 22 | Error Log::createLastError( Error err, std::string log ) { 23 | switch ( err ) { 24 | case FileNotFound: 25 | LastError = "File not found ( " + log + " )"; 26 | break; 27 | case FileRepeated: 28 | LastError = "File repeated in watches ( " + log + " )"; 29 | break; 30 | case FileOutOfScope: 31 | LastError = "Symlink file out of scope ( " + log + " )"; 32 | break; 33 | case FileRemote: 34 | LastError = 35 | "File is located in a remote file system, use a generic watcher. ( " + log + " )"; 36 | break; 37 | case WatcherFailed: 38 | LastError = "File system watcher failed ( " + log + " )"; 39 | break; 40 | case Unspecified: 41 | default: 42 | LastError = log; 43 | } 44 | 45 | efDEBUG( "%s\n", LastError.c_str() ); 46 | return err; 47 | } 48 | 49 | }} // namespace efsw::Errors 50 | -------------------------------------------------------------------------------- /libs/dobby/cmake/auto_source_group.cmake: -------------------------------------------------------------------------------- 1 | function (auto_source_group _folder _base _pattern) 2 | if (ARGC GREATER 3) 3 | set(_exclude ${ARGN}) 4 | else () 5 | set(_exclude) 6 | endif () 7 | file (GLOB _files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ ${_folder}/*) 8 | set (folder_files) 9 | foreach (_fname ${_files}) 10 | if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_fname}) 11 | auto_source_group ("${_fname}" "${_base}" "${_pattern}" "${_exclude}") 12 | elseif (_fname MATCHES ${_pattern}) 13 | if(_exclude) 14 | if (NOT _fname MATCHES ${_exclude}) 15 | set(folder_files ${folder_files} ${_fname}) 16 | endif () 17 | else () 18 | set(folder_files ${folder_files} ${_fname}) 19 | endif () 20 | endif () 21 | endforeach () 22 | 23 | string(REPLACE "./" "" _folder2 ${_folder}) 24 | string(REPLACE "/" "\\" _folder2 ${_folder2}) 25 | if (_folder2 STREQUAL ".") 26 | source_group(${_base} FILES ${folder_files}) 27 | else () 28 | source_group(${_base}\\${_folder2} FILES ${folder_files}) 29 | endif () 30 | 31 | set(AUTO_FILES_RESULT ${AUTO_FILES_RESULT} ${folder_files} PARENT_SCOPE) 32 | endfunction () -------------------------------------------------------------------------------- /libs/efsw/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Martín Lucas Golini 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | This software is a fork of the "simplefilewatcher" by James Wynn (james@jameswynn.com) 22 | http://code.google.com/p/simplefilewatcher/ also MIT licensed. 23 | -------------------------------------------------------------------------------- /libs/dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-posix.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "dobby/dobby_internal.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #if !defined(__APPLE__) 9 | PUBLIC int DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { 10 | #if defined(__ANDROID__) || defined(__linux__) 11 | int page_size = (int)sysconf(_SC_PAGESIZE); 12 | uintptr_t patch_page = ALIGN_FLOOR(address, page_size); 13 | uintptr_t patch_end_page = ALIGN_FLOOR((uintptr_t)address + buffer_size, page_size); 14 | 15 | // change page permission as rwx 16 | mprotect((void *)patch_page, page_size, PROT_READ | PROT_WRITE | PROT_EXEC); 17 | if (patch_page != patch_end_page) { 18 | mprotect((void *)patch_end_page, page_size, PROT_READ | PROT_WRITE | PROT_EXEC); 19 | } 20 | 21 | // patch buffer 22 | memcpy(address, buffer, buffer_size); 23 | 24 | // restore page permission 25 | mprotect((void *)patch_page, page_size, PROT_READ | PROT_EXEC); 26 | if (patch_page != patch_end_page) { 27 | mprotect((void *)patch_end_page, page_size, PROT_READ | PROT_EXEC); 28 | } 29 | 30 | addr_t clear_start_ = (addr_t)address; 31 | ClearCache((void *)clear_start_, (void *)(clear_start_ + buffer_size)); 32 | #endif 33 | return 0; 34 | } 35 | 36 | #endif -------------------------------------------------------------------------------- /libs/dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-trampoline-template-arm.S: -------------------------------------------------------------------------------- 1 | // .section __TEXT,__text,regular,pure_instructions 2 | 3 | #if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) 4 | 5 | #if defined(__WIN32__) || defined(__APPLE__) 6 | #define cdecl(s) _##s 7 | #else 8 | #define cdecl(s) s 9 | #endif 10 | 11 | .align 4 12 | 13 | #if !defined(ENABLE_CLOSURE_TRAMPOLINE_CARRY_OBJECT_PTR) 14 | 15 | // closure trampoline carray the object pointer, and fetch required members at the runtime assembly code. 16 | // #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 17 | // #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) 18 | #define OFFSETOF_ClourseTrampolineEntry_carry_data 4 19 | #define OFFSETOF_ClourseTrampolineEntry_carry_handler 0 20 | .globl 21 | cdecl(closure_trampoline_template) cdecl(closure_trampoline_template) 22 | : ldr r12, 23 | ClourseTrampolineEntryPtr ldr pc, [ r12, #0 ] ClourseTrampolineEntryPtr :.long 0 24 | 25 | #else 26 | 27 | ; 28 | closure trampoline just carray the required members from the object..globl cdecl(closure_trampoline_template) 29 | cdecl(closure_trampoline_template) 30 | : ldr r12, 31 | = carry_data ldr pc, = carry_handler carry_data :.long 0 carry_handler :.long 0 32 | #endif 33 | 34 | #endif -------------------------------------------------------------------------------- /libs/dobby/source/dobby/platform_features.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(__APPLE__) && __arm64e__ 4 | #if __has_feature(ptrauth_calls) 5 | #include 6 | #endif 7 | #endif 8 | 9 | #if defined(BUILDING_KERNEL) 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #else 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #if defined(__linux__) || defined(__APPLE__) 27 | #include 28 | #include 29 | #endif 30 | #endif 31 | 32 | #if defined(BUILDING_KERNEL) 33 | #include "kernel_mode_header.h" 34 | #endif 35 | 36 | #if defined(BUILDING_KERNEL) 37 | #define abs(a) ((a) < 0 ? -(a) : (a)) 38 | #define llabs(a) (((long long)a) < 0 ? -((long long)a) : ((long long)a)) 39 | #define min(a, b) (((a) < (b)) ? (a) : (b)) 40 | #define max(a, b) (((a) > (b)) ? (a) : (b)) 41 | #ifdef __cplusplus 42 | #define abs(a) ((a) < 0 ? -(a) : (a)) 43 | #endif 44 | #else 45 | #endif 46 | 47 | #ifdef __cplusplus 48 | #include "TINYSTL/vector.h" 49 | #include "TINYSTL/unordered_map.h" 50 | #include "TINYSTL/tinystl.h" 51 | #endif -------------------------------------------------------------------------------- /example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.20) 3 | project(example) 4 | 5 | add_executable(example "") 6 | target_sources(example 7 | PRIVATE 8 | src/main.cpp 9 | src/ExampleListener.cpp 10 | src/SimpleCommandInterpreter.cpp 11 | ) 12 | target_include_directories(example 13 | PRIVATE 14 | src 15 | ) 16 | find_package(Threads REQUIRED) 17 | target_link_libraries(example 18 | PRIVATE 19 | jet-live 20 | Threads::Threads 21 | ) 22 | set_target_properties(example 23 | PROPERTIES 24 | CXX_STANDARD 17 25 | ) 26 | target_compile_options(example 27 | PRIVATE 28 | $<$:-fno-rtti> 29 | $<$:-fno-exceptions> 30 | $<$:-Wall> 31 | $<$:-Wall> 32 | $<$:-Wextra> 33 | $<$:-Wextra> 34 | $<$:-Wpedantic> 35 | $<$:-Wpedantic> 36 | $<$:-Wshadow> 37 | $<$:-Wshadow> 38 | $<$:-Wconversion> 39 | $<$:-Wconversion> 40 | ) 41 | if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") 42 | target_compile_options(example 43 | PRIVATE 44 | $<$:-Wvexing-parse> 45 | $<$:-Wvexing-parse> 46 | ) 47 | endif() 48 | -------------------------------------------------------------------------------- /libs/tiny-process-library/README.md: -------------------------------------------------------------------------------- 1 | # tiny-process-library 2 | A small platform independent library making it simple to create and stop new processes in C++, as well as writing to stdin and reading from stdout and stderr of a new process. 3 | 4 | This library was created for, and is used by the C++ IDE project [juCi++](https://gitlab.com/cppit/jucipp). 5 | 6 | ### Features 7 | * No external dependencies 8 | * Simple to use 9 | * Platform independent 10 | * Creating processes using executables is supported on all platforms 11 | * Creating processes using functions is only possible on Unix-like systems 12 | * Read separately from stdout and stderr using anonymous functions 13 | * Write to stdin 14 | * Kill a running process (SIGTERM is supported on Unix-like systems) 15 | * Correctly closes file descriptors/handles 16 | 17 | ### Usage 18 | See [examples.cpp](examples.cpp). 19 | 20 | ### Get, compile and run 21 | 22 | #### Unix-like systems 23 | ```sh 24 | git clone http://gitlab.com/eidheim/tiny-process-library 25 | cd tiny-process-library 26 | mkdir build 27 | cd build 28 | cmake .. 29 | make 30 | ./examples 31 | ``` 32 | 33 | #### Windows with MSYS2 (https://msys2.github.io/) 34 | ```sh 35 | git clone http://gitlab.com/eidheim/tiny-process-library 36 | cd tiny-process-library 37 | mkdir build 38 | cd build 39 | cmake -G"MSYS Makefiles" .. 40 | make 41 | ./examples 42 | ``` 43 | -------------------------------------------------------------------------------- /tests/src/good/FailedCompilationCrash_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "utility/FailedCompilationCrash.hpp" 6 | #include "Globals.hpp" 7 | #include "WaitForReload.hpp" 8 | 9 | TEST_CASE("Crash when trying to reload code after success and then failed compilation", "[common]") 10 | { 11 | int v1 = 23; 12 | int v2 = 45; 13 | int sum = v1 + v2; 14 | int mul = v1 * v2; 15 | 16 | REQUIRE(failedCompilationComputeResult(v1, v2) == sum); 17 | 18 | std::cout << "JET_TEST: disable(failed_comp:1); enable(failed_comp:2)" << std::endl; 19 | // waiting for compilation to finish 20 | int updatesCount = 0; 21 | while (true) { 22 | if (updatesCount == 30) { 23 | break; 24 | } 25 | g_live->update(); 26 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 27 | updatesCount++; 28 | } 29 | 30 | std::cout << "JET_TEST: disable(failed_comp:2); enable(failed_comp:3)" << std::endl; 31 | waitForReload(); // fail, here should be a crash 32 | REQUIRE(failedCompilationComputeResult(v1, v2) == sum); // still old code 33 | 34 | std::cout << "JET_TEST: disable(failed_comp:3); enable(failed_comp:4)" << std::endl; 35 | waitForReload(); // success 36 | REQUIRE(failedCompilationComputeResult(v1, v2) == mul); // new code 37 | } 38 | -------------------------------------------------------------------------------- /libs/dobby/source/InstructionRelocation/arm64/inst_constants.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if 0 4 | enum LoadRegLiteralOp { 5 | LoadRegLiteralFixed = 0x18000000, 6 | LoadRegLiteralFixedMask = 0x3B000000, 7 | LoadRegLiteralMask = 0xFF000000, 8 | }; 9 | 10 | // PC relative addressing. 11 | enum PCRelAddressingOp { 12 | PCRelAddressingFixed = 0x10000000, 13 | PCRelAddressingFixedMask = 0x1F000000, 14 | PCRelAddressingMask = 0x9F000000, 15 | ADR = PCRelAddressingFixed | 0x00000000, 16 | ADRP = PCRelAddressingFixed | 0x80000000 17 | }; 18 | 19 | // Unconditional branch. 20 | enum UnconditionalBranchOp { 21 | UnconditionalBranchFixed = 0x14000000, 22 | UnconditionalBranchFixedMask = 0x7C000000, 23 | UnconditionalBranchMask = 0xFC000000, 24 | 25 | B = UnconditionalBranchFixed | 0x00000000, 26 | BL = UnconditionalBranchFixed | 0x80000000 27 | }; 28 | #endif 29 | 30 | // Compare and branch. 31 | enum CompareBranchOp { 32 | CompareBranchFixed = 0x34000000, 33 | CompareBranchFixedMask = 0x7E000000, 34 | CompareBranchMask = 0xFF000000, 35 | }; 36 | 37 | // Conditional branch. 38 | enum ConditionalBranchOp { 39 | ConditionalBranchFixed = 0x54000000, 40 | ConditionalBranchFixedMask = 0xFE000000, 41 | ConditionalBranchMask = 0xFF000010, 42 | }; 43 | 44 | // Test and branch. 45 | enum TestBranchOp { 46 | TestBranchFixed = 0x36000000, 47 | TestBranchFixedMask = 0x7E000000, 48 | TestBranchMask = 0x7F000000, 49 | }; -------------------------------------------------------------------------------- /libs/Catch2/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.cc: -------------------------------------------------------------------------------- 1 | #include "misc_utility.h" 2 | 3 | #include 4 | 5 | segment_command_t *macho_kit_get_segment_by_name(mach_header_t *header, const char *segname) { 6 | segment_command_t *curr_seg_cmd = NULL; 7 | 8 | curr_seg_cmd = (segment_command_t *)((addr_t)header + sizeof(mach_header_t)); 9 | for (int i = 0; i < header->ncmds; i++) { 10 | if (curr_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { 11 | if (!strncmp(curr_seg_cmd->segname, segname, sizeof(curr_seg_cmd->segname))) { 12 | break; 13 | } 14 | } 15 | curr_seg_cmd = (segment_command_t *)((addr_t)curr_seg_cmd + curr_seg_cmd->cmdsize); 16 | } 17 | 18 | return curr_seg_cmd; 19 | } 20 | 21 | section_t *macho_kit_get_section_by_name(mach_header_t *header, const char *segname, const char *sectname) { 22 | section_t *section = NULL; 23 | segment_command_t *segment = NULL; 24 | 25 | int i = 0; 26 | 27 | segment = macho_kit_get_segment_by_name(header, segname); 28 | if (!segment) 29 | goto finish; 30 | 31 | section = (section_t *)((addr_t)segment + sizeof(segment_command_t)); 32 | for (i = 0; i < segment->nsects; ++i) { 33 | if (!strncmp(section->sectname, sectname, sizeof(section->sectname))) { 34 | break; 35 | } 36 | section += 1; 37 | } 38 | if (i == segment->nsects) { 39 | section = NULL; 40 | } 41 | 42 | finish: 43 | return section; 44 | } -------------------------------------------------------------------------------- /libs/efsw/src/efsw/Debug.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_DEBUG_HPP 2 | #define EFSW_DEBUG_HPP 3 | 4 | #include 5 | 6 | namespace efsw { 7 | 8 | #ifdef DEBUG 9 | 10 | void efREPORT_ASSERT( const char* File, const int Line, const char* Exp ); 11 | 12 | #define efASSERT( expr ) \ 13 | if ( !( expr ) ) { \ 14 | efREPORT_ASSERT( __FILE__, __LINE__, #expr ); \ 15 | } 16 | #define efASSERTM( expr, msg ) \ 17 | if ( !( expr ) ) { \ 18 | efREPORT_ASSERT( __FILE__, __LINE__, #msg ); \ 19 | } 20 | 21 | void efPRINT( const char* format, ... ); 22 | void efPRINTC( unsigned int cond, const char* format, ... ); 23 | 24 | #else 25 | 26 | #define efASSERT( expr ) 27 | #define efASSERTM( expr, msg ) 28 | 29 | #ifndef EFSW_COMPILER_MSVC 30 | #define efPRINT( format, args... ) \ 31 | {} 32 | #define efPRINTC( cond, format, args... ) \ 33 | {} 34 | #else 35 | #define efPRINT 36 | #define efPRINTC 37 | #endif 38 | 39 | #endif 40 | 41 | #ifdef EFSW_VERBOSE 42 | #define efDEBUG efPRINT 43 | #define efDEBUGC efPRINTC 44 | #else 45 | 46 | #ifndef EFSW_COMPILER_MSVC 47 | #define efDEBUG( format, args... ) \ 48 | {} 49 | #define efDEBUGC( cond, format, args... ) \ 50 | {} 51 | #else 52 | #define efDEBUG( ... ) \ 53 | {} 54 | #define efDEBUGC( ... ) \ 55 | {} 56 | #endif 57 | 58 | #endif 59 | 60 | } // namespace efsw 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/jet/live/AsyncEventQueue.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "AsyncEventQueue.hpp" 3 | #include "jet/live/Utility.hpp" 4 | 5 | namespace jet 6 | { 7 | void AsyncEventQueue::addLog(LogSeverity severity, std::string&& message) 8 | { 9 | std::lock_guard lock(m_logQueueMutex); 10 | m_logQueue.push(jet::make_unique(severity, std::move(message))); 11 | } 12 | 13 | LogEvent* AsyncEventQueue::getLogEvent() 14 | { 15 | std::lock_guard lock(m_logQueueMutex); 16 | return m_logQueue.empty() ? nullptr : m_logQueue.front().get(); 17 | } 18 | 19 | void AsyncEventQueue::popLogEvent() 20 | { 21 | std::lock_guard lock(m_logQueueMutex); 22 | if (!m_logQueue.empty()) { 23 | m_logQueue.pop(); 24 | } 25 | } 26 | 27 | void AsyncEventQueue::addEvent(std::unique_ptr&& event) 28 | { 29 | std::lock_guard lock(m_queueMutex); 30 | m_queue.push(std::move(event)); 31 | } 32 | 33 | IEvent* AsyncEventQueue::getEvent() 34 | { 35 | std::lock_guard lock(m_queueMutex); 36 | return m_queue.empty() ? nullptr : m_queue.top().get(); 37 | } 38 | 39 | void AsyncEventQueue::popEvent() 40 | { 41 | std::lock_guard lock(m_queueMutex); 42 | if (!m_queue.empty()) { 43 | m_queue.pop(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/FileInfo.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_FILEINFO_HPP 2 | #define EFSW_FILEINFO_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace efsw { 10 | 11 | class FileInfo { 12 | public: 13 | static bool exists( const std::string& filePath ); 14 | 15 | static bool isLink( const std::string& filePath ); 16 | 17 | static bool inodeSupported(); 18 | 19 | FileInfo(); 20 | 21 | FileInfo( const std::string& filepath ); 22 | 23 | FileInfo( const std::string& filepath, bool linkInfo ); 24 | 25 | bool operator==( const FileInfo& Other ) const; 26 | 27 | bool operator!=( const FileInfo& Other ) const; 28 | 29 | FileInfo& operator=( const FileInfo& Other ); 30 | 31 | bool isDirectory() const; 32 | 33 | bool isRegularFile() const; 34 | 35 | bool isReadable() const; 36 | 37 | bool sameInode( const FileInfo& Other ) const; 38 | 39 | bool isLink() const; 40 | 41 | std::string linksTo(); 42 | 43 | bool exists(); 44 | 45 | void getInfo(); 46 | 47 | void getRealInfo(); 48 | 49 | std::string Filepath; 50 | Uint64 ModificationTime; 51 | Uint64 Size; 52 | Uint32 OwnerId; 53 | Uint32 GroupId; 54 | Uint32 Permissions; 55 | Uint64 Inode; 56 | }; 57 | 58 | typedef std::map FileInfoMap; 59 | typedef std::vector FileInfoList; 60 | typedef std::vector> MovedList; 61 | 62 | } // namespace efsw 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/ApplicationEventMonitor/MGCopyAnswerMonitor.cc: -------------------------------------------------------------------------------- 1 | #include "./dobby_monitor.h" 2 | 3 | #include 4 | #include 5 | 6 | #define LOG_TAG "MGCopyAnswer" 7 | 8 | static uintptr_t getCallFirstArg(DobbyRegisterContext *ctx) { 9 | uintptr_t result; 10 | #if defined(_M_X64) || defined(__x86_64__) 11 | #if defined(_WIN32) 12 | result = ctx->general.regs.rcx; 13 | #else 14 | result = ctx->general.regs.rdi; 15 | #endif 16 | #elif defined(__arm64__) || defined(__aarch64__) 17 | result = ctx->general.regs.x0; 18 | #elif defined(__arm__) 19 | result = ctx->general.regs.r0; 20 | #else 21 | #error "Not Support Architecture." 22 | #endif 23 | return result; 24 | } 25 | 26 | void common_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { 27 | CFStringRef key_ = 0; 28 | key_ = (CFStringRef)getCallFirstArg(ctx); 29 | 30 | char str_key[256] = {0}; 31 | CFStringGetCString(key_, str_key, 256, kCFStringEncodingUTF8); 32 | LOG("[#] MGCopyAnswer:: %s\n", str_key); 33 | } 34 | 35 | #if 0 36 | __attribute__((constructor)) static void ctor() { 37 | void *lib = dlopen("/usr/lib/libMobileGestalt.dylib", RTLD_NOW); 38 | void *MGCopyAnswer_addr = DobbySymbolResolver("libMobileGestalt.dylib", "MGCopyAnswer"); 39 | 40 | sleep(1); 41 | 42 | dobby_enable_near_trampoline(); 43 | DobbyInstrument((void *)MGCopyAnswer_addr, common_handler); 44 | dobby_disable_near_trampoline(); 45 | } 46 | #endif 47 | -------------------------------------------------------------------------------- /libs/dobby/builtin-plugin/ObjcRuntimeReplace/dobby_objc_message_hook.mm: -------------------------------------------------------------------------------- 1 | #include "dobby_objc_message_hook.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | /* clang -rewrite-objc main.m */ 8 | 9 | void DobbyHookMessageEx(const char *class_name, const char *selector_name, void *fake_impl, void **out_orig_impl) { 10 | Class class_ = objc_getClass(class_name); 11 | SEL sel_ = sel_registerName(selector_name); 12 | 13 | Method method_ = class_getInstanceMethod(class_, sel_); 14 | if (!method_) { 15 | method_ = class_getClassMethod(class_, sel_); 16 | if (!method_) { 17 | printf("Not found class: %s, selector: %s method\n", class_name, selector_name); 18 | return; 19 | } 20 | } 21 | 22 | auto orig_impl = (void *)method_setImplementation(method_, (IMP)fake_impl); 23 | if (out_orig_impl) { 24 | *out_orig_impl = orig_impl; 25 | } 26 | } 27 | 28 | void *DobbyMessageMethodResolver(const char *class_name, const char *selector_name) { 29 | Class class_ = objc_getClass(class_name); 30 | SEL sel_ = sel_registerName(selector_name); 31 | 32 | Method method_ = class_getInstanceMethod(class_, sel_); 33 | if (!method_) 34 | method_ = class_getClassMethod(class_, sel_); 35 | 36 | if (!method_) { 37 | printf("Not found class: %s, selector: %s method\n", class_name, selector_name); 38 | return nullptr; 39 | } 40 | return (void *)method_getImplementation(method_); 41 | } 42 | -------------------------------------------------------------------------------- /libs/xxHash/LICENSE: -------------------------------------------------------------------------------- 1 | xxHash Library 2 | Copyright (c) 2012-2021 Yann Collet 3 | All rights reserved. 4 | 5 | BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) 6 | 7 | Redistribution and use in source and binary forms, with or without modification, 8 | are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, this 14 | list of conditions and the following disclaimer in the documentation and/or 15 | other materials provided with the distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 21 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 24 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /libs/dobby/source/core/arch/arm/registers-arm.h: -------------------------------------------------------------------------------- 1 | #ifndef ARCH_ARM_REGISTERS 2 | #define ARCH_ARM_REGISTERS 3 | 4 | #include "core/arch/arm/constants-arm.h" 5 | #include "core/arch/Cpu.h" 6 | 7 | namespace zz { 8 | namespace arm { 9 | 10 | #define GENERAL_REGISTERS(V) \ 11 | V(r0) V(r1) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) V(r8) V(r9) V(r10) V(r11) V(r12) V(sp) V(lr) V(pc) 12 | 13 | enum RegisterCode { 14 | #define REGISTER_CODE(R) kRegCode_##R, 15 | GENERAL_REGISTERS(REGISTER_CODE) 16 | #undef REGISTER_CODE 17 | kRegAfterLast 18 | }; 19 | 20 | class Register : public RegisterBase { 21 | public: 22 | explicit constexpr Register(int code) : RegisterBase(code) { 23 | } 24 | 25 | static constexpr Register Create(int code) { 26 | return Register(code); 27 | } 28 | 29 | static constexpr Register R(int code) { 30 | return Register(code); 31 | } 32 | 33 | bool Is(const Register ®) const { 34 | return (reg.reg_id == this->reg_id); 35 | } 36 | 37 | bool IsValid() const { 38 | return (reg_id != 0); 39 | } 40 | 41 | int code() const { 42 | return reg_id; 43 | } 44 | 45 | private: 46 | }; 47 | 48 | typedef Register CPURegister; 49 | 50 | #define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R); 51 | GENERAL_REGISTERS(DECLARE_REGISTER) 52 | #undef DECLARE_REGISTER 53 | 54 | constexpr Register no_reg = Register::Create(0); 55 | 56 | } // namespace arm 57 | } // namespace zz 58 | #endif -------------------------------------------------------------------------------- /libs/dobby/source/core/assembler/assembler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/common.h" 4 | #include "pseudo_label.h" 5 | 6 | namespace zz { 7 | struct ExternalReference { 8 | void *address; 9 | 10 | explicit ExternalReference(void *address) : address(address) { 11 | address = pac_strip(address); 12 | } 13 | }; 14 | 15 | struct AssemblerBase { 16 | addr_t fixed_addr; 17 | CodeMemBuffer code_buffer_; 18 | stl::vector data_labels; 19 | 20 | explicit AssemblerBase(addr_t fixed_addr) { 21 | this->fixed_addr = fixed_addr; 22 | } 23 | 24 | ~AssemblerBase() = default; 25 | 26 | size_t pc_offset() { 27 | return code_buffer_.size(); 28 | } 29 | 30 | void set_fixed_addr(addr_t in_fixed_addr) { 31 | this->fixed_addr = in_fixed_addr; 32 | } 33 | 34 | CodeMemBuffer *code_buffer() { 35 | return &code_buffer_; 36 | } 37 | 38 | // --- label 39 | 40 | RelocDataLabel *createDataLabel(uint64_t data) { 41 | auto data_label = new RelocDataLabel(data); 42 | data_labels.push_back(data_label); 43 | return data_label; 44 | } 45 | 46 | void bindLabel(PseudoLabel *label) { 47 | label->bind_to(pc_offset()); 48 | if (label->has_confused_instructions()) { 49 | label->link_confused_instructions(&code_buffer_); 50 | } 51 | } 52 | 53 | void relocDataLabels() { 54 | for (auto *data_label : data_labels) { 55 | bindLabel(data_label); 56 | code_buffer_.emit(data_label->data_, data_label->data_size_); 57 | } 58 | } 59 | }; 60 | 61 | } // namespace zz -------------------------------------------------------------------------------- /libs/dobby/common/pac_kit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #if defined(__APPLE__) 8 | #if defined(__arm64e__) || __has_feature(ptrauth_calls) 9 | #define has_feature_ptrauth_calls 10 | #endif 11 | #endif 12 | 13 | #ifdef has_feature_ptrauth_calls 14 | #include 15 | 16 | template static inline T pac_strip(T &addr, bool keep = false) { 17 | if (addr == 0) { 18 | return 0; 19 | } 20 | if (keep) { 21 | return (T)ptrauth_strip((void *)addr, ptrauth_key_asia); 22 | } else { 23 | addr = (T)ptrauth_strip((void *)addr, ptrauth_key_asia); 24 | return addr; 25 | } 26 | return addr; 27 | } 28 | 29 | template static inline T pac_sign(T &addr, bool keep = false) { 30 | if (addr == 0) { 31 | return 0; 32 | } 33 | if (keep) { 34 | return (T)ptrauth_sign_unauthenticated((void *)addr, ptrauth_key_asia, 0); 35 | } else { 36 | addr = (T)ptrauth_sign_unauthenticated((void *)addr, ptrauth_key_asia, 0); 37 | return addr; 38 | } 39 | return addr; 40 | } 41 | 42 | template static inline T pac_strip_and_sign(T &addr) { 43 | pac_strip(addr); 44 | pac_sign(addr); 45 | return addr; 46 | } 47 | #else 48 | template static inline T pac_strip(T &addr, bool keep = false) { 49 | return addr; 50 | } 51 | 52 | template static inline T pac_sign(T &addr, bool keep = false) { 53 | return addr; 54 | } 55 | 56 | template static inline T pac_strip_and_sign(T &addr) { 57 | return addr; 58 | } 59 | #endif 60 | -------------------------------------------------------------------------------- /libs/argh/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Adi Shavit 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of nor the names of its contributors may be used to 13 | endorse or promote products derived from this software without specific 14 | prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /src/jet/live/ICompilationUnitsParser.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | #include 6 | #include "jet/live/DataTypes.hpp" 7 | 8 | namespace jet 9 | { 10 | struct LiveContext; 11 | /** 12 | * Compilation units parser interface. 13 | */ 14 | class ICompilationUnitsParser 15 | { 16 | public: 17 | virtual ~ICompilationUnitsParser() {} 18 | 19 | /** 20 | * Retrieves a vector of paths to files which should be monitored for changes. 21 | */ 22 | virtual std::vector getFilesToMonitor() const = 0; 23 | 24 | /** 25 | * Parses and returns info about all compilation units used to construct this application. 26 | * \return "cu source path" -> "compilation unit" map 27 | */ 28 | virtual std::unordered_map parseCompilationUnits(const LiveContext* context) = 0; 29 | 30 | /** 31 | * Updates compilation units list inside `context` using `filepath`, if this `filepath` is a source of 32 | * compilation units. Fills output vectors with added, modified and removed compilation units. 33 | * \return `true` if update was made, `false` if CU list was not touched. 34 | */ 35 | virtual bool updateCompilationUnits(LiveContext* context, 36 | const std::string& filepath, 37 | std::vector* addedCompilationUnits, 38 | std::vector* modifiedCompilationUnits, 39 | std::vector* removedCompilationUnits) = 0; 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /libs/efsw/src/efsw/DirWatcherGeneric.hpp: -------------------------------------------------------------------------------- 1 | #ifndef EFSW_DIRWATCHERGENERIC_HPP 2 | #define EFSW_DIRWATCHERGENERIC_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace efsw { 10 | 11 | class DirWatcherGeneric { 12 | public: 13 | typedef std::map DirWatchMap; 14 | 15 | DirWatcherGeneric* Parent; 16 | WatcherGeneric* Watch; 17 | DirectorySnapshot DirSnap; 18 | DirWatchMap Directories; 19 | bool Recursive; 20 | 21 | DirWatcherGeneric( DirWatcherGeneric* parent, WatcherGeneric* ws, const std::string& directory, 22 | bool recursive, bool reportNewFiles = false ); 23 | 24 | ~DirWatcherGeneric(); 25 | 26 | void watch( bool reportOwnChange = false ); 27 | 28 | void watchDir( std::string& dir ); 29 | 30 | static bool isDir( const std::string& directory ); 31 | 32 | bool pathInWatches( std::string path ); 33 | 34 | void addChilds( bool reportNewFiles = true ); 35 | 36 | DirWatcherGeneric* findDirWatcher( std::string dir ); 37 | 38 | DirWatcherGeneric* findDirWatcherFast( std::string dir ); 39 | 40 | protected: 41 | bool Deleted; 42 | 43 | DirWatcherGeneric* createDirectory( std::string newdir ); 44 | 45 | void removeDirectory( std::string dir ); 46 | 47 | void moveDirectory( std::string oldDir, std::string newDir ); 48 | 49 | void resetDirectory( std::string directory ); 50 | 51 | void handleAction( const std::string& filename, unsigned long action, 52 | std::string oldFilename = "" ); 53 | }; 54 | 55 | } // namespace efsw 56 | 57 | #endif 58 | --------------------------------------------------------------------------------