리버스 엔지니어링 프로젝트를 생성할 때 프로젝트를 더욱 편리하게 사용하고 확장하기 쉽게 만드는 방법과 컴파일러 식별은 일상적인 개발 효율성과 코드 품질을 크게 향상시킬 수 있습니다. 이 글에서는 주로 Theos의 Tweak 프로젝트를 사용하여 Xcode 컴파일러에서 인식할 수 있는 프로젝트를 만드는 방법과 프로젝트에서 일반적으로 사용되는 구성을 설명합니다.
https://www.onezen.cc/2017/09/16/iosrevert/revdevconfig.html
환경을 설정한 후 해당 Tweak 프로젝트를 생성합니다.
앞서 생성한 Tweak 프로젝트의 이름을 기반으로 Xcode 정적 라이브러리 프로젝트를 생성한 다음, Tweak과 생성된 Xcode 프로젝트를 함께 혼합합니다.
Xcode 프로젝트에 Config 폴더(폴더 없는 새 그룹)를 생성하고 Makefile, 해당 plist 파일 및 제어 구성 파일을 복사하지 않고 이 디렉터리에 배치합니다. 그런 다음 Xcode에서 해당 폴더를 생성한 다음 생성된 .xm
파일의 모든 접미사를 .xmi
로 바꾸고 이를 프로젝트의 가장 바깥쪽 레이어에 유일한 항목 클래스로 배치합니다.
유형을 Objective-C++
로 인식하도록 Xcode 컴파일러에서 Tweak.xmi를 설정하십시오.
컴파일러가 로고 구문을 인식할 수 있도록 XcodeTheos 헤더 파일을 설정합니다. 해당 헤더 파일의 주소: https://github.com/onezens/Xcode-Theos 프로젝트를 가져온 후 전역 헤더 파일을 생성하고 헤더를 넣습니다. tweak.xmi
파일에서 내부 코드가 검은색이어서 컴파일러에서 인식되지 않는 것을 발견했습니다. 이때 프로젝트를 닫았다가 다시 열면 Xcode에서 다시 인식된다는 것을 발견했습니다.
그런 다음 Xcode가 로고 매크로를 인식할 수 있도록 XcodeTheos
매크로를 설정합니다.
함께 설정한 후 로고 후크 코드 작성을 시작합니다. 모든 것이 정상이면 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
include는 .a 및 .dylib 라이브러리의 모든 헤더 파일을 배치합니다. 동적 라이브러리는 모든 정적 라이브러리 폴더를 용이하게 하기 위해 함께 배치됩니다.
프로젝트에 동적 라이브러리를 추가했을 때 트윅 플러그인 실행이 호스트 APP에서 작동하지 않는 것을 발견했습니다. 로그 프롬프트 정보는 다음과 같습니다.
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)
우리는 Tweak 프로젝트의 동적 라이브러리가 호스트의 번들 경로인 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
자식 주소: https://github.com/onezens/WeChatBot