转载一篇debug文章

http://versprite.com/og/ios-reverse-engineering-part-two-debugging-and-tracing-with-lldb/

iOS Reverse Engineering Part Two: Debugging and Tracing with LLDB

Overview

In our previous post – http://versprite.com/og/ios-reverse-engineering-part-one-configuring-lldb/ – we learned how to configure and setup debugserver and LLDB on your iOS device. In this post we will demonstrate how to use LLDB to perform basic debugging and message tracing.

objc_msgSend()

This topic has already been covered numerous times, but lets run through a refresher on Objective-C’s objc_msgSend(). This function is one of the more important items within the libobjc.A.dylib library. During runtime objc_msgSend() is used to send messages to an object within memory. This can be considered the equivalent to calling functions in C.

The compiler will convert a message expression – [receiver message] into a call on objc_msgSend(). When we take a look at the objc_msgSend() declaration:

id objc_msgSend (id self, SEL op, arg1, arg2 ..)

We see as parameters it takes a pointer to the instance of the class that is to receive the message, and the selector of the method that handles the message. objc_msgSend() takes the id type, which is literally just a pointer to a C struct, being identified as objc_object. After an object is created, memory is allocated for the objc_object type that consists if an isa pointer, which is followed by the data for that object. In this usage, the id type is basically a pointer to the receiver’s class instance in memory.

The second argument SEL, is pretty much the method’s signature string representation. Whew! Hopefully this is making a bit of sense, and now we can move into learning about ARM, and the Procedure Call Standard for the ARM Architecture.

ARM Calling Conventions

The ARM architecture contains 16 registers numbered r0 – r15, each 32-bits wide. The procedure call standard state that the first four registers (r0 – r3) are used to pass argument values into a subroutine and to return a result value from a function.

The prolog for a function call goes something like this:

– PUSH the value of the link register (LR)(r14) to the stack
– PUSH the value of the frame pointer (r7) to the stack
– Update the frame pointer to the value of the stack pointer (SP)
– PUSH the preserved registers to the stack
– Make space for local storage

An example might look like this:

push    {r4-r7, lr} // save LR, R7, R4-R6
add     r7, sp, #12 // adjust R7 to point to saved R7
push    {r8, r10, r11} // save remaining GPRs (R8, R10, R11)
vstmdb  sp!, {d8-d15} // save VFP/Advanced SIMD registers D8
sub     sp, sp, #36 // allocate space for local storage

objc_msgSend() Tracing

In order to start tracing objc_msgSend(), let us combine everything we have learned so far. We know from the declaration that objc_msgSend() takes two parameters, which point to the class instance and method signature. We also know from the ARM calling conventions, that the registers r0, and r1 will probably contain those respective values being passed into the objc_msgSend() function.

We will be using the Damn Vulnerable iOS App for demonstration. The first thing I am going to do is set breakpoint at [InsecureDataStorageVulnVC saveinPlistFileTapped:], because I only really wanna to trace the objc_msgSend() calls within this subroutine.

(lldb) b -[InsecureDataStorageVulnVC saveInPlistFileTapped:] Breakpoint 1: where = DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:], address = 0x000e5c2c

Now when we venture over to the application and attempt to save our data in the Plist file:

* thread #1: tid = 0x145aa, 0x000d0c2c DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:], queue = ‘com.apple.main-thread‘, stop reason = breakpoint 1.1
    frame #0: 0x000d0c2c DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:]
DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:]:
-> 0xd0c2c:  push   {r4, r5, r6, r7, lr}
   0xd0c2e:  add    r7, sp, #0xc
   0xd0c30:  push.w {r8, r10, r11}
   0xd0c34:  sub    sp, #0xc

To start tracing the objc_msgSend() calls within this subroutine let us disassemble where we are currently located.

(lldb) di
DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:]:
-> 0xd0c2c:  push   {r4, r5, r6, r7, lr}
   0xd0c2e:  add    r7, sp, #0xc
   0xd0c30:  push.w {r8, r10, r11}
   0xd0c34:  sub    sp, #0xc
   0xd0c36:  mov    r4, r0
   0xd0c38:  movs   r0, #0x9
   0xd0c3a:  movs   r1, #0x1
   0xd0c3c:  movs   r2, #0x1
   0xd0c3e:  blx    0x291db0                  ; symbol stub for: NSSearchPathForDirectoriesInDomains
   0xd0c42:  mov    r7, r7
   0xd0c44:  blx    0x291e44                  ; symbol stub for: objc_retainAutoreleasedReturnValue
   0xd0c48:  str    r0, [sp, #0x8]
   0xd0c4a:  movw   r1, #0x76b8
   0xd0c4e:  movt   r1, #0x1d
   0xd0c52:  movs   r2, #0x0
   0xd0c54:  add    r1, pc
   0xd0c56:  ldr    r1, [r1]
   0xd0c58:  blx    0x291e28                  ; symbol stub for: objc_msgSend
   0xd0c5c:  mov    r7, r7

We can set a breakpoint at the address 0x291e28 for the objc_msgSend() call.

(lldb) b 0x291e28

Breakpoint 2: where = DamnVulnerableIOSApp`symbol stub for: objc_msgSend, address = 0x00291e28

However once we hit this breakpoint, we need to perform additional inspection. We can do this by adding a stop-hook:

(lldb) target stop-hook add
Enter your stop hook command(s).  Type ‘DONE‘ to end.
> register read
> x/s $r1
> expr -o -- $r0
> DONE
Stop hook #1 added.

Through this stoop-hook we will read the values in the current registers, examine the contents of r1 as a string, and print the object description of the pointer located in r0. Remember r1 should contain the selector and r0 should contain the class instance.

After resuming execution, we hit the next breakpoint that we have set, and our stoop-hook is invoked.

General Purpose Registers:
        r0 = 0x176f6d70
        r1 = 0x335c9122  "objectAtIndex:"
        r2 = 0x00000000
        r3 = 0x00000000
        r4 = 0x176d50d0
        r5 = 0x001402bf  "saveInPlistFileTapped:"
        r6 = 0x175d8d30
        r7 = 0x27d40528
        r8 = 0x17664620
        r9 = 0x00000000
       r10 = 0x175f1180
       r11 = 0x00000000
       r12 = 0x3d47f1d0  (void *)0x3b627959: _os_lock_handoff_unlock$VARIANT$mp + 1
        sp = 0x27d40504
        lr = 0x000d0c5d  DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:] + 49
        pc = 0x00291e28  DamnVulnerableIOSApp`symbol stub for: objc_msgSend
      cpsr = 0x40000010

0x335c9122: "objectAtIndex:"
<__NSArrayI 0x176f6d70>(
/var/mobile/Applications/04A94C51-51CD-4633-9649-ACE1BCCFED72/Documents
)

Everything looks to be working, now we have a little homemade tracer, and can start moving through the rest of the calls.

General Purpose Registers:
        r0 = 0x3b7b8df4  (void *)0x3b7b8dcc: NSMutableDictionary
        r1 = 0x380953cd  "alloc"
        r2 = 0x002aa198  (void *)0x3b7b8df4: NSMutableDictionary
        r3 = 0x00000001
        r4 = 0x176d50d0
        r5 = 0x001402bf  "saveInPlistFileTapped:"
        r6 = 0x175d8d30
        r7 = 0x27d40528
        r8 = 0x17664620
        r9 = 0x17902868
       r10 = 0x175f1180
       r11 = 0x00000000
       r12 = 0x3b011479  libobjc.A.dylib`-[NSObject autorelease] + 1
        sp = 0x27d40504
        lr = 0x000d0ca3  DamnVulnerableIOSApp`-[InsecureDataStorageVulnVC saveInPlistFileTapped:] + 119
        pc = 0x00291e28  DamnVulnerableIOSApp`symbol stub for: objc_msgSend
      cpsr = 0x60000010

0x380953cd: "alloc"
NSMutableDictionary

https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/gdb_to_lldb_transition_guide/document/lldb-command-examples.html

时间: 2024-09-30 06:14:43

转载一篇debug文章的相关文章

转载一篇好文章

作者:熊 辉美国罗格斯-新泽西州立大学 记得我刚开始写英文论文的时候,感觉很棘手,效率也低,常常一个摘要就要写上两三天.现在我当了 8 年教授,写了一百多篇论文,逐渐可以快写这种“八股文”了.由于我现在身份转换了,也因为身为老师,要经常修改学生的英文论文,为了不让自己在修改论文时太痛苦,就常常思考该如何训练学生写好英文论文. 其实,发表出来的文章基本可分为两种:一种是属于看上去很美,但不能细看,细看就会发现一些问题:另一种是看上去很美,也真的很美,而且很耐读.如何写成第二种呢?学生写英文论文经常

前两篇转载别人的精彩文章,自己也总结一下python split的用法吧!

前言:前两篇转载别人的精彩文章,自己也总结一下吧! 最近又开始用起py,是为什么呢? 自己要做一个文本相似度匹配程序,大致思路就是两个文档,一个是试题,一个是材料,我将试题按每题分割出来,再将每题的内容与材料中进行文本相似度匹配. 所以先首先要做的是将试题把每道题作为一个字符串切割开来,存放到字典中. 程序入下: # -*- coding:utf-8 -*- import re #正则模块 f = open('test.txt','r') s = f.read() s1 = s.split('工

前段时间一直不知道怎么学习,在网上找到一篇好文章分享给在路上的产品经理

如果你也是一枚刚入门的交互设计师,是不是常有这样一种感觉:不知从何下手,闷头读了一大堆书.学了一大堆软件.画了一大堆图之后还是感觉心里不踏实,总害怕自己还缺点什么,恨不得要有本<交互设计学习大纲>就好了.出现这个问题有两个原因,一是交互设计师没有可视性强的产物,交互设计师的产物一般是线框图.流程图.信息架构图.说明文档等等,但这些东西既不如视觉设计稿华丽精美,也不如程序代码高贵冷艳,在外行人看来初级交互设计师和高级交互设计师画的好像都差不多,轻易看不出你修炼到了几层功力;第二个原因是交互设计是

js查找一篇英文文章中出现频率最高的单词

下面这个函数是js查找一篇英文文章中出现频率最高的单词(由26个英文字母大小写构成),输出该单词及出现次数,不区分大小写,主要是正则的运用: function counts(article){ article = article.trim().toUpperCase(); var array = article.match(/[A-z]+/g); article = " "+array.join(" ")+" "; var max = 0,wor

jsp连接mysql----------第一篇技术类文章

今天做作业连了一天的mysql. 最后我痛定思痛,决定从0开始学习jsp,省的又面临不会的局面. 忙活了一晚上,终于把数据库连接上了,不过,好伤心啊,我连个数据库都这么墨迹... <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@page import="data.database"%> <%@page

转几篇WPF文章

How to view word document in WPF application (CSVSTOViewWordInWPF) WPF 浏览PDF 文件 如何保存RichTextBox的文本到数据库?以及如何对RichTextBox的Document做绑定? 使用ViewModel模式来简化WPF的TreeView 转几篇WPF文章

统计一篇英文文章内每个单词出现频率,并返回出现频率最高的前10个单词及其出现次数

统计一篇英文文章内每个单词出现频率,并返回出现频率最高的前10个单词及其出现次数 from collections import Counter import re with open('a.txt', 'r', encoding='utf-8') as f: txt = f.read() c = Counter(re.split('\W+',txt)) #取出每个单词出现的个数 print(c) ret = c.most_common(10) #取出频率最高的前10个 print(ret) 原

跟我学SpringCloud | 终篇:文章汇总(持续更新)

SpringCloud系列教程 | 终篇:文章汇总(持续更新) 我为什么这些文章?一是巩固自己的知识,二是希望有更加开放和与人分享的心态,三是接受各位大神的批评指教,有任何问题可以联系我: [email protected]. Github源码下载:https://github.com/meteor1993/SpringCloudLearning <跟我学SpringCloud>系列: Greenwich版 Spring Cloud Greenwich.SR1; Spring Boot 2.1

《转载-两篇很好的文章整合》Android中自定义控件

两篇很好的文章,有相互借鉴的地方,整合到一起收藏 分别转载自:http://blog.csdn.net/xu_fu/article/details/7829721 http://www.cnblogs.com/0616--ataozhijia/p/4003380.html Android系统的视图结构的设计也采用了组合模式,即View作为所有图形的基类,Viewgroup对View继承扩展为视图容器类,由此就得到了视图部分的基本结构--树形结构 View定义了绘图的基本操作 基本操作由三个函数完