普通视图
iOS小技能:给debugserver添加task_for_pid权限,以便调试从AppStore中获取的App。
iOS小技能:__attribute__的应用
iOS小技能:消息发送的步骤(利用类型编码加快消息分发)
iOS小技能:动态地给类添加新的方法、实例变量、属性。
iOS动态库的注入原理
「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战」。
前言
动态库的注入原理:
- 一个是基于修改Mach-O 的Load Commands,即通过修改可执行文件的Load Commands来实现的. 在Load Commands中增加一个LC_LOAD_DYLIB , 写入dylib路径。
Usage: insert_dylib dylib_path binary_path [new_binary_path]
- 一个是利用环境变量DYLD_INSERT_LIBRARIES,例如使用它进行dumpdecrypted(补充:Clutch 通过
posix_spawnp
生成一个新的进程,然后暂停进程并dump内存) - 另一个是在挂载的进程上创建一个挂起的线程, 然后在这个线程里申请一片用于加载动态库的内存,然后恢复线程,动态库就被注入(通过 taskfor_pid函数获取目标进程句柄,然后通过在进程内创建新线程并执行自己的代码。) cycript 就是以这种方式执行脚本代码。
I、静态库和动态库的区别
1.1 动态库的特点
- 存在形式有 .dylib,.framework 和链接符号 .tdb;
- 它的好处是可以只保留一份文件和内存空间,从而能够被多个进程使用,例如系统动态库;
- 可减小可执行文件的体积,不需要链接到目标文件。
1.2 静态库的特点
- 以.a 或者.framework形式存在的一种共享程序代码的方式,从本质上来讲就是一种可执行文件的二进制形式;常常会将程序的部分功能编译成库,暴露出头文件的形式供开发者调用
- 静态库以一个或者多个object文件组成;可以将一个静态库拆解成多个object文件(ar -x)
- 静态库链接的时会直接链接到目标文件,并作为它的一部分存在。
II、动态库的编译和注入
2.1 编译
xcrun --sdk iphoneos clang++ dynamiclib -arch arm64 -framework Foundation Person.mm -o target.dylib -fvisibility=hidden
- Makefile
CC = xcrun --sdk iphoneos clang++
ARCH = arm64
FRAMEWORK = -framework Foundation
VERSION = -compatibility_version 1 -current_version 1
VISIBLE = -fvisibility=hidden
TARGET = target.dylib
SOURCE = Person.m
$(TARGET):$(SOURCE)
$(CC) -dynamiclib -arch $(ARCH) $(FRAMEWORK) $(SOURCE) -o $(TARGET) $(VERSION)
.PHONY:clean
clean:
rm $(TARGET)
2.2 动态库的注入方式
2.2.1 cycript注入动态库的方式
在挂载的进程上创建一个挂起的线程, 然后在这个线程里申请一片用于加载动态库的内存,然后恢复线程,动态库就被注入(通过 taskfor_pid函数获取目标进程句柄,然后通过在进程内创建新线程并执行自己的代码。)
2.2.2 通过环境变量DYLD_INSERT_LIBRARIES 注入
DYLD_INSERT_LIBRARIES=/PathFrom/dumpdecrypted.dylib /PathTo
#New Run Script Phase:
cd ${TARGET_BUILD_DIR}
export DYLD_INSERT_LIBRARIES=./libKNoke.dylib && /Applications/QKNQ.app/Contents/MacOS/QKNQ
2.2.3 通过增加load command 的LC_LOAD_DYLIB或者LC_LOAD_WEAK_DYLIB,指定动态库的路径来实现注入
修改App可执行文件的头部,给它添加这么一个load command,并指定load我们构造的dylib就好
- 二次打包动态库的注入:
避免每次从环境变量注入–偏静态:通过LC_LOAD_DYLIB实现dylib的加载
通过修改可执行文件的Load Commands来实现的. 在Load Commands中增加一个LC_LOAD_DYLIB , 写入dylib路径 Usage: insert_dylib dylib_path binary_path [new_binary_path]
1、现在iOS上的绝大多数以root权限运行的App,都是通过setuid + bash来实现的
2、App运行所需要的信息,一般都存放在其MachO头部43中,其中dylib的信息是由load commands指定的.
这些信息是以静态的方式存放在二进制文件里(不是由DYLD_INSERT_LIBRARIES动态指定),而又是由dyld动态加载的,所以我们给它起了个“偏静态”的名字--在此App得到执行时,dyld会查看其MachO头部中的load commands,并把里面LC_LOAD_DYLIB相关的dylib给加载到进程的内存空间
- 如果需要修改LC_ID_DYLIDB、、LC_LOAD_DYLIB,可以使用install_name_tool
install_name_toll -id xxx imputfile
install_name_toll -change old new imputfile
- 通过cydia substrate提高的注入:
配置plist文件,并将对应的plist、dylib文件放入指定目录 /Layout/Library/MobileSubstrate/DynamicLibraries/、/usr/lib/TweakInject
其实也是通过DYLD_INSERT_LIBRARIES将自己注入,然后遍历DynamicLibraries目录下的plist文件,再将符合规则的动态库通过dlopen打开
III、导出和隐藏符号
3.1 导出符号
- 查看导出符号信息
nm -gm tmp_64.dylib
(__DATA,__data) external
(undefined) external _CFDataCreate (from CoreFoundation)
(undefined) external _CFNotificationCenterGetDarwinNotifyCenter (from CoreFoundation)
(__TEXT,__text) external
(undefined) external _IOObjectRelease (from IOKit)
(undefined) external _IORegistryEntryCreateCFProperty (from IOKit)
000000010ffa3f97 (__DATA,__objc_data) external _OBJC_CLASS_$_BslyjNwZmPCJkVst
000000010ffa3f97 (__DATA,__objc_data) external _OBJC_CLASS_$_ChiDDQmRSQpwQJgm
3.2 隐藏符号
- static 参数修饰,不会导出符号信息
static char _person_name[30] = {'\0'};
- 在编译参数中加入-exported_symbols_list export_list
CC = xcrun --sdk iphoneos clang
ARCH = arm64
FRAMEWORK = -framework Foundation
VERSION = -compatibility_version 1 -current_version 1
EXPORT = -exported_symbols_list export_list
VISIBLE = -fvisibility=hidden
TARGET = target.dylib
SOURCE = Person.mm
target1:$(SOURCE1)
$(CC) -dynamiclib -arch $(ARCH) $(FRAMEWORK) $(SOURCE) -o $(TARGET) $(VERSION)
target2:$(SOURCE1)
$(CC) -dynamiclib -arch $(ARCH) $(FRAMEWORK) $(SOURCE) -o $(TARGET) $(VERSION) $(EXPORT)
target3:$(SOURCE1)
$(CC) -dynamiclib -arch $(ARCH) $(FRAMEWORK) $(SOURCE) -o $(TARGET) $(VERSION) $(VISIBLE)
clean:
rm $(TARGET)
- 在编译参数中指定-fvisibility=hidden,对指定符号增加visibility(“default”)来导出符号
//#define EXPORT __attribute__((visibility("default")))
CC = xcrun --sdk iphoneos clang++
ARCH = arm64
FRAMEWORK = -framework Foundation
VERSION = -compatibility_version 1 -current_version 1
VISIBLE = -fvisibility=hidden
TARGET = target.dylib
SOURCE = Person.m
$(TARGET):$(SOURCE)
$(CC) -dynamiclib -arch $(ARCH) $(FRAMEWORK) $(SOURCE) -o $(TARGET) $(VERSION)
.PHONY:clean
clean:
rm $(TARGET)
see also
由于篇幅原因,更多内容请关注 #小程序:iOS逆向,只为你呈现有价值的信息,专注于移动端技术研究领域;更多服务和咨询请关注#公众号:iOS逆向。
🍅 联系作者: iOS逆向(公号:iosrev)
🍅 作者简介:CSDN 博客专家认证🏆丨全站 Top 50、华为云云享专家认证🏆、iOS逆向公号号主
🍅 简历模板、技术互助。关注我,都给你。
iOS逆向小技能:Cydia Substrate的组成部分、编写Tweak的步骤
iOS设备日志查看工具:syslog、socat
iOS逆向小技能:Theos的安装
iOS逆向小技能:使用substrate及runtime进行hook(定时检测app是否开启)
iOS小技能: 处理接口的暂无数据
iOS小技能:视图置顶(让一个View至于最顶端, 避免被其他子视图遮盖住)
iOS15适配本地通知功能
iOS接入开屏广告教程 : 以腾讯优量汇为案例
程序员必备小技能:mac文件备份和清理、常用工具的安装和配置
iOS入门常见问题汇总
小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
引言
给新手看的入门基础篇
I、入门常见问题
1.1 请问iOS入门的话,xcode虚拟机就可以了?
使用Xcode的模拟器只是真机方面的功能无法调试而已,比如app的扫一扫功能涉及到的摄像机、录音亦或者接入三方SDK的时候也最好在真机调试测试。
1.2 请问包管理就是cocoa pods吧?
是的,另外Carthage也可以管理iOS依赖库。
Swift Package Manager 是 Apple 为了弥补当前 iOS 开发中缺少官方组件库管理工具的产物。相较于其他组件管理控件,他的定义文件更加轻松易懂,使用起来也很 Magic,只需将源码放入对应的文件夹内,Xcode 就会自动生成工程文件,并生成编译目标产物所需要的相关配置。同时,SPM 与 Cocoapods 相互兼容,可以在特性上提供互补。
github.com/apple/swift-package-manager 相关文档:developer.apple.com/documentati…
iOS第三方库管理规范,以Cocoapods为案例进行讲解
1.3 用于开发iOS的Mac最低配置需要什么样的?
8G内存有点小,最好16G。 不过这个性价比还不错
II 常用第三方库注意事项
2.1 极光消息推送
定期更新SDK,尤其系统大版本更新的时候。
2.2 toast 提示
设置toast显示时长 (针对SVProgressHUD第三方库)
[SVProgressHUD setMinimumDismissTimeInterval:0.4];// 设置最小显示时长
[SVProgressHUD setMaximumDismissTimeInterval:0.5];//
III、流程保证质量(规范+测试+设计)
kunnan.blog.csdn.net/article/det…
see also
9 月 14 日起 App Store Connect 已经开放 iOS 15 和 iPadOS 15 App 的提交,同时苹果宣布自 2022 年 4 月起,所有提交至 App Store 的 iOS 和 iPadOS app 都必须使用 Xcode 13 和 iOS 15 SDK 构建。 Xcode 13 需在 macOS 11.3 及以上版本运行:
更多资讯和服务请关注#小程序:iOS逆向
,只为你呈现有价值的信息,专注于移动端技术研究领域。