抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

以下内容节选自《iOS应用逆向工程》:

逆向工程最受欢迎的应用场合就是“借鉴”他人的软件功能。

在App Store里面,有不少优秀的App。当我们不知道App中的某个功能是如何实现的时候,逆向工程就能起到关键性的作用,此时使用iOS逆向工程技术就能够对它了解一二。

有些老牌软件的架构设计合理,代码工整规范,实现得非常优雅。我们没有他们那样深厚的技术功底和人才储备,想要借鉴他们使用的高级技术,却又求学无门。在这种情况下,逆向工程就是解决问题的金钥匙。通过逆向那些软件,可以从App中把它们的设计思路抽象出来为我所用,从而提高自己App的精致程度。比如,WhatsApp的稳定性、健壮性出类拔萃,如果我们自己要编写一个IM类App,通过逆向工程技术学习WhatsApp的整体架构与设计思路将是非常有益的。

一、功能介绍

想要了解app的功能是怎么实现的,最简单的方法就是反编译了。
所幸的是,Hopper Disassembler提供了反编译功能,能够将汇编代码转成伪代码。

想要使用这个功能的话,要先把光标定位到某个函数的汇编代码里:
This is a picture without description

然后点击菜单的 Window –> Show Pseudo Code Of Procedure 选项,就会弹出一个伪代码窗口:
This is a picture without description

这个功能虽然强大,但是每次只能反编译一个函数,并不支持批量生成伪代码。
不过Hopper内置了一个Python解析器(这背后一定有肮脏的Python交易),所以我们可以编写Python脚本来实现这个功能。

打开Hopper的帮助文件/Applications/Hopper Disassembler v3.app/Contents/Resources/Hopper.help,会出现一个窗口:
This is a picture without description

点击Scripting Reference选项,可以看到Hopper提供的类和方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Class Tag
getName

Class Procedure
addTag
decompile
getBasicBlock
getBasicBlockAtAddress
getBasicBlockCount
getEntryPoint
getHeapSize
getTagAtIndex
getTagCount
getTagList
hasTag
removeTag
tagIterator

//......

搜索关键字Pseudo,可以发现以反编译的方法:

1
2
3
decompile()

Returns a string containing the pseudo-code of the procedure, or None if the decompilation is not possible.

既然Hopper提供了这个方法,那么实现批量导出伪代码的功能就不难了。

由于代码比较长,所以放在Github里,具体代码可以在https://github.com/poboke/Class-Decompile下载。

二、使用方法

1、将下载的Class Decompile.py文件放到~/Library/Application Support/Hopper/Scripts目录里。

2、将可执行文件拖到Hopper里,等待分析完成。如果日志框里出现以下文字,就说明分析完成了:

Analysis segment __LINKEDIT

Analysis segment External Symbols

Background analysis ended

3、点击菜单 Scripts –> Class Decompile
This is a picture without description

4、Hopper会出现一个弹框,可以选择反编译类型:
This is a picture without description

  • Decompile All Classes : 反编译所有类
  • Decompile One Class : 反编译单个类
  • Cancel : 取消

5、如果选择反编译单个类的话,会出现以下弹框:
This is a picture without description
输入某个类名后,点击 OK 按钮就可以反编译出该类的伪代码。

6、反编译出来的伪代码保存在~/ClassDecompiles目录里。

7、打开反编译的文件,例如CalculatorController.m,可以看到生成的伪代码:

CalculatorController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@implementation CalculatorController

//......

- (void)clearRecentConversionsMenu:(id)arg2
{
rdi = self->_conversionController;
r14 = *objc_msgSend;
[rdi clearRecentConversions];
rax = [self updateRecentConversionsMenu];
return;
}

- (void)openExpressionSyntaxHelp:(id)arg2
{
r14 = *objc_msgSend;
rbx = [[NSBundle mainBundle] pathForResource:@"ExpressionSyntax" ofType:@"rtf"];
rdi = [NSWorkspace sharedWorkspace];
rdx = rbx;
rax = [rdi openFile:rdx];
return;
}

//......

@end

评论