├── .gitignore ├── .idea ├── .gitignore ├── .name ├── compiler.xml ├── deploymentTargetDropDown.xml ├── gradle.xml ├── migrations.xml ├── misc.xml └── vcs.xml ├── app ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── pareto │ │ └── bypasskeyattestation │ │ └── ExampleInstrumentedTest.kt │ └── main │ ├── AndroidManifest.xml │ ├── cpp │ ├── CMakeLists.txt │ ├── Dobby │ │ ├── .clang-format │ │ ├── CMakeLists.txt │ │ ├── LICENSE │ │ ├── README.md │ │ ├── README_zh-cn.md │ │ ├── builtin-plugin │ │ │ ├── ApplicationEventMonitor │ │ │ │ ├── MGCopyAnswerMonitor.cc │ │ │ │ ├── dynamic_loader_monitor.cc │ │ │ │ ├── file_operation_monitor.cc │ │ │ │ ├── memory_operation_instrument.cc │ │ │ │ ├── posix_file_descriptor_operation_monitor.cc │ │ │ │ └── posix_socket_network_monitor.cc │ │ │ ├── BionicLinkerUtil │ │ │ │ ├── bionic_linker_demo.cc │ │ │ │ ├── bionic_linker_util.cc │ │ │ │ └── bionic_linker_util.h │ │ │ ├── CMakeLists.txt │ │ │ ├── ImportTableReplace │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── dobby_import_replace.cc │ │ │ │ └── dobby_import_replace.h │ │ │ ├── ObjcRuntimeReplace │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── dobby_objc_runtime_repalce.h │ │ │ │ └── dobby_objc_runtime_replace.mm │ │ │ ├── SupervisorCallMonitor │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── README │ │ │ │ ├── mach_system_call_log_handler.cc │ │ │ │ ├── misc_utility.cc │ │ │ │ ├── misc_utility.h │ │ │ │ ├── sensitive_api_monitor.cc │ │ │ │ ├── supervisor_call_monitor.cc │ │ │ │ ├── supervisor_call_monitor.h │ │ │ │ ├── system_call_log_handler.cc │ │ │ │ └── test_supervisor_call_monitor.cc │ │ │ └── SymbolResolver │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── dobby_symbol_resolver.h │ │ │ │ ├── elf │ │ │ │ └── dobby_symbol_resolver.cc │ │ │ │ ├── macho │ │ │ │ ├── dobby_symbol_resolver.cc │ │ │ │ ├── dobby_symbol_resolver_priv.h │ │ │ │ ├── macho_ctx.cc │ │ │ │ ├── macho_ctx.h │ │ │ │ ├── shared-cache │ │ │ │ │ └── dyld_cache_format.h │ │ │ │ ├── shared_cache_ctx.cpp │ │ │ │ └── shared_cache_ctx.h │ │ │ │ ├── mmap_file_util.h │ │ │ │ └── pe │ │ │ │ └── dobby_symbol_resolver.cc │ │ ├── cmake │ │ │ ├── Macros.cmake │ │ │ ├── Util.cmake │ │ │ ├── auto_source_group.cmake │ │ │ ├── build_environment_check.cmake │ │ │ ├── compiler_and_linker.cmake │ │ │ ├── dobby.xcode.source.cmake │ │ │ ├── platform │ │ │ │ └── platform-darwin.cmake │ │ │ └── xcode_generator_helper.cmake │ │ ├── docs │ │ │ └── compile.md │ │ ├── examples │ │ │ ├── CMakeLists.txt │ │ │ ├── main.cc │ │ │ └── socket_example.cc │ │ ├── external │ │ │ ├── TINYSTL │ │ │ │ ├── README │ │ │ │ ├── algorithm.h │ │ │ │ ├── allocator.h │ │ │ │ ├── buffer.h │ │ │ │ ├── hash.h │ │ │ │ ├── hash_base.h │ │ │ │ ├── new.h │ │ │ │ ├── stddef.h │ │ │ │ ├── string.h │ │ │ │ ├── string_view.h │ │ │ │ ├── traits.h │ │ │ │ ├── unordered_map.h │ │ │ │ ├── unordered_set.h │ │ │ │ └── vector.h │ │ │ ├── deprecated │ │ │ │ └── misc-helper │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── async_logger.cc │ │ │ │ │ ├── deprecated │ │ │ │ │ ├── pthread_helper.cc │ │ │ │ │ ├── pthread_helper.h │ │ │ │ │ └── unistd_helper.h │ │ │ │ │ ├── format_printer.cc │ │ │ │ │ ├── misc-helper │ │ │ │ │ ├── async_logger.h │ │ │ │ │ ├── format_printer.h │ │ │ │ │ └── variable_cache.h │ │ │ │ │ └── variable_cache.c │ │ │ ├── logging │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── kernel_logging.cc │ │ │ │ ├── logging.cc │ │ │ │ ├── logging │ │ │ │ │ ├── check_logging.h │ │ │ │ │ └── logging.h │ │ │ │ └── priv_headers │ │ │ │ │ └── _simple.h │ │ │ └── osbase │ │ │ │ └── CMakeLists.txt │ │ ├── include │ │ │ └── dobby.h │ │ ├── scripts │ │ │ ├── Dockerfile │ │ │ ├── platform_builder.py │ │ │ ├── setup_linux_cross_compile.sh │ │ │ └── setup_macos_cross_compile.sh │ │ ├── source │ │ │ ├── Backend │ │ │ │ ├── KernelMode │ │ │ │ │ ├── ExecMemory │ │ │ │ │ │ ├── clear-cache-tool-all.c │ │ │ │ │ │ └── code-patch-tool-darwin.cc │ │ │ │ │ ├── PlatformUtil │ │ │ │ │ │ ├── Darwin │ │ │ │ │ │ │ └── ProcessRuntimeUtility.cc │ │ │ │ │ │ └── ProcessRuntimeUtility.h │ │ │ │ │ └── UnifiedInterface │ │ │ │ │ │ ├── exec_mem_placeholder.asm │ │ │ │ │ │ ├── platform-darwin.cc │ │ │ │ │ │ └── platform.h │ │ │ │ └── UserMode │ │ │ │ │ ├── ExecMemory │ │ │ │ │ ├── clear-cache-tool-all.c │ │ │ │ │ ├── clear-cache-tool │ │ │ │ │ │ ├── clear-cache-tool-arm-dummy.cc │ │ │ │ │ │ └── clear-cache-tool-arm64-dummy.cc │ │ │ │ │ ├── code-patch-tool-darwin.cc │ │ │ │ │ ├── code-patch-tool-posix.cc │ │ │ │ │ ├── code-patch-tool-windows.cc │ │ │ │ │ └── substrated │ │ │ │ │ │ └── mach_interface_support │ │ │ │ │ │ └── substrated.defs │ │ │ │ │ ├── MultiThreadSupport │ │ │ │ │ ├── ThreadSupport.cpp │ │ │ │ │ └── ThreadSupport.h │ │ │ │ │ ├── PlatformUtil │ │ │ │ │ ├── Darwin │ │ │ │ │ │ └── ProcessRuntimeUtility.cc │ │ │ │ │ ├── Linux │ │ │ │ │ │ └── ProcessRuntimeUtility.cc │ │ │ │ │ ├── ProcessRuntimeUtility.h │ │ │ │ │ └── Windows │ │ │ │ │ │ └── ProcessRuntimeUtility.cc │ │ │ │ │ ├── Thread │ │ │ │ │ ├── PlatformThread.cc │ │ │ │ │ ├── PlatformThread.h │ │ │ │ │ ├── platform-thread-posix.cc │ │ │ │ │ └── platform-thread-windows.cc │ │ │ │ │ └── UnifiedInterface │ │ │ │ │ ├── platform-darwin │ │ │ │ │ └── mach_vm.h │ │ │ │ │ ├── platform-posix.cc │ │ │ │ │ ├── platform-windows.cc │ │ │ │ │ ├── platform.h │ │ │ │ │ ├── semaphore.cc │ │ │ │ │ └── semaphore.h │ │ │ ├── InstructionRelocation │ │ │ │ ├── InstructionRelocation.h │ │ │ │ ├── arm │ │ │ │ │ ├── InstructionRelocationARM.cc │ │ │ │ │ └── InstructionRelocationARM.h │ │ │ │ ├── arm64 │ │ │ │ │ ├── InstructionRelocationARM64.cc │ │ │ │ │ ├── InstructionRelocationARM64.h │ │ │ │ │ ├── inst_constants.h │ │ │ │ │ └── inst_decode_encode_kit.h │ │ │ │ ├── x64 │ │ │ │ │ ├── InstructionRelocationX64.cc │ │ │ │ │ └── InstructionRelocationX64.h │ │ │ │ └── x86 │ │ │ │ │ ├── InstructionRelocationX86.cc │ │ │ │ │ ├── InstructionRelocationX86.h │ │ │ │ │ ├── InstructionRelocationX86Shared.cc │ │ │ │ │ ├── InstructionRelocationX86Shared.h │ │ │ │ │ ├── deprecated │ │ │ │ │ ├── Ia32Disassembler.cc │ │ │ │ │ ├── X86OpcodoDecodeTable.cc │ │ │ │ │ └── X86OpcodoDecodeTable.h │ │ │ │ │ └── x86_insn_decode │ │ │ │ │ ├── build_config.h │ │ │ │ │ ├── x86_insn_decode.c │ │ │ │ │ ├── x86_insn_decode.h │ │ │ │ │ ├── x86_insn_reader.c │ │ │ │ │ ├── x86_opcode_modrm_reg_group.c │ │ │ │ │ ├── x86_opcode_one_byte.c │ │ │ │ │ ├── x86_opcode_sse_group.c │ │ │ │ │ └── x86_opcode_two_byte.c │ │ │ ├── InterceptEntry.cpp │ │ │ ├── InterceptEntry.h │ │ │ ├── InterceptRouting │ │ │ │ ├── InterceptRouting.cpp │ │ │ │ ├── InterceptRouting.h │ │ │ │ ├── Routing │ │ │ │ │ ├── FunctionInlineHook │ │ │ │ │ │ ├── FunctionInlineHook.cc │ │ │ │ │ │ ├── FunctionInlineHookRouting.h │ │ │ │ │ │ └── RoutingImpl.cc │ │ │ │ │ ├── FunctionWrapper │ │ │ │ │ │ ├── FunctionWrapperExport.cc │ │ │ │ │ │ ├── function-wrapper.cc │ │ │ │ │ │ ├── function-wrapper.h │ │ │ │ │ │ ├── intercept_routing_handler.cc │ │ │ │ │ │ └── intercept_routing_handler.h │ │ │ │ │ └── InstructionInstrument │ │ │ │ │ │ ├── InstructionInstrument.cc │ │ │ │ │ │ ├── InstructionInstrumentRouting.h │ │ │ │ │ │ ├── RoutingImpl.cc │ │ │ │ │ │ ├── instrument_routing_handler.cc │ │ │ │ │ │ └── instrument_routing_handler.h │ │ │ │ └── RoutingPlugin │ │ │ │ │ ├── NearBranchTrampoline │ │ │ │ │ ├── NearBranchTrampoline.cc │ │ │ │ │ ├── NearBranchTrampoline.h │ │ │ │ │ └── near_trampoline_arm64.cc │ │ │ │ │ ├── RoutingPlugin.cc │ │ │ │ │ └── RoutingPlugin.h │ │ │ ├── Interceptor.cpp │ │ │ ├── Interceptor.h │ │ │ ├── MemoryAllocator │ │ │ │ ├── AssemblyCodeBuilder.cc │ │ │ │ ├── AssemblyCodeBuilder.h │ │ │ │ ├── CodeBuffer │ │ │ │ │ ├── CodeBufferBase.cc │ │ │ │ │ ├── CodeBufferBase.h │ │ │ │ │ ├── code-buffer-arm.h │ │ │ │ │ ├── code-buffer-arm64.h │ │ │ │ │ ├── code-buffer-x64.h │ │ │ │ │ ├── code-buffer-x86.cc │ │ │ │ │ ├── code-buffer-x86.h │ │ │ │ │ ├── code_buffer_arm.h │ │ │ │ │ ├── code_buffer_arm64.h │ │ │ │ │ ├── code_buffer_x64.h │ │ │ │ │ └── code_buffer_x86.h │ │ │ │ ├── MemoryAllocator.cc │ │ │ │ ├── NearMemoryAllocator.cc │ │ │ │ └── NearMemoryAllocator.h │ │ │ ├── PlatformUnifiedInterface │ │ │ │ ├── ExecMemory │ │ │ │ │ ├── ClearCacheTool.h │ │ │ │ │ └── CodePatchTool.h │ │ │ │ └── MemoryAllocator.h │ │ │ ├── TrampolineBridge │ │ │ │ ├── ClosureTrampolineBridge │ │ │ │ │ ├── ClosureTrampoline.h │ │ │ │ │ ├── arm │ │ │ │ │ │ ├── ClosureTrampolineARM.cc │ │ │ │ │ │ ├── closure_bridge_arm.cc │ │ │ │ │ │ ├── dummy │ │ │ │ │ │ │ ├── closure-bridge-template-arm.cc │ │ │ │ │ │ │ └── closure-trampoline-template-arm.S │ │ │ │ │ │ └── helper_arm.cc │ │ │ │ │ ├── arm64 │ │ │ │ │ │ ├── ClosureTrampolineARM64.cc │ │ │ │ │ │ ├── closure_bridge_arm64.cc │ │ │ │ │ │ ├── dummy │ │ │ │ │ │ │ ├── closure-bridge-template-arm64.c │ │ │ │ │ │ │ ├── closure-trampoline-template-arm64.S │ │ │ │ │ │ │ └── dynamic-closure-trampoline-template-arm64.S │ │ │ │ │ │ └── helper_arm64.cc │ │ │ │ │ ├── common_bridge_handler.cc │ │ │ │ │ ├── common_bridge_handler.h │ │ │ │ │ ├── x64 │ │ │ │ │ │ ├── ClosureTrampolineX64.cc │ │ │ │ │ │ ├── closure_bridge_x64.cc │ │ │ │ │ │ ├── dummy │ │ │ │ │ │ │ ├── closure-bridge-template-x64.c │ │ │ │ │ │ │ └── closure-trampoline-template-x64.S │ │ │ │ │ │ └── helper_x64.cc │ │ │ │ │ └── x86 │ │ │ │ │ │ ├── ClosureTrampolineX86.cc │ │ │ │ │ │ ├── closure_bridge_x86.cc │ │ │ │ │ │ └── helper_x86.cc │ │ │ │ └── Trampoline │ │ │ │ │ ├── Trampoline.h │ │ │ │ │ ├── arm │ │ │ │ │ └── trampoline_arm.cc │ │ │ │ │ ├── arm64 │ │ │ │ │ └── trampoline_arm64.cc │ │ │ │ │ ├── x64 │ │ │ │ │ └── trampoline_x64.cc │ │ │ │ │ └── x86 │ │ │ │ │ └── trampoline_x86.cc │ │ │ ├── core │ │ │ │ ├── arch │ │ │ │ │ ├── Cpu.cc │ │ │ │ │ ├── Cpu.h │ │ │ │ │ ├── CpuFeature.cc │ │ │ │ │ ├── CpuFeature.h │ │ │ │ │ ├── CpuRegister.cc │ │ │ │ │ ├── CpuRegister.h │ │ │ │ │ ├── CpuUtils.h │ │ │ │ │ ├── arm │ │ │ │ │ │ ├── constants-arm.h │ │ │ │ │ │ └── registers-arm.h │ │ │ │ │ ├── arm64 │ │ │ │ │ │ ├── constants-arm64.h │ │ │ │ │ │ └── registers-arm64.h │ │ │ │ │ ├── x64 │ │ │ │ │ │ ├── constants-x64.h │ │ │ │ │ │ └── registers-x64.h │ │ │ │ │ └── x86 │ │ │ │ │ │ ├── constants-x86.h │ │ │ │ │ │ ├── cpu-x86.cc │ │ │ │ │ │ ├── cpu-x86.h │ │ │ │ │ │ └── registers-x86.h │ │ │ │ ├── assembler │ │ │ │ │ ├── AssemblerPseudoLabel.h │ │ │ │ │ ├── assembler-arch.h │ │ │ │ │ ├── assembler-arm.cc │ │ │ │ │ ├── assembler-arm.h │ │ │ │ │ ├── assembler-arm64.cc │ │ │ │ │ ├── assembler-arm64.h │ │ │ │ │ ├── assembler-ia32.cc │ │ │ │ │ ├── assembler-ia32.h │ │ │ │ │ ├── assembler-x64.cc │ │ │ │ │ ├── assembler-x64.h │ │ │ │ │ ├── assembler-x86-shared.cc │ │ │ │ │ ├── assembler-x86-shared.h │ │ │ │ │ ├── assembler.cc │ │ │ │ │ └── assembler.h │ │ │ │ ├── codegen │ │ │ │ │ ├── codegen-arm.cc │ │ │ │ │ ├── codegen-arm.h │ │ │ │ │ ├── codegen-arm64.cc │ │ │ │ │ ├── codegen-arm64.h │ │ │ │ │ ├── codegen-ia32.cc │ │ │ │ │ ├── codegen-ia32.h │ │ │ │ │ ├── codegen-x64.cc │ │ │ │ │ ├── codegen-x64.h │ │ │ │ │ └── codegen.h │ │ │ │ └── emulator │ │ │ │ │ └── dummy.cc │ │ │ ├── dobby.cpp │ │ │ └── dobby │ │ │ │ ├── common.h │ │ │ │ ├── dobby_internal.h │ │ │ │ ├── kernel_mode_header.h │ │ │ │ ├── pac_kit.h │ │ │ │ ├── platform_detect_macro.h │ │ │ │ ├── platform_features.h │ │ │ │ ├── types.h │ │ │ │ └── utility_macro.h │ │ └── tests │ │ │ ├── CMakeLists.txt │ │ │ ├── UniconEmulator.cpp │ │ │ ├── UniconEmulator.h │ │ │ ├── test_insn_decoder_x86.cpp │ │ │ ├── test_insn_relo_arm.cpp │ │ │ ├── test_insn_relo_arm64.cpp │ │ │ ├── test_insn_relo_x64.cpp │ │ │ └── test_native.cpp │ ├── json.hpp │ ├── main.cpp │ └── zygisk.hpp │ └── java │ └── com │ └── pareto │ └── bypasskeyattestation │ ├── CustomKeyStoreSpi.java │ ├── CustomProvider.java │ └── EntryPoint.java ├── build.gradle.kts ├── docs ├── assets │ ├── image-20231206194441375.png │ ├── image-20231206194902623.png │ ├── image-20231206204532183.png │ ├── image-20231206204618107.png │ ├── image-20231206204803506.png │ ├── image-20231206205018254.png │ ├── image-20231206205854947.png │ ├── image-20231206210013858.png │ ├── image-20231206210101742.png │ ├── image-20231206210143247.png │ ├── image-20231206210320245.png │ ├── image-20231206210430273.png │ ├── image-20231206210517186.png │ ├── image-20231206210830493.png │ ├── image-20231207102813599.png │ ├── image-20231207102826652.png │ ├── image-20231208191506535.png │ ├── image-20231208192239640.png │ ├── image-20231208192355224.png │ ├── image-20231222202803391.png │ └── image-20231222202915406.png ├── intro.md └── other.md ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── module ├── 0.txt ├── 1.txt ├── 2.txt ├── 3.txt ├── META-INF │ └── com │ │ └── google │ │ └── android │ │ ├── update-binary │ │ └── updater-script ├── classes.dex ├── customize.sh ├── module.prop ├── pif.json ├── post-fs-data.sh ├── service.sh └── zygisk │ ├── arm64-v8a.so │ ├── armeabi-v7a.so │ ├── x86.so │ └── x86_64.so ├── module_resetprop ├── 0.txt ├── 1.txt ├── 2.txt ├── 3.txt ├── META-INF │ └── com │ │ └── google │ │ └── android │ │ ├── update-binary │ │ └── updater-script ├── bin │ ├── arm64-v8a │ │ └── resetprop │ ├── armeabi-v7a │ │ └── resetprop │ ├── x86 │ │ └── resetprop │ └── x86_64 │ │ └── resetprop ├── classes.dex ├── customize.sh ├── module.prop ├── pif.json ├── post-fs-data.sh ├── service.sh └── zygisk │ ├── arm64-v8a.so │ ├── armeabi-v7a.so │ ├── x86.so │ └── x86_64.so ├── readme.md └── settings.gradle.kts /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | bypassKeyAttestation -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/migrations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -keep class com.pareto.bypasskeyattestation.EntryPoint {public ;} 23 | -keep class com.pareto.bypasskeyattestation.CustomProvider 24 | -keep class com.pareto.bypasskeyattestation.CustomKeyStoreSpi -------------------------------------------------------------------------------- /app/src/androidTest/java/com/pareto/bypasskeyattestation/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.pareto.bypasskeyattestation 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.pareto.bypasskeyattestation", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.22.1) 2 | 3 | project("bypassKeyAttestation") 4 | 5 | find_package(cxx REQUIRED CONFIG) 6 | 7 | link_libraries(cxx::cxx) 8 | 9 | add_library(${CMAKE_PROJECT_NAME} SHARED main.cpp) 10 | 11 | add_subdirectory(Dobby) 12 | 13 | SET_OPTION(Plugin.Android.BionicLinkerUtil ON) 14 | 15 | target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE log dobby_static) -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | 3 | IndentWidth: 2 4 | TabWidth: 2 5 | UseTab: Never 6 | ColumnLimit: 120 7 | 8 | FixNamespaceComments: true 9 | 10 | # default is false 11 | #AlignConsecutiveMacros: true 12 | #AlignConsecutiveAssignments: true 13 | #AlignConsecutiveDeclarations: true 14 | 15 | # default is true 16 | ReflowComments: false 17 | SortIncludes : false 18 | AllowShortFunctionsOnASingleLine: false -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/README_zh-cn.md: -------------------------------------------------------------------------------- 1 | ## Dobby 2 | 3 | **待更新** -------------------------------------------------------------------------------- /app/src/main/cpp/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_branch_trampoline(); 43 | DobbyInstrument((void *)MGCopyAnswer_addr, common_handler); 44 | dobby_disable_near_branch_trampoline(); 45 | } 46 | #endif 47 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/memory_operation_instrument.cc: -------------------------------------------------------------------------------- 1 | #include "./dobby_monitor.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | static uintptr_t getCallFirstArg(DobbyRegisterContext *ctx) { 8 | uintptr_t result; 9 | #if defined(_M_X64) || defined(__x86_64__) 10 | #if defined(_WIN32) 11 | result = ctx->general.regs.rcx; 12 | #else 13 | result = ctx->general.regs.rdi; 14 | #endif 15 | #elif defined(__arm64__) || defined(__aarch64__) 16 | result = ctx->general.regs.x0; 17 | #elif defined(__arm__) 18 | result = ctx->general.regs.r0; 19 | #else 20 | #error "Not Support Architecture." 21 | #endif 22 | return result; 23 | } 24 | 25 | void format_integer_manually(char *buf, uint64_t integer) { 26 | int tmp = 0; 27 | for (tmp = (int)integer; tmp > 0; tmp = (tmp >> 4)) { 28 | buf += (tmp % 16); 29 | buf--; 30 | } 31 | } 32 | 33 | // [ATTENTION]: 34 | // printf will call 'malloc' internally, and will crash in a loop. 35 | // so, use 'puts' is a better choice. 36 | void malloc_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { 37 | size_t size_ = 0; 38 | size_ = getCallFirstArg(ctx); 39 | char *buffer_ = (char *)"[-] function malloc first arg: 0x00000000.\n"; 40 | format_integer_manually(strchr(buffer_, '.') - 1, size_); 41 | puts(buffer_); 42 | } 43 | 44 | void free_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { 45 | uintptr_t mem_ptr; 46 | 47 | mem_ptr = getCallFirstArg(ctx); 48 | 49 | char *buffer = (char *)"[-] function free first arg: 0x00000000.\n"; 50 | format_integer_manually(strchr(buffer, '.') - 1, mem_ptr); 51 | puts(buffer); 52 | } 53 | 54 | __attribute__((constructor)) static void ctor() { 55 | // DobbyInstrument((void *)mmap, malloc_handler); 56 | // DobbyInstrument((void *)free, free_handler); 57 | return; 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_socket_network_monitor.cc: -------------------------------------------------------------------------------- 1 | #include /* getenv */ 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | std::unordered_map posix_socket_file_descriptors; 16 | 17 | int (*orig_bind)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 18 | int fake_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { 19 | } 20 | 21 | static const char *get_traced_socket(int fd, bool removed) { 22 | std::unordered_map::iterator it; 23 | it = posix_socket_file_descriptors.find(fd); 24 | if (it != posix_socket_file_descriptors.end()) { 25 | if (removed) 26 | posix_socket_file_descriptors.erase(it); 27 | return it->second; 28 | } 29 | return NULL; 30 | } 31 | 32 | int (*orig_connect)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 33 | int fake_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { 34 | const char *traced_socket = get_traced_socket(sockfd, false); 35 | if (traced_socket) { 36 | INFO_LOG("[-] connect: %s\n", traced_socket); 37 | } 38 | return orig_connect(sockfd, addr, addrlen); 39 | } 40 | 41 | ssize_t (*orig_send)(int sockfd, const void *buf, size_t len, int flags); 42 | ssize_t fake_send(int sockfd, const void *buf, size_t len, int flags) { 43 | const char *traced_socket = get_traced_socket(sockfd, false); 44 | if (traced_socket) { 45 | INFO_LOG("[-] send: %s, buf: %p, len: %zu\n", traced_socket, buf, len); 46 | } 47 | return orig_send(sockfd, buf, len, flags); 48 | } 49 | 50 | ssize_t (*orig_recv)(int sockfd, void *buf, size_t len, int flags); 51 | ssize_t fake_recv(int sockfd, void *buf, size_t len, int flags) { 52 | const char *traced_socket = get_traced_socket(sockfd, false); 53 | if (traced_socket) { 54 | INFO_LOG("[-] recv: %s, buf: %p, len: %zu\n", traced_socket, buf, len); 55 | } 56 | return orig_recv(sockfd, buf, len, flags); 57 | } -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/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 () -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(dobby_import_replace INTERFACE 2 | dobby_import_replace.cc 3 | ) -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(objc_runtime_replace 2 | dobby_objc_runtime_replace.mm 3 | ) 4 | 5 | target_link_libraries(objc_runtime_replace 6 | "-framework Foundation" 7 | ) -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/dobby_objc_runtime_repalce.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | IMP DobbyObjcReplace(Class _class, SEL _selector, IMP replacement); 11 | 12 | void DobbyObjcReplaceEx(const char *class_name, const char *selector_name, void *fake_impl, void **orig_impl); 13 | 14 | void *DobbyObjcResolveMethodImp(const char *class_name, const char *selector_name); 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/dobby_objc_runtime_replace.mm: -------------------------------------------------------------------------------- 1 | #include "dobby_objc_runtime_repalce.h" 2 | 3 | #include 4 | #include 5 | 6 | /* clang -rewrite-objc main.m */ 7 | 8 | IMP DobbyObjcReplace(Class class_, SEL sel_, IMP fake_impl) { 9 | Method method_ = class_getInstanceMethod(class_, sel_); 10 | if (!method_) 11 | method_ = class_getClassMethod(class_, sel_); 12 | 13 | if (!method_) { 14 | // DEBUG_LOG("Not found class: %s, selector: %s method\n", class_getName(class_), sel_getName(sel_)); 15 | return NULL; 16 | } 17 | 18 | return method_setImplementation(method_, (IMP)fake_impl); 19 | } 20 | 21 | void DobbyObjcReplaceEx(const char *class_name, const char *selector_name, void *fake_impl, void **out_orig_impl) { 22 | Class class_ = objc_getClass(class_name); 23 | SEL sel_ = sel_registerName(selector_name); 24 | 25 | Method method_ = class_getInstanceMethod(class_, sel_); 26 | if (!method_) { 27 | method_ = class_getClassMethod(class_, sel_); 28 | if (!method_) { 29 | // ERROR_LOG("Not found class: %s, selector: %s method\n", class_name, selector_name); 30 | return; 31 | } 32 | } 33 | 34 | auto orig_impl = (void *)method_setImplementation(method_, (IMP)fake_impl); 35 | if (out_orig_impl) { 36 | *out_orig_impl = orig_impl; 37 | } 38 | return; 39 | } 40 | 41 | void *DobbyObjcResolveMethodImp(const char *class_name, const char *selector_name) { 42 | Class class_ = objc_getClass(class_name); 43 | SEL sel_ = sel_registerName(selector_name); 44 | 45 | Method method_ = class_getInstanceMethod(class_, sel_); 46 | if (!method_) 47 | method_ = class_getClassMethod(class_, sel_); 48 | 49 | if (!method_) { 50 | // DEBUG_LOG("Not found class: %s, selector: %s method\n", class_name, selector_name); 51 | return NULL; 52 | } 53 | return (void *)method_getImplementation(method_); 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/README: -------------------------------------------------------------------------------- 1 | Monitor all supervisor call -------------------------------------------------------------------------------- /app/src/main/cpp/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 | } -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/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(); -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCE_FILE_LIST) 2 | 3 | if (NOT DEFINED DOBBY_DIR) 4 | message(FATAL_ERROR "DOBBY_DIR must be set!") 5 | endif () 6 | 7 | if (SYSTEM.Darwin AND (NOT DOBBY_BUILD_KERNEL_MODE)) 8 | set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} 9 | ${CMAKE_CURRENT_SOURCE_DIR}/macho/macho_ctx.cc 10 | ${CMAKE_CURRENT_SOURCE_DIR}/macho/shared_cache_ctx.cpp 11 | ${CMAKE_CURRENT_SOURCE_DIR}/macho/dobby_symbol_resolver.cc 12 | 13 | 14 | ${DOBBY_DIR}/source/Backend/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc 15 | ) 16 | endif () 17 | if (SYSTEM.Darwin AND DOBBY_BUILD_KERNEL_MODE) 18 | set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} 19 | ${CMAKE_CURRENT_SOURCE_DIR}/macho/dobby_symbol_resolver.cc 20 | 21 | ${DOBBY_DIR}/source/Backend/KernelMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc 22 | ) 23 | endif () 24 | if (SYSTEM.Linux OR SYSTEM.Android) 25 | set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} 26 | ${CMAKE_CURRENT_SOURCE_DIR}/elf/dobby_symbol_resolver.cc 27 | 28 | ${DOBBY_DIR}/source/Backend/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc 29 | ) 30 | endif () 31 | if (SYSTEM.Windows) 32 | set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} 33 | ${CMAKE_CURRENT_SOURCE_DIR}/pe/dobby_symbol_resolver.cc 34 | 35 | ${DOBBY_DIR}/source/Backend/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc 36 | ) 37 | endif () 38 | 39 | add_library(macho_ctx_kit 40 | macho/macho_ctx.h 41 | macho/macho_ctx.cc 42 | ) 43 | 44 | add_library(shared_cache_ctx_kit 45 | macho/shared_cache_ctx.h 46 | macho/shared_cache_ctx.cpp 47 | ) 48 | 49 | add_library(dobby_symbol_resolver 50 | ${SOURCE_FILE_LIST} 51 | ) 52 | 53 | 54 | include_directories( 55 | . 56 | ) 57 | 58 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver_priv.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "macho_ctx.h" 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_ctx.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "shared-cache/dyld_cache_format.h" 6 | 7 | #if defined(__LP64__) 8 | typedef struct mach_header_64 mach_header_t; 9 | typedef struct segment_command_64 segment_command_t; 10 | typedef struct section_64 section_t; 11 | typedef struct nlist_64 nlist_t; 12 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 13 | #else 14 | typedef struct mach_header mach_header_t; 15 | typedef struct segment_command segment_command_t; 16 | typedef struct section section_t; 17 | typedef struct nlist nlist_t; 18 | #define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT 19 | #endif 20 | 21 | typedef uintptr_t addr_t; 22 | 23 | typedef struct shared_cache_ctx { 24 | struct dyld_cache_header *runtime_shared_cache; 25 | struct dyld_cache_header *mmap_shared_cache; 26 | 27 | uintptr_t runtime_slide; 28 | 29 | bool latest_shared_cache_format; 30 | struct dyld_cache_local_symbols_info *local_symbols_info; 31 | struct dyld_cache_local_symbols_entry *local_symbols_entries; 32 | struct dyld_cache_local_symbols_entry_64 *local_symbols_entries_64; 33 | 34 | nlist_t *symtab; 35 | char *strtab; 36 | } shared_cache_ctx_t; 37 | 38 | int shared_cache_ctx_init(shared_cache_ctx_t *ctx); 39 | 40 | int shared_cache_load_symbols(shared_cache_ctx_t *ctx); 41 | 42 | bool shared_cache_is_contain(shared_cache_ctx_t *ctx, addr_t addr, size_t length); 43 | 44 | int shared_cache_get_symbol_table(shared_cache_ctx_t *ctx, mach_header_t *image_header, nlist_t **out_symtab, 45 | uint32_t *out_symtab_count, char **out_strtab); -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/mmap_file_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class MmapFileManager { 13 | const char *file_; 14 | uint8_t *mmap_buffer_; 15 | size_t mmap_buffer_size_; 16 | 17 | public: 18 | explicit MmapFileManager(const char *file) : file_(file), mmap_buffer_(nullptr) { 19 | } 20 | 21 | ~MmapFileManager() { 22 | if (mmap_buffer_) { 23 | munmap((void *)mmap_buffer_, mmap_buffer_size_); 24 | } 25 | } 26 | 27 | uint8_t *map() { 28 | size_t file_size = 0; 29 | { 30 | struct stat s; 31 | int rt = stat(file_, &s); 32 | if (rt != 0) { 33 | // printf("mmap %s failed\n", file_); 34 | return NULL; 35 | } 36 | file_size = s.st_size; 37 | } 38 | 39 | return map_options(file_size, 0); 40 | } 41 | 42 | uint8_t *map_options(size_t _size, off_t _off) { 43 | if (!mmap_buffer_) { 44 | int fd = open(file_, O_RDONLY, 0); 45 | if (fd < 0) { 46 | // printf("%s open failed\n", file_); 47 | return NULL; 48 | } 49 | 50 | // auto align 51 | auto mmap_buffer = (uint8_t *)mmap(0, _size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE, fd, _off); 52 | if (mmap_buffer == MAP_FAILED) { 53 | // printf("mmap %s failed\n", file_); 54 | return NULL; 55 | } 56 | 57 | close(fd); 58 | 59 | mmap_buffer_ = mmap_buffer; 60 | mmap_buffer_size_ = _size; 61 | } 62 | return mmap_buffer_; 63 | } 64 | }; 65 | -------------------------------------------------------------------------------- /app/src/main/cpp/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/ProcessRuntimeUtility.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 | } -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/cmake/Macros.cmake: -------------------------------------------------------------------------------- 1 | macro(SET_OPTION option value) 2 | set(${option} ${value} CACHE INTERNAL "" FORCE) 3 | endmacro() -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 () -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/cmake/compiler_and_linker.cmake: -------------------------------------------------------------------------------- 1 | # :< You Shall Not Pass! 2 | if (0) 3 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror") 4 | endif () 5 | 6 | set(linker_flags "") 7 | if (NOT DOBBY_DEBUG) 8 | set(linker_flags "${linker_flags} -Wl,-x -Wl,-S") 9 | endif () 10 | 11 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions") 12 | 13 | if (SYSTEM.Darwin) 14 | # set(compiler_flags "${compiler_flags} -nostdinc++") 15 | elseif (SYSTEM.Android) 16 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer") 17 | if (NOT DOBBY_DEBUG) 18 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections") 19 | set(linker_flags "${linker_flags} -Wl,--gc-sections -Wl,--exclude-libs,ALL") 20 | endif () 21 | elseif (SYSTEM.Linux) 22 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") 23 | if (COMPILER.Clang) 24 | if (PROCESSOR.ARM) 25 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=armv7-unknown-linux-gnueabihf") 26 | elseif (PROCESSOR.ARM64) 27 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=aarch64-unknown-linux-gnu") 28 | elseif (PROCESSOR.X86) 29 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=i686-unknown-linux-gnu") 30 | elseif (PROCESSOR.X86_64) 31 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=x86_64-unknown-linux-gnu") 32 | endif () 33 | endif () 34 | elseif (SYSTEM.Windows) 35 | endif () 36 | 37 | if (NOT DOBBY_DEBUG) 38 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") 39 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden") 40 | endif () 41 | 42 | if (PROCESSOR.ARM) 43 | set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch armv7 -x assembler-with-cpp") 44 | elseif (PROCESSOR.AARCH64) 45 | set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch arm64 -x assembler-with-cpp") 46 | endif () 47 | 48 | # sync cxx with c flags 49 | set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}") 50 | 51 | message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") 52 | message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") 53 | message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") 54 | message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") 55 | message(STATUS "CMAKE_SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}") 56 | -------------------------------------------------------------------------------- /app/src/main/cpp/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() -------------------------------------------------------------------------------- /app/src/main/cpp/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() -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/docs/compile.md: -------------------------------------------------------------------------------- 1 | # Build 2 | 3 | ## CMake build options 4 | 5 | ``` 6 | option(DOBBY_GENERATE_SHARED "Build shared library" ON) 7 | 8 | option(DOBBY_DEBUG "Enable debug logging" OFF) 9 | 10 | option(NearBranch "Enable near branch trampoline" ON) 11 | 12 | option(FullFloatingPointRegisterPack "Save and pack all floating-point registers" OFF) 13 | 14 | option(Plugin.SymbolResolver "Enable symbol resolver" ON) 15 | 16 | option(Plugin.ImportTableReplace "Enable import table replace " OFF) 17 | 18 | option(Plugin.Android.BionicLinkerUtil "Enable android bionic linker util" OFF) 19 | 20 | option(DOBBY_BUILD_EXAMPLE "Build example" OFF) 21 | 22 | option(DOBBY_BUILD_TEST "Build test" OFF) 23 | ``` 24 | 25 | ## Build with `scripts/platform_builder.py` 26 | 27 | #### Build for iphoneos 28 | 29 | ```shell 30 | python3 scripts/platform_builder.py --platform=iphoneos --arch=all 31 | ``` 32 | 33 | #### Build for macos 34 | 35 | ``` 36 | python3 scripts/platform_builder.py --platform=macos --arch=all 37 | ``` 38 | 39 | #### Build for linux 40 | 41 | ``` 42 | # prepare and download cmake/llvm 43 | sh scripts/setup_linux_cross_compile.sh 44 | python3 scripts/platform_builder.py --platform=linux --arch=all --cmake_dir=$HOME/opt/cmake-3.25.2 --llvm_dir=$HOME/opt/llvm-15.0.6 45 | ``` 46 | 47 | #### Build for android 48 | 49 | ``` 50 | # prepare and download cmake/llvm/ndk 51 | sh scripts/setup_linux_cross_compile.sh 52 | python3 scripts/platform_builder.py --platform=android --arch=all --cmake_dir=$HOME/opt/cmake-3.25.2 --llvm_dir=$HOME/opt/llvm-15.0.6 --android_ndk_dir=$HOME/opt/ndk-r25b 53 | ``` 54 | 55 | ## Build with CMake 56 | 57 | #### Build for host 58 | 59 | ```shell 60 | cd Dobby && mkdir cmake-build-host && cd cmake-build-host 61 | cmake .. 62 | make -j4 63 | ``` 64 | 65 | ## Build with Android Studio CMake 66 | 67 | ``` 68 | if(NOT TARGET dobby) 69 | set(DOBBY_DIR /Users/jmpews/Workspace/Project.wrk/Dobby) 70 | macro(SET_OPTION option value) 71 | set(${option} ${value} CACHE INTERNAL "" FORCE) 72 | endmacro() 73 | SET_OPTION(DOBBY_DEBUG OFF) 74 | SET_OPTION(DOBBY_GENERATE_SHARED OFF) 75 | add_subdirectory(${DOBBY_DIR} dobby) 76 | get_property(DOBBY_INCLUDE_DIRECTORIES 77 | TARGET dobby 78 | PROPERTY INCLUDE_DIRECTORIES) 79 | include_directories( 80 | . 81 | ${DOBBY_INCLUDE_DIRECTORIES} 82 | $ 83 | ) 84 | endif() 85 | 86 | add_library(native-lib SHARED 87 | ${DOBBY_DIR}/examples/socket_example.cc 88 | native-lib.cpp) 89 | ``` 90 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 | ) -------------------------------------------------------------------------------- /app/src/main/cpp/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 | } -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/TINYSTL/README: -------------------------------------------------------------------------------- 1 | ref: https://github.com/mendsley/tinystl -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/TINYSTL/algorithm.h: -------------------------------------------------------------------------------- 1 | #pragma once -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/TINYSTL/allocator.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-2018 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_ALLOCATOR_H 28 | #define TINYSTL_ALLOCATOR_H 29 | 30 | #include 31 | 32 | namespace tinystl { 33 | 34 | struct allocator { 35 | static void* static_allocate(size_t bytes) { 36 | return operator new(bytes); 37 | } 38 | 39 | static void static_deallocate(void* ptr, size_t /*bytes*/) { 40 | operator delete(ptr); 41 | } 42 | }; 43 | } 44 | 45 | #ifndef TINYSTL_ALLOCATOR 46 | # define TINYSTL_ALLOCATOR ::tinystl::allocator 47 | #endif 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/TINYSTL/hash.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-2018 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_STRINGHASH_H 28 | #define TINYSTL_STRINGHASH_H 29 | 30 | #include 31 | 32 | namespace tinystl { 33 | 34 | static inline size_t hash_string(const char* str, size_t len) { 35 | // Implementation of sdbm a public domain string hash from Ozan Yigit 36 | // see: http://www.eecs.harvard.edu/margo/papers/usenix91/paper.ps 37 | 38 | size_t hash = 0; 39 | typedef const char* pointer; 40 | for (pointer it = str, end = str + len; it != end; ++it) 41 | hash = *it + (hash << 6) + (hash << 16) - hash; 42 | 43 | return hash; 44 | } 45 | 46 | template 47 | inline size_t hash(const T& value) { 48 | const size_t asint = (size_t)value; 49 | return hash_string((const char*)&asint, sizeof(asint)); 50 | } 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/TINYSTL/new.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-2018 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_NEW_H 28 | #define TINYSTL_NEW_H 29 | 30 | #include 31 | 32 | namespace tinystl { 33 | 34 | struct placeholder {}; 35 | } 36 | 37 | inline void* operator new(size_t, tinystl::placeholder, void* ptr) { 38 | return ptr; 39 | } 40 | 41 | inline void operator delete(void*, tinystl::placeholder, void*) throw() {} 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/TINYSTL/stddef.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright 2012-2018 Matthew Endsley 3 | * All rights reserved 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted providing that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 18 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 22 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 23 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | * POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #ifndef TINYSTL_STDDEF_H 28 | #define TINYSTL_STDDEF_H 29 | 30 | #if defined(_WIN64) 31 | typedef long long unsigned int size_t; 32 | typedef long long int ptrdiff_t; 33 | #elif defined(_WIN32) 34 | typedef unsigned int size_t; 35 | typedef int ptrdiff_t; 36 | #elif defined (__linux__) && defined(__SIZE_TYPE__) && defined(__PTRDIFF_TYPE__) 37 | typedef __SIZE_TYPE__ size_t; 38 | typedef __PTRDIFF_TYPE__ ptrdiff_t; 39 | #else 40 | # include 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/deprecated/misc-helper/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(.) 2 | 3 | if(NOT DOBBY_BUILD_KERNEL_MODE) 4 | set(SOURCE_FILE_LIST 5 | ${CMAKE_CURRENT_SOURCE_DIR}/variable_cache.c 6 | ${CMAKE_CURRENT_SOURCE_DIR}/async_logger.cc 7 | ${CMAKE_CURRENT_SOURCE_DIR}/format_printer.cc 8 | ) 9 | else() 10 | set(SOURCE_FILE_LIST 11 | ${CMAKE_CURRENT_SOURCE_DIR}/format_printer.cc 12 | ) 13 | endif() 14 | 15 | add_library(misc_helper 16 | ${SOURCE_FILE_LIST} 17 | ${SOURCE_HEADER_LIST} 18 | ) -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/deprecated/misc-helper/async_logger.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define aync_logger_buffer_size (20 * 1024 * 1024) 13 | int async_logger_buffer_cursor = 0; 14 | char async_logger_buffer[aync_logger_buffer_size]; 15 | 16 | static pthread_mutex_t async_logger_mutex = PTHREAD_MUTEX_INITIALIZER; 17 | 18 | static int output_fd = -1; 19 | 20 | void async_logger_print(char *str) { 21 | pthread_mutex_lock(&async_logger_mutex); 22 | #if 0 23 | { 24 | write(STDOUT_FILENO, str, strlen(str) + 1); 25 | } 26 | #endif 27 | memcpy(async_logger_buffer + async_logger_buffer_cursor, str, strlen(str)); 28 | async_logger_buffer_cursor += strlen(str); 29 | pthread_mutex_unlock(&async_logger_mutex); 30 | return; 31 | } 32 | 33 | static void *async_logger_print_impl(void *ctx) { 34 | while (1) { 35 | pthread_mutex_lock(&async_logger_mutex); 36 | if (async_logger_buffer_cursor > 0) { 37 | write(output_fd, async_logger_buffer, async_logger_buffer_cursor); 38 | async_logger_buffer_cursor = 0; 39 | } 40 | pthread_mutex_unlock(&async_logger_mutex); 41 | sleep(1); 42 | } 43 | } 44 | 45 | void async_logger_init(char *logger_path) { 46 | static int async_logger_initialized = 0; 47 | if (async_logger_initialized) 48 | return; 49 | async_logger_initialized = 1; 50 | 51 | // init stdout write lock 52 | pthread_mutex_t write_mutex; 53 | pthread_mutex_init(&write_mutex, NULL); 54 | 55 | output_fd = STDOUT_FILENO; 56 | if (logger_path) { 57 | int fd = open(logger_path, O_CREAT | O_WRONLY | O_TRUNC, 0644); 58 | output_fd = fd; 59 | } 60 | 61 | // init async logger 62 | pthread_mutex_init(&async_logger_mutex, NULL); 63 | pthread_t async_logger_thread; 64 | int ret = pthread_create(&async_logger_thread, NULL, async_logger_print_impl, NULL); 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * light weight pthread compatible library for Windows 3 | * (C) 2009 Okamura Yasunobu 4 | * 5 | * WARNING This library does NOT support all future of pthread 6 | * 7 | */ 8 | 9 | #ifndef CROSS_THREAD_H 10 | #define CROSS_THREAD_H 11 | 12 | #ifdef _WIN32 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | typedef struct pthread_tag { 23 | HANDLE handle; 24 | } pthread_t; 25 | 26 | typedef struct pthread_mutex_tag { 27 | HANDLE handle; 28 | } pthread_mutex_t; 29 | 30 | /* stub */ 31 | typedef struct pthread_attr_tag { 32 | int attr; 33 | } pthread_attr_t; 34 | 35 | typedef struct pthread_mutexattr_tag { 36 | int attr; 37 | } pthread_mutexattr_t; 38 | 39 | typedef DWORD pthread_key_t; 40 | 41 | /* ignore attribute */ 42 | int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); 43 | 44 | /* ignore value_ptr */ 45 | void pthread_exit(void *value_ptr); 46 | 47 | /* ignore value_ptr */ 48 | int pthread_join(pthread_t thread, void **value_ptr); 49 | 50 | pthread_t pthread_self(void); 51 | 52 | /* do nothing */ 53 | int pthread_detach(pthread_t thread); 54 | 55 | /* DO NOT USE */ 56 | int pthread_cancel(pthread_t thread); 57 | 58 | int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); /* do nothing */ 59 | int pthread_mutexattr_init(pthread_mutexattr_t *attr); /* do nothing */ 60 | 61 | int pthread_mutex_destroy(pthread_mutex_t *mutex); 62 | int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); 63 | int pthread_mutex_lock(pthread_mutex_t *mutex); 64 | int pthread_mutex_trylock(pthread_mutex_t *mutex); 65 | int pthread_mutex_unlock(pthread_mutex_t *mutex); 66 | 67 | /* ignore deconstructor */ 68 | int pthread_key_create(pthread_key_t *key, void (*destr_function)(void *)); 69 | int pthread_key_delete(pthread_key_t key); 70 | int pthread_setspecific(pthread_key_t key, const void *pointer); 71 | void *pthread_getspecific(pthread_key_t key); 72 | 73 | #define sleep(num) Sleep(1000 * (num)) 74 | 75 | #ifdef __cplusplus 76 | } 77 | #endif 78 | 79 | #else 80 | #include 81 | #include 82 | #define Sleep(num) usleep(num * 1000) 83 | #endif 84 | 85 | #endif /* CROSS_THREAD_H */ 86 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/unistd_helper.h: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | 3 | #include 4 | #define open _open 5 | #define read _read 6 | #define O_RDONLY _O_RDONLY 7 | #define O_WRONLY _O_WRONLY 8 | #define O_CREAT _O_CREAT 9 | #define O_TRUNC _O_TRUNC 10 | 11 | #define ssize_t int 12 | 13 | #define STDIN_FILENO 0 14 | #define STDOUT_FILENO 1 15 | #define STDERR_FILENO 2 16 | /* should be in some equivalent to */ 17 | typedef __int8 int8_t; 18 | typedef __int16 int16_t; 19 | typedef __int32 int32_t; 20 | typedef __int64 int64_t; 21 | typedef unsigned __int8 uint8_t; 22 | typedef unsigned __int16 uint16_t; 23 | typedef unsigned __int32 uint32_t; 24 | typedef unsigned __int64 uint64_t; 25 | 26 | #else 27 | 28 | #include 29 | 30 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/deprecated/misc-helper/format_printer.cc: -------------------------------------------------------------------------------- 1 | #include "misc-helper/format_printer.h" 2 | 3 | void hexdump(const uint8_t *bytes, size_t len) { 4 | size_t ix; 5 | for (ix = 0; ix < len; ++ix) { 6 | if (ix != 0 && !(ix % 16)) 7 | LOG_FUNCTION_IMPL(0, "\n"); 8 | LOG_FUNCTION_IMPL(0, "%02X ", bytes[ix]); 9 | } 10 | LOG_FUNCTION_IMPL(0, "\n"); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/async_logger.h: -------------------------------------------------------------------------------- 1 | #ifndef ASYNC_LOGGER_H 2 | #define ASYNC_LOGGER_H 3 | 4 | void async_logger_print(char *str); 5 | 6 | void async_logger_init(char *logger_path); 7 | 8 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/format_printer.h: -------------------------------------------------------------------------------- 1 | #include "dobby/common.h" 2 | 3 | void hexdump(const uint8_t *bytes, size_t len); -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/variable_cache.h: -------------------------------------------------------------------------------- 1 | #ifndef VARIABLE_CACHE_H 2 | #define VARIABLE_CACHE_H 3 | 4 | #include 5 | 6 | #define cache_set stash 7 | void cache_set(const char *name, uint64_t value); 8 | 9 | #define cache_get(x) cache(x) 10 | #define assert_cache(x) (assert(cache(x)), cache(x)) 11 | uint64_t cache_get(const char *name); 12 | 13 | int serialized_to_file(const char *filepath); 14 | 15 | int unserialized_from_file(const char *filepath); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/logging/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(.) 2 | 3 | if(NOT DOBBY_BUILD_KERNEL_MODE) 4 | set(SOURCE_FILE_LIST 5 | ${CMAKE_CURRENT_SOURCE_DIR}/logging.cc 6 | ) 7 | else() 8 | set(SOURCE_FILE_LIST 9 | ${CMAKE_CURRENT_SOURCE_DIR}/kernel_logging.cc 10 | ) 11 | endif() 12 | add_library(logging 13 | ${SOURCE_FILE_LIST} 14 | ${SOURCE_HEADER_LIST} 15 | ) -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/logging/kernel_logging.cc: -------------------------------------------------------------------------------- 1 | #include "logging/logging.h" 2 | 3 | #include 4 | #include "utility_macro.h" 5 | 6 | #if defined(BUILDING_KERNEL) 7 | #define abort() 8 | #else 9 | #include 10 | #endif 11 | 12 | static int _log_level = 1; 13 | PUBLIC void log_set_level(int level) { 14 | _log_level = level; 15 | } 16 | 17 | PUBLIC int log_internal_impl(int level, const char *fmt, ...) { 18 | if (level < _log_level) 19 | return 0; 20 | 21 | va_list ap; 22 | va_start(ap, fmt); 23 | 24 | vprintf(fmt, ap); 25 | 26 | va_end(ap); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/external/osbase/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(osbase STATIC 2 | ${PROJECT_SOURCE_DIR}/source/Backend/UserMode/UnifiedInterface/platform-posix.cc 3 | ) -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/scripts/setup_linux_cross_compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -x 4 | set -e 5 | 6 | # sudo dpkg --add-architecture armhf 7 | # sudo dpkg --add-architecture i386 8 | # sudo dpkg --add-architecture arm64 9 | # sudo apt-get -y update 10 | # sudo apt-get -y dist-upgrade 11 | # sudo apt-get -y install git build-essential libssl-dev pkg-config unzip gcc-multilib 12 | # sudo apt-get -y install libc6-armhf-cross libc6-dev-armhf-cross gcc-arm-linux-gnueabihf libssl-dev:armhf 13 | # sudo apt-get -y install libc6-i386-cross libc6-dev-i386-cross gcc-i686-linux-gnu libssl-dev:i386 14 | # sudo apt-get -y install libc6-arm64-cross libc6-dev-arm64-cross gcc-aarch64-linux-gnu libssl-dev:arm64 15 | 16 | sudo apt-get -y update 17 | sudo apt-get -y install aptitude 18 | sudo apt-get -f -y install \ 19 | apt-utils \ 20 | binutils \ 21 | build-essential \ 22 | curl \ 23 | wget \ 24 | unzip \ 25 | gcc-multilib \ 26 | g++-multilib \ 27 | make \ 28 | zsh 29 | 30 | sudo apt-get -f -y install gcc g++ libc6-dev 31 | sudo apt-get -f -y install gcc-i686-linux-gnu g++-i686-linux-gnu 32 | sudo apt-get -f -y install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf 33 | sudo apt-get -f -y install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu 34 | 35 | mkdir -p ~/opt 36 | 37 | cd ~/opt 38 | CMAKE_VERSION=3.25.2 39 | CMAKE_DOWNLOAD_PACKAGE=cmake-$CMAKE_VERSION-linux-x86_64 40 | wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/$CMAKE_DOWNLOAD_PACKAGE.tar.gz && 41 | tar -zxf $CMAKE_DOWNLOAD_PACKAGE.tar.gz >/dev/null && 42 | mv $CMAKE_DOWNLOAD_PACKAGE cmake-$CMAKE_VERSION 43 | CMAKE_HOME=~/opt/cmake-$CMAKE_VERSION 44 | 45 | cd ~/opt 46 | LLVM_VERSION=15.0.6 47 | LLVM_DOWNLOAD_PACKAGE=clang+llvm-$LLVM_VERSION-x86_64-linux-gnu-ubuntu-18.04 48 | wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/$LLVM_DOWNLOAD_PACKAGE.tar.xz && 49 | tar -xf $LLVM_DOWNLOAD_PACKAGE.tar.xz >/dev/null && 50 | mv $LLVM_DOWNLOAD_PACKAGE llvm-$LLVM_VERSION 51 | LLVM_HOME=~/opt/llvm-$LLVM_VERSION 52 | 53 | cd ~/opt 54 | NDK_VERSION=r25b 55 | NDK_DOWNLOAD_PACKAGE=android-ndk-$NDK_VERSION-linux 56 | NDK_DOWNLOAD_UNZIP_PACKAGE=android-ndk-$NDK_VERSION 57 | wget https://dl.google.com/android/repository/$NDK_DOWNLOAD_PACKAGE.zip && 58 | unzip -q $NDK_DOWNLOAD_PACKAGE.zip >/dev/null && 59 | mv $NDK_DOWNLOAD_UNZIP_PACKAGE ndk-$NDK_VERSION && 60 | rm $NDK_DOWNLOAD_PACKAGE.zip 61 | ANDROID_NDK_HOME=~/opt/android-ndk-$NDK_VERSION 62 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/clear-cache-tool-all.c: -------------------------------------------------------------------------------- 1 | void ClearCache(void *start, void *end) { 2 | return; 3 | } 4 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/Backend/KernelMode/PlatformUtil/ProcessRuntimeUtility.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PlatformUnifiedInterface/MemoryAllocator.h" 4 | 5 | #include "UnifiedInterface/platform.h" 6 | 7 | typedef struct _RuntimeModule { 8 | char path[1024]; 9 | void *load_address; 10 | } RuntimeModule; 11 | 12 | struct MemRegion : MemRange { 13 | MemoryPermission permission; 14 | MemRegion(addr_t addr, size_t size, MemoryPermission perm) : MemRange(addr, size), permission(perm) { 15 | } 16 | }; 17 | 18 | class ProcessRuntimeUtility { 19 | public: 20 | static const tinystl::vector &GetProcessMemoryLayout(); 21 | 22 | static const tinystl::vector *GetProcessModuleMap(); 23 | 24 | static RuntimeModule GetProcessModule(const char *name); 25 | }; -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/exec_mem_placeholder.asm: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define PAGE_SHIFT 14 4 | .align PAGE_SHIFT 5 | 6 | .globl EXT(kernel_executable_memory_placeholder) 7 | EXT(kernel_executable_memory_placeholder): 8 | .rept 0x4000/4 9 | .long 0x41414141 10 | .endr -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/platform.h: -------------------------------------------------------------------------------- 1 | #ifndef PLATFORM_INTERFACE_COMMON_PLATFORM_H 2 | #define PLATFORM_INTERFACE_COMMON_PLATFORM_H 3 | 4 | #include "dobby/common.h" 5 | 6 | // ================================================================ 7 | // base :: OSMemory 8 | 9 | enum MemoryPermission { kNoAccess, kRead, kReadWrite, kReadWriteExecute, kReadExecute }; 10 | 11 | class OSMemory { 12 | public: 13 | static int PageSize(); 14 | 15 | static void *Allocate(size_t size, MemoryPermission access); 16 | 17 | static void *Allocate(size_t size, MemoryPermission access, void *fixed_address); 18 | 19 | static bool Free(void *address, size_t size); 20 | 21 | static bool Release(void *address, size_t size); 22 | 23 | static bool SetPermission(void *address, size_t size, MemoryPermission access); 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm-dummy.cc: -------------------------------------------------------------------------------- 1 | #ifndef USER_MODE_CLEAR_CACHE_TOOL_H 2 | #define USER_MODE_CLEAR_CACHE_TOOL_H 3 | 4 | #include "core/arch/Cpu.h" 5 | 6 | #include "PlatformInterface/globals.h" 7 | 8 | #if !HOST_OS_IOS 9 | #include // for cache flushing. 10 | #endif 11 | 12 | void CpuFeatures::FlushICache(void *startp, void *endp) { 13 | 14 | #if HOST_OS_IOS 15 | // Precompilation never patches code so there should be no I cache flushes. 16 | CpuFeatures::ClearCache(startp, endp); 17 | 18 | #else 19 | 20 | register uint32_t beg asm("r0") = reinterpret_cast(startp); 21 | register uint32_t end asm("r1") = reinterpret_cast(endp); 22 | register uint32_t flg asm("r2") = 0; 23 | 24 | #ifdef __clang__ 25 | // This variant of the asm avoids a constant pool entry, which can be 26 | // problematic when LTO'ing. It is also slightly shorter. 27 | register uint32_t scno asm("r7") = __ARM_NR_cacheflush; 28 | 29 | asm volatile("svc 0\n" : : "r"(beg), "r"(end), "r"(flg), "r"(scno) : "memory"); 30 | #else 31 | // Use a different variant of the asm with GCC because some versions doesn't 32 | // support r7 as an asm input. 33 | asm volatile( 34 | // This assembly works for both ARM and Thumb targets. 35 | 36 | // Preserve r7; it is callee-saved, and GCC uses it as a frame pointer for 37 | // Thumb targets. 38 | " push {r7}\n" 39 | // r0 = beg 40 | // r1 = end 41 | // r2 = flags (0) 42 | " ldr r7, =%c[scno]\n" // r7 = syscall number 43 | " svc 0\n" 44 | 45 | " pop {r7}\n" 46 | : 47 | : "r"(beg), "r"(end), "r"(flg), [scno] "i"(__ARM_NR_cacheflush) 48 | : "memory"); 49 | #endif 50 | #endif 51 | } 52 | 53 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-posix.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "dobby/dobby_internal.h" 3 | #include "core/arch/Cpu.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #if !defined(__APPLE__) 10 | PUBLIC int DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { 11 | #if defined(__ANDROID__) || defined(__linux__) 12 | int page_size = (int)sysconf(_SC_PAGESIZE); 13 | uintptr_t patch_page = ALIGN_FLOOR(address, page_size); 14 | uintptr_t patch_end_page = ALIGN_FLOOR((uintptr_t)address + buffer_size, page_size); 15 | 16 | // change page permission as rwx 17 | mprotect((void *)patch_page, page_size, PROT_READ | PROT_WRITE | PROT_EXEC); 18 | if (patch_page != patch_end_page) { 19 | mprotect((void *)patch_end_page, page_size, PROT_READ | PROT_WRITE | PROT_EXEC); 20 | } 21 | 22 | // patch buffer 23 | memcpy(address, buffer, buffer_size); 24 | 25 | // restore page permission 26 | mprotect((void *)patch_page, page_size, PROT_READ | PROT_EXEC); 27 | if (patch_page != patch_end_page) { 28 | mprotect((void *)patch_end_page, page_size, PROT_READ | PROT_EXEC); 29 | } 30 | 31 | addr_t clear_start_ = (addr_t)address; 32 | ClearCache((void *)clear_start_, (void *)(clear_start_ + buffer_size)); 33 | #endif 34 | return 0; 35 | } 36 | 37 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.h: -------------------------------------------------------------------------------- 1 | #ifndef USER_MODE_MULTI_THREAD_SUPPORT_H 2 | #define USER_MODE_MULTI_THREAD_SUPPORT_H 3 | 4 | #include 5 | #include 6 | 7 | #include "dobby/dobby_internal.h" 8 | 9 | #include "source/Backend/UserMode/Thread/PlatformThread.h" 10 | 11 | // StackFrame base in CallStack 12 | typedef struct _StackFrame { 13 | // context between `pre_call` and `post_call` 14 | std::map kv_context; 15 | // origin function ret address 16 | void *orig_ret; 17 | } StackFrame; 18 | 19 | // (thead) CallStack base in thread 20 | typedef struct _CallStack { 21 | tinystl::vector stackframes; 22 | } CallStack; 23 | 24 | // ThreadSupport base on vm_core, support mutipl platforms. 25 | class ThreadSupport { 26 | public: 27 | // Push stack frame 28 | static void PushStackFrame(StackFrame *stackframe) { 29 | CallStack *callstack = ThreadSupport::CurrentThreadCallStack(); 30 | callstack->stackframes.push_back(stackframe); 31 | } 32 | 33 | // Pop stack frame 34 | static StackFrame *PopStackFrame() { 35 | CallStack *callstack = ThreadSupport::CurrentThreadCallStack(); 36 | StackFrame *stackframe = callstack->stackframes.back(); 37 | callstack->stackframes.pop_back(); 38 | return stackframe; 39 | } 40 | 41 | // ===== 42 | static void SetStackFrameContextValue(StackFrame *stackframe, char *key, void *value) { 43 | std::map *kv_context = &stackframe->kv_context; 44 | kv_context->insert(std::pair(key, value)); 45 | }; 46 | 47 | static void *GetStackFrameContextValue(StackFrame *stackframe, char *key) { 48 | std::map kv_context = stackframe->kv_context; 49 | std::map::iterator it; 50 | it = kv_context.find(key); 51 | if (it != kv_context.end()) { 52 | return (void *)it->second; 53 | } 54 | return NULL; 55 | }; 56 | 57 | static CallStack *CurrentThreadCallStack(); 58 | 59 | private: 60 | static zz::OSThread::LocalStorageKey thread_callstack_key_; 61 | }; 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/ProcessRuntimeUtility.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PlatformUnifiedInterface/MemoryAllocator.h" 4 | 5 | #include "UnifiedInterface/platform.h" 6 | 7 | typedef struct _RuntimeModule { 8 | char path[1024]; 9 | void *load_address; 10 | } RuntimeModule; 11 | 12 | struct MemRegion : MemRange { 13 | MemoryPermission permission; 14 | 15 | MemRegion(addr_t addr, size_t size, MemoryPermission perm) : MemRange(addr, size), permission(perm) { 16 | } 17 | }; 18 | 19 | class ProcessRuntimeUtility { 20 | public: 21 | static const tinystl::vector &GetProcessMemoryLayout(); 22 | 23 | static const tinystl::vector &GetProcessModuleMap(); 24 | 25 | static RuntimeModule GetProcessModule(const char *name); 26 | }; -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace base { 7 | 8 | class ThreadLocalStorageInterface { 9 | using LocalStorageKey = int32_t; 10 | 11 | static LocalStorageKey CreateThreadLocalKey(); 12 | 13 | static void DeleteThreadLocalKey(LocalStorageKey key); 14 | 15 | static void *GetThreadLocal(LocalStorageKey key); 16 | 17 | static int GetThreadLocalInt(LocalStorageKey key) { 18 | return static_cast(reinterpret_cast(GetThreadLocal(key))); 19 | } 20 | 21 | static void SetThreadLocal(LocalStorageKey key, void *value); 22 | 23 | static void SetThreadLocalInt(LocalStorageKey key, int value) { 24 | SetThreadLocal(key, reinterpret_cast(static_cast(value))); 25 | } 26 | 27 | static bool HasThreadLocal(LocalStorageKey key) { 28 | return GetThreadLocal(key) != nullptr; 29 | } 30 | }; 31 | 32 | typedef void *ThreadHandle; 33 | 34 | class ThreadInterface { 35 | public: 36 | class Delegate { 37 | public: 38 | virtual void ThreadMain() = 0; 39 | }; 40 | 41 | public: 42 | static bool Create(Delegate *delegate, ThreadHandle *handle); 43 | 44 | static int CurrentId(); 45 | 46 | static void SetName(const char *); 47 | }; 48 | } // namespace base 49 | 50 | class OSThread : public base::ThreadInterface, public base::ThreadInterface::Delegate { 51 | base::ThreadHandle handle_; 52 | 53 | char name_[256]; 54 | 55 | public: 56 | OSThread(const char *name); 57 | 58 | bool Start(); 59 | }; 60 | 61 | enum MemoryPermission { kNoAccess, kRead, kReadWrite, kReadWriteExecute, kReadExecute }; 62 | 63 | class OSMemory { 64 | public: 65 | static int PageSize(); 66 | 67 | static void *Allocate(size_t size, MemoryPermission access); 68 | 69 | static void *Allocate(size_t size, MemoryPermission access, void *fixed_address); 70 | 71 | static bool Free(void *address, size_t size); 72 | 73 | static bool Release(void *address, size_t size); 74 | 75 | static bool SetPermission(void *address, size_t size, MemoryPermission access); 76 | }; 77 | 78 | class OSPrint { 79 | public: 80 | static void Print(const char *format, ...); 81 | 82 | static void VPrint(const char *format, va_list args); 83 | }; -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/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 | }; -------------------------------------------------------------------------------- /app/src/main/cpp/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/AssemblyCodeBuilder.h" 8 | 9 | #include "InstructionRelocation/x86/InstructionRelocationX86Shared.h" 10 | -------------------------------------------------------------------------------- /app/src/main/cpp/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/AssemblyCodeBuilder.h" 8 | 9 | #include "InstructionRelocation/x86/InstructionRelocationX86Shared.h" 10 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/common.h" 4 | 5 | #include "MemoryAllocator/AssemblyCodeBuilder.h" 6 | 7 | #include "x86_insn_decode/x86_insn_decode.h" 8 | 9 | int GenRelocateCodeFixed(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch); 10 | 11 | void GenRelocateCodeX86Shared(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch); 12 | 13 | int GenRelocateSingleX86Insn(addr_t curr_orig_ip, addr_t curr_relo_ip, uint8_t *buffer_cursor, AssemblerBase *assembler, 14 | CodeBufferBase *code_buffer, x86_insn_decode_t &insn, int8_t mode); -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptEntry.cpp: -------------------------------------------------------------------------------- 1 | #include "InterceptEntry.h" 2 | #include "Interceptor.h" 3 | 4 | InterceptEntry::InterceptEntry(InterceptEntryType type, addr_t address) { 5 | this->type = type; 6 | 7 | #if defined(TARGET_ARCH_ARM) 8 | if (address % 2) { 9 | address -= 1; 10 | this->thumb_mode = true; 11 | } 12 | #endif 13 | 14 | this->patched_addr = address; 15 | this->id = Interceptor::SharedInstance()->count(); 16 | } -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptEntry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "dobby/common.h" 5 | 6 | typedef enum { kFunctionInlineHook, kInstructionInstrument } InterceptEntryType; 7 | 8 | class InterceptRouting; 9 | 10 | typedef struct InterceptEntry { 11 | uint32_t id; 12 | InterceptEntryType type; 13 | InterceptRouting *routing; 14 | 15 | union { 16 | addr_t addr; 17 | addr_t patched_addr; 18 | }; 19 | uint32_t patched_size; 20 | 21 | addr_t relocated_addr; 22 | uint32_t relocated_size; 23 | 24 | uint8_t origin_insns[256]; 25 | uint32_t origin_insn_size; 26 | 27 | bool thumb_mode; 28 | 29 | InterceptEntry(InterceptEntryType type, addr_t address); 30 | } InterceptEntry; -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "InterceptEntry.h" 4 | #include "MemoryAllocator/AssemblyCodeBuilder.h" 5 | #include "InstructionRelocation/InstructionRelocation.h" 6 | #include "TrampolineBridge/Trampoline/Trampoline.h" 7 | 8 | class InterceptRouting { 9 | public: 10 | explicit InterceptRouting(InterceptEntry *entry) : entry_(entry) { 11 | entry->routing = this; 12 | 13 | origin_ = nullptr; 14 | relocated_ = nullptr; 15 | 16 | trampoline_ = nullptr; 17 | trampoline_buffer_ = nullptr; 18 | trampoline_target_ = 0; 19 | } 20 | 21 | virtual void DispatchRouting() = 0; 22 | 23 | virtual void Prepare(); 24 | 25 | virtual void Active(); 26 | 27 | void Commit(); 28 | 29 | InterceptEntry *GetInterceptEntry(); 30 | 31 | void SetTrampolineBuffer(CodeBufferBase *buffer) { 32 | trampoline_buffer_ = buffer; 33 | } 34 | 35 | CodeBufferBase *GetTrampolineBuffer() { 36 | return trampoline_buffer_; 37 | } 38 | 39 | void SetTrampolineTarget(addr_t address) { 40 | trampoline_target_ = address; 41 | } 42 | 43 | addr_t GetTrampolineTarget() { 44 | return trampoline_target_; 45 | } 46 | 47 | protected: 48 | bool GenerateRelocatedCode(); 49 | 50 | bool GenerateTrampolineBuffer(addr_t src, addr_t dst); 51 | 52 | protected: 53 | InterceptEntry *entry_; 54 | 55 | CodeMemBlock *origin_; 56 | CodeMemBlock *relocated_; 57 | 58 | CodeMemBlock *trampoline_; 59 | // trampoline buffer before active 60 | CodeBufferBase *trampoline_buffer_; 61 | addr_t trampoline_target_; 62 | }; 63 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHook.cc: -------------------------------------------------------------------------------- 1 | #include "dobby/dobby_internal.h" 2 | 3 | #include "Interceptor.h" 4 | #include "InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h" 5 | 6 | PUBLIC int DobbyHook(void *address, dobby_dummy_func_t replace_func, dobby_dummy_func_t *origin_func) { 7 | if (!address) { 8 | ERROR_LOG("function address is 0x0"); 9 | return -1; 10 | } 11 | 12 | #if defined(__APPLE__) && defined(__arm64__) 13 | address = pac_strip(address); 14 | replace_func = pac_strip(replace_func); 15 | #endif 16 | 17 | #if defined(ANDROID) 18 | void *page_align_address = (void *)ALIGN_FLOOR(address, OSMemory::PageSize()); 19 | if (!OSMemory::SetPermission(page_align_address, OSMemory::PageSize(), kReadExecute)) { 20 | return -1; 21 | } 22 | #endif 23 | 24 | DEBUG_LOG("----- [DobbyHook:%p] -----", address); 25 | 26 | // check if already register 27 | auto entry = Interceptor::SharedInstance()->find((addr_t)address); 28 | if (entry) { 29 | ERROR_LOG("%p already been hooked.", address); 30 | return -1; 31 | } 32 | 33 | entry = new InterceptEntry(kFunctionInlineHook, (addr_t)address); 34 | 35 | auto *routing = new FunctionInlineHookRouting(entry, replace_func); 36 | routing->Prepare(); 37 | routing->DispatchRouting(); 38 | 39 | // set origin func entry with as relocated instructions 40 | if (origin_func) { 41 | *origin_func = (dobby_dummy_func_t)entry->relocated_addr; 42 | #if defined(__APPLE__) && defined(__arm64__) 43 | *origin_func = pac_sign(*origin_func); 44 | #endif 45 | } 46 | 47 | routing->Commit(); 48 | 49 | Interceptor::SharedInstance()->add(entry); 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/dobby_internal.h" 4 | 5 | #include "InterceptRouting/InterceptRouting.h" 6 | 7 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 8 | 9 | class FunctionInlineHookRouting : public InterceptRouting { 10 | public: 11 | FunctionInlineHookRouting(InterceptEntry *entry, dobby_dummy_func_t replace_func) : InterceptRouting(entry) { 12 | this->replace_func = replace_func; 13 | } 14 | 15 | void DispatchRouting() override; 16 | 17 | private: 18 | void BuildRouting(); 19 | 20 | private: 21 | dobby_dummy_func_t replace_func; 22 | }; 23 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/RoutingImpl.cc: -------------------------------------------------------------------------------- 1 | #include "dobby/dobby_internal.h" 2 | #include "InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h" 3 | 4 | void FunctionInlineHookRouting::BuildRouting() { 5 | SetTrampolineTarget((addr_t)replace_func); 6 | 7 | // generate trampoline buffer, run before GenerateRelocatedCode 8 | addr_t from = entry_->patched_addr; 9 | #if defined(TARGET_ARCH_ARM) 10 | if (entry_->thumb_mode) 11 | from += 1; 12 | #endif 13 | addr_t to = GetTrampolineTarget(); 14 | GenerateTrampolineBuffer(from, to); 15 | } 16 | 17 | void FunctionInlineHookRouting::DispatchRouting() { 18 | BuildRouting(); 19 | 20 | // generate relocated code which size == trampoline size 21 | GenerateRelocatedCode(); 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.cc: -------------------------------------------------------------------------------- 1 | #include "dobby/dobby_internal.h" 2 | 3 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 4 | 5 | #include "intercept_routing_handler.h" 6 | 7 | #include "function-wrapper.h" 8 | 9 | void FunctionWrapperRouting::DispatchRouting() { 10 | Prepare(); 11 | BuildPreCallRouting(); 12 | BuildPostCallRouting(); 13 | } 14 | 15 | // Add pre_call(prologue) handler before running the origin function, 16 | void FunctionWrapperRouting::BuildPreCallRouting() { 17 | // create closure trampoline jump to prologue_routing_dispath with the `entry_` data 18 | ClosureTrampolineEntry *cte = ClosureTrampoline::CreateClosureTrampoline(entry_, (void *)prologue_routing_dispatch); 19 | this->prologue_dispatch_bridge = cte->address; 20 | 21 | DEBUG_LOG("Create pre call closure trampoline to 'prologue_routing_dispatch' at %p", cte->address); 22 | } 23 | 24 | // Add post_call(epilogue) handler before `Return` of the origin function, as implementation is replace the origin 25 | // `Return Address` of the function. 26 | void FunctionWrapperRouting::BuildPostCallRouting() { 27 | // create closure trampoline jump to prologue_routing_dispath with the `entry_` data 28 | ClosureTrampolineEntry *closure_trampoline_entry; 29 | // format trampoline 30 | closure_trampoline_entry = ClosureTrampoline::CreateClosureTrampoline(entry_, (void *)epilogue_routing_dispatch); 31 | DEBUG_LOG("Create post call closure trampoline to 'prologue_routing_dispatch' at %p", 32 | closure_trampoline_entry->address); 33 | 34 | this->SetTrampolineTarget(closure_trampoline_entry->address); 35 | this->epilogue_dispatch_bridge = closure_trampoline_entry->address; 36 | 37 | GenerateTrampolineBuffer(entry_->target_address, GetTrampolineTarget()); 38 | } -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/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 -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrument.cc: -------------------------------------------------------------------------------- 1 | #include "dobby/dobby_internal.h" 2 | 3 | #include "Interceptor.h" 4 | #include "InterceptRouting/InterceptRouting.h" 5 | #include "InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h" 6 | 7 | PUBLIC int DobbyInstrument(void *address, dobby_instrument_callback_t pre_handler) { 8 | if (!address) { 9 | ERROR_LOG("address is 0x0.\n"); 10 | return -1; 11 | } 12 | 13 | #if defined(__APPLE__) && defined(__arm64__) 14 | address = pac_strip(address); 15 | #endif 16 | 17 | #if defined(ANDROID) 18 | void *page_align_address = (void *)ALIGN_FLOOR(address, OSMemory::PageSize()); 19 | if (!OSMemory::SetPermission(page_align_address, OSMemory::PageSize(), kReadExecute)) { 20 | return -1; 21 | } 22 | #endif 23 | 24 | DEBUG_LOG("\n\n----- [DobbyInstrument:%p] -----", address); 25 | 26 | auto entry = Interceptor::SharedInstance()->find((addr_t)address); 27 | if (entry) { 28 | ERROR_LOG("%s already been instrumented.", address); 29 | return -1; 30 | } 31 | 32 | entry = new InterceptEntry(kInstructionInstrument, (addr_t)address); 33 | 34 | auto routing = new InstructionInstrumentRouting(entry, pre_handler, nullptr); 35 | routing->Prepare(); 36 | routing->DispatchRouting(); 37 | routing->Commit(); 38 | 39 | Interceptor::SharedInstance()->add(entry); 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/dobby_internal.h" 4 | 5 | #include "InterceptRouting/InterceptRouting.h" 6 | 7 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 8 | 9 | class InstructionInstrumentRouting : public InterceptRouting { 10 | public: 11 | InstructionInstrumentRouting(InterceptEntry *entry, dobby_instrument_callback_t pre_handler, 12 | dobby_instrument_callback_t post_handler) 13 | : InterceptRouting(entry) { 14 | this->prologue_dispatch_bridge = nullptr; 15 | this->pre_handler = pre_handler; 16 | this->post_handler = post_handler; 17 | } 18 | 19 | void DispatchRouting() override; 20 | 21 | private: 22 | void BuildRouting(); 23 | 24 | public: 25 | dobby_instrument_callback_t pre_handler; 26 | dobby_instrument_callback_t post_handler; 27 | 28 | private: 29 | void *prologue_dispatch_bridge; 30 | }; 31 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/RoutingImpl.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "dobby/dobby_internal.h" 3 | 4 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 5 | 6 | #include "InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h" 7 | #include "InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h" 8 | 9 | // create closure trampoline jump to prologue_routing_dispatch with the `entry_` data 10 | void InstructionInstrumentRouting::BuildRouting() { 11 | void *handler = (void *)instrument_routing_dispatch; 12 | #if defined(__APPLE__) && defined(__arm64__) 13 | handler = pac_strip(handler); 14 | #endif 15 | auto closure_trampoline = ClosureTrampoline::CreateClosureTrampoline(entry_, handler); 16 | this->SetTrampolineTarget((addr_t)closure_trampoline->address); 17 | DEBUG_LOG("[closure trampoline] closure trampoline: %p, data: %p", closure_trampoline->address, entry_); 18 | 19 | // generate trampoline buffer, before `GenerateRelocatedCode` 20 | addr_t from = entry_->patched_addr; 21 | #if defined(TARGET_ARCH_ARM) 22 | if (entry_->thumb_mode) 23 | from += 1; 24 | #endif 25 | addr_t to = GetTrampolineTarget(); 26 | GenerateTrampolineBuffer(from, to); 27 | } 28 | 29 | void InstructionInstrumentRouting::DispatchRouting() { 30 | BuildRouting(); 31 | 32 | // generate relocated code which size == trampoline size 33 | GenerateRelocatedCode(); 34 | } 35 | 36 | #if 0 37 | void *InstructionInstrumentRouting::GetTrampolineTarget() { 38 | return this->prologue_dispatch_bridge; 39 | } 40 | #endif 41 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.cc: -------------------------------------------------------------------------------- 1 | #include "dobby/dobby_internal.h" 2 | 3 | #include "InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h" 4 | #include "InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h" 5 | 6 | #include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" 7 | 8 | void instrument_forward_handler(InterceptEntry *entry, DobbyRegisterContext *ctx) { 9 | auto routing = static_cast(entry->routing); 10 | if (routing->pre_handler) { 11 | auto handler = (dobby_instrument_callback_t)routing->pre_handler; 12 | (*handler)((void *)entry->patched_addr, ctx); 13 | } 14 | 15 | // set prologue bridge next hop address as relocated instructions 16 | set_routing_bridge_next_hop(ctx, (void *)entry->relocated_addr); 17 | } 18 | 19 | void instrument_routing_dispatch(InterceptEntry *entry, DobbyRegisterContext *ctx) { 20 | instrument_forward_handler(entry, ctx); 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/dobby_internal.h" 4 | 5 | extern "C" { 6 | void instrument_routing_dispatch(InterceptEntry *entry, DobbyRegisterContext *ctx); 7 | } -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.cc: -------------------------------------------------------------------------------- 1 | #include "InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h" 2 | 3 | #include "dobby/dobby_internal.h" 4 | 5 | #include "MemoryAllocator/NearMemoryAllocator.h" 6 | 7 | #include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" 8 | 9 | using namespace zz; 10 | 11 | PUBLIC void dobby_enable_near_branch_trampoline() { 12 | RoutingPluginInterface *plugin = new NearBranchTrampolinePlugin; 13 | RoutingPluginManager::registerPlugin("near_branch_trampoline", plugin); 14 | RoutingPluginManager::near_branch_trampoline = plugin; 15 | } 16 | 17 | PUBLIC void dobby_disable_near_branch_trampoline() { 18 | NearBranchTrampolinePlugin *plugin = (NearBranchTrampolinePlugin *)RoutingPluginManager::near_branch_trampoline; 19 | delete plugin; 20 | RoutingPluginManager::near_branch_trampoline = NULL; 21 | } 22 | 23 | #if 0 24 | int NearBranchTrampolinePlugin::PredefinedTrampolineSize() { 25 | #if __arm64__ 26 | return 4; 27 | #elif __arm__ 28 | return 4; 29 | #endif 30 | } 31 | #endif 32 | 33 | extern CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t from, addr_t to); 34 | bool NearBranchTrampolinePlugin::GenerateTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { 35 | CodeBufferBase *trampoline_buffer; 36 | trampoline_buffer = GenerateNearTrampolineBuffer(routing, src, dst); 37 | if (trampoline_buffer == NULL) 38 | return false; 39 | routing->SetTrampolineBuffer(trampoline_buffer); 40 | return true; 41 | } 42 | 43 | // generate trampoline, patch the original entry 44 | bool NearBranchTrampolinePlugin::Active(InterceptRouting *routing) { 45 | addr_t src, dst; 46 | InterceptEntry *entry = routing->GetInterceptEntry(); 47 | src = (addr_t)entry->patched_addr; 48 | dst = (addr_t)routing->GetTrampolineTarget(); 49 | return true; 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/dobby_internal.h" 4 | 5 | #include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" 6 | 7 | class NearBranchTrampolinePlugin : public RoutingPluginInterface { 8 | bool Prepare(InterceptRouting *routing) { 9 | return false; 10 | }; 11 | 12 | bool Active(InterceptRouting *routing); 13 | 14 | bool GenerateTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst); 15 | }; 16 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc: -------------------------------------------------------------------------------- 1 | #include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" 2 | 3 | tinystl::vector RoutingPluginManager::plugins; 4 | 5 | RoutingPluginInterface *RoutingPluginManager::near_branch_trampoline = NULL; 6 | 7 | void RoutingPluginManager::registerPlugin(const char *name, RoutingPluginInterface *plugin) { 8 | DEBUG_LOG("register %s plugin", name); 9 | 10 | RoutingPluginManager::plugins.push_back(plugin); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/dobby_internal.h" 4 | 5 | #include "InterceptRouting/InterceptRouting.h" 6 | 7 | class RoutingPluginInterface { 8 | public: 9 | // @Return: if false will continue to iter next plugin 10 | virtual bool Prepare(InterceptRouting *routing) = 0; 11 | 12 | // @Return: if false will continue to iter next plugin 13 | virtual bool Active(InterceptRouting *routing) = 0; 14 | 15 | // @Return: if false will continue to iter next plugin 16 | virtual bool GenerateTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) = 0; 17 | 18 | private: 19 | char name_[256]; 20 | }; 21 | 22 | class RoutingPluginManager { 23 | public: 24 | static void registerPlugin(const char *name, RoutingPluginInterface *plugin); 25 | 26 | public: 27 | static tinystl::vector plugins; 28 | 29 | static RoutingPluginInterface *near_branch_trampoline; 30 | }; 31 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/Interceptor.cpp: -------------------------------------------------------------------------------- 1 | #include "Interceptor.h" 2 | 3 | Interceptor *Interceptor::instance = nullptr; 4 | 5 | Interceptor *Interceptor::SharedInstance() { 6 | if (Interceptor::instance == nullptr) { 7 | Interceptor::instance = new Interceptor(); 8 | } 9 | return Interceptor::instance; 10 | } 11 | 12 | InterceptEntry *Interceptor::find(addr_t addr) { 13 | for (auto *entry : entries) { 14 | if (entry->patched_addr == addr) { 15 | return entry; 16 | } 17 | } 18 | return nullptr; 19 | } 20 | 21 | void Interceptor::add(InterceptEntry *entry) { 22 | entries.push_back(entry); 23 | } 24 | 25 | void Interceptor::remove(addr_t addr) { 26 | for (auto iter = entries.begin(); iter != entries.end(); iter++) { 27 | if ((*iter)->patched_addr == addr) { 28 | entries.erase(iter); 29 | break; 30 | } 31 | } 32 | } 33 | 34 | const InterceptEntry *Interceptor::getEntry(int i) { 35 | return entries[i]; 36 | } 37 | 38 | int Interceptor::count() { 39 | return entries.size(); 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/Interceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/dobby_internal.h" 4 | #include "InterceptEntry.h" 5 | 6 | class Interceptor { 7 | public: 8 | static Interceptor *SharedInstance(); 9 | 10 | public: 11 | InterceptEntry *find(addr_t addr); 12 | 13 | void remove(addr_t addr); 14 | 15 | void add(InterceptEntry *entry); 16 | 17 | const InterceptEntry *getEntry(int i); 18 | 19 | int count(); 20 | 21 | private: 22 | static Interceptor *instance; 23 | 24 | tinystl::vector entries; 25 | }; -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.cc: -------------------------------------------------------------------------------- 1 | #include "MemoryAllocator/AssemblyCodeBuilder.h" 2 | 3 | #include "dobby/dobby_internal.h" 4 | #include "PlatformUnifiedInterface/ExecMemory/CodePatchTool.h" 5 | 6 | AssemblyCode *AssemblyCodeBuilder::FinalizeFromTurboAssembler(AssemblerBase *assembler) { 7 | auto buffer = (CodeBufferBase *)assembler->GetCodeBuffer(); 8 | auto realized_addr = (addr_t)assembler->GetRealizedAddress(); 9 | #if defined(TEST_WITH_UNICORN) 10 | // impl: unicorn emulator map memory 11 | realized_addr = 0; 12 | #endif 13 | if (!realized_addr) { 14 | size_t buffer_size = 0; 15 | buffer_size = buffer->GetBufferSize(); 16 | #if TARGET_ARCH_ARM 17 | // extra bytes for align needed 18 | buffer_size += 4; 19 | #endif 20 | 21 | auto block = MemoryAllocator::SharedAllocator()->allocateExecBlock(buffer_size); 22 | if (block == nullptr) 23 | return nullptr; 24 | 25 | realized_addr = block->addr; 26 | assembler->SetRealizedAddress((void *)realized_addr); 27 | } 28 | 29 | // Realize the buffer code to the executable memory address, remove the external label, etc 30 | DobbyCodePatch((void *)realized_addr, buffer->GetBuffer(), buffer->GetBufferSize()); 31 | 32 | auto block = new AssemblyCode(realized_addr, buffer->GetBufferSize()); 33 | return block; 34 | } -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PlatformUnifiedInterface/MemoryAllocator.h" 4 | 5 | #include "core/assembler/assembler.h" 6 | 7 | using namespace zz; 8 | 9 | using AssemblyCode = CodeMemBlock; 10 | 11 | class AssemblyCodeBuilder { 12 | public: 13 | static AssemblyCode *FinalizeFromTurboAssembler(AssemblerBase *assembler); 14 | }; 15 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc: -------------------------------------------------------------------------------- 1 | #include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" 2 | 3 | CodeBufferBase *CodeBufferBase::Copy() { 4 | CodeBufferBase *result = new CodeBufferBase(); 5 | result->EmitBuffer(GetBuffer(), GetBufferSize()); 6 | return result; 7 | } 8 | 9 | void CodeBufferBase::Emit8(uint8_t data) { 10 | Emit(data); 11 | } 12 | 13 | void CodeBufferBase::Emit16(uint16_t data) { 14 | Emit(data); 15 | } 16 | 17 | void CodeBufferBase::Emit32(uint32_t data) { 18 | Emit(data); 19 | } 20 | 21 | void CodeBufferBase::Emit64(uint64_t data) { 22 | Emit(data); 23 | } 24 | 25 | void CodeBufferBase::EmitBuffer(uint8_t *buffer, int buffer_size) { 26 | buffer_.insert(buffer_.end(), buffer, buffer + buffer_size); 27 | } 28 | 29 | uint8_t *CodeBufferBase::GetBuffer() { 30 | return buffer_.data(); 31 | } 32 | 33 | size_t CodeBufferBase::GetBufferSize() { 34 | return buffer_.size(); 35 | } 36 | 37 | #if 0 // Template Advanced won't enable even in userspace 38 | template T CodeBufferBase::Load(int offset) { 39 | return *reinterpret_cast(buffer + offset); 40 | } 41 | 42 | template void CodeBufferBase::Store(int offset, T value) { 43 | *reinterpret_cast(buffer + offset) = value; 44 | } 45 | 46 | template void CodeBufferBase::Emit(T value) { 47 | // Ensure the free space enough for the template T value 48 | ensureCapacity(sizeof(T) + GetBufferSize()); 49 | 50 | *reinterpret_cast(buffer_cursor) = value; 51 | buffer_cursor += sizeof(T); 52 | } 53 | #endif 54 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/common.h" 4 | 5 | class CodeBufferBase { 6 | public: 7 | CodeBufferBase() { 8 | } 9 | 10 | public: 11 | virtual CodeBufferBase *Copy(); 12 | 13 | void Emit8(uint8_t data); 14 | 15 | void Emit16(uint16_t data); 16 | 17 | void Emit32(uint32_t data); 18 | 19 | void Emit64(uint64_t data); 20 | 21 | template T Load(int offset) { 22 | return *(T *)(buffer_.data() + offset); 23 | } 24 | 25 | template void Store(int offset, T value) { 26 | *(T *)(buffer_.data() + offset) = value; 27 | } 28 | 29 | template void Emit(T value) { 30 | EmitBuffer((uint8_t *)&value, sizeof(value)); 31 | } 32 | 33 | void EmitBuffer(uint8_t *buffer, int len); 34 | 35 | uint8_t *GetBuffer(); 36 | size_t GetBufferSize(); 37 | 38 | private: 39 | tinystl::vector buffer_; 40 | }; 41 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.h: -------------------------------------------------------------------------------- 1 | #ifndef CODE_BUFFER_ARM_H 2 | #define CODE_BUFFER_ARM_H 3 | 4 | #include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" 5 | 6 | typedef int32_t arm_inst_t; 7 | typedef int16_t thumb1_inst_t; 8 | typedef int32_t thumb2_inst_t; 9 | 10 | class CodeBuffer : public CodeBufferBase { 11 | enum ExecuteState { ARMExecuteState, ThumbExecuteState }; 12 | 13 | public: 14 | CodeBuffer() : CodeBufferBase() { 15 | } 16 | 17 | public: 18 | arm_inst_t LoadARMInst(uint32_t offset) { 19 | return *reinterpret_cast(GetBuffer() + offset); 20 | } 21 | 22 | thumb1_inst_t LoadThumb1Inst(uint32_t offset) { 23 | return *reinterpret_cast(GetBuffer() + offset); 24 | } 25 | 26 | thumb2_inst_t LoadThumb2Inst(uint32_t offset) { 27 | return *reinterpret_cast(GetBuffer() + offset); 28 | } 29 | 30 | void RewriteAddr(uint32_t offset, addr32_t addr) { 31 | memcpy(GetBuffer() + offset, &addr, sizeof(addr)); 32 | } 33 | 34 | void RewriteARMInst(uint32_t offset, arm_inst_t instr) { 35 | *reinterpret_cast(GetBuffer() + offset) = instr; 36 | } 37 | 38 | void RewriteThumb1Inst(uint32_t offset, thumb1_inst_t instr) { 39 | *reinterpret_cast(GetBuffer() + offset) = instr; 40 | } 41 | 42 | void RewriteThumb2Inst(uint32_t offset, thumb2_inst_t instr) { 43 | memcpy(GetBuffer() + offset, &instr, sizeof(instr)); 44 | } 45 | 46 | void EmitARMInst(arm_inst_t instr) { 47 | Emit(instr); 48 | } 49 | 50 | void EmitThumb1Inst(thumb1_inst_t instr) { 51 | Emit(instr); 52 | } 53 | 54 | void EmitThumb2Inst(thumb2_inst_t instr) { 55 | Emit(instr); 56 | } 57 | }; 58 | 59 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.h: -------------------------------------------------------------------------------- 1 | #ifndef CODE_BUFFER_ARM64_H 2 | #define CODE_BUFFER_ARM64_H 3 | 4 | #include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" 5 | 6 | typedef int32_t arm64_inst_t; 7 | 8 | class CodeBuffer : public CodeBufferBase { 9 | 10 | public: 11 | CodeBuffer() : CodeBufferBase() { 12 | } 13 | 14 | public: 15 | arm64_inst_t LoadInst(uint32_t offset) { 16 | return *reinterpret_cast(GetBuffer() + offset); 17 | } 18 | 19 | void RewriteInst(uint32_t offset, arm64_inst_t instr) { 20 | *reinterpret_cast(GetBuffer() + offset) = instr; 21 | } 22 | }; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.h: -------------------------------------------------------------------------------- 1 | #ifndef CODE_BUFFER_X64_H 2 | #define CODE_BUFFER_X64_H 3 | 4 | #include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" 5 | 6 | class CodeBuffer : public CodeBufferBase { 7 | public: 8 | CodeBuffer() : CodeBufferBase() { 9 | } 10 | 11 | public: 12 | void FixBindLabel(int offset, int32_t disp) { 13 | Store(offset, disp); 14 | } 15 | }; 16 | 17 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_IA32) 3 | 4 | #include "MemoryAllocator/CodeBuffer/code-buffer-x86.h" 5 | 6 | void CodeBuffer::Emit32(int32_t data) { 7 | ensureCapacity(GetBufferSize() + sizeof(int32_t)); 8 | *reinterpret_cast(getCursor()) = data; 9 | buffer_cursor += sizeof(int32_t); 10 | return; 11 | } 12 | 13 | void CodeBuffer::FixBindLabel(int offset, int32_t disp) { 14 | *reinterpret_cast(buffer + offset) = disp; 15 | return; 16 | } 17 | 18 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" 4 | 5 | class CodeBuffer : public CodeBufferBase { 6 | public: 7 | CodeBuffer() : CodeBufferBase() { 8 | } 9 | 10 | public: 11 | void FixBindLabel(int offset, int32_t disp); 12 | }; -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" 4 | 5 | typedef int32_t arm_inst_t; 6 | typedef int16_t thumb1_inst_t; 7 | typedef int32_t thumb2_inst_t; 8 | 9 | class CodeBuffer : public CodeBufferBase { 10 | enum ExecuteState { ARMExecuteState, ThumbExecuteState }; 11 | 12 | public: 13 | CodeBuffer() : CodeBufferBase() { 14 | } 15 | 16 | public: 17 | arm_inst_t LoadARMInst(uint32_t offset) { 18 | return *reinterpret_cast(GetBuffer() + offset); 19 | } 20 | 21 | thumb1_inst_t LoadThumb1Inst(uint32_t offset) { 22 | return *reinterpret_cast(GetBuffer() + offset); 23 | } 24 | 25 | thumb2_inst_t LoadThumb2Inst(uint32_t offset) { 26 | return *reinterpret_cast(GetBuffer() + offset); 27 | } 28 | 29 | void RewriteAddr(uint32_t offset, addr32_t addr) { 30 | memcpy(GetBuffer() + offset, &addr, sizeof(addr)); 31 | } 32 | 33 | void RewriteARMInst(uint32_t offset, arm_inst_t instr) { 34 | *reinterpret_cast(GetBuffer() + offset) = instr; 35 | } 36 | 37 | void RewriteThumb1Inst(uint32_t offset, thumb1_inst_t instr) { 38 | *reinterpret_cast(GetBuffer() + offset) = instr; 39 | } 40 | 41 | void RewriteThumb2Inst(uint32_t offset, thumb2_inst_t instr) { 42 | memcpy(GetBuffer() + offset, &instr, sizeof(instr)); 43 | } 44 | 45 | void EmitARMInst(arm_inst_t instr) { 46 | Emit(instr); 47 | } 48 | 49 | void EmitThumb1Inst(thumb1_inst_t instr) { 50 | Emit(instr); 51 | } 52 | 53 | void EmitThumb2Inst(thumb2_inst_t instr) { 54 | Emit(instr); 55 | } 56 | }; -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" 4 | 5 | typedef int32_t arm64_inst_t; 6 | 7 | class CodeBuffer : public CodeBufferBase { 8 | 9 | public: 10 | CodeBuffer() : CodeBufferBase() { 11 | } 12 | 13 | public: 14 | arm64_inst_t LoadInst(uint32_t offset) { 15 | return *reinterpret_cast(GetBuffer() + offset); 16 | } 17 | 18 | void RewriteInst(uint32_t offset, arm64_inst_t instr) { 19 | *reinterpret_cast(GetBuffer() + offset) = instr; 20 | } 21 | }; -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" 4 | 5 | class CodeBuffer : public CodeBufferBase { 6 | public: 7 | CodeBuffer() : CodeBufferBase() { 8 | } 9 | 10 | public: 11 | void FixBindLabel(int offset, int32_t disp) { 12 | Store(offset, disp); 13 | } 14 | }; -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x86.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" 4 | 5 | class CodeBuffer : public CodeBufferBase { 6 | public: 7 | CodeBuffer() : CodeBufferBase() { 8 | } 9 | 10 | public: 11 | void FixBindLabel(int offset, int32_t disp) { 12 | Store(offset, disp); 13 | } 14 | }; -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PlatformUnifiedInterface/MemoryAllocator.h" 4 | 5 | #include "dobby/common.h" 6 | 7 | class NearMemoryAllocator { 8 | public: 9 | MemoryAllocator *default_allocator; 10 | NearMemoryAllocator() { 11 | default_allocator = MemoryAllocator::SharedAllocator(); 12 | } 13 | 14 | private: 15 | static NearMemoryAllocator *shared_allocator; 16 | 17 | public: 18 | static NearMemoryAllocator *SharedAllocator(); 19 | 20 | public: 21 | MemBlock *allocateNearBlock(uint32_t size, addr_t pos, size_t search_range, bool executable); 22 | MemBlock *allocateNearBlockFromDefaultAllocator(uint32_t size, addr_t pos, size_t search_range, bool executable); 23 | MemBlock *allocateNearBlockFromUnusedRegion(uint32_t size, addr_t pos, size_t search_range, bool executable); 24 | 25 | uint8_t *allocateNearExecMemory(uint32_t size, addr_t pos, size_t search_range); 26 | uint8_t *allocateNearExecMemory(uint8_t *buffer, uint32_t buffer_size, addr_t pos, size_t search_range); 27 | 28 | uint8_t *allocateNearDataMemory(uint32_t size, addr_t pos, size_t search_range); 29 | uint8_t *allocateNearDataMemory(uint8_t *buffer, uint32_t buffer_size, addr_t pos, size_t search_range); 30 | }; -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/CodePatchTool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | int DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size); -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/dobby_internal.h" 4 | 5 | #ifdef ENABLE_CLOSURE_TRAMPOLINE_TEMPLATE 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif //__cplusplus 9 | void closure_trampoline_template(); 10 | void closure_bridge_template(); 11 | #ifdef __cplusplus 12 | } 13 | #endif //__cplusplus 14 | #endif 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif //__cplusplus 19 | 20 | typedef struct { 21 | void *address; 22 | int size; 23 | void *carry_handler; 24 | void *carry_data; 25 | } ClosureTrampolineEntry; 26 | 27 | asm_func_t get_closure_bridge(); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif //__cplusplus 32 | 33 | class ClosureTrampoline { 34 | private: 35 | static tinystl::vector *trampolines_; 36 | 37 | public: 38 | static ClosureTrampolineEntry *CreateClosureTrampoline(void *carry_data, void *carry_handler); 39 | }; 40 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/ClosureTrampolineARM.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_ARM) 3 | 4 | #include "dobby/dobby_internal.h" 5 | 6 | #include "core/assembler/assembler-arm.h" 7 | 8 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 9 | 10 | using namespace zz; 11 | using namespace zz::arm; 12 | 13 | ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { 14 | ClosureTrampolineEntry *tramp_entry = nullptr; 15 | tramp_entry = new ClosureTrampolineEntry; 16 | 17 | #ifdef ENABLE_CLOSURE_TRAMPOLINE_TEMPLATE 18 | #define CLOSURE_TRAMPOLINE_SIZE (7 * 4) 19 | // use closure trampoline template code, find the executable memory and patch it. 20 | auto code = AssemblyCodeBuilder::FinalizeCodeFromAddress(closure_trampoline_template, CLOSURE_TRAMPOLINE_SIZE); 21 | #else 22 | // use assembler and codegen modules instead of template_code 23 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 24 | #define _ turbo_assembler_. 25 | TurboAssembler turbo_assembler_(0); 26 | 27 | AssemblerPseudoLabel entry_label(0); 28 | AssemblerPseudoLabel forward_bridge_label(0); 29 | 30 | _ Ldr(r12, &entry_label); 31 | _ Ldr(pc, &forward_bridge_label); 32 | _ PseudoBind(&entry_label); 33 | _ EmitAddress((uint32_t)(uintptr_t)tramp_entry); 34 | _ PseudoBind(&forward_bridge_label); 35 | _ EmitAddress((uint32_t)(uintptr_t)get_closure_bridge()); 36 | 37 | auto closure_tramp = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); 38 | tramp_entry->address = (void *)closure_tramp->addr; 39 | tramp_entry->size = closure_tramp->size; 40 | tramp_entry->carry_data = carry_data; 41 | tramp_entry->carry_handler = carry_handler; 42 | 43 | delete closure_tramp; 44 | 45 | return tramp_entry; 46 | #endif 47 | } 48 | 49 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-bridge-template-arm.cc: -------------------------------------------------------------------------------- 1 | // .section __TEXT,__text,regular,pure_instructions 2 | // .ios_version_min 11, 0 3 | 4 | #if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) 5 | 6 | #if defined(__WIN32__) || defined(__APPLE__) 7 | #define cdecl(s) "_" s 8 | #else 9 | #define cdecl(s) s 10 | #endif 11 | 12 | #define xASM(x) __asm(x) 13 | 14 | __attribute__((naked)) void closure_bridge_template() { 15 | xASM(".arm"); 16 | xASM("sub sp, sp, #(14*4)"); 17 | xASM("str lr, [sp, #(13*4)]"); 18 | xASM("str r12, [sp, #(12*4)]"); 19 | xASM("str r11, [sp, #(11*4)]"); 20 | xASM("str r10, [sp, #(10*4)]"); 21 | xASM("str r9, [sp, #(9*4)]"); 22 | xASM("str r8, [sp, #(8*4)]"); 23 | xASM("str r7, [sp, #(7*4)]"); 24 | xASM("str r6, [sp, #(6*4)]"); 25 | xASM("str r5, [sp, #(5*4)]"); 26 | xASM("str r4, [sp, #(4*4)]"); 27 | xASM("str r3, [sp, #(3*4)]"); 28 | xASM("str r2, [sp, #(2*4)]"); 29 | xASM("str r1, [sp, #(1*4)]"); 30 | xASM("str r0, [sp, #(0*4)]"); 31 | 32 | // dummy align 33 | xASM("sub sp, sp, #8"); 34 | 35 | xASM("mov r0, sp"); 36 | xASM("mov r1, r12"); 37 | xASM("bl " cdecl("common_closure_bridge_handler")); 38 | 39 | // dummy align 40 | xASM("add sp, sp, #8"); 41 | 42 | xASM("ldr r0, [sp], #4"); 43 | xASM("ldr r1, [sp], #4"); 44 | xASM("ldr r2, [sp], #4"); 45 | xASM("ldr r3, [sp], #4"); 46 | xASM("ldr r4, [sp], #4"); 47 | xASM("ldr r5, [sp], #4"); 48 | xASM("ldr r6, [sp], #4"); 49 | xASM("ldr r7, [sp], #4"); 50 | xASM("ldr r8, [sp], #4"); 51 | xASM("ldr r9, [sp], #4"); 52 | xASM("ldr r10, [sp], #4"); 53 | xASM("ldr r11, [sp], #4"); 54 | xASM("ldr r12, [sp], #4"); 55 | xASM("ldr lr, [sp], #4"); 56 | 57 | #if 1 58 | xASM("str r12, [sp, #-4]"); 59 | xASM("ldr pc, [sp, #-4]"); 60 | #else 61 | xASM("mov pc, r12"); 62 | #endif 63 | } 64 | 65 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/ClosureTrampolineARM64.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_ARM64) 3 | 4 | #include "dobby/dobby_internal.h" 5 | 6 | #include "core/assembler/assembler-arm64.h" 7 | 8 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 9 | 10 | using namespace zz; 11 | using namespace zz::arm64; 12 | 13 | // // tips 14 | // _ ldr(TMP_REG_1, OFFSETOF(ClosureTrampolineEntry, carry_data)); 15 | // _ ldr(TMP_REG_0, OFFSETOF(ClosureTrampolineEntry, carry_handler)); 16 | 17 | // use assembler and codegen modules instead of template_code 18 | ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { 19 | ClosureTrampolineEntry *tramp_entry = nullptr; 20 | tramp_entry = new ClosureTrampolineEntry; 21 | 22 | #define _ turbo_assembler_. 23 | TurboAssembler turbo_assembler_(0); 24 | 25 | AssemblerPseudoLabel entry_label(0); 26 | AssemblerPseudoLabel forward_bridge_label(0); 27 | 28 | // prologue: alloc stack, store lr 29 | _ sub(SP, SP, 2 * 8); 30 | _ str(x30, MemOperand(SP, 8)); 31 | 32 | // store data at stack 33 | _ Ldr(TMP_REG_0, &entry_label); 34 | _ str(TMP_REG_0, MemOperand(SP, 0)); 35 | 36 | _ Ldr(TMP_REG_0, &forward_bridge_label); 37 | _ blr(TMP_REG_0); 38 | 39 | // epilogue: release stack(won't restore lr) 40 | _ ldr(x30, MemOperand(SP, 8)); 41 | _ add(SP, SP, 2 * 8); 42 | 43 | // branch to next hop 44 | _ br(TMP_REG_0); 45 | 46 | _ PseudoBind(&entry_label); 47 | _ EmitInt64((uint64_t)tramp_entry); 48 | _ PseudoBind(&forward_bridge_label); 49 | _ EmitInt64((uint64_t)get_closure_bridge()); 50 | 51 | auto closure_tramp = AssemblyCodeBuilder::FinalizeFromTurboAssembler(static_cast(&turbo_assembler_)); 52 | 53 | tramp_entry->address = (void *)closure_tramp->addr; 54 | tramp_entry->size = closure_tramp->size; 55 | tramp_entry->carry_data = carry_data; 56 | tramp_entry->carry_handler = carry_handler; 57 | 58 | delete closure_tramp; 59 | 60 | return tramp_entry; 61 | } 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-trampoline-template-arm64.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 8 19 | #define OFFSETOF_ClourseTrampolineEntry_carry_handler 0 20 | .globl 21 | cdecl(closure_trampoline_template) cdecl(closure_trampoline_template) 22 | : ldr x17, 23 | ClourseTrampolineEntryPtr ldr x16, OFFSETOF_ClourseTrampolineEntry_carry_data ldr x17, 24 | OFFSETOF_ClourseTrampolineEntry_carry_handler br x17 ClourseTrampolineEntryPtr :.long 0.long 0 25 | 26 | #else 27 | 28 | ; 29 | closure trampoline just carray the required members from the object..globl cdecl(closure_trampoline_template) 30 | cdecl(closure_trampoline_template) 31 | : ldr x16, 32 | = carry_data ldr x17, = carry_handler br x17 carry_data :.long 0.long 0 carry_handler :.long 0.long 0 33 | 34 | #endif 35 | 36 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/dynamic-closure-trampoline-template-arm64.S: -------------------------------------------------------------------------------- 1 | // .section __TEXT,__text,regular,pure_instructions 2 | 3 | // For iOS, we can't allocate executable memory, but we can use `remap` doing some trick. 4 | // For details, please refer `libffi` 5 | 6 | #if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) 7 | 8 | #if defined(__WIN32__) || defined(__APPLE__) 9 | #define cdecl(s) _##s 10 | #else 11 | #define cdecl(s) s 12 | #endif 13 | 14 | #define PAGE_MAX_SIZE 4096 15 | #define PAGE_MAX_SHIFT 14 16 | 17 | .align PAGE_MAX_SHIFT.globl cdecl(dynamic_closure_trampoline_table_page) cdecl(dynamic_closure_trampoline_table_page) 18 | :.rept(PAGE_MAX_SIZE - 4 * 4) / 19 | 8 // sub dynamic_closure_trampoline_forward size 20 | adr x16, 21 | #0 b cdecl(dynamic_closure_trampoline_forward) 22 | .endr 23 | 24 | cdecl(dynamic_closure_trampoline_forward) 25 | : sub x16, 26 | x16, #0x4000 // [DynamicClosureTrampoline **] 27 | ldr x16, 28 | [ x16, #0 ] // [DynamicClosureTrampoline *] 29 | ldr x17, 30 | [ x16, #0 ] // trampolineTo 31 | br x17 32 | 33 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/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 | #include "dobby/dobby_internal.h" 7 | 8 | using namespace zz::arm64; 9 | 10 | void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { 11 | *reinterpret_cast(&ctx->general.x[TMP_REG_0.code()]) = address; 12 | } 13 | 14 | void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { 15 | } 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.cc: -------------------------------------------------------------------------------- 1 | #include "logging/logging.h" 2 | 3 | #include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" 4 | 5 | PUBLIC void common_closure_bridge_handler(DobbyRegisterContext *ctx, ClosureTrampolineEntry *entry) { 6 | DEBUG_LOG("common bridge handler: carry data: %p, carry handler: %p", (InterceptEntry *)entry->carry_data, 7 | entry->carry_handler); 8 | 9 | typedef void (*routing_handler_t)(InterceptEntry *, DobbyRegisterContext *); 10 | auto routing_handler = (routing_handler_t)entry->carry_handler; 11 | 12 | #if defined(__APPLE__) && __arm64e__ 13 | #if __has_feature(ptrauth_calls) 14 | uint64_t discriminator = 0; 15 | // discriminator = __builtin_ptrauth_type_discriminator(__typeof(routing_handler)); 16 | routing_handler = (__typeof(routing_handler))__builtin_ptrauth_sign_unauthenticated((void *)routing_handler, 17 | ptrauth_key_asia, discriminator); 18 | #endif 19 | #endif 20 | 21 | routing_handler((InterceptEntry *)entry->carry_data, ctx); 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h: -------------------------------------------------------------------------------- 1 | #ifndef CLOSURE_TRAMPOLINE_COMMON_HANDLER_H 2 | #define CLOSURE_TRAMPOLINE_COMMON_HANDLER_H 3 | 4 | #include "dobby/dobby_internal.h" 5 | 6 | #include "Interceptor.h" 7 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 8 | 9 | extern "C" { 10 | void common_closure_bridge_handler(DobbyRegisterContext *ctx, ClosureTrampolineEntry *entry); 11 | } 12 | 13 | void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address); 14 | 15 | void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address); 16 | 17 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/ClosureTrampolineX64.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_X64) 3 | 4 | #include "dobby/dobby_internal.h" 5 | 6 | #include "core/assembler/assembler-x64.h" 7 | 8 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 9 | 10 | using namespace zz; 11 | using namespace zz::x64; 12 | 13 | ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { 14 | ClosureTrampolineEntry *tramp_entry = nullptr; 15 | tramp_entry = new ClosureTrampolineEntry; 16 | 17 | auto tramp_size = 32; 18 | auto tramp_mem = MemoryAllocator::SharedAllocator()->allocateExecMemory(tramp_size); 19 | if (tramp_mem == nullptr) { 20 | return nullptr; 21 | } 22 | #define _ turbo_assembler_. 23 | #define __ turbo_assembler_.GetCodeBuffer()-> 24 | TurboAssembler turbo_assembler_(0); 25 | 26 | uint8_t *push_rip_6 = (uint8_t *)"\xff\x35\x06\x00\x00\x00"; 27 | uint8_t *jmp_rip_8 = (uint8_t *)"\xff\x25\x08\x00\x00\x00"; 28 | 29 | __ EmitBuffer(push_rip_6, 6); 30 | __ EmitBuffer(jmp_rip_8, 6); 31 | __ Emit64((uint64_t)tramp_entry); 32 | __ Emit64((uint64_t)get_closure_bridge()); 33 | 34 | tramp_entry->address = tramp_mem; 35 | tramp_entry->size = tramp_size; 36 | tramp_entry->carry_data = carry_data; 37 | tramp_entry->carry_handler = carry_handler; 38 | 39 | auto closure_tramp_buffer = static_cast(turbo_assembler_.GetCodeBuffer()); 40 | DobbyCodePatch(tramp_mem, (uint8_t *)closure_tramp_buffer->GetBuffer(), closure_tramp_buffer->GetBufferSize()); 41 | 42 | return tramp_entry; 43 | } 44 | 45 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-bridge-template-x64.c: -------------------------------------------------------------------------------- 1 | #if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) 2 | 3 | #if defined(__WIN32__) || defined(__APPLE__) 4 | #define xcdecl(s) "_" s 5 | #else 6 | #define xcdecl(s) s 7 | #endif 8 | 9 | #define xASM(x) __asm(x) 10 | 11 | __attribute__((naked)) void closure_bridge_template() { 12 | // flags register 13 | xASM("pushfq"); 14 | 15 | // general register 16 | xASM("sub rsp, #(16*8)"); 17 | xASM("mov [rsp+16*0], rax"); 18 | xASM("mov [rsp+16*1], rbx"); 19 | xASM("mov [rsp+16*2], rcx"); 20 | xASM("mov [rsp+16*3], rdx"); 21 | xASM("mov [rsp+16*4], rbp"); 22 | xASM("mov [rsp+16*5], rsp"); 23 | xASM("mov [rsp+16*6], rdi"); 24 | xASM("mov [rsp+16*7], rsi"); 25 | xASM("mov [rsp+16*8], r8"); 26 | xASM("mov [rsp+16*9], r9"); 27 | xASM("mov [rsp+16*10], r10"); 28 | xASM("mov [rsp+16*11], r11"); 29 | xASM("mov [rsp+16*12], r12"); 30 | xASM("mov [rsp+16*13], r13"); 31 | xASM("mov [rsp+16*14], r14"); 32 | xASM("mov [rsp+16*15], r15"); 33 | 34 | // ======= Jump to UnifiedInterface Bridge Handle ======= 35 | 36 | // prepare args 37 | // @rdi: data_address 38 | // @rsi: DobbyRegisterContext stack address 39 | xASM("mov rdi, rsp"); 40 | xASM("mov rsi, [rsp-16*8]"); 41 | xASM("call " xcdecl("common_closure_bridge_handler")); 42 | 43 | // ======= DobbyRegisterContext Restore ======= 44 | 45 | // general register 46 | xASM("pop r15"); 47 | xASM("pop r14"); 48 | xASM("pop r13"); 49 | xASM("pop r12"); 50 | xASM("pop r11"); 51 | xASM("pop r10"); 52 | xASM("pop r9"); 53 | xASM("pop r8"); 54 | xASM("pop rsi"); 55 | xASM("pop rdi"); 56 | xASM("pop rsp"); 57 | xASM("pop rbp"); 58 | xASM("pop rdx"); 59 | xASM("pop rcx"); 60 | xASM("pop rbx"); 61 | xASM("pop rax"); 62 | 63 | // flags register 64 | xASM("popfq"); 65 | 66 | // trick: use the 'carry_data' placeholder, as the return address 67 | xASM("ret"); 68 | }; 69 | 70 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-trampoline-template-x64.S: -------------------------------------------------------------------------------- 1 | #if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) 2 | 3 | #if defined(__WIN32__) || defined(__APPLE__) 4 | #define cdecl(s) _##s 5 | #else 6 | #define cdecl(s) s 7 | #endif 8 | 9 | .align 4 10 | 11 | ; 12 | closure trampoline just carray the required members from the object. 13 | .globl 14 | cdecl(closure_trampoline_template) cdecl(closure_trampoline_template) 15 | : push[rip + 6 + 6] jmp[rip + 6 + 8] carry_data :.long 0.long 0 carry_handler :.long 0.long 0 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 | addr_t rsp = ctx->rsp; 8 | 9 | // ClosureTrampolineEntry reserved stack 10 | addr_t entry_placeholder_stack_addr = rsp - 8; 11 | *(addr_t *)entry_placeholder_stack_addr = (addr_t)address; 12 | } 13 | 14 | void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { 15 | } 16 | 17 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/ClosureTrampolineX86.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 | 8 | #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" 9 | 10 | using namespace zz; 11 | using namespace zz::x86; 12 | 13 | ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { 14 | ClosureTrampolineEntry *tramp_entry = nullptr; 15 | tramp_entry = new ClosureTrampolineEntry; 16 | 17 | auto tramp_size = 32; 18 | auto tramp_mem = MemoryAllocator::SharedAllocator()->allocateExecMemory(tramp_size); 19 | if (tramp_mem == nullptr) { 20 | return nullptr; 21 | } 22 | 23 | #define _ turbo_assembler_. 24 | #define __ turbo_assembler_.GetCodeBuffer()-> 25 | TurboAssembler turbo_assembler_(tramp_mem); 26 | 27 | int32_t offset = (int32_t)((uintptr_t)get_closure_bridge() - ((uintptr_t)tramp_mem + 18)); 28 | 29 | _ sub(esp, Immediate(4, 32)); 30 | _ mov(Address(esp, 4 * 0), Immediate((int32_t)(uintptr_t)tramp_entry, 32)); 31 | _ jmp(Immediate(offset, 32)); 32 | 33 | tramp_entry->address = tramp_mem; 34 | tramp_entry->size = tramp_size; 35 | tramp_entry->carry_data = carry_data; 36 | tramp_entry->carry_handler = carry_handler; 37 | 38 | auto closure_tramp_buffer = static_cast(turbo_assembler_.GetCodeBuffer()); 39 | DobbyCodePatch(tramp_mem, (uint8_t *)closure_tramp_buffer->GetBuffer(), closure_tramp_buffer->GetBufferSize()); 40 | 41 | return tramp_entry; 42 | } 43 | 44 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/Trampoline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryAllocator/AssemblyCodeBuilder.h" 4 | 5 | CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to); -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm/trampoline_arm.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | 3 | #if defined(TARGET_ARCH_ARM) 4 | 5 | #include "dobby/dobby_internal.h" 6 | 7 | #include "core/assembler/assembler-arm.h" 8 | #include "core/codegen/codegen-arm.h" 9 | 10 | #include "InstructionRelocation/arm/InstructionRelocationARM.h" 11 | #include "MemoryAllocator/NearMemoryAllocator.h" 12 | #include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" 13 | 14 | using namespace zz::arm; 15 | 16 | static CodeBufferBase *generate_arm_trampoline(addr32_t from, addr32_t to) { 17 | TurboAssembler turbo_assembler_((void *)from); 18 | #define _ turbo_assembler_. 19 | 20 | CodeGen codegen(&turbo_assembler_); 21 | codegen.LiteralLdrBranch(to); 22 | 23 | return turbo_assembler_.GetCodeBuffer()->Copy(); 24 | } 25 | 26 | CodeBufferBase *generate_thumb_trampoline(addr32_t from, addr32_t to) { 27 | ThumbTurboAssembler thumb_turbo_assembler_((void *)from); 28 | #undef _ 29 | #define _ thumb_turbo_assembler_. 30 | 31 | _ AlignThumbNop(); 32 | _ t2_ldr(pc, MemOperand(pc, 0)); 33 | _ EmitAddress(to); 34 | 35 | return thumb_turbo_assembler_.GetCodeBuffer()->Copy(); 36 | } 37 | 38 | CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { 39 | enum ExecuteState { ARMExecuteState, ThumbExecuteState }; 40 | 41 | // set instruction running state 42 | ExecuteState execute_state_; 43 | execute_state_ = ARMExecuteState; 44 | if ((addr_t)from % 2) { 45 | execute_state_ = ThumbExecuteState; 46 | } 47 | 48 | if (execute_state_ == ARMExecuteState) { 49 | return generate_arm_trampoline(from, to); 50 | } else { 51 | // Check if needed pc align, (relative pc instructions needed 4 align) 52 | from = from - THUMB_ADDRESS_FLAG; 53 | return generate_thumb_trampoline(from, to); 54 | } 55 | return NULL; 56 | } 57 | 58 | CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { 59 | return NULL; 60 | } 61 | 62 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm64/trampoline_arm64.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_ARM64) 3 | 4 | #include "dobby/dobby_internal.h" 5 | 6 | #include "core/assembler/assembler-arm64.h" 7 | #include "core/codegen/codegen-arm64.h" 8 | 9 | #include "MemoryAllocator/NearMemoryAllocator.h" 10 | #include "InstructionRelocation/arm64/InstructionRelocationARM64.h" 11 | #include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" 12 | 13 | using namespace zz::arm64; 14 | 15 | CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { 16 | TurboAssembler turbo_assembler_((void *)from); 17 | #define _ turbo_assembler_. 18 | 19 | uint64_t distance = llabs((int64_t)(from - to)); 20 | uint64_t adrp_range = ((uint64_t)1 << (2 + 19 + 12 - 1)); 21 | if (distance < adrp_range) { 22 | // adrp, add, br 23 | _ AdrpAdd(TMP_REG_0, from, to); 24 | _ br(TMP_REG_0); 25 | DEBUG_LOG("[trampoline] use [adrp, add, br]"); 26 | } else { 27 | // ldr, br, branch-address 28 | CodeGen codegen(&turbo_assembler_); 29 | codegen.LiteralLdrBranch((uint64_t)to); 30 | DEBUG_LOG("[trampoline] use [ldr, br, #label]"); 31 | } 32 | #undef _ 33 | 34 | // Bind all labels 35 | turbo_assembler_.RelocBind(); 36 | 37 | auto result = turbo_assembler_.GetCodeBuffer()->Copy(); 38 | return result; 39 | } 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x64/trampoline_x64.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | 3 | #if defined(TARGET_ARCH_X64) 4 | 5 | #include "dobby/dobby_internal.h" 6 | 7 | #include "core/assembler/assembler-x64.h" 8 | #include "core/codegen/codegen-x64.h" 9 | 10 | #include "InstructionRelocation/x64/InstructionRelocationX64.h" 11 | 12 | #include "MemoryAllocator/NearMemoryAllocator.h" 13 | #include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" 14 | 15 | using namespace zz::x64; 16 | 17 | static addr_t allocate_indirect_stub(addr_t jmp_insn_addr) { 18 | uint32_t jmp_near_range = (uint32_t)2 * 1024 * 1024 * 1024; 19 | auto stub_addr = (addr_t)NearMemoryAllocator::SharedAllocator()->allocateNearDataMemory(sizeof(void *), jmp_insn_addr, 20 | jmp_near_range); 21 | if (stub_addr == 0) { 22 | ERROR_LOG("Not found near forward stub"); 23 | return 0; 24 | } 25 | 26 | DEBUG_LOG("forward stub: %p", stub_addr); 27 | return stub_addr; 28 | } 29 | 30 | CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { 31 | TurboAssembler turbo_assembler_((void *)from); 32 | #define _ turbo_assembler_. 33 | 34 | // allocate forward stub 35 | auto jump_near_next_insn_addr = from + 6; 36 | addr_t forward_stub = allocate_indirect_stub(jump_near_next_insn_addr); 37 | if (forward_stub == 0) 38 | return nullptr; 39 | 40 | *(addr_t *)forward_stub = to; 41 | 42 | CodeGen codegen(&turbo_assembler_); 43 | codegen.JmpNearIndirect((addr_t)forward_stub); 44 | 45 | auto buffer = turbo_assembler_.GetCodeBuffer()->Copy(); 46 | return buffer; 47 | } 48 | 49 | CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { 50 | DEBUG_LOG("x64 near branch trampoline enable default"); 51 | return nullptr; 52 | } 53 | 54 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x86/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 | CodeBufferBase *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 | CodeBufferBase *result = NULL; 24 | result = turbo_assembler_.GetCodeBuffer()->Copy(); 25 | return result; 26 | } 27 | 28 | CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { 29 | DEBUG_LOG("x86 near branch trampoline enable default"); 30 | return NULL; 31 | } 32 | 33 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/arch/Cpu.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "core/arch/Cpu.h" 3 | #include "core/arch/CpuUtils.h" 4 | 5 | #include "xnucxx/LiteMemOpt.h" 6 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/arch/Cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_ARCH_CPU_H 2 | #define CORE_ARCH_CPU_H 3 | 4 | #include "CpuRegister.h" 5 | #include "CpuFeature.h" 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/arch/CpuFeature.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "core/arch/CpuFeature.h" 3 | #include "logging/logging.h" 4 | 5 | void CpuFeatures::ClearCache(void *start, void *end) { 6 | UNIMPLEMENTED(); 7 | } -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/arch/CpuFeature.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_ARCH_CPU_FEATURE_H 2 | #define CORE_ARCH_CPU_FEATURE_H 3 | 4 | #include "dobby/common.h" 5 | 6 | class CpuFeatures { 7 | private: 8 | static void FlushICache(void *start, size_t size) { 9 | ClearCache(start, (void *)((addr_t)start + size)); 10 | } 11 | 12 | static void FlushICache(void *start, void *end) { 13 | ClearCache(start, end); 14 | } 15 | 16 | static void ClearCache(void *start, void *end); 17 | }; 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/arch/CpuRegister.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "CpuRegister.h" 3 | 4 | constexpr RegisterBase RegisterBase::from_code(int code) { 5 | return RegisterBase{code}; 6 | } 7 | 8 | constexpr RegisterBase RegisterBase::no_reg() { 9 | return RegisterBase{0}; 10 | } -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/arch/CpuRegister.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_ARCH_CPU_REGISTER_H 2 | #define CORE_ARCH_CPU_REGISTER_H 3 | 4 | class RegisterBase { 5 | public: 6 | static constexpr RegisterBase from_code(int code); 7 | 8 | static constexpr RegisterBase no_reg(); 9 | 10 | virtual bool Is(const RegisterBase ®) const { 11 | return (reg.reg_code_ == this->reg_code_); 12 | } 13 | 14 | int code() const { 15 | return reg_code_; 16 | }; 17 | 18 | protected: 19 | explicit constexpr RegisterBase(int code) : reg_code_(code) { 20 | } 21 | 22 | int reg_code_; 23 | }; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/arch/CpuUtils.h: -------------------------------------------------------------------------------- 1 | #ifndef CPU_UTILITY_H 2 | #define CPU_UTILITY_H 3 | 4 | /* Define the default attributes for the functions in this file. */ 5 | #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) 6 | 7 | #if defined(__i386__) || defined(__x86_64__) 8 | static __inline__ void __DEFAULT_FN_ATTRS __cpuid(int __info[4], int __level) { 9 | __asm__("cpuid" : "=a"(__info[0]), "=b"(__info[1]), "=c"(__info[2]), "=d"(__info[3]) : "a"(__level)); 10 | } 11 | 12 | static __inline__ void __DEFAULT_FN_ATTRS __cpuidex(int __info[4], int __level, int __ecx) { 13 | __asm__("cpuid" : "=a"(__info[0]), "=b"(__info[1]), "=c"(__info[2]), "=d"(__info[3]) : "a"(__level), "c"(__ecx)); 14 | } 15 | #endif 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/arch/arm/constants-arm.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_ARCH_CONSTANTS_ARM_H 2 | #define CORE_ARCH_CONSTANTS_ARM_H 3 | 4 | enum AddrMode { Offset = 0, PreIndex = 1, PostIndex = 2 }; 5 | 6 | enum Condition { 7 | EQ = 0, // equal 8 | NE = 1, // not equal 9 | CS = 2, // carry set/unsigned higher or same 10 | CC = 3, // carry clear/unsigned lower 11 | MI = 4, // minus/negative 12 | PL = 5, // plus/positive or zero 13 | VS = 6, // overflow 14 | VC = 7, // no overflow 15 | HI = 8, // unsigned higher 16 | LS = 9, // unsigned lower or same 17 | GE = 10, // signed greater than or equal 18 | LT = 11, // signed less than 19 | GT = 12, // signed greater than 20 | LE = 13, // signed less than or equal 21 | AL = 14, // always (unconditional) 22 | 23 | }; 24 | 25 | enum Shift { 26 | LSL = 0, // Logical shift left 27 | LSR = 1, // Logical shift right 28 | ASR = 2, // Arithmetic shift right 29 | ROR = 3, // Rotate right 30 | }; 31 | 32 | enum { 33 | B0 = 1 << 0, 34 | B4 = 1 << 4, 35 | B5 = 1 << 5, 36 | B6 = 1 << 6, 37 | B7 = 1 << 7, 38 | B8 = 1 << 8, 39 | B9 = 1 << 9, 40 | B10 = 1 << 10, 41 | B12 = 1 << 12, 42 | B14 = 1 << 14, 43 | B15 = 1 << 15, 44 | B16 = 1 << 16, 45 | B17 = 1 << 17, 46 | B18 = 1 << 18, 47 | B19 = 1 << 19, 48 | B20 = 1 << 20, 49 | B21 = 1 << 21, 50 | B22 = 1 << 22, 51 | B23 = 1 << 23, 52 | B24 = 1 << 24, 53 | B25 = 1 << 25, 54 | B26 = 1 << 26, 55 | B27 = 1 << 27, 56 | B28 = 1 << 28, 57 | }; 58 | 59 | enum InstructionFields { 60 | // Registers. 61 | kRdShift = 12, 62 | kRtShift = 12, 63 | kRmShift = 10, 64 | kRnShift = 16, 65 | 66 | // Condition 67 | kConditionShift = 28, 68 | }; 69 | 70 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/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_code_ == this->reg_code_); 35 | } 36 | 37 | bool IsValid() const { 38 | return (reg_code_ != 0); 39 | } 40 | 41 | int code() const { 42 | return reg_code_; 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 -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/assembler/AssemblerPseudoLabel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" 4 | 5 | class Label { 6 | public: 7 | Label(addr_t addr) : pos_(addr) { 8 | } 9 | 10 | protected: 11 | addr_t pos_; 12 | }; 13 | 14 | class AssemblerPseudoLabel : public Label { 15 | public: 16 | typedef struct { 17 | int link_type; 18 | size_t pc_offset; 19 | addr_t vmaddr_; 20 | } ref_label_insn_t; 21 | 22 | public: 23 | AssemblerPseudoLabel(addr_t addr) : Label(addr) { 24 | ref_label_insns_.reserve(4); 25 | 26 | bind_to(addr); 27 | } 28 | 29 | bool has_confused_instructions() { 30 | return ref_label_insns_.size(); 31 | } 32 | 33 | void link_confused_instructions(); 34 | 35 | void link_confused_instructions(CodeBufferBase *buffer_); 36 | 37 | void link_to(int link_type, uint32_t pc_offset) { 38 | ref_label_insn_t insn; 39 | insn.link_type = link_type; 40 | insn.pc_offset = pc_offset; 41 | ref_label_insns_.push_back(insn); 42 | } 43 | 44 | public: 45 | addr_t pos() { 46 | return pos_; 47 | }; 48 | 49 | void bind_to(addr_t addr) { 50 | pos_ = addr; 51 | } 52 | 53 | protected: 54 | tinystl::vector ref_label_insns_; 55 | }; 56 | 57 | struct RelocLabel : public AssemblerPseudoLabel { 58 | public: 59 | RelocLabel() : AssemblerPseudoLabel(0) { 60 | memset(data_, 0, sizeof(data_)); 61 | data_size_ = 0; 62 | } 63 | 64 | template static RelocLabel *withData(T value) { 65 | auto label = new RelocLabel(); 66 | label->setData(value); 67 | return label; 68 | } 69 | 70 | template T data() { 71 | return *(T *)data_; 72 | } 73 | 74 | template void setData(T value) { 75 | data_size_ = sizeof(T); 76 | memcpy(data_, &value, data_size_); 77 | } 78 | 79 | template void fixupData(T value) { 80 | *(T *)data_ = value; 81 | } 82 | 83 | uint8_t data_[8]; 84 | int data_size_; 85 | }; -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 AssemblerPseudoLabel::link_confused_instructions(CodeBufferBase *buffer) { 7 | CodeBuffer *_buffer = (CodeBuffer *)buffer; 8 | 9 | for (auto &ref_label_insn : ref_label_insns_) { 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_->Emit32(value); 36 | } 37 | 38 | } // namespace arm 39 | } // namespace zz 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if TARGET_ARCH_ARM64 3 | 4 | #include "core/assembler/assembler-arm64.h" 5 | 6 | void AssemblerPseudoLabel::link_confused_instructions(CodeBufferBase *buffer_) { 7 | auto buffer = (CodeBuffer *)buffer_; 8 | 9 | for (auto &ref_label_insn : ref_label_insns_) { 10 | int64_t fixup_offset = pos() - ref_label_insn.pc_offset; 11 | 12 | arm64_inst_t inst = buffer->LoadInst(ref_label_insn.pc_offset); 13 | arm64_inst_t new_inst = 0; 14 | 15 | if (ref_label_insn.link_type == kLabelImm19) { 16 | new_inst = encode_imm19_offset(inst, fixup_offset); 17 | } 18 | 19 | buffer->RewriteInst(ref_label_insn.pc_offset, new_inst); 20 | } 21 | } 22 | 23 | using namespace zz::arm64; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /app/src/main/cpp/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_->Emit8(0xE9); 10 | buffer_->Emit32((int)imm.value()); 11 | } 12 | 13 | addr32_t TurboAssembler::CurrentIP() { 14 | return pc_offset() + (addr_t)realized_addr_; 15 | } 16 | 17 | void AssemblerPseudoLabel::link_confused_instructions(CodeBufferBase *buffer) { 18 | auto _buffer = (CodeBuffer *)buffer; 19 | 20 | for (auto &ref_label_insn : ref_label_insns_) { 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 -------------------------------------------------------------------------------- /app/src/main/cpp/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 | void AssemblerPseudoLabel::link_confused_instructions(CodeBufferBase *buffer) { 9 | CodeBuffer *_buffer = (CodeBuffer *)buffer; 10 | 11 | for (auto &ref_label_insn : ref_label_insns_) { 12 | int64_t new_offset = pos() - ref_label_insn.pc_offset; 13 | 14 | if (ref_label_insn.link_type == kDisp32_off_9) { 15 | // why 9 ? 16 | // use `call` and `pop` get the runtime ip register 17 | // but the ip register not the real call next insn 18 | // it need add two insn length == 9 19 | int disp32_fix_pos = ref_label_insn.pc_offset - sizeof(int32_t); 20 | _buffer->FixBindLabel(disp32_fix_pos, new_offset + 9); 21 | } 22 | } 23 | } 24 | 25 | void Assembler::jmp(Immediate imm) { 26 | buffer_->Emit8(0xE9); 27 | buffer_->Emit32((int)imm.value()); 28 | } 29 | 30 | addr64_t TurboAssembler::CurrentIP() { 31 | return pc_offset() + (addr_t)realized_addr_; 32 | } 33 | 34 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/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_->Emit8(0xE9); 10 | buffer_->Emit32((int)imm.value()); 11 | } 12 | 13 | uint64_t TurboAssembler::CurrentIP() { 14 | return pc_offset() + (addr_t)realized_addr_; 15 | } 16 | 17 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/assembler/assembler.cc: -------------------------------------------------------------------------------- 1 | #include "core/assembler/assembler.h" 2 | #include "logging/logging.h" 3 | 4 | namespace zz { 5 | 6 | const void *ExternalReference::address() { 7 | return address_; 8 | } 9 | 10 | AssemblerBase::AssemblerBase(void *address) { 11 | realized_addr_ = address; 12 | buffer_ = nullptr; 13 | } 14 | 15 | AssemblerBase::~AssemblerBase() { 16 | buffer_ = nullptr; 17 | } 18 | 19 | size_t AssemblerBase::ip_offset() const { 20 | return reinterpret_cast(buffer_)->GetBufferSize(); 21 | } 22 | 23 | size_t AssemblerBase::pc_offset() const { 24 | return reinterpret_cast(buffer_)->GetBufferSize(); 25 | } 26 | 27 | CodeBuffer *AssemblerBase::GetCodeBuffer() { 28 | return buffer_; 29 | } 30 | 31 | void AssemblerBase::PseudoBind(AssemblerPseudoLabel *label) { 32 | auto pc_offset = reinterpret_cast(buffer_)->GetBufferSize(); 33 | label->bind_to(pc_offset); 34 | if (label->has_confused_instructions()) { 35 | label->link_confused_instructions(reinterpret_cast(buffer_)); 36 | } 37 | } 38 | 39 | void AssemblerBase::RelocBind() { 40 | for (auto *data_label : data_labels_) { 41 | PseudoBind(data_label); 42 | reinterpret_cast(buffer_)->EmitBuffer(data_label->data_, data_label->data_size_); 43 | } 44 | } 45 | 46 | void AssemblerBase::AppendRelocLabel(RelocLabel *label) { 47 | data_labels_.push_back(label); 48 | } 49 | 50 | void AssemblerBase::SetRealizedAddress(void *address) { 51 | realized_addr_ = address; 52 | } 53 | 54 | void *AssemblerBase::GetRealizedAddress() { 55 | return realized_addr_; 56 | } 57 | 58 | void AssemblerBase::FlushICache(addr_t start, int size) { 59 | } 60 | 61 | void AssemblerBase::FlushICache(addr_t start, addr_t end) { 62 | } 63 | 64 | } // namespace zz 65 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/assembler/assembler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" 4 | 5 | #include "AssemblerPseudoLabel.h" 6 | 7 | class CodeBuffer; 8 | 9 | namespace zz { 10 | 11 | class ExternalReference { 12 | public: 13 | explicit ExternalReference(void *address) : address_(address) { 14 | #if defined(__APPLE__) && __arm64e__ 15 | address_ = pac_strip((void *)address_); 16 | #endif 17 | } 18 | 19 | const void *address(); 20 | 21 | private: 22 | const void *address_; 23 | }; 24 | 25 | class AssemblerBase { 26 | public: 27 | explicit AssemblerBase(void *address); 28 | 29 | ~AssemblerBase(); 30 | 31 | size_t ip_offset() const; 32 | 33 | size_t pc_offset() const; 34 | 35 | CodeBuffer *GetCodeBuffer(); 36 | 37 | void PseudoBind(AssemblerPseudoLabel *label); 38 | 39 | void RelocBind(); 40 | 41 | void AppendRelocLabel(RelocLabel *label); 42 | 43 | protected: 44 | tinystl::vector data_labels_; 45 | 46 | public: 47 | virtual void *GetRealizedAddress(); 48 | 49 | virtual void SetRealizedAddress(void *address); 50 | 51 | static void FlushICache(addr_t start, int size); 52 | 53 | static void FlushICache(addr_t start, addr_t end); 54 | 55 | protected: 56 | CodeBuffer *buffer_; 57 | 58 | void *realized_addr_; 59 | }; 60 | 61 | } // namespace zz 62 | 63 | #if 0 64 | #include "globals.h" 65 | #if TARGET_ARCH_ARM 66 | #include "core/assembler/assembler-arm.h" 67 | #elif TARGET_ARCH_ARM64 68 | #include "core/assembler/assembler-arm64.h" 69 | #elif TARGET_ARCH_X64 70 | #include "core/assembler/assembler-x64.h" 71 | #else 72 | #error "unsupported architecture" 73 | #endif 74 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/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_->GetCodeBuffer()->Emit32((addr_t)address); 14 | } 15 | 16 | } // namespace arm 17 | } // namespace zz 18 | 19 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_ARM64) 3 | 4 | #include "dobby/dobby_internal.h" 5 | #include "core/codegen/codegen-arm64.h" 6 | 7 | namespace zz { 8 | namespace arm64 { 9 | 10 | void CodeGen::LiteralLdrBranch(uint64_t address) { 11 | auto turbo_assembler_ = reinterpret_cast(this->assembler_); 12 | #define _ turbo_assembler_-> 13 | 14 | auto label = RelocLabel::withData(address); 15 | turbo_assembler_->AppendRelocLabel(label); 16 | 17 | _ Ldr(TMP_REG_0, label); 18 | _ br(TMP_REG_0); 19 | 20 | #undef _ 21 | } 22 | 23 | } // namespace arm64 24 | } // namespace zz 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_CODEGEN_ARM64_H 2 | #define CORE_CODEGEN_ARM64_H 3 | 4 | #include "core/codegen/codegen.h" 5 | #include "core/assembler/assembler.h" 6 | #include "core/assembler/assembler-arm64.h" 7 | 8 | namespace zz { 9 | namespace arm64 { 10 | 11 | class CodeGen : public CodeGenBase { 12 | public: 13 | CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { 14 | } 15 | void LiteralLdrBranch(uint64_t address); 16 | }; 17 | 18 | } // namespace arm64 19 | } // namespace zz 20 | 21 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/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_->GetCodeBuffer()-> 13 | uint32_t currIP = turbo_assembler_->CurrentIP() + 5; 14 | int32_t offset = (int32_t)(address - currIP); 15 | 16 | __ Emit8(0xe9); 17 | __ Emit32(offset); 18 | } 19 | 20 | } // namespace x86 21 | } // namespace zz 22 | 23 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/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 -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.cc: -------------------------------------------------------------------------------- 1 | #include "platform_detect_macro.h" 2 | #if defined(TARGET_ARCH_X64) 3 | 4 | #include "core/codegen/codegen-x64.h" 5 | 6 | namespace zz { 7 | namespace x64 { 8 | 9 | void CodeGen::JmpNearIndirect(addr_t forward_stub_addr) { 10 | TurboAssembler *turbo_assembler_ = reinterpret_cast(this->assembler_); 11 | #define _ turbo_assembler_-> 12 | #define __ turbo_assembler_->GetCodeBuffer()-> 13 | uint64_t currIP = turbo_assembler_->CurrentIP() + 6; 14 | int32_t offset = (int32_t)(forward_stub_addr - currIP); 15 | 16 | // jmp *(rip + disp32) 17 | __ Emit8(0xFF); 18 | __ Emit8(0x25); // ModR/M: 00 100 101 19 | __ Emit32(offset); 20 | } 21 | 22 | } // namespace x64 23 | } // namespace zz 24 | 25 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_CODEGEN_X64_H 2 | #define CORE_CODEGEN_X64_H 3 | 4 | #include "core/codegen/codegen.h" 5 | #include "core/assembler/assembler.h" 6 | #include "core/assembler/assembler-x64.h" 7 | 8 | namespace zz { 9 | namespace x64 { 10 | 11 | class CodeGen : public CodeGenBase { 12 | public: 13 | CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { 14 | } 15 | 16 | void JmpNearIndirect(addr_t forward_stub_addr); 17 | }; 18 | 19 | } // namespace x64 20 | } // namespace zz 21 | 22 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/codegen/codegen.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_CODEGEN_H 2 | #define CORE_CODEGEN_H 3 | 4 | #include "core/assembler/assembler.h" 5 | 6 | using namespace zz; 7 | 8 | class CodeGenBase { 9 | public: 10 | CodeGenBase(AssemblerBase *assembler) : assembler_(assembler) { 11 | } 12 | 13 | protected: 14 | AssemblerBase *assembler_; 15 | }; 16 | 17 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/core/emulator/dummy.cc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/app/src/main/cpp/Dobby/source/core/emulator/dummy.cc -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/dobby.cpp: -------------------------------------------------------------------------------- 1 | #include "dobby/dobby_internal.h" 2 | #include "Interceptor.h" 3 | 4 | __attribute__((constructor)) static void ctor() { 5 | DEBUG_LOG("================================"); 6 | DEBUG_LOG("Dobby"); 7 | DEBUG_LOG("dobby in debug log mode, disable with cmake flag \"-DDOBBY_DEBUG=OFF\""); 8 | DEBUG_LOG("================================"); 9 | } 10 | 11 | PUBLIC const char *DobbyGetVersion() { 12 | return __DOBBY_BUILD_VERSION__; 13 | } 14 | 15 | PUBLIC int DobbyDestroy(void *address) { 16 | #if defined(TARGET_ARCH_ARM) 17 | if ((addr_t)address % 2) { 18 | address = (void *)((addr_t)address - 1); 19 | } 20 | #endif 21 | auto entry = Interceptor::SharedInstance()->find((addr_t)address); 22 | if (entry) { 23 | uint8_t *buffer = entry->origin_insns; 24 | uint32_t buffer_size = entry->origin_insn_size; 25 | DobbyCodePatch(address, buffer, buffer_size); 26 | Interceptor::SharedInstance()->remove((addr_t)address); 27 | return 0; 28 | } 29 | 30 | return -1; 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 | #include "dobby/pac_kit.h" 9 | 10 | #include "logging/logging.h" 11 | #include "logging/check_logging.h" -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/dobby/dobby_internal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dobby/common.h" 4 | 5 | #include "UnifiedInterface/platform.h" 6 | 7 | #include "PlatformUnifiedInterface/MemoryAllocator.h" 8 | #include "PlatformUnifiedInterface/ExecMemory/CodePatchTool.h" 9 | #include "PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h" 10 | 11 | #include "MemoryAllocator/AssemblyCodeBuilder.h" 12 | 13 | #include "InterceptRouting/InterceptRouting.h" -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/dobby/kernel_mode_header.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | typedef void *vm_map_entry_t; 11 | extern vm_map_t kernel_map; 12 | 13 | typedef void *pmap_paddr_t; 14 | struct pmap; 15 | typedef struct pmap *pmap_t; 16 | extern pmap_t kernel_pmap; 17 | 18 | extern task_t kernel_task; 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | // ----- pmap ----- 25 | 26 | typedef void *pmap_paddr_t; 27 | struct pmap; 28 | typedef struct pmap *pmap_t; 29 | 30 | typedef uint64_t vaddr_t; 31 | typedef uint64_t paddr_t; 32 | 33 | struct pmap; 34 | typedef struct pmap *pmap_t; 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | extern pmap_t kernel_pmap; 41 | 42 | void pmap_kit_init(); 43 | 44 | paddr_t pmap_kit_kvtophys(pmap_t pmap, vaddr_t va); 45 | 46 | int pmap_kit_set_perm(pmap_t pmap, vaddr_t start, vaddr_t end, unsigned int prot); 47 | 48 | #define cppvPsnk 1 49 | #define cppvPsrc 2 50 | void pmap_kit_bcopy_phys(paddr_t src, paddr_t dst, size_t size, int flags); 51 | 52 | typedef uint64_t pt_entry_t; 53 | pt_entry_t pmap_kit_kva_to_pte(pmap_t pmap, vaddr_t va); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/dobby/pac_kit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #if defined(__arm64e__) && __has_feature(ptrauth_calls) 6 | #include 7 | #endif 8 | 9 | static inline void *pac_strip(void *addr) { 10 | if (addr == NULL) { 11 | return NULL; 12 | } 13 | #if __has_feature(ptrauth_calls) 14 | addr = ptrauth_strip(addr, ptrauth_key_asia); 15 | #endif 16 | return addr; 17 | } 18 | 19 | static inline void *pac_sign(void *addr) { 20 | if (addr == NULL) { 21 | return NULL; 22 | } 23 | #if __has_feature(ptrauth_calls) 24 | addr = ptrauth_sign_unauthenticated((void *)addr, ptrauth_key_asia, 0); 25 | #endif 26 | return addr; 27 | } 28 | 29 | static inline void *pac_strip_and_sign(void *addr) { 30 | return pac_sign(pac_strip(addr)); 31 | } -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/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 | #ifdef __cplusplus 46 | // #include "TINYSTL/vector.h" 47 | // #include "TINYSTL/unordered_map.h" 48 | #include "TINYSTL/vector.h" 49 | #include "TINYSTL/unordered_map.h" 50 | #endif 51 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/source/dobby/utility_macro.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // offset of struct member 4 | #define OFFSETOF(TYPE, ELEMENT) ((size_t) & (((TYPE *)0)->ELEMENT)) 5 | 6 | // assert 7 | #define ASSERT(X) 8 | 9 | // left/right shift 10 | #define LeftShift(a, b, c) ((a & ((1 << b) - 1)) << c) 11 | #define RightShift(a, b, c) ((a >> c) & ((1 << b) - 1)) 12 | 13 | // align 14 | #ifndef ALIGN 15 | #define ALIGN ALIGN_FLOOR 16 | #endif 17 | #define ALIGN_FLOOR(address, range) ((uintptr_t)address & ~((uintptr_t)range - 1)) 18 | #define ALIGN_CEIL(address, range) (((uintptr_t)address + (uintptr_t)range - 1) & ~((uintptr_t)range - 1)) 19 | 20 | // borrow from gdb, refer: binutils-gdb/gdb/arch/arm.h 21 | #define submask(x) ((1L << ((x) + 1)) - 1) 22 | #define bits(obj, st, fn) (((obj) >> (st)) & submask((fn) - (st))) 23 | #define bit(obj, st) (((obj) >> (st)) & 1) 24 | #define sbits(obj, st, fn) ((long)(bits(obj, st, fn) | ((long)bit(obj, fn) * ~submask(fn - st)))) 25 | 26 | // make it easy 27 | #define set_bit(obj, st, bit) obj = (((~(1 << st)) & obj) | (bit << st)) 28 | #define set_bits(obj, st, fn, bits) obj = (((~(submask(fn - st) << st)) & obj) | (bits << st)) 29 | 30 | // definition to expand macro then apply to pragma message 31 | // #pragma message(VAR_NAME_VALUE(HOST_OS_IOS)) 32 | #define VALUE_TO_STRING(x) #x 33 | #define VALUE(x) VALUE_TO_STRING(x) 34 | #define VAR_NAME_VALUE(var) #var "=" VALUE(var) 35 | 36 | // format print 37 | #ifdef __LP64__ 38 | #define __PRI_64_prefix "l" 39 | #define __PRI_PTR_prefix "l" 40 | #else 41 | #define __PRI_64_prefix "ll" 42 | #define __PRI_PTR_prefix 43 | #endif 44 | #define PRIxPTR __PRI_PTR_prefix "x" /* uintptr_t */ 45 | 46 | // deprecated declared 47 | #if defined(__GNUC__) || defined(__clang__) 48 | #define DEPRECATED __attribute__((deprecated)) 49 | #elif defined(_MSC_VER) 50 | #define DEPRECATED __declspec(deprecated) 51 | #else 52 | #pragma message("WARNING: You need to implement DEPRECATED for this compiler") 53 | #define DEPRECATED 54 | #endif 55 | 56 | // export method 57 | #if defined(_WIN32) 58 | #define PUBLIC 59 | #else 60 | #define PUBLIC __attribute__((visibility("default"))) 61 | #define INTERNAL __attribute__((visibility("internal"))) 62 | #endif -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/tests/UniconEmulator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | class CapstoneDisassembler { 10 | public: 11 | void disassemble(uintptr_t addr, char *buffer, size_t buffer_size); 12 | 13 | static CapstoneDisassembler *Get(const std::string &arch); 14 | 15 | private: 16 | CapstoneDisassembler(const std::string &arch, csh csh_); 17 | 18 | ~CapstoneDisassembler(); 19 | 20 | private: 21 | std::string arch_; 22 | csh csh_; 23 | 24 | static std::unordered_map instances_; 25 | }; 26 | 27 | class UniconEmulator { 28 | public: 29 | UniconEmulator(const std::string &arch); 30 | 31 | void mapMemory(uintptr_t addr, char *buffer, size_t buffer_size); 32 | 33 | void *readRegister(int regId); 34 | 35 | void writeRegister(int regId, void *value); 36 | 37 | void start(uintptr_t addr, uintptr_t end); 38 | 39 | void stop() { 40 | uc_emu_stop(uc_); 41 | } 42 | 43 | void emulate(uintptr_t addr, uintptr_t end, char *buffer, size_t buffer_size); 44 | 45 | void setUnmappedAddr(uintptr_t addr) { 46 | unmapped_addr_ = addr; 47 | } 48 | 49 | intptr_t getFaultAddr() { 50 | return unmapped_addr_; 51 | } 52 | 53 | bool isThumb() { 54 | void *reg_value = readRegister(UC_ARM_REG_CPSR); 55 | return (intptr_t)reg_value & 0x20; 56 | } 57 | 58 | void reset(); 59 | 60 | public: 61 | std::string arch_; 62 | uintptr_t start_, end_; 63 | 64 | private: 65 | uc_err err_; 66 | uc_engine *uc_; 67 | uintptr_t unmapped_addr_; 68 | }; 69 | 70 | void set_global_arch(std::string arch); 71 | 72 | void check_insn_relo(char *buffer, size_t buffer_size, bool check_fault_addr, int check_reg_id, 73 | void (^callback)(UniconEmulator *orig, UniconEmulator *relo), uintptr_t relo_stop_size = 0); -------------------------------------------------------------------------------- /app/src/main/cpp/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 | -------------------------------------------------------------------------------- /app/src/main/cpp/Dobby/tests/test_native.cpp: -------------------------------------------------------------------------------- 1 | #include "dobby.h" 2 | 3 | #include 4 | #include 5 | 6 | #define LOG(fmt, ...) printf("[test_native] " fmt, ##__VA_ARGS__) 7 | 8 | void test_execve() { 9 | char *argv[] = {NULL}; 10 | char *envp[] = {NULL}; 11 | 12 | LOG("test execve"); 13 | 14 | DobbyInstrument(DobbySymbolResolver(0, "_execve"), [](void *, DobbyRegisterContext *ctx) { 15 | LOG("execve: %s", (char *)ctx->general.regs.rdi); 16 | return; 17 | }); 18 | 19 | execve("ls", argv, envp); 20 | 21 | return; 22 | } 23 | 24 | int main(int argc, char *argv[]) { 25 | log_set_level(0); 26 | 27 | test_execve(); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/pareto/bypasskeyattestation/CustomProvider.java: -------------------------------------------------------------------------------- 1 | package com.pareto.bypasskeyattestation; 2 | 3 | import java.security.Provider; 4 | 5 | public final class CustomProvider extends Provider { 6 | 7 | CustomProvider(Provider provider) { 8 | super(provider.getName(), provider.getVersion(), provider.getInfo()); 9 | putAll(provider); 10 | this.put("KeyStore.AndroidKeyStore", CustomKeyStoreSpi.class.getName()); 11 | } 12 | 13 | @Override 14 | public synchronized Service getService(String type, String algorithm) { 15 | return super.getService(type, algorithm); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | plugins { 3 | id("com.android.application") version "8.1.4" apply false 4 | } 5 | 6 | -------------------------------------------------------------------------------- /docs/assets/image-20231206194441375.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206194441375.png -------------------------------------------------------------------------------- /docs/assets/image-20231206194902623.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206194902623.png -------------------------------------------------------------------------------- /docs/assets/image-20231206204532183.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206204532183.png -------------------------------------------------------------------------------- /docs/assets/image-20231206204618107.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206204618107.png -------------------------------------------------------------------------------- /docs/assets/image-20231206204803506.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206204803506.png -------------------------------------------------------------------------------- /docs/assets/image-20231206205018254.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206205018254.png -------------------------------------------------------------------------------- /docs/assets/image-20231206205854947.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206205854947.png -------------------------------------------------------------------------------- /docs/assets/image-20231206210013858.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206210013858.png -------------------------------------------------------------------------------- /docs/assets/image-20231206210101742.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206210101742.png -------------------------------------------------------------------------------- /docs/assets/image-20231206210143247.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206210143247.png -------------------------------------------------------------------------------- /docs/assets/image-20231206210320245.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206210320245.png -------------------------------------------------------------------------------- /docs/assets/image-20231206210430273.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206210430273.png -------------------------------------------------------------------------------- /docs/assets/image-20231206210517186.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206210517186.png -------------------------------------------------------------------------------- /docs/assets/image-20231206210830493.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231206210830493.png -------------------------------------------------------------------------------- /docs/assets/image-20231207102813599.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231207102813599.png -------------------------------------------------------------------------------- /docs/assets/image-20231207102826652.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231207102826652.png -------------------------------------------------------------------------------- /docs/assets/image-20231208191506535.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231208191506535.png -------------------------------------------------------------------------------- /docs/assets/image-20231208192239640.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231208192239640.png -------------------------------------------------------------------------------- /docs/assets/image-20231208192355224.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231208192355224.png -------------------------------------------------------------------------------- /docs/assets/image-20231222202803391.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231222202803391.png -------------------------------------------------------------------------------- /docs/assets/image-20231222202915406.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/docs/assets/image-20231222202915406.png -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Kotlin code style for this project: "official" or "obsolete": 19 | kotlin.code.style=official 20 | # Enables namespacing of each library's R class so that its R class includes only the 21 | # resources declared in the library itself and none from the library's dependencies, 22 | # thereby reducing the size of the R class for that library 23 | android.nonTransitiveRClass=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Dec 01 12:25:48 CST 2023 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /module/0.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module/0.txt -------------------------------------------------------------------------------- /module/1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module/1.txt -------------------------------------------------------------------------------- /module/2.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module/2.txt -------------------------------------------------------------------------------- /module/3.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module/3.txt -------------------------------------------------------------------------------- /module/META-INF/com/google/android/update-binary: -------------------------------------------------------------------------------- 1 | #!/sbin/sh 2 | 3 | ################# 4 | # Initialization 5 | ################# 6 | 7 | umask 022 8 | 9 | # echo before loading util_functions 10 | ui_print() { echo "$1"; } 11 | 12 | require_new_magisk() { 13 | ui_print "*******************************" 14 | ui_print " Please install Magisk v20.4+! " 15 | ui_print "*******************************" 16 | exit 1 17 | } 18 | 19 | ######################### 20 | # Load util_functions.sh 21 | ######################### 22 | 23 | OUTFD=$2 24 | ZIPFILE=$3 25 | 26 | mount /data 2>/dev/null 27 | 28 | [ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk 29 | . /data/adb/magisk/util_functions.sh 30 | [ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk 31 | 32 | install_module 33 | exit 0 34 | -------------------------------------------------------------------------------- /module/META-INF/com/google/android/updater-script: -------------------------------------------------------------------------------- 1 | #MAGISK -------------------------------------------------------------------------------- /module/classes.dex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module/classes.dex -------------------------------------------------------------------------------- /module/customize.sh: -------------------------------------------------------------------------------- 1 | # Error on < Android 8. 2 | if [ "$API" -lt 26 ]; then 3 | abort "!!! You can't use this module on Android < 8.0" 4 | fi 5 | 6 | # Copy default pif.json if it doesn't exist. 7 | if [ ! -e /data/adb/pif.json ]; then 8 | mv -f $MODPATH/pif.json /data/adb/pif.json 9 | ui_print "Moved default pif.json file!" 10 | fi 11 | 12 | mv -f $MODPATH/*.txt /data/local/tmp/ 13 | chmod +rw /data/local/tmp 14 | 15 | # SafetyNet-Fix module is obsolete and it's incompatible with PIF. 16 | if [ -d /data/adb/modules/safetynet-fix ]; then 17 | touch /data/adb/modules/safetynet-fix/remove 18 | ui_print "!!! SafetyNet-Fix module will be removed on next reboot." 19 | fi 20 | 21 | # MagiskHidePropsConf module is obsolete in Android 8+ but it shouldn't give issues. 22 | if [ -d /data/adb/modules/MagiskHidePropsConf ]; then 23 | ui_print "!!! WARNING, 'MagiskHidePropsConf' module may cause issues with PIF" 24 | fi 25 | -------------------------------------------------------------------------------- /module/module.prop: -------------------------------------------------------------------------------- 1 | id=bypassKeyAttestation 2 | name=bypass key attestation 3 | version=v1.0.3 4 | versionCode=1 5 | author=pareto 6 | description=bypass key attestation 7 | -------------------------------------------------------------------------------- /module/pif.json: -------------------------------------------------------------------------------- 1 | { 2 | "PRODUCT": "realme", 3 | "DEVICE": "RMX2032", 4 | "MANUFACTURER": "realme", 5 | "BRAND": "realme", 6 | "MODEL": "RMX2032", 7 | "FINGERPRINT": "realme/RMX2032/RMX2032:10/QKQ1.200209.002/1642670490:user/release-keys", 8 | "SECURITY_PATCH": "2022-01-05", 9 | "FIRST_API_LEVEL": 28 10 | } -------------------------------------------------------------------------------- /module/post-fs-data.sh: -------------------------------------------------------------------------------- 1 | # Remove Play Services from Magisk Denylist when set to enforcing 2 | if magisk --denylist status; then 3 | magisk --denylist rm com.google.android.gms 4 | fi 5 | 6 | # Remove conflicting modules if installed 7 | if [ -d /data/adb/modules/safetynet-fix ]; then 8 | touch /data/adb/modules/safetynet-fix/remove 9 | fi 10 | 11 | # Conditional early sensitive properties 12 | 13 | resetprop_if_diff() { 14 | local NAME=$1 15 | local EXPECTED=$2 16 | local CURRENT=$(resetprop $NAME) 17 | 18 | [ -z "$CURRENT" ] || [ "$CURRENT" == "$EXPECTED" ] || resetprop $NAME $EXPECTED 19 | } 20 | 21 | resetprop_if_match() { 22 | local NAME=$1 23 | local CONTAINS=$2 24 | local VALUE=$3 25 | 26 | [[ "$(resetprop $NAME)" == *"$CONTAINS"* ]] && resetprop $NAME $VALUE 27 | } 28 | 29 | # RootBeer, Microsoft 30 | resetprop_if_diff ro.build.tags release-keys 31 | 32 | # Samsung 33 | resetprop_if_diff ro.boot.warranty_bit 0 34 | resetprop_if_diff ro.vendor.boot.warranty_bit 0 35 | resetprop_if_diff ro.vendor.warranty_bit 0 36 | resetprop_if_diff ro.warranty_bit 0 37 | 38 | # OnePlus 39 | resetprop_if_diff ro.is_ever_orange 0 40 | 41 | # Other 42 | resetprop_if_diff ro.build.type user 43 | resetprop_if_diff ro.debuggable 0 44 | resetprop_if_diff ro.secure 1 45 | -------------------------------------------------------------------------------- /module/service.sh: -------------------------------------------------------------------------------- 1 | # Conditional sensitive properties 2 | 3 | resetprop_if_diff() { 4 | local NAME=$1 5 | local EXPECTED=$2 6 | local CURRENT=$(resetprop $NAME) 7 | 8 | [ -z "$CURRENT" ] || [ "$CURRENT" == "$EXPECTED" ] || resetprop $NAME $EXPECTED 9 | } 10 | 11 | resetprop_if_match() { 12 | local NAME=$1 13 | local CONTAINS=$2 14 | local VALUE=$3 15 | 16 | [[ "$(resetprop $NAME)" == *"$CONTAINS"* ]] && resetprop $NAME $VALUE 17 | } 18 | 19 | # Magisk recovery mode 20 | resetprop_if_match ro.bootmode recovery unknown 21 | resetprop_if_match ro.boot.mode recovery unknown 22 | resetprop_if_match vendor.boot.mode recovery unknown 23 | 24 | # SELinux 25 | if [ -n "$(resetprop ro.build.selinux)" ]; then 26 | resetprop --delete ro.build.selinux 27 | fi 28 | 29 | # use toybox to protect *stat* access time reading 30 | if [ "$(toybox cat /sys/fs/selinux/enforce)" == "0" ]; then 31 | chmod 640 /sys/fs/selinux/enforce 32 | chmod 440 /sys/fs/selinux/policy 33 | fi 34 | 35 | # SafetyNet/Play Integrity 36 | { 37 | # late props which must be set after boot_completed for various OEMs 38 | until [ "$(getprop sys.boot_completed)" == "1" ]; do 39 | sleep 1 40 | done 41 | 42 | # Avoid breaking Realme fingerprint scanners 43 | resetprop_if_diff ro.boot.flash.locked 1 44 | 45 | # Avoid breaking Oppo fingerprint scanners 46 | resetprop_if_diff ro.boot.vbmeta.device_state locked 47 | 48 | # Avoid breaking OnePlus display modes/fingerprint scanners 49 | resetprop_if_diff vendor.boot.verifiedbootstate green 50 | 51 | # Avoid breaking OnePlus/Oppo display fingerprint scanners on OOS/ColorOS 12+ 52 | resetprop_if_diff ro.boot.verifiedbootstate green 53 | resetprop_if_diff ro.boot.veritymode enforcing 54 | resetprop_if_diff vendor.boot.vbmeta.device_state locked 55 | }& 56 | -------------------------------------------------------------------------------- /module/zygisk/arm64-v8a.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module/zygisk/arm64-v8a.so -------------------------------------------------------------------------------- /module/zygisk/armeabi-v7a.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module/zygisk/armeabi-v7a.so -------------------------------------------------------------------------------- /module/zygisk/x86.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module/zygisk/x86.so -------------------------------------------------------------------------------- /module/zygisk/x86_64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module/zygisk/x86_64.so -------------------------------------------------------------------------------- /module_resetprop/0.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/0.txt -------------------------------------------------------------------------------- /module_resetprop/1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/1.txt -------------------------------------------------------------------------------- /module_resetprop/2.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/2.txt -------------------------------------------------------------------------------- /module_resetprop/3.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/3.txt -------------------------------------------------------------------------------- /module_resetprop/META-INF/com/google/android/update-binary: -------------------------------------------------------------------------------- 1 | #!/sbin/sh 2 | 3 | ################# 4 | # Initialization 5 | ################# 6 | 7 | umask 022 8 | 9 | # echo before loading util_functions 10 | ui_print() { echo "$1"; } 11 | 12 | require_new_magisk() { 13 | ui_print "*******************************" 14 | ui_print " Please install Magisk v20.4+! " 15 | ui_print "*******************************" 16 | exit 1 17 | } 18 | 19 | ######################### 20 | # Load util_functions.sh 21 | ######################### 22 | 23 | OUTFD=$2 24 | ZIPFILE=$3 25 | 26 | mount /data 2>/dev/null 27 | 28 | [ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk 29 | . /data/adb/magisk/util_functions.sh 30 | [ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk 31 | 32 | install_module 33 | exit 0 34 | -------------------------------------------------------------------------------- /module_resetprop/META-INF/com/google/android/updater-script: -------------------------------------------------------------------------------- 1 | #MAGISK -------------------------------------------------------------------------------- /module_resetprop/bin/arm64-v8a/resetprop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/bin/arm64-v8a/resetprop -------------------------------------------------------------------------------- /module_resetprop/bin/armeabi-v7a/resetprop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/bin/armeabi-v7a/resetprop -------------------------------------------------------------------------------- /module_resetprop/bin/x86/resetprop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/bin/x86/resetprop -------------------------------------------------------------------------------- /module_resetprop/bin/x86_64/resetprop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/bin/x86_64/resetprop -------------------------------------------------------------------------------- /module_resetprop/classes.dex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/classes.dex -------------------------------------------------------------------------------- /module_resetprop/customize.sh: -------------------------------------------------------------------------------- 1 | # Error on < Android 8. 2 | if [ "$API" -lt 26 ]; then 3 | abort "!!! You can't use this module on Android < 8.0" 4 | fi 5 | 6 | # Copy default pif.json if it doesn't exist. 7 | if [ ! -e /data/adb/pif.json ]; then 8 | mv -f $MODPATH/pif.json /data/adb/pif.json 9 | ui_print "- Moved default pif.json file!" 10 | fi 11 | 12 | # SafetyNet-Fix module is obsolete and it's incompatible with PIF. 13 | if [ -d /data/adb/modules/safetynet-fix ]; then 14 | touch /data/adb/modules/safetynet-fix/remove 15 | ui_print "!!! SafetyNet-Fix module will be removed on next reboot." 16 | fi 17 | 18 | # MagiskHidePropsConf module is obsolete in Android 8+ but it shouldn't give issues. 19 | if [ -d /data/adb/modules/MagiskHidePropsConf ]; then 20 | ui_print "!!! WARNING, MagiskHidePropsConf module may cause issues with PIF" 21 | fi 22 | 23 | # use our resetprop 24 | mv -f $MODPATH/bin/$ABI/resetprop $MODPATH 25 | rm -rf $MODPATH/bin 26 | set_perm $MODPATH/resetprop root root 755 27 | -------------------------------------------------------------------------------- /module_resetprop/module.prop: -------------------------------------------------------------------------------- 1 | id=bypassKeyAttestation 2 | name=bypass key attestation 3 | version=v1.0.3 4 | versionCode=1 5 | author=pareto 6 | description=bypass key attestation 7 | -------------------------------------------------------------------------------- /module_resetprop/pif.json: -------------------------------------------------------------------------------- 1 | { 2 | "PRODUCT": "realme", 3 | "DEVICE": "RMX2032", 4 | "MANUFACTURER": "realme", 5 | "BRAND": "realme", 6 | "MODEL": "RMX2032", 7 | "FINGERPRINT": "realme/RMX2032/RMX2032:10/QKQ1.200209.002/1642670490:user/release-keys", 8 | "SECURITY_PATCH": "2022-01-05", 9 | "FIRST_API_LEVEL": 28 10 | } -------------------------------------------------------------------------------- /module_resetprop/post-fs-data.sh: -------------------------------------------------------------------------------- 1 | # Remove Play Services from Magisk Denylist when set to enforcing 2 | if magisk --denylist status; then 3 | magisk --denylist rm com.google.android.gms 4 | fi 5 | 6 | # Remove conflicting modules if installed 7 | if [ -d /data/adb/modules/safetynet-fix ]; then 8 | touch /data/adb/modules/safetynet-fix/remove 9 | fi 10 | 11 | RESETPROP="${0%/*}/resetprop" 12 | 13 | # Conditional early sensitive properties 14 | 15 | resetprop_if_diff() { 16 | local NAME=$1 17 | local EXPECTED=$2 18 | local CURRENT=$(resetprop $NAME) 19 | 20 | [ -z "$CURRENT" ] || [ "$CURRENT" == "$EXPECTED" ] || $RESETPROP -n $NAME $EXPECTED 21 | } 22 | 23 | resetprop_if_match() { 24 | local NAME=$1 25 | local CONTAINS=$2 26 | local VALUE=$3 27 | 28 | [[ "$(resetprop $NAME)" == *"$CONTAINS"* ]] && $RESETPROP -n $NAME $VALUE 29 | } 30 | 31 | # RootBeer, Microsoft 32 | resetprop_if_diff ro.build.tags release-keys 33 | 34 | # Samsung 35 | resetprop_if_diff ro.boot.warranty_bit 0 36 | resetprop_if_diff ro.vendor.boot.warranty_bit 0 37 | resetprop_if_diff ro.vendor.warranty_bit 0 38 | resetprop_if_diff ro.warranty_bit 0 39 | 40 | # OnePlus 41 | resetprop_if_diff ro.is_ever_orange 0 42 | 43 | # Other 44 | resetprop_if_diff ro.build.type user 45 | resetprop_if_diff ro.debuggable 0 46 | resetprop_if_diff ro.secure 1 47 | -------------------------------------------------------------------------------- /module_resetprop/service.sh: -------------------------------------------------------------------------------- 1 | # Conditional sensitive properties 2 | 3 | RESETPROP="${0%/*}/resetprop" 4 | 5 | resetprop_if_diff() { 6 | local NAME=$1 7 | local EXPECTED=$2 8 | local CURRENT=$(resetprop $NAME) 9 | 10 | [ -z "$CURRENT" ] || [ "$CURRENT" == "$EXPECTED" ] || $RESETPROP -n $NAME $EXPECTED 11 | } 12 | 13 | resetprop_if_match() { 14 | local NAME=$1 15 | local CONTAINS=$2 16 | local VALUE=$3 17 | 18 | [[ "$(resetprop $NAME)" == *"$CONTAINS"* ]] && $RESETPROP -n $NAME $VALUE 19 | } 20 | 21 | # Magisk recovery mode 22 | resetprop_if_match ro.bootmode recovery unknown 23 | resetprop_if_match ro.boot.mode recovery unknown 24 | resetprop_if_match vendor.boot.mode recovery unknown 25 | 26 | # SELinux 27 | if [ -n "$(resetprop ro.build.selinux)" ]; then 28 | $RESETPROP --delete ro.build.selinux 29 | fi 30 | 31 | # use toybox to protect *stat* access time reading 32 | if [ "$(toybox cat /sys/fs/selinux/enforce)" == "0" ]; then 33 | chmod 640 /sys/fs/selinux/enforce 34 | chmod 440 /sys/fs/selinux/policy 35 | fi 36 | 37 | # SafetyNet/Play Integrity 38 | { 39 | # late props which must be set after boot_completed for various OEMs 40 | until [ "$(getprop sys.boot_completed)" == "1" ]; do 41 | sleep 1 42 | done 43 | 44 | # Avoid breaking Realme fingerprint scanners 45 | resetprop_if_diff ro.boot.flash.locked 1 46 | 47 | # Avoid breaking Oppo fingerprint scanners 48 | resetprop_if_diff ro.boot.vbmeta.device_state locked 49 | 50 | # Avoid breaking OnePlus display modes/fingerprint scanners 51 | resetprop_if_diff vendor.boot.verifiedbootstate green 52 | 53 | # Avoid breaking OnePlus/Oppo display fingerprint scanners on OOS/ColorOS 12+ 54 | resetprop_if_diff ro.boot.verifiedbootstate green 55 | resetprop_if_diff ro.boot.veritymode enforcing 56 | resetprop_if_diff vendor.boot.vbmeta.device_state locked 57 | }& 58 | -------------------------------------------------------------------------------- /module_resetprop/zygisk/arm64-v8a.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/zygisk/arm64-v8a.so -------------------------------------------------------------------------------- /module_resetprop/zygisk/armeabi-v7a.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/zygisk/armeabi-v7a.so -------------------------------------------------------------------------------- /module_resetprop/zygisk/x86.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/zygisk/x86.so -------------------------------------------------------------------------------- /module_resetprop/zygisk/x86_64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doom-man/bypasskeyattestation/c1b1d16889b64ad7c76a28d40d60f343445c0073/module_resetprop/zygisk/x86_64.so -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # bypassKeyAttestation 2 | 3 | 饶过密钥认证 4 | 5 | ## 使用流程 6 | 1. magisk 安装bypassKeyAttestation模块 7 | 2. 配置排除列表,选中目标apk 8 | 3. 关闭“遵守排除列表(Enforce DenyList)” 9 | 4. 重启手机 10 | 11 | 12 | 如果遇到问题,关闭改其他所有模块, 重启。 13 | 14 | ## 15 | 尝试欺骗key attestation生成证书时 application_id和signatures 的数据,实际数据不是通过目标应用的接口去生成的,当前情况无法导出证书。 16 | 17 | 18 | > https://bbs.kanxue.com/thread-279799.htm 19 | 20 | 21 | 该模块无用啦, 仅学习 需要修复的可以看看其他以下项目: 22 | > https://github.com/5ec1cff/TrickyStore 23 | > https://github.com/chiteroman/PlayIntegrityFix 24 | > https://github.com/chiteroman/BootloaderSpoofer 25 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | gradlePluginPortal() 6 | } 7 | } 8 | dependencyResolutionManagement { 9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | } 15 | 16 | rootProject.name = "bypassKeyAttestation" 17 | include(":app") 18 | --------------------------------------------------------------------------------