เมื่อสร้างโครงการวิศวกรรมย้อนกลับ วิธีทำให้โครงการสะดวกในการใช้งานและขยายได้ง่ายขึ้น รวมถึงการระบุคอมไพลเลอร์ สามารถปรับปรุงประสิทธิภาพการพัฒนารายวันและคุณภาพโค้ดของเราได้อย่างมาก บทความนี้ส่วนใหญ่จะอธิบายวิธีใช้โปรเจ็กต์ปรับแต่งของ Theos เพื่อสร้างโปรเจ็กต์ที่คอมไพเลอร์ Xcode รู้จัก รวมถึงการกำหนดค่าที่ใช้ทั่วไปในโปรเจ็กต์
https://www.onezen.cc/2017/09/16/iosrevert/revdevconfig.html
หลังจากตั้งค่าสภาพแวดล้อมแล้ว ให้สร้างโปรเจ็กต์ปรับแต่งที่เกี่ยวข้อง
สร้างโปรเจ็กต์ไลบรารีแบบคงที่ Xcode ตามชื่อของโปรเจ็กต์ปรับแต่งที่สร้างขึ้นก่อนหน้านี้ จากนั้นผสมการปรับแต่งและโปรเจ็กต์ Xcode ที่สร้างขึ้นเข้าด้วยกัน
สร้างโฟลเดอร์ Config (กลุ่มใหม่ที่ไม่มีโฟลเดอร์) ในโปรเจ็กต์ Xcode และวาง Makefile ไฟล์ plist ที่เกี่ยวข้อง และไฟล์การกำหนดค่าควบคุมในไดเร็กทอรีนี้โดยไม่ต้องคัดลอก จากนั้นสร้างโฟลเดอร์ที่เกี่ยวข้องใน Xcode จากนั้นแทนที่ส่วนต่อท้ายทั้งหมดของไฟล์ .xm
ที่สร้างขึ้นด้วย .xmi
และวางไว้ในเลเยอร์นอกสุดของโปรเจ็กต์เป็นคลาสรายการเดียวเท่านั้น
ตั้งค่า Tweak.xmi ในคอมไพเลอร์ Xcode เพื่อจดจำประเภทเป็น Objective-C++
ตั้งค่าไฟล์ส่วนหัวของ XcodeTheos เพื่อให้คอมไพเลอร์จดจำไวยากรณ์ของโลโก้ได้ ที่อยู่ของไฟล์ส่วนหัวที่เกี่ยวข้อง: https://github.com/onezens/Xcode-Theos หลังจากนำเข้าโปรเจ็กต์แล้ว ให้สร้างไฟล์ส่วนหัวส่วนกลางและใส่ส่วนหัว ใน tweak.xmi
ฉันพบว่าโค้ดข้างในเป็นสีดำและคอมไพเลอร์ไม่รู้จัก ในเวลานี้ หลังจากปิดโปรเจ็กต์และเปิดใหม่อีกครั้ง ฉันพบว่า Xcode จะได้รับการยอมรับอีกครั้ง
จากนั้นตั้งค่ามาโคร XcodeTheos
เพื่อให้ Xcode รู้จักมาโครโลโก้
หลังจากตั้งค่าร่วมกันแล้ว ให้เริ่มเขียนโค้ด hook ของโลโก้ หากทุกอย่างเป็นปกติ คุณจะพบว่าการเขียนโค้ดโลโก้ใน Xcode นั้นราบรื่นมาก และคอมไพเลอร์ Xcode จะแจ้งให้คุณดำเนินการสำเร็จ
ขั้นแรกให้แก้ไขไฟล์คอมไพล์ของ Makefile เมื่อสร้างไฟล์ที่มีไวยากรณ์โลโก้ที่เกี่ยวข้องในอนาคต ให้ตั้งชื่อไฟล์เป็นไฟล์ xmi เสมอและเขียนลงใน Makefile
WeChatBot_FILES = Tweak.xm
=> 修改为:
WeChatBot_FILES = Tweak.xmi
มีปัญหากับเส้นทางการอ้างอิงไฟล์ส่วนหัวในโครงการ ทำให้การคอมไพล์ล้มเหลว
➜ 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
พบว่าเป็นไฟล์ส่วนหัว เหตุผลในการแนะนำคือการตั้งค่าไดเร็กทอรีไฟล์ส่วนหัวใน Makefile
#头文件
WeChatBot_OBJCFLAGS += -I./WeChatBot/Headers/wechatHeaders/
WeChatBot_OBJCFLAGS += -I./WeChatBot/Headers/
หากคุณใช้ theos เวอร์ชันล่าสุด เราจะพบว่าการคอมไพล์ไฟล์ .xmi
จะมีข้อผิดพลาดดังต่อไปนี้
➜ 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
สารละลาย:
.xmi
ทั้งหมดเป็นไฟล์ .xi
และนำเข้าไฟล์ส่วนหัว #include <substrate.h>
https://github.com/onezens/theos.git
เพื่อแทนที่เวอร์ชันดั้งเดิมสำหรับการรวบรวมแก้ไขปัญหาการคอมไพล์คำเตือนและรายงานข้อผิดพลาด
➜ 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
สารละลาย:
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
รวมวางไฟล์ส่วนหัวทั้งหมดของไลบรารี .a และ .dylib ไดนามิกวางโฟลเดอร์ไลบรารีแบบไดนามิกทั้งหมดไว้ด้วยกันเพื่ออำนวยความสะดวกในการประมวลผลสคริปต์แบบคงที่ป้องกันโฟลเดอร์ไลบรารีแบบคงที่ทั้งหมด
เมื่อเราเพิ่มไลบรารีไดนามิกลงในโปรเจ็กต์ เราพบว่าการเรียกใช้ปลั๊กอินปรับแต่งไม่ทำงานในแอปโฮสต์ ข้อมูลพรอมต์บันทึกคือ:
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
จากข้อมูลบันทึกจะเห็นได้ว่าโฮสต์อยู่ในบันเดิลของตัวเองและไม่ได้โหลดลงในไดนามิกไลบรารีของเรา ดังนั้นฟังก์ชันของปลั๊กอินทั้งหมดของเราจึงไม่มีผล
ดูไลบรารีแบบไดนามิกที่สร้างขึ้น:
➜ 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)
เราพบว่าไลบรารีไดนามิกของโปรเจ็กต์ปรับแต่งนั้นขึ้นอยู่กับ rpath ซึ่งเป็นเส้นทางบันเดิลของโฮสต์ ดังนั้นเราจึงจำเป็นต้องเปลี่ยนเส้นทางนี้
วิธีแก้ไขคือเปลี่ยนเส้นทางการพึ่งพาไลบรารีแบบไดนามิกผ่านสคริปต์:
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
ก่อนแต่ละแพ็คเกจ ให้รันสคริปต์นี้และดูข้อมูลหลังจากแพ็คเกจเสร็จสมบูรณ์:
➜ 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)
ลดความซับซ้อนของคำสั่งที่ใช้กันทั่วไปและปรับปรุงประสิทธิภาพการพัฒนารายวัน
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
สคริปต์ postinst คือสคริปต์ที่ดำเนินการก่อนการติดตั้งแพ็กเกจ deb แต่ละครั้ง สคริปต์ postrm คือสคริปต์ที่ดำเนินการหลังจากการติดตั้งแพ็กเกจ deb แต่ละครั้งเสร็จสิ้น
หมายเหตุ: คุณต้องแก้ไขสิทธิ์ในการดำเนินการของทั้งสองก่อนบรรจุภัณฑ์
chmod 755 .theos/_/DEBIAN/postinst
chmod 755 .theos/_/DEBIAN/postrm
คำอธิบายสคริปต์ที่เกี่ยวข้อง: http://iphonedevwiki.net/index.php/Packaging
สถานการณ์การใช้งาน: ติดตั้งปลั๊กอินใน Cydia และแสดงสคริปต์ postrm ของปุ่มย้อนกลับ & ลบการพึ่งพาการควบคุม:
#!/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
คำอธิบายพารามิเตอร์:
Acceptable parameters for finish
# return - normal behaviour (return to cydia)
# reopen - exit cydia
# restart - reload springboard
# reload - reload springboard
# reboot - reboot device
แมปไฟล์กับอุปกรณ์เคลื่อนที่ผ่านไดเร็กทอรีโครงร่างในไดเร็กทอรีรากของโปรเจ็กต์ จากนั้นอ่านไฟล์ทรัพยากร
#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: https://github.com/onezens/WeChatBot