├── .github └── workflows │ └── c-cpp.yml ├── .gitignore ├── .gitmodules ├── .travis.yml ├── LICENSE ├── README.md ├── compile-cmake.command ├── compile-cmake.sh ├── compile.command ├── compile.sh ├── copy-headers.sh ├── doc └── heap.md ├── iblessing ├── CMakeLists.txt ├── iblessing-core │ ├── common │ │ └── macro │ │ │ └── CommonDefines.hpp │ ├── core │ │ ├── disasm │ │ │ ├── ARM64Disasembler.cpp │ │ │ ├── ARM64Disasembler.hpp │ │ │ ├── ARM64Registers.cpp │ │ │ ├── ARM64Registers.hpp │ │ │ ├── ARM64ThreadState.cpp │ │ │ └── ARM64ThreadState.hpp │ │ ├── dyld │ │ │ ├── DyldSimulator.cpp │ │ │ └── DyldSimulator.hpp │ │ ├── foundation │ │ │ ├── CoreFoundation.cpp │ │ │ └── CoreFoundation.hpp │ │ ├── memory │ │ │ ├── VirtualMemory.cpp │ │ │ ├── VirtualMemory.hpp │ │ │ ├── VirtualMemoryV2.cpp │ │ │ └── VirtualMemoryV2.hpp │ │ ├── polyfill │ │ │ ├── mach-machine.h │ │ │ ├── mach-universal.cpp │ │ │ └── mach-universal.hpp │ │ ├── runtime │ │ │ ├── ARM64Runtime.cpp │ │ │ ├── ARM64Runtime.hpp │ │ │ ├── ObjcBlock.cpp │ │ │ ├── ObjcBlock.hpp │ │ │ ├── ObjcCategory.cpp │ │ │ ├── ObjcCategory.hpp │ │ │ ├── ObjcClass.cpp │ │ │ ├── ObjcClass.hpp │ │ │ ├── ObjcIvar.cpp │ │ │ ├── ObjcIvar.hpp │ │ │ ├── ObjcMethod.cpp │ │ │ ├── ObjcMethod.hpp │ │ │ ├── ObjcObject.cpp │ │ │ ├── ObjcObject.hpp │ │ │ ├── ObjcRuntime.cpp │ │ │ ├── ObjcRuntime.hpp │ │ │ ├── SimpleSimProcedure.cpp │ │ │ └── SimpleSimProcedure.hpp │ │ ├── structs │ │ │ ├── Foundation.cpp │ │ │ └── Foundation.hpp │ │ ├── symtab │ │ │ ├── StringTable.cpp │ │ │ ├── StringTable.hpp │ │ │ ├── Symbol.cpp │ │ │ ├── Symbol.hpp │ │ │ ├── SymbolTable.cpp │ │ │ └── SymbolTable.hpp │ │ └── unicorn │ │ │ ├── UnicornARM64Runtime.cpp │ │ │ └── UnicornARM64Runtime.hpp │ ├── infra │ │ ├── Map.hpp │ │ ├── Object.cpp │ │ ├── Object.hpp │ │ └── Vector.hpp │ ├── scanner │ │ ├── Scanner.cpp │ │ ├── Scanner.hpp │ │ ├── context │ │ │ ├── ScannerContext.cpp │ │ │ ├── ScannerContext.hpp │ │ │ ├── ScannerContextManager.cpp │ │ │ ├── ScannerContextManager.hpp │ │ │ ├── ScannerWorkDirManager.cpp │ │ │ └── ScannerWorkDirManager.hpp │ │ ├── dispatcher │ │ │ ├── ScannerDispatcher.cpp │ │ │ └── ScannerDispatcher.hpp │ │ └── driver │ │ │ ├── ScannerDisassemblyDriver.cpp │ │ │ └── ScannerDisassemblyDriver.hpp │ ├── v2 │ │ ├── analyser │ │ │ ├── wrapper │ │ │ │ ├── AntiWrapper.cpp │ │ │ │ ├── AntiWrapper.hpp │ │ │ │ ├── FunctionPrototype.cpp │ │ │ │ ├── FunctionPrototype.hpp │ │ │ │ ├── SimpleWrapperAnalyser.cpp │ │ │ │ └── SimpleWrapperAnalyser.hpp │ │ │ └── xref │ │ │ │ ├── FunctionXrefAnalyser.cpp │ │ │ │ └── FunctionXrefAnalyser.hpp │ │ ├── common │ │ │ └── ibtypes.h │ │ ├── dyld │ │ │ ├── dyld.cpp │ │ │ └── dyld.hpp │ │ ├── iblessing-core.cpp │ │ ├── iblessing-core.hpp │ │ ├── mach-o │ │ │ ├── mach-o.cpp │ │ │ └── mach-o.hpp │ │ ├── memory │ │ │ ├── memory.cpp │ │ │ └── memory.hpp │ │ ├── objc │ │ │ ├── objc.cpp │ │ │ └── objc.hpp │ │ ├── util │ │ │ ├── StringUtils.cpp │ │ │ ├── StringUtils.h │ │ │ └── termcolor.h │ │ └── vendor │ │ │ ├── capstone │ │ │ ├── arm.h │ │ │ ├── arm64.h │ │ │ ├── capstone.h │ │ │ ├── evm.h │ │ │ ├── m680x.h │ │ │ ├── m68k.h │ │ │ ├── mips.h │ │ │ ├── mos65xx.h │ │ │ ├── platform.h │ │ │ ├── ppc.h │ │ │ ├── sparc.h │ │ │ ├── systemz.h │ │ │ ├── tms320c64x.h │ │ │ ├── x86.h │ │ │ └── xcore.h │ │ │ ├── keystone │ │ │ ├── arm.h │ │ │ ├── arm64.h │ │ │ ├── evm.h │ │ │ ├── hexagon.h │ │ │ ├── keystone.h │ │ │ ├── mips.h │ │ │ ├── ppc.h │ │ │ ├── sparc.h │ │ │ ├── systemz.h │ │ │ └── x86.h │ │ │ └── unicorn │ │ │ ├── arm.h │ │ │ ├── arm64.h │ │ │ ├── m68k.h │ │ │ ├── mips.h │ │ │ ├── platform.h │ │ │ ├── sparc.h │ │ │ ├── unicorn.h │ │ │ └── x86.h │ └── vendor │ │ ├── httplib │ │ └── httplib.h │ │ ├── libs │ │ └── dummy │ │ └── rapidjson │ │ ├── allocators.h │ │ ├── cursorstreamwrapper.h │ │ ├── document.h │ │ ├── encodedstream.h │ │ ├── encodings.h │ │ ├── error │ │ ├── en.h │ │ └── error.h │ │ ├── filereadstream.h │ │ ├── filewritestream.h │ │ ├── fwd.h │ │ ├── internal │ │ ├── biginteger.h │ │ ├── clzll.h │ │ ├── diyfp.h │ │ ├── dtoa.h │ │ ├── ieee754.h │ │ ├── itoa.h │ │ ├── meta.h │ │ ├── pow10.h │ │ ├── regex.h │ │ ├── stack.h │ │ ├── strfunc.h │ │ ├── strtod.h │ │ └── swap.h │ │ ├── istreamwrapper.h │ │ ├── memorybuffer.h │ │ ├── memorystream.h │ │ ├── msinttypes │ │ ├── inttypes.h │ │ └── stdint.h │ │ ├── ostreamwrapper.h │ │ ├── pointer.h │ │ ├── prettywriter.h │ │ ├── rapidjson.h │ │ ├── reader.h │ │ ├── schema.h │ │ ├── stream.h │ │ ├── stringbuffer.h │ │ └── writer.h ├── iblessing-sample │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.h │ ├── ViewController.m │ ├── insecureUnserialization │ │ ├── InsecureUnSerialization.h │ │ └── InsecureUnSerialization.m │ ├── main.m │ └── methodChain │ │ ├── MethodChainClasses.h │ │ ├── MethodChainClasses.m │ │ ├── NSString+IBS.h │ │ └── NSString+IBS.m ├── iblessing.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ ├── iblessing-sample.xcscheme │ │ └── iblessing.xcscheme ├── iblessing │ ├── builtin │ │ ├── generator │ │ │ ├── Generator.cpp │ │ │ ├── Generator.hpp │ │ │ ├── GeneratorDispatcher.cpp │ │ │ ├── GeneratorDispatcher.hpp │ │ │ ├── IDAObjcMsgXREFGenerator.cpp │ │ │ ├── IDAObjcMsgXREFGenerator.hpp │ │ │ ├── IDASymbolWrapperNamingScriptGenerator.cpp │ │ │ ├── IDASymbolWrapperNamingScriptGenerator.hpp │ │ │ ├── IDASymbolicScriptGenerator.cpp │ │ │ ├── IDASymbolicScriptGenerator.hpp │ │ │ ├── ObjcMsgXREFReportGenerator.cpp │ │ │ ├── ObjcMsgXREFReportGenerator.hpp │ │ │ ├── ObjcMsgXREFServerGenerator.cpp │ │ │ ├── ObjcMsgXREFServerGenerator.hpp │ │ │ ├── ObjcMsgXREFStatisticsGenerator.cpp │ │ │ └── ObjcMsgXREFStatisticsGenerator.hpp │ │ ├── scanner │ │ │ ├── AppInfoScanner.hpp │ │ │ ├── AppInfoScanner.mm │ │ │ ├── CocoaAppInfoScanner.cpp │ │ │ ├── CocoaAppInfoScanner.hpp │ │ │ ├── ObjcClassXrefScanner.cpp │ │ │ ├── ObjcClassXrefScanner.hpp │ │ │ ├── ObjcMethodXrefScanner.cpp │ │ │ ├── ObjcMethodXrefScanner.hpp │ │ │ ├── ObjcUnserializationScanner.cpp │ │ │ ├── ObjcUnserializationScanner.hpp │ │ │ ├── PredicateScanner.cpp │ │ │ ├── PredicateScanner.hpp │ │ │ ├── SymbolWrapperScanner.cpp │ │ │ ├── SymbolWrapperScanner.hpp │ │ │ ├── SymbolXREFScanner.cpp │ │ │ ├── SymbolXREFScanner.hpp │ │ │ ├── assistance │ │ │ │ └── state │ │ │ │ │ ├── ProgramState.cpp │ │ │ │ │ ├── ProgramState.hpp │ │ │ │ │ ├── ProgramStateManager.cpp │ │ │ │ │ └── ProgramStateManager.hpp │ │ │ ├── domain │ │ │ │ ├── ObjcMethodCall.cpp │ │ │ │ ├── ObjcMethodCall.hpp │ │ │ │ ├── ObjcMethodChain.cpp │ │ │ │ └── ObjcMethodChain.hpp │ │ │ └── sub-scanner │ │ │ │ └── objc-msg-xref │ │ │ │ ├── ObjcReflectionInfo.hpp │ │ │ │ ├── ObjcReflectionInfoManager.cpp │ │ │ │ └── ObjcReflectionInfoManager.hpp │ │ └── serialization │ │ │ ├── ObjcMethodCallSnapshotSerializationManager.cpp │ │ │ ├── ObjcMethodCallSnapshotSerializationManager.hpp │ │ │ ├── ObjcMethodChainSerializationManager.cpp │ │ │ ├── ObjcMethodChainSerializationManager.hpp │ │ │ ├── SymbolWrapperSerializationManager.cpp │ │ │ └── SymbolWrapperSerializationManager.hpp │ ├── iblessing.entitlements │ ├── main.cpp │ ├── platform │ │ └── macos │ │ │ ├── csr.h │ │ │ ├── csrutil.cpp │ │ │ └── csrutil.hpp │ ├── registry │ │ ├── PluginRegistry.cpp │ │ └── PluginRegistry.h │ ├── tests │ │ ├── TestManager.cpp │ │ ├── TestManager.hpp │ │ ├── TestObjcMethodXrefs.cpp │ │ ├── TestObjcMethodXrefs.hpp │ │ ├── Tester.cpp │ │ ├── Tester.hpp │ │ └── benchmark │ │ │ └── iblessing-sample.benchmark │ └── vendor │ │ └── argparse │ │ └── argparse.h ├── plugin-example │ ├── example │ │ ├── classdump.cpp │ │ ├── classdump.hpp │ │ ├── otool.cpp │ │ └── otool.hpp │ ├── main.cpp │ └── plugin-example.entitlements └── plugins │ └── simprocedure │ └── iblessing-simple-simprocedure.json ├── resource └── images │ ├── ida_objc_msgSend_xrefs.png │ ├── ida_wrapped_call_after.png │ ├── ida_wrapped_call_before.png │ └── objc_msgSend_xref_server.png ├── run-test.command ├── run-test.sh ├── server └── index.html └── v2 ├── classdump.cpp └── otool.cpp /.github/workflows/c-cpp.yml: -------------------------------------------------------------------------------- 1 | name: C/C++ CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build-linux: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@master 14 | with: 15 | submodules: true 16 | - name: cmake 17 | run: ./compile-cmake.sh 18 | 19 | build-macos: 20 | runs-on: macos-latest 21 | steps: 22 | - uses: actions/checkout@master 23 | with: 24 | submodules: true 25 | - name: cmake 26 | run: ./compile-cmake.sh && ./run-test.sh 27 | 28 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "submodules/capstone"] 2 | path = submodules/capstone 3 | url = https://github.com/aquynh/capstone 4 | [submodule "submodules/unicorn"] 5 | path = submodules/unicorn 6 | url = https://github.com/unicorn-engine/unicorn 7 | [submodule "submodules/keystone"] 8 | path = submodules/keystone 9 | url = https://github.com/keystone-engine/keystone 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | sudo: false 3 | osx_image: xcode11.6 4 | 5 | git: 6 | submodules: true 7 | 8 | script: 9 | - ./compile-cmake.sh 10 | 11 | compiler: 12 | # - clang 13 | - gcc 14 | 15 | os: 16 | - linux 17 | - osx 18 | 19 | # before_deploy: 20 | # # Set up git user name and tag this commit 21 | # - git config --local user.name Soulghost 22 | # - git config --local user.email xiuyutong1994@163.com 23 | # - export TRAVIS_TAG=${TRAVIS_TAG:-$(date +'%Y%m%d%H%M%S')-$(git log --format=%h -1)} 24 | # - git tag $TRAVIS_TAG 25 | 26 | deploy: 27 | provider: releases 28 | prerelease: true 29 | api_key: $deploy_token 30 | file: 31 | - cmake-build/iblessing-darwin 32 | - cmake-build/iblessing-darwin-all 33 | - cmake-build/iblessing-linux 34 | - cmake-build/iblessing-linux-all 35 | - cmake-build/iblessing-framework-darwin.tar.gz 36 | - cmake-build/iblessing-framework-linux.tar.gz 37 | - iblessing/plugins/simprocedure/iblessing-simple-simprocedure.json 38 | skip_cleanup: true 39 | on: 40 | tags: true 41 | -------------------------------------------------------------------------------- /compile-cmake.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # todo: use fakeroot 4 | cd "$(dirname "$0")" 5 | 6 | set -xe 7 | cd submodules/capstone 8 | make 9 | cd ../.. 10 | 11 | cd submodules/unicorn 12 | UNICORN_ARCHS="arm aarch64 x86" ./make.sh 13 | cd ../.. 14 | 15 | cd submodules/keystone 16 | mkdir -p build 17 | cd build 18 | ../make-lib.sh 19 | cd ../../.. 20 | 21 | cp submodules/capstone/libcapstone.a iblessing/iblessing-core/vendor/libs/ 22 | cp submodules/unicorn/libunicorn.a iblessing/iblessing-core/vendor/libs/ 23 | cp submodules/keystone/build/llvm/lib/libkeystone.a iblessing/iblessing-core/vendor/libs/ 24 | 25 | mkdir -p cmake-build 26 | cd cmake-build 27 | 28 | if [[ "$OSTYPE" == "darwin"* ]]; then 29 | cmake -Diblessing.PLATFORM=macos ../iblessing 30 | else 31 | cmake -Diblessing.PLATFORM=linux ../iblessing 32 | fi 33 | 34 | cmake --build . 35 | 36 | if [[ "$OSTYPE" == "darwin"* ]]; then 37 | mv iblessing iblessing-darwin 38 | mv iblessing-all iblessing-darwin-all 39 | else 40 | mv iblessing iblessing-linux 41 | mv iblessing-all iblessing-linux-all 42 | fi 43 | 44 | cd .. 45 | sh ./copy-headers.sh 46 | 47 | cd cmake-build 48 | if [[ "$OSTYPE" == "darwin"* ]]; then 49 | tar -czvf iblessing-framework-darwin.tar.gz ./libiblessing-core.dylib include 50 | else 51 | tar -czvf iblessing-framework-linux.tar.gz ./libiblessing-core.so include 52 | fi 53 | 54 | cd .. 55 | echo "[+] iblessing is in cmake-build directory~" 56 | -------------------------------------------------------------------------------- /compile-cmake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname "$0")" 4 | 5 | ./compile-cmake.command 6 | -------------------------------------------------------------------------------- /compile.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # todo: use fakeroot 4 | cd "$(dirname "$0")" 5 | 6 | set -xe 7 | cd submodules/capstone 8 | make 9 | cd ../.. 10 | 11 | cd submodules/unicorn 12 | UNICORN_ARCHS="arm aarch64 x86" ./make.sh 13 | cd ../.. 14 | 15 | cd submodules/keystone 16 | mkdir -p build 17 | cd build 18 | ../make-lib.sh 19 | cd ../../.. 20 | 21 | cp submodules/capstone/libcapstone.a iblessing/iblessing/vendor/libs/ 22 | cp submodules/unicorn/libunicorn.a iblessing/iblessing/vendor/libs/ 23 | cp submodules/keystone/build/llvm/lib/libkeystone.a iblessing/iblessing/vendor/libs/ 24 | 25 | cd iblessing 26 | xcodebuild archive -target iblessing -configuration Release 27 | cd .. 28 | mkdir -p build 29 | mv iblessing/build/UninstalledProducts/macosx/iblessing build/ 30 | -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname "$0")" 4 | 5 | ./compile.command 6 | -------------------------------------------------------------------------------- /copy-headers.sh: -------------------------------------------------------------------------------- 1 | set -xe 2 | 3 | cd cmake-build 4 | true && rm -rf include 5 | mkdir include 6 | cd include 7 | mkdir iblessing-core 8 | rsync -a --prune-empty-dirs --include '*.h' --include '*.hpp' --include '*/' --exclude '*' ../../iblessing/iblessing-core/v2 ./iblessing-core 9 | rsync -a --prune-empty-dirs --include '*.h' --include '*.hpp' --include '*/' --exclude '*' ../../iblessing/iblessing-core/core ./iblessing-core 10 | rsync -a --prune-empty-dirs --include '*.h' --include '*.hpp' --include '*/' --exclude '*' ../../iblessing/iblessing-core/infra ./iblessing-core 11 | rsync -a --prune-empty-dirs --include '*.h' --include '*.hpp' --include '*/' --exclude '*' ../../iblessing/iblessing-core/common ./iblessing-core 12 | rsync -a --prune-empty-dirs --include '*.h' --include '*.hpp' --include '*/' --exclude '*' ../../iblessing/iblessing-core/scanner ./iblessing-core 13 | 14 | cd ../.. 15 | pwd -------------------------------------------------------------------------------- /doc/heap.md: -------------------------------------------------------------------------------- 1 | 1. x0 x1 使用特定的 mask 来区分内容,比如 self sel - 不够通用化 (SelfInstanceTrickMask, SelfSelectorMark) 2 | 2. 如果是 block 需要构造 x0 指向 block 对象,然后在堆上构建一个合法 block 对象,最后还要初始化入参 3 | 3. state 路径分裂只 restore 了 cpu 和栈,内存未回滚,因此存在一定的误差 4 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/common/macro/CommonDefines.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // CommonDefines.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef CommonDefines_hpp 10 | #define CommonDefines_hpp 11 | 12 | #define NS_IB_BEGIN namespace iblessing { 13 | #define NS_IB_END } 14 | #define CCASSERT(cond, desc) IBASSERT(cond, desc) 15 | #define IBASSERT(cond, desc) assert(cond) 16 | 17 | #endif /* CommonDefines_hpp */ 18 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/disasm/ARM64Disasembler.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ARM64Disasembler.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/23. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ARM64Disasembler.hpp" 10 | #include 11 | 12 | using namespace std; 13 | using namespace iblessing; 14 | 15 | ARM64Disassembler::ARM64Disassembler() { 16 | csh handle; 17 | assert(cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &handle) == CS_ERR_OK); 18 | // enable detail 19 | cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); 20 | this->handle = handle; 21 | } 22 | 23 | void ARM64Disassembler::startDisassembly(uint8_t *code, uint64_t address, ARM64DisassemblerCallback callback) { 24 | bool stop = false; 25 | while (!stop) { 26 | // dis 27 | cs_insn *insn = nullptr; 28 | size_t count = cs_disasm(handle, code, 4, address, 0, &insn); 29 | ARM64PCRedirect *redirect = nullptr; 30 | if (count != 1) { 31 | // dummy insn 32 | cs_insn *dummy_insn = new cs_insn(); 33 | dummy_insn->address = address; 34 | callback(false, dummy_insn, &stop, &redirect); 35 | delete dummy_insn; 36 | 37 | code += 4; 38 | address += 4; 39 | continue; 40 | } else { 41 | callback(true, insn, &stop, &redirect); 42 | } 43 | 44 | // free and go 45 | cs_free(insn, 1); 46 | insn = nullptr; 47 | 48 | if (redirect != nullptr) { 49 | code = redirect->code; 50 | address = redirect->address; 51 | delete redirect; 52 | } else { 53 | code += 4; 54 | address += 4; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/disasm/ARM64Disasembler.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ARM64Disasembler.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/23. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ARM64Disasembler_hpp 10 | #define ARM64Disasembler_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | NS_IB_BEGIN 17 | 18 | class ARM64PCRedirect { 19 | public: 20 | uint64_t address; 21 | uint8_t *code; 22 | 23 | ARM64PCRedirect(uint64_t address, uint8_t *code) : 24 | address(address), code(code) {} 25 | }; 26 | 27 | typedef std::function ARM64DisassemblerCallback; 28 | 29 | class ARM64Disassembler { 30 | public: 31 | ARM64Disassembler(); 32 | void startDisassembly(uint8_t *code, uint64_t address, ARM64DisassemblerCallback callback); 33 | 34 | private: 35 | csh handle; 36 | }; 37 | 38 | NS_IB_END 39 | 40 | #endif /* ARM64Disasembler_hpp */ 41 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/disasm/ARM64Registers.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ARM64Registers.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/23. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ARM64Registers.hpp" 10 | #include 11 | 12 | using namespace std; 13 | using namespace iblessing; 14 | 15 | #pragma mark - ARM64Register 16 | string ARM64Register::getDesc() { 17 | return "r?"; 18 | } 19 | 20 | string ARM64Register::getValueDesc() { 21 | return "?"; 22 | } 23 | 24 | uint64_t ARM64Register::getValue() { 25 | assert(false); 26 | return 0; 27 | } 28 | 29 | void ARM64Register::setValue(void *data, uint64_t size) { 30 | void *valueToFree = this->value; 31 | 32 | if (size > this->size) { 33 | // chunk src and assign 34 | void *dst = malloc(this->size); 35 | memcpy(dst, data, this->size); 36 | this->value = dst; 37 | available = true; 38 | } else { 39 | void *dst = malloc(this->size); 40 | bzero(dst, this->size); 41 | memcpy(dst, data, size); 42 | this->value = dst; 43 | available = true; 44 | } 45 | 46 | if (valueToFree && valueToFree != this->value) { 47 | free(valueToFree); 48 | } 49 | } 50 | 51 | bool ARM64Register::movFrom(ARM64Register *other) { 52 | if (!other->available) { 53 | available = false; 54 | return false; 55 | } 56 | 57 | // for apple's opt mark: mov x29, x29 58 | if (this == other) { 59 | return true; 60 | } 61 | 62 | this->setValue(other->value, other->size); 63 | return true; 64 | } 65 | 66 | #pragma mark - ARM64RegisterX 67 | string ARM64RegisterX::getDesc() { 68 | return StringUtils::format("x%d", num); 69 | } 70 | 71 | string ARM64RegisterX::getValueDesc() { 72 | return StringUtils::format("0x%llx", getValue()); 73 | } 74 | 75 | uint64_t ARM64RegisterX::getValue() { 76 | assert(!longRegister); 77 | if (__builtin_expect(this->size == 8, true)) { 78 | // x mode 79 | return *reinterpret_cast(value); 80 | } 81 | // w mode 82 | return *reinterpret_cast(value); 83 | } 84 | 85 | ARM64RegisterX* ARM64RegisterX::setW() { 86 | this->size = 4; 87 | return this; 88 | } 89 | 90 | ARM64RegisterX* ARM64RegisterX::setX() { 91 | this->size = 8; 92 | return this; 93 | } 94 | 95 | void ARM64RegisterX::invalidate() { 96 | available = false; 97 | } 98 | 99 | #pragma mark - ARM64RegisterSP 100 | string ARM64RegisterSP::getDesc() { 101 | return StringUtils::format("sp"); 102 | } 103 | 104 | string ARM64RegisterSP::getValueDesc() { 105 | return StringUtils::format("0x%llx", getValue()); 106 | } 107 | 108 | uint64_t ARM64RegisterSP::getValue() { 109 | return *reinterpret_cast(value); 110 | } 111 | 112 | void ARM64RegisterSP::invalidate() { 113 | available = false; 114 | } 115 | 116 | #pragma mark - ARM64RegisterD 117 | string ARM64RegisterD::getDesc() { 118 | return StringUtils::format("d%d", num); 119 | } 120 | 121 | string ARM64RegisterD::getValueDesc() { 122 | return StringUtils::format("0x%llx", getValue()); 123 | } 124 | 125 | uint64_t ARM64RegisterD::getValue() { 126 | assert(!longRegister); 127 | return *reinterpret_cast(value); 128 | } 129 | 130 | void ARM64RegisterD::invalidate() { 131 | available = false; 132 | } 133 | 134 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/disasm/ARM64Registers.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ARM64Registers.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/23. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ARM64Registers_hpp 10 | #define ARM64Registers_hpp 11 | 12 | #include 13 | 14 | NS_IB_BEGIN 15 | 16 | typedef enum ARM64RegisterType { 17 | ARM64_REG_TYPE_SP, 18 | ARM64_REG_TYPE_X, 19 | ARM64_REG_TYPE_D 20 | } ARM64RegisterType; 21 | 22 | class ARM64Register { 23 | public: 24 | bool available; 25 | bool longRegister; 26 | ARM64RegisterType type; 27 | std::string comment; 28 | 29 | uint64_t size; 30 | void *value; 31 | 32 | ARM64Register(bool available, uint64_t size, ARM64RegisterType type, std::string comment) : 33 | available(available), 34 | longRegister(false), 35 | comment(comment), 36 | size(size), 37 | value(0) 38 | {} 39 | 40 | virtual std::string getDesc(); 41 | virtual std::string getValueDesc(); 42 | virtual uint64_t getValue(); 43 | virtual void setValue(void *data, uint64_t size); 44 | virtual bool movFrom(ARM64Register *other); 45 | virtual void invalidate() = 0; 46 | }; 47 | 48 | class ARM64RegisterX : public ARM64Register { 49 | public: 50 | int num; 51 | 52 | ARM64RegisterX() : ARM64Register(false, 8, ARM64_REG_TYPE_X, "") {} 53 | 54 | ARM64RegisterX(int num) : ARM64RegisterX() { 55 | this->num = num; 56 | } 57 | 58 | ARM64RegisterX* setW(); 59 | ARM64RegisterX* setX(); 60 | virtual std::string getDesc(); 61 | virtual std::string getValueDesc(); 62 | virtual uint64_t getValue(); 63 | virtual void invalidate(); 64 | }; 65 | 66 | class ARM64RegisterSP : public ARM64Register { 67 | public: 68 | ARM64RegisterSP(uint64_t value) : ARM64Register(true, 8, ARM64_REG_TYPE_SP, "") { 69 | setValue(&value, 8); 70 | } 71 | 72 | virtual std::string getDesc(); 73 | virtual std::string getValueDesc(); 74 | virtual uint64_t getValue(); 75 | virtual void invalidate(); 76 | }; 77 | 78 | class ARM64RegisterD : public ARM64Register { 79 | public: 80 | int num; 81 | 82 | ARM64RegisterD() : ARM64Register(false, 8, ARM64_REG_TYPE_D, "") { 83 | 84 | } 85 | ARM64RegisterD(int num) : ARM64RegisterD() { 86 | this->num = num; 87 | } 88 | 89 | virtual std::string getDesc(); 90 | virtual std::string getValueDesc(); 91 | virtual uint64_t getValue(); 92 | virtual void invalidate(); 93 | }; 94 | 95 | NS_IB_END 96 | 97 | #endif /* ARM64Registers_hpp */ 98 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/disasm/ARM64ThreadState.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ARM64ThreadState.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/23. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ARM64ThreadState.hpp" 10 | #include "VirtualMemory.hpp" 11 | 12 | using namespace std; 13 | using namespace iblessing; 14 | 15 | ARM64ThreadState* ARM64ThreadState::_instance = nullptr; 16 | 17 | ARM64ThreadState* ARM64ThreadState::mainThreadState() { 18 | if (ARM64ThreadState::_instance == nullptr) { 19 | ARM64ThreadState::_instance = new ARM64ThreadState(); 20 | } 21 | return ARM64ThreadState::_instance; 22 | } 23 | 24 | ARM64ThreadState::ARM64ThreadState() { 25 | // init x registers 26 | x.clear(); 27 | for (int i = 0; i < 31; i++) { 28 | ARM64RegisterX *rx = new ARM64RegisterX(i); 29 | x.push_back(rx); 30 | } 31 | 32 | // init sp 33 | sp = new ARM64RegisterSP(VirtualMemory::progressDefault()->spUpperBound); 34 | 35 | // init d 36 | d.clear(); 37 | for (int i = 0; i < 32; i++) { 38 | ARM64RegisterD *rd = new ARM64RegisterD(i); 39 | d.push_back(rd); 40 | } 41 | } 42 | 43 | ARM64Register* ARM64ThreadState::getRegisterFromOprand(cs_arm64_op op) { 44 | assert(op.type == ARM64_OP_REG); 45 | return getRegisterFromRegType(op.reg); 46 | } 47 | 48 | ARM64Register* ARM64ThreadState::getRegisterFromRegType(arm64_reg reg) { 49 | if (reg >= ARM64_REG_X0 && reg <= ARM64_REG_X28) { 50 | return x[reg - ARM64_REG_X0]->setX(); 51 | } 52 | if (reg >= ARM64_REG_W0 && reg <= ARM64_REG_W30) { 53 | return x[reg - ARM64_REG_W0]->setW(); 54 | } 55 | if (reg == ARM64_REG_X29) { 56 | return x[29]->setX(); 57 | } 58 | if (reg == ARM64_REG_X30) { 59 | return x[30]->setX(); 60 | } 61 | if (reg == ARM64_REG_SP) { 62 | return sp; 63 | } 64 | 65 | // SMID 66 | if (reg >= ARM64_REG_D0 && reg <= ARM64_REG_D31) { 67 | return d[reg - ARM64_REG_D0]; 68 | } 69 | return nullptr; 70 | } 71 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/disasm/ARM64ThreadState.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ARM64ThreadState.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/23. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ARM64ThreadState_hpp 10 | #define ARM64ThreadState_hpp 11 | 12 | #include 13 | #include "ARM64Registers.hpp" 14 | #include 15 | #include 16 | 17 | NS_IB_BEGIN 18 | 19 | class ARM64ThreadState { 20 | public: 21 | static ARM64ThreadState* mainThreadState(); 22 | 23 | ARM64RegisterSP *sp; 24 | std::vector x; 25 | // SMID - Single Instruction Multiple Data 26 | std::vector d; 27 | ARM64Register* getRegisterFromOprand(cs_arm64_op op); 28 | ARM64Register* getRegisterFromRegType(arm64_reg reg); 29 | 30 | protected: 31 | ARM64ThreadState(); 32 | 33 | private: 34 | static ARM64ThreadState *_instance; 35 | }; 36 | 37 | NS_IB_END 38 | 39 | #endif /* ARM64ThreadState_hpp */ 40 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/dyld/DyldSimulator.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // DyldSimulator.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/4/27. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef DyldSimulator_hpp 10 | #define DyldSimulator_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | typedef std::function DyldBindHandler; 17 | 18 | NS_IB_BEGIN 19 | 20 | class DyldSimulator { 21 | public: 22 | static bool eachBind(uint8_t *mappedData, std::vector segmentHeaders, ib_dyld_info_command *dyldinfo, DyldBindHandler handler); 23 | }; 24 | 25 | NS_IB_END 26 | 27 | #endif /* DyldSimulator_hpp */ 28 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/foundation/CoreFoundation.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // CoreFoundation.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/13. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef CoreFoundation_hpp 10 | #define CoreFoundation_hpp 11 | 12 | #include 13 | #include 14 | 15 | NS_IB_BEGIN 16 | 17 | class CoreFoundation { 18 | public: 19 | static std::vector argumentsFromSignature(const char *signaure); 20 | static std::string resolveTypeEncoding(std::string &typeEncoding); 21 | }; 22 | 23 | NS_IB_END 24 | 25 | #endif /* CoreFoundation_hpp */ 26 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/memory/VirtualMemory.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // HeapStackMemory.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/23. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef HeapStackMemory_hpp 10 | #define HeapStackMemory_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | NS_IB_BEGIN 19 | 20 | class MemoryUnit { 21 | public: 22 | typedef enum MemoryType { 23 | Common = 0, 24 | ObjcClass, 25 | ObjcInstance, 26 | ObjcIvar, 27 | ObjcIvarTiny, 28 | Any 29 | } MemoryType; 30 | 31 | bool available; 32 | void *data; 33 | uint64_t size; 34 | MemoryType type; 35 | std::string comment; 36 | 37 | MemoryUnit(bool available, void *data, uint64_t size, std::string comment): 38 | MemoryUnit(available, data, Common, size, comment) {} 39 | 40 | MemoryUnit(bool available, void *data, MemoryType type, uint64_t size, std::string comment): 41 | available(available), 42 | data(data), 43 | type(type), 44 | size(size), 45 | comment(comment) {} 46 | }; 47 | 48 | class VirtualMemory { 49 | public: 50 | static VirtualMemory* progressDefault(); 51 | 52 | uint64_t spUpperBound; 53 | uint64_t spLowerBound; 54 | uint64_t heapCursor; 55 | uint64_t heapCopyCursor; 56 | 57 | // file 58 | uint8_t *mappedFile; 59 | uint64_t mappedSize; 60 | // vmaddr base 61 | uint64_t vmaddr_base; 62 | // symtab、dlsymtab、strtab's vmaddr base on LINKEDIT's vmaddr 63 | uint64_t linkedit_base; 64 | // bss 65 | uint64_t vmaddr_bss_start; 66 | uint64_t vmaddr_bss_end; 67 | // objc 68 | uint64_t objc_classlist_addr; 69 | uint64_t objc_classlist_size; 70 | uint64_t objc_catlist_addr; 71 | uint64_t objc_catlist_size; 72 | 73 | // extra info 74 | std::vector segmentHeaders; 75 | ib_dyld_info_command *dyldinfo; 76 | struct ib_segment_command_64 *textSeg; 77 | struct ib_section_64 *textSect; 78 | std::vector, std::pair>> allRelocs; 79 | 80 | void storeRegister(ARM64Register *reg, uint64_t address); 81 | uint64_t storeObject(void *data, uint64_t size, MemoryUnit::MemoryType type); 82 | bool writeBySize(void *data, uint64_t address, uint64_t size, MemoryUnit::MemoryType type); 83 | void* readBySize(uint64_t address, uint64_t size, bool fatal = true); 84 | void* readObject(uint64_t address, MemoryUnit::MemoryType type); 85 | char* readAsString(uint64_t address, uint64_t limit); 86 | char* readFromStringTable(uint64_t address); 87 | MemoryUnit* getMemoryUnit(uint64_t address); 88 | void reset(); 89 | 90 | bool isMappedFileHeapForAddress(uint64_t address); 91 | bool isVirtualHeapForAddress(uint64_t address); 92 | bool isRealHeapCopyForAddress(uint64_t address); 93 | bool isValidAddress(uint64_t address); 94 | 95 | VirtualMemory(); 96 | 97 | private: 98 | static VirtualMemory *_instance; 99 | std::unordered_map memory; 100 | }; 101 | 102 | NS_IB_END 103 | 104 | #endif /* HeapStackMemory_hpp */ 105 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/memory/VirtualMemoryV2.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // VirtualMemoryV2.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/3. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef VirtualMemoryV2_hpp 10 | #define VirtualMemoryV2_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | NS_IB_BEGIN 20 | 21 | class SymbolTable; 22 | class ObjcRuntime; 23 | 24 | class VirtualMemoryV2 { 25 | public: 26 | VirtualMemoryV2(std::shared_ptr fileMemory) : fileMemory(fileMemory) { 27 | uc = nullptr; 28 | } 29 | std::vector> textPatch; 30 | std::vector> dataPatch; 31 | 32 | static VirtualMemoryV2* progressDefault(); 33 | int loadWithMachOData(std::shared_ptr symtab, std::shared_ptr objcRuntime, uint8_t *mappedFile); 34 | int mappingMachOToEngine(std::shared_ptr symtab, std::shared_ptr objcRuntime, uc_engine *uc, uint8_t *mappedFile); 35 | void relocAllRegions(std::shared_ptr symtab, std::shared_ptr objcRuntime, uc_engine *target = nullptr); 36 | uint64_t read64(uint64_t address, bool *success); 37 | uint32_t read32(uint64_t address, bool *success); 38 | bool write32(uint64_t address, uint32_t value); 39 | bool write64(uint64_t address, uint64_t value); 40 | void* readBySize(uint64_t address, uint64_t size); 41 | char* readString(uint64_t address, uint64_t limit); 42 | CFString* readAsCFString(uint64_t address, bool needCheck = true); 43 | char* readAsCFStringContent(uint64_t address, bool needCheck = true); 44 | std::pair querySegInfo(uint64_t address); 45 | 46 | // shortcuts 47 | uint8_t* getMappedFile(); 48 | std::vector getSegmentHeaders(); 49 | struct ib_section_64* getTextSect(); 50 | struct ib_dyld_info_command* getDyldInfo(); 51 | uint64_t getBaseAddr(); 52 | uc_engine* getEngine(); 53 | std::shared_ptr getFileMemory(); 54 | 55 | private: 56 | VirtualMemoryV2() {}; 57 | 58 | protected: 59 | static VirtualMemoryV2 *_instance; 60 | std::map> addr2segInfo; 61 | uc_engine *uc; 62 | std::shared_ptr fileMemory; 63 | }; 64 | 65 | NS_IB_END 66 | 67 | #endif /* VirtualMemoryV2_hpp */ 68 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/polyfill/mach-universal.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // mach-universal.cpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/9. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "mach-universal.hpp" 10 | #include 11 | 12 | void ib_swap_mach_header_64(struct ib_mach_header_64 *mh, enum IBByteOrder target_byte_order) { 13 | assert(false); 14 | } 15 | 16 | void ib_swap_fat_header(struct ib_fat_header *mh, enum IBByteOrder target_byte_order) { 17 | mh->magic = __builtin_bswap32(mh->magic); 18 | mh->nfat_arch = __builtin_bswap32(mh->nfat_arch); 19 | } 20 | 21 | void ib_swap_fat_arch(struct ib_fat_arch *arch, enum IBByteOrder target_byte_order) { 22 | arch->cputype = __builtin_bswap32(arch->cputype); 23 | arch->cpusubtype = __builtin_bswap32(arch->cpusubtype); 24 | arch->offset = __builtin_bswap32(arch->offset); 25 | arch->size = __builtin_bswap32(arch->size); 26 | arch->align = __builtin_bswap32(arch->align); 27 | } 28 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/ARM64Runtime.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ARM64Runtime.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/23. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ARM64Runtime_hpp 10 | #define ARM64Runtime_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | NS_IB_BEGIN 18 | 19 | class ARM64Runtime { 20 | public: 21 | static void bindVirtualMemory(std::shared_ptr vm2); 22 | static bool handleInstruction(cs_insn *insn, std::string *insnDesc = nullptr, std::string *insnComment = nullptr, bool fatal = true); 23 | static bool handleSTP(cs_insn *insn, std::string *insnDesc, std::string *insnComment, bool fatal = true); 24 | static bool handleSTR(cs_insn *insn, std::string *insnDesc, std::string *insnComment, bool fatal = true); 25 | static bool handleADD(cs_insn *insn, std::string *insnDesc, std::string *insnComment, bool fatal = true); 26 | static bool handleADRP(cs_insn *insn, std::string *insnDesc, std::string *insnComment, bool fatal = true); 27 | static bool handleLDR(cs_insn *insn, std::string *insnDesc, std::string *insnComment, bool swMode = false, bool fatal = true); 28 | static bool handleADR(cs_insn *insn, std::string *insnDesc, std::string *insnComment, bool fatal = true); 29 | static bool handleMOV(cs_insn *insn, std::string *insnDesc, std::string *insnComment, bool fatal = true); 30 | static bool isRET(std::shared_ptr symtab, cs_insn *insn); 31 | }; 32 | 33 | NS_IB_END 34 | 35 | #endif /* ARM64Runtime_hpp */ 36 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/ObjcBlock.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcBlock.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/8/5. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ObjcBlock.hpp" 10 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/ObjcBlock.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcBlock.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/8/5. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcBlock_hpp 10 | #define ObjcBlock_hpp 11 | 12 | #include 13 | 14 | NS_IB_BEGIN 15 | 16 | enum BlockVariableType { 17 | BlockVariableTypePrimary = 0, 18 | BlockVariableTypeObjcClass, 19 | BlockVariableTypeUnknown 20 | }; 21 | 22 | struct BlockVariable { 23 | BlockVariableType type; 24 | ObjcClassRuntimeInfo *classInfo; 25 | }; 26 | 27 | class ObjcBlock : public Object { 28 | public: 29 | void *stack; 30 | uint64_t stackSize; 31 | uint64_t invoker; 32 | bool commonBlock; // is x0 = self 33 | std::vector args; 34 | }; 35 | 36 | NS_IB_END 37 | 38 | #endif /* ObjcBlock_hpp */ 39 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/ObjcCategory.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcCategory.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/10/3. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcCategory_hpp 10 | #define ObjcCategory_hpp 11 | 12 | #include 13 | 14 | NS_IB_BEGIN 15 | 16 | class ObjcRuntime; 17 | class SymbolTable; 18 | 19 | class ObjcCategoryDecoratedClass { 20 | public: 21 | bool isExternal; 22 | uint64_t address; 23 | ObjcClassRuntimeInfo *classInfo; 24 | }; 25 | 26 | class ObjcCategory { 27 | public: 28 | std::string name; 29 | std::shared_ptr decoratedClass; 30 | std::vector> instanceMethods; 31 | std::vector> classMethods; 32 | 33 | static std::shared_ptr loadFromAddress(std::shared_ptr symtab, ObjcRuntime *runtime, std::shared_ptr vm2, uint64_t address); 34 | }; 35 | 36 | NS_IB_END 37 | 38 | #endif /* ObjcCategory_hpp */ 39 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/ObjcClass.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcClass.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/3/10. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcClass_hpp 10 | #define ObjcClass_hpp 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | NS_IB_BEGIN 22 | 23 | class ObjcRuntime; 24 | 25 | class ObjcClassRuntimeInfo { 26 | public: 27 | ObjcClassRuntimeInfo() { 28 | isExternal = false; 29 | isSub = false; 30 | superClassInfo = nullptr; 31 | } 32 | 33 | bool isExternal; 34 | bool isSub; 35 | uint64_t address; 36 | std::string className; 37 | Vector methodList; 38 | Vector ivarList; 39 | ObjcClassRuntimeInfo *superClassInfo; 40 | std::unordered_map name2method; 41 | std::unordered_map name2ivar; 42 | std::unordered_map offset2ivar; 43 | 44 | static ObjcClassRuntimeInfo* realizeFromAddress(uint64_t address); 45 | static ObjcClassRuntimeInfo* realizeFromAddress(ObjcRuntime *runtime , std::shared_ptr symtab, std::shared_ptr virtualMemory, uint64_t address); 46 | static std::string classNameAtAddress(uint64_t address); 47 | static std::string classNameAtAddress(std::shared_ptr virtualMemory, uint64_t address); 48 | static uint64_t trickAlignForClassRO(uint64_t address); 49 | ObjcMethod* getMethodBySEL(std::string sel, bool fatal = false); 50 | Vector getAllMethods(); 51 | Vector getAllIvars(); 52 | }; 53 | 54 | NS_IB_END 55 | 56 | #endif /* ObjcClass_hpp */ 57 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/ObjcIvar.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcIvar.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/3/10. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ObjcIvar.hpp" 10 | 11 | using namespace std; 12 | using namespace iblessing; 13 | 14 | ObjcIvar::ObjcIvar(struct ib_ivar_t ivar) { 15 | raw = ivar; 16 | } 17 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/ObjcIvar.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcIvar.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/3/10. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcIvar_hpp 10 | #define ObjcIvar_hpp 11 | 12 | #include 13 | #include 14 | 15 | NS_IB_BEGIN 16 | 17 | enum IvarType { 18 | IvarTypeUnKnown = 0, 19 | IvarTypeObjcClass, 20 | IvarTypePrimary 21 | }; 22 | 23 | class ObjcClassRuntimeInfo; 24 | 25 | struct ib_ivar_t { 26 | int32_t *offset; 27 | const char *name; 28 | const char *type; 29 | // alignment is sometimes -1; use alignment() instead 30 | uint32_t alignment_raw; 31 | uint32_t size; 32 | }; 33 | 34 | class ObjcIvar : public Object { 35 | public: 36 | struct ib_ivar_t raw; 37 | ObjcClassRuntimeInfo *clazz; 38 | uint64_t offset; 39 | IvarType type; 40 | std::string typeName; 41 | 42 | ObjcIvar(struct ib_ivar_t ivar); 43 | }; 44 | 45 | class ObjcIvarObject : public Object { 46 | public: 47 | ObjcIvar *info; 48 | void *data; 49 | 50 | ObjcIvarObject(ObjcIvar *info): info(info) {} 51 | }; 52 | 53 | NS_IB_END 54 | 55 | #endif /* ObjcIvar_hpp */ 56 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/ObjcMethod.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcMethod.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/3/10. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ObjcMethod.hpp" 10 | #include "VirtualMemory.hpp" 11 | #include "SymbolTable.hpp" 12 | #include 13 | #include 14 | #include "ObjcClass.hpp" 15 | 16 | using namespace std; 17 | using namespace iblessing; 18 | 19 | ObjcMethod* ObjcMethod::createDummy(std::string name) { 20 | ObjcMethod *m = new ObjcMethod(); 21 | m->name = name; 22 | m->isDummy = true; 23 | m->classInfo = nullptr; 24 | return m; 25 | } 26 | 27 | string ObjcMethod::desc() { 28 | string className; 29 | if (classInfo) { 30 | className = classInfo->className; 31 | } 32 | 33 | string prefix = isClassMethod ? "+" : "-"; 34 | return StringUtils::format("%s[%s %s]", prefix.c_str(), className.c_str(), name.c_str()); 35 | } 36 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/ObjcMethod.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcMethod.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/3/10. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcMethod_hpp 10 | #define ObjcMethod_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | NS_IB_BEGIN 17 | 18 | class ObjcClassRuntimeInfo; 19 | 20 | class ObjcMethod : public Object { 21 | public: 22 | bool isClassMethod; 23 | bool isDummy; 24 | std::string name; 25 | std::string types; 26 | std::vector argTypes; 27 | uint64_t imp; 28 | ObjcClassRuntimeInfo *classInfo; 29 | 30 | ObjcMethod(): isDummy(false) {} 31 | static ObjcMethod* createDummy(std::string name); 32 | bool operator < (ObjcMethod *other) { 33 | return name < other->name; 34 | } 35 | 36 | std::string desc(); 37 | }; 38 | 39 | NS_IB_END 40 | 41 | #endif /* ObjcMethod_hpp */ 42 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/ObjcObject.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcObject.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/3/10. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ObjcObject.hpp" 10 | #include "VirtualMemory.hpp" 11 | #include "SymbolTable.hpp" 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | using namespace iblessing; 17 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/ObjcObject.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcObject.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/3/10. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcObject_hpp 10 | #define ObjcObject_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | NS_IB_BEGIN 18 | 19 | class ObjcObject { 20 | public: 21 | ObjcClassRuntimeInfo *isa; 22 | 23 | ObjcObject(ObjcClassRuntimeInfo *isa): isa(isa) {}; 24 | }; 25 | 26 | NS_IB_END 27 | 28 | #endif /* ObjcObject_hpp */ 29 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/ObjcRuntime.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcRuntime.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/25. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcRuntime_hpp 10 | #define ObjcRuntime_hpp 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | NS_IB_BEGIN 24 | 25 | class SymbolTable; 26 | 27 | class ObjcRuntime { 28 | public: 29 | ObjcRuntime(std::shared_ptr symtab, std::shared_ptr vm2) : symtab(symtab), vm2(vm2) {} 30 | 31 | std::unordered_map address2RuntimeInfo; 32 | std::unordered_map runtimeInfo2address; 33 | std::unordered_map externalClassRuntimeInfo; 34 | std::unordered_map name2ExternalClassRuntimeInfo; 35 | std::unordered_map ivarInstanceTrickAddress2RuntimeInfo; 36 | std::unordered_map heapInstanceTrickAddress2RuntimeInfo; 37 | std::unordered_map classList; 38 | std::unordered_map address2className; 39 | 40 | uint64_t classlist_addr; 41 | uint64_t classlist_size; 42 | uint64_t catlist_addr; 43 | uint64_t catlist_size; 44 | std::vector> categoryList; 45 | 46 | // block 47 | std::set blockISAs; 48 | std::unordered_map invoker2block; 49 | 50 | static ObjcRuntime* getInstance(); 51 | ObjcClassRuntimeInfo* getClassInfoByAddress(uint64_t address, bool needRealize = true); 52 | ObjcClassRuntimeInfo* evalReturnForIvarGetter(ObjcClassRuntimeInfo *targetClass, std::string getterSEL); 53 | void loadClassList(uint64_t vmaddr, uint64_t size); 54 | void loadCatList(std::shared_ptr symtab, uint64_t vmaddr, uint64_t size); 55 | uint64_t getClassAddrByName(std::string className); 56 | ObjcClassRuntimeInfo* getClassInfoByName(std::string className); 57 | bool isClassObjectAtAddress(uint64_t address); 58 | bool isValidClassInfo(ObjcClassRuntimeInfo *info); 59 | bool isExistMethod(std::string methodPrefix, std::string classExpr, std::string detectedSEL); 60 | ObjcMethod* inferNearestMethod(std::string methodPrefix, std::string classExpr, std::string detectedSEL); 61 | 62 | protected: 63 | std::shared_ptr vm2; 64 | std::shared_ptr symtab; 65 | static ObjcRuntime *_instance; 66 | }; 67 | 68 | NS_IB_END 69 | 70 | #endif /* ObjcRuntime_hpp */ 71 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/runtime/SimpleSimProcedure.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleSimProcedure.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/1/22. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef SimpleSimProcedure_hpp 10 | #define SimpleSimProcedure_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | NS_IB_BEGIN 17 | 18 | struct SimProcedureMethod { 19 | std::string name; 20 | std::string prefix; 21 | std::string type; 22 | std::string value; 23 | std::string rawValue; 24 | std::vector argTypes; 25 | }; 26 | 27 | struct SimProcedureEvalResult { 28 | bool success; 29 | bool isObjc; 30 | std::string value; 31 | std::string rawValue; 32 | std::string prefix; 33 | std::vector argTypes; 34 | 35 | static SimProcedureEvalResult failed() { 36 | SimProcedureEvalResult res; 37 | res.success = false; 38 | return res; 39 | } 40 | }; 41 | 42 | class SimpleSimProcedure : Object { 43 | public: 44 | static SimpleSimProcedure* getInstance(); 45 | 46 | // className -> 47 | std::map> simMethods; 48 | 49 | int loadSimpleSimProcedure(std::string filePath); 50 | int load(); 51 | SimProcedureEvalResult evalMethod(std::string className, std::string sel); 52 | 53 | private: 54 | static SimpleSimProcedure* _instance; 55 | }; 56 | 57 | NS_IB_END 58 | 59 | #endif /* SimpleSimProcedure_hpp */ 60 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/structs/Foundation.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Foundation.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/26. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "Foundation.hpp" 10 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/structs/Foundation.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Foundation.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/26. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef Foundation_hpp 10 | #define Foundation_hpp 11 | 12 | #include 13 | 14 | NS_IB_BEGIN 15 | 16 | typedef struct CFString { 17 | uint64_t isa; 18 | uint64_t info; 19 | uint64_t data; 20 | uint64_t length; 21 | } CFString __attribute__((aligned(8))); 22 | 23 | NS_IB_END 24 | 25 | #endif /* Foundation_hpp */ 26 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/symtab/StringTable.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // StringTable.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/20. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "StringTable.hpp" 10 | 11 | using namespace iblessing; 12 | 13 | StringTable* StringTable::_instance = nullptr; 14 | 15 | StringTable::~StringTable() { 16 | 17 | } 18 | 19 | StringTable* StringTable::getInstance() { 20 | if (StringTable::_instance == nullptr) { 21 | StringTable::_instance = new StringTable(); 22 | } 23 | return StringTable::_instance; 24 | } 25 | 26 | void StringTable::buildStringTable(uint64_t vmaddr, uint8_t *data, uint64_t size) { 27 | uint64_t cur = 0; 28 | this->vmaddr = vmaddr; 29 | stringData = data; 30 | stringDataSize = size; 31 | while (cur < size) { 32 | const char *symName = (const char *)data; 33 | uint64_t slen = strlen(symName); 34 | index2Names[cur] = std::string(symName); 35 | 36 | cur += slen + 1; 37 | data += slen + 1; 38 | } 39 | } 40 | 41 | std::string StringTable::getStringAtIndex(uint64_t index) { 42 | if (index2Names.find(index) == index2Names.end()) { 43 | if (index < stringDataSize) { 44 | return (const char *)(stringData + index); 45 | } 46 | assert(false); 47 | } 48 | return index2Names[index]; 49 | } 50 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/symtab/StringTable.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // StringTable.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/20. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef StringTable_hpp 10 | #define StringTable_hpp 11 | 12 | #include 13 | #include 14 | 15 | NS_IB_BEGIN 16 | 17 | class StringTable : public Object { 18 | public: 19 | uint64_t vmaddr; 20 | uint8_t *stringData; 21 | uint64_t stringDataSize; 22 | 23 | virtual ~StringTable(); 24 | static StringTable* getInstance(); 25 | 26 | void buildStringTable(uint64_t vmaddr, uint8_t *data, uint64_t size); 27 | std::string getStringAtIndex(uint64_t index); 28 | 29 | private: 30 | static StringTable *_instance; 31 | std::map index2Names; 32 | 33 | // StringTable(); 34 | }; 35 | 36 | NS_IB_END 37 | 38 | #endif /* StringTable_hpp */ 39 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/symtab/Symbol.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Symbol.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "Symbol.hpp" 10 | 11 | using namespace iblessing; 12 | 13 | Symbol::Symbol() { 14 | isStub = false; 15 | } 16 | 17 | Symbol::~Symbol() { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/symtab/Symbol.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Symbol.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef Symbol_hpp 10 | #define Symbol_hpp 11 | 12 | #include 13 | #include 14 | 15 | NS_IB_BEGIN 16 | 17 | class Symbol : public Object { 18 | public: 19 | Symbol(); 20 | virtual ~Symbol(); 21 | 22 | std::string name; 23 | bool isStub; 24 | struct ib_nlist_64 *info; 25 | }; 26 | 27 | NS_IB_END 28 | 29 | #endif /* Symbol_hpp */ 30 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/symtab/SymbolTable.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolTable.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef SymbolTable_hpp 10 | #define SymbolTable_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | NS_IB_BEGIN 22 | 23 | typedef struct SymbolRelocation { 24 | ib_scattered_relocation_info *info; 25 | uint64_t relocAddr; 26 | uint64_t relocValue; 27 | uint64_t relocSize; 28 | Symbol *relocSymbol; 29 | ib_section_64 *relocSection; 30 | } SymbolRelocation; 31 | 32 | class SymbolTable : public Object { 33 | public: 34 | SymbolTable(std::shared_ptr strtab) : strtab(strtab) {}; 35 | virtual ~SymbolTable(); 36 | static SymbolTable* getInstance(); 37 | 38 | void buildSymbolTable(uint8_t *data, uint64_t nSymbols); 39 | void buildDynamicSymbolTable(std::vector sectionHeaders, uint8_t *data, uint64_t nSymbols, uint8_t *mappedData); 40 | void insertSymbol(Symbol *symbol); 41 | void sync(); 42 | bool relocSymbol(uint64_t addr, uint64_t idx, ib_section_64 *section); 43 | uint64_t relocQuery(uint64_t addr); 44 | 45 | Symbol* getSymbolNearByAddress(uint64_t address); 46 | Symbol* getSymbolByAddress(uint64_t address); 47 | Symbol* getSymbolByName(std::string name); 48 | std::shared_ptr strtab; 49 | std::vector getAllRelocs(); 50 | 51 | private: 52 | Map symbolMap; 53 | std::map symbolMapCpp; 54 | std::map> name2symbol; 55 | std::vector> symbolTable; 56 | std::vector symbols; 57 | std::map relocs; 58 | 59 | static SymbolTable *_instance; 60 | SymbolTable(); 61 | }; 62 | 63 | NS_IB_END 64 | 65 | #endif /* SymbolTable_hpp */ 66 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/unicorn/UnicornARM64Runtime.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // UnicornARM64Runtime.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/6/2. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "UnicornARM64Runtime.hpp" 10 | #include "VirtualMemory.hpp" 11 | #include 12 | 13 | using namespace std; 14 | using namespace iblessing; 15 | 16 | #define Steps 9 17 | 18 | /** 19 | mov x0, #0x1000 20 | ret 21 | */ 22 | #define RETURNCODE "\x00\x00\x82\xd2\xc0\x03\x5f\xd6" 23 | 24 | static void hook_ins(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { 25 | void *buffer = malloc(16); 26 | uc_mem_read(uc, 0x1f0000000 - 0x30, buffer, 16); 27 | free(buffer); 28 | printf(">>> Tracing instruction at 0x%llx, instruction size = 0x%x\n", address, size); 29 | if (address == 0x100004088) { 30 | uc_mem_write(uc, 0x104637688, RETURNCODE, sizeof(RETURNCODE) - 1); 31 | } else if (address == 0x10000408c) { 32 | uint64_t x0 = 0; 33 | assert(uc_reg_read(uc, UC_ARM64_REG_X0, &x0) == UC_ERR_OK); 34 | assert(x0 == 0x1000); 35 | } 36 | } 37 | 38 | 39 | void UnicornARM64Runtime::testFunction(uint64_t address, uint64_t endaddr) { 40 | uc_engine *uc; 41 | uc_err err; 42 | 43 | printf("[*] Emulate ARM64 code\n"); 44 | err = uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc); 45 | if (err) { 46 | printf("[-] failed to open unicore engine, error %s\n", uc_strerror(err)); 47 | return; 48 | } 49 | 50 | uc_mem_map(uc, 0x0000000100000000, (uint64_t)1024 * 1024 * 1024 * 4, UC_PROT_ALL); 51 | 52 | VirtualMemory *vm = VirtualMemory::progressDefault(); 53 | uint64_t mainOff = address - vm->vmaddr_base; 54 | uint8_t *codes = vm->mappedFile + mainOff; 55 | uc_mem_write(uc, address, codes, Steps * sizeof(uint32_t)); 56 | 57 | uint64_t sp = 0x1f0000000; 58 | uint64_t x21 = 0x11111111, x22 = 0x22222222; 59 | uint64_t x20 = 0x33333333, x19 = 0x44444444; 60 | uc_reg_write(uc, UC_ARM64_REG_SP, &sp); 61 | uc_reg_write(uc, UC_ARM64_REG_X21, &x21); 62 | uc_reg_write(uc, UC_ARM64_REG_X22, &x22); 63 | uc_reg_write(uc, UC_ARM64_REG_X20, &x20); 64 | uc_reg_write(uc, UC_ARM64_REG_X19, &x19); 65 | 66 | uc_hook ins_trace; 67 | uc_hook_add(uc, &ins_trace, UC_HOOK_CODE, (void *)hook_ins, nullptr, address, address + Steps * sizeof(uint32_t), 0); 68 | 69 | err = uc_emu_start(uc, address, address + Steps * sizeof(uint32_t), -1, Steps); 70 | if (err) { 71 | printf("[-] failed to open unicore engine, error %s\n", uc_strerror(err)); 72 | return; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/core/unicorn/UnicornARM64Runtime.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // UnicornARM64Runtime.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/6/2. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef UnicornARM64Runtime_hpp 10 | #define UnicornARM64Runtime_hpp 11 | 12 | #include 13 | 14 | NS_IB_BEGIN 15 | 16 | class UnicornARM64Runtime { 17 | public: 18 | static void testFunction(uint64_t address, uint64_t endaddr); 19 | }; 20 | 21 | NS_IB_END 22 | 23 | #endif /* UnicornARM64Runtime_hpp */ 24 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/infra/Object.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // IBObject.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | 12 | using namespace iblessing; 13 | 14 | Object::Object() { 15 | _referenceCount = 1; 16 | } 17 | 18 | Object::~Object() { 19 | 20 | } 21 | 22 | void Object::retain() { 23 | assert(_referenceCount > 0); 24 | ++_referenceCount; 25 | } 26 | 27 | void Object::release() { 28 | assert(_referenceCount > 0); 29 | --_referenceCount; 30 | if (_referenceCount == 0) { 31 | delete this; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/infra/Object.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // IBObject.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/2/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef IBObject_hpp 10 | #define IBObject_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | NS_IB_BEGIN 22 | 23 | class Object { 24 | public: 25 | virtual ~Object(); 26 | 27 | void retain(); 28 | void release(); 29 | unsigned int getReferenceCount() const; 30 | 31 | protected: 32 | Object(); 33 | 34 | unsigned int _referenceCount; 35 | }; 36 | 37 | NS_IB_END 38 | 39 | #endif /* IBObject_hpp */ 40 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/scanner/Scanner.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Scanner.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/6/28. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "Scanner.hpp" 10 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/scanner/Scanner.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Scanner.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/6/28. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef Scanner_hpp 10 | #define Scanner_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | NS_IB_BEGIN 22 | 23 | class Scanner { 24 | public: 25 | Scanner(std::string identifier, std::string desc, bool isBinaryScanner = true): 26 | identifier(identifier), 27 | desc(desc), 28 | isBinaryScanner(isBinaryScanner), 29 | disasmDriver(nullptr) 30 | {} 31 | 32 | virtual ~Scanner() {}; 33 | std::map options; 34 | std::string inputPath; 35 | std::string outputPath; 36 | std::string fileName; 37 | std::string identifier; 38 | std::string desc; 39 | int jobs; 40 | 41 | // Binary Scanner 42 | bool isBinaryScanner; 43 | std::shared_ptr macho; 44 | std::shared_ptr memory; 45 | std::shared_ptr objc; 46 | std::shared_ptr dyld; 47 | 48 | // FIXME: buggy design pattern 49 | void *dispatcher; 50 | std::shared_ptr disasmDriver; 51 | 52 | virtual int start() = 0; 53 | }; 54 | 55 | NS_IB_END 56 | 57 | #endif /* Scanner_hpp */ 58 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/scanner/context/ScannerContext.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ScannerContext.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/8. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ScannerContext_hpp 10 | #define ScannerContext_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | NS_IB_BEGIN 23 | 24 | typedef enum scanner_err { 25 | SC_ERR_OK = 0, 26 | SC_ERR_UNKNOWN, 27 | SC_ERR_NEED_ARCHIVE_LIPO, 28 | SC_ERR_NEED_ARCHIVE_NOLIPO, 29 | SC_ERR_INVALID_ARGUMENTS, 30 | SC_ERR_INVALID_BINARY, // invalid binary file 31 | SC_ERR_RESET_WORK_DIR, 32 | SC_ERR_MAP_FAILED, 33 | SC_ERR_UNSUPPORT_ARCH, // only support aarch64 now 34 | SC_ERR_MACHO_MISSING_SEGMENT_TEXT, 35 | SC_ERR_MACHO_MISSING_SEGMENT_DYLD, 36 | SC_ERR_MACHO_MISSING_SEGMENT_SYMTAB, 37 | SC_ERR_MACHO_MISSING_SEGMENT_DYSYMTAB 38 | } scanner_err; 39 | 40 | class ScannerContext { 41 | public: 42 | ScannerContext(); 43 | 44 | std::string getBinaryPath(); 45 | static scanner_err headerDetector(std::string binaryPath, 46 | uint8_t **mappedFileOut, /** OUT */ 47 | uint64_t *sizeOut, /** OUT */ 48 | ib_mach_header_64 **hdrOut /** OUT */); 49 | static scanner_err headerDetector(uint8_t *mappedFile, /** OUT */ 50 | ib_mach_header_64 **hdrOut, /** OUT */ 51 | uint64_t *archOffsetOut = nullptr, /** OUT */ 52 | uint64_t *archSizeOut = nullptr /** OUT */); 53 | scanner_err archiveStaticLibraryAndRetry(std::string binaryPath, scanner_err analyzeError); 54 | scanner_err setupWithBinaryPath(std::string binaryPath, bool reentry = false); 55 | 56 | std::shared_ptr fileMemory; 57 | std::shared_ptr readonlyMemory; 58 | std::shared_ptr strtab; 59 | std::shared_ptr symtab; 60 | std::shared_ptr objcRuntime; 61 | 62 | private: 63 | std::string binaryPath; 64 | std::shared_ptr workDirManager; 65 | }; 66 | 67 | NS_IB_END 68 | 69 | #endif /* ScannerContext_hpp */ 70 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/scanner/context/ScannerContextManager.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ScannerContext.cpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/8. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ScannerContextManager.hpp" 10 | #include 11 | 12 | using namespace std; 13 | using namespace iblessing; 14 | 15 | ScannerContextManager* ScannerContextManager::_instance = nullptr; 16 | 17 | ScannerContextManager* ScannerContextManager::globalManager() { 18 | if (ScannerContextManager::_instance == nullptr) { 19 | ScannerContextManager::_instance = new ScannerContextManager(); 20 | } 21 | return ScannerContextManager::_instance; 22 | } 23 | 24 | ScannerContext* ScannerContextManager::getContextByBinaryPath(string binaryPath) { 25 | cout << "[*] ScannerContextManager get context for file " << binaryPath << endl; 26 | if (contextMap.find(binaryPath) != contextMap.end()) { 27 | cout << "[+] ScannerContextManager get context hit cache for file " << binaryPath << endl; 28 | return contextMap[binaryPath]; 29 | } 30 | 31 | ScannerContext *ctx = new ScannerContext(); 32 | scanner_err err = ctx->setupWithBinaryPath(binaryPath); 33 | if (err != SC_ERR_OK) { 34 | switch (err) { 35 | case SC_ERR_INVALID_BINARY: 36 | cout << termcolor::red << "[-] ScannerContextManager Error: invalid binary file " << binaryPath; 37 | cout << termcolor::reset << endl; 38 | return nullptr; 39 | case SC_ERR_MAP_FAILED: 40 | cout << termcolor::red << "[-] ScannerContextManager Error: mmap failed, please try again"; 41 | cout << termcolor::reset << endl; 42 | return nullptr; 43 | case SC_ERR_UNSUPPORT_ARCH: 44 | cout << termcolor::red << "[-] ScannerContextManager Error: unsupport arch, only support aarch64 now"; 45 | cout << termcolor::reset << endl; 46 | return nullptr; 47 | case SC_ERR_MACHO_MISSING_SEGMENT_DYLD: 48 | cout << termcolor::red << "[-] ScannerContextManager Error: DYLD_INFO_ONLY segment not found, maybe the mach-o file is corrupted"; 49 | cout << termcolor::reset << endl; 50 | return nullptr; 51 | case SC_ERR_MACHO_MISSING_SEGMENT_TEXT: 52 | cout << termcolor::red << "[-] ScannerContextManager Error: __TEXT segment not found, maybe the mach-o file is corrupted"; 53 | cout << termcolor::reset << endl; 54 | return nullptr; 55 | case SC_ERR_MACHO_MISSING_SEGMENT_SYMTAB: 56 | cout << termcolor::red << "[-] ScannerContextManager Error: SYMTAB segment not found, maybe the mach-o file is corrupted"; 57 | cout << endl; 58 | return nullptr; 59 | case SC_ERR_MACHO_MISSING_SEGMENT_DYSYMTAB: 60 | cout << termcolor::red << "[-] ScannerContextManager Error: DYSYMTAB segment not found, maybe the mach-o file is corrupted"; 61 | cout << endl; 62 | return nullptr; 63 | default: 64 | cout << termcolor::red << "[-] ScannerContextManager Error: ?"; 65 | return nullptr; 66 | } 67 | } 68 | 69 | contextMap[binaryPath] = ctx; 70 | cout << "[*] ScannerContextManager create new context for file " << binaryPath << endl; 71 | return ctx; 72 | } 73 | 74 | 75 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/scanner/context/ScannerContextManager.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ScannerContext.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/8. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ScannerContextManager_hpp 10 | #define ScannerContextManager_hpp 11 | 12 | #include "ScannerContext.hpp" 13 | #include 14 | 15 | NS_IB_BEGIN 16 | 17 | class ScannerContextManager { 18 | public: 19 | static ScannerContextManager* globalManager(); 20 | ScannerContext* getContextByBinaryPath(std::string binaryPath); 21 | 22 | private: 23 | static ScannerContextManager *_instance; 24 | std::map contextMap; 25 | }; 26 | 27 | NS_IB_END 28 | 29 | #endif /* ScannerContextManager_hpp */ 30 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/scanner/context/ScannerWorkDirManager.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ScannerWorkDirManager.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/9/25. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ScannerWorkDirManager.hpp" 10 | #include 11 | 12 | #ifdef IB_PLATFORM_DARWIN 13 | #include 14 | #else 15 | #include 16 | #endif 17 | 18 | #include 19 | 20 | using namespace std; 21 | using namespace iblessing; 22 | 23 | #ifdef IB_PLATFORM_DARWIN 24 | namespace fs = std::filesystem; 25 | #else 26 | namespace fs = std::experimental::filesystem; 27 | #endif 28 | 29 | ScannerWorkDirManager::ScannerWorkDirManager(string workDir) { 30 | if (!StringUtils::has_prefix(workDir, "/tmp/")) { 31 | workDir = "/tmp/"; 32 | } 33 | 34 | this->workDir = workDir; 35 | } 36 | 37 | string ScannerWorkDirManager::getWorkDir() { 38 | return this->workDir; 39 | } 40 | 41 | int ScannerWorkDirManager::resetWorkDir() { 42 | if (!cleanFolder() && !createWorkDirIfNeeded()) { 43 | return 0; 44 | } 45 | return 1; 46 | } 47 | 48 | int ScannerWorkDirManager::createWorkDirIfNeeded() { 49 | if (!fs::exists(workDir)) { 50 | if (mkdir(workDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ) != 0) { 51 | return 1; 52 | } 53 | return 0; 54 | } 55 | return 0; 56 | } 57 | 58 | int ScannerWorkDirManager::cleanFolder() { 59 | if (fs::exists(workDir)) { 60 | if (fs::remove_all(workDir)) { 61 | return 0; 62 | } else { 63 | return 1; 64 | } 65 | } 66 | return 0; 67 | } 68 | 69 | int ScannerWorkDirManager::createShadowFile(std::string filePath, char **shadowPathOut /** OUT */) { 70 | fs::path originPath = filePath; 71 | 72 | string fileName = originPath.filename(); 73 | fs::path shadowPath = StringUtils::path_join(workDir, fileName); 74 | 75 | try { 76 | fs::copy(originPath, shadowPath); 77 | *shadowPathOut = strdup(shadowPath.c_str()); 78 | } catch (fs::filesystem_error e) { 79 | return 1; 80 | } 81 | return 0; 82 | } 83 | 84 | std::vector ScannerWorkDirManager::findAllObjectFiles(std::set excludeFiles) { 85 | vector files; 86 | for (auto &p : fs::directory_iterator(workDir)) { 87 | string fileName = p.path().filename(); 88 | if (excludeFiles.find(fileName) != excludeFiles.end()) { 89 | continue;; 90 | } 91 | 92 | if (p.path().has_extension() && p.path().extension() == ".o") { 93 | files.push_back(p.path()); 94 | } 95 | } 96 | return files; 97 | } 98 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/scanner/context/ScannerWorkDirManager.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ScannerWorkDirManager.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/9/25. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ScannerWorkDirManager_hpp 10 | #define ScannerWorkDirManager_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | NS_IB_BEGIN 17 | 18 | class ScannerWorkDirManager { 19 | public: 20 | std::string getWorkDir(); 21 | ScannerWorkDirManager(std::string workDir); 22 | int resetWorkDir(); 23 | int createWorkDirIfNeeded(); 24 | int cleanFolder(); 25 | int createShadowFile(std::string filePath, char **shadowPathOut /** OUT */); 26 | std::vector findAllObjectFiles(std::set excludeFiles = {}); 27 | 28 | private: 29 | std::string workDir; 30 | }; 31 | 32 | NS_IB_END 33 | 34 | 35 | #endif /* ScannerWorkDirManager_hpp */ 36 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/scanner/dispatcher/ScannerDispatcher.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ScannerDispatcher.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/6/28. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ScannerDispatcher_hpp 10 | #define ScannerDispatcher_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | NS_IB_BEGIN; 19 | 20 | typedef std::function ScannerProvider; 21 | 22 | class ScannerDispatcher { 23 | public: 24 | int jobs; 25 | 26 | static ScannerDispatcher* getInstance(); 27 | void registerScanner(std::string scannerId, ScannerProvider provider); 28 | int start(std::string scannerId, std::map options, std::string inputPath, std::string outputPath); 29 | Scanner* prepareForScanner(std::string scannerId, std::map options, std::string inputPath, std::string outputPath, std::shared_ptr disasmDriver = nullptr); 30 | std::vector allScanners(); 31 | 32 | private: 33 | ScannerDispatcher(); 34 | static ScannerDispatcher *_instance; 35 | std::map scannerMap; 36 | }; 37 | 38 | NS_IB_END; 39 | 40 | #endif /* ScannerDispatcher_hpp */ 41 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/scanner/driver/ScannerDisassemblyDriver.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ScannerDisassemblyDriver.cpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/8. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ScannerDisassemblyDriver.hpp" 10 | 11 | using namespace std; 12 | using namespace iblessing; 13 | 14 | void ScannerDisassemblyDriver::subscribeDisassemblyEvent(void *scanner, ARM64DisassemblerCallback callback) { 15 | for (auto it = subscribers.begin(); it != subscribers.end(); it++) { 16 | if (scanner == it->first) { 17 | return; 18 | } 19 | } 20 | 21 | subscribers.push_back({scanner, callback}); 22 | } 23 | 24 | void ScannerDisassemblyDriver::unsubscribeDisassemblyEvent(void *scanner) { 25 | for (auto it = subscribers.begin(); it != subscribers.end(); it++) { 26 | if (it->first == scanner) { 27 | subscribers.erase(it); 28 | break; 29 | } 30 | } 31 | } 32 | 33 | void ScannerDisassemblyDriver::startDisassembly(uint8_t *code, uint64_t startAddress, uint64_t endAddress, ARM64DisassemblerCallback callback) { 34 | ARM64Disassembler disasm; 35 | disasm.startDisassembly(code, startAddress, [&](bool success, cs_insn *insn, bool *stop, ARM64PCRedirect **redirect) { 36 | if (callback) { 37 | callback(success, insn, stop, redirect); 38 | } 39 | 40 | if (insn->address >= endAddress) { 41 | printf("\n[*] ScannerDisassemblyDriver - reach to end of __text, stop\n"); 42 | *stop = true; 43 | } 44 | 45 | for (auto it = subscribers.begin(); it != subscribers.end(); it++) { 46 | it->second(success, insn, stop, redirect); 47 | } 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/scanner/driver/ScannerDisassemblyDriver.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ScannerDisassemblyDriver.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/8. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ScannerDisassemblyDriver_hpp 10 | #define ScannerDisassemblyDriver_hpp 11 | 12 | #include 13 | #include 14 | 15 | NS_IB_BEGIN 16 | 17 | class ScannerDisassemblyDriver { 18 | public: 19 | void subscribeDisassemblyEvent(void *scanner, ARM64DisassemblerCallback callback); 20 | void unsubscribeDisassemblyEvent(void *scanner); 21 | void startDisassembly(uint8_t *code, uint64_t startAddress, uint64_t endAddress, ARM64DisassemblerCallback callback = 0); 22 | 23 | private: 24 | // traverse >>> find, so we use vector instead of map 25 | std::vector> subscribers; 26 | }; 27 | 28 | NS_IB_END 29 | 30 | #endif /* ScannerDisassemblyDriver_hpp */ 31 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/analyser/wrapper/AntiWrapper.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // AntiWrapper.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/16. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "AntiWrapper.hpp" 10 | #include 11 | 12 | using namespace std; 13 | using namespace iblessing; 14 | 15 | string AntiWrapperRegLink::getIDAExpr() { 16 | if (current >= ARM64_REG_X0 && current <= ARM64_REG_X28) { 17 | return StringUtils::format("x%d", current - ARM64_REG_X0); 18 | } 19 | if (current >= ARM64_REG_X29 && current <= ARM64_REG_X30) { 20 | return StringUtils::format("x%d", 29 + current - ARM64_REG_X29); 21 | } 22 | assert(false); 23 | return ""; 24 | } 25 | 26 | AntiWrapperRegLink AntiWrapperRegLink::getRootSource() { 27 | AntiWrapperRegLink *cur = this; 28 | while (cur && cur->from != nullptr && cur->from != this) { 29 | cur = cur->from; 30 | } 31 | return *cur; 32 | } 33 | 34 | AntiWrapperRegLink* AntiWrapperRegLinkGraph::linkFromOp(cs_arm64_op op) { 35 | AntiWrapperRegLink *link = nullptr; 36 | if (op.reg >= ARM64_REG_X0 && op.reg <= ARM64_REG_X28) { 37 | link = x[op.reg - ARM64_REG_X0]; 38 | link->current = op.reg; 39 | } 40 | if (op.reg >= ARM64_REG_X29 && op.reg <= ARM64_REG_X30) { 41 | link = x[29 + op.reg - ARM64_REG_X29]; 42 | link->current = op.reg; 43 | } 44 | return link; 45 | } 46 | 47 | bool AntiWrapperRegLinkGraph::createLink(cs_arm64_op src, cs_arm64_op dst) { 48 | AntiWrapperRegLink *srcLink = linkFromOp(src); 49 | AntiWrapperRegLink *dstLink = linkFromOp(dst); 50 | if (!srcLink || !dstLink) { 51 | return false; 52 | } 53 | 54 | srcLink->active = true; 55 | dstLink->active = true; 56 | srcLink->from = dstLink; 57 | return true; 58 | } 59 | 60 | void AntiWrapper::setSimpleWrapper(AntiWrapperBlock block) { 61 | simpleWrapperMap[block.startAddr] = block; 62 | } 63 | 64 | bool AntiWrapper::isWrappedCall(uint64_t addr) { 65 | return simpleWrapperMap.find(addr) != simpleWrapperMap.end(); 66 | } 67 | 68 | AntiWrapperArgs AntiWrapper::performWrapperTransform(uint64_t addr, AntiWrapperArgs args) { 69 | AntiWrapperBlock &block = simpleWrapperMap[addr]; 70 | return block.transformer(block, args); 71 | } 72 | 73 | 74 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/analyser/wrapper/AntiWrapper.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // AntiWrapper.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/16. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef AntiWrapper_hpp 10 | #define AntiWrapper_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | NS_IB_BEGIN; 19 | 20 | struct AntiWrapperBlock; 21 | 22 | struct AntiWrapperArgs { 23 | uint64_t x[31]; 24 | uint8_t nArgs; 25 | }; 26 | 27 | struct AntiWrapperRegLink { 28 | bool active; 29 | arm64_reg current; 30 | AntiWrapperRegLink *from; 31 | 32 | AntiWrapperRegLink() { 33 | active = false; 34 | current = ARM64_REG_INVALID; 35 | from = nullptr; 36 | } 37 | 38 | AntiWrapperRegLink(const AntiWrapperRegLink &f) { 39 | active = f.active; 40 | current = f.current; 41 | from = f.from; 42 | } 43 | 44 | AntiWrapperRegLink getRootSource(); 45 | std::string getIDAExpr(); 46 | }; 47 | 48 | struct AntiWrapperRegLinkGraph { 49 | std::vector x{31, nullptr}; 50 | 51 | AntiWrapperRegLinkGraph() { 52 | for (int i = 0; i <= 28; i++) { 53 | this->x[i] = new AntiWrapperRegLink(); 54 | this->x[i]->current = static_cast((int)ARM64_REG_X0 + i); 55 | } 56 | for (int i = 29; i <= 30; i++) { 57 | this->x[i] = new AntiWrapperRegLink(); 58 | this->x[i]->current = static_cast((int)ARM64_REG_X29 + i - 29); 59 | } 60 | } 61 | 62 | ~AntiWrapperRegLinkGraph() { 63 | 64 | } 65 | 66 | AntiWrapperRegLink* linkFromOp(cs_arm64_op op); 67 | bool createLink(cs_arm64_op src, cs_arm64_op dst); 68 | }; 69 | 70 | typedef std::function AntiWrapperTransformer; 71 | 72 | struct AntiWrapperBlock { 73 | uint64_t startAddr; 74 | uint64_t endAddr; 75 | std::string symbolName; 76 | AntiWrapperTransformer transformer; 77 | AntiWrapperRegLinkGraph regLinkGraph; 78 | }; 79 | 80 | class AntiWrapper { 81 | public: 82 | std::map simpleWrapperMap; 83 | 84 | void setSimpleWrapper(AntiWrapperBlock block); 85 | bool isWrappedCall(uint64_t addr); 86 | AntiWrapperArgs performWrapperTransform(uint64_t addr, AntiWrapperArgs args); 87 | }; 88 | 89 | NS_IB_END; 90 | 91 | #endif /* AntiWrapper_hpp */ 92 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/analyser/wrapper/FunctionPrototype.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FunctionPrototype.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/28. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "FunctionPrototype.hpp" 10 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/analyser/wrapper/FunctionPrototype.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // FunctionPrototype.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/28. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef FunctionPrototype_hpp 10 | #define FunctionPrototype_hpp 11 | 12 | #include 13 | #include 14 | 15 | NS_IB_BEGIN 16 | 17 | struct FunctionProtoType { 18 | int nArgs; 19 | bool variadic; 20 | std::string returnType; 21 | std::vector argTypes; 22 | }; 23 | 24 | NS_IB_END 25 | 26 | #endif /* FunctionPrototype_hpp */ 27 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/analyser/wrapper/SimpleWrapperAnalyser.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleWrapperAnalyser.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2021/5/3. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef SimpleWrapperAnalyser_hpp 10 | #define SimpleWrapperAnalyser_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace iblessing { 21 | namespace Analyser { 22 | 23 | class SimpleWrapperAnalyser { 24 | public: 25 | SimpleWrapperAnalyser(std::shared_ptr macho, std::shared_ptr memory) : macho(macho), memory(memory) { 26 | init(); 27 | } 28 | static std::shared_ptr create(std::shared_ptr macho, std::shared_ptr memory); 29 | void init(); 30 | 31 | std::shared_ptr disasmDriver; 32 | std::vector targetSymbols; 33 | 34 | ib_return_t start(); 35 | std::pair isWrappedCall(uint64_t address); 36 | AntiWrapperArgs performWrapperTransform(uint64_t addr, AntiWrapperArgs args); 37 | 38 | // inner usage 39 | std::map symbol2proto; 40 | AntiWrapper antiWrapper; 41 | 42 | protected: 43 | std::shared_ptr macho; 44 | std::shared_ptr memory; 45 | pthread_mutex_t wrapperLock; 46 | uc_engine *uc; 47 | uc_hook memexp_hook; 48 | uc_context *ctx; 49 | 50 | 51 | uint64_t funcStartCursor = 0; 52 | uint8_t progressCur = 0; 53 | bool hasMemLoader = false; 54 | AntiWrapperRegLinkGraph currentGraph; 55 | }; 56 | 57 | }; 58 | }; 59 | 60 | #endif /* SimpleWrapperAnalyser_hpp */ 61 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/analyser/xref/FunctionXrefAnalyser.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // FunctionXrefAnalyser.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2021/5/3. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef SymbolXrefAnalyser_hpp 10 | #define SymbolXrefAnalyser_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace iblessing { 21 | namespace Analyser { 22 | 23 | struct SymbolXREF { 24 | std::string name; 25 | uint64_t startAddr; 26 | uint64_t endAddr; 27 | uint64_t symbolAddr; 28 | uint64_t callerAddr; 29 | 30 | bool operator < (const SymbolXREF &rhs) const { 31 | return startAddr < rhs.startAddr; 32 | } 33 | }; 34 | 35 | class FunctionXrefAnalyser { 36 | public: 37 | FunctionXrefAnalyser(std::shared_ptr macho, std::shared_ptr memory) : macho(macho), memory(memory) {} 38 | static std::shared_ptr create(std::shared_ptr macho, std::shared_ptr memory); 39 | 40 | std::shared_ptr disasmDriver; 41 | std::vector targetSymbols; 42 | std::map> xrefs; 43 | 44 | ib_return_t start(); 45 | protected: 46 | std::shared_ptr macho; 47 | std::shared_ptr memory; 48 | 49 | std::map> currentXREFs; 50 | uint64_t funcStartCursor = 0; 51 | uint8_t progressCur = 0; 52 | }; 53 | 54 | }; 55 | }; 56 | 57 | #endif /* SymbolXrefAnalyser_hpp */ 58 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/common/ibtypes.h: -------------------------------------------------------------------------------- 1 | // 2 | // iblessing-base.h 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/4/30. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef iblessing_base_h 10 | #define iblessing_base_h 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | typedef int ib_return_t; 17 | #define IB_SUCCESS 0 18 | #define IB_MACHO_LOAD_ERROR 1 19 | #define IB_MEMORY_LOAD_ERROR_INVALID_MACHO 2 20 | #define IB_INVALID_ARGUMENTS 3 21 | #define IB_UNINIT_MODULE 4 22 | #define IB_MEMORY_COPYOUT_ERROR 5 23 | #define IB_MEMORY_MAPPING_ERROR 6 24 | #define IB_OBJC_DATA_LOAD_ERROR 7 25 | 26 | #endif /* iblessing_base_h */ 27 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/dyld/dyld.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // dyld.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/4/30. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #include "dyld.hpp" 10 | #include 11 | 12 | using namespace std; 13 | using namespace iblessing; 14 | 15 | shared_ptr Dyld::create(shared_ptr macho, shared_ptr memory, shared_ptr objc) { 16 | return make_shared(macho, memory, objc); 17 | } 18 | 19 | void Dyld::doBindAll(DyldBindHandler handler) { 20 | shared_ptr fvm = memory->fileMemory; 21 | shared_ptr vm2 = memory->virtualMemory; 22 | shared_ptr symtab = macho->context->symtab; 23 | DyldSimulator::eachBind(fvm->mappedFile, fvm->segmentHeaders, fvm->dyldinfo, [&](uint64_t addr, uint8_t type, const char *symbolName, uint8_t symbolFlags, uint64_t addend, uint64_t libraryOrdinal, const char *msg) { 24 | uint64_t symbolAddr = addr + addend; 25 | 26 | // load non-lazy symbols 27 | vm2->write64(symbolAddr, symbolAddr); 28 | 29 | // record class info 30 | if (objc) { 31 | shared_ptr rt = objc->getRuntime(); 32 | if (string(symbolName).rfind("_OBJC_CLASS_$") == 0) { 33 | string className; 34 | vector parts = StringUtils::split(symbolName, '_'); 35 | if (parts.size() > 1) { 36 | className = parts[parts.size() - 1]; 37 | } else { 38 | className = symbolName; 39 | } 40 | 41 | ObjcClassRuntimeInfo *externalClassInfo = rt->getClassInfoByName(className); 42 | if (!externalClassInfo) { 43 | externalClassInfo = new ObjcClassRuntimeInfo(); 44 | externalClassInfo->className = className; 45 | externalClassInfo->isExternal = true; 46 | externalClassInfo->address = symbolAddr; 47 | rt->name2ExternalClassRuntimeInfo[externalClassInfo->className] = externalClassInfo; 48 | rt->runtimeInfo2address[externalClassInfo] = symbolAddr; 49 | } 50 | rt->externalClassRuntimeInfo[symbolAddr] = externalClassInfo; 51 | 52 | } else if (strcmp(symbolName, "__NSConcreteGlobalBlock") == 0 || 53 | strcmp(symbolName, "__NSConcreteStackBlock") == 0) { 54 | rt->blockISAs.insert(symbolAddr); 55 | } 56 | } 57 | 58 | // record symbol 59 | Symbol *sym = new Symbol(); 60 | sym->name = symbolName; 61 | struct ib_nlist_64 *nl = (struct ib_nlist_64 *)calloc(1, sizeof(ib_nlist_64)); 62 | nl->n_value = symbolAddr; 63 | sym->info = nl; 64 | symtab->insertSymbol(sym); 65 | 66 | if (handler) { 67 | handler(addr, type, symbolName, symbolFlags, addend, libraryOrdinal, msg); 68 | } 69 | }); 70 | } 71 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/dyld/dyld.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // dyld.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/4/30. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef dyld_hpp 10 | #define dyld_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace iblessing { 17 | 18 | class Dyld { 19 | public: 20 | Dyld(std::shared_ptr macho, std::shared_ptr memory, std::shared_ptr objc = nullptr) : 21 | macho(macho), memory(memory), objc(objc) {}; 22 | static std::shared_ptr create(std::shared_ptr macho, std::shared_ptr memory, std::shared_ptr objc = nullptr); 23 | 24 | void doBindAll(DyldBindHandler handler = nullptr); 25 | 26 | protected: 27 | std::shared_ptr macho; 28 | std::shared_ptr memory; 29 | std::shared_ptr objc; 30 | }; 31 | 32 | }; 33 | 34 | #endif /* dyld_hpp */ 35 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/iblessing-core.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // iblessing-core.cpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2021/5/1. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #include 10 | 11 | const char *VersionOfIblessingCore = "1.0"; 12 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/iblessing-core.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // iblessing.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/4/30. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef iblessing_h 10 | #define iblessing_h 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #endif /* iblessing_h */ 18 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/mach-o/mach-o.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // mach-o.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/4/30. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #include "mach-o.hpp" 10 | #include "ScannerContext.hpp" 11 | 12 | using namespace std; 13 | using namespace iblessing; 14 | 15 | shared_ptr MachO::createFromFile(std::string filePath) { 16 | shared_ptr macho = make_shared(filePath); 17 | return macho; 18 | } 19 | 20 | ib_return_t MachO::loadSync() { 21 | shared_ptr sc = make_shared(); 22 | scanner_err err = sc->setupWithBinaryPath(_filePath); 23 | if (err != SC_ERR_OK) { 24 | return IB_MACHO_LOAD_ERROR; 25 | } 26 | this->context = sc; 27 | return IB_SUCCESS; 28 | } 29 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/mach-o/mach-o.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // mach-o.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/4/30. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef mach_o_hpp 10 | #define mach_o_hpp 11 | 12 | #include 13 | #include 14 | 15 | namespace iblessing { 16 | 17 | class MachO { 18 | public: 19 | MachO(std::string filePath) : _filePath(filePath) {} 20 | 21 | std::shared_ptr context; 22 | 23 | static std::shared_ptr createFromFile(std::string filePath); 24 | ib_return_t loadSync(); 25 | 26 | private: 27 | std::string _filePath; 28 | }; 29 | 30 | }; 31 | 32 | #endif /* mach_o_hpp */ 33 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/memory/memory.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // memory.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/4/30. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef memory_hpp 10 | #define memory_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace iblessing { 17 | 18 | class Objc; 19 | 20 | class Memory { 21 | public: 22 | Memory(std::shared_ptr macho) : macho(macho) {} 23 | 24 | static std::shared_ptr createFromMachO(std::shared_ptr macho); 25 | ib_return_t loadSync(); 26 | ib_return_t copyToUCEngine(uc_engine *uc); 27 | 28 | std::shared_ptr fileMemory; 29 | std::shared_ptr virtualMemory; 30 | std::shared_ptr objc; 31 | 32 | protected: 33 | std::shared_ptr macho; 34 | }; 35 | 36 | }; 37 | 38 | #endif /* memory_hpp */ 39 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/objc/objc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // objc.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/4/30. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #include "objc.hpp" 10 | 11 | using namespace std; 12 | using namespace iblessing; 13 | 14 | Objc::Objc(shared_ptr macho, Memory *memory) { 15 | shared_ptr rt = make_shared(macho->context->symtab, memory->virtualMemory); 16 | this->runtime = rt; 17 | this->macho = macho; 18 | this->memory = memory; 19 | 20 | shared_ptr fileMemory = memory->fileMemory; 21 | rt->classlist_addr = fileMemory->objc_classlist_addr; 22 | rt->classlist_size = fileMemory->objc_classlist_size; 23 | rt->catlist_addr = fileMemory->objc_catlist_addr; 24 | rt->catlist_size = fileMemory->objc_catlist_size; 25 | } 26 | 27 | shared_ptr Objc::create(std::shared_ptr macho, Memory *memory) { 28 | return make_shared(macho, memory); 29 | } 30 | 31 | shared_ptr Objc::getRuntime() { 32 | return this->runtime; 33 | } 34 | 35 | ib_return_t Objc::loadClassList() { 36 | shared_ptr rt = this->runtime; 37 | rt->loadClassList(rt->classlist_addr, rt->classlist_size); 38 | return IB_SUCCESS; 39 | } 40 | 41 | ib_return_t Objc::loadCategoryList() { 42 | shared_ptr rt = this->runtime; 43 | if (rt->catlist_addr != 0 && rt->catlist_size != 0) { 44 | rt->loadCatList(macho->context->symtab, rt->catlist_addr, rt->catlist_size); 45 | } 46 | return IB_SUCCESS; 47 | } 48 | 49 | ib_return_t Objc::realizeClasses(ClassRealizeCallback callback) { 50 | unordered_map &classList = runtime->classList; 51 | uint64_t count = 0, total = classList.size(); 52 | for (auto it = classList.begin(); it != classList.end(); it++) { 53 | if (it->second == 0) { 54 | // printf("\t[+] skip bad class %s\n", it->first.c_str()); 55 | continue; 56 | } 57 | ObjcClassRuntimeInfo *classInfo = runtime->getClassInfoByAddress(it->second); 58 | count++; 59 | callback(classInfo, count, total); 60 | } 61 | return IB_SUCCESS; 62 | } 63 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/objc/objc.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // objc.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/4/30. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef objc_hpp 10 | #define objc_hpp 11 | 12 | #include 13 | #include 14 | 15 | namespace iblessing { 16 | 17 | typedef std::function ClassRealizeCallback; 18 | 19 | class Objc { 20 | public: 21 | Objc(std::shared_ptr macho, Memory *memory); 22 | 23 | static std::shared_ptr create(std::shared_ptr macho, Memory *memory); 24 | ib_return_t loadClassList(); 25 | ib_return_t loadCategoryList(); 26 | 27 | std::shared_ptr getRuntime(); 28 | ib_return_t realizeClasses(ClassRealizeCallback callback); 29 | 30 | protected: 31 | std::shared_ptr runtime; 32 | std::shared_ptr macho; 33 | Memory *memory; 34 | }; 35 | 36 | }; 37 | 38 | #endif /* objc_hpp */ 39 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/util/StringUtils.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | Copyright (c) 2014 cocos2d-x.org 3 | Copyright (c) 2014-2016 Chukong Technologies Inc. 4 | Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. 5 | 6 | http://www.cocos2d-x.org 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | ****************************************************************************/ 26 | 27 | #ifndef stringutils_h 28 | #define stringutils_h 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #ifdef _USRDLL 35 | #define CC_DLL __attribute__ ((visibility("default"))) 36 | #else 37 | #define CC_DLL 38 | #endif 39 | 40 | #if defined(__GNUC__) && (__GNUC__ >= 4) 41 | #define CC_FORMAT_PRINTF(formatPos, argPos) __attribute__((__format__(printf, formatPos, argPos))) 42 | #elif defined(__has_attribute) 43 | #if __has_attribute(format) 44 | #define CC_FORMAT_PRINTF(formatPos, argPos) __attribute__((__format__(printf, formatPos, argPos))) 45 | #endif // __has_attribute(format) 46 | #else 47 | #define CC_FORMAT_PRINTF(formatPos, argPos) 48 | #endif 49 | 50 | namespace StringUtils { 51 | std::string CC_DLL format(const char* format, ...) CC_FORMAT_PRINTF(1, 2); 52 | std::vector CC_DLL split(std::string s, char sep); 53 | bool CC_DLL has_prefix(const std::string &str, const std::string &prefix); 54 | bool CC_DLL has_suffix(const std::string &str, const std::string &suffix); 55 | std::string CC_DLL path_join(std::string a, std::string b); 56 | int countNonPrintablecharacters(const char *str, int limit); 57 | 58 | }; 59 | 60 | #endif /* stringutils_hpp */ 61 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/vendor/keystone/arm.h: -------------------------------------------------------------------------------- 1 | /* Keystone Assembler Engine */ 2 | /* By Nguyen Anh Quynh, 2016 */ 3 | 4 | #ifndef KEYSTONE_ARM_H 5 | #define KEYSTONE_ARM_H 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include "keystone.h" 12 | 13 | typedef enum ks_err_asm_arm { 14 | KS_ERR_ASM_ARM_INVALIDOPERAND = KS_ERR_ASM_ARCH, 15 | KS_ERR_ASM_ARM_MISSINGFEATURE, 16 | KS_ERR_ASM_ARM_MNEMONICFAIL, 17 | } ks_err_asm_arm; 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/vendor/keystone/arm64.h: -------------------------------------------------------------------------------- 1 | /* Keystone Assembler Engine */ 2 | /* By Nguyen Anh Quynh, 2016 */ 3 | 4 | #ifndef KEYSTONE_ARM64_H 5 | #define KEYSTONE_ARM64_H 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include "keystone.h" 12 | 13 | typedef enum ks_err_asm_arm64 { 14 | KS_ERR_ASM_ARM64_INVALIDOPERAND = KS_ERR_ASM_ARCH, 15 | KS_ERR_ASM_ARM64_MISSINGFEATURE, 16 | KS_ERR_ASM_ARM64_MNEMONICFAIL, 17 | } ks_err_asm_arm64; 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/vendor/keystone/evm.h: -------------------------------------------------------------------------------- 1 | /* Keystone Assembler Engine */ 2 | /* By Nguyen Anh Quynh, 2016-2018 */ 3 | 4 | #ifndef KEYSTONE_EVM_H 5 | #define KEYSTONE_EVM_H 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include "keystone.h" 12 | 13 | typedef enum ks_err_asm_evm { 14 | KS_ERR_ASM_EVM_INVALIDOPERAND = KS_ERR_ASM_ARCH, 15 | KS_ERR_ASM_EVM_MISSINGFEATURE, 16 | KS_ERR_ASM_EVM_MNEMONICFAIL, 17 | } ks_err_asm_evm; 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/vendor/keystone/hexagon.h: -------------------------------------------------------------------------------- 1 | /* Keystone Assembler Engine */ 2 | /* By Nguyen Anh Quynh, 2016 */ 3 | 4 | #ifndef KEYSTONE_HEXAGON_H 5 | #define KEYSTONE_HEXAGON_H 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include "keystone.h" 12 | 13 | typedef enum ks_err_asm_hexagon { 14 | KS_ERR_ASM_HEXAGON_INVALIDOPERAND = KS_ERR_ASM_ARCH, 15 | KS_ERR_ASM_HEXAGON_MISSINGFEATURE, 16 | KS_ERR_ASM_HEXAGON_MNEMONICFAIL, 17 | } ks_err_asm_hexagon; 18 | 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/vendor/keystone/mips.h: -------------------------------------------------------------------------------- 1 | /* Keystone Assembler Engine */ 2 | /* By Nguyen Anh Quynh, 2016 */ 3 | 4 | #ifndef KEYSTONE_MIPS_H 5 | #define KEYSTONE_MIPS_H 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include "keystone.h" 12 | 13 | typedef enum ks_err_asm_mips { 14 | KS_ERR_ASM_MIPS_INVALIDOPERAND = KS_ERR_ASM_ARCH, 15 | KS_ERR_ASM_MIPS_MISSINGFEATURE, 16 | KS_ERR_ASM_MIPS_MNEMONICFAIL, 17 | } ks_err_asm_mips; 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/vendor/keystone/ppc.h: -------------------------------------------------------------------------------- 1 | /* Keystone Assembler Engine */ 2 | /* By Nguyen Anh Quynh, 2016 */ 3 | 4 | #ifndef KEYSTONE_PPC_H 5 | #define KEYSTONE_PPC_H 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include "keystone.h" 12 | 13 | typedef enum ks_err_asm_ppc { 14 | KS_ERR_ASM_PPC_INVALIDOPERAND = KS_ERR_ASM_ARCH, 15 | KS_ERR_ASM_PPC_MISSINGFEATURE, 16 | KS_ERR_ASM_PPC_MNEMONICFAIL, 17 | } ks_err_asm_ppc; 18 | 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/vendor/keystone/sparc.h: -------------------------------------------------------------------------------- 1 | /* Keystone Assembler Engine */ 2 | /* By Nguyen Anh Quynh, 2016 */ 3 | 4 | #ifndef KEYSTONE_SPARC_H 5 | #define KEYSTONE_SPARC_H 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include "keystone.h" 12 | 13 | typedef enum ks_err_asm_sparc { 14 | KS_ERR_ASM_SPARC_INVALIDOPERAND = KS_ERR_ASM_ARCH, 15 | KS_ERR_ASM_SPARC_MISSINGFEATURE, 16 | KS_ERR_ASM_SPARC_MNEMONICFAIL, 17 | } ks_err_asm_sparc; 18 | 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/vendor/keystone/systemz.h: -------------------------------------------------------------------------------- 1 | /* Keystone Assembler Engine */ 2 | /* By Nguyen Anh Quynh, 2016 */ 3 | 4 | #ifndef KEYSTONE_SYSTEMZ_H 5 | #define KEYSTONE_SYSTEMZ_H 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include "keystone.h" 12 | 13 | typedef enum ks_err_asm_systemz { 14 | KS_ERR_ASM_SYSTEMZ_INVALIDOPERAND = KS_ERR_ASM_ARCH, 15 | KS_ERR_ASM_SYSTEMZ_MISSINGFEATURE, 16 | KS_ERR_ASM_SYSTEMZ_MNEMONICFAIL, 17 | } ks_err_asm_systemz; 18 | 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/vendor/keystone/x86.h: -------------------------------------------------------------------------------- 1 | /* Keystone Assembler Engine */ 2 | /* By Nguyen Anh Quynh, 2016 */ 3 | 4 | #ifndef KEYSTONE_X86_H 5 | #define KEYSTONE_X86_H 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #include "keystone.h" 12 | 13 | typedef enum ks_err_asm_x86 { 14 | KS_ERR_ASM_X86_INVALIDOPERAND = KS_ERR_ASM_ARCH, 15 | KS_ERR_ASM_X86_MISSINGFEATURE, 16 | KS_ERR_ASM_X86_MNEMONICFAIL, 17 | } ks_err_asm_x86; 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/vendor/unicorn/m68k.h: -------------------------------------------------------------------------------- 1 | /* Unicorn Emulator Engine */ 2 | /* By Nguyen Anh Quynh , 2014-2017 */ 3 | /* This file is released under LGPL2. 4 | See COPYING.LGPL2 in root directory for more details 5 | */ 6 | 7 | #ifndef UNICORN_M68K_H 8 | #define UNICORN_M68K_H 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #ifdef _MSC_VER 15 | #pragma warning(disable:4201) 16 | #endif 17 | 18 | //> M68K registers 19 | typedef enum uc_m68k_reg { 20 | UC_M68K_REG_INVALID = 0, 21 | 22 | UC_M68K_REG_A0, 23 | UC_M68K_REG_A1, 24 | UC_M68K_REG_A2, 25 | UC_M68K_REG_A3, 26 | UC_M68K_REG_A4, 27 | UC_M68K_REG_A5, 28 | UC_M68K_REG_A6, 29 | UC_M68K_REG_A7, 30 | 31 | UC_M68K_REG_D0, 32 | UC_M68K_REG_D1, 33 | UC_M68K_REG_D2, 34 | UC_M68K_REG_D3, 35 | UC_M68K_REG_D4, 36 | UC_M68K_REG_D5, 37 | UC_M68K_REG_D6, 38 | UC_M68K_REG_D7, 39 | 40 | UC_M68K_REG_SR, 41 | UC_M68K_REG_PC, 42 | 43 | UC_M68K_REG_ENDING, // <-- mark the end of the list of registers 44 | } uc_m68k_reg; 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/v2/vendor/unicorn/sparc.h: -------------------------------------------------------------------------------- 1 | /* Unicorn Emulator Engine */ 2 | /* By Nguyen Anh Quynh , 2014-2017 */ 3 | /* This file is released under LGPL2. 4 | See COPYING.LGPL2 in root directory for more details 5 | */ 6 | 7 | #ifndef UNICORN_SPARC_H 8 | #define UNICORN_SPARC_H 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | // GCC SPARC toolchain has a default macro called "sparc" which breaks 15 | // compilation 16 | #undef sparc 17 | 18 | #ifdef _MSC_VER 19 | #pragma warning(disable:4201) 20 | #endif 21 | 22 | //> SPARC registers 23 | typedef enum uc_sparc_reg { 24 | UC_SPARC_REG_INVALID = 0, 25 | 26 | UC_SPARC_REG_F0, 27 | UC_SPARC_REG_F1, 28 | UC_SPARC_REG_F2, 29 | UC_SPARC_REG_F3, 30 | UC_SPARC_REG_F4, 31 | UC_SPARC_REG_F5, 32 | UC_SPARC_REG_F6, 33 | UC_SPARC_REG_F7, 34 | UC_SPARC_REG_F8, 35 | UC_SPARC_REG_F9, 36 | UC_SPARC_REG_F10, 37 | UC_SPARC_REG_F11, 38 | UC_SPARC_REG_F12, 39 | UC_SPARC_REG_F13, 40 | UC_SPARC_REG_F14, 41 | UC_SPARC_REG_F15, 42 | UC_SPARC_REG_F16, 43 | UC_SPARC_REG_F17, 44 | UC_SPARC_REG_F18, 45 | UC_SPARC_REG_F19, 46 | UC_SPARC_REG_F20, 47 | UC_SPARC_REG_F21, 48 | UC_SPARC_REG_F22, 49 | UC_SPARC_REG_F23, 50 | UC_SPARC_REG_F24, 51 | UC_SPARC_REG_F25, 52 | UC_SPARC_REG_F26, 53 | UC_SPARC_REG_F27, 54 | UC_SPARC_REG_F28, 55 | UC_SPARC_REG_F29, 56 | UC_SPARC_REG_F30, 57 | UC_SPARC_REG_F31, 58 | UC_SPARC_REG_F32, 59 | UC_SPARC_REG_F34, 60 | UC_SPARC_REG_F36, 61 | UC_SPARC_REG_F38, 62 | UC_SPARC_REG_F40, 63 | UC_SPARC_REG_F42, 64 | UC_SPARC_REG_F44, 65 | UC_SPARC_REG_F46, 66 | UC_SPARC_REG_F48, 67 | UC_SPARC_REG_F50, 68 | UC_SPARC_REG_F52, 69 | UC_SPARC_REG_F54, 70 | UC_SPARC_REG_F56, 71 | UC_SPARC_REG_F58, 72 | UC_SPARC_REG_F60, 73 | UC_SPARC_REG_F62, 74 | UC_SPARC_REG_FCC0, // Floating condition codes 75 | UC_SPARC_REG_FCC1, 76 | UC_SPARC_REG_FCC2, 77 | UC_SPARC_REG_FCC3, 78 | UC_SPARC_REG_G0, 79 | UC_SPARC_REG_G1, 80 | UC_SPARC_REG_G2, 81 | UC_SPARC_REG_G3, 82 | UC_SPARC_REG_G4, 83 | UC_SPARC_REG_G5, 84 | UC_SPARC_REG_G6, 85 | UC_SPARC_REG_G7, 86 | UC_SPARC_REG_I0, 87 | UC_SPARC_REG_I1, 88 | UC_SPARC_REG_I2, 89 | UC_SPARC_REG_I3, 90 | UC_SPARC_REG_I4, 91 | UC_SPARC_REG_I5, 92 | UC_SPARC_REG_FP, 93 | UC_SPARC_REG_I7, 94 | UC_SPARC_REG_ICC, // Integer condition codes 95 | UC_SPARC_REG_L0, 96 | UC_SPARC_REG_L1, 97 | UC_SPARC_REG_L2, 98 | UC_SPARC_REG_L3, 99 | UC_SPARC_REG_L4, 100 | UC_SPARC_REG_L5, 101 | UC_SPARC_REG_L6, 102 | UC_SPARC_REG_L7, 103 | UC_SPARC_REG_O0, 104 | UC_SPARC_REG_O1, 105 | UC_SPARC_REG_O2, 106 | UC_SPARC_REG_O3, 107 | UC_SPARC_REG_O4, 108 | UC_SPARC_REG_O5, 109 | UC_SPARC_REG_SP, 110 | UC_SPARC_REG_O7, 111 | UC_SPARC_REG_Y, 112 | 113 | // special register 114 | UC_SPARC_REG_XCC, 115 | 116 | // pseudo register 117 | UC_SPARC_REG_PC, // program counter register 118 | 119 | UC_SPARC_REG_ENDING, // <-- mark the end of the list of registers 120 | 121 | // extras 122 | UC_SPARC_REG_O6 = UC_SPARC_REG_SP, 123 | UC_SPARC_REG_I6 = UC_SPARC_REG_FP, 124 | } uc_sparc_reg; 125 | 126 | #ifdef __cplusplus 127 | } 128 | #endif 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/vendor/libs/dummy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Soulghost/iblessing/ff14351de3f3c2155e8df47c26d4367523af7628/iblessing/iblessing-core/vendor/libs/dummy -------------------------------------------------------------------------------- /iblessing/iblessing-core/vendor/rapidjson/cursorstreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_CURSORSTREAMWRAPPER_H_ 16 | #define RAPIDJSON_CURSORSTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | 20 | #if defined(__GNUC__) 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(effc++) 23 | #endif 24 | 25 | #if defined(_MSC_VER) && _MSC_VER <= 1800 26 | RAPIDJSON_DIAG_PUSH 27 | RAPIDJSON_DIAG_OFF(4702) // unreachable code 28 | RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated 29 | #endif 30 | 31 | RAPIDJSON_NAMESPACE_BEGIN 32 | 33 | 34 | //! Cursor stream wrapper for counting line and column number if error exists. 35 | /*! 36 | \tparam InputStream Any stream that implements Stream Concept 37 | */ 38 | template > 39 | class CursorStreamWrapper : public GenericStreamWrapper { 40 | public: 41 | typedef typename Encoding::Ch Ch; 42 | 43 | CursorStreamWrapper(InputStream& is): 44 | GenericStreamWrapper(is), line_(1), col_(0) {} 45 | 46 | // counting line and column number 47 | Ch Take() { 48 | Ch ch = this->is_.Take(); 49 | if(ch == '\n') { 50 | line_ ++; 51 | col_ = 0; 52 | } else { 53 | col_ ++; 54 | } 55 | return ch; 56 | } 57 | 58 | //! Get the error line number, if error exists. 59 | size_t GetLine() const { return line_; } 60 | //! Get the error column number, if error exists. 61 | size_t GetColumn() const { return col_; } 62 | 63 | private: 64 | size_t line_; //!< Current Line 65 | size_t col_; //!< Current Column 66 | }; 67 | 68 | #if defined(_MSC_VER) && _MSC_VER <= 1800 69 | RAPIDJSON_DIAG_POP 70 | #endif 71 | 72 | #if defined(__GNUC__) 73 | RAPIDJSON_DIAG_POP 74 | #endif 75 | 76 | RAPIDJSON_NAMESPACE_END 77 | 78 | #endif // RAPIDJSON_CURSORSTREAMWRAPPER_H_ 79 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/vendor/rapidjson/filereadstream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FILEREADSTREAM_H_ 16 | #define RAPIDJSON_FILEREADSTREAM_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | RAPIDJSON_DIAG_OFF(unreachable-code) 25 | RAPIDJSON_DIAG_OFF(missing-noreturn) 26 | #endif 27 | 28 | RAPIDJSON_NAMESPACE_BEGIN 29 | 30 | //! File byte stream for input using fread(). 31 | /*! 32 | \note implements Stream concept 33 | */ 34 | class FileReadStream { 35 | public: 36 | typedef char Ch; //!< Character type (byte). 37 | 38 | //! Constructor. 39 | /*! 40 | \param fp File pointer opened for read. 41 | \param buffer user-supplied buffer. 42 | \param bufferSize size of buffer in bytes. Must >=4 bytes. 43 | */ 44 | FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { 45 | RAPIDJSON_ASSERT(fp_ != 0); 46 | RAPIDJSON_ASSERT(bufferSize >= 4); 47 | Read(); 48 | } 49 | 50 | Ch Peek() const { return *current_; } 51 | Ch Take() { Ch c = *current_; Read(); return c; } 52 | size_t Tell() const { return count_ + static_cast(current_ - buffer_); } 53 | 54 | // Not implemented 55 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 56 | void Flush() { RAPIDJSON_ASSERT(false); } 57 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 58 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 59 | 60 | // For encoding detection only. 61 | const Ch* Peek4() const { 62 | return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0; 63 | } 64 | 65 | private: 66 | void Read() { 67 | if (current_ < bufferLast_) 68 | ++current_; 69 | else if (!eof_) { 70 | count_ += readCount_; 71 | readCount_ = std::fread(buffer_, 1, bufferSize_, fp_); 72 | bufferLast_ = buffer_ + readCount_ - 1; 73 | current_ = buffer_; 74 | 75 | if (readCount_ < bufferSize_) { 76 | buffer_[readCount_] = '\0'; 77 | ++bufferLast_; 78 | eof_ = true; 79 | } 80 | } 81 | } 82 | 83 | std::FILE* fp_; 84 | Ch *buffer_; 85 | size_t bufferSize_; 86 | Ch *bufferLast_; 87 | Ch *current_; 88 | size_t readCount_; 89 | size_t count_; //!< Number of characters read 90 | bool eof_; 91 | }; 92 | 93 | RAPIDJSON_NAMESPACE_END 94 | 95 | #ifdef __clang__ 96 | RAPIDJSON_DIAG_POP 97 | #endif 98 | 99 | #endif // RAPIDJSON_FILESTREAM_H_ 100 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/vendor/rapidjson/filewritestream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_FILEWRITESTREAM_H_ 16 | #define RAPIDJSON_FILEWRITESTREAM_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(unreachable-code) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Wrapper of C file stream for output using fwrite(). 29 | /*! 30 | \note implements Stream concept 31 | */ 32 | class FileWriteStream { 33 | public: 34 | typedef char Ch; //!< Character type. Only support char. 35 | 36 | FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { 37 | RAPIDJSON_ASSERT(fp_ != 0); 38 | } 39 | 40 | void Put(char c) { 41 | if (current_ >= bufferEnd_) 42 | Flush(); 43 | 44 | *current_++ = c; 45 | } 46 | 47 | void PutN(char c, size_t n) { 48 | size_t avail = static_cast(bufferEnd_ - current_); 49 | while (n > avail) { 50 | std::memset(current_, c, avail); 51 | current_ += avail; 52 | Flush(); 53 | n -= avail; 54 | avail = static_cast(bufferEnd_ - current_); 55 | } 56 | 57 | if (n > 0) { 58 | std::memset(current_, c, n); 59 | current_ += n; 60 | } 61 | } 62 | 63 | void Flush() { 64 | if (current_ != buffer_) { 65 | size_t result = std::fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_); 66 | if (result < static_cast(current_ - buffer_)) { 67 | // failure deliberately ignored at this time 68 | // added to avoid warn_unused_result build errors 69 | } 70 | current_ = buffer_; 71 | } 72 | } 73 | 74 | // Not implemented 75 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; } 76 | char Take() { RAPIDJSON_ASSERT(false); return 0; } 77 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 78 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 79 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 80 | 81 | private: 82 | // Prohibit copy constructor & assignment operator. 83 | FileWriteStream(const FileWriteStream&); 84 | FileWriteStream& operator=(const FileWriteStream&); 85 | 86 | std::FILE* fp_; 87 | char *buffer_; 88 | char *bufferEnd_; 89 | char *current_; 90 | }; 91 | 92 | //! Implement specialized version of PutN() with memset() for better performance. 93 | template<> 94 | inline void PutN(FileWriteStream& stream, char c, size_t n) { 95 | stream.PutN(c, n); 96 | } 97 | 98 | RAPIDJSON_NAMESPACE_END 99 | 100 | #ifdef __clang__ 101 | RAPIDJSON_DIAG_POP 102 | #endif 103 | 104 | #endif // RAPIDJSON_FILESTREAM_H_ 105 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/vendor/rapidjson/internal/clzll.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_CLZLL_H_ 16 | #define RAPIDJSON_CLZLL_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #if defined(_MSC_VER) 21 | #include 22 | #if defined(_WIN64) 23 | #pragma intrinsic(_BitScanReverse64) 24 | #else 25 | #pragma intrinsic(_BitScanReverse) 26 | #endif 27 | #endif 28 | 29 | RAPIDJSON_NAMESPACE_BEGIN 30 | namespace internal { 31 | 32 | inline uint32_t clzll(uint64_t x) { 33 | // Passing 0 to __builtin_clzll is UB in GCC and results in an 34 | // infinite loop in the software implementation. 35 | RAPIDJSON_ASSERT(x != 0); 36 | 37 | #if defined(_MSC_VER) 38 | unsigned long r = 0; 39 | #if defined(_WIN64) 40 | _BitScanReverse64(&r, x); 41 | #else 42 | // Scan the high 32 bits. 43 | if (_BitScanReverse(&r, static_cast(x >> 32))) 44 | return 63 - (r + 32); 45 | 46 | // Scan the low 32 bits. 47 | _BitScanReverse(&r, static_cast(x & 0xFFFFFFFF)); 48 | #endif // _WIN64 49 | 50 | return 63 - r; 51 | #elif (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll) 52 | // __builtin_clzll wrapper 53 | return static_cast(__builtin_clzll(x)); 54 | #else 55 | // naive version 56 | uint32_t r; 57 | while (!(x & (static_cast(1) << 63))) { 58 | x <<= 1; 59 | ++r; 60 | } 61 | 62 | return r; 63 | #endif // _MSC_VER 64 | } 65 | 66 | #define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll 67 | 68 | } // namespace internal 69 | RAPIDJSON_NAMESPACE_END 70 | 71 | #endif // RAPIDJSON_CLZLL_H_ 72 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/vendor/rapidjson/internal/ieee754.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_IEEE754_ 16 | #define RAPIDJSON_IEEE754_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | class Double { 24 | public: 25 | Double() {} 26 | Double(double d) : d_(d) {} 27 | Double(uint64_t u) : u_(u) {} 28 | 29 | double Value() const { return d_; } 30 | uint64_t Uint64Value() const { return u_; } 31 | 32 | double NextPositiveDouble() const { 33 | RAPIDJSON_ASSERT(!Sign()); 34 | return Double(u_ + 1).Value(); 35 | } 36 | 37 | bool Sign() const { return (u_ & kSignMask) != 0; } 38 | uint64_t Significand() const { return u_ & kSignificandMask; } 39 | int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } 40 | 41 | bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } 42 | bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } 43 | bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; } 44 | bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } 45 | bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } 46 | 47 | uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } 48 | int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } 49 | uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } 50 | 51 | static int EffectiveSignificandSize(int order) { 52 | if (order >= -1021) 53 | return 53; 54 | else if (order <= -1074) 55 | return 0; 56 | else 57 | return order + 1074; 58 | } 59 | 60 | private: 61 | static const int kSignificandSize = 52; 62 | static const int kExponentBias = 0x3FF; 63 | static const int kDenormalExponent = 1 - kExponentBias; 64 | static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); 65 | static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); 66 | static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); 67 | static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); 68 | 69 | union { 70 | double d_; 71 | uint64_t u_; 72 | }; 73 | }; 74 | 75 | } // namespace internal 76 | RAPIDJSON_NAMESPACE_END 77 | 78 | #endif // RAPIDJSON_IEEE754_ 79 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/vendor/rapidjson/internal/pow10.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_POW10_ 16 | #define RAPIDJSON_POW10_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | RAPIDJSON_NAMESPACE_BEGIN 21 | namespace internal { 22 | 23 | //! Computes integer powers of 10 in double (10.0^n). 24 | /*! This function uses lookup table for fast and accurate results. 25 | \param n non-negative exponent. Must <= 308. 26 | \return 10.0^n 27 | */ 28 | inline double Pow10(int n) { 29 | static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes 30 | 1e+0, 31 | 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, 32 | 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, 33 | 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, 34 | 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, 35 | 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, 36 | 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, 37 | 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, 38 | 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, 39 | 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, 40 | 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, 41 | 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, 42 | 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, 43 | 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, 44 | 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, 45 | 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, 46 | 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 47 | }; 48 | RAPIDJSON_ASSERT(n >= 0 && n <= 308); 49 | return e[n]; 50 | } 51 | 52 | } // namespace internal 53 | RAPIDJSON_NAMESPACE_END 54 | 55 | #endif // RAPIDJSON_POW10_ 56 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/vendor/rapidjson/internal/strfunc.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ 16 | #define RAPIDJSON_INTERNAL_STRFUNC_H_ 17 | 18 | #include "../stream.h" 19 | #include 20 | 21 | RAPIDJSON_NAMESPACE_BEGIN 22 | namespace internal { 23 | 24 | //! Custom strlen() which works on different character types. 25 | /*! \tparam Ch Character type (e.g. char, wchar_t, short) 26 | \param s Null-terminated input string. 27 | \return Number of characters in the string. 28 | \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. 29 | */ 30 | template 31 | inline SizeType StrLen(const Ch* s) { 32 | RAPIDJSON_ASSERT(s != 0); 33 | const Ch* p = s; 34 | while (*p) ++p; 35 | return SizeType(p - s); 36 | } 37 | 38 | template <> 39 | inline SizeType StrLen(const char* s) { 40 | return SizeType(std::strlen(s)); 41 | } 42 | 43 | template <> 44 | inline SizeType StrLen(const wchar_t* s) { 45 | return SizeType(std::wcslen(s)); 46 | } 47 | 48 | //! Returns number of code points in a encoded string. 49 | template 50 | bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { 51 | RAPIDJSON_ASSERT(s != 0); 52 | RAPIDJSON_ASSERT(outCount != 0); 53 | GenericStringStream is(s); 54 | const typename Encoding::Ch* end = s + length; 55 | SizeType count = 0; 56 | while (is.src_ < end) { 57 | unsigned codepoint; 58 | if (!Encoding::Decode(is, &codepoint)) 59 | return false; 60 | count++; 61 | } 62 | *outCount = count; 63 | return true; 64 | } 65 | 66 | } // namespace internal 67 | RAPIDJSON_NAMESPACE_END 68 | 69 | #endif // RAPIDJSON_INTERNAL_STRFUNC_H_ 70 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/vendor/rapidjson/internal/swap.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_INTERNAL_SWAP_H_ 16 | #define RAPIDJSON_INTERNAL_SWAP_H_ 17 | 18 | #include "../rapidjson.h" 19 | 20 | #if defined(__clang__) 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(c++98-compat) 23 | #endif 24 | 25 | RAPIDJSON_NAMESPACE_BEGIN 26 | namespace internal { 27 | 28 | //! Custom swap() to avoid dependency on C++ header 29 | /*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. 30 | \note This has the same semantics as std::swap(). 31 | */ 32 | template 33 | inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { 34 | T tmp = a; 35 | a = b; 36 | b = tmp; 37 | } 38 | 39 | } // namespace internal 40 | RAPIDJSON_NAMESPACE_END 41 | 42 | #if defined(__clang__) 43 | RAPIDJSON_DIAG_POP 44 | #endif 45 | 46 | #endif // RAPIDJSON_INTERNAL_SWAP_H_ 47 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/vendor/rapidjson/memorybuffer.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_MEMORYBUFFER_H_ 16 | #define RAPIDJSON_MEMORYBUFFER_H_ 17 | 18 | #include "stream.h" 19 | #include "internal/stack.h" 20 | 21 | RAPIDJSON_NAMESPACE_BEGIN 22 | 23 | //! Represents an in-memory output byte stream. 24 | /*! 25 | This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. 26 | 27 | It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. 28 | 29 | Differences between MemoryBuffer and StringBuffer: 30 | 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. 31 | 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. 32 | 33 | \tparam Allocator type for allocating memory buffer. 34 | \note implements Stream concept 35 | */ 36 | template 37 | struct GenericMemoryBuffer { 38 | typedef char Ch; // byte 39 | 40 | GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} 41 | 42 | void Put(Ch c) { *stack_.template Push() = c; } 43 | void Flush() {} 44 | 45 | void Clear() { stack_.Clear(); } 46 | void ShrinkToFit() { stack_.ShrinkToFit(); } 47 | Ch* Push(size_t count) { return stack_.template Push(count); } 48 | void Pop(size_t count) { stack_.template Pop(count); } 49 | 50 | const Ch* GetBuffer() const { 51 | return stack_.template Bottom(); 52 | } 53 | 54 | size_t GetSize() const { return stack_.GetSize(); } 55 | 56 | static const size_t kDefaultCapacity = 256; 57 | mutable internal::Stack stack_; 58 | }; 59 | 60 | typedef GenericMemoryBuffer<> MemoryBuffer; 61 | 62 | //! Implement specialized version of PutN() with memset() for better performance. 63 | template<> 64 | inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { 65 | std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); 66 | } 67 | 68 | RAPIDJSON_NAMESPACE_END 69 | 70 | #endif // RAPIDJSON_MEMORYBUFFER_H_ 71 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/vendor/rapidjson/memorystream.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_MEMORYSTREAM_H_ 16 | #define RAPIDJSON_MEMORYSTREAM_H_ 17 | 18 | #include "stream.h" 19 | 20 | #ifdef __clang__ 21 | RAPIDJSON_DIAG_PUSH 22 | RAPIDJSON_DIAG_OFF(unreachable-code) 23 | RAPIDJSON_DIAG_OFF(missing-noreturn) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Represents an in-memory input byte stream. 29 | /*! 30 | This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. 31 | 32 | It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. 33 | 34 | Differences between MemoryStream and StringStream: 35 | 1. StringStream has encoding but MemoryStream is a byte stream. 36 | 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. 37 | 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). 38 | \note implements Stream concept 39 | */ 40 | struct MemoryStream { 41 | typedef char Ch; // byte 42 | 43 | MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} 44 | 45 | Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } 46 | Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } 47 | size_t Tell() const { return static_cast(src_ - begin_); } 48 | 49 | Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 50 | void Put(Ch) { RAPIDJSON_ASSERT(false); } 51 | void Flush() { RAPIDJSON_ASSERT(false); } 52 | size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } 53 | 54 | // For encoding detection only. 55 | const Ch* Peek4() const { 56 | return Tell() + 4 <= size_ ? src_ : 0; 57 | } 58 | 59 | const Ch* src_; //!< Current read position. 60 | const Ch* begin_; //!< Original head of the string. 61 | const Ch* end_; //!< End of stream. 62 | size_t size_; //!< Size of the stream. 63 | }; 64 | 65 | RAPIDJSON_NAMESPACE_END 66 | 67 | #ifdef __clang__ 68 | RAPIDJSON_DIAG_POP 69 | #endif 70 | 71 | #endif // RAPIDJSON_MEMORYBUFFER_H_ 72 | -------------------------------------------------------------------------------- /iblessing/iblessing-core/vendor/rapidjson/ostreamwrapper.h: -------------------------------------------------------------------------------- 1 | // Tencent is pleased to support the open source community by making RapidJSON available. 2 | // 3 | // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4 | // 5 | // Licensed under the MIT License (the "License"); you may not use this file except 6 | // in compliance with the License. You may obtain a copy of the License at 7 | // 8 | // http://opensource.org/licenses/MIT 9 | // 10 | // Unless required by applicable law or agreed to in writing, software distributed 11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 | // specific language governing permissions and limitations under the License. 14 | 15 | #ifndef RAPIDJSON_OSTREAMWRAPPER_H_ 16 | #define RAPIDJSON_OSTREAMWRAPPER_H_ 17 | 18 | #include "stream.h" 19 | #include 20 | 21 | #ifdef __clang__ 22 | RAPIDJSON_DIAG_PUSH 23 | RAPIDJSON_DIAG_OFF(padded) 24 | #endif 25 | 26 | RAPIDJSON_NAMESPACE_BEGIN 27 | 28 | //! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. 29 | /*! 30 | The classes can be wrapped including but not limited to: 31 | 32 | - \c std::ostringstream 33 | - \c std::stringstream 34 | - \c std::wpstringstream 35 | - \c std::wstringstream 36 | - \c std::ifstream 37 | - \c std::fstream 38 | - \c std::wofstream 39 | - \c std::wfstream 40 | 41 | \tparam StreamType Class derived from \c std::basic_ostream. 42 | */ 43 | 44 | template 45 | class BasicOStreamWrapper { 46 | public: 47 | typedef typename StreamType::char_type Ch; 48 | BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} 49 | 50 | void Put(Ch c) { 51 | stream_.put(c); 52 | } 53 | 54 | void Flush() { 55 | stream_.flush(); 56 | } 57 | 58 | // Not implemented 59 | char Peek() const { RAPIDJSON_ASSERT(false); return 0; } 60 | char Take() { RAPIDJSON_ASSERT(false); return 0; } 61 | size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } 62 | char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } 63 | size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } 64 | 65 | private: 66 | BasicOStreamWrapper(const BasicOStreamWrapper&); 67 | BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); 68 | 69 | StreamType& stream_; 70 | }; 71 | 72 | typedef BasicOStreamWrapper OStreamWrapper; 73 | typedef BasicOStreamWrapper WOStreamWrapper; 74 | 75 | #ifdef __clang__ 76 | RAPIDJSON_DIAG_POP 77 | #endif 78 | 79 | RAPIDJSON_NAMESPACE_END 80 | 81 | #endif // RAPIDJSON_OSTREAMWRAPPER_H_ 82 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // iblessing-sample 4 | // 5 | // Created by soulghost on 2020/7/25. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (nonatomic, strong) UIWindow *window; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // iblessing-sample 4 | // 5 | // Created by soulghost on 2020/7/25. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 18 | return YES; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // iblessing-sample 4 | // 5 | // Created by soulghost on 2020/7/25. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // iblessing-sample 4 | // 5 | // Created by soulghost on 2020/7/25. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | } 21 | 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/insecureUnserialization/InsecureUnSerialization.h: -------------------------------------------------------------------------------- 1 | // 2 | // InsecureUnSerialization.h 3 | // iblessing-sample 4 | // 5 | // Created by soulghost on 2020/8/18. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface InsecureUnSerialization : NSObject 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/insecureUnserialization/InsecureUnSerialization.m: -------------------------------------------------------------------------------- 1 | // 2 | // InsecureUnSerialization.m 3 | // iblessing-sample 4 | // 5 | // Created by soulghost on 2020/8/18. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #import "InsecureUnSerialization.h" 10 | 11 | @implementation InsecureUnSerialization 12 | 13 | - (int)insecureArchiverData { 14 | NSString *idx = @"comehere"; 15 | static dispatch_once_t onceToken; 16 | dispatch_once(&onceToken, ^{ 17 | [self insecureArchiverData]; 18 | }); 19 | 20 | 21 | [NSKeyedUnarchiver unarchiveObjectWithData:nil]; 22 | 23 | return 1000; 24 | } 25 | 26 | - (void)insecureArchiverFile { 27 | [NSKeyedUnarchiver unarchiveObjectWithFile:nil]; 28 | } 29 | 30 | - (void)insecureArchiverTopLevel { 31 | [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:nil error:nil]; 32 | 33 | 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // iblessing-sample 4 | // 5 | // Created by soulghost on 2020/7/25. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | NSString * appDelegateClassName; 14 | @autoreleasepool { 15 | // Setup code that might create autoreleased objects goes here. 16 | appDelegateClassName = NSStringFromClass([AppDelegate class]); 17 | } 18 | return UIApplicationMain(argc, argv, nil, appDelegateClassName); 19 | } 20 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/methodChain/MethodChainClasses.h: -------------------------------------------------------------------------------- 1 | // 2 | // MethodChainClasses.h 3 | // iblessing-sample 4 | // 5 | // Created by soulghost on 2020/7/25. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface IBImportTest : NSObject 12 | 13 | @end 14 | 15 | @interface IBSRoot : NSObject 16 | 17 | + (void)rootClassMethodCallFromPrimary; 18 | + (void)rootClassMethodCallFromInstanceClass; 19 | + (void)rootClassMethodCallFromReflection; 20 | + (void)rootClassMethodCallFromCategoryMethod; 21 | - (void)rootInstanceMethodCallFromAllocate; 22 | - (void)rootInstanceMethodCallFromIvar; 23 | - (void)rootInstanceMethodFromBranchTrue; 24 | - (void)rootInstanceMethodFromBranchFalse; 25 | - (void)rootInstanceMethodFromSwitchTableA; 26 | - (void)rootInstanceMethodFromSwitchTableB; 27 | - (void)rootInstanceMethodFromSwitchTableC; 28 | 29 | @end 30 | 31 | @interface IBSCallTester : NSObject 32 | 33 | @property (nonatomic, assign) int paddingEvil1; 34 | @property (nonatomic, assign) char paddingEvil12; 35 | @property (nonatomic, strong) IBSRoot *root; 36 | @property (nonatomic, assign) char paddingEvil2; 37 | @property (nonatomic, assign) bool paddingEvil3; 38 | @property (nonatomic, copy) void (^ivarBlock)(void); 39 | 40 | + (void)testPrimaryCallToRootClassMethodAncestor; 41 | + (void)testReflectionCallToRootClassMethodAncestor; 42 | + (void)testInstanceCallToRootClassMethodAncestor; 43 | - (void)selfCallChain1; 44 | - (void)selfCallChain2; 45 | - (void)selfCallChain3; 46 | - (void)testLoop; 47 | 48 | - (void)testIvarCall; 49 | - (void)testAllocateCall; 50 | - (void)testLocalBlockOnStack; 51 | 52 | @end 53 | 54 | @interface BlockSubA : NSObject 55 | 56 | - (void)testAllocateCapture; 57 | - (void)testCallFromBlockArg; 58 | 59 | @end 60 | 61 | @interface BlockSubB : NSObject 62 | 63 | - (void)testCallFromblockArg; 64 | 65 | @end 66 | 67 | @interface BranchCall : NSObject 68 | 69 | @end 70 | 71 | @interface TrapObject : NSObject 72 | 73 | @end 74 | 75 | @interface CategoryObject : NSObject 76 | 77 | @end 78 | 79 | @interface CategoryObject (Addon) 80 | 81 | - (void)callFromInstance; 82 | + (void)callFromClass; 83 | 84 | @end 85 | 86 | @interface InstanceObject : NSObject 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/methodChain/NSString+IBS.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+IBS.h 3 | // iblessing-sample 4 | // 5 | // Created by soulghost on 2020/10/3. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSString (IBS) 14 | 15 | - (NSString *)ibs_encoding; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /iblessing/iblessing-sample/methodChain/NSString+IBS.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+IBS.m 3 | // iblessing-sample 4 | // 5 | // Created by soulghost on 2020/10/3. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #import "NSString+IBS.h" 10 | 11 | @implementation NSString (IBS) 12 | 13 | - (NSString *)ibs_encoding { 14 | return [self stringByAppendingFormat:@"x"]; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /iblessing/iblessing.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iblessing/iblessing.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iblessing/iblessing.xcodeproj/xcshareddata/xcschemes/iblessing-sample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/generator/Generator.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Generator.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "Generator.hpp" 10 | 11 | using namespace std; 12 | using namespace iblessing; 13 | 14 | int Generator::start() { 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/generator/Generator.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Generator.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef Generator_hpp 10 | #define Generator_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | class Generator { 17 | public: 18 | Generator(std::string identifier, std::string desc): 19 | identifier(identifier), 20 | desc(desc) 21 | {} 22 | 23 | virtual ~Generator() {}; 24 | std::map options; 25 | std::string inputPath; 26 | std::string outputPath; 27 | std::string fileName; 28 | std::string identifier; 29 | std::string desc; 30 | 31 | virtual int start() = 0; 32 | }; 33 | 34 | #endif /* Generator_hpp */ 35 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/generator/GeneratorDispatcher.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // GeneratorDispatcher.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef GeneratorDispatcher_hpp 10 | #define GeneratorDispatcher_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include "Generator.hpp" 16 | #include 17 | 18 | NS_IB_BEGIN; 19 | 20 | typedef std::function GeneratorProvider; 21 | 22 | class GeneratorDispatcher { 23 | public: 24 | GeneratorDispatcher(); 25 | void registerGenerator(std::string generatorId, GeneratorProvider provider); 26 | int start(std::string generatorId, std::map options, std::string inputPath, std::string outputPath); 27 | Generator* prepareForGenerator(std::string scannerId, std::map options, std::string inputPath, std::string outputPath); 28 | std::vector allGenerators(); 29 | 30 | private: 31 | std::map generatorMap; 32 | }; 33 | 34 | NS_IB_END; 35 | 36 | #endif /* GeneratorDispatcher_hpp */ 37 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/generator/IDAObjcMsgXREFGenerator.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // IDAObjcMsgXREFGenerator.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "IDAObjcMsgXREFGenerator.hpp" 10 | #include 11 | #include "ObjcMethodChainSerializationManager.hpp" 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | using namespace std; 20 | using namespace iblessing; 21 | 22 | int IDAObjMsgXREFGenerator::start() { 23 | cout << "[*] start IDAObjMsgXREFGenerator" << endl; 24 | 25 | string scriptsPath = StringUtils::path_join(outputPath, fileName + "_ida_objc_msg_xrefs.iblessing.py"); 26 | ofstream ss(scriptsPath); 27 | ss.clear(); 28 | 29 | if (!loadMethodChains()) { 30 | cout << termcolor::red; 31 | cout << StringUtils::format(" [!] failed to parse %s\n", inputPath.c_str()); 32 | cout << termcolor::reset << endl; 33 | return 1; 34 | } 35 | 36 | cout << " [*] Generating XREF Scripts ..." << endl; 37 | ss << "def add_objc_xrefs():"; 38 | for (auto it = sel2chain.begin(); it != sel2chain.end(); it++) { 39 | MethodChain *current = it->second; 40 | 41 | // ignore import symbol since IDA can build them 42 | if (current->impAddr == 0 || 43 | current->className == "iblessing_ImportSymbol") { 44 | continue; 45 | } 46 | 47 | for (auto it = current->prevMethods.begin(); it != current->prevMethods.end(); it++) { 48 | MethodChain *prev = it->first; 49 | if (prev->className == "iblessing_ImportSymbol") { 50 | continue; 51 | } 52 | 53 | uint64_t callerAddr = it->second; 54 | if (callerAddr == 0) { 55 | callerAddr = prev->impAddr; 56 | } 57 | // add xref(preCallerAddr, cur->impAddr) 58 | ss << StringUtils::format("\n ida_xref.add_cref(0x%llx, 0x%llx, XREF_USER)", 59 | callerAddr, 60 | current->impAddr); 61 | } 62 | } 63 | 64 | ss << "\n\nif __name__ == '__main__':\n"; 65 | ss << " add_objc_xrefs()\n"; 66 | 67 | printf(" [*] saved to %s\n", scriptsPath.c_str()); 68 | ss.close(); 69 | return 0; 70 | } 71 | 72 | bool IDAObjMsgXREFGenerator::loadMethodChains() { 73 | sel2chain = ObjcMethodChainSerializationManager::loadMethodChain(inputPath); 74 | if (sel2chain.empty()) { 75 | return false; 76 | } 77 | 78 | printf("\t[+] load storage from disk succeeded!\n"); 79 | return true; 80 | } 81 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/generator/IDAObjcMsgXREFGenerator.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // IDAObjcMsgXREFGenerator.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef IDAObjcMsgXREFGenerator_hpp 10 | #define IDAObjcMsgXREFGenerator_hpp 11 | 12 | #include "Generator.hpp" 13 | #include "ObjcMethodChain.hpp" 14 | #include 15 | 16 | NS_IB_BEGIN 17 | 18 | class IDAObjMsgXREFGenerator : public Generator { 19 | public: 20 | IDAObjMsgXREFGenerator(std::string name, std::string desc): Generator(name, desc) {} 21 | 22 | virtual ~IDAObjMsgXREFGenerator() {}; 23 | virtual int start(); 24 | 25 | private: 26 | std::map sel2chain; 27 | bool loadMethodChains(); 28 | }; 29 | 30 | NS_IB_END 31 | 32 | #endif /* IDAObjcMsgXREFGenerator_hpp */ 33 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/generator/IDASymbolWrapperNamingScriptGenerator.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // IDASymbolWrapperNamingScriptGenerator.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/30. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "IDASymbolWrapperNamingScriptGenerator.hpp" 10 | #include "SymbolWrapperSerializationManager.hpp" 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | using namespace iblessing; 16 | 17 | int IDASymbolWrapperNamingScriptGenerator::start() { 18 | cout << "[*] start IDAObjMsgXREFGenerator" << endl; 19 | 20 | string scriptsPath = StringUtils::path_join(outputPath, fileName + "_ida_symbol_wrapper_naming.iblessing.py"); 21 | ofstream ss(scriptsPath); 22 | if (!ss.is_open()) { 23 | cout << termcolor::red; 24 | cout << StringUtils::format(" [!] cannot open output file %s\n", scriptsPath.c_str()); 25 | cout << termcolor::reset << endl; 26 | return 1; 27 | } 28 | ss.clear(); 29 | 30 | std::vector wrapperInfos = SymbolWrapperSerializationManager::loadWrapperInfosFromReport(inputPath); 31 | if (wrapperInfos.size() == 0) { 32 | cout << termcolor::red; 33 | cout << StringUtils::format(" [!] failed to parse %s\n", inputPath.c_str()); 34 | cout << termcolor::reset << endl; 35 | return 1; 36 | } 37 | 38 | cout << " [*] Generating Naming Scripts ..." << endl; 39 | ss << "def namingWrappers():"; 40 | for (SymbolWrapperInfo &info : wrapperInfos) { 41 | string name = info.name; 42 | string proto = info.prototype; 43 | uint64_t addr = info.address; 44 | ss << StringUtils::format("\n idc.set_name(0x%llx, '%s', ida_name.SN_FORCE)", 45 | addr, name.c_str()); 46 | 47 | ss << StringUtils::format("\n idc.apply_type(0x%llx, idc.parse_decl('%s', idc.PT_SILENT))", addr, proto.c_str()); 48 | } 49 | 50 | ss << "\n\nif __name__ == '__main__':\n"; 51 | ss << " namingWrappers()\n"; 52 | 53 | printf(" [*] saved to %s\n", scriptsPath.c_str()); 54 | ss.close(); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/generator/IDASymbolWrapperNamingScriptGenerator.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // IDASymbolWrapperNamingScriptGenerator.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/30. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef IDASymbolWrapperNamingScriptGenerator_hpp 10 | #define IDASymbolWrapperNamingScriptGenerator_hpp 11 | 12 | #include "Generator.hpp" 13 | #include "ObjcMethodChain.hpp" 14 | #include 15 | 16 | NS_IB_BEGIN 17 | 18 | class IDASymbolWrapperNamingScriptGenerator : public Generator { 19 | public: 20 | IDASymbolWrapperNamingScriptGenerator(std::string name, std::string desc): Generator(name, desc) {} 21 | 22 | virtual ~IDASymbolWrapperNamingScriptGenerator() {}; 23 | virtual int start(); 24 | }; 25 | 26 | NS_IB_END 27 | 28 | #endif /* IDASymbolWrapperNamingScriptGenerator_hpp */ 29 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/generator/IDASymbolicScriptGenerator.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // IDASymbolicScriptGenerator.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/15. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef IDASymbolicScriptGenerator_hpp 10 | #define IDASymbolicScriptGenerator_hpp 11 | 12 | #include "Generator.hpp" 13 | 14 | NS_IB_BEGIN 15 | 16 | class IDASymbolicScriptGenerator : public Generator { 17 | public: 18 | IDASymbolicScriptGenerator(std::string name, std::string desc): Generator(name, desc) {} 19 | 20 | virtual ~IDASymbolicScriptGenerator() {}; 21 | virtual int start(); 22 | }; 23 | 24 | NS_IB_END 25 | 26 | #endif /* IDASymbolicScriptGenerator_hpp */ 27 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/generator/ObjcMsgXREFReportGenerator.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcMsgXREFReportGenerator.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/8/10. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcMsgXREFReportGenerator_hpp 10 | #define ObjcMsgXREFReportGenerator_hpp 11 | 12 | #include "Generator.hpp" 13 | #include "ObjcMethodChain.hpp" 14 | #include 15 | 16 | NS_IB_BEGIN 17 | 18 | class ObjcMsgXREFReportGenerator : public Generator { 19 | public: 20 | ObjcMsgXREFReportGenerator(std::string name, std::string desc): Generator(name, desc) {} 21 | 22 | virtual ~ObjcMsgXREFReportGenerator() {}; 23 | virtual int start(); 24 | 25 | private: 26 | std::map sel2chain; 27 | bool loadMethodChains(); 28 | }; 29 | 30 | NS_IB_END 31 | 32 | #endif /* ObjcMsgXREFReportGenerator_hpp */ 33 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/generator/ObjcMsgXREFServerGenerator.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcMsgXREFServerGenerator.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/22. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcMsgXREFServerGenerator_hpp 10 | #define ObjcMsgXREFServerGenerator_hpp 11 | 12 | #include "Generator.hpp" 13 | #include "ObjcMethodChain.hpp" 14 | #include 15 | 16 | NS_IB_BEGIN 17 | 18 | class ObjcMsgXREFServerGenerator : public Generator { 19 | public: 20 | ObjcMsgXREFServerGenerator(std::string name, std::string desc): Generator(name, desc) {} 21 | 22 | virtual ~ObjcMsgXREFServerGenerator() {}; 23 | virtual int start(); 24 | 25 | private: 26 | std::map sel2chain; 27 | bool loadMethodChains(); 28 | }; 29 | 30 | NS_IB_END 31 | 32 | #endif /* ObjcMsgXREFServerGenerator_hpp */ 33 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/generator/ObjcMsgXREFStatisticsGenerator.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcMsgXREFStatisticsGenerator.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/25. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcMsgXREFStatisticsGenerator_hpp 10 | #define ObjcMsgXREFStatisticsGenerator_hpp 11 | 12 | #include "Generator.hpp" 13 | #include "ObjcMethodChain.hpp" 14 | #include 15 | #include 16 | 17 | NS_IB_BEGIN 18 | 19 | class ObjcMsgXREFStatisticsGenerator : public Generator { 20 | public: 21 | ObjcMsgXREFStatisticsGenerator(std::string name, std::string desc): Generator(name, desc) {} 22 | 23 | virtual ~ObjcMsgXREFStatisticsGenerator() {}; 24 | virtual int start(); 25 | 26 | private: 27 | std::map sel2chain; 28 | std::map loadMethodChains(std::string path); 29 | }; 30 | 31 | NS_IB_END 32 | 33 | #endif /* ObjcMsgXREFStatisticsGenerator_hpp */ 34 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/AppInfoScanner.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // AppInfoScanner.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef AppInfoScanner_hpp 10 | #define AppInfoScanner_hpp 11 | 12 | #include 13 | 14 | NS_IB_BEGIN 15 | 16 | class AppInfoScanner : public Scanner { 17 | public: 18 | AppInfoScanner(std::string name, std::string desc): Scanner(name, desc, false) {} 19 | 20 | virtual ~AppInfoScanner() {}; 21 | virtual int start(); 22 | 23 | private: 24 | std::map PrivacyMap = { 25 | {"NSBluetoothAlwaysUsageDescription", "Bluetooth"}, 26 | {"NSBluetoothPeripheralUsageDescription", "Bluetooth"}, // Deprecated 27 | {"NSCalendarsUsageDescription", "Calendars"}, 28 | {"NSRemindersUsageDescription", "Reminders"}, 29 | {"NSCameraUsageDescription", "Camera"}, 30 | {"NSMicrophoneUsageDescription", "Microphone"}, 31 | {"NSContactsUsageDescription", "Contacts"}, 32 | {"NSFaceIDUsageDescription", "FaceID"}, 33 | // FIXME : macOS only? 34 | {"NSDesktopFolderUsageDescription", "DesktopFolder"}, 35 | {"NSDocumentsFolderUsageDescription", "DocumentsFolder"}, 36 | {"NSDownloadsFolderUsageDescription", "DownloadsFolder"}, 37 | {"NSNetworkVolumesUsageDescription", "NetworkVolumes"}, 38 | {"NSRemovableVolumesUsageDescription", "RemovableVolumes"}, 39 | {"NSFileProviderPresenceUsageDescription", "FileProviderPresence"}, 40 | {"NSFileProviderDomainUsageDescription", "FileProviderDomainUsage"}, 41 | {"NSGKFriendListUsageDescription", "GameCenter"}, 42 | {"NSHealthClinicalHealthRecordsShareUsageDescription", "HealthClinicalHealthRecordsShare"}, 43 | {"NSHealthShareUsageDescription", "HealthShare"}, 44 | {"NSHealthUpdateUsageDescription", "HealthUpdate"}, 45 | {"NSHomeKitUsageDescription", "HomeKit"}, 46 | {"NSLocationAlwaysAndWhenInUseUsageDescription", "LocationAlwaysAndWhenInUse"}, 47 | {"NSLocationUsageDescription", "Location"}, 48 | {"NSLocationWhenInUseUsageDescription", "LocationWhenInUse"}, 49 | {"NSLocationTemporaryUsageDescription", "LocationTemporary"}, 50 | {"NSLocationAlwaysUsageDescription", "LocationAlwaysUsage"}, 51 | {"NSAppleMusicUsageDescription", "AppleMusic"}, 52 | {"NSMotionUsageDescription", "Motion"}, 53 | {"NSFallDetectionUsageDescription", "FallDetection"}, 54 | {"NSLocalNetworkUsageDescription", "LocalNetwork"}, 55 | {"NSNearbyInteractionUsageDescription", "NearbyInteraction"}, 56 | {"NSNearbyInteractionAllowOnceUsageDescription", "NearbyInteractionAllowOnceUsage"}, 57 | {"NFCReaderUsageDescription", "CReader"}, 58 | {"NSPhotoLibraryAddUsageDescription", "PhotoLibraryAdd"}, 59 | {"NSPhotoLibraryUsageDescription", "PhotoLibrary"}, 60 | {"NSUserTrackingUsageDescription", "UserTracking"}, 61 | {"NSAppleEventsUsageDescription", "AppleEvents"}, 62 | {"NSSystemAdministrationUsageDescription", "SystemAdministration"}, 63 | {"NSSensorKitUsageDescription", "SensorKit"}, 64 | {"NSSiriUsageDescription", "Siri"}, 65 | {"NSSpeechRecognitionUsageDescription", "SpeechRecognition"}, 66 | {"NSVideoSubscriberAccountUsageDescription", "VideoSubscriber"} 67 | }; 68 | }; 69 | 70 | NS_IB_END 71 | 72 | #endif /* AppInfoScanner_hpp */ 73 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/CocoaAppInfoScanner.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CocoaAppInfoScanner.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/8/10. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "CocoaAppInfoScanner.hpp" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | using namespace iblessing; 18 | 19 | int CocoaAppInfoScanner::start() { 20 | cout << "[*] start Cocoa App Info Scanner" << endl; 21 | 22 | string bundlePath = inputPath; 23 | string outputFilePath; 24 | string infoName; 25 | if (options.find("infoName") != options.end()) { 26 | infoName = options["infoName"]; 27 | if (!StringUtils::has_suffix(infoName, ".plist")) { 28 | infoName = infoName + ".plist"; 29 | } 30 | printf(" [*] specific info.plist name to %s", infoName.c_str()); 31 | } 32 | 33 | outputFilePath = StringUtils::path_join(outputPath, fileName + "_info.iblessing.txt"); 34 | stringstream report; 35 | 36 | // list files 37 | DIR *dirp = opendir(bundlePath.c_str()); 38 | if (dirp == NULL) { 39 | cout << termcolor::red; 40 | cout << "[-] error: file not exist at path " << bundlePath; 41 | cout << termcolor::reset << endl; 42 | return 1; 43 | } 44 | 45 | struct dirent *dp; 46 | vector plistFiles; 47 | string infoPath; 48 | if (infoName.length() == 0) { 49 | bool findDefaultInfoFile = false; 50 | while ((dp = readdir(dirp)) != NULL) { 51 | string fileName = string(dp->d_name); 52 | if (StringUtils::has_suffix(fileName, ".plist")) { 53 | plistFiles.push_back(fileName); 54 | if (fileName == "Info.plist") { 55 | findDefaultInfoFile = true; 56 | } 57 | } 58 | } 59 | closedir(dirp); 60 | 61 | if (findDefaultInfoFile) { 62 | cout << termcolor::white; 63 | cout << "[+] find default plist file Info.plist!"; 64 | cout << termcolor::reset << endl; 65 | infoPath = StringUtils::path_join(bundlePath, "Info.plist"); 66 | } 67 | } else { 68 | infoPath = StringUtils::path_join(bundlePath, infoName); 69 | } 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/CocoaAppInfoScanner.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // CocoaAppInfoScanner.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/8/10. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef CocoaAppInfoScanner_hpp 10 | #define CocoaAppInfoScanner_hpp 11 | 12 | #include 13 | 14 | NS_IB_BEGIN 15 | 16 | class CocoaAppInfoScanner : public Scanner { 17 | public: 18 | CocoaAppInfoScanner(std::string name, std::string desc): Scanner(name, desc, false) {} 19 | 20 | virtual ~CocoaAppInfoScanner() {}; 21 | virtual int start(); 22 | }; 23 | 24 | NS_IB_END 25 | 26 | #endif /* CocoaAppInfoScanner_hpp */ 27 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/ObjcClassXrefScanner.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcClassXrefScanner.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/8. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcClassXrefScanner_hpp 10 | #define ObjcClassXrefScanner_hpp 11 | 12 | #include 13 | 14 | NS_IB_BEGIN 15 | 16 | class ObjcClassXrefScanner : public Scanner { 17 | public: 18 | ObjcClassXrefScanner(std::string name, std::string desc): Scanner(name, desc) {} 19 | 20 | virtual ~ObjcClassXrefScanner() {}; 21 | virtual int start(); 22 | }; 23 | 24 | NS_IB_END 25 | 26 | #endif /* ObjcClassXrefScanner_hpp */ 27 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/ObjcMethodXrefScanner.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcMethodXrefScanner.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/5/15. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcMethodXrefScanner_hpp 10 | #define ObjcMethodXrefScanner_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | NS_IB_BEGIN 18 | 19 | class ObjcMethodXrefScanner : public Scanner { 20 | public: 21 | ObjcMethodXrefScanner(std::string name, std::string desc): Scanner(name, desc) {} 22 | virtual ~ObjcMethodXrefScanner() {}; 23 | virtual int start(); 24 | }; 25 | 26 | NS_IB_END 27 | 28 | 29 | #endif /* ObjcMethodXrefScanner_hpp */ 30 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/ObjcUnserializationScanner.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcUnserializationScanner.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/16. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcUnserializationScanner_hpp 10 | #define ObjcUnserializationScanner_hpp 11 | 12 | #include 13 | 14 | NS_IB_BEGIN 15 | 16 | class ObjcUnserializationScanner : public Scanner { 17 | public: 18 | ObjcUnserializationScanner(std::string name, std::string desc): Scanner(name, desc) {} 19 | 20 | virtual ~ObjcUnserializationScanner() {}; 21 | virtual int start(); 22 | }; 23 | 24 | NS_IB_END 25 | 26 | #endif /* ObjcUnserializationScanner_hpp */ 27 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/PredicateScanner.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // PredicateScanner.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/4/27. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef PredicateScanner_hpp 10 | #define PredicateScanner_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | NS_IB_BEGIN 17 | 18 | class PredicateScanner : public Scanner { 19 | public: 20 | PredicateScanner(std::string name, std::string desc): Scanner(name, desc) {} 21 | 22 | virtual ~PredicateScanner() {}; 23 | virtual int start(); 24 | }; 25 | 26 | NS_IB_END 27 | 28 | #endif /* PredicateScanner_hpp */ 29 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/SymbolWrapperScanner.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolWrapperScanner.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/16. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "SymbolWrapperScanner.hpp" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using namespace std; 18 | using namespace iblessing; 19 | using namespace iblessing::Analyser; 20 | 21 | __attribute__((constructor)) 22 | static void scannerRegister() { 23 | ScannerDispatcher::getInstance()->registerScanner("symbol-wrapper", []() { 24 | return new SymbolWrapperScanner("symbol-wrapper", "symbol wrapper scanner"); 25 | }); 26 | }; 27 | 28 | int SymbolWrapperScanner::start() { 29 | printf("[*] start Symbol Wrapper Scanner Finished\n"); 30 | assert(macho != nullptr); 31 | 32 | shared_ptr memory = Memory::createFromMachO(macho); 33 | assert(memory->loadSync() == IB_SUCCESS); 34 | this->memory = memory; 35 | 36 | if (options.find("symbols") == options.end()) { 37 | cout << termcolor::red; 38 | cout << StringUtils::format("[-] Error: you should specific symbols by -d 'symbols=,' or 'symbols=*'"); 39 | cout << termcolor::reset << endl; 40 | return 1; 41 | } 42 | 43 | string symbolsExpr = options["symbols"]; 44 | vector allSymbols = StringUtils::split(symbolsExpr, ','); 45 | 46 | shared_ptr wrapperAnalyser = SimpleWrapperAnalyser::create(macho, memory); 47 | wrapperAnalyser->targetSymbols = allSymbols; 48 | wrapperAnalyser->start(); 49 | 50 | printf("[*] Step 3. serialize wrapper graph to file\n"); 51 | // setup recordPath 52 | string graphPath = StringUtils::path_join(outputPath, fileName + "_wrapper-graph.iblessing.txt"); 53 | if (SymbolWrapperSerializationManager::createReportFromAntiWrapper(graphPath, wrapperAnalyser->antiWrapper, wrapperAnalyser->symbol2proto)) { 54 | printf("\t[*] wrapper graph file saved to %s\n", graphPath.c_str()); 55 | } else { 56 | printf("\t[*] error: cannot save to path %s\n", graphPath.c_str()); 57 | } 58 | 59 | printf("[*] Symbol Wrapper Scanner finished\n"); 60 | return IB_SUCCESS; 61 | } 62 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/SymbolWrapperScanner.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolWrapperScanner.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/16. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef SymbolWrapperScanner_hpp 10 | #define SymbolWrapperScanner_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | NS_IB_BEGIN 18 | 19 | class SymbolWrapperScanner : public Scanner { 20 | public: 21 | SymbolWrapperScanner(std::string name, std::string desc): Scanner(name, desc) {} 22 | 23 | virtual ~SymbolWrapperScanner() {}; 24 | virtual int start(); 25 | }; 26 | 27 | NS_IB_END 28 | 29 | #endif /* SymbolWrapperScanner_hpp */ 30 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/SymbolXREFScanner.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolXREFScanner.cpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/2. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "SymbolXREFScanner.hpp" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | using namespace iblessing; 18 | using namespace iblessing::Analyser; 19 | 20 | __attribute__((constructor)) 21 | static void scannerRegister() { 22 | ScannerDispatcher::getInstance()->registerScanner("symbol-xref", []() { 23 | return new SymbolXREFScanner("symbol-xref", "symbol (function) xref scanner"); 24 | }); 25 | }; 26 | 27 | int SymbolXREFScanner::start() { 28 | printf("[*] start Symbol (Function) Xref Scanner Finished\n"); 29 | assert(macho != nullptr); 30 | 31 | shared_ptr memory = Memory::createFromMachO(macho); 32 | assert(memory->loadSync() == IB_SUCCESS); 33 | this->memory = memory; 34 | 35 | if (options.find("symbols") == options.end()) { 36 | cout << termcolor::red; 37 | cout << StringUtils::format("[-] Error: you should specific symbols by -d 'symbols=,' or 'symbols=*'"); 38 | cout << termcolor::reset << endl; 39 | return 1; 40 | } 41 | 42 | string symbolsExpr = options["symbols"]; 43 | vector allSymbols = StringUtils::split(symbolsExpr, ','); 44 | 45 | shared_ptr xrefAnalyser = FunctionXrefAnalyser::create(macho, memory); 46 | xrefAnalyser->targetSymbols = allSymbols; 47 | 48 | printf(" [*] try to find xrefs for"); 49 | bool first = true; 50 | for (string symbol : allSymbols) { 51 | printf("%s%s", first ? "" : ", ", symbol.c_str()); 52 | first = false; 53 | } 54 | printf("\n"); 55 | 56 | xrefAnalyser->start(); 57 | 58 | for (auto it = xrefAnalyser->xrefs.begin(); it != xrefAnalyser->xrefs.end(); it++) { 59 | printf("Symbol %s:\n", it->first.c_str()); 60 | for (auto sit = it->second.begin(); sit != it->second.end(); sit++) { 61 | printf(" [+] 0x%llx ~ 0x%llx: 0x%llx -> 0x%llx\n", sit->startAddr, sit->endAddr, sit->callerAddr, sit->symbolAddr); 62 | } 63 | printf("\n"); 64 | } 65 | 66 | printf("[+] Symbol (Function) Xref Scanner Finished\n"); 67 | return IB_SUCCESS; 68 | } 69 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/SymbolXREFScanner.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolXREFScanner.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/2. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef SymbolXREFScanner_hpp 10 | #define SymbolXREFScanner_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | NS_IB_BEGIN 17 | 18 | class SymbolXREFScanner : public Scanner { 19 | public: 20 | SymbolXREFScanner(std::string name, std::string desc): Scanner(name, desc) {} 21 | 22 | virtual ~SymbolXREFScanner() {}; 23 | virtual int start(); 24 | 25 | private: 26 | void init(); 27 | }; 28 | 29 | NS_IB_END 30 | 31 | #endif /* SymbolXREFScanner_hpp */ 32 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/assistance/state/ProgramState.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ProgramState.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/9/18. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ProgramState.hpp" 10 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/assistance/state/ProgramState.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ProgramState.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/9/18. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ProgramState_hpp 10 | #define ProgramState_hpp 11 | 12 | #include 13 | #include 14 | 15 | NS_IB_BEGIN 16 | 17 | class ProgramState { 18 | public: 19 | uc_context *uc_ctx; 20 | uint64_t pc; 21 | int depth; 22 | std::string condition; 23 | 24 | // stack 25 | void *uc_stack; 26 | uint64_t uc_stack_top_addr; 27 | uint64_t uc_stack_size; 28 | 29 | ~ProgramState() { 30 | free(uc_stack); 31 | uc_stack = nullptr; 32 | } 33 | }; 34 | 35 | NS_IB_END 36 | 37 | #endif /* ProgramState_hpp */ 38 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/assistance/state/ProgramStateManager.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ProgramStateManager.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/9/18. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ProgramStateManager.hpp" 10 | 11 | using namespace std; 12 | using namespace iblessing; 13 | 14 | bool ProgramStateManager::enqueueState(shared_ptr &state) { 15 | if (visitedPc.find(state->pc) != visitedPc.end()) { 16 | return false; 17 | } 18 | 19 | visitedPc.insert(state->pc); 20 | stateQueue.push(state); 21 | return true; 22 | } 23 | 24 | shared_ptr ProgramStateManager::popState() { 25 | if (stateQueue.empty()) { 26 | return nullptr; 27 | } 28 | 29 | shared_ptr state = stateQueue.front(); 30 | stateQueue.pop(); 31 | return state; 32 | } 33 | 34 | bool ProgramStateManager::isEmpty() { 35 | return stateQueue.empty(); 36 | } 37 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/assistance/state/ProgramStateManager.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ProgramStateManager.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/9/18. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ProgramStateManager_hpp 10 | #define ProgramStateManager_hpp 11 | 12 | #include "ProgramState.hpp" 13 | #include 14 | #include 15 | #include 16 | 17 | NS_IB_BEGIN 18 | 19 | class ProgramStateManager { 20 | public: 21 | bool enqueueState(std::shared_ptr &state); 22 | std::shared_ptr popState(); 23 | bool isEmpty(); 24 | 25 | private: 26 | std::queue> stateQueue; 27 | std::set visitedPc; 28 | }; 29 | 30 | NS_IB_END 31 | 32 | #endif /* ProgramStateManager_hpp */ 33 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/domain/ObjcMethodCall.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcMethodCall.cpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/10/23. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ObjcMethodCall.hpp" 10 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/domain/ObjcMethodCall.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcMethodCall.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/10/23. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcMethodCall_hpp 10 | #define ObjcMethodCall_hpp 11 | 12 | #include "ObjcMethod.hpp" 13 | 14 | NS_IB_BEGIN 15 | 16 | class ObjcMethodCallArg { 17 | public: 18 | std::string typeEncoding; 19 | std::string typeName; 20 | std::string value; 21 | bool isPrimaryType; 22 | bool resolved; 23 | 24 | ObjcMethodCallArg(std::string typeEncoding, std::string typeName, std::string value, bool isPrimaryType, bool resolved) { 25 | this->typeEncoding = typeEncoding; 26 | this->typeName = typeName; 27 | this->value = value; 28 | this->isPrimaryType = isPrimaryType; 29 | this->resolved = resolved; 30 | } 31 | 32 | bool operator < (const ObjcMethodCallArg &rhs) const { 33 | if (typeName < rhs.typeName) { 34 | return true; 35 | } else if (typeName > rhs.typeName) { 36 | return false; 37 | } 38 | return value < rhs.value; 39 | } 40 | }; 41 | 42 | class ObjcMethodCall { 43 | public: 44 | ObjcMethod *method; 45 | std::vector args; 46 | 47 | ObjcMethodCall(ObjcMethod *method, std::vector &args) { 48 | this->method = method; 49 | this->args = args; 50 | } 51 | 52 | bool operator < (const ObjcMethodCall &rhs) const { 53 | return args < rhs.args; 54 | } 55 | }; 56 | 57 | NS_IB_END 58 | 59 | #endif /* ObjcMethodCall_hpp */ 60 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/domain/ObjcMethodChain.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcMethodChain.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "ObjcMethodChain.hpp" 10 | 11 | using namespace std; 12 | using namespace iblessing; 13 | 14 | uint64_t MethodChain::chainIdCounter = 0; 15 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/domain/ObjcMethodChain.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcMethodChain.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/19. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcMethodChain_hpp 10 | #define ObjcMethodChain_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | NS_IB_BEGIN 19 | 20 | class MethodChain { 21 | public: 22 | static uint64_t chainIdCounter; 23 | uint64_t chainId; 24 | uint64_t impAddr; 25 | std::string prefix; 26 | std::string className; 27 | std::string methodName; 28 | 29 | std::set> prevMethods; 30 | std::set> nextMethods; 31 | 32 | MethodChain() { 33 | chainId = ++chainIdCounter; 34 | } 35 | 36 | std::string getCommonDesc() { 37 | return StringUtils::format("%s[%s %s] (0x%llx)", 38 | prefix.c_str(), 39 | className.c_str(), 40 | methodName.c_str(), 41 | impAddr); 42 | } 43 | 44 | std::string getCompareKey() { 45 | if (className.rfind("0x") == 0) { 46 | return StringUtils::format("%s[%s %s]", 47 | prefix.c_str(), 48 | "0xcafecafecafecafe", 49 | methodName.c_str()); 50 | } else { 51 | return StringUtils::format("%s[%s %s]", 52 | prefix.c_str(), 53 | className.c_str(), 54 | methodName.c_str()); 55 | } 56 | } 57 | 58 | bool operator < (MethodChain *rhs) { 59 | return getCommonDesc() < rhs->getCommonDesc(); 60 | } 61 | }; 62 | 63 | NS_IB_END 64 | 65 | #endif /* ObjcMethodChain_hpp */ 66 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/sub-scanner/objc-msg-xref/ObjcReflectionInfo.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcReflectionInfo.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/11/28. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcReflectionInfo_hpp 10 | #define ObjcReflectionInfo_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | NS_IB_BEGIN 18 | 19 | struct ObjcReflectionCallArg { 20 | std::string type; 21 | std::string value; 22 | bool resolved; 23 | 24 | ObjcReflectionCallArg(std::string type, std::string value, bool resolved) { 25 | this->type = type; 26 | this->value = value; 27 | this->resolved = resolved; 28 | } 29 | }; 30 | 31 | struct ObjcReflectionCall { 32 | uint64_t pc; 33 | std::string callerDesc; 34 | std::vector args; 35 | bool resolved; 36 | }; 37 | 38 | struct ObjcReflectionCallStatistics { 39 | uint64_t resolvedCount; 40 | uint64_t totalCount; 41 | }; 42 | 43 | class ObjcReflectionInfo { 44 | public: 45 | std::map, ObjcReflectionCallStatistics>> callMap; 46 | std::set visitedPc; 47 | 48 | void addCall(std::string name, ObjcReflectionCall &call) { 49 | if (visitedPc.find(call.pc) != visitedPc.end()) { 50 | return; 51 | } 52 | 53 | std::pair, ObjcReflectionCallStatistics> &callsInfo = callMap[name]; 54 | callsInfo.first.push_back(call); 55 | callsInfo.second.totalCount++; 56 | if (call.resolved) { 57 | callsInfo.second.resolvedCount++; 58 | } 59 | } 60 | }; 61 | 62 | NS_IB_END 63 | 64 | #endif /* ObjcReflectionInfo_hpp */ 65 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/scanner/sub-scanner/objc-msg-xref/ObjcReflectionInfoManager.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcRelectionInfoManager.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/11/28. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcReflectionInfoManager_hpp 10 | #define ObjcReflectionInfoManager_hpp 11 | 12 | #include "ObjcReflectionInfo.hpp" 13 | 14 | NS_IB_BEGIN 15 | 16 | class ObjcReflectionInfoManager { 17 | public: 18 | ObjcReflectionInfo info; 19 | std::string reportPath; 20 | 21 | bool syncToDisk(); 22 | bool syncToDisk(std::string path); 23 | }; 24 | 25 | NS_IB_END 26 | 27 | #endif /* ObjcRelectionInfoManager_hpp */ 28 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/serialization/ObjcMethodCallSnapshotSerializationManager.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcMethodCallSnapshotSerializationManager.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/10/24. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcMethodCallSnapshotSerializationManager_hpp 10 | #define ObjcMethodCallSnapshotSerializationManager_hpp 11 | 12 | #include "ObjcMethodCall.hpp" 13 | #include 14 | #include 15 | 16 | NS_IB_BEGIN 17 | 18 | class ObjcMethodCallSnapshotSerializationManager { 19 | public: 20 | static bool storeAsJSON(std::string path, std::map> callSnapshots); 21 | }; 22 | 23 | NS_IB_END 24 | 25 | #endif /* ObjcMethodCallSnapshotSerializationManager_hpp */ 26 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/serialization/ObjcMethodChainSerializationManager.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcMethodChainSerializationManager.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/21. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef ObjcMethodChainSerializationManager_hpp 10 | #define ObjcMethodChainSerializationManager_hpp 11 | 12 | #include "ObjcMethodChain.hpp" 13 | #include 14 | 15 | NS_IB_BEGIN 16 | 17 | class ObjcMethodChainSerializationManager { 18 | public: 19 | static std::string currentVersion; 20 | static bool storeMethodChain(std::string path, std::map &sel2chain); 21 | static std::string detectMethodChainVersion(std::string path); 22 | static std::map loadMethodChain(std::string path); 23 | }; 24 | 25 | NS_IB_END 26 | 27 | #endif /* ObjcMethodChainSerializationManager_hpp */ 28 | -------------------------------------------------------------------------------- /iblessing/iblessing/builtin/serialization/SymbolWrapperSerializationManager.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // SymbolWrapperSerializationManager.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/28. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef SymbolWrapperSerializationManager_hpp 10 | #define SymbolWrapperSerializationManager_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | NS_IB_BEGIN 17 | 18 | typedef struct SymbolWrapperInfo { 19 | uint64_t address; 20 | std::string name; 21 | std::string prototype; 22 | } SymbolWrapperInfo; 23 | 24 | class SymbolWrapperSerializationManager { 25 | public: 26 | static std::string currentVersion; 27 | static bool createReportFromAntiWrapper(std::string path, AntiWrapper &antiWrapper, std::map &symbol2proto); 28 | static std::string detectReportVersion(std::string path); 29 | static std::vector loadWrapperInfosFromReport(std::string path); 30 | }; 31 | 32 | NS_IB_END 33 | 34 | #endif /* SymbolWrapperSerializationManager_hpp */ 35 | -------------------------------------------------------------------------------- /iblessing/iblessing/iblessing.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-unsigned-executable-memory 6 | 7 | com.apple.security.cs.disable-executable-page-protection 8 | 9 | com.apple.security.cs.disable-library-validation 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /iblessing/iblessing/platform/macos/csrutil.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // csrutil.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/23. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "csrutil.hpp" 10 | #include "csr.h" 11 | 12 | using namespace std; 13 | using namespace iblessing; 14 | 15 | bool CSRUtil::isSIPon() { 16 | csr_config_t config; 17 | if (csr_get_active_config(&config) != 0) { 18 | printf("[-] error: failed to retrieve system integrity configuration.\n"); 19 | // treat as off 20 | return false; 21 | } 22 | 23 | // from /usr/bin/csrutil 24 | config = config & 0xF9u; 25 | if (config > 102) { 26 | if (config == 103) { 27 | return false; 28 | } 29 | 30 | if (config == 119) { 31 | return false; 32 | } 33 | 34 | if (!(config & 0x10)) { 35 | return false; 36 | } 37 | } 38 | 39 | if (!config) { 40 | return true; 41 | } 42 | 43 | if (config != 16) { 44 | if (!(config & 0x10)) { 45 | return false; 46 | } 47 | } 48 | 49 | return true; 50 | } 51 | -------------------------------------------------------------------------------- /iblessing/iblessing/platform/macos/csrutil.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // csrutil.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2020/7/23. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef csrutil_hpp 10 | #define csrutil_hpp 11 | 12 | #include 13 | 14 | NS_IB_BEGIN 15 | 16 | class CSRUtil { 17 | public: 18 | static bool isSIPon(); 19 | }; 20 | 21 | NS_IB_END 22 | 23 | #endif /* csrutil_hpp */ 24 | -------------------------------------------------------------------------------- /iblessing/iblessing/registry/PluginRegistry.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // PluginRegistry.cpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2021/5/5. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #include "PluginRegistry.h" 10 | #include 11 | #include 12 | #include 13 | #ifdef IB_PLATFORM_DARWIN 14 | #include 15 | #else 16 | #include 17 | #endif 18 | 19 | #include 20 | #include 21 | 22 | #ifdef IB_PLATFORM_DARWIN 23 | namespace fs = std::filesystem; 24 | #else 25 | namespace fs = std::experimental::filesystem; 26 | #endif 27 | 28 | using namespace std; 29 | 30 | void registerPlugins() { 31 | size_t size = pathconf(".", _PC_PATH_MAX); 32 | char *buf = (char *)malloc((size_t)size); 33 | char *path = getcwd(buf, (size_t)size); 34 | string currentPath = string(path); 35 | free(buf); 36 | 37 | string pluginsPath = StringUtils::path_join(currentPath, "Plugins"); 38 | if (!fs::exists(pluginsPath)) { 39 | return; 40 | } 41 | 42 | printf("[+] scan and load plugins in %s\n", pluginsPath.c_str()); 43 | vector plugins; 44 | #ifdef IB_PLATFORM_DARWIN 45 | string pluginExt = ".dylib"; 46 | #else 47 | string pluginExt = ".so"; 48 | #endif 49 | for (auto &p : fs::directory_iterator(pluginsPath)) { 50 | string fileName = p.path().filename(); 51 | if (!StringUtils::has_suffix(fileName, pluginExt)) { 52 | continue; 53 | } 54 | 55 | plugins.push_back(StringUtils::path_join(pluginsPath, fileName)); 56 | } 57 | 58 | for (string plugin : plugins) { 59 | void *handle = dlopen(plugin.c_str(), RTLD_NOW); 60 | if (handle) { 61 | cout << termcolor::bold << termcolor::yellow; 62 | cout << "[+] load plugin at " + plugin; 63 | cout << termcolor::reset << endl; 64 | } else { 65 | cout << termcolor::red; 66 | cout << "[-] failed to load plugin at " + plugin; 67 | cout << ", " << dlerror() << termcolor::reset << endl; 68 | assert(false); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /iblessing/iblessing/registry/PluginRegistry.h: -------------------------------------------------------------------------------- 1 | // 2 | // PluginRegistry.h 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2021/5/5. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef PluginRegistry_h 10 | #define PluginRegistry_h 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | extern void registerPlugins(void); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | 22 | #endif /* PluginRegistry_h */ 23 | -------------------------------------------------------------------------------- /iblessing/iblessing/tests/TestManager.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // TestManager.cpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/16. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "TestManager.hpp" 10 | #include "Tester.hpp" 11 | #include "TestObjcMethodXrefs.hpp" 12 | 13 | #include 14 | 15 | using namespace std; 16 | using namespace iblessing; 17 | 18 | bool TestManager::testAll() { 19 | bool success = true; 20 | 21 | static vector tests{ 22 | new TestObjcMethodXrefs() 23 | }; 24 | 25 | for (Tester *test : tests) { 26 | if (!test->start()) { 27 | success = false; 28 | break; 29 | } 30 | } 31 | 32 | for (Tester *test : tests) { 33 | delete test; 34 | } 35 | return success; 36 | } 37 | -------------------------------------------------------------------------------- /iblessing/iblessing/tests/TestManager.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // TestManager.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/16. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef TestManager_hpp 10 | #define TestManager_hpp 11 | 12 | #include 13 | 14 | NS_IB_BEGIN 15 | 16 | class TestManager { 17 | public: 18 | virtual ~TestManager() {}; 19 | static bool testAll(); 20 | }; 21 | 22 | NS_IB_END 23 | 24 | #endif /* TestManager_hpp */ 25 | -------------------------------------------------------------------------------- /iblessing/iblessing/tests/TestObjcMethodXrefs.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // TestObjcMethodXrefs.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/16. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef TestObjcMethodXrefs_hpp 10 | #define TestObjcMethodXrefs_hpp 11 | 12 | #include "Tester.hpp" 13 | 14 | NS_IB_BEGIN 15 | 16 | class TestObjcMethodXrefs : public Tester { 17 | public: 18 | virtual bool start(); 19 | }; 20 | 21 | NS_IB_END 22 | 23 | #endif /* TestObjcMethodXrefs_hpp */ 24 | -------------------------------------------------------------------------------- /iblessing/iblessing/tests/Tester.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Tester.cpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/16. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #include "Tester.hpp" 10 | -------------------------------------------------------------------------------- /iblessing/iblessing/tests/Tester.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Tester.hpp 3 | // iblessing 4 | // 5 | // Created by Soulghost on 2020/8/16. 6 | // Copyright © 2020 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef Tester_hpp 10 | #define Tester_hpp 11 | 12 | #include 13 | 14 | NS_IB_BEGIN 15 | 16 | class Tester { 17 | public: 18 | virtual ~Tester() {}; 19 | virtual bool start() = 0; 20 | }; 21 | 22 | NS_IB_END 23 | 24 | #endif /* Tester_hpp */ 25 | -------------------------------------------------------------------------------- /iblessing/iblessing/tests/benchmark/iblessing-sample.benchmark: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Soulghost/iblessing/ff14351de3f3c2155e8df47c26d4367523af7628/iblessing/iblessing/tests/benchmark/iblessing-sample.benchmark -------------------------------------------------------------------------------- /iblessing/plugin-example/example/classdump.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // classdump.cpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/4/30. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #include "classdump.hpp" 10 | #include "CoreFoundation.hpp" 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | using namespace iblessing; 18 | 19 | int classdump_main(int argc, const char **argv) { 20 | string filePath = "/Users/soulghost/Desktop/git/iblessing/iblessing/build/Debug-iphoneos/iblessing-sample.app/iblessing-sample"; 21 | // string filePath = "/opt/one-btn/tmp/apps/WeChat/Payload/WeChat"; 22 | shared_ptr macho = MachO::createFromFile(filePath); 23 | assert(macho->loadSync() == IB_SUCCESS); 24 | 25 | shared_ptr memory = Memory::createFromMachO(macho); 26 | assert(memory->loadSync() == IB_SUCCESS); 27 | 28 | shared_ptr objc = memory->objc; 29 | objc->loadClassList(); 30 | objc->loadCategoryList(); 31 | 32 | shared_ptr dyld = Dyld::create(macho, memory, objc); 33 | dyld->doBindAll(); 34 | 35 | objc->realizeClasses([&](ObjcClassRuntimeInfo *info, uint64_t current, uint64_t total) { 36 | printf("[+] %s.h\n", info->className.c_str()); 37 | printf("@interface %s", info->className.c_str()); 38 | if (info->superClassInfo) { 39 | printf(" : %s\n", info->superClassInfo->className.c_str()); 40 | } else { 41 | printf(" : ?\n"); 42 | } 43 | 44 | for (ObjcMethod *method : info->methodList) { 45 | printf("%s (%s)", method->isClassMethod ? "+" : "-", CoreFoundation::resolveTypeEncoding(method->argTypes[0]).c_str()); 46 | printf("%s;\n", method->name.c_str()); 47 | } 48 | 49 | printf("\n"); 50 | 51 | for (ObjcIvar *ivar : info->ivarList) { 52 | printf("@property (nonatomic) %s %s%s;\n", ivar->typeName.c_str(), ivar->type == IvarTypeObjcClass ? "*" : "?", ivar->raw.name); 53 | } 54 | printf("@end\n"); 55 | }); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /iblessing/plugin-example/example/classdump.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // classdump.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/4/30. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef classdump_hpp 10 | #define classdump_hpp 11 | 12 | #include 13 | 14 | extern int classdump_main(int argc, const char **argv); 15 | 16 | #endif /* classdump_hpp */ 17 | -------------------------------------------------------------------------------- /iblessing/plugin-example/example/otool.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // otool.hpp 3 | // iblessing 4 | // 5 | // Created by soulghost on 2021/4/30. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #ifndef otool_hpp 10 | #define otool_hpp 11 | 12 | #include 13 | 14 | extern int otool_main(int argc, const char **argv); 15 | 16 | #endif /* otool_hpp */ 17 | -------------------------------------------------------------------------------- /iblessing/plugin-example/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // plugin-example 4 | // 5 | // Created by Soulghost on 2021/6/28. 6 | // Copyright © 2021 soulghost. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "classdump.hpp" 11 | #include "otool.hpp" 12 | 13 | int main(int argc, const char * argv[]) { 14 | // insert code here... 15 | // classdump_main(argc, argv); 16 | // otool_main(argc, argv); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /iblessing/plugin-example/plugin-example.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /resource/images/ida_objc_msgSend_xrefs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Soulghost/iblessing/ff14351de3f3c2155e8df47c26d4367523af7628/resource/images/ida_objc_msgSend_xrefs.png -------------------------------------------------------------------------------- /resource/images/ida_wrapped_call_after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Soulghost/iblessing/ff14351de3f3c2155e8df47c26d4367523af7628/resource/images/ida_wrapped_call_after.png -------------------------------------------------------------------------------- /resource/images/ida_wrapped_call_before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Soulghost/iblessing/ff14351de3f3c2155e8df47c26d4367523af7628/resource/images/ida_wrapped_call_before.png -------------------------------------------------------------------------------- /resource/images/objc_msgSend_xref_server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Soulghost/iblessing/ff14351de3f3c2155e8df47c26d4367523af7628/resource/images/objc_msgSend_xref_server.png -------------------------------------------------------------------------------- /run-test.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname "$0")" 4 | set -xe 5 | 6 | cd cmake-build 7 | if [[ "$OSTYPE" == "darwin"* ]]; then 8 | binary='iblessing-darwin' 9 | else 10 | binary='iblessing-linux' 11 | fi 12 | 13 | ./${binary} -m scan -i objc-msg-xref -f ../iblessing/iblessing/tests/benchmark/iblessing-sample.benchmark 14 | ./${binary} -m test 15 | -------------------------------------------------------------------------------- /run-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname "$0")" 4 | 5 | ./run-test.command -------------------------------------------------------------------------------- /v2/classdump.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace iblessing; 6 | 7 | int main(int argc, char **argv) { 8 | char *filePath = argv[1]; 9 | // load mach-o 10 | MachO *macho = MachO::createFromFile(filePath); 11 | assert(macho->loadSync() == IB_SUCCESS); 12 | 13 | // load memory 14 | Memory *mem = Memory::createFromMachO(macho); 15 | assert(mem != nullptr); 16 | 17 | // load objc-runtime 18 | ObjcRuntime *rt = ObjcRuntime::createFromMemory(mem); 19 | assert(rt->realizeAll() == IB_SUCCESS); 20 | 21 | for (ObjcClass *classInfo : rt->realizedClasses) { 22 | ObjcClass *currentClass = classInfo; 23 | while (currentClass) { 24 | vector methods = classInfo->getMethods(); 25 | vector ivars = classInfo->getIvars(); 26 | // print class / method / props here 27 | 28 | currentClass = classInfo->superClassInfo; 29 | } 30 | } 31 | 32 | return 0; 33 | } -------------------------------------------------------------------------------- /v2/otool.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Soulghost/iblessing/ff14351de3f3c2155e8df47c26d4367523af7628/v2/otool.cpp --------------------------------------------------------------------------------