Wenn Sie beim Erstellen eines Reverse-Engineering-Projekts das Projekt benutzerfreundlicher und einfacher zu erweitern gestalten und den Compiler identifizieren, können Sie unsere tägliche Entwicklungseffizienz und Codequalität erheblich verbessern. In diesem Artikel wird hauptsächlich beschrieben, wie Sie mit dem Tweak-Projekt von Theos ein Projekt erstellen, das vom Xcode-Compiler erkannt werden kann, sowie die häufig verwendeten Konfigurationen im Projekt.
https://www.onezen.cc/2017/09/16/iosrevert/revdevconfig.html
Erstellen Sie nach dem Einrichten der Umgebung das entsprechende Tweak-Projekt
Erstellen Sie ein statisches Xcode-Bibliotheksprojekt basierend auf dem Namen des zuvor erstellten Tweak-Projekts und mischen Sie dann den Tweak und das erstellte Xcode-Projekt zusammen.
Erstellen Sie im Xcode-Projekt einen Konfigurationsordner (Neue Gruppe ohne Ordner) und platzieren Sie das Makefile, die entsprechende Plist-Datei und die Steuerungskonfigurationsdatei ohne Kopieren in diesem Verzeichnis. Erstellen Sie dann den entsprechenden Ordner in Xcode, ersetzen Sie alle Suffixe der generierten .xm
Dateien durch .xmi
und fügen Sie sie als einzige Eintragsklasse in die äußerste Ebene des Projekts ein
Stellen Sie Tweak.xmi im Xcode-Compiler so ein, dass der Typ als Objective-C++
erkannt wird
Legen Sie die XcodeTheos-Header-Datei fest, damit der Compiler die Logos-Syntax erkennen kann: https://github.com/onezens/Xcode-Theos. Erstellen Sie nach dem Importieren des Projekts eine globale Header-Datei und platzieren Sie den Header Datei in tweak.xmi
Ich habe festgestellt, dass der darin enthaltene Code schwarz war und vom Compiler nicht erkannt wurde. Zu diesem Zeitpunkt stellte ich nach dem Schließen und erneuten Öffnen des Projekts fest, dass er von Xcode erneut erkannt wurde.
Legen Sie dann das XcodeTheos
Makro fest, damit Xcode das Logos-Makro erkennt.
Nachdem Sie es zusammen eingerichtet haben, beginnen Sie mit dem Schreiben des Logos-Hook-Codes. Wenn alles normal ist, werden Sie feststellen, dass das Schreiben des Logos-Codes in Xcode super reibungslos verläuft und der Xcode-Compiler Sie auffordert, es erfolgreich durchzuführen.
Ändern Sie zunächst die Kompilierungsdatei von Makefile Wenn Sie in Zukunft eine Datei mit der entsprechenden Logos-Syntax erstellen, benennen Sie diese immer als xmi-Datei und schreiben Sie sie in das Makefile.
WeChatBot_FILES = Tweak.xm
=> 修改为:
WeChatBot_FILES = Tweak.xmi
Es liegt ein Problem mit dem Referenzpfad der Header-Datei im Projekt vor, was dazu führt, dass die Kompilierung fehlschlägt.
➜ WeChatBot git:(master) ✗ make
> Making all for tweak WeChatBot…
==> Preprocessing Tweak.xmi…
Tweak.xmi:2:9: fatal error: 'wechatbot-prefix-header.h' file not found
#import "wechatbot-prefix-header.h"
^~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
make[3]: *** [/Users/wz/Documents/GitHub/WeChatBot/.theos/obj/debug/armv7/Tweak.mii] Error 1
make[2]: *** [/Users/wz/Documents/GitHub/WeChatBot/.theos/obj/debug/armv7/WeChatBot.dylib] Error 2
make[1]: *** [internal-library-all_] Error 2
make: *** [WeChatBot.all.tweak.variables] Error 2
Es wurde festgestellt, dass es sich um eine Header-Datei handelte. Der Grund für die Einführung bestand darin, das Header-Dateiverzeichnis im Makefile festzulegen.
#头文件
WeChatBot_OBJCFLAGS += -I./WeChatBot/Headers/wechatHeaders/
WeChatBot_OBJCFLAGS += -I./WeChatBot/Headers/
Wenn Sie die neueste Version von theos verwenden, werden wir feststellen, dass beim Kompilieren der .xmi
Datei der folgende Fehler auftritt
➜ WeChatBot git:(master) ✗ make
> Making all for tweak WeChatBot…
==> Preprocessing Tweak.xmi…
==> Compiling Tweak.xmi (arm64)…
Tweak.xmi:18:104: error: use of undeclared identifier 'MSHookMessageEx'
{Class _logos_class$_ungrouped$MicroMessengerAppDelegate = objc_getClass("MicroMessengerAppDelegate"); MSHookMessageEx(_logos_class$_ungro...
^
1 error generated.
make[3]: *** [/Users/wz/Documents/GitHub/WeChatBot/.theos/obj/debug/arm64/Tweak.xmi.ca6fefe9.o] Error 1
make[2]: *** [/Users/wz/Documents/GitHub/WeChatBot/.theos/obj/debug/arm64/WeChatBot.dylib] Error 2
make[1]: *** [internal-library-all_] Error 2
make: *** [WeChatBot.all.tweak.variables] Error 2
Lösung:
.xmi
in .xi
-Dateien und importieren Sie die Header-Datei #include <substrate.h>
https://github.com/onezens/theos.git
um die Originalversion für die Kompilierung zu ersetzenLösen Sie das Problem von Kompilierungswarnungen und Fehlerberichten
➜ WeChatBot git:(master) ✗ make
> Making all for tweak WeChatBot…
==> Preprocessing Tweak.xmi…
==> Compiling Tweak.xmi (arm64)…
Tweak.xmi:8:4: error: 'UIAlertView' is deprecated: first deprecated in iOS 9.0 - UIAlertView is deprecated. Use UIAlertController with a preferredStyle
of UIAlertControllerStyleAlert instead [-Werror,-Wdeprecated-declarations]
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Works for hook" message:__null delegate:__null cancelButtonTitle:@"cancel" otherBu...
^
/opt/theos/sdks/iPhoneOS11.2.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAlertView.h:26:12: note: 'UIAlertView' has been explicitly marked
deprecated here
@interface UIAlertView : UIView
^
Tweak.xmi:8:27: error: 'UIAlertView' is deprecated: first deprecated in iOS 9.0 - UIAlertView is deprecated. Use UIAlertController with a
preferredStyle of UIAlertControllerStyleAlert instead [-Werror,-Wdeprecated-declarations]
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Works for hook" message:__null delegate:__null cancelButtonTitle:@"cancel" otherBu...
^
/opt/theos/sdks/iPhoneOS11.2.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIAlertView.h:26:12: note: 'UIAlertView' has been explicitly marked
deprecated here
@interface UIAlertView : UIView
^
2 errors generated.
make[3]: *** [/Users/wz/Documents/GitHub/WeChatBot/.theos/obj/debug/arm64/Tweak.xmi.6c3ff448.o] Error 1
make[2]: *** [/Users/wz/Documents/GitHub/WeChatBot/.theos/obj/debug/arm64/WeChatBot.dylib] Error 2
make[1]: *** [internal-library-all_] Error 2
make: *** [WeChatBot.all.tweak.variables] Error 2
Lösung:
TARGET = iphone:11.2:7.0
#忽略OC警告
WeChatBot_OBJCFLAGS += -Wno-deprecated-declarations
#导入系统的frameworks
WeChatBot_FRAMEWORKS = Foundation UIKit
#导入系统库
WeChatBot_LIBRARIES = stdc++ c++
#导入第三方Frameworks, 动态库需特殊处理
WeChatBot_LDFLAGS += -F./Libraries/dynamic -F./Libraries/static # 识别的库实现
WeChatBot_CFLAGS += -F./Libraries/dynamic -F./Libraries/static # 头文件识别
WeChatBot_FRAMEWORKS += WCBFWStatic WCBFWDynamic
#导入第三方lib
WeChatBot_LDFLAGS += -L./Libraries/dynamic -L./Libraries/static # 识别的库实现
WeChatBot_CFLAGS += -I./Libraries/include # 头文件识别
WeChatBot_LIBRARIES += WCBStatic WCBDyLib
include platziert alle Header-Dateien der .a- und .dylib-Bibliotheken. Die dynamischen Bibliotheken werden zusammengestellt, um die Skriptverarbeitung zu erleichtern.
Als wir die dynamische Bibliothek zum Projekt hinzufügten, stellten wir fest, dass die Ausführung unseres Tweak-Plug-Ins in der Host-APP nicht funktionierte. Die Informationen zur Protokollaufforderung lauteten:
Apr 9 15:55:28 wz5 WeChat[5329] <Error>: MS:Error: dlopen(/Library/MobileSubstrate/DynamicLibraries/WeChatBot.dylib, 9): Library not loaded: @rpath/WCBFWDynamic.framework/WCBFWDynamic
Referenced from: /Library/MobileSubstrate/DynamicLibraries/WeChatBot.dylib
Reason: image not found
Aus den Protokollinformationen ist ersichtlich, dass sich der Host in einem eigenen Bundle befindet und nicht in unsere dynamische Bibliothek geladen wird, sodass die Funktion unseres gesamten Plug-Ins nicht wirksam wird.
Sehen Sie sich die generierte dynamische Bibliothek an:
➜ WeChatBot git:(master) ✗ otool -L .theos/_/Library/MobileSubstrate/DynamicLibraries/WeChatBot.dylib
.theos/_/Library/MobileSubstrate/DynamicLibraries/WeChatBot.dylib:
/Library/MobileSubstrate/DynamicLibraries/WeChatBot.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1450.14.0)
/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 1450.14.0)
/System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 3698.33.6)
@rpath/WCBFWDynamic.framework/WCBFWDynamic (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.1)
@rpath/libWCBDyLib.dylib (compatibility version 0.0.0, current version 0.0.0)
/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)
Wir haben festgestellt, dass die dynamische Bibliothek des Tweak-Projekts von rpath abhängt, dem Bundle-Pfad des Hosts, daher müssen wir diesen Pfad ändern.
Die Lösung besteht darin, den Abhängigkeitspfad der dynamischen Bibliothek über ein Skript zu ändern:
TWEAK_NAME=WeChatBot
cydiaLibPath=/Library/MobileSubstrate/DynamicLibraries/$TWEAK_NAME
dylibPath=Libraries/dynamic
oriDylibPath=$dylibPath/ori
tweakLayoutPath=layout$cydiaLibPath
echo $tweakLayoutPath
if [[ ! -d $oriDylibPath ]]; then
mkdir $oriDylibPath
fi
if [[ ! -d $tweakLayoutPath ]]; then
mkdir $tweakLayoutPath
fi
checkDylibID() {
path=$1
libFullPath=$2
ckLibId=$(otool -L $path | grep rpath)
if [[ -n $ckLibId ]]; then
cp -r $libFullPath $oriDylibPath
ckLibId=${ckLibId%' ('*}
ckLibId=${ckLibId#*/}
install_name_tool -id $cydiaLibPath/$ckLibId $path
otool -L $path
fi
cp -r $libFullPath $tweakLayoutPath
}
for file in $dylibPath/*; do
if [[ $file =~ ".dylib" ]]; then
checkDylibID $file $file
elif [[ $file =~ ".framework" ]]; then
name=${file##*/}
name=${name%.*}
checkDylibID $file/$name $file
fi
done
Führen Sie vor jedem Paket dieses Skript aus und sehen Sie sich die Informationen an, nachdem das Paket abgeschlossen ist:
➜ WeChatBot git:(master) ✗ otool -L .theos/_/Library/MobileSubstrate/DynamicLibraries/WeChatBot.dylib
.theos/_/Library/MobileSubstrate/DynamicLibraries/WeChatBot.dylib:
/Library/MobileSubstrate/DynamicLibraries/WeChatBot.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
/System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1450.14.0)
/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 1450.14.0)
/System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 3698.33.6)
/Library/MobileSubstrate/DynamicLibraries/WeChatBot/WCBFWDynamic.framework/WCBFWDynamic (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.1)
/Library/MobileSubstrate/DynamicLibraries/WeChatBot/libWCBDyLib.dylib (compatibility version 0.0.0, current version 0.0.0)
/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)
Vereinfachen Sie häufig verwendete Befehle und verbessern Sie die tägliche Entwicklungseffizienz
before-package::
sh bin/check_dynamic_lib.sh #动态库处理脚本
cp ./bin/postinst .theos/_/DEBIAN/
cp ./bin/postrm .theos/_/DEBIAN/
chmod 755 .theos/_/DEBIAN/postinst
chmod 755 .theos/_/DEBIAN/postrm
after-install::
install.exec "killall -9 SpringBoard"
p::
make package
c::
make clean
i::
make
make p
make install
Das Postinst-Skript ist ein Skript, das vor jeder Deb-Paketinstallation ausgeführt wird. Das Postrm-Skript ist ein Skript, das nach Abschluss jeder Deb-Paketinstallation ausgeführt wird.
Hinweis: Sie müssen die Ausführungsberechtigungen dieser beiden vor dem Packen ändern.
chmod 755 .theos/_/DEBIAN/postinst
chmod 755 .theos/_/DEBIAN/postrm
Zugehörige Skriptbeschreibung: http://iphonedevwiki.net/index.php/Packaging
Anwendungsszenario: Installieren Sie das Plug-In in Cydia, zeigen Sie das PostRM-Skript für die Zurück-Schaltfläche an und löschen Sie die Steuerabhängigkeit:
#!/bin/bash
declare -a cydia
cydia=($CYDIA)
if [[ ${CYDIA+@} ]]; then
eval "echo 'finish:open' >&${cydia[0]}"
else
echo "uninstall wk completed!"
echo ""
fi
killall -9 WeChat
exit 0
Parameterbeschreibung:
Acceptable parameters for finish
# return - normal behaviour (return to cydia)
# reopen - exit cydia
# restart - reload springboard
# reload - reload springboard
# reboot - reboot device
Ordnen Sie die Datei über das Layoutverzeichnis im Projektstammverzeichnis dem mobilen Gerät zu und lesen Sie dann die Ressourcendatei
#define kWCBImgSrcPath @"/Library/AppSupport/WeChatBot/imgs"
UIImage *img = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/wcb_icon.png", kWCBImgSrcPath]];
NSLog(@"[WeChatBot] img: %@", img);
UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
[imgView sizeToFit];
imgView.center = CGPointMake(46, 60);
[self.window addSubview:imgView];
#用于编译的SDK和支持的ios最低版本
TARGET = iphone:11.2:9.0
#用于调试的设备地址
THEOS_DEVICE_IP = localhost
THEOS_DEVICE_PORT = 2222
# 打包命名不一样,正式包不会输出log等
DEBUG = 1
# 采用ARC内存管理
WeChatBot_CFLAGS = -fobjc-arc
#忽略OC警告,避免警告导致编译不过
WeChatBot_OBJCFLAGS += -Wno-deprecated-declarations -Wno-unused-variable
Package: cc.onezen.wechatbot #包名
Name: WeChatBot
Depends: mobilesubstrate #依赖库和依赖插件,如果需要插件在cydia安装后不重启springboard可以删掉,否则每次重新
Version: 0.0.1
Architecture: iphoneos-arm
Description: An awesome MobileSubstrate tweak!
Maintainer: wz
Author: wz
Section: Tweaks #cydia源中的分类
Icon: file:///Library/AppSupport/WeChatBot/imgs/wcb_icon.png #icon
Git-Adresse: https://github.com/onezens/WeChatBot