From 57da4f8318d5f4fe2f86151a5463fb973cce77ed Mon Sep 17 00:00:00 2001 From: artemis Date: Sat, 27 Jul 2024 10:56:51 +0800 Subject: [PATCH] Refactor code to support helper injection --- CMakeLists.txt | 5 + README.md | 46 ++--- dylib_dobby_hook.xcodeproj/project.pbxproj | 60 +++++- dylib_dobby_hook/apps/AirBuddyHack.m | 4 +- dylib_dobby_hook/apps/DevHack.m | 4 +- dylib_dobby_hook/apps/DevUtilsHack.m | 4 +- dylib_dobby_hook/apps/ForkLiftHack.m | 45 ++--- dylib_dobby_hook/apps/HackProtocol.h | 58 ------ dylib_dobby_hook/apps/HackProtocolDefault.h | 24 +++ dylib_dobby_hook/apps/HackProtocolDefault.m | 46 +++++ dylib_dobby_hook/apps/InfuseHack.m | 3 +- dylib_dobby_hook/apps/LightRoomHack.m | 90 --------- dylib_dobby_hook/apps/MacUpdaterHack.m | 4 +- dylib_dobby_hook/apps/MovistProHack.m | 4 +- dylib_dobby_hook/apps/NavicatPremiumHack.m | 4 +- dylib_dobby_hook/apps/PaddleBaseHack.m | 4 +- dylib_dobby_hook/apps/PasteHack.m | 4 +- dylib_dobby_hook/apps/ProxyManHack.m | 186 ++++++++++++------ dylib_dobby_hook/apps/TablePlusHack.m | 4 +- dylib_dobby_hook/apps/TransmitHack.m | 4 +- dylib_dobby_hook/helpers/ForkLiftHelperHack.m | 128 ++++++++++++ .../helpers/HackHelperProtocolDefault.h | 16 ++ .../helpers/HackHelperProtocolDefault.m | 14 ++ dylib_dobby_hook/utils/Constant.h | 2 + dylib_dobby_hook/utils/Constant.m | 68 ++++--- dylib_dobby_hook/utils/common_ret.h | 1 - dylib_dobby_hook/utils/common_ret.m | 1 - script/apps/forklift_hack.sh | 92 +++++++++ script/auto_hack.sh | 6 +- script/lightroom_hack.sh | 40 ---- tools/mac_patch_helper | Bin 61216 -> 70128 bytes tools/patch.json | 10 +- 32 files changed, 632 insertions(+), 349 deletions(-) create mode 100644 dylib_dobby_hook/apps/HackProtocolDefault.h create mode 100644 dylib_dobby_hook/apps/HackProtocolDefault.m delete mode 100644 dylib_dobby_hook/apps/LightRoomHack.m create mode 100644 dylib_dobby_hook/helpers/ForkLiftHelperHack.m create mode 100644 dylib_dobby_hook/helpers/HackHelperProtocolDefault.h create mode 100644 dylib_dobby_hook/helpers/HackHelperProtocolDefault.m create mode 100644 script/apps/forklift_hack.sh delete mode 100644 script/lightroom_hack.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 133d96e..b3a54c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,12 +56,15 @@ file(GLOB UtilsHeader ${CMAKE_SOURCE_DIR}/dylib_dobby_hook/utils/*.h) file(GLOB Apps ${CMAKE_SOURCE_DIR}/dylib_dobby_hook/apps/*.m) file(GLOB AppsHeader ${CMAKE_SOURCE_DIR}/dylib_dobby_hook/apps/*.h) +file(GLOB Helpers ${CMAKE_SOURCE_DIR}/dylib_dobby_hook/helpers/*.m) +file(GLOB HelpersHeader ${CMAKE_SOURCE_DIR}/dylib_dobby_hook/helpers/*.h) file(GLOB StaticLibs ${CMAKE_SOURCE_DIR}/libs/*.a) include_directories( ${CMAKE_SOURCE_DIR}/dylib_dobby_hook ${CMAKE_SOURCE_DIR}/dylib_dobby_hook/apps + ${CMAKE_SOURCE_DIR}/dylib_dobby_hook/helpers ${CMAKE_SOURCE_DIR}/dylib_dobby_hook/utils ) @@ -70,8 +73,10 @@ add_library(${PROJECT_NAME} SHARED ${MainHeader} ${UtilsHeader} ${AppsHeader} + ${HelpersHeader} ${Utils} ${Apps} + ${Helpers} ) set_target_properties(${PROJECT_NAME} PROPERTIES diff --git a/README.md b/README.md index 2a5ad38..3fccb97 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ 2. libs: 项目依赖的开源 dobby 库 3. release: build 后的成品 4. script: - - hack.sh 自定义注入脚本 `sudo sh hack.sh` - - auto_hack.sh 妹妹全自动注入脚本 `sudo sh auto_hack.sh` + - hack.sh 自定义注入脚本 `sudo sh hack.sh` + - auto_hack.sh 妹妹全自动注入脚本 `sudo sh auto_hack.sh` 5. tools: insert_dylib 开源注入工具 ## Feat @@ -29,32 +29,31 @@
点击这里展开/收起 -| App | version | x86 | arm | Download | remark | Author | -|-----------------|---------|-----|-----|----------------------------------------------|----------------------------------------------------------------------------------------------------------------------|---------------------| -| TablePlus | 6.* | ✔ | ✔ | https://tableplus.com/ | inject_bin="/Applications/TablePlus.app/Contents/Frameworks/Sparkle.framework/Versions/B/Sparkle" | | -| DevUtils | 1.* | ✔ | ✔ | https://devutils.com/ | | | -| AirBuddy | 2.* | ✔ | ✔ | https://v2.airbuddy.app/download | inject_bin="/Applications/AirBuddy.app/Contents/Frameworks/LetsMove.framework/Versions/A/LetsMove" | | -| Navicat Premium | 17.* | ✔ | ✔ | App Store | inject_bin="/Applications/Navicat Premium.app/Contents/Frameworks/EE.framework/Versions/A/EE" | QiuChenlyOpenSource | -| Paste | 4.1.3 | ✘ | ✔ | App Store | | LeeeMooo | -| Transmit | 5.* | ✔ | ✔ | https://panic.com/transmit/#download | | | -| AnyGo | 7.* | ✔ | ✔ | https://itoolab.com/gps-location-changer/ | DMCA | | -| Downie | 4.* | ✔ | ✔ | https://software.charliemonroe.net/downie/ | inject_bin="/Applications/Permute 3.app/Contents/Frameworks/Licensing.framework/Versions/A/Licensing" | | -| Permute | 3.* | ✔ | ✔ | https://software.charliemonroe.net/permute/ | inject_bin="/Applications/Downie 4.app/Contents/Frameworks/Licensing.framework/Versions/A/Licensing" | | -| ProxyMan | 5.2 | ✔ | ✔ | https://proxyman.io/ | inject_bin="/Applications/Proxyman.app/Contents/Frameworks/HexFiend.framework/Versions/A/HexFiend" | | -| Movist Pro | 2.* | ✔ | ✔ | https://movistprime.com/ | inject_bin="/Applications/Movist Pro.app/Contents/Frameworks/MediaKeyTap.framework/Versions/A/MediaKeyTap" | | -| Surge | 5.7.* | ✔ | ✔ | https://nssurge.com/ | DMCA | | -| Infuse | 7.7.* | ✔ | ✔ | App Store | inject_bin="/Applications/Infuse.app/Contents/Frameworks/Differentiator.framework/Versions/A/Differentiator" | | -| MacUpdater | 3. | ✔ | ✔ | https://www.corecode.io/macupdater/#download | inject_bin="/Applications/MacUpdater.app/Contents/Frameworks/Sparkle.framework/Versions/B/Sparkle" | | -| CleanShotX | 4. | ✔ | ✘ | https://updates.getcleanshot.com/v3/ | DMCA | | -| ForkLift | 4. | ✔ | ✔ | https://binarynights.com/ | inject_bin="/Applications/ForkLift.app/Contents/Frameworks/UniversalDetector.framework/Versions/A/UniversalDetector" | | +| App | version | x86 | arm | Download | SIP | Author | +|-----------------|---------|-----|-----|----------------------------------------------|-----|---------------------| +| TablePlus | 6.* | ✔ | ✔ | https://tableplus.com/ | | | +| DevUtils | 1.* | ✔ | ✔ | https://devutils.com/ | | | +| AirBuddy | 2.* | ✔ | ✔ | https://v2.airbuddy.app/download | | | +| Navicat Premium | 17.* | ✔ | ✔ | App Store | | QiuChenlyOpenSource | +| Paste | 4.1.3 | ✘ | ✔ | App Store | | LeeeMooo | +| Transmit | 5.* | ✔ | ✔ | https://panic.com/transmit/#download | | | +| AnyGo | 7.* | ✔ | ✔ | https://itoolab.com/gps-location-changer/ | | | +| Downie | 4.* | ✔ | ✔ | https://software.charliemonroe.net/downie/ | | | +| Permute | 3.* | ✔ | ✔ | https://software.charliemonroe.net/permute/ | | | +| ProxyMan | 5. | ✔ | ✔ | https://proxyman.io/ | | | +| Movist Pro | 2.* | ✔ | ✔ | https://movistprime.com/ | | | +| Surge | 5.7.* | ✔ | ✔ | https://nssurge.com/ | | | +| Infuse | 7.7.* | ✔ | ✔ | App Store | | | +| MacUpdater | 3. | ✔ | ✔ | https://www.corecode.io/macupdater/#download | | | +| CleanShotX | 4. | ✔ | ✘ | https://updates.getcleanshot.com/v3/ | | | +| ForkLift | 4. | ✔ | ✔ | https://binarynights.com/ | ON | |
- ## Usage - [download latest release](https://github.com/marlkiller/dylib_dobby_hook/releases/download/latest/dylib_dobby_hook.tar.gz) + ```shell tar -xzvf dylib_dobby_hook.tar.gz cd script @@ -76,7 +75,7 @@ sudo sh auto_hack.sh #import "HackProtocol.h" -@interface XXXHack : NSObject +@interface XXXHack : HackProtocolDefault @end @@ -156,6 +155,7 @@ cp -f "${BUILT_PRODUCTS_DIR}/${prefix}${dylib_name}.dylib" "${app_bundle_framewo ``` ## Sponsor + [![JetBrains](jetbrains.svg)](https://www.jetbrains.com/?from=dylib_dobby_hook "JetBrains") ## Ref diff --git a/dylib_dobby_hook.xcodeproj/project.pbxproj b/dylib_dobby_hook.xcodeproj/project.pbxproj index c641c21..5aab559 100644 --- a/dylib_dobby_hook.xcodeproj/project.pbxproj +++ b/dylib_dobby_hook.xcodeproj/project.pbxproj @@ -26,9 +26,13 @@ B546A6582BC4F0CD0012338D /* ProxyManHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B546A6572BC4F0CD0012338D /* ProxyManHack.m */; }; B55407272B653DCB005C08E6 /* NavicatPremiumHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B55407262B653DCB005C08E6 /* NavicatPremiumHack.m */; }; B554D7BC2B63F2A300B7EFEA /* DevUtilsHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B554D7BB2B63F2A300B7EFEA /* DevUtilsHack.m */; }; - B580D3CA2BE3579300979568 /* LightRoomHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B580D3C72BE3579300979568 /* LightRoomHack.m */; }; B58160172BE88569001DDB9B /* encryp_utils.m in Sources */ = {isa = PBXBuildFile; fileRef = B58160112BE88569001DDB9B /* encryp_utils.m */; }; B581601B2BE88569001DDB9B /* encryp_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = B58160162BE88569001DDB9B /* encryp_utils.h */; }; + B5A7D30F2C548B71003D4C7F /* HackProtocolDefault.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A7D30E2C548B71003D4C7F /* HackProtocolDefault.h */; }; + B5A7D3112C548BAB003D4C7F /* HackProtocolDefault.m in Sources */ = {isa = PBXBuildFile; fileRef = B5A7D3102C548BAB003D4C7F /* HackProtocolDefault.m */; }; + B5A7D3142C549130003D4C7F /* ForkLiftHelperHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B5A7D3132C549130003D4C7F /* ForkLiftHelperHack.m */; }; + B5A7D3172C5491A0003D4C7F /* HackHelperProtocolDefault.m in Sources */ = {isa = PBXBuildFile; fileRef = B5A7D3152C5491A0003D4C7F /* HackHelperProtocolDefault.m */; }; + B5A7D3182C5491A0003D4C7F /* HackHelperProtocolDefault.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A7D3162C5491A0003D4C7F /* HackHelperProtocolDefault.h */; }; B5D0C0BB2C4B553500881398 /* ForkLiftHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B5D0C0BA2C4B553500881398 /* ForkLiftHack.m */; }; B5D2ED3F2BC0252D0030CBCA /* DevHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B5D2ED3E2BC0252D0030CBCA /* DevHack.m */; }; B5F06B1D2BEF591E0079E68D /* InfuseHack.m in Sources */ = {isa = PBXBuildFile; fileRef = B5F06B1C2BEF591E0079E68D /* InfuseHack.m */; }; @@ -76,9 +80,22 @@ B554D7BB2B63F2A300B7EFEA /* DevUtilsHack.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DevUtilsHack.m; sourceTree = ""; }; B56968C62BEA4E2A0022FAC6 /* libdylib_dobby_hook.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libdylib_dobby_hook.dylib; sourceTree = ""; }; B56968C72BEA4E4D0022FAC6 /* cmake_debugger.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = cmake_debugger.sh; sourceTree = ""; }; - B580D3C72BE3579300979568 /* LightRoomHack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LightRoomHack.m; sourceTree = ""; }; + B57AEDBA2C5009E400B9C5FB /* forklift_hack.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = forklift_hack.sh; sourceTree = ""; }; + B57AEDBB2C5009F200B9C5FB /* dtrace_kill.d */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.dtrace; path = dtrace_kill.d; sourceTree = ""; }; + B57AEDBC2C5009F200B9C5FB /* SMJobBlessUtil-python3.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = "SMJobBlessUtil-python3.py"; sourceTree = ""; }; + B57AEDBD2C5009F200B9C5FB /* mac_patch_helper */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = mac_patch_helper; sourceTree = ""; }; + B57AEDBE2C5009F200B9C5FB /* patch.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = patch.json; sourceTree = ""; }; B58160112BE88569001DDB9B /* encryp_utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = encryp_utils.m; sourceTree = ""; }; B58160162BE88569001DDB9B /* encryp_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = encryp_utils.h; sourceTree = ""; }; + B5A7D30E2C548B71003D4C7F /* HackProtocolDefault.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HackProtocolDefault.h; sourceTree = ""; }; + B5A7D3102C548BAB003D4C7F /* HackProtocolDefault.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HackProtocolDefault.m; sourceTree = ""; }; + B5A7D3132C549130003D4C7F /* ForkLiftHelperHack.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ForkLiftHelperHack.m; sourceTree = ""; }; + B5A7D3152C5491A0003D4C7F /* HackHelperProtocolDefault.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HackHelperProtocolDefault.m; sourceTree = ""; }; + B5A7D3162C5491A0003D4C7F /* HackHelperProtocolDefault.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HackHelperProtocolDefault.h; sourceTree = ""; }; + B5BE2D582C52A5E40056B3E2 /* build.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = ""; }; + B5BE2D592C52A5E40056B3E2 /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = ""; }; + B5BE2D5A2C52A5E40056B3E2 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + B5BE2D5B2C52A5E40056B3E2 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; B5D0C0BA2C4B553500881398 /* ForkLiftHack.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ForkLiftHack.m; sourceTree = ""; }; B5D2ED3E2BC0252D0030CBCA /* DevHack.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DevHack.m; sourceTree = ""; }; B5F06B1C2BEF591E0079E68D /* InfuseHack.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InfuseHack.m; sourceTree = ""; }; @@ -111,6 +128,10 @@ 38350BE92B53F73A00DD52B3 = { isa = PBXGroup; children = ( + B5BE2D582C52A5E40056B3E2 /* build.sh */, + B5BE2D592C52A5E40056B3E2 /* CMakeLists.txt */, + B5BE2D5A2C52A5E40056B3E2 /* LICENSE */, + B5BE2D5B2C52A5E40056B3E2 /* README.md */, 38350C0B2B5407CD00DD52B3 /* release */, 38350C082B54047F00DD52B3 /* script */, 38350C062B53F93D00DD52B3 /* tools */, @@ -133,6 +154,7 @@ isa = PBXGroup; children = ( B581601D2BE894A2001DDB9B /* utils */, + B5A7D3122C54911C003D4C7F /* helpers */, B581601C2BE8949B001DDB9B /* apps */, 38350BF52B53F73A00DD52B3 /* dylib_dobby_hook.h */, 38350BF72B53F73A00DD52B3 /* dylib_dobby_hook.m */, @@ -152,6 +174,10 @@ 38350C062B53F93D00DD52B3 /* tools */ = { isa = PBXGroup; children = ( + B57AEDBB2C5009F200B9C5FB /* dtrace_kill.d */, + B57AEDBD2C5009F200B9C5FB /* mac_patch_helper */, + B57AEDBE2C5009F200B9C5FB /* patch.json */, + B57AEDBC2C5009F200B9C5FB /* SMJobBlessUtil-python3.py */, 38350C072B53F96100DD52B3 /* insert_dylib */, ); path = tools; @@ -160,6 +186,7 @@ 38350C082B54047F00DD52B3 /* script */ = { isa = PBXGroup; children = ( + B5BE2D572C52A4530056B3E2 /* apps */, B56968C72BEA4E4D0022FAC6 /* cmake_debugger.sh */, 38350C092B54047F00DD52B3 /* hack.sh */, 38E793632B6C7AB8005677AA /* all_in_one.sh */, @@ -179,10 +206,10 @@ B581601C2BE8949B001DDB9B /* apps */ = { isa = PBXGroup; children = ( + B5D0C0BA2C4B553500881398 /* ForkLiftHack.m */, B5F06B1C2BEF591E0079E68D /* InfuseHack.m */, 38D1AC312B54D1CC00E6CB9E /* AirBuddyHack.m */, 38D1AC2B2B54D03B00E6CB9E /* HackProtocol.h */, - B580D3C72BE3579300979568 /* LightRoomHack.m */, B5FE3B842BA2A571001AE437 /* TransmitHack.m */, 382A25842B6918DF0083F28C /* PasteHack.m */, 38B83E302B5505B300919735 /* TablePlusHack.m */, @@ -193,6 +220,8 @@ B546A6572BC4F0CD0012338D /* ProxyManHack.m */, B502BD5C2BCFB35200DAD97F /* MovistProHack.m */, B53522452C2FE4D4001CA305 /* MacUpdaterHack.m */, + B5A7D30E2C548B71003D4C7F /* HackProtocolDefault.h */, + B5A7D3102C548BAB003D4C7F /* HackProtocolDefault.m */, ); path = apps; sourceTree = ""; @@ -212,6 +241,24 @@ path = utils; sourceTree = ""; }; + B5A7D3122C54911C003D4C7F /* helpers */ = { + isa = PBXGroup; + children = ( + B5A7D3162C5491A0003D4C7F /* HackHelperProtocolDefault.h */, + B5A7D3152C5491A0003D4C7F /* HackHelperProtocolDefault.m */, + B5A7D3132C549130003D4C7F /* ForkLiftHelperHack.m */, + ); + path = helpers; + sourceTree = ""; + }; + B5BE2D572C52A4530056B3E2 /* apps */ = { + isa = PBXGroup; + children = ( + B57AEDBA2C5009E400B9C5FB /* forklift_hack.sh */, + ); + path = apps; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -221,8 +268,10 @@ files = ( B5FECEAD2BC4FC29008916D6 /* common_ret.h in Headers */, B581601B2BE88569001DDB9B /* encryp_utils.h in Headers */, + B5A7D30F2C548B71003D4C7F /* HackProtocolDefault.h in Headers */, 38350BF62B53F73A00DD52B3 /* dylib_dobby_hook.h in Headers */, 3816BBB72B54FED80051CF39 /* MemoryUtils.h in Headers */, + B5A7D3182C5491A0003D4C7F /* HackHelperProtocolDefault.h in Headers */, 38350C022B53F78900DD52B3 /* dobby.h in Headers */, 38D1AC282B54C9C100E6CB9E /* Constant.h in Headers */, 38D1AC2C2B54D03B00E6CB9E /* HackProtocol.h in Headers */, @@ -313,17 +362,20 @@ B50E935E2BBD024F0073FEAA /* PaddleBaseHack.m in Sources */, 38D1AC322B54D1CC00E6CB9E /* AirBuddyHack.m in Sources */, B5D2ED3F2BC0252D0030CBCA /* DevHack.m in Sources */, + B5A7D3112C548BAB003D4C7F /* HackProtocolDefault.m in Sources */, B546A6582BC4F0CD0012338D /* ProxyManHack.m in Sources */, B58160172BE88569001DDB9B /* encryp_utils.m in Sources */, B53522462C2FE4D4001CA305 /* MacUpdaterHack.m in Sources */, + B5A7D3142C549130003D4C7F /* ForkLiftHelperHack.m in Sources */, 38350BF82B53F73A00DD52B3 /* dylib_dobby_hook.m in Sources */, + B5A7D3172C5491A0003D4C7F /* HackHelperProtocolDefault.m in Sources */, 382A25862B6918DF0083F28C /* PasteHack.m in Sources */, B554D7BC2B63F2A300B7EFEA /* DevUtilsHack.m in Sources */, + B5D0C0BB2C4B553500881398 /* ForkLiftHack.m in Sources */, B5F06B1D2BEF591E0079E68D /* InfuseHack.m in Sources */, B55407272B653DCB005C08E6 /* NavicatPremiumHack.m in Sources */, 3816BBB92B54FF090051CF39 /* MemoryUtils.m in Sources */, 38B83E312B5505B300919735 /* TablePlusHack.m in Sources */, - B580D3CA2BE3579300979568 /* LightRoomHack.m in Sources */, B5FECEAE2BC4FC29008916D6 /* common_ret.m in Sources */, 38D1AC2A2B54CA4D00E6CB9E /* Constant.m in Sources */, B502BD5D2BCFB35200DAD97F /* MovistProHack.m in Sources */, diff --git a/dylib_dobby_hook/apps/AirBuddyHack.m b/dylib_dobby_hook/apps/AirBuddyHack.m index e854a99..9006939 100644 --- a/dylib_dobby_hook/apps/AirBuddyHack.m +++ b/dylib_dobby_hook/apps/AirBuddyHack.m @@ -9,14 +9,14 @@ #import "Constant.h" #import "dobby.h" #import "MemoryUtils.h" -#import "HackProtocol.h" #include "common_ret.h" #include #import #include #import +#import "HackProtocolDefault.h" -@interface AirBuddyHack : NSObject +@interface AirBuddyHack : HackProtocolDefault @end @implementation AirBuddyHack diff --git a/dylib_dobby_hook/apps/DevHack.m b/dylib_dobby_hook/apps/DevHack.m index e66cd4a..cff8170 100644 --- a/dylib_dobby_hook/apps/DevHack.m +++ b/dylib_dobby_hook/apps/DevHack.m @@ -11,7 +11,7 @@ #import "MemoryUtils.h" #import #include -#import "HackProtocol.h" +#import "HackProtocolDefault.h" #include #import #import "common_ret.h" @@ -72,7 +72,7 @@ - (void)drawRect:(NSRect)dirtyRect { @end -@interface DevHack : NSObject +@interface DevHack : HackProtocolDefault //+ (NSWindow *)myWindow; @end diff --git a/dylib_dobby_hook/apps/DevUtilsHack.m b/dylib_dobby_hook/apps/DevUtilsHack.m index abaea6d..15d8c85 100644 --- a/dylib_dobby_hook/apps/DevUtilsHack.m +++ b/dylib_dobby_hook/apps/DevUtilsHack.m @@ -10,9 +10,9 @@ #import "dobby.h" #import "MemoryUtils.h" #import -#import "HackProtocol.h" +#import "HackProtocolDefault.h" -@interface DevUtilsHack : NSObject +@interface DevUtilsHack : HackProtocolDefault @end diff --git a/dylib_dobby_hook/apps/ForkLiftHack.m b/dylib_dobby_hook/apps/ForkLiftHack.m index 81991b2..051235d 100644 --- a/dylib_dobby_hook/apps/ForkLiftHack.m +++ b/dylib_dobby_hook/apps/ForkLiftHack.m @@ -9,11 +9,12 @@ #import "Constant.h" #import "MemoryUtils.h" #import -#import "HackProtocol.h" #include +#import +#import "dobby.h" +#import "HackProtocolDefault.h" - -@interface ForkLiftHack : NSObject +@interface ForkLiftHack : HackProtocolDefault @@ -22,9 +23,11 @@ @interface ForkLiftHack : NSObject @implementation ForkLiftHack +static IMP listenerIMP; - (NSString *)getAppName { + // com.binarynights.ForkLiftHelper return @"com.binarynights.ForkLift"; } @@ -32,32 +35,12 @@ - (NSString *)getSupportAppVersion { return @"4."; } ++ (CKContainer *)containerWithIdentifier:identifier { + return class_createInstance([CKContainer class], 0); +} - - (BOOL)hack { - - -// -// ; struct ForkLift.RegistrationData { -// ; let name: Swift.String -// ; let quantity: Swift.Int -// ; let license_type: Swift.Int -// ; let validityDate: Foundation.Date -// ; let signature: Swift.String -// ; let licenseKey: Swift.String? -// ; } -//_$s8ForkLift16RegistrationDataVMn: // nominal type descriptor for ForkLift.RegistrationData -//00000001008327c0 struct __swift_StructDescriptor { ; "RegistrationData", DATA XREF=_$s8ForkLift16RegistrationDataVMa+7 -// struct __swift_ContextDescriptor { // context -// 0x10051, // flags -// _$s8ForkLiftMXM-0x1008327c4, // parent context -// aRegistrationda-0x1008327c8, // name of the type -// _$s8ForkLift16RegistrationDataVMa-0x1008327cc, // type accessor function pointer -// _$s8ForkLift16RegistrationDataVMF-0x1008327d0 // fields -// }, -// 0x6, // number of fields -// 0x2 -//} + // 自定义日期字符串 NSDictionary *registrationDataDict = @{ @"name": [Constant G_EMAIL_ADDRESS], @@ -73,6 +56,14 @@ - (BOOL)hack { [defaults synchronize]; + + [MemoryUtils hookClassMethod: + NSClassFromString(@"CKContainer") + originalSelector:NSSelectorFromString(@"containerWithIdentifier:") + swizzledClass:[self class] + swizzledSelector:@selector(containerWithIdentifier: ) + ]; + return YES; } diff --git a/dylib_dobby_hook/apps/HackProtocol.h b/dylib_dobby_hook/apps/HackProtocol.h index 389fbcf..e4ea144 100644 --- a/dylib_dobby_hook/apps/HackProtocol.h +++ b/dylib_dobby_hook/apps/HackProtocol.h @@ -12,61 +12,3 @@ - (BOOL)hack; @end - -@interface NSObject (HackProtocolDefaults) -- (void)ret; -- (void)ret_; -- (void)ret__; - -- (int)ret1; -- (int)ret0; -+ (int)ret1; -+ (int)ret0; - -@end - -@implementation NSObject (HackProtocolDefaults) - -- (void)ret { - NSLog(@">>>>>> called - ret"); -} -- (void)ret_ { - NSLog(@">>>>>> called - ret_"); -} -- (void)ret__ { - NSLog(@">>>>>> called - ret__"); -} - -- (int)ret1 { - NSLog(@">>>>>> called - ret1"); - return 1; -} -- (int)ret0 { - NSLog(@">>>>>> called - ret0"); - return 0; -} -+ (int)ret1 { - NSLog(@">>>>>> called + ret1"); - return 1; -} -+ (int)ret0 { - NSLog(@">>>>>> called + ret0"); - return 0; -} -+ (void)ret { - NSLog(@">>>>>> called + ret"); -} - -- (BOOL)hack { - return NO; -} - -- (NSString *)getAppName { - return nil; -} - -- (NSString *)getSupportAppVersion { - return nil; -} - -@end diff --git a/dylib_dobby_hook/apps/HackProtocolDefault.h b/dylib_dobby_hook/apps/HackProtocolDefault.h new file mode 100644 index 0000000..a0eedc2 --- /dev/null +++ b/dylib_dobby_hook/apps/HackProtocolDefault.h @@ -0,0 +1,24 @@ +// +// HackProtocolDefault.h +// dylib_dobby_hook +// + +#ifndef HackProtocolDefault_h +#define HackProtocolDefault_h + +#import "HackProtocol.h" + +@interface HackProtocolDefault : NSObject + +- (void)ret; +- (void)ret_; +- (void)ret__; + +- (int)ret1; +- (int)ret0; ++ (int)ret1; ++ (int)ret0; + +@end +#endif + diff --git a/dylib_dobby_hook/apps/HackProtocolDefault.m b/dylib_dobby_hook/apps/HackProtocolDefault.m new file mode 100644 index 0000000..1956d39 --- /dev/null +++ b/dylib_dobby_hook/apps/HackProtocolDefault.m @@ -0,0 +1,46 @@ +// +// HackCommon.m +// dylib_dobby_hook +// +// Created by 马治武 on 2024/7/27. +// + +#import +#import "HackProtocolDefault.h" + +@implementation HackProtocolDefault + + +- (void)ret { + NSLog(@">>>>>> called - ret"); +} +- (void)ret_ { + NSLog(@">>>>>> called - ret_"); +} +- (void)ret__ { + NSLog(@">>>>>> called - ret__"); +} + +- (int)ret1 { + NSLog(@">>>>>> called - ret1"); + return 1; +} +- (int)ret0 { + NSLog(@">>>>>> called - ret0"); + return 0; +} ++ (int)ret1 { + NSLog(@">>>>>> called + ret1"); + return 1; +} ++ (int)ret0 { + NSLog(@">>>>>> called + ret0"); + return 0; +} ++ (void)ret { + NSLog(@">>>>>> called + ret"); +} + + +@end + diff --git a/dylib_dobby_hook/apps/InfuseHack.m b/dylib_dobby_hook/apps/InfuseHack.m index bdfd4d0..3c27f32 100644 --- a/dylib_dobby_hook/apps/InfuseHack.m +++ b/dylib_dobby_hook/apps/InfuseHack.m @@ -10,10 +10,9 @@ #import "dobby.h" #import "MemoryUtils.h" #import -#import "HackProtocol.h" #include #import "common_ret.h" - +#import "HackProtocolDefault.h" @interface InfuseHack : NSObject diff --git a/dylib_dobby_hook/apps/LightRoomHack.m b/dylib_dobby_hook/apps/LightRoomHack.m deleted file mode 100644 index 285584f..0000000 --- a/dylib_dobby_hook/apps/LightRoomHack.m +++ /dev/null @@ -1,90 +0,0 @@ -// -// LightRoomHack.m -// dylib_dobby_hook -// -// Created by gyc on 2024/4/10. -// - -#import -#import "Constant.h" -#import "dobby.h" -#import "MemoryUtils.h" -#import -#include -#import "HackProtocol.h" -#include -#import "common_ret.h" - -@interface LightRoomHack : NSObject - -@end - - -@implementation LightRoomHack - - - -- (NSString *)getAppName { - // >>>>>> AppName is [com.adobe.lightroomCC],Version is [7.2], myAppCFBundleVersion is []. - return @"com.adobe.lightroomCC"; -} - -- (NSString *)getSupportAppVersion { - return @"7.2"; -} - - - -- (BOOL)hack { - - NSString *searchFilePath = [[Constant getCurrentAppPath] stringByAppendingString:@"/Contents/MacOS/Adobe Lightroom"]; - // 获取文件中指定CPU架构段的偏移量 - uintptr_t fileOffset =[MemoryUtils getCurrentArchFileOffset: searchFilePath]; - -#if defined(__arm64__) || defined(__aarch64__) - // TODO - NSString *get_licenseType =@""; -#elif defined(__x86_64__) - NSString *get_licenseType =@"55 48 89 E5 41 57 41 56 41 54 53 48 83 EC .. .. .. F6 48 8B 07 48 8B 40 10 44 8B 78 08 .. .. .. 10 8B 58 30 48 8D 35 C1 69 1C 00 48 8D 7D C8 E8 83 F8 FF FF"; - -#endif - - //特征码搜索,在文件中搜索的 - NSArray *get_licenseTypeCodeOffsets =[MemoryUtils searchMachineCodeOffsets: - searchFilePath - machineCode:get_licenseType - count:(int)1 - ]; - //获取特征码搜索到的函数实际在内存中的地址,,,理解是:执行文件在内存中加载的实际位置+偏移量,而偏移量=(特征码在文件中的位置-当前CPU类型的架构段基地值) - intptr_t _get_licenseTypeCode =[MemoryUtils getPtrFromGlobalOffset:0 targetFunctionOffset:(uintptr_t)[get_licenseTypeCodeOffsets[0] unsignedIntegerValue] reduceOffset:(uintptr_t)fileOffset]; - - // 将文件偏移量转换为内存地址// 确定 je 指令在get_license中的偏移量==0x10011970e - 0x1001196b9 - uintptr_t jumpInstructionMemoryAddress = 0x10011970e - 0x1001196b9 +_get_licenseTypeCode; - - // 验证内存地址处的机器码是否为 je 指令的机器码 (0x74) - NSString *currentMachineCode =[MemoryUtils readMachineCodeStringAtAddress:jumpInstructionMemoryAddress length:1]; - NSLog(@"Machine code at address %p: %@", (void *)jumpInstructionMemoryAddress, currentMachineCode); - if ([currentMachineCode isEqualToString:@"74"]) { - // 如果是,则构造 jne (0x75) 指令的机器码字符串 - NSString *newMachineCode = @"75"; - // 写入新的机器码,writeMachineCodeString方法会导致试图写入只读内存崩溃 - // [MemoryUtils writeMachineCodeString:newMachineCode toAddress:jumpInstructionMemoryAddress]; - NSLog(@">>>>>> Before %s",[MemoryUtils readMachineCodeStringAtAddress:jumpInstructionMemoryAddress length:3].UTF8String); - uint8_t ret1Day[1] = {0x75 }; - DobbyCodePatch((void *)jumpInstructionMemoryAddress, ret1Day,1); - NSLog(@">>>>>> After %s",[MemoryUtils readMachineCodeStringAtAddress:jumpInstructionMemoryAddress length:3].UTF8String); - NSString *machineCodeAfterWrite = [MemoryUtils readMachineCodeStringAtAddress:jumpInstructionMemoryAddress length:3]; - NSLog(@"Successfully changed JE to JNE at address: %p", (void *)jumpInstructionMemoryAddress); - NSLog(@"Machine code at address %p: %@", (void *)jumpInstructionMemoryAddress, machineCodeAfterWrite); - return YES; - } else { - // 如果不是,则记录一个错误并返回 NO - NSLog(@"Expected JE instruction not found at address: %p", (void *)jumpInstructionMemoryAddress); - return NO; - } - - return YES; -} - -@end - diff --git a/dylib_dobby_hook/apps/MacUpdaterHack.m b/dylib_dobby_hook/apps/MacUpdaterHack.m index 6b4a803..5ba49db 100644 --- a/dylib_dobby_hook/apps/MacUpdaterHack.m +++ b/dylib_dobby_hook/apps/MacUpdaterHack.m @@ -11,11 +11,11 @@ #import "MemoryUtils.h" #import "encryp_utils.h" #import -#import "HackProtocol.h" +#import "HackProtocolDefault.h" #include #import "common_ret.h" -@interface MacUpdaterHack : NSObject +@interface MacUpdaterHack : HackProtocolDefault diff --git a/dylib_dobby_hook/apps/MovistProHack.m b/dylib_dobby_hook/apps/MovistProHack.m index 4056188..ca5cf64 100644 --- a/dylib_dobby_hook/apps/MovistProHack.m +++ b/dylib_dobby_hook/apps/MovistProHack.m @@ -7,10 +7,10 @@ #import #import -#import "HackProtocol.h" +#import "HackProtocolDefault.h" -@interface MovistProHack : NSObject +@interface MovistProHack : HackProtocolDefault @end diff --git a/dylib_dobby_hook/apps/NavicatPremiumHack.m b/dylib_dobby_hook/apps/NavicatPremiumHack.m index 934f9d5..5bb180a 100644 --- a/dylib_dobby_hook/apps/NavicatPremiumHack.m +++ b/dylib_dobby_hook/apps/NavicatPremiumHack.m @@ -10,10 +10,10 @@ #import "dobby.h" #import "MemoryUtils.h" #import -#import "HackProtocol.h" +#import "HackProtocolDefault.h" #import "common_ret.h" -@interface NavicatPremiumHack : NSObject +@interface NavicatPremiumHack : HackProtocolDefault @end @implementation NavicatPremiumHack diff --git a/dylib_dobby_hook/apps/PaddleBaseHack.m b/dylib_dobby_hook/apps/PaddleBaseHack.m index 96e4ef1..8c382ca 100644 --- a/dylib_dobby_hook/apps/PaddleBaseHack.m +++ b/dylib_dobby_hook/apps/PaddleBaseHack.m @@ -12,10 +12,10 @@ #import #include #import -#import "HackProtocol.h" +#import "HackProtocolDefault.h" #import "common_ret.h" -@interface PaddleBaseHack : NSObject +@interface PaddleBaseHack : HackProtocolDefault @end diff --git a/dylib_dobby_hook/apps/PasteHack.m b/dylib_dobby_hook/apps/PasteHack.m index fded907..a747fe0 100644 --- a/dylib_dobby_hook/apps/PasteHack.m +++ b/dylib_dobby_hook/apps/PasteHack.m @@ -3,10 +3,10 @@ #import "dobby.h" #import "MemoryUtils.h" #import -#import "HackProtocol.h" #import "common_ret.h" +#import "HackProtocolDefault.h" -@interface PasteHack : NSObject +@interface PasteHack : HackProtocolDefault @end diff --git a/dylib_dobby_hook/apps/ProxyManHack.m b/dylib_dobby_hook/apps/ProxyManHack.m index c781fcf..dee034a 100644 --- a/dylib_dobby_hook/apps/ProxyManHack.m +++ b/dylib_dobby_hook/apps/ProxyManHack.m @@ -10,18 +10,20 @@ #import "dobby.h" #import "MemoryUtils.h" #import -#include -#import "HackProtocol.h" -#include +#import "HackProtocolDefault.h" +#import +#import +#import #import "common_ret.h" -@interface ProxyManHack : NSObject +@interface ProxyManHack : HackProtocolDefault @end @implementation ProxyManHack +static IMP viewDidLoadIMP; - (NSString *)getAppName { // >>>>>> AppName is [com.proxyman.NSProxy],Version is [5.1.1], myAppCFBundleVersion is [50101]. @@ -32,72 +34,146 @@ - (NSString *)getSupportAppVersion { return @"5"; } +intptr_t (*getProxyManAppStructOriginalAddress)(void); +intptr_t getProxyManAppStruct(void) { + + intptr_t app = getProxyManAppStructOriginalAddress(); + // 得到 App 里面的 license 对象 + intptr_t *licenseServer = app + 0xA0; + // 得到 license 里面 112 偏移处的 licensekey 字段 + intptr_t *licenseKey = *licenseServer + 0x70; + // 修改授权信息为激活状态 + *licenseKey = 0x0; + return app; +} + + + + +/** + * 通杀掉ProxyMan 的 Helper Check函数 + */ +intptr_t handleHelper(intptr_t a1, intptr_t a2, intptr_t a3) { + intptr_t *v7 = (void *) a1 + 40; + intptr_t *v6 = (void *) a1 + 32; + intptr_t v6_1 = *v6; //版本号 + intptr_t v7_1 = *v7; + intptr_t *v8 = (void *) v7_1 + 16; + intptr_t v8_1 = *v8; + void (*v8Call)(intptr_t, int, intptr_t) = (void *) v8_1;// 让Helper版本识别正确 + v8Call(v7_1, 1, v6_1); + return v6_1; +} + +- (void) hook_viewDidLoad{ + ((void*(*)(id, SEL))viewDidLoadIMP)(self, _cmd); + // objc_ivar_offset__TtC8Proxyman25PremiumPlanViewController_registerAtLbl: + // -[_TtC8Proxyman25PremiumPlanViewController registerAtLbl]: // -[Proxyman.PremiumPlanViewController registerAtLbl] + NSTextField *registerAtLbl = [MemoryUtils getInstanceIvar:self ivarName:"registerAtLbl"]; + NSView *expiredLicenseInfoStackView = [MemoryUtils getInstanceIvar:self ivarName:"expiredLicenseInfoStackView"]; + NSTextField *licenseUntilLbl = [MemoryUtils getInstanceIvar:self ivarName:"licenseUntilLbl"]; + [expiredLicenseInfoStackView setHidden:true]; + [licenseUntilLbl setStringValue:@"更新永久可用. (直到 QiuChenlyTeam 停止更新 以后)"]; + [registerAtLbl setStringValue:[Constant G_EMAIL_ADDRESS]]; +} - (BOOL)hack { - - + NSString *searchFilePath = [[Constant getCurrentAppPath] stringByAppendingString:@"/Contents/MacOS/Proxyman"]; uintptr_t fileOffset =[MemoryUtils getCurrentArchFileOffset: searchFilePath]; - -#if defined(__arm64__) || defined(__aarch64__) - NSString *sub_0x10001af90Code = @"F4 4F BE A9 FD 7B 01 A9 FD 43 00 91 F3 03 01 AA E1 03 00 AA .. .. 00 90 42 .. .. 91 48 80 5F F8 08 11 40 F9 E0 03 13 AA 00 01 3F D6 E0 03 13 AA FD 7B 41 A9 F4 4F C2 A8 C0 03 5F D6"; - NSString *remainingDaysCode = @".. .. .. 94 F4 03 00 AA F5 03 01 AA E0 83 01 91 .. .. .. 94 28 00 80 52 89 FE 7F D3 BF 02 00 72 34 01 88 1A"; -#elif defined(__x86_64__) - NSString *sub_0x10001af90Code = @"55 48 89 E5 53 50 48 89 F3 48 89 FE 48 8D .. .. .. .. .. 48 8B 42 F8 48 89 DF FF 50 20 48 89 D8 48 83 C4 08 5B 5D C3"; - NSString *remainingDaysCode =@"E8 .. .. .. .. 49 89 C6 41 89 D7 48 8D BD C8 FE FF FF E8 .. .. .. .. 41 B4 01 41 F6 C7 01 75 .."; - -#endif + int proxymanCoreIndex = [MemoryUtils indexForImageWithName:@"ProxymanCore"]; + NSString *proxymanCoreFilePath = [[Constant getCurrentAppPath] stringByAppendingString:@"/Contents/Frameworks/ProxymanCore.framework/Versions/A/ProxymanCore"]; + uintptr_t proxymanCoreFileOffset =[MemoryUtils getCurrentArchFileOffset: proxymanCoreFilePath]; - NSArray *sub_0x10001af90Offsets =[MemoryUtils searchMachineCodeOffsets: - searchFilePath - machineCode:sub_0x10001af90Code - count:(int)1 - ]; - intptr_t _sub_0x10001af90 = [MemoryUtils getPtrFromGlobalOffset:0 targetFunctionOffset:(uintptr_t)[sub_0x10001af90Offsets[0] unsignedIntegerValue] reduceOffset:(uintptr_t)fileOffset]; - - - NSArray *remainingDaysCodeOffsets =[MemoryUtils searchMachineCodeOffsets: - searchFilePath - machineCode:remainingDaysCode - count:(int)1 + + Class NSMutableArrayClass = NSClassFromString(@"_TtC8Proxyman25PremiumPlanViewController"); + SEL componentsJoinedByStringSeletor = NSSelectorFromString(@"viewDidLoad"); + Method componentsJoinedByStringMethod = class_getInstanceMethod(NSMutableArrayClass, componentsJoinedByStringSeletor); + viewDidLoadIMP = method_getImplementation(componentsJoinedByStringMethod); + [MemoryUtils hookInstanceMethod: + NSMutableArrayClass + originalSelector:componentsJoinedByStringSeletor + swizzledClass:[self class] + swizzledSelector:NSSelectorFromString(@"hook_viewDidLoad") ]; - intptr_t _remainingDaysCode = [MemoryUtils getPtrFromGlobalOffset:0 targetFunctionOffset:(uintptr_t)[remainingDaysCodeOffsets[0] unsignedIntegerValue] reduceOffset:(uintptr_t)fileOffset]; -// 000000010032a6b0 db "You have reached the limit of free rules\n(Limit at %d)", 0 -// 0x10001af90 ret 0 注册标识 -// frame #0: 0x00000001001324b0 Proxyman`___lldb_unnamed_symbol9700 -// frame #1: 0x00000001001adefb Proxyman`___lldb_unnamed_symbol12544 + 171 // call sub_1001324b0 -// frame #2: 0x00000001001ad9ef Proxyman`___lldb_unnamed_symbol12534 + 79 // call sub_1001ade50 -// frame #3: 0x0000000102fb0e6c ProxymanCore`ProxymanCore.runOnMainThread(() -> ()) -> () + 140 -// frame #4: 0x00000001001ad313 Proxyman`___lldb_unnamed_symbol12530 + 595 // thread -// frame #5: 0x0000000100054ae3 Proxyman`___lldb_unnamed_symbol4628 + 99 // call sub_1001ad0c0 cmp 01 , // 需要 ret 0 - - DobbyHook((void *)_sub_0x10001af90, ret0, nil); - - - - - NSLog(@">>>>>> Before %s",[MemoryUtils readMachineCodeStringAtAddress:_remainingDaysCode length:8].UTF8String); + + #if defined(__arm64__) || defined(__aarch64__) - - // nop:0x1F, 0x20, 0x03, 0xD5 - // mov x0,#1 - uint8_t ret1Day[4] = {0x20, 0x00, 0x80, 0xD2 }; - DobbyCodePatch((void *)_remainingDaysCode, ret1Day,4); - + NSString *patch_1Code = @"FF ?? ?? D1 FC 6F ?? A9 FA 67 ?? A9 F8 5F ?? A9 F6 57 ?? A9 F4 4F ?? A9 FD 7B ?? A9 FD ?? 03 91 F3 03 14 AA 9F 76 00 F9 00 00 80 D2 ?? ?? 0B 94 00 E4 00 6F 80 82 8B 3C 80 82 8C 3C 9F 6E 00 F9 01 04 80 52 E2 00 80 52 ?? ?? 0B 94 F4 03 00 AA ?? ?? 0B 94 F5 03 00 AA F4 03 00 AA ?? ?? 0B 94 F6 03 00 AA 00 00 80 D2 ?? ?? 0B 94 01 07 80 52 E2 00 80 52 ?? ?? 0B 94 F4 03 00 AA E0 03 16 AA ?? ?? 0B 94 ?? ?? 0B 94 F7 03 00 AA 00 00 80 D2 ?? ?? 0B 94 01 06 80 52 E2 00 80 52 ?? ?? 0B 94 F4 03 00 AA ?? ?? 0B 94 F8 03 00 AA ?? ?? 0B 94 75 4E 00 F9 76 72 00 F9 77 56 00 F9 E0 03 ?? AA ?? ?? 0B 94 E0 03 ?? AA ?? ?? 0B 94 E0 03 ?? AA"; #elif defined(__x86_64__) - //push 1,pop rax - uint8_t ret1Day[5] = {0x6A, 0x01, 0x58, 0x90, 0x90 }; - DobbyCodePatch((void *)_remainingDaysCode, ret1Day,5); + NSString *patch_1Code = @"55 48 89 E5 41 57 41 56 41 55 41 54 53 48 81 EC ?? 00 00 00 4C 89 EB 49 C7 85 E8 00 00 00 00 00 00 00 31 FF E8 ?? ?? ?? 00 0F 57 C0 41 0F 11 85 B8 00 00 00 41 0F 11 85 C8 00 00 00 49 C7 85 D8 00 00 00 00 00 00 00 BE 20 00 00 00 BA 07 00 00 00 48 89 C7 E8 ?? ?? ?? 00 49 89 C5 E8 ?? ?? ?? 00 49 89 C7 49 89 C5 E8 ?? ?? ?? 00 49 89 C4 31 FF E8 ?? ?? ?? 00 BE 38 00 00 00 BA 07 00 00 00 48 89 C7 E8 ?? ?? ?? 00 49 89 C5 4C 89 E7 E8 ?? ?? ?? 00 4C 89 E7 E8 ?? ?? ?? 00 49 89 C6 31 FF E8 ?? ?? ?? 00 BE 30 00 00 00 BA 07 00 00 00 48 89 C7 E8 ?? ?? ?? 00 49 89 C5 E8 ?? ?? ?? 00 48 89 45 D0 E8 ?? ?? ?? 00 4C 89 BB 98 00 00 00 4C 89 A3 E0 00 00 00 4C 89 75 C8"; #endif - NSLog(@">>>>>> After %s",[MemoryUtils readMachineCodeStringAtAddress:_remainingDaysCode length:8].UTF8String); - - + NSArray *patch_1Offsets =[MemoryUtils searchMachineCodeOffsets: + searchFilePath + machineCode:patch_1Code + count:(int)1 + ]; + intptr_t _patch_1 = [MemoryUtils getPtrFromGlobalOffset:0 targetFunctionOffset:(uintptr_t)[patch_1Offsets[0] unsignedIntegerValue] reduceOffset:(uintptr_t)fileOffset]; + DobbyHook((void *)_patch_1, getProxyManAppStruct, &getProxyManAppStructOriginalAddress); +// +//#if defined(__arm64__) || defined(__aarch64__) +// NSString *patch_2Code = @"55 48 89 E5 41 57 41 56 41 54 53 41 89 F4 ?? 89 ?? 48 89 D7 FF 15 ?? ?? ?? 00 ?? 89 ?? ?? 8D ?? 30 E8 ?? ?? ?? 00 49 89 C6 ?? 8B ?? 20 48 8D 3D ?? ?? ?? 00 ?? 89"; +//#elif defined(__x86_64__) +// NSString *patch_2Code = @"FF 03 01 D1 F6 57 01 A9 F4 4F 02 A9 FD 7B 03 A9 FD C3 00 91 F6 03 01 AA F5 03 00 AA E0 03 02 AA ?? ?? ?? 94 F3 03 00 AA A0 C2 00 91 ?? ?? ?? 94"; +//#endif +// NSArray *patch_2Offsets =[MemoryUtils searchMachineCodeOffsets: +// searchFilePath +// machineCode:patch_2Code +// count:(int)1 +// ]; +// intptr_t _patch_2 = [MemoryUtils getPtrFromGlobalOffset:0 targetFunctionOffset:(uintptr_t)[patch_2Offsets[0] unsignedIntegerValue] reduceOffset:(uintptr_t)fileOffset]; +// DobbyHook((void *)_patch_2, handleHelper, nil); + + + // Version 5.3.0 (50300) + // ProxymanCore.AppConfiguration.isHideExpireLicenseBadge.getter : Swift.Bool + // 如果返回 false , App StatusBar 会触发 Warning 按钮 +//#if defined(__arm64__) || defined(__aarch64__) +// NSString *patch_3Code = @"FF 83 01 D1 F8 5F 02 A9 F6 57 03 A9 F4 4F 04 A9 FD 7B 05 A9 FD 43 01 91 93 22 20 91 E1 23 00 91 E0 03 13 AA 02 00 80 D2 03 00 80 D2"; +//#elif defined(__x86_64__) +// NSString *patch_3Code = @"55 48 89 E5 41 57 41 56 41 55 41 54 53 48 83 EC 18 49 8D BD 08 08 00 00"; +//#endif +// NSArray *patch_3Offsets =[MemoryUtils searchMachineCodeOffsets: +// proxymanCoreFilePath +// machineCode:patch_3Code +// count:(int)1 +// ]; +// intptr_t _patch_3 = [MemoryUtils getPtrFromGlobalOffset:proxymanCoreIndex targetFunctionOffset:(uintptr_t)[patch_3Offsets[0] unsignedIntegerValue] reduceOffset:(uintptr_t)proxymanCoreFileOffset]; +// DobbyHook((void *)_patch_3, ret1, nil); + + + // 计算时间差 + NSDate *startTime = [NSDate date]; + // 直接 hook 导入表函数,似乎更优雅 + void* isHideExpireLicenseBadge = DobbySymbolResolver( + "/Contents/Frameworks/ProxymanCore.framework/Versions/A/ProxymanCore", "_$s12ProxymanCore16AppConfigurationC24isHideExpireLicenseBadgeSbvg" + ); + // 记录结束时间 + NSDate *endTime = [NSDate date]; + // 计算时间差 + NSTimeInterval executionTime2 = [endTime timeIntervalSinceDate:startTime]; + NSLog(@"DobbySymbolResolver Execution Time: %f seconds", executionTime2); + DobbyHook(isHideExpireLicenseBadge, ret1, nil); + +// TODO: Undefined symbol: _DobbyImportTableReplace +// DobbyImportTableReplace( +// "/Contents/Frameworks/ProxymanCore.framework/Versions/A/ProxymanCore", +// "_$s12ProxymanCore16AppConfigurationC24isHideExpireLicenseBadgeSbvg", +// (void *)ret1, +// nil +// ); return YES; } +- (BOOL)swizzled_isHideExpireLicenseBadge { + // 在这里实现您自己的逻辑,返回您期望的结果 + return YES; // 示例中返回固定的值,您需要根据您的实际需求进行逻辑处理 +} + + @end diff --git a/dylib_dobby_hook/apps/TablePlusHack.m b/dylib_dobby_hook/apps/TablePlusHack.m index f1822b6..10106e4 100644 --- a/dylib_dobby_hook/apps/TablePlusHack.m +++ b/dylib_dobby_hook/apps/TablePlusHack.m @@ -12,7 +12,7 @@ #import "encryp_utils.h" #import #include -#import "HackProtocol.h" +#import "HackProtocolDefault.h" #import "common_ret.h" @interface DummyURLSessionDataTask : NSObject @@ -28,7 +28,7 @@ - (void)resume { @end -@interface TablePlusHack : NSObject +@interface TablePlusHack : HackProtocolDefault @end diff --git a/dylib_dobby_hook/apps/TransmitHack.m b/dylib_dobby_hook/apps/TransmitHack.m index 7413437..855c818 100644 --- a/dylib_dobby_hook/apps/TransmitHack.m +++ b/dylib_dobby_hook/apps/TransmitHack.m @@ -11,10 +11,10 @@ #import "MemoryUtils.h" #import #include -#import "HackProtocol.h" #import "common_ret.h" +#import "HackProtocolDefault.h" -@interface TransmitHack : NSObject +@interface TransmitHack : HackProtocolDefault @end diff --git a/dylib_dobby_hook/helpers/ForkLiftHelperHack.m b/dylib_dobby_hook/helpers/ForkLiftHelperHack.m new file mode 100644 index 0000000..04db717 --- /dev/null +++ b/dylib_dobby_hook/helpers/ForkLiftHelperHack.m @@ -0,0 +1,128 @@ +// +// ForkLiftHelperHack.m +// dylib_dobby_hook +// +// Created by 马治武 on 2024/7/27. +// + +#import +#import "Constant.h" +#import "MemoryUtils.h" +#import +#include +#import +#import "dobby.h" +#import "HackHelperProtocolDefault.h" + + +@interface ForkLiftHelperHack : HackHelperProtocolDefault + + + +@end + + +@implementation ForkLiftHelperHack + +static IMP listenerIMP; + + +- (NSString *)getAppName { + return @"com.binarynights.ForkLiftHelper"; +} + +- (NSString *)getSupportAppVersion { + return @"4."; +} + + +//- (BOOL)hk_listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection { +// +// NSLog(@">>>>>> hk_listener"); +// +// newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol: +// NSProtocolFromString(@"_TtP31com_binarynights_ForkLiftHelper21ForkLiftHelperProtcol_") +// ]; +// newConnection.exportedObject = self; +// [newConnection resume]; +// +// return YES; +//} + + +OSStatus hk_SecCodeCopySigningInformation(SecCodeRef codeRef, SecCSFlags flags, CFDictionaryRef *signingInfo) { + + OSStatus status = SecCodeCopySigningInformation_ori(codeRef, flags, signingInfo); + NSLog(@">>>>>> hk_SecCodeCopySigningInformation_ori status = %d", status); + + CFMutableDictionaryRef fakeDict = CFDictionaryCreateMutableCopy(NULL, 0, *signingInfo); + + CFNumberRef flagsVal = CFNumberCreate(NULL, kCFNumberSInt32Type, @65536); + if (flagsVal) { + CFDictionarySetValue(fakeDict, kSecCodeInfoFlags, flagsVal); + CFRelease(flagsVal); + } + + CFStringRef teamId = CFStringCreateWithCString(NULL, "J3CP9BBBN6", kCFStringEncodingUTF8); + if (teamId) { + CFDictionarySetValue(fakeDict, kSecCodeInfoTeamIdentifier, teamId); + CFRelease(teamId); + } + + + NSDictionary *entitlementsDict = @{ + @"com.apple.security.cs.allow-dyld-environment-variables": @0, + @"com.apple.security.cs.allow-jit": @1, + @"com.apple.security.cs.allow-unsigned-executable-memory": @1, + @"com.apple.security.cs.disable-executable-page-protection": @1, + @"com.apple.security.cs.disable-library-validation": @0, + @"com.apple.security.get-task-allow": @1 + }; + CFDictionarySetValue(fakeDict, kSecCodeInfoEntitlementsDict, (__bridge const void *)(entitlementsDict)); + + CFRelease(*signingInfo); + *signingInfo = fakeDict; + + NSLog(@">>>>>> hk_SecCodeCopySigningInformation_ori kSecCodeInfoFlags = %@", (CFNumberRef)CFDictionaryGetValue(*signingInfo, kSecCodeInfoFlags)); + NSLog(@">>>>>> hk_SecCodeCopySigningInformation_ori entitlementsDict = %@", (CFDictionaryRef)CFDictionaryGetValue(*signingInfo, kSecCodeInfoEntitlementsDict)); + NSLog(@">>>>>> hk_SecCodeCopySigningInformation_ori kSecCodeInfoTeamIdentifier = %@", (CFDictionaryRef)CFDictionaryGetValue(*signingInfo, kSecCodeInfoTeamIdentifier)); + + return errSecSuccess; +} + + + +OSStatus hk_SecCodeCheckValidityWithErrors(SecCodeRef code, SecCSFlags flags,SecRequirementRef requirement, CFErrorRef *errors){ + // anchor apple generic and certificate leaf[subject.OU] = "J3CP9BBBN6" + // NSString* fakeRequirement = [NSString stringWithFormat:@"identifier \"com.binarynights.ForkLift\""]; + NSLog(@">>>>>> hk_SecCodeCheckValidityWithErrors requirement = %@",requirement); + return errSecSuccess; +} + +OSStatus (*SecCodeCopySigningInformation_ori)(SecCodeRef codeRef, SecCSFlags flags, CFDictionaryRef *signingInfo); + +OSStatus (*SecRequirementCreateWithString_forklift_ori)(CFStringRef text, SecCSFlags flags,SecRequirementRef *requirement); + +OSStatus (*SecCodeCheckValidityWithErrors_ori)(SecCodeRef code, SecCSFlags flags,SecRequirementRef requirement, CFErrorRef *errors); + + +- (BOOL)hack { + + // Class ForkLiftHelper10HelperTool = NSClassFromString(@"_TtC31com_binarynights_ForkLiftHelper10HelperTool"); + // SEL listenerSel = NSSelectorFromString(@"listener:shouldAcceptNewConnection:"); + // Method listenerMethod = class_getInstanceMethod(ForkLiftHelper10HelperTool, listenerSel); + // listenerIMP = method_getImplementation(listenerMethod); + // [MemoryUtils hookInstanceMethod:ForkLiftHelper10HelperTool + // originalSelector:listenerSel + // swizzledClass:[self class] + // swizzledSelector:@selector(hk_listener:shouldAcceptNewConnection:) + // ]; + + // DobbyHook((void *)sub_10005ad20, (void *)hook_sub_10005ad20, (void *)&sub_10005ad20_ori); + + DobbyHook(SecCodeCopySigningInformation, (void *)hk_SecCodeCopySigningInformation, (void *)&SecCodeCopySigningInformation_ori); + DobbyHook(SecCodeCheckValidityWithErrors, (void *)hk_SecCodeCheckValidityWithErrors, (void *)&SecCodeCheckValidityWithErrors_ori); + return YES; +} + +@end diff --git a/dylib_dobby_hook/helpers/HackHelperProtocolDefault.h b/dylib_dobby_hook/helpers/HackHelperProtocolDefault.h new file mode 100644 index 0000000..e0821c1 --- /dev/null +++ b/dylib_dobby_hook/helpers/HackHelperProtocolDefault.h @@ -0,0 +1,16 @@ +// +// HackProtocolDefault.h +// dylib_dobby_hook +// + +#ifndef HackHelperProtocolDefault_h +#define HackHelperProtocolDefault_h + +#import "HackProtocolDefault.h" + +@interface HackHelperProtocolDefault : HackProtocolDefault + + +@end +#endif + diff --git a/dylib_dobby_hook/helpers/HackHelperProtocolDefault.m b/dylib_dobby_hook/helpers/HackHelperProtocolDefault.m new file mode 100644 index 0000000..fb70c43 --- /dev/null +++ b/dylib_dobby_hook/helpers/HackHelperProtocolDefault.m @@ -0,0 +1,14 @@ +// +// HackCommon.m +// dylib_dobby_hook +// +// Created by 马治武 on 2024/7/27. +// + +#import +#import "HackHelperProtocolDefault.h" + +@implementation HackHelperProtocolDefault + +@end + diff --git a/dylib_dobby_hook/utils/Constant.h b/dylib_dobby_hook/utils/Constant.h index 8538314..c5ba4bb 100644 --- a/dylib_dobby_hook/utils/Constant.h +++ b/dylib_dobby_hook/utils/Constant.h @@ -18,11 +18,13 @@ @property (class, nonatomic, strong) NSString *currentAppVersion; @property (class, nonatomic, strong) NSString *currentAppCFBundleVersion; @property (class, nonatomic, assign) BOOL arm; +@property (class, nonatomic, assign) BOOL helper; + (BOOL) isFirstOpen; + (BOOL)isArm; ++ (BOOL)isHelper; + (NSString *)getCurrentAppPath; + (NSString *)getCurrentAppVersion; + (NSString *)getCurrentAppCFBundleVersion; diff --git a/dylib_dobby_hook/utils/Constant.m b/dylib_dobby_hook/utils/Constant.m index e2e3926..5e16ba2 100644 --- a/dylib_dobby_hook/utils/Constant.m +++ b/dylib_dobby_hook/utils/Constant.m @@ -10,12 +10,12 @@ #import "dobby.h" #import #import -#import "HackProtocol.h" #import #import "common_ret.h" #include #include - +#import "HackProtocolDefault.h" +#import "HackHelperProtocolDefault.h" @implementation Constant @@ -37,6 +37,7 @@ static void __attribute__ ((constructor)) initialize(void){ static NSString *currentAppVersion; static NSString *currentAppCFBundleVersion; static BOOL arm; +static BOOL helper; // 告诉编译器不生成默认的 getter 和 setter 方法 @dynamic G_EMAIL_ADDRESS; @@ -47,6 +48,7 @@ static void __attribute__ ((constructor)) initialize(void){ @dynamic currentAppVersion; @dynamic currentAppCFBundleVersion; @dynamic arm; +@dynamic helper; + (NSString *)G_EMAIL_ADDRESS { return love69(G_EMAIL_ADDRESS); @@ -58,6 +60,10 @@ + (NSString *)G_DYLIB_NAME { return G_DYLIB_NAME; } ++ (NSString *)currentAppName { + return currentAppName; +} + + (BOOL) isFirstOpen { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; // 获取当前的版本号 @@ -99,6 +105,10 @@ + (void)initialize { // 返回包的完整路径。 currentAppPath = [[app bundlePath] copy]; NSLog(@">>>>>> [app bundlePath] %@",currentAppPath); + // /Library/PrivilegedHelperTools + if ([currentAppPath isEqualToString:@"/Library/PrivilegedHelperTools"]) { + helper = YES; + } // 返回应用程序执行文件的路径。 // NSString *executablePath = [app executablePath]; @@ -109,6 +119,10 @@ + (void)initialize { } } ++ (BOOL)isHelper { + return helper; +} + + (BOOL)isArm { return arm; } @@ -156,37 +170,47 @@ + (BOOL)isDebuggerAttached { + (NSArray *)getAllHackClasses { - NSMutableArray *hackClasses = [NSMutableArray array]; + if ([self isHelper]) { + return [self getAllSubclassesOfClass:[HackHelperProtocolDefault class]]; + }else{ + return [self getAllSubclassesOfClass:[HackProtocolDefault class]]; + } - int numClasses; - Class *classes = NULL; - numClasses = objc_getClassList(NULL, 0); +} + ++ (NSArray *)getAllSubclassesOfClass:(Class)parentClass { + NSMutableArray *subclasses = [NSMutableArray array]; - if (numClasses > 0) { - classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * numClasses); - numClasses = objc_getClassList(classes, numClasses); - - for (int i = 0; i < numClasses; i++) { - Class class = classes[i]; - - if (class_conformsToProtocol(class, @protocol(HackProtocol))) { - [hackClasses addObject:class]; - } + // 获取所有已加载的类 + unsigned int numClasses = 0; + Class *classes = objc_copyClassList(&numClasses); + for (int i = 0; i < numClasses; i++) { + Class currentClass = classes[i]; + if ([self isSubclassOfClass:currentClass parentClass:parentClass] && + currentClass != parentClass) { + [subclasses addObject:currentClass]; } - free(classes); } - return hackClasses; + + free(classes); + return [subclasses copy]; } ++ (BOOL)isSubclassOfClass:(Class)class parentClass:(Class)parentClass { + while (class != nil) { + if (class == parentClass) { + return YES; + } + class = class_getSuperclass(class); + } + return NO; +} + (void)doHack { NSArray *personClasses = [Constant getAllHackClasses]; for (Class class in personClasses) { - - if ([class isEqualTo:NSObject.class]) { - continue;; - } + id it = [[class alloc] init]; if ([currentAppName hasPrefix:[it getAppName]]) { NSString *supportAppVersion = [it getSupportAppVersion]; diff --git a/dylib_dobby_hook/utils/common_ret.h b/dylib_dobby_hook/utils/common_ret.h index b962635..39ef8ac 100644 --- a/dylib_dobby_hook/utils/common_ret.h +++ b/dylib_dobby_hook/utils/common_ret.h @@ -16,7 +16,6 @@ #import "MemoryUtils.h" #import #include -#import "HackProtocol.h" #include #import #import "common_ret.h" diff --git a/dylib_dobby_hook/utils/common_ret.m b/dylib_dobby_hook/utils/common_ret.m index d58c971..0c59811 100644 --- a/dylib_dobby_hook/utils/common_ret.m +++ b/dylib_dobby_hook/utils/common_ret.m @@ -10,7 +10,6 @@ #import "Constant.h" #import "MemoryUtils.h" #include -#import "HackProtocol.h" #include #import #include diff --git a/script/apps/forklift_hack.sh b/script/apps/forklift_hack.sh new file mode 100644 index 0000000..e815994 --- /dev/null +++ b/script/apps/forklift_hack.sh @@ -0,0 +1,92 @@ +current_path=$PWD +mac_patch_helper="$current_path/../tools/mac_patch_helper" +mac_patch_helper_config="$current_path/../tools/patch.json" +SMJobBlessUtil="$current_path/../tools/SMJobBlessUtil-python3.py" + +helper_name="com.binarynights.ForkLiftHelper" +app_name="ForkLift" + +########### 注入 ########### +echo ">>>>>> helper_name is ${helper_name}" + +dylib_name="dylib_dobby_hook" +prefix="lib" +insert_dylib="${current_path}/../tools/insert_dylib" + +chmod a+x ${insert_dylib} + +BUILT_PRODUCTS_DIR="${current_path}/../release" + +app_bundle_framework="/Applications/${app_name}.app/Contents/Frameworks/" +echo ">>>>>> app_bundle_framework is ${app_bundle_framework}" + +if [ ! -d "$app_bundle_framework" ]; then + mkdir -p "$app_bundle_framework" +fi + +helper_executable_path="/Applications/${app_name}.app/Contents/Library/LaunchServices/${helper_name}" +helper_executable_backup_path="${helper_executable_path}_Backup" +echo ">>>>>> helper_executable_path is ${helper_executable_path}" + +if [ ! -f "$helper_executable_backup_path" ]; +then + cp "$helper_executable_path" "$helper_executable_backup_path" +fi + + + +echo "check insert_dylib quarantine:" +xattr "${insert_dylib}" +# sudo xattr -r -d com.apple.quarantine "${insert_dylib}" +"${insert_dylib}" --weak --all-yes "${app_bundle_framework}/${prefix}${dylib_name}.dylib" "$helper_executable_backup_path" "$helper_executable_path" +echo ">>>>>> hack [${helper_name}] completed" + + +############ 修复 ########### + +sudo chmod a+x $mac_patch_helper +$mac_patch_helper "ForkLift" $mac_patch_helper_config + +forklift_path="/Applications/ForkLift.app" +forklift_helper_path="/Applications/ForkLift.app/Contents/Library/LaunchServices/com.binarynights.ForkLiftHelper" +# codesign -dvv "/Applications/ForkLift.app/Contents/Library/LaunchServices/com.binarynights.ForkLiftHelper" + +# +echo $SUDO_USER +sudo chmod a+rwx "$forklift_helper_path" + + +sudo launchctl unload "/Library/LaunchDaemons/com.binarynights.ForkLiftHelper.plist" +sudo /usr/bin/killall -u root -9 "com.binarynights.ForkLiftHelper" +sudo /bin/rm "/Library/LaunchDaemons/com.binarynights.ForkLiftHelper.plist" +sudo /bin/rm "/Library/PrivilegedHelperTools/com.binarynights.ForkLiftHelper" +sudo rm -rf "~/Library/Preferences/com.binarynights.ForkLift.plist" +sudo rm -rf "~/Library/Application Support/com.binarynights.ForkLift" +sudo /bin/rm /Library/PrivilegedHelperTools/com.binarynights.ForkLiftHelper + +xattr -c '/Applications/ForkLift.app' + + +# Ref : https://github.com/imothee/tmpdisk/blob/291d3f83e22967b1387ae48f4c930c2c4acbb888/BuildScripts/build.sh#L29 +identifier_name="identifier \\\"$helper_name\\\"" +#ORG_UNIT="certificate leaf[subject.OU] = \"$DEVELOPMENT_TEAM\"" +#requirements_name="$GENERIC and $IDENTIFIER and $ORG_UNIT" +requirements_name="$identifier_name" +sudo /usr/libexec/PlistBuddy -c 'Print SMPrivilegedExecutables' "/Applications/ForkLift.app/Contents/Info.plist" +sudo /usr/libexec/PlistBuddy -c "Set :SMPrivilegedExecutables:$helper_name \"$requirements_name\"" "/Applications/ForkLift.app/Contents/Info.plist" +sudo /usr/libexec/PlistBuddy -c 'Print SMPrivilegedExecutables' "/Applications/ForkLift.app/Contents/Info.plist" + + +echo "codesign before" +sudo codesign -d -r- "$forklift_path" +sudo codesign -d -r- "$forklift_helper_path" + +sudo codesign -f -s - --all-architectures --deep "$forklift_path" +sudo codesign -f -s - --all-architectures --deep "$forklift_helper_path" + +echo "codesign after" +sudo codesign -d -r- "$forklift_path" +sudo codesign -d -r- "$forklift_helper_path" + + + diff --git a/script/auto_hack.sh b/script/auto_hack.sh index c395736..b587353 100644 --- a/script/auto_hack.sh +++ b/script/auto_hack.sh @@ -54,7 +54,11 @@ hack_app "Movist Pro" "/Applications/Movist Pro.app/Contents/Frameworks/MediaKey hack_app "AirBuddy" "/Applications/AirBuddy.app/Contents/Frameworks/LetsMove.framework/Versions/A/LetsMove" hack_app "Infuse" "/Applications/Infuse.app/Contents/Frameworks/Differentiator.framework/Versions/A/Differentiator" hack_app "MacUpdater" "/Applications/MacUpdater.app/Contents/Frameworks/Sparkle.framework/Versions/B/Sparkle" -hack_app "ForkLift" "/Applications/ForkLift.app/Contents/Frameworks/UniversalDetector.framework/Versions/A/UniversalDetector" +hack_app "CleanShot X" "/Applications/CleanShot X.app/Contents/Frameworks/LetsMove.framework/Versions/A/LetsMove" +# fixed with helper +hack_app "ForkLift" "/Applications/ForkLift.app/Contents/Frameworks/UniversalDetector.framework/Versions/A/UniversalDetector" "apps/forklift_hack.sh" +hack_app "Surge" "/Applications/Surge.app/Contents/Frameworks/MMMarkdown.framework/Versions/A/MMMarkdown" "apps/surge_hack.sh" + diff --git a/script/lightroom_hack.sh b/script/lightroom_hack.sh deleted file mode 100644 index 4090328..0000000 --- a/script/lightroom_hack.sh +++ /dev/null @@ -1,40 +0,0 @@ -current_path=$PWD -echo "当前路径:$current_path" - -app_name="Adobe Lightroom" - -dylib_name="dylib_dobby_hook" -prefix="lib" -insert_dylib="${current_path}/../tools/insert_dylib" - -BUILT_PRODUCTS_DIR="${current_path}/../release" -# lightroom路径多一个AdobeLightroomCC -app_bundle_path="/Applications/Adobe Lightroom CC/${app_name}.app/Contents/MacOS" -app_bundle_framework="/Applications/Adobe Lightroom CC/${app_name}.app/Contents/Frameworks/" - -if [ ! -d "$app_bundle_framework" ]; then - mkdir -p "$app_bundle_framework" -fi - -if [ -n "$inject_bin" ]; then - app_executable_path="$inject_bin" -else - app_executable_path="${app_bundle_path}/${app_name}" -fi -app_executable_backup_path="${app_executable_path}_Backup" - - -cp -f "${insert_dylib}" "${app_bundle_path}/" -if [ ! -f "$app_executable_backup_path" ]; -then - cp "$app_executable_path" "$app_executable_backup_path" -fi - - - -cp -f "${BUILT_PRODUCTS_DIR}/${prefix}${dylib_name}.dylib" "${app_bundle_framework}" - -"${app_bundle_path}/insert_dylib" --weak --all-yes "@rpath/${prefix}${dylib_name}.dylib" "$app_executable_backup_path" "$app_executable_path" - - - diff --git a/tools/mac_patch_helper b/tools/mac_patch_helper index 98c0d70f265b3973b15f4aab63532c51834e1283..863bb11b15eceb5d1a69f482f31f9a32f6e2df79 100755 GIT binary patch literal 70128 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

^Bwi;EFN@ESp6WtWrPw;JWMMY*qiFo*mRIS?$~ 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 literal 61216 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 T2T~qLc_8J1ln4I%Jn;VjnPk#( diff --git a/tools/patch.json b/tools/patch.json index 6ac3a66..68c2a7b 100644 --- a/tools/patch.json +++ b/tools/patch.json @@ -15,14 +15,14 @@ ] }, "ForkLift":{ - "TODO// patch":{ - "/Applications/ForkLift.app/Contents/Library/LaunchServices/com.binarynights.ForkLiftHelper":{ - - } - }, "clear_certificate":[ "/Applications/ForkLift.app/Contents/Library/LaunchServices/com.binarynights.ForkLiftHelper" ] + }, + "SMJobBlessApp":{ + "clear_certificate":[ + "/Applications/SMJobBlessApp.app/Contents/Library/LaunchServices/com.apple.bsd.SMJobBlessHelper" + ] } }