Damon

宏愿纵未了 奋斗总不太晚

0%

这篇主要是介绍 Facebook 的开源库 fishhook 的原理和源码实现,需要了解 Mach-O 的相关知识,最好先阅读 Mach-O 文件探索,两篇结合来看效果更佳。

使用

首先写一个 demo 来使用 fishhook,这个 demo 来 hook 系统函数 printf ,让它始终打印 damon

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#import <stdio.h>
#import "fishhook.h"

static int (*original_printf)(const char * __restrict, ...);

int new_printf(const char * __restrict s) {
original_printf("damon");
return 0;
}

int main(int argc, char * argv[]) {
struct rebinding printf_rebinding = {
"printf",
new_printf,
(void *)&original_printf
};
rebind_symbols((struct rebinding[1]){ printf_rebinding }, 1);
printf("123");
return 0;
}
阅读全文 »

简介

Mach-O 是Mach object的缩写,常见的Mach-O文件类型有目标文件、可执行文件、Dsym文件等。了解Mach-O文件的格式,对于静态分析、动态调试、自动化测试及安全都很有意义。可以使用可视化工具来查看 Mach-O 文件,推荐使用 MachOView 软件

文件结构

Mach-O主要由三部分组成,分别是 Header、Load Command、Data。

Mach-O 头部(Header)保存了CPU架构、大小端序、文件类型、加载命令数量等一些基本信息。Header的定义:

1
2
3
4
5
6
7
8
9
struct mach_header_64 {
uint32_t magic;
cpu_type_t cputype;
cpu_subtype_t cpusubtype;
uint32_t filetype;
uint32_t ncmds;
uint32_t flags;
uint32_t reserved;
}
  • magic:魔数,用于标识当前设备是大端还是小端,iOS是小端序。对于64位架构的程序,它被定义为常量 MH_MAGIC_64,值为 0xfeedfacf
  • cputype: 标识 CPU 的架构,如ARM、ARM64、X86_64等。
  • cpusubtype: 标识具体的CPU类型,区别不同版本处理器
  • filetype: 表示 Mach-O 的文件类型,如可执行文件、动态库文件、符号文件等
  • ncmds: Load Commands(加载命令)的数量
  • flags: 标志信息,例如是否启动 ASLR
  • reserved: 保留字段
阅读全文 »

TCP是一个面向连接可靠的基于字节流传输层通信协议,负责建立、维护、管理端到端连接。

TCP 数据格式

  1. Source Port / Destination Port:源端口和目标端口,分别用16位来存储。tcp头没有ip地址,这是网络层做的事情。
  2. Sequence Number:序列号,占16位,用来解决网络包乱序问题。假如一个报文段的序号是500,而数据有20个字节,这就表明这个报文段的第一个字节序号是500,最后一个字节的序号是519,下一个报文段的序号要从520开始。如果溢出了就回到0。
  3. Acknowledgement Number:确认号,占16位,用来表示期望收到下一个报文段的第一个字节的序号,用来解决丢包的问题。假如A给B发数据,序列号是500,长度为20个字节(500 ~ 519),如果B都收到了这20个字节,就会在发给A的报文段中确认号为520,表明下一个序号应该是520
  4. Offset:数据偏移,占4为位,表示 TCP 报文首部信息的长度,因为 TCP 首部可能会有选项内容,所以这个长度是不确定的。看图片右边的箭头就知道了,没有选项字段的话,TCP头部长度为20字节。
    阅读全文 »

MJRefresh 是一个功能强大的 iOS 上拉下拉刷新组件。有很多大厂App(抖音、快手、京东、喜马拉雅等)都在使用,所以是一个很值得学习的库。

原理

先简单说明上拉下拉刷新的原理再去详细分析 MJRefresh 框架结构以及具体实现。

header/footer的位置

首先 header/footer 是添加到 UIScrollView 上的,是它的子控件,比如 header 的高度是40,那么它的y值就是 -40 ,footer的y值就是 contentSizeHeight

下拉/上拉悬停

上拉或者下拉到一定程度,松手后就会进入刷新状态,这时候 header/footer 都在显示在可见范围悬停,这是通过设置 UIScrollView 的 contentInset.topcontentInset.bottom 来实现,刷新结束后,再重置回来。

设计

上面介绍了一些上拉下拉的原理,其实很简单, 接下去具体看一下 MJRefresh 是如何做的。

结构设计

MJRefreshComponent 是header和footer 的基类,实际都是使用最后一层的类。接下来具体看每个类的具体职责和实现。

阅读全文 »

开始之前,假设你已经有Django和Django REST framework的一些基础了

mixins,ViewSet和routers配合使用

minxis的类有5种

  • CreateModelMixin
  • ListModelMixin
  • RetrieveModelMixin
  • UpdateModelMixin
  • DestroyModelMixin

他们分别对应了对数据库的增查改删操作,使用它们的好处是不用重复写着相同的业务代码逻辑,因为每个mixins内部都写好了对应的逻辑,只需要设置一下querysetserializer_class就可以了.

ViewSet也有5种,分别是

  • ViewSetMixin
  • ViewSet
  • GenericViewSet
  • ReadOnlyModelViewSet
  • ModelViewSet
阅读全文 »

如果对闭包不了解的同学请移步到这里先, 因为装饰器要通过闭包来实现

前言

刚开始学Python的时候,装饰器(decorator)一直是个让人难以理解的东西,所以想通过这篇文章能够带你一步一步来理解Python装饰器的原理

什么是装饰器?

经典的设计模式有23种,设计模式其实也就是巨人们常年写代码经验的思想总结,虽然说这是一种思想,但是由于语法的限制没有办法轻易实现(比如说用C语言来实现组合模式).在面向对象的设计模式中, decorator被称为装饰模式,OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator。

下面开始介绍装饰器的原理

阅读全文 »

Python基础

Python中,函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。
例如:

1
2
3
4
5
def now():
print('2017-11-06')

f = now
f() # 打印 2017-11-06

理解什么是闭包?

Python 中,闭包的概念是:
1.首先是个嵌套函数
2.内层函数使用了外层函数的变量或者参数
3.外层函数把内层函数当做返回值进行返回

一段简单的闭包代码示例

1
2
3
4
5
6
7
8
9
10
11
12
def func_outer(): # 外部函数

temp = 666 # 外部函数的变量

def func_inner(): # 嵌套的内部函数
print(temp) # 使用了外部函数的变量

return func_inner # 返回内部函数


test = func_outer()
test() # 打印666

由以上可以看出,test变量其实就是返回的func_innter函数对象,test()就是通过这个变量来调用func_innter函数.

阅读全文 »

在阅读之前,希望先了解 NSURLSession 的使用和 HTTP/HTTPS 的基础知识。

AFNetworking 的结构:

  • Manager(网络通信,处理网络请求)
    • AFHTTPSessionManger 和外界交互的,本身并没有做什么事情,AFURLSessionManager 的子类
    • AFURLSessionManager 主要的实现逻辑是在这个类
  • Serialization(网络消息的序列化和反序列化)
  • Security(网络安全、https)
  • Reachability (网络状态监听)
阅读全文 »

UICollectionView的简单介绍

在iOS6发布前,开发人员都习惯用UITableView来展示所有类型的数据集合。虽然苹果公司在照片应用中使用过很长一段时间类似UICollectionView视图的UI,但第三方开发人员无法使用它。当时我们可以利用第三方框架(如three20)来做类似的功能。在iOS6苹果引入了一个新的控制器UICollectionViewController。提供了一个更加优雅的方法,把各种类型的数据显示在视图中。
现在, 在各种类型的APP中,UICollectionView的身影随处可见,不管在什么应用,总有UICollectionView的应用场景,而苹果也在iOS10中对UICollectionView做了更好的优化。本文主要是展示UICollectionView的常用动画和装逼动画,也会在本文对所有的动画进行详细的讲解。先看效果

效果1:

效果2 : 圆形放大

效果3 :

效果4:

阅读全文 »

什么是runtime?

简单来说,runtime就是一个C语言库,包含了很多底层C语言的API。Objective-C语言是一门动态语言,我们平时变编写的Objective-C代码,在程序运行时,最终都是转成了runtimeC语言代码。所以,只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法。

利用runtime能做什么?

利用runtime机制让我们可以在程序运行时动态修改类对象、对象中的所有属性、方法,就算是私有方法以及私有属性都是可以动态修改的。KVO的底层实现就是利用runtime来实现的

类和对象基本数据结构

首先,我们来认识一下classesobjects的概念。我们都知道,Objects是由Classes生成,但是在Objective-C中,Classes本身也是objects,也能处理消息,这也就是为什么有类方法和实例方法。

阅读全文 »