利他才能利己


  • 首页

  • 标签

  • 归档

  • 搜索

Wireshark: 简单分析 TCP 三次挥手

发表于 2018-09-09 | 分类于 网络协议 |

话说握手

你要是开发人员,相信你一定听说过 TCP(Transmission Control Protocol 传输控制协议)或是 TCP 握手的说法。

所谓握手,通俗来讲就是通信双方协商在后续通信过程中需要使用的通信信息的过程。TCP 为了建立可靠的连接需要三次握手,后续给大家分享 TLS 为了实现加密、校验、身份认证同样需要握手的过程。

TCP 三次握手可以使用下图来表达:

本篇给大家分享如何使用 Wireshark 来跟踪 HTTP 包,查看 TCP 握手的过程。

在看下面内容之前,先简单看一下 TCP 协议报头。

下图是 TCP 报头的格式:

其中,Seq(Sequence Number) 是 32 位的序列号,Acknowledgment number 称之为确认序号,也是 32 位的,但是他不是标志位 ACK,这个要区别开,当 ACK 置 1 时 Acknowledgment number 才有效,指接收方期待的下一个报文段的序列号。

TCP 报头信息中有六个控制位(标志位),分别是:SYN、ACK、PSH、FIN、RST 和 URG。

1
2
3
4
5
6
SYN: 表示建立连接
FIN: 表示关闭连接
ACK: 表示响应
PSH: 表示有数据传输
RST: 表示连接重置
URG: 表示紧急数据

Seq 序列号有两个作用:
第一,在 SYN 置 1 时,此为当前连接的初始序列号(Initial Sequence Number, ISN)该值是个随机值,数据的第一个字节序号为此 ISN+1。

第二,在 SYN 置 0 时,为当前连接报文段的累计数据包字节数。

TCP 协议设计比较复杂,其涉及的知识较多,这里大家整不明白也没有关系,并不影响你阅读下面的内容,如果对 TCP 协议本身感兴趣,可以去拜读【TCP/IP 详解,卷 1:协议】这本书。

网络模型

每次说到网络层,就要拿出类似下面的网络模型图,OSI 将网络模型分为7层,TCP/IP 模型将网络模型分为 4 层,网络 4 层模型由 7 层模型简化合并而来,没有本质的区别,如图:

HTTP 仅仅是个协议,属于应用层的面向对象的协议,从上图可以看出 HTTP 是在 TCP 基础之上的。

HTTP 协议一共有五大特点

1、支持客户/服务器模式
2、简单快速
3、灵活
4、无连接
5、无状态

这里强调一下 无连接 和 无状态 这两个特点。

无连接,指的是限制每次连接只处理一个请求。服务器处理完客户端的请求,并收到客户端的应答后,即断开连接。采用这种方式可以节省传输时间。Keep-Alive 特性不在本篇讨论范围,暂时你可以将其忽略。

无状态,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求,会给我们发送数据过来,但是发送完,不会记录任何信息。

可以利用 HTTP 的这两个特点来分析 TCP 三次握手的过程。

三次握手过程

三次过程如下面草图,如下所示:

我们用实际例子来看一下这个过程,以 GET 请求下面地址为例,使用 Wireshark 抓包。

1
http://www.baidu.com/news/detailV3.html?id=1279391&COMMON_ACCESS_TOKEN=(null)&COMMON_ACCESS_TOKEN_SECRET=(null)&_cT=IOS&_cV=3.1.3&_cA=PM

看返回结果,选中 HTTP/1.1 200 OK 右键, 在弹出框中选择 Follow/TCP Stream,如下图所示:

关闭弹出的弹窗,回到主界面,看到如下图所示的三次(红色 1、2、3处) TCP 握手过程:

第一次,请求客户端发送一个 [SYN] 包,序列号是 0(seq=0)。

第二次,服务器收到 [SYN] 包,然后会发送一个 [SYN, ACK] 包,序列号是 0,ACK 置 1(seq=0,ack=1)。

第三次,客户端请求服务器,客户端会发送一个 [ACK] 包,序列号是 1,Ack 置 1(seq=1,ack=1)来回复服务器。

这里注意一下,大写的 ACK 是一个 bit 位表示确认,小写的 ack 是一个确认序列号,表示数值。

简单的画一个草图,如下:

这个过程,简单描述为下面三个步骤:

双方在建立连接之前都处于 CLOSED 的状态。

1、发送方给接收方发送 SYN 信号,此时发送方处于 SYN_SENT 状态。
2、接收方确认并回复给发送方 SYN/ACK 信号,此时接收方处于 SYN_RCVD 状态。
3、发送方给接收方发送确认 ACK 信号,发送完毕后,发送方(客户端)进入 ESTABLISHED 状态,当接收端(服务端)接收到这个包时,也进入 ESTABLISHED 状态,TCP 握手结束。

上面的步骤,建议感兴趣的朋友去实际操作一下。

为什么是三次握手

回头再来想一想,TCP 的连接为什么需要三次握手呢,为什么不是一次,两次呢?一次不就挺好吗,三次是不是有点多此一举了?

TCP 协议不是一个人定出来的而是一群人拟定的,设计三次握手固然有它的意义,是经过精心设计且在性能和效率上面衡量过的。

在知乎 TCP 为什么是三次握手,而不是两次或四次? 上面有不错的答案,虽然有些回答比较搞笑,但是很好理解,比如这位仁兄:

我们不妨换个思路来想这个问题,TCP 协议设计初衷是 让数据进行可靠,高效,安全的传输,如果握手是一次,两次或四次,就无法很好的保证 TCP 的 可靠,安全及高效 的传输,说不定哪天有人设计出来一种可替代 TCP 协议的其他协议就是两次握手或者不需要握手,哈哈!

参考阅读

如何理解HTTP协议的“无连接,无状态”特点?

TCP 为什么是三次握手,而不是两次或四次?


扫码关注,你我就各多一个朋友~

Wireshark:抓取 HTTP 包

发表于 2018-09-01 | 分类于 网络协议 |

广告时间,见谅勿怪,看到了就点一下吧,感激不尽🙇‍!


最近在看人工智能相关的知识,无意中发现了一个巨牛的 人工智能教程,分享一下给大家。

教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。

点 这里 可以直接看教程。


开篇简要

初识 Wireshark 简单介绍了强大的 Wireshark 工具,想用好或者是说想发挥 Wireshark 的巨大威力,还有很长的路要走(对我来说)。学习 Wireshark 的成本要比其他网络抓包工具的成本高,所以请做好学习的准备。

我身边很多开发同事,甚至包括一些刚入职的测试工程师都不喜欢使用抓包工具,遇到问题凭着自己的感觉在那里侃侃而谈,既耽误时间又没有解决问题,有时候还伤了和气,明明可以使用工具可以解决的问题,偏偏要各抒己见。

说到 Wireshark 更是很少人使用,至少我身边的同事是这样。如果让你一直去看那些 RFC 等网络协议,不到半小时估计你就会感到疲惫,但是结合 Wireshark 来理解网络协议就会感到无比的快乐,何乐而不为呢?!

继续阅读下去,你可以了解到如下几个知识:

1. 如何抓取 PC 端、iOS 设备的网络包?
2. 使用一些过滤条件如何查看包的内容?
3. 如何在 Wireshark 中显示域名?

PC 端的 HTTP 请求

打开 Wireshark,选择对应的网口,因为我使用的是无线网络(WiFi),所以选择 Wi-Fi:en0 这个网口,你可以根据你的网络使用情况来选择对应的网口,如下图:

可以看到对应有网络数据的网口,Wireshark 还在右侧显示对应的波浪,很人性化的设计。双击对应的网口,就可以使用 Wireshark 来抓包看数据了。

下面我就以 PC 端访问 www.veryitman.com 来演示 HTTP 请求的抓包情况。

查看本机的 ip 地址,我的是 10.4.17.7, 再来看一下 www.veryitman.com 对应的 ip 地址:

1
ping ww.veryitman.com

显示结果如下:

1
64 bytes from 185.199.110.153: icmp_seq=0 ttl=52 time=317.074 ms

那么, 185.199.110.153 就是其对应的 ip 地址。总的来说,对于 PC 端,源地址是 10.4.17.7,目的地址是 185.199.110.153,对于服务器来说,正好反过来。

首先在过滤器中输入 http, 如下图所示:

然后打开浏览器,我使用的是 Chrome,打开 http://www.veryitman.com/2018/08/20/%E5%88%9D%E8%AF%86-Wireshark/ 网站站点,Wireshark 显示如下(部分截图):

改变一下过滤语句,将之前的 http 改为 ip.src==10.4.17.7 && http && ip.dst==185.199.109.153, 显示如下:

可以选择任何一个请求,展示区域如下:

上图中的三个区域分别对应的是 View 中的 Packet List, Packet Details,Packet Bytes 三个视图。

选择任何一个请求,在对应的 区域2 可以看到该请求的详情。

刚才使用的过滤条件只看到 PC(客户端)的请求,没有看到服务器返回信息,我们修改一下过滤条件为 ip.src==185.199.109.153 && http && ip.dst==10.4.17.7,这样就看以看到服务器的回包信息了,如下图所示:

双击进入该响应,就可以看到对应的响应数据详情了。

iOS 设备的 HTTP 请求

跟查看 PC 端的 HTTP 请求方式基本一致,只是此时的本机 ip 地址是手机端的而不是 pc 端的。

初识 Wireshark 中已经跟大家分享过如何去连接 iOS 设备到 Wireshark 抓包了,这里不再赘述。

至于查看 iOS 设备的 ip 地址,就很简单了,打开 设置/wifi 看一下详情就知道了。

显示域名

如果你经常使用 Charles 抓包,就可以发现 Charles 展示的请求中都是以域名来显示的,但是在 Wireshark 都是显示 ip 地址,或许因此感到不适,那么,Wireshark 能否展示域名呢?

Wireshark 是可以像 Charles 那样展示域名的,只是它默认显示 ip 地址罢了。

打开 Preferences,如图:

这样 Wireshark 的显示就是另一番景象了如下图所示:

当然,你也看出来了,过滤条件还是可以使用的。

你还可以使用其他的过滤条件,如下面的一些过滤条件,能帮你快速定位你要的数据。

1
2
3
4
5
http.host == "veryitman.com"

http.host contains "veryitman.com"

http contains "HTTP/1.1 200 OK"

扫码关注,你我就各多一个朋友~

卖废品的一次经历

发表于 2018-08-26 | 分类于 随笔 |

偶遇

这两天在收拾屋子,本来想把一些不重要的物品直接卖掉,省得给自己增加运输成本。但是又有些不舍,毕竟跟自己在一起生活了这么多年,每一本书,每对桌椅,每件衣服都是我和老婆努力挣钱买回来的,里面都包含着奋斗的故事。

话又说回来,无舍无得。于是,我就开始将物品分类,按照优先级挑选,重要的东西就放到箱子中,次要的就放到沙发上,不重要的就扔到大厅里,最后再来审视一遍这些不重要的物品是否还有留下来的必要,最终我把不重要的东西放到一个大袋子中,准备把它们卖给废品站。

在百度上面找了好几家附近收废品的,打电话过去都要求卖家自己把东西拿过去,态度十分不友好,我也就没再多问,就挂掉了电话。

无独有偶,中午下楼去买东西回来的时候,正好看到一个大爷骑着三轮车在我前面驰骋,大爷的车技贼溜,在小巷子中开出了赛车的感觉。还没等我张嘴,他就即将要离开我的视线,急中生智,我看到他车子后面留有电话,于是我就急忙的努力的追赶着去记住他的电话,最后迫不及待的放下手中的东西,拿出手机拨打了他的电话。

大爷办事利落,不一会就到了楼下,三下五除二的把废品收拾了一番,像是收获了一批战利品一样。他很惊诧为什么我知道他的电话,我说我看到了你车上的电话号码了,就记下来了。

大爷说:“小伙子,你的记性还真好,不愧是上过大学的人。“,我说:“是呀,我过目不忘!哈哈!”。

那天中午,我把东西半卖半送的都给这位大爷了,谁叫他夸我呢!

思量

上面这件事算不上什么大事,顶多也就算个鸡毛蒜皮的小事,但是给了我很多回忆和思考。

很多高中生也包括他们的家长们,都经常会说等上了大学就好了,不用那么累了,在大学的殿堂里可以无忧无虑的 享受 了。在我看来这是不对的,高中之所以累是因为有连绵不绝的作业和没有尽头的考试,当然还有班主任喋喋不休的教导,让你的神经时长处于紧绷的状态。高中是人生中必经的一个过程,至少我觉得它锻炼了我的意志和耐力,包括对心理上的考验,我很感激高中三年的生活。

大学生活和学习的确是一个值得向往和想象的,你可以吊儿郎当的过完几年大学生活,也可以努力拼搏过来,没有人逼你去怎么做,完全取决于你自己。

我大学的成绩算是优异,每次看到奖学金名单上有自己的名字,同学们都会说你真厉害,居然考这么好的成绩。我会说,如果你再努力一下肯定比我考的更好,就像那个大爷说我好记性一样,其实并不是我过目不忘,而是自己努力的结果,因为我知道自己并不是天才。

很多人进入社会参加工作后,发现工作并不是想象中的那般一帆风顺,自己一起进公司的同事,明明能力和自己相当甚至还不如自己,为什么别人就升职加薪,马上就要走上人生巅峰了,自己却还是原地踏步或者举步维艰呢?总是想不明白这是为什么,那是因为你自己没有看到别人比你更加努力。

还有不少人会抱怨为什么别人能力没有我强,领导偏偏把一些重要的事情交给了他,开始怀疑对方是不是对领导施了什么魔法,而自己从来都没有想过怎么去向对方请教,或者思考自己是不是真的做好了本职工作。

这件小事给了我几个启发:

1. 一定要给自己树立一个长远目标和短期目标,不断的完成短期目标,向长远目标前进。

2. 对于别人的赞美或是诋毁,要保持一颗平常心,戒骄戒躁。

3. 不要总是夸你的孩子聪明,要夸他比别人更努力,因为努力比聪明更重要。

4. 不要总是抱怨命运的不公,多去审视自己的不足,想办法去补全。

5. 有个可以交心的朋友尤为重要,可以让彼此敞开心扉,无所顾忌的交谈。

这个世上没有免费的午餐,一切都要靠你自己去奋斗去争取,机会总是留给有准备的人,坚持自己的目标一直前行,相信自己,机会总有一天会和你不期而遇。

相信总有一天,你会感激正在努力的自己!


扫码关注,你我就各多一个朋友~

初识 Wireshark

发表于 2018-08-20 | 分类于 Tools |

使用 Charles 介绍了在 MacOS 上面的使用 Charles 工具, 虽然 Charles 很不错, 但是其只能抓 HTTP/HTTPS 的包, 对 TCP、UDP 等其他协议的网络包, 爱莫能助。

今天给大家分享强大的网络抓包工具 Wireshark,算是初步认识一下这个工具,后续分享更多关于 Wireshark 的内容。

简介

Wireshark 是免费的,支持 Windows、MacOS 和 Linux,提供丰富的 GUI 交互,能分析所有的网络协议,并且是开源的。

掌握好 Wireshark,能对绝大部分的网络协议进行分析了,所以学习它的使用对你的工作不无裨益。

关于 Wireshark 本身 UI(展示的界面内容) 的部分不在本文的讨论范围内,更多关于 Wireshark 的介绍和特性,可以去 Wireshark 官网 查阅。

安装

我的 MacOS 版本:

点击 Wireshark 的 下载地址, 可以去下载对应的平台版本。

注意: 之前的 Mac 系统版本可能需要安装 x11, 现在新系统不需要安装了.

抓 iOS 设备的数据包

想抓 iOS 设备的网络数据,需要让 iOS 设备数据通过 MacOS 才行,因为 Wireshark 是针对网口进行抓包的。

当然了,你的 iOS 设备不需要越狱.

通过 usb 连接 iOS 设备后,接下来创建远程虚拟接口,在终端执行下面命令:

1
rvictl -s 设备id(udid)

rvictl 即 Remote Virtual Interface Tool。它可以通过 iOS 设备的 UDID 创建一个虚拟网卡,然后通过这个虚拟网卡监听设备上所有的网络流量。

执行成功后,Mac 会出现一个对应的虚拟网络接口,名字是 rvi0(如果有多个 iOS 设备, 则累加,rvi1,rvi2…),如下图所示:

只要启动 Wireshark,监听 rvi0 接口就能抓到 iOS 设备的数据了。

关于获取 iOS 设备 ID(UDID),可以使用 Xcode, 在 Window/Devices and Simulators 中选择相应设备,右面设备信息的 identifier 里就是对应的 UDID. 也可以通过 iTunes 或者第三方工具如 iTools 获取.

你可以安装 ideviceinstaller 来查看设备 ID.

1
brew install ideviceinstaller

然后执行下面命令:

1
idevice_id -l

以抓取下面的一个 HTTP 请求为例,简单说明一下相关的知识。

GET 请求:

1
/news/detailV3.html?id=1279391&COMMON_ACCESS_TOKEN=(null)&COMMON_ACCESS_TOKEN_SECRET=(null)&_cT=IOS&_cV=3.1.3&_cA=PM

看返回结果,选中 Rsponse(200 OK) 右键, Follow/HTTP Stream,如图所示:

在弹出的窗口中就可以看到具体的响应内容,以及响应的 json 数据。

过滤器过滤

在 Wireshark 中显示过滤器会显示很多当前网络的数据包,如果你想看指定规则的数据包怎么办?

别担心,Wireshark 给我们提供了过滤功能,按照一定的过滤规则就可以达到你的目的。

1. 网络协议过滤

比如 TCP,只显示 TCP 协议,HTTP 只显示 HTTP 协议等。在过滤器输入框中直接输入协议名称即可,不区分大小写。

2. IP 地址过滤

如 ip.src == 192.168.1.102 显示源地址为 192.168.1.102,
而 ip.dst == 192.168.1.102, 目标地址为 192.168.1.102。

3. 端口过滤

tcp.port == 80, 端口为 80 的

tcp.srcport == 80, 只显示 TCP 协议的原端口为 80 的。

4. Http 模式过滤

http.request.method == “GET”,只显示 HTTP GET 方法的。

5. 结合逻辑运算符 AND/OR 组成复杂的表达式

AND/OR 也可以写成 && / ||

下面举几个常用的示例,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//源地址或者目标地址是192.168.1.103
ip.src == 192.168.1.103 or ip.dst == 192.168.1.103

//显示所有目标或源地址是192.168.1.1的数据包
ip.addr == 192.168.1.1

//显示目标地址是192.168.1.1的数据包
ip.dst == 192.168.1.1

//显示源地址是192.168.1.1的数据包
ip.src == 192.168.1.1

//tcp 连接端口为9101的数据包
tcp.port == 9101

更多的过滤规则可以去 官方手册 和 CaptureFilters 查阅和学习。

美中不足

Wireshark 只能查看封包,而不能修改封包的内容,或者发送封包。

对于 HTTP、HTTPS 网络封包,Wireshark 都可以捕获, 但不能直接解密 HTTPS,所以想使用 Wireshark 来分析 HTTPS 包中的内容,需要去额外配置,较麻烦,后续研究再分享给大家。

所以建议大家,分析 HTTP/HTTPS 去使用各自平台上面的其他工具, 如 Fiddler 和 Charles 等优秀的抓包工具。


扫码关注,你我就各多一个朋友~

配置 php7 + Nginx

发表于 2018-08-19 | 分类于 Server |

最近在看人工智能相关的知识,无意中发现了一个巨牛的 人工智能教程,分享一下给大家。

教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点 这里 可以直接看教程。


PHP7

之前为了配合完成一个项目(PHP 版本为5.6),在本机搭建了 PHP56 的环境,后面自己系统升级为 macOS High Sierra,发现系统自带的 PHP 版本已经是 7.1 了,于是就开始使用系统自带的 PHP 版本了。

1
php -v

显示 PHP 版本信息,如下:

1
2
3
PHP 7.1.16 (cli) (built: Apr  1 2018 13:14:42) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies

系统自带的 PHP7.1 没有默认的 php.ini 文件,执行下面命令查找一下:

1
php -r "echo php_ini_loaded_file();"

此时并没有打印对应的配置文件信息。需要我们手动去复制一份:

1
sudo cp /private/etc/php.ini.default /private/etc/php.ini

再次执行上面命令,即可看到配置文件的绝对路径了。或者执行 php --ini

1
2
3
4
5
6
php --ini

Configuration File (php.ini) Path: /etc
Loaded Configuration File: /etc/php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)

这里有个问题需要注意,php.ini 文件复制成功后,需要下面两步操作,否则在 php 代码发生致命错误的时候,页面不会输出任何内容,只是报 HTTP ERROR 500 的错误。

第一步,修改 php.ini 文件的权限,否则无法编辑保存,默认是只读属性。

1
sudo chmod 777 /private/etc/php.ini

第二步,编辑 php.ini 文件,将 display_errors = Off 改为下面 on 即可。

1
display_errors = On

记得每次修改完配置文件,需要重启 php-fpm 和 nginx 服务。

PHP56

1. 安装 PHP56

可以参考下面两篇文章。

  • PHP开发准备

  • 安装 PHP 遇到的问题

2. 卸载(删除)PHP56

执行 brew uninstall

1
brew uninstall php

即可完成卸载。

如果卸载遇到问题,就打开 /usr/local/Cellar/ 目录,删除对应的 PHP 目录即可。

配置 php-fpm

现在新版本的 PHP 其内核已经集成了 php-fpm,我们不需要另外安装了。

配置 php-fpm 配置文件

1
sudo cp /private/etc/php-fpm.conf.default /private/etc/php-fpm.conf

修改配置文件

1
sudo vi /private/etc/php-fpm.conf

找到 error_log 项,添加下面两个配置项,如下:

1
2
error_log = /usr/local/var/log/php-fpm.log
pid = /usr/local/var/run/php-fpm.pid

如果不配置上面的配置项,启动 php-fpm 会报错:

1
2
3
ERROR: failed to open error_log (/usr/var/log/php-fpm.log): No such file or directory (2)
ERROR: failed to post process the configuration
ERROR: FPM initialization failed

接下来, 继续配置,将 www.conf.default 复制一份命名为 www.conf 即可。

1
2
3
cd /private/etc/php-fpm.d/

sudo cp www.conf.default www.conf

不配置上面的,会报如下错误:

1
2
ERROR: No pool defined. at least one pool section must be specified in config file
ERROR: FPM initialization failed

至此,可以启动 php-fpm 了,执行下面命令:

1
sudo php-fpm -D

不出意外的话,已经成功启动,可以使用下面命令查看端口使用情况

1
netstat -an | grep 9000

如果你在启动 php-fpm 遇到下面的错误:

1
2
ERROR: unable to bind listening socket for address '127.0.0.1:9000': Address already in use (48)
ERROR: FPM initialization failed

有两种方式解决这个问题

**1.**修改 php-fpm 使用的端口号

1
sudo vim /private/etc/php-fpm.d/www.conf

将 listen = 127.0.0.1:9000 改为 listen = 127.0.0.1:9001 即可。

**2.**杀掉9000端口占用的进程

关闭所有之前启动的 php-fpm

1
killall php-fpm

找到占用端口的进程号

1
netstat -an | grep 9000

然后 kill -9 pid,重新启动 php-fpm 即可。

安装和配置 Nginx

1
brew install nginx

创建文件

1
2
3
4
5
mkdir -p /usr/local/var/log/nginx
mkdir -p /usr/local/etc/nginx/sites-available
mkdir -p /usr/local/etc/nginx/sites-enabled
mkdir -p /usr/local/etc/nginx/conf.d
mkdir -p /usr/local/etc/nginx/ssl
1
2
3
4
5
6
7
sudo mkdir -p /var/www
sudo chown :staff /var/www
sudo chmod 775 /var/www
vi /var/www/info.php
vi /var/www/index.html
vi /var/www/403.html
vi /var/www/404.html

改变 nginx.conf 配置文件

该配置文件在 /usr/local/etc/nginx/nginx.conf 下面.

我的配置:

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
27
28
29
30
31
32
33
34
35
36
37
38
worker_processes  1;

error_log /usr/local/etc/nginx/logs/error.log debug;
pid /usr/local/var/run/nginx.pid;

events {
worker_connections 256;
}

http {
include mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /usr/local/etc/nginx/logs/access.log main;

sendfile on;

keepalive_timeout 65;

index index.html index.php;

include /usr/local/etc/nginx/sites-enabled/*;
include /usr/local/etc/nginx/conf.d/*;
server {
listen 8080;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root ~/projs/phpdev/nginx/nginx_sites/; #web的根目录
index index.php index.html index.htm; #加index.php
}
}
}

注意:

1
2
3
4
location / {
root ~/projs/phpdev/nginx/nginx_sites/; #web的根目录
index index.php index.html index.htm; #加index.php
}

配置了我的 web 目录和支持的文件.

运行 PHP

  • 创建 index.php

  • 启动 php-fpm

1
sudo php-fpm

或者以守护进程的方式来启动 PHP-fpm

1
sudo php-fpm -D
  • 启动 Nginx
1
sudo nginx
  • 编辑 index.php

在 web 目录(我配置的) ~/projs/phpdev/nginx/nginx_sites/ 新建文件 index.php.

index.php 里面可以编写代码:

1
2
3
4
5
6
7
8
9
10
<!-- lang: php -->
<!-- ~/nginx_sites/index.php -->
<?php
echo "Hello PHP";
echo "</br>";

echo "学习 php";
echo "</br>";
echo phpinfo();
?>

打开浏览器, 输入地址:http://localhost:8080/index.php 你会看到下面的页面:

也可以在该目录下创建其他 PHP 文件, 如 m.php 文件.

浏览器中输入 http://localhost:8080/m.php 可以执行相对应的文件.

注意:这里的 m.php 是新建的 PHP 文件.

重要文件

1. php 配置文件

1
/private/etc/php.ini

2. nginx log 文件

1
2
3
4
5
/usr/local/var/log/nginx/access.log

/usr/local/var/log/nginx/error.log

/usr/local/etc/nginx/logs/error.log

3. nginx 配置文件

1
/usr/local/etc/nginx/nginx.conf

4. php-fpm 配置文件

1
/private/etc/php-fpm.d/www.conf

常见问题

502 bad gateaway

我是经常看到这个问题,但是每次引起的原因又不太一样,绝大部分是因为 php-fpm 启动不了或者是其端口错误导致的。

这种情况下,建议去看 /usr/local/etc/nginx/logs/error.log 日志文件。

例如下面的错误:

1
2
3
4
5
6
7
[error] 
61016#0: *1 kevent() reported that connect() failed (61: Connection refused) while connecting to upstream,
client: 127.0.0.1,
server: localhost,
request: "GET /3.php HTTP/1.1",
upstream: "fastcgi://127.0.0.1:9000",
host: "localhost:8080"

最终,我修改了 /private/etc/php-fpm.d/www.conf 中端口为 9000(我之前将该端口修改了其他的),重启 php-fpm 解决问题。


扫码关注,你我就各多一个朋友~

简单配置 Apache

发表于 2018-07-14 | 分类于 Server |

声明

有时候, 我们希望在自己本机(PC)搭建一个 WebServer, 然后自己可以在浏览器或者手机上面可以访问对应的地址直接查看效果, 再或者希望测试下载功能等, 其实 MacOS 自带的有 Apache 服务器.

下面简单分享一下, 在 MacOS 中如何简单的使用 Apache 服务器.

常用命令

常用的命令有开启/重启/停止等.

1.开启: sudo apachectl start
2.重启: sudo apachectl restart
3.关闭: sudo apachectl stop
4.查看版本号: httpd -v

1.查看 Apache 版本号

1
httpd -v  

或者使用下面的命令:

1
sudo apachectl -v

查看结果如下:

1
2
Server version: Apache/2.4.28 (Unix)
Server built: Oct 9 2017 19:54:20

2.启动 Apache

1
sudo apachectl start

在浏览器打开: http://localhost

会显示:

1
It works

3.停止 Apache

1
sudo apachectl stop

如果没有开启 Apache 服务, 执行上面命令的话, 会报下面的错误:

1
2
/System/Library/LaunchDaemons/org.apache.httpd.plist: 
Could not find specified service

4.重新启动 Apache

1
sudo apachectl restart

如果修改了 Apache 的配置文件, 需要重新启动 Apache 服务, 执行上面的命令即可.

配置 Sites

在自己的用户目录, 新建一个 Sites 目录, 例如我的用户目录是 /Users/mark, 可以在终端分别执行:

1
2
3
cd /Users/mark

mkdir Sites

执行成功后, 可以看到如下图所示的目录:

接下来修改 Apache 中的配置文件, 执行下面命令开始编辑 httpd.conf 文件.

1
sudo vim /etc/apache2/httpd.conf 

打开 httpd.conf 文件,查找 userdir 关键字.

找到如下两行被注释掉的内容:

1
2
3
#Include /private/etc/apache2/extra/httpd-userdir.conf

#LoadModule userdir_module libexec/apache2/mod_userdir.so

将其前面的 #(注释) 去掉, 紧接着编辑这个文件, 增加如下内容:

1
2
3
<Directory /Users/mark/Sites>
Require all granted
</Directory>

将上面的这些代码放到如下代码下面即可:

1
2
3
4
5
<Directory "/Library/WebServer/CGI-Executables">
AllowOverride None
Options All
Require all granted
</Directory>

保存该文件并退出 vim.

执行下面的命令修改 httpd-userdir.conf 文件:

1
sudo vim /private/etc/apache2/extra/httpd-userdir.conf

增加如下内容:

1
2
3
4
5
UserDir Sites

<IfModule bonjour_module>
RegisterUserSite customized-users
</IfModule>

注意: 如果在 /private/etc/apache2/extra/ 目录下没有该文件, 新建一个即可.

保存文件并退出即可.

我们可以将自己需要运行的 html 等文件放到该目录, 如我将 index.html 放到该目录.

重新启动 Apache 服务, 在浏览器中输入 http://localhost/~mark/, 可以看到 index.html 里面的内容.

WebServer 目录

上面我们提到, 启动 Apache 服务之后, 在浏览器可以看到 It Works 的字样, 那么这个是哪个文件输出的呢?

这个文件是 sudo mvim index.html.en~orig, 在如下目录:

1
/Library/WebServer/Documents

可以使用 vim 编辑该文件, 然后再刷新浏览器就可以看到其变化.

我们也可以把自己的 html 文件放到这里, 如 mark.html, 内容如下:

1
2
3
4
5
<html>
<body>
<h1>Hi, mark, Apache server works!</h1>
</body>
</html>

在浏览器中输入 http://localhost/mark.html, 可以看到对应的输出.

如果嫌配置 Sites 目录麻烦, 可以使用这种方式, 直接拷贝对应的文件或者目录放到 /Library/WebServer/Documents 中, 只不过需要 root 权限罢了.


扫码关注,你我就各多一个朋友~

RunLoop: 移除常驻线程

发表于 2018-07-01 | 分类于 iOS |

概要

下面两篇文章:

  • 常驻线程是一种什么体验

  • NSTimer 实现常驻线程的问题

都是在 iOS 平台上如何利用 RunLoop 的特性实现常驻线程.

可能你看到本篇文章的标题 移除常驻线程, 有点不理解甚至觉得作者是不是有点神经病, 都已经需要常驻线程了, 为什么还要去退出呢?

实际应用场景中的确几乎遇不到这种情况, 所以, 本篇只是从技术的角度给大家分享 RunLoop 其他的一些知识点.

且耐住性子往下看…

为了不让大家误解, 统一一下相关的词汇和语境.

  • 输入源, 包括 source 和 timer.
  • 退出 RunLoop 指的是在常驻线程的方法中立即返回.
  • 这里的 RunLoop 指的是子线程中的 RunLoop 不是主线程中的.
  • 结合之前介绍常驻线程的文章来看现在的文章, 不然不好理解.

运行 RunLoop 的方法

这里有三种方式开启运行 RunLoop, 分别如下:

1
2
3
4
5
- (void)run;

- (void)runUntilDate:(NSDate *)limitDate;

- (void)runMode:(NSString *)mode beforeDate:(NSDate *)limitDate;
  • run 方法

看一下 API 文档如何解释 run 方法的:

1
2
3
4
5
Puts the receiver into a permanent loop, 
during which time it processes data from all attached input sources.
If no input sources or timers are attached to the run loop, this method exits immediately;
otherwise, it runs the receiver in the NSDefaultRunLoopMode by repeatedly invoking runMode:beforeDate:.
In other words, this method effectively begins an infinite loop that processes data from the run loop’s input sources and timers.

大致意思讲的是, 在没有任何输入源的情况下, run 方法会立即执行后退出, 不会保持线程的持久性, 换句话说, 在有输入源的情况下, 该方法会进入一个无限循环当中. 本质上, 在 NSDefaultRunLoopMode 模式下, 该方法是反复调用 runMode:beforeDate: 方法的.

在之前文章实现常驻线程的代码中, 我们使用了 run 方法来开启运行 RunLoop.

可以看出, 我们之前实现的常驻线程使用 run 方法是无法退出常驻线程的.

  • *runUntilDate:(NSDate )limitDate 方法

该方法 API 释义:

1
2
Runs the loop until the specified date, 
during which time it processes data from all attached input sources.

保证有输入源的情况下该方法启动的 RunLoop 可以在指定的日期内一直运行不会返回. 换句话说, 日期只要已到该方法就会立即退出 RunLoop.

示例代码:

1
2
3
4
5
6
7
8
//等同于 run, 可保证一直运行
[runLoop runUntilDate:[NSDate distantFuture]];

//立即返回, 退出 RunLoop
[runLoop runUntilDate:[NSDate date]];

//然后过12秒后返回
[runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:12.0f]];
  • **runMode:(NSString )mode beforeDate:(NSDate )limitDate 方法

该方法有两个参数 mode 和 limitDate, mode 就是 RunLoop 的运行模式, limitDate 就是上面方法一样的释义即在指定的日期内.

1
Runs the loop once, blocking for input in the specified mode until a given date.

可以这么理解, 该方法开启的 RunLoop 处理完之后会立即返回(once), 如果在指定日期内事件还没处理, 在该日期后会立即返回.
换句话说, 如果指定的日期是当前的, 该方法执行后 RunLoop 会立即退出.

示例代码:

1
2
3
4
5
//立即返回
[runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]];

//有事件到达处理后就返回,如果没有则过12秒返回
[runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:12.0]];

这三个方法, 总结一下大概如下:

  • 这三个方法在没有任何输入源情况下会都立即返回(退出 RunLoop), 不会等待.
  • run 可保证 RunLoop 在有输入源的情况下一直运行.
  • runUntilDate 可以通过设置超时时间来退出 RunLoop. 超时时间一过就会立即退出 RunLoop.
  • 使用 runMode 方式启动的 RunLoop 会在处理完事件后或者超时后, 立即返回. 即可以通过设置超时时间或者使用 CFRunLoopStop 方法来退出 RunLoop.

移除常驻线程

先看一下, 在子线程执行的方法中如何实现的. 示例代码如下:

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
27
28
29
30
31
32
33
34
- (void)asyncRun {

@autoreleasepool {

NSLog(@"veryitman--asyncRun. Current Thread: %@", [NSThread currentThread]);

NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
_threadRunLoop = runLoop;

// 保持常驻线程的方式1: source
NSPort *port = [NSMachPort port];
_threadPort = port;
[runLoop addPort:port forMode:NSRunLoopCommonModes];

NSLog(@"veryitman--asyncRun. Current RunLoop: %@", runLoop);

// 执行其他逻辑
//...

// 手动开启 RunLoop
// [runLoop run];

while (!self.stopLoopRunning && [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) {

// 这里是为了验证常驻线程是否已经退出
NSLog(@"--- asyncRun ----");

// 实际业务中, 建议使用空语句实现
; //实现为空语句
}

NSLog(@"veryitman--asyncRun. End Run.");
}
}

结合上面讲解的原理, 这里选择使用 runMode 方法来开启运行 RunLoop. 大家也可以自由发挥使用其他的方法.

注意: stopLoopRunning 是定义的一个属性.

移除的示例代码如下:

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
- (void)viewDidDisappear:(BOOL)animated {

[super viewDidDisappear:animated];

// 取消线程
// 实际业务场景中自行决定 canCancel 的设置, 这里只是示例
BOOL canCancel = YES;
if (canCancel) {
[[self permanentThread] cancel];
}

/// 停止常驻线程
{
self.stopLoopRunning = YES;

// 移除 port
// 如果是用 timer 的方式的常驻线程, 可以 invalid 对应的 timer
[self.threadRunLoop removePort:self.threadPort forMode:NSRunLoopCommonModes];

// 停止 RunLoop
if (nil != self.threadRunLoop) {
CFRunLoopStop([self.threadRunLoop getCFRunLoop]);
}
}
}

离开页面后, 可以发现 NSLog(@"--- asyncRun ----"); 停止了打印, 并且当前的 Controller 也 dealloc 了.


扫码关注,你我就各多一个朋友~

iOS 逆向: dumpdecrypted 砸壳记

发表于 2018-06-07 | 分类于 iOS |

今天是一个特别的日子, 高考的第一天, 祝各位莘莘学子金榜题名.

最近在看人工智能相关的知识,无意中发现了一个巨牛的 人工智能教程,分享一下给大家。

教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点 这里 可以直接看教程。


iOS 逆向: 砸壳 介绍了如何使用工具 Clutch 对 iOS 的应用进行砸壳操作, 今天继续给大家分享使用另外一个工具 dumpdecrypted 对 APP 进行砸壳.

概要

有些朋友就会问了, 既然 Clutch 已经很牛B了, 为什么还需要 dumpdecrypted 这个工具呢?

刚开始的时候, 我也很排斥使用 dumpdecrypted 这个工具的, 使用起来比较复杂, 并且套路不熟的情况下还很容易出错.

之前说过 Clutch 并不是万能的, 从 App Store 下载的 App(比如 WeChat)有些并不能使用 Clutch 来进行砸壳, 换句话说, 使用 Clutch 工具来进行砸壳会失败, 那么, dumpdecrypted 就登场了.

本次砸壳的系统依然是 iOS10.3.x, 工具使用 dumpdecrypted, 砸壳的对象是 WeChat 这个 App.

准备工作

  • MacOS PC
  • 越狱手机一台(我用的是iPhone6SPlus 10.3.1)
  • dumpdecrypted
  • class-dump
  • 在 Cydia 中安装 cycript, 可以先不用管 cycript 是什么, 下载安装即可.
  • iFunBox 或者其他助手工具

编译 dumpdecrypted

去 Github 下载 dumpdecrypted 源码, 源码就一个 C 源文件.

下载 zip 包之后, 解压, 如图:

在当前目录, 执行 make 即可完成编译, 如图所示:

编译成功后生成 dumpdecrypted.dylib 文件.

这里有个小插曲, 编译 dumpdecrypted 的时候报错了, 错误信息如下:

1
2
3
4
xcrun: error: SDK "iphoneos" cannot be located
xcrun: error: unable to lookup item 'Path' in SDK 'iphoneos'
clang: warning: no such sysroot directory: '-F/System/Library/Frameworks' [-Wmissing-sysroot]
dumpdecrypted.c:27:10: fatal error: 'stdio.h' file not found

无法找到对应的 SDK 和 stdio.h 文件, 这种问题大多数是 Xcode 路径造成的.

使用下面的命令看一下系统指向的 Xcode 路径:

1
xcode-select -p

控制台输出:

1
/Library/Developer/CommandLineTools

显然不是 Xcode 的路径, 那只能重新切换一下其路径即指向正确的 Xcode 路径即可.

命令如下:

1
sudo xcode-select --switch /Applications/Xcode.app

再次编译 dumpdecrypted 即可成功完成.

对 dumpecrypted.dylib 签名

如果不对该文件进行签名, 后续砸壳的操作会失败.

先找到已经在电脑上面安装的苹果开发者证书, 操作如下:

1
2
## 列出可签名证书, 找到 mac 上面已经安装的证书
security find-identity -v -p codesigning

为 dumpecrypted.dylib 签名, 命令如下:

1
codesign --force --verify --verbose --sign "iPhone Developer: xxx xxxx (xxxxxxxxxx)" dumpdecrypted.dylib

其中, "iPhone Developer: xxx xxxx (xxxxxxxxxx)" 为你自己本机安装的开发者证书名称.

SSH 连接手机

使用 OpenSSH 让 Mac 和手机连接起来 这样可以很方便的在 Mac 终端使用 shell 命令来操作手机的目录了.

关于 OpenSSH 的使用请参考我之前的博文 iOS 逆向: 越狱使用 SSH.

查找目标 App 所在进程

  • 双击 Home 按键后, 手动杀掉 iPhone 上面所有在后台的 App.
  • Home 到手机桌面.
  • 打开目标 App 即WeChat, 这里称之为 TargetApp.
  • Home 到手机桌面.
  • 查看当前运行的所有进程, 命令如下:
1
ps -e

看到这个货:

在如下目录:

1
/var/containers/Bundle/Application/2837EC87-7C28-45C5-9309-24FACD3A97C9/WeChat.app/WeChat

WeChat.app 就是我们要找的 TargetApp.

连接 SSH 成功后, 在 MacOS 终端 ls 一下该目录, 可以发现 WeChat.app 躺在那里.

砸壳

1. 查找 Documents 目录

WeChat 为当前的进程目标执行文件名称, 从上面的图可以看出, 其对应的进程 id 是 18983.

在命令行中通过 cycript 执行如下操作:

1
cycript -p 18983

再执行 OC 的方法, 如下:

1
[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]

可以看到对应的输出, 如下图所示, 这就是对应的 Documents 目录.

注意: 执行过程中, 在 iPhone 上面打开运行一下 App, 不然上面的执行一直卡在那里不动.

找到目录如下:

1
/var/mobile/Containers/Data/Application/2EFA08B6-DD7B-41A6-92C9-C6115CA6DDA1/Documents/

同理, 你也可以使用 iFunBox 查看该目录.

2. 拷贝 dumpdecrypted.dylib.

拷贝 dumpdecrypted.dylib 这个之前编译签名好的文件到iPhone 上面该 APP 的 Documents 目录有两种方法.

第一种方法, 直接在 mac 上面拖拽 dumpdecrypted.dylib 到 iFunBox 显示的这个目录中, 这种方法比较简单且快.

第二种方法, 使用 scp 命令进行操作.

1
scp ~/dumpdecrypted.dylib root@192.168.99.231:/var/mobile/Containers/Data/Application/2EFA08B6-DD7B-41A6-92C9-C6115CA6DDA1/Documents/

192.168.99.231 是 iPhone 设备的 ip 地址.

3. 退出 cycript, 回到命令行模式

1
ctrl + d

4. cd 到 Documents 目录

1
cd /var/mobile/Containers/Data/Application/2EFA08B6-DD7B-41A6-92C9-C6115CA6DDA1/Documents/

5. 砸壳

终端在 Documents 目录下面, 执行下面命令即可:

1
DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/containers/Bundle/Application/2837EC87-7C28-45C5-9309-24FACD3A97C9/WeChat.app/WeChat

执行过程显示如下:

最后生成了 WeChat.decrypted 文件, 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
-rw-r--r--  1 root   mobile 74513728 Jun  7 15:20 WeChat.decrypted
drwxr-xr-x 14 mobile mobile 448 Jun 7 15:20 .
-rw-r--r-- 1 root mobile 207760 Jun 7 15:15 dumpdecrypted.dylib
-rw-r--r-- 1 mobile mobile 8 Jun 7 13:22 db.globalconfig
-rw-r--r-- 1 mobile mobile 15 Jun 7 11:35 SafeMode.dat
drwxr-xr-x 26 mobile mobile 832 Jun 7 11:35 MMappedKV
drwxr-xr-x 3 mobile mobile 96 Jun 7 11:35 CrashReport
-rw-r--r-- 1 mobile mobile 1011 Jun 7 11:35 LocalInfo.lst
drwxr-xr-x 5 mobile mobile 160 Jun 7 11:35 MemoryStat
drwxr-xr-x 6 mobile mobile 192 Jun 7 11:35 00000000000000000000000000000000
drwxr-xr-x 15 mobile mobile 480 Jun 5 13:43 MMResourceMgr
-rw-r--r-- 1 mobile mobile 592 Jun 5 13:43 heavy_user_id_mapping.dat
drwxr-xr-x 2 mobile mobile 64 Jun 5 10:07 OpenImResource

使用 iFunBox 或者 scp 命令将 WeChat.decrypted 文件导出到 mac 的任意目录即可.

后续会跟大家分享如何使用砸壳后的文件, 敬请期待.

越狱系列文章

基于 iOS10.3.1 进行的实践。

  • iOS 逆向: dumpdecrypted 砸壳记

  • iOS 逆向: 砸壳

  • iOS 逆向: 查看系统文件目录和结构

  • iOS 逆向: 越狱使用 SSH

  • dumpdecrypted 砸壳:导出头文件


总有一天,你一定会感激正在努力的自己~

iOS 逆向: 砸壳

发表于 2018-05-13 | 分类于 iOS |

最近在看人工智能相关的知识,无意中发现了一个巨牛的 人工智能教程,分享一下给大家。

教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点 这里 可以直接看教程。

简介

所谓的砸壳, 指的是将从 App Store 上面下载的 App 进行破解的过程. 从 App Store 上下载的 ipa 中的二进制文件是经过加密(加壳)的,需要通过破解才能让我们对其 为所欲为, 这里的破解就是通常所说的砸壳.

类似的, Android 应用(apk 文件)也有加壳操作, 如果想破解别人的 apk, 首先要进行砸壳操作.

准备工具

[1]. Clutch
[2]. iFunBox 或者 pp 助手
[3]. 越狱手机一台(本人iPhone6sPlus iOS10.3.x 系统).
[4]. 可以正常使用 SSH 功能.

如果你还没有安装上面提到的除 Clutch 之外的工具, 请先阅读 iOS 逆向: 查看系统文件目录和结构 这篇文章, 并安装对应的工具.

安装 Clutch

可以在 Github 获取 Clutch 源码, 然后自己在 MacOS 上面编译得到二进制文件.

也可以去直接下载已经编译好的 二进制包, 直接使用, 我是直接下载了已经编译好的二进制包的, 截止到写这篇文章为止, Clutch 版本为 2.0.4.

下载完成后, 我将其放到 ~/Downloads 目录下面了.

准备好越狱设备, 保证可以正常连接 wifi, 使用 scp 命令将 Clutch 二进制文件复制到设备的系统目录中, 命令如下:

1
scp ~/Downloads/Clutch root@192.168.91.126:/usr/bin

其中, 192.168.91.126 是我设备连接 wifi 后的 IP 地址.

复制成功后, 使用 iFunBox 可以看到 Clutch 静静地躺在那里.

你可以使用 iFunBox 或者 pp 助手, 直接将 ~/Downloads/Clutch 拖拽到 /usr/bin 目录.

Clutch 的基本使用

SSH 连接越狱设备, 开始使用 Clutch. 关于使用 SSH, 可以阅读一下 iOS 逆向: 越狱使用 SSH 这篇文章.

如果你发现直接执行 Clutch 说没有权限之类的提示, 可以先将其授予可执行的权限.

1
chmod +x /usr/bin/Clutch

Clutch 命令选项如下:

1
2
3
4
5
6
-b --binary-dump     Only dump binary files from specified bundleID
-d --dump Dump specified bundleID into .ipa file
-i --print-installed Print installed application
--clean Clean /var/tmp/clutch directory
--version Display version and exit
-? --help Display this help and exit

-b 选项表示产出一个二进制文件, -d 选项表示产出一个 ipa 文件, -i 表示列出手机上面已经安装的 APP.

我们先看一下手机上已经安装的 App, 命令如下:

1
Clutch -i

这些 APP 前面的数字表示指定的 id. -d 和 -b 选项都需要指定这些 id.

砸吧, 骚年

我们现在开始使用 Clutch 来对 APP 进行砸壳操作, 这里以已经安装的 App 序号为 8 的为例子.

使用下面的命令开始砸壳:

1
Clutch -d 8

效果如下图所示:

砸壳成功后会在 /private/var/mobile/Documents/Dumped 这个目录生成对应的 *.ipa 文件.

砸壳后的 ipa 文件, 可以从 iFunBox 中复制到 MacOS 的目录中, 然后你就可以对该 ipa 进行下一步操作了, 比如获取图片/音频/视频等资源和对应的头文件. 关于这些后续的越狱工作, 我会在下几篇博客中分享给大家.

也许有人会说了, 我自己从 pp 助手 中备份指定的 App 就可以获取资源了, 不需要使用 Clutch 这么麻烦了. 高系统版本, pp 助手 是无法直接获取 ipa 文件的, 况且我们也不仅仅是想获取别人 APP 的资源文件.

当然了, 你可以从越狱 APP 市场直接下载已经被砸壳的 App 进行玩耍, 不需要自己千辛万苦的去砸壳了.

Clutch 并不是万能的

上面大家可以看出, Clutch 是可以进行砸壳的并且也挺方便, 但 Clutch 并不是万能的, 也就是说, Clutch 不能将任意一个 App Store 下载 APP 进行砸壳.

拿上面序号为4 的微信来说, 执行下面命令报错:

1
Clutch -d 4

砸壳执行过程如下:

1
2
3
4
Writing new checksum
...
FAILED: <WeChat bundleID: com.tencent.xin>
Finished dumping com.tencent.xin in 28.7 seconds

还有一些 APP, 再被砸壳的时候会报如下的错误:

1
could not obtain mach port either the process is dead

虽然最新版本(2.0.4)说解决了该问题, 但是实际操作过程中, 还是会出现这个问题, 无法进行砸壳.

越狱系列文章

基于 iOS10.3.1 进行的实践。

  • iOS 逆向: dumpdecrypted 砸壳记

  • iOS 逆向: 砸壳

  • iOS 逆向: 查看系统文件目录和结构

  • iOS 逆向: 越狱使用 SSH

  • dumpdecrypted 砸壳:导出头文件


特别喜欢上善如水这句话,你呢?

iOS 逆向: 查看系统文件目录和结构

发表于 2018-05-13 | 分类于 iOS |

最近在看人工智能相关的知识,无意中发现了一个巨牛的 人工智能教程,分享一下给大家。

教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点 这里 可以直接看教程。

简介

在 iOS 逆向: 越狱使用 SSH 中给大家分享了如何使用工具对 iOS10.3 的系统进行越狱和配置使用 SSH 的内容, 今天继续探逆向的知识.

手机被越狱之后, 我们首先要搞清楚是否能够正常的访问手机里面的文件和目录结构, 这些文件和目录结构究竟是什么样的, 虽然这些知识很基础, 但是还是很有必要去了解和学习的, 就算是为后期逆向 APP 做点准备吧.

安装 iFunBox

iFunBox 是一个可以浏览 iPhone 文件目录的文件管理工具, 支持 MacOS 和 Windows 两个平台.

点击 下载地址 可以去下载 MacOS 版本的 iFunBox. 关于 iFunBox 的介绍和特性可以去 这里 查阅.

最新版本是 1.8, 如图:

手机插上 USB 连接上 Mac 电脑, iFunBox 就可以识别你的手机了, 如图所示:

这个时候, 你点击 Raw File System 其实是看不到 iPhone 的系统目录的, 接下来在 iPhone 中安装另外一个软件就可以了.

安装 Apple File Conduit 2

在 Cydia 中搜索 Apple File Conduit, 如下图所示.

点击更改/安装即可.

如果你没有搜索到, 那么就需要自己添加对应的软件源地址.

点击【软件源】–编辑/添加 –输入源地址 apt.25pp.com – 添加源, 然后再去搜索 Apple File Conduit 安装.

安装好之后, 再用 iFunBox, 就可以正常查看 iPhone 的系统目录了, 如下图所示:

看到这些目录, 是不是跟 linux 或者 MacOS 的目录有很多相似的地方, 哈哈.

安装 pp 助手

既然已经安装了 iFunBox 工具, 那为什么还需要安装 pp 助手 之类的工具呢? 其实, 这个看个人的需要吧, 在某种程度上, pp 助手 的界面和便捷性要比 iFunBox 好一点.

安装好 pp 助手 后, 点击 Tools/File Manager 显示的目录导航, 如图:

可以看出, 相比 iFunBox 的界面显示, pp 助手 工具显得更加友好一些.

至于使用哪个工具, 要看个人爱好和自己的工作需要, 毕竟工具都是为了提高我们学习和工作效率的, 没有什么绝对的好与坏, 自己觉得合适顺手就好了, 最主要的是能够帮到自己. 我一般是将两者结合使用的, 当然你如果你有更好的工具也可以推荐给我.

越狱系列文章

基于 iOS10.3.1 进行的实践。

  • iOS 逆向: dumpdecrypted 砸壳记

  • iOS 逆向: 砸壳

  • iOS 逆向: 查看系统文件目录和结构

  • iOS 逆向: 越狱使用 SSH

  • dumpdecrypted 砸壳:导出头文件


每一个关注,都会激励我继续前行

<1…111213…20>

193 日志
16 分类
163 标签
© 2024 veryitman