Ipa-medit 是一款无需越狱即可对重签名的 ipa 进行内存搜索和修补的工具。 它支持运行在 iPhone 和 Apple Silicon Mac 上的 iOS 应用。 该工具是为移动游戏安全测试而创建的。 许多移动游戏都有越狱检测,但 ipa-medit 不需要越狱,因此无需绕过越狱检测即可进行内存修改。
内存修改是游戏作弊最简单的方法之一,也是安全测试中需要检查的项目之一。 还有一些像 GameGem 和 iGameGuardian 这样的简易作弊工具。 然而,对于非越狱设备和 CUI(命令行界面)以及 Apple Silicon Mac,当时没有可用的工具。 因此,我将其作为安全测试工具制作了出来。 Android 版本请见 sterrasec/apk-medit。
$ brew install --HEAD libplist
$ brew install --HEAD usbmuxd
$ brew install --HEAD libimobiledevice
$ brew install --HEAD ideviceinstaller
从 GitHub Releases 下载二进制文件并将其放入您的 $PATH 中。
您可以使用 make 命令构建它。
构建需要 Go 编译器。
如果目标是在 Apple Silicon Mac 上运行的 iOS 应用,则需要对二进制文件进行签名,但脚本 script/codesign.sh 会自动执行并完成签名。
$ git clone [email protected]:sterrasec/ipa-medit.git
$ cd ipa-medit
$ make build
目标 .ipa 文件必须使用安装在您计算机上的证书进行签名。 如果您想修改第三方应用的内存,请使用 ipautil 之类的工具重新签名。
$ ipautil decode tap1000000.ipa # 解压
$ ipautil build Payload # 重新签名并生成 .ipa 文件
启动时,您需要使用 -bin 指定 .ipa 文件中的可执行文件路径,并使用 -id 指定 bundle id。
$ unzip tap1000000.ipa
$ ipa-medit -bin="./Payload/tap1000000.app/tap1000000" -id="jp.hoge.tap1000000"
启动时,您需要使用 -name 指定进程名称,或使用 -pid 指定进程 ID。
iOS 应用的进程名称和 PID 可以在活动监视器中查看。
$ ipa-medit -name <进程名称>
以下是交互式提示中可用的命令。
在内存中搜索指定的整数值。
> find 999986
成功暂停进程
扫描:0x00000001025e4000-0x00000001025e8000
扫描:0x00000001025f4000-0x00000001025fc000
扫描:0x0000000102604000-0x0000000102608000
....
扫描:0x000000016eb34000-0x000000016ebbc000
扫描:0x000000016ebc0000-0x000000016ebe8000
扫描:0x000000016ebec000-0x000000016ec74000
扫描:0x000000016ec78000-0x000000016ed00000
找到:1 个!!
地址:0x10a2feea0
默认情况下,当针对 iPhone 上运行的 iOS 应用时,由于 LLDB API 较慢,仅搜索整数。 当针对 Apple Silicon Mac 上运行的 iOS 应用时,也会搜索字符串。
您也可以指定数据类型,如 string、word、dword、qword。
> find dword 999994
搜索双字...
目标值:999994([58 66 15 0])
找到:1 个!!
地址:0x11378aea0
过滤先前的搜索结果,只保留与当前搜索结果匹配的项。
> filter 999842
成功暂停进程
找到:1 个!!
地址:0x1087beea0
在搜索到的地址写入指定值。
> patch 10
成功修补!
附加到目标进程。
> attach
成功暂停进程
从已附加的进程分离。
> detach
成功继续进程
获取目标进程的信息。 仅当针对 iPhone 上运行的 iOS 应用时有效。
> ps
SBProcess: pid = 926, state = running, threads = 37, executable = tap1000000
State: Running
thread #1: tid = 0x545ee, 0x00000001bd6552d0 libsystem_kernel.dylib`mach_msg_trap + 8, queue = 'com.apple.main-thread'
thread #3: tid = 0x54619, 0x00000001bd67a184 libsystem_kernel.dylib`__workq_kernreturn + 8
thread #4: tid = 0x5461a, 0x00000001bd67a184 libsystem_kernel.dylib`__workq_kernreturn + 8
thread #5: tid = 0x5461b, 0x00000001bd67a184 libsystem_kernel.dylib`__workq_kernreturn + 8
thread #6: tid = 0x5461c, 0x00000001bd67a184 libsystem_kernel.dylib`__workq_kernreturn + 8
thread #7: tid = 0x5461d, 0x00000001bd6552d0 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'com.apple.uikit.eventfetch-thread'
thread #8: tid = 0x5461e, 0x00000001bd6791ac libsystem_kernel.dylib`__psynch_cvwait + 8, name = 'GC Finalizer'
thread #9: tid = 0x5461f, 0x00000001bd65530c libsystem_kernel.dylib`semaphore_wait_trap + 8, name = 'Job.Worker 0'
thread #10: tid = 0x54620, 0x00000001bd65530c libsystem_kernel.dylib`semaphore_wait_trap + 8, name = 'Job.Worker 1'
thread #11: tid = 0x54621, 0x00000001bd65530c libsystem_kernel.dylib`semaphore_wait_trap + 8, name = 'Job.Worker 2'
...
thread #35: tid = 0x54659, 0x00000001bd6552d0 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'AURemoteIO::IOThread'
thread #36: tid = 0x54662, 0x00000001bd679814 libsystem_kernel.dylib`__semwait_signal + 8
thread #37: tid = 0x54663, 0x00000001bd6552d0 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'com.apple.CoreMotion.MotionThread'
thread #38: tid = 0x54664, 0x00000001bd65530c libsystem_kernel.dylib`semaphore_wait_trap + 8, name = 'Loading.PreloadManager'
要退出 medit,请使用 exit 命令或按 Ctrl-D。
> exit
再见!
如果出现错误 /private/var/containers/Bundle/Application/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/hoge.app: error: failed to get reply to handshake packet 且无法正常与 iOS 设备和 lldb 通信,请启动 Xcode 并构建某个应用,之后即可正常工作。
如果出现错误 Could not connect to lockdownd. 且无法正常与 iOS 设备和 ideviceinstaller 通信,请启动 Xcode 并构建某个应用,之后即可正常工作。
如果此方法无法解决问题,请按照“要求”部分中的命令示例,将 ideviceinstaller 和 libimobiledevice 更新到最新版本。
可以通过在 brew install 时添加 --HEAD 选项来安装 libimobiledevice 和 ideviceinstaller 的最新未版本化代码来解决此问题。
MIT 许可证