老铁们,大家好,相信还有很多朋友对于深入iOS逆向分析(第三部分)和的相关问题不太懂,没关系,今天就由我来为大家分享分享深入iOS逆向分析(第三部分)以及的问题,文章篇幅可能偏长,希望可以帮助到大家,下面一起来看看吧!
iOS /opt/theos/bin/nic.pl
NIC 2.0 - 新实例创建器
----------------------------------
[1.] iPhone/activator_event
[2.] iPhone/application_modern
[3.] iPhone/Cydget
[4.] iPhone/flipswitch_switch
[5.] iPhone/框架
[6.]iphone/ios7_notification_center_widget
[7.] iPhone/图书馆
[8.] iPhone/notification_center_widget
[9.] iPhone/preference_bundle_modern
[10.] iPhone/工具
[11.] iPhone/调整
[12.]iphone/xpc_service
//选择调整项目
选择模板(必填): 11
//项目名称
项目名称(必填): MyFirstReProject
//deb包的名称(类似于bundle标识符)
包名称[com.yourcompany.myfirstreproject]: com.iosre.myfirstreproject
//调整作者
作者/维护者姓名[系统管理员]: Flonger
//调整对象的包标识符
[iphone/tweak] MobileSubstrate Bundle 过滤器[com.apple.springboard]: com.apple.springboard
//调整安装完成后需要重启的应用程序
[iphone/tweak] 安装时要终止的应用程序列表(以空格分隔,“-”表示无)[SpringBoard]: SpringBoard
在myfirstreproject/中实例化iphone/tweak.
完毕。项目文件结构简介
生成文件
//项目中包含的常用头文件
包括$(THEOS)/makefiles/common.mk
//创建项目时指定的“项目名称”。指定后一般不要更改。
TWEAK_NAME=MyFirstReProject
//tweak包含的源文件,指定多个文件时用空格分隔
MyFirstReProject_FILES=Tweak.xm
//tweak项目的头文件一般包括application.mk、tweak.mk和tool.mk。
包括$(THEOS_MAKE_PATH)/tweak.mk
//指定安装调整后需要做什么。这里就是杀死SpringBoard进程。
安装后:
install.exec "killall -9 SpringBoard"
补充:
//编译调试或发布
调试=0
//越狱后的iPhone的IP地址
THEOS_DEVICE_IP=192.168.1.113
//指定支持的处理器架构
ARCHS=ARMv7 ARM64
//指定需要的SDK版本iphone:Base SDK:Deployment Target
TARGET=iphone:latest:8.0 //最新的SDK,程序在iOS8.0以上版本发布
//导入帧,多个帧之间用空格分隔
MyFirstReProject_FRAMEWORKS=UIKit
MyFirstReProject_PRIVATE_FRAMEWORKS=应用程序支持
//链接libsqlite3.0.dylib、libz.dylib和dylib1.o
MyFirstReProject_LDFLAGS=-lz lsqlite3.0 dylib1.o
//清理干净
清洁:
rm -rf ./packages/*调整文件
“xm”中的“x”表示该文件支持Logos语法。如果后缀名是单个“x”,则表示源文件支持Logos和C语法;如果后缀名是“xm”
,表示源文件支持Logos和C/C++语法。
/* 如何与徽标挂钩
钩子的编写语法与Objective-C @implementation 类似。
你不需要#include,它会自动完成,就像
类列表和自动构造函数的生成。
%hook类名
//挂钩类方法
+ (id)sharedInstance {
返回原始;
}
//使用参数挂钩实例方法。
- (void)messageName:(int)参数{
日志; //将有关此调用的消息(包括其类、名称和参数)写入系统日志。
%原始; //使用原始参数调用原始函数。
原始(零); //使用自定义参数调用原始函数。
//如果您使用%orig(),则必须提供所有参数(除了self 和_cmd,自动生成的参数。)
}
//挂钩一个不带参数的实例方法。
- (id)noArguments {
日志;
id 很棒=%orig;
[很棒的做其他事情];
回归真棒;
}
//一定要确保自己清理干净;不这样做可能会造成严重后果!
结尾
*/%hook指定需要hook的类,必须以%end结尾
%log 该命令在%hook内部使用,将函数的类名、参数等信息写入到syslog中。
在Cydia 中搜索并安装syslogd
%orig 指令由%hook 在内部使用来执行挂钩函数的原始代码。
控制
控制文件记录了deb包管理系统所需的基本信息,并将被打包到deb包中。
编译工程
调整xm文件
%hook跳板
- (void)applicationDidFinishLaunching:(id)application
{
%原始;
UIAlertView *alert=[[UIAlertView 分配]
initWithTitle:@"你好,坦洲!"
message:nil
delegate:self cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[警报显示];
}
- (void)_menuButtonDown:(id)向下
{
NSLog(@"x=%d, y=%d", 10, 20);
%log((NSString *)@"iOSRE", (NSString *)@"调试");
%原始; //调用原来的_menuButtonDown:
}
结尾
%hook SBLockScreenDateViewController
- (void)setCustomSubtitleText:(id)arg1 和Color:(id)arg2
{
/*
NSDate *date=[NSDate 日期];
NSDateFormatter *format1=[[NSDateFormatter alloc]init];
[format1 setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
NSString *str1=[format1 stringFromDate:date];
*/
结构tm *loctime;
字符timeBuf[1024]={0};
现在time_t=时间(NULL);
loctime=当地时间(现在);
strftime(timeBuf, 30, "[%Y/%m/%d %H:%M:%S]", loctime);
%orig([NSString stringWithUTF8String:timeBuf],arg2);
}
%endMakeFile 文件
调试=0
THEOS_DEVICE_IP=10.171.4.22
ARCHS=ARMv7 ARM64
目标=iphone:latest:8.0
包括$(THEOS)/makefiles/common.mk
TWEAK_NAME=MyFirstReProject
MyFirstReProject_FILES=Tweak.xm
MyFirstReProject_FRAMEWORKS=UIKit
包括$(THEOS_MAKE_PATH)/tweak.mk
安装后:
install.exec "killall -9 SpringBoard"
清洁:
rm -rf ./packages/*控制文件
Package: com.iosre.myfirstreproject
名称: MyFirstReProject
取决于: mobilesubstrate
版本: 1.0.1
Architecture: iphoneos-arm
描述: 我的第一次重新项目!
维护者: Flonger
作者: 弗隆
第:节调整
首页: https://www.baidu.com 编译命令
//编译
make package //打包
make install //安装验证结果
9.deb包介绍
官方网站:http://www.debian.org/doc/debian-policy/
deb包本质上是一个压缩包文件。它包含一些特定的目录和文件。安装过程是dpkg程序按照指定的规则复制文件并执行脚本。
dpkg -c xxxx.deb //查看deb包DEBIAN目录的目录结构
存放安装、卸载等过程中需要执行的控制文件和脚本等。
控制文件导出。 //deb包的名称。使用此名称来卸载和查询包信息。
Package: com.iosre.myfirstreproject
//项目名称(产品名称)
名称: MyFirstReProject
//依赖包(可以指定多个,用","分隔)
取决于: mobilesubstrate,固件(=8.0)
//deb包版本号
版本: 1.0.1
//描述软件支持的平台架构
Architecture: iphoneos-arm
//deb包介绍
描述: 我的第一次重新项目!
//deb包维护者和联系信息
Maintenanceer: Flonger//软件作者
作者: 方格
//Deb包所属类别
第:节调整
//软件主页
首页: https://www.baidu.com 脚本文件preinst
该脚本将在Deb 包文件解压之前运行。许多“preinst”脚本的任务是停止作用于要升级的包的服务,直到安装或升级该包。
后置
该脚本的主要任务是完成安装包时的配置工作。许多“postinst”脚本负责执行命令来重新启动新安装或升级的软件的服务。
普雷姆
该脚本负责停止与软件包关联的守护程序服务。它在删除包关联文件之前执行。
后期
该脚本负责修改包链接或文件关联,或删除由它创建的文件。 dpkg打包时,会复制当前目录下的layout目录下的所有文件和目录。
这些文件和目录将被镜像到目标设备(布局是相对于设备根目录的)
//发布时的Makefile
调试=0
THEOS_DEVICE_IP=10.171.4.22
ARCHS=ARMv7 ARM64
目标=iphone:latest:8.0
包括$(THEOS)/makefiles/common.mk
TWEAK_NAME=MyFirstReProject
MyFirstReProject_FILES=Tweak.xm
MyFirstReProject_FRAMEWORKS=UIKit
包括$(THEOS_MAKE_PATH)/tweak.mk
清洁:
rm -rf ./packages/*
包前:
cp ./script/postinst ./.theos/_/DEBIAN/
cp ./script/postrm ./.theos/_/DEBIAN/
10. 常见Logos语法介绍
维基百科:http://iphonedevwiki.net/index.php/Logos
10.1 Block-level
%挂钩
指定需要hook的类,并且必须以%end结尾。可以被%group 包含
%hook SBApplicationController
-(无效)uninstallApplication:(SBApplication *)应用程序{
NSLog(@"嘿,我们正在挂钩uninstallApplication:");
%原始; //调用该方法的原始实现
返回;
}
%end%组
该指令用于对%hooks 进行分组,以方便代码管理和组的条件初始化。它必须以%end 结尾。
一个%group 可以包含多个%hooks,所有不属于自定义组的%hooks 将隐式分类到%group_ungrouped 中。
%组iOS8
%hook IOS8_SPECIFIC_CLASS
//这里是你的代码
%end //结束钩子
%end //结束组ios8
%组iOS9
%hook IOS9_SPECIFIC_CLASS
//这里是你的代码
%end //结束钩子
%end //结束组ios9
%ctor{
if (kCFCoreFoundationVersionNumber 1200) {
%init(iOS9);
} 别的{
%init(iOS8);
}
}新的
在%hook 内部使用,向现有类添加新函数。功能与class_addMethod相同。
注意:Objective-C 类别和class_addMethod 的区别:前者是静态的,后者是动态的。
%hook SBApplicationController
-(无效)uninstallApplication:(SBApplication *)应用程序{
NSLog(@"嘿,我们正在挂钩uninstallApplication:");
%原始; //调用该方法的原始实现
返回;
}
新的
- (void)命名空间新方法
{
NSLog(@"我们在SpringBoard 中添加了一个新方法。");
}
%结束
10.2 Top level
%ctor
Tweak的构造函数完成初始化工作;如果未显示定义,Theos 会自动生成一个%ctor 并在其中调用%init(_ungrouped) 。
%dtor
Tweak 的构造函数完成了收尾工作。如果没有显示定义,Theos 将自动生成一个%dtor。
10.3 Function level
%初始化
该指令用于初始化某个%group,必须在%hook或%ctor内调用;如果它带有参数,它会初始化指定的组。如果不带参数,则初始化_ungrouped。
注意:请记住,只有调用%ini 后,相应的%group 才能工作! %ctor{
if (kCFCoreFoundationVersionNumber 1200) %init(iOS9);
否则%init(iOS8);
}%c
该指令的功能相当于objc_getClass或NSClassFromString,即动态获取一个类的定义并在%hook或%ctor中使用。 %hook跳板
- (void)_menuButtonDown:(id)向下
{
%原始;
SBScreenShotter *shotter=[%c(SBScreenShotter)sharedInstance];
[射手保存屏幕截图:YES];
}
%结束@%日志
该指令在%hook内部使用,将函数的类名、参数等信息写入syslog。您可以添加其他打印信息,格式为%log([(),….])。尾-f /var/log/syslog | grep 微信%orig
该指令在%hook内部使用,用于执行被hook函数的原始代码;您还可以使用%orig 更改原始函数的参数。 //实践
@interface SBScreenshotter: NSObject
+ (id)共享实例;
- (void)saveScreenshot: (BOOL)arg1;
@结尾
@接口SpringBoard
+ (void)_AutoScreenSave2;
- (void)_AutoScreenSave;
@结尾
%hook跳板
- (void)applicationDidFinishLaunching:(id)application
{
%原始;
UIAlertView *alert=[[UIAlertView 分配]
initWithTitle:@"你好,坦洲!"
message:nil
delegate:self cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[警报显示];
}
新的
- (void)_AutoScreenSave
{
NSLog(@"实例方法");
SBScreenShotter *shotter=[%c(SBScreenShotter)sharedInstance];
[射手保存屏幕截图:YES];
}
新的
+ (void)_AutoScreenSave2
{
NSLog(@"类方法");
SBScreenShotter *shotter=[%c(SBScreenShotter)sharedInstance];
[射手保存屏幕截图:YES];
}
- (void)_menuButtonDown:(id)向下
{
//SBScreenShotter *shotter=[%c(SBScreenShotter)sharedInstance];
//[射手saveScreenshot:YES];
//[self_AutoScreenSave];
[%c(SpringBoard)_AutoScreenSave2];
NSLog(@"x=%d, y=%d", 10, 20);
%log((NSString *)@"iOSRE", (NSString *)@"调试");
%原始; //调用原来的_menuButtonDown:
}
结尾
%hook SBLockScreenDateViewController
- (void)setCustomSubtitleText:(id)arg1 和Color:(id)arg2
{
/*
NSDate *date=[NSDate 日期];
NSDateFormatter *format1=[[NSDateFormatter alloc]init];
[format1 setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
NSString *str1=[format1 stringFromDate:date];
*/
结构tm *loctime;
字符timeBuf[1024]={0};
现在time_t=时间(NULL);
loctime=当地时间(现在);
strftime(timeBuf, 30, "[%Y/%m/%d
%H:%M:%S]", loctime); %orig([NSString stringWithUTF8String:timeBuf],arg2); } %end /* %group HookTest %hook SpringBoard - (void)_lockButtonDown:(struct __IOHIDEvent *)arg1 fromSource:(int)arg2 { NSLog(@"_lockButtonDown"); } - (void)_lockButtonUp:(struct __IOHIDEvent *)arg1 fromSource:(int)arg2 { NSLog(@"_lockButtonUp"); } - (void)powerDownCanceled:(id)arg1 { NSLog(@"powerDownCanceled"); %orig; } - (void)powerDown { NSLog(@"powerDown"); } - (void)powerDownRequested:(id)arg1 { NSLog(@"powerDownRequested"); } %end %end */ %ctor { %init(_ungrouped); //%init(HookTest); }11.Tweak工作原理
1.Cydia Substrate 和 Mobile Substrate
Cydia Substrate 原名为 Mobile Substrate 已经正式更名为 Cydia Substrate。 它是越狱后cydia插件/软件(主要指theos开发的tweak)运行的一个基础依赖包。提供软件运行的公共库,可以用来动态替换内存中的代码、数据等所以iOS系统越狱环境下安装绝大部分插件,必须首先安装Cydia Substrate。 Cydia Substrate主要由3部分组成:MobileHooker,MobileLoader 和 safe mode。2.MobileHooker
MobileHooker用于替换覆盖系统的方法,这个过程被称为Hooking(挂钩) 它主要包含两个函数: void MSHookMessageEx(Class class, SEL selector, IMP replacement, IMP *result); void MSHookFunction(voidfunction,voidreplacement,void** p_original); MSHookMessageEx 主要作用于Objective-C函数 MSHookFunction 主要作用于C和C++函数 Logos语法%hook就是对此函数做了一层封装,让编写hook代码变的更直观,上面的例子用的就是logos语法。 MSHookMessageEx http://www.cydiasubstrate.com/api/c/MSHookMessageEx/ void MSHookMessageEx(Class _class, SEL message, IMP hook, IMP *old);NSString *(*oldDescription)(id self, SEL _cmd); // implicit self and _cmd are explicit with IMP ABI NSString *newDescription(id self, SEL _cmd) { NSString *description = (*oldDescription)(self, _cmd); description = [description stringByAppendingString:@"!"]; return description; } MSHookMessageEx( [NSObject class], @selector(description),&newDescription, &oldDescription );MSHookFunction http://www.cydiasubstrate.com/api/c/MSHookFunction/ void MSHookFunction(void *symbol, void *hook, void **old);void *(*oldConnect)(int, const sockaddr *, socklen_t); void *newConnect( int socket, const sockaddr *address, socklen_t length ) { if (address->sa_family == AF_INET) { sockaddr_in *address_in = address; if (address_in->sin_port == htons(6667)) { sockaddr_in copy = *address_in; address_in->sin_port = htons(7001); return oldConnect(socket, ©, length); } } return oldConnect(socket, address, length); } MSHookFunction(&connect, &newConnect, &oldConnect);3.MobileLoader
MobileLoader 将tweak插件注入到第三方应用程序中(动态注入:ptrace) 启动时MobileLoader会根据/Library/MobileSubstrate/DynamicLibraries/目录中plist文件指定的作用范围, 有选择的在第三方进程空间里通过dlopen函数加载同名的dylib。 每一个.dylib文件都会有一个同名的.plist文件。.plist文件的作用就是用来指定tweak插件的作用对象。 Flongers-iphone:/Library/MobileSubstrate/DynamicLibraries root# pwd /Library/MobileSubstrate/DynamicLibraries Flongers-iphone:/Library/MobileSubstrate/DynamicLibraries root# ls AppList.dylib@ MFService.dylib* MyFirstReProject.plist afc2dService.dylib* AppList.plist MFService.plist* PreferenceLoader.dylib* afc2dService.plist MFAccelerator.dylib* MFServiceEx.dylib* PreferenceLoader.plist patcyh.dylib@ MFAccelerator.plist* MFServiceEx.plist* RHRevealLoader.dylib* patcyh.plist MFHongbaoRobot.dylib* MobileSafety.dylib* RHRevealLoader.plist MFHongbaoRobot.plist* MobileSafety.plist RocketBootstrap.dylib@ MFService.bundle/ MyFirstReProject.dylib* RocketBootstrap.plist4.safe mode
因为APP程序质量参差不齐崩溃再所难免,tweak本质是dylib,寄生在别人进程里,如果注入Springboard等。 系统进程一旦出错,可能导致整个进程崩溃,崩溃后就会造成iOS瘫痪。 所以CydiaSubstrate引入了安全模式,在安全模式下所有基于CydiaSubstratede 的三方dylib都会被禁用,便于查错与修复。 建议: ssh到iPhonedpkg -r com.iosre.myfirstreprojec 可以删除对应的Tweak插件包12. Tweak练习
1.定位目标文件
ps方法ps -e | grep WeChatfind方法 find -name sshd固定目录中查找 AppStore App全部位于“/var/mobile/Containers/Bundle/Application/”下, 系统App全部位于“/Applications/”下 daemon的配置文件均位于 “/System/Library/LaunchDaemons/” “/Library/LaunchDaemons” “/Library/LaunchAgents/” 是一个plist格式的文件。其中的“ProgramArguments”字段,即是daemon可执行文件的绝对路径 Flongers-iphone:/Library/LaunchDaemons root# cat com.openssh.sshd.plistLabelcom.openssh.sshdProgram/usr/libexec/sshd-keygen-wrapperProgramArguments/usr/sbin/sshd-iSessionCreateSocketsListenersSockServiceNamesshStandardErrorPath/dev/nullinetdCompatibilityWait2.获取头文件信息和bundleid
砸壳通过class-dump获取头文件获取bundleidcodesign -dvvv WeChat3.分析头文件编写tweak代码
Makefile文件 THEOS_DEVICE_IP = 192.168.1.113 DEBUG = 1 ARCHS = armv7 arm64 TARGET = iphone:latest:8.0 include $(THEOS)/makefiles/common.mk TWEAK_NAME = WeChatReProject WeChatReProject_FILES = Tweak.xm WeChatReProject_FRAMEWORKS = UIKit include $(THEOS_MAKE_PATH)/tweak.mk after-install:: install.exec "killall -9 WeChat" clean:: rm -rf ./packages/*control文件 Package: com.iosre.wechatreproject Name: WeChatReProject Depends: mobilesubstrate Version: 0.0.1 Architecture: iphoneos-arm Description: WeChat Tweak Maintainer: FLonger Author: Flonger Section: Tweaks Homepage: https://www.baidu.complist文件 { Filter = { Bundles = ( "com.tencent.xin" ); }; }tweak.xm文件#import#import#import@interface SeePeopleNearByLogicController - (void)onRetrieveLocationOK:(id)arg1; @end %hook SeePeopleNearByLogicController - (void)onRetrieveLocationOK:(id)arg1 { CLLocation *location = [[CLLocation alloc] initWithLatitude:31.154352 longitude:121.42562]; %orig(location); UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[@"onRetrieveLocationOK" stringByAppendingString:[[NSString alloc] initWithFormat:@"location is %@", location]] message:nil delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil]; [alertView show];【深入iOS逆向分析(第三部分)】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
终于等到这篇文章了!之前两篇我也看过了,感觉收获很大。
有10位网友表示赞同!
我最近对iOS逆向也挺感兴趣的,这个系列文讲解得真不错。
有16位网友表示赞同!
期待作者能分享更多实用的技巧和案例。
有16位网友表示赞同!
以前学过一些逆向的基础知识,想看看这篇文章有没有讲到更深层的知识点。
有6位网友表示赞同!
iOS逆向真的很烧脑!希望这位作者能够继续深入浅出地讲解。
有17位网友表示赞同!
我下载了之前两篇的文章,准备好好学习一下再看这篇文章。
有9位网友表示赞同!
看了文章预告,感觉这次讲的应该非常有趣,一定会学到很多新东西。
有14位网友表示赞同!
这个系列文是不是已经写完了?我还想继续看下去呢!
有8位网友表示赞同!
我很想知道作者是怎么把iOS App 里面的代码分析出来的。
有11位网友表示赞同!
希望这位作者可以开设更多的课程或教程,这样学习起来会更方便。
有16位网友表示赞同!
学习逆向工程真的需要非常强的逻辑思维能力呀!
有18位网友表示赞同!
这篇文章会不会涉及到一些安全性问题?我很感兴趣这个方面的知识。
有6位网友表示赞同!
我觉得这种技术对于程序员来说很有用,可以帮他们更好地理解其他人的代码。
有12位网友表示赞同!
我之前看过几本iOS逆向相关的书籍,希望能看看这篇文章是否能补充教材的内容。
有18位网友表示赞同!
感觉学习这个系列文需要有一定的编程基础,对 iOS 平台也很熟悉才容易理解吧?
有13位网友表示赞同!
期待作者能够多分享一些实际案例,这样更容易理解和学习。
有19位网友表示赞同!
我对iOS逆向一直很困惑,希望这篇文章能解答我心中的疑惑!
有14位网友表示赞同!
希望看完这篇文章后,我能自己尝试一下一些简单的逆向操作!
有15位网友表示赞同!
学习这种技术需要花费大量的时间和精力吧?
有16位网友表示赞同!