iOS小技能:lldb打印block参数签名

简介: iOS逆向时经常会遇到参数为block类型,本文介绍一个lldb script,可快速打印出Objective-C方法中block参数的类型。

前言

iOS逆向时经常会遇到参数为block类型,本文介绍一个lldb script,可快速打印出Objective-C方法中block参数的类型。

zblock <block-address> : print oc block signature, parameter -d for disassemble
AI 代码解读

I lldb打印block参数签名

1.1 install

cd ~
git clone git@github.com:zhangkn/zlldb.git
AI 代码解读

然后在 ~/.lldbinit 文件中添加下行内容:command script import ~/zlldb/main.py

1.2 使用

  1. 如果是逆向工作的话,没有代码,那可以断点到 objc_msgSend这行
  2. 执行命令 zblock 0x100588080 (block的地址传给 zblock命令),然后block的参数就出来了。
  3. 根据每一行的 type encoding 对照[苹果文档ocrtTypeEncodings](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html

)即可知道block的参数都有什么。

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html

由于Xcode11内置的lldb script开始默认Python3版本,facebook的chisel还有些支持问题(可能现在解决了)。zlldb就是把我自己常用的几个命令放到了这里,支持Python3(也就是最新版Xcode)。除了zblock外,还有几个简单的命令,大家可以参考README。

Objective-C type encodings

Objective-C method encodings

1.3 Python script

main.py

zblock_print_block_signature
def zblock_print_block_signature(debugger, target, process, block_address):
    pointer_size = 8 if zblock_arch_for_target_is_64bit(target) else 4
    # print("pointer size = {0}".format(pointer_size))
    # print("block address = %x"%(block_address))

    flags_address = block_address + pointer_size    # The `flags` integer is after a pointer in the struct
    
    flags_error = lldb.SBError()
    flags = process.ReadUnsignedFromMemory(flags_address, 4, flags_error)

    if not flags_error.Success():
        print("Could not retrieve the block flags")
        return
    
    block_has_signature = ((flags & (1 << 30)) != 0)    # BLOCK_HAS_SIGNATURE = (1 << 30)
    block_has_copy_dispose_helpers = ((flags & (1 << 25)) != 0) # BLOCK_HAS_COPY_DISPOSE = (1 << 25)

    
    if not block_has_signature:
        print("The block does not have a signature")
        return
    
    block_descriptor_address = block_address + 2 * 4 + 2 * pointer_size    # The block descriptor struct pointer is after 2 pointers and 2 int in the struct
    
    block_descriptor_error = lldb.SBError()
    block_descriptor = process.ReadPointerFromMemory(block_descriptor_address, block_descriptor_error)
    if not block_descriptor_error.Success():
        print("Could not read the block descriptor struct")
        return
    
    signature_address = block_descriptor + 2 * pointer_size    # The signature is after 2 unsigned int in the descriptor struct
    if block_has_copy_dispose_helpers:
        signature_address += 2 * pointer_size    # If there are a copy and dispose function pointers the signature
    
    signature_pointer_error = lldb.SBError()
    signature_pointer = process.ReadPointerFromMemory(signature_address, signature_pointer_error)
    
    signature_error = lldb.SBError()
    signature = process.ReadCStringFromMemory(signature_pointer, 255, signature_error)

    if not signature_error.Success():
        print("Could not retrieve the signature")
        return
    
    print("Signature Address: 0x%x" %(signature_address))
    print("Signature String: %s" %(signature))

    escaped_signature = signature.replace('"', '\\"')

    method_signature_cmd = 'po [NSMethodSignature signatureWithObjCTypes:"' + escaped_signature + '"]'
    debugger.HandleCommand(method_signature_cmd)

    docurl = 'https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html'
    print('Type Encodings Ref: %s' % (docurl))

def zblock_disass_block_invoke_function(debugger, target, process, block_address, instruction_count):
    pointer_size = 8 if zblock_arch_for_target_is_64bit(target) else 4
    
    invoke_function_address = block_address + pointer_size + 2 * 4    # The `invoke` function is after one pointer and 2 int in the struct
    print("Invoke address: 0x%x" % (invoke_function_address))
    
    invoke_function_error = lldb.SBError()
    invoke_function_pointer = process.ReadPointerFromMemory(invoke_function_address, invoke_function_error)
    if not invoke_function_error.Success():
        print("Could not retrieve the block invoke function pointer")
        return
    
    disass_cmd = "disassemble --start-address " + str(invoke_function_pointer) + " -c " + str(instruction_count)
    debugger.HandleCommand(disass_cmd)

def zblock_arch_for_target_is_64bit(target):
    arch_64 = ['arm64', 'x86_64']
    arch = target.GetTriple().split('-')[0]
    return arch in arch_64

def cmd_zblock(debugger, command, result, internal_dict):
    cmd_args = shlex.split(command)

    usage = "usage: %prog arg1 [--disass -d] [--number-instructions -n]"
    parser = optparse.OptionParser(prog='zblock', usage=usage)
    parser.add_option('-d', '--disass', action='store_true', dest='disass', default=False)
    parser.add_option('-n', '--number-instructions', dest='numberinstructions', default=20)
    
    try:
        (options, args) = parser.parse_args(cmd_args)
    except:
        print("error parse parameter")
        return
    
    if len(args) == 0:
        print("You need to specify the name of a variable or an address")
        return
    
    number_instructions = options.numberinstructions
    should_disass = options.disass
    
    target = debugger.GetSelectedTarget()
    process = target.GetProcess()
    thread = process.GetSelectedThread()
    frame = thread.GetSelectedFrame()

    variable_arg = args[0]
    address = int(variable_arg,0)
    if address == 0: 
        print("invalid address")
        return

    print("Block address: 0x%x" % (address))
    
    zblock_print_block_signature(debugger, target, process, address)

    if should_disass:
        zblock_disass_block_invoke_function(debugger, target, process, address, number_instructions)
AI 代码解读

see also

公号:iOS逆向

Chisel_fblldb.py_lldbinit

Chisel is a collection of LLDB commands to assist debugging iOS apps.

https://github.com/kunnan/kunnan.github.io/blob/master/_posts/Debug/2018-07-07-Chisel_fblldb.py_lldbinit.md

目录
打赏
0
0
0
0
480
分享
相关文章
【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
246 75
超级签名源码/超级签/ios分发/签名端本地linux服务器完成签名
该系统完全在linux下运行,不存在使用第三方收费工具,市面上很多系统都是使用的是第三方收费系统,例如:某心签名工具,某测侠等,不开源而且需要每年交费,这种系统只是在这些工具的基础上套了一层壳。请需要系统的放大你们的眼睛。
69 0
iOS block修饰符用copy还是strong
iOS block修饰符用copy还是strong
181 0
iOS URL参数转字典
iOS URL参数转字典
201 0
ios签名工具永久有效吗?
苹果APP上架难,不用越狱,下载未上架APP!
【IOS实用玩机技巧】爱思助手 IPA 签名功能常见问题汇总(iOS上架)
【IOS实用玩机技巧】爱思助手 IPA 签名功能常见问题汇总(iOS上架)
2577 0
【IOS实用玩机技巧】爱思助手 IPA 签名功能常见问题汇总(iOS上架)
iOS小技能:下拉刷新控件的适配
1. 下拉顶部背景色设置: 往tableView的父控件添加拉伸背景视图 2. present 半屏适配 iOS13 modalPresentationStyle属性默认不是全屏样式`UIModalPresentationFullScreen`,而是半屏样式,需要根据需求手动设置。 present 半屏,会导致列表下拉刷新失效。
233 0
iOS小技能:下拉刷新控件的适配
iOS开发 - 如何写出漂亮的block
iOS开发 - 如何写出漂亮的block
116 0
iOS开发- 关于Block的几种应用
iOS开发- 关于Block的几种应用
133 0

热门文章

最新文章

  • 1
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    40
  • 2
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    33
  • 3
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    29
  • 4
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    27
  • 5
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    27
  • 6
    iOS8 中无需开源库的内置功能一览
    618
  • 7
    iOS7应用开发7:自定义视图、手势操作
    1
  • 8
    IOS小工具以及精彩的博客
    3
  • 9
    Facebook SDK(iOS)初学讲解
    2
  • 10
    iOS - Swift NSPoint 位置
    582
  • 1
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    27
  • 2
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    29
  • 3
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    40
  • 4
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    33
  • 5
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    27
  • 6
    uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
    143
  • 7
    【05】2025年1月首发完整版-篇幅较长-苹果app如何上架到app store完整流程·不借助第三方上架工具的情况下无需花钱但需仔细学习-优雅草央千澈详解关于APP签名以及分发-们最关心的一篇来了-IOS上架app
    246
  • 8
    app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
    90
  • 9
    深入探索iOS开发中的SwiftUI框架
    145
  • 10
    ios样式开关按钮jQuery插件
    61
  • AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等