普通视图

发现新文章,点击刷新页面。
昨天以前掘金专栏-iOS逆向

iOS小技能:给debugserver添加task_for_pid权限,以便调试从AppStore中获取的App。

2022年10月27日 09:49
持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情 前言 在做iOS开发时,在Mac上输入LLDB的命令就可以控制iOS端的App,是因为在iOS客户端中

iOS动态库的注入原理

2022年2月6日 11:18

「这是我参与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入门常见问题汇总

2021年10月30日 14:49

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

引言

给新手看的入门基础篇

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为案例进行讲解

kunnan.blog.csdn.net/article/det…

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逆向 ,只为你呈现有价值的信息,专注于移动端技术研究领域。

❌
❌