程序员的自我修养阅读笔记-动态链接
前前后后看了俩遍了,但是总感觉过一会就会忘,于是决定重要的部分写个博客加深记忆。因为基本是以自己的话来解释,如果文章描述又不对的地方请读者斧正。长期更新,直到写完为止。
动态链接为什么要动态链接内存和磁盘空间静态链接占用的内存太多了,十分浪费空间。因为我们知道,静态链接会在预编译的时候将#include后跟着的文件名对应的文件进行填充。假设所有库都是静态库,一个计算机的很多进程都会用到相同的库,如果100个进程都用这个静态库,那内存里就会有100个该静态库的副本(在对应进程里),实在是比较浪费空间。
程序开发和发布如果更新的是静态链接的库,那整个项目都得重新链接一遍,这在项目代码量和复杂度很大的情况下是难以想象的,无论是时间还是性能要求方面。
动态链接动态链接是运行时链接,假设a进程运行,运行时会根据依赖关系首先找对应的.o文件,随后加载到内存,如果所有依赖的文件都有才会进行链接的操作,和静态的链接基本相同。而如果另一个进程也用到了a进程所用到的动态链接库,不需要再生成一个对应的库的副本,因为该库已经加载到内存中,直接取用即可。程序开发同理,只需要下载更新的库替换旧库,运行时会调用,省 ...
PEB_TEB-滴水逆向观看笔记
TEB,PEB结构分析PEB,全名Process eviroment block,进程环境块。
NT内核系统之中,fs寄存器指向TEB结构,TEB+0x30指向PEB结构,PEB+0x0c指向PEB_LDR_DATA结构,PEB_LDR_DATA+0x1c处存放一些指向动态链接库的链表地址,win7下第一个指向ntdll.dll,第三个kernel32.dll
TEB结构1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374typedef struct _TEB{NT_TIB Tib; /* 00h */PVOID EnvironmentPointer; /* 1Ch */CLIENT_ID Cid; /* 20h */PVOID ActiveRpcHandle; /* 28h */PVOID ThreadLocalStoragePointer; /* 2 ...
保护模式-滴水逆向观看笔记
保护模式简介x86cpu一共三种模式,实模式,保护模式,虚拟8086模式
特点
段机制
页机制
段寄存器是什么比如
mov dword ptr ds:[0x12345678],5
就是ds段寄存器作为base,偏移0x12345678的位置
一共有ES CS SS DS FS GS LDTR TR共8个
结构
selecter是可见部分
attribute是属性部分,可读可写可执行
base是基址
limit是总长度多少
可以通过mov指令对段寄存器进行读写(除了LDTR,TR)
成员简介
GDT和LDTGDT是全局描述符表,LDT是局部描述符表
我们执行mov ds,ax等指令时,CPU会查表,根据AX的值决定查找GDT或者LDT
段描述符
段选择子
加载段描述符到段寄存器
这里十分有意思,用到了fword,也就是6个字节,而这里用到的是les指令,所以这里高俩直接给es,低四个字节给dst的寄存器ecx。
段描述符成员介绍p位p=1代表段描述符有效,p=0代表段描述符无效
g位当g位为零的时候,limit最大0xfffff,也就是20位。g位为1时最大0x ...
APC队列-滴水逆向观看笔记
APC队列主要结构体KAPC
其中:
类型是当前这个结构体对应的类型,比如线程,中断之类的
大小就是整个结构体的大小
目标线程,因为每个线程都有自己对应的apc双向链表,所以用这个来指定对应的线程
挂的位置是apc队列里的下标
KernelRoutine,就是指向一个ExFreePoolWithTag,用来释放APC函数的内存的
NormalRoutine 在用户层,指向的就是用户APC的总入口;在内核层,就是指向内核的APC函数的地址、
NormalContext 内核中的话是空,用户中的话是真正的APC函数。
ApcStateIndex 挂哪个队列,之后重点讲
ApcMode是内核或用户的apc
Inserted指是否插入队列
KeInitializeApc
作用是分配空间,初始化KAPC结构体
第一个参数是KAPC指针,3环调用中上一个函数NtQueueApcThread就是分配了一个KAPC的空间,但是未初始化,然后传给我们这个函数来进行初始化
目标线程会挂到KAPC里的当前线程那儿
第三个是挂到哪儿
第四个是销毁KAPC的函数地址,和KAPC里的KernelRouti ...
Hook-滴水逆向观看笔记
HookSSTD Hook系统服务表 SystemServiceTable
如何访问系统服务表
SSDT有四个成员,每个成员16字节,一般后三个成员是空的,而第一个成员就是系统服务表
第一个4字节存储的是存储内核函数的一段内存的基址,第三个4字节存储的是存储内核函数的个数,第四个是内核函数参数的个数,注意第四个参数是byte数组
得到函数表地址
上面那个是系统服务表的结构体,下面是SSDT的结构体
通过页表基址修改页属性
通过修改CR0寄存器
ssdt hook是比较低级的hook,十分容易被发现。
inline hookSSDT Hook的缺点
容易发现,容易绕过
只能hook系统服务表里有的函数
位置选择
地址的计算
code是jmp的二进制编码的后面几位的值
多核同步之临界区前置知识
演示
LOCK
Lock指令可以保证一行汇编指令的原子性,也就是如果多个核同时执行这个汇编指令的话,结果不会是只执行了一次,而是他会先让一个核执行,然后再给其他核进行执行,依次类推。
多行代码原子操作
临界区
不过这串代码是有问题的。如果一个线程进入if,还没来得及修改dwFlag,另一个 ...
c++异常处理学习笔记
由于打ctf的时候经常看见异常处理的题目,虽然知道流程但是原理还是不是很理解,也不会写,所以准备学一下。记录一下本人的学习过程,如有错误,希望各位大佬能指正。
概述异常是程序在执行期间产生的问题。C++ 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。
触发异常后,如果有对应的异常处理就会跳到异常处理去执行,相当于是编写代码的人针对会发生的错误的解决方案。如果没有异常处理或者异常处理程序未成功处理异常,程序就会退出。具体可以看加密与解密的seh异常处理部分。
SEH异常处理简述有关数据结构TIB,TEBTIB(Thread Information Block 线程信息块) 是保存线程基本信息的数据结构,user mode下位于TEB(Thread Enviroment Block线程环境块)的头部,TEB是操作系统为了保存每个线程的私有数据而创建的,所以每个线程都有TEB。
TIB结构如下
x86平台的user mode上,fs:[0]总是指向TEB,可以通过这个来定位。(x64平台上是gs:[0]指向TEB)
_EXCEPTION_REGISTRATION_RECORDT ...
llvm常见函数收集
数据类型ConstantInt(整形常量和布尔常量共用)1This class represents both boolean and integral constants.
APINT(无符号数类型)是”unsigned”, “unsigned long” 或者 “uint64_t”的替代,不过功能更加强大,可以支持不同bit wise的数
1APInt provides a variety of arithmetic operators and methods to manipulate integer values of any bit-width. It supports both the typical integer arithmetic and comparison operations as well as bitwise manipulation.
1APInt c = val->getValue() - (randA * randX + randB * randY);
需要注意
未初始化时是0
一旦bit width设置了,除了通过截断,符号扩展,或零扩 ...
objection源码分析记录
对神器objection的分析,学习一下frida的代码写法和大佬的思路
下方的大标题是objection的目录信息
androidliblibjava.tswarpJavaPerform(包装perform)123456789101112131415// all Java calls need to be wrapped in a Java.perform().// this helper just wraps that into a Promise that the// rpc export will sniff and resolve before returning// the result when its ready.export const wrapJavaPerform = (fn: any): Promise<any> => { return new Promise((resolve, reject) => { Java.perform(() => { try { r ...
MAS CRACKME3 分析笔记
第一印象首先拖进gda,看了一下,发现了四个甚至三个检测root
眼前一黑
随后看了一下native
可以看到是一个简单的异或然后比较,异或的key大概是主函数里的放到init的native里初始化的pizza(我去,pizza)
不过这里的异或还有一个数组是未知的,而这个数组它是由一个函数进行初始化的。混淆过的函数
感觉就是直接步过这个函数然后看数组值就行。
同时这里也有和level2一样的native反调试
直接用level2代码把exit hook了就差不多过了
个人想法是,java层把那几个checkroot全hook了,返回值恒等于true,然后native直接ida 动态调试提取数组就可以解了。
但是没做,直接看答案了,因为不知道那个类的是不是可以直接hook
看wp后分析主函数有个verifyLibs,完全没看到(寄
里面是对davlik字节码的检测和native代码的检测,用的是crc32
由于整个都是检测,直接pass掉就行,改dailvk代码即可
root检测总代码12345678910111213141516171819202122232425 ...
游戏安全-手游安全技术入门 阅读笔记
第一章静态修改文件游戏文件被静态修改并重新打包,签名
静态修改游戏资源修改游戏的资源文件,达到改变游戏逻辑或者塞入一些不健康信息的目的。
静态修改游戏代码一般手游都是用c++编写,通过编译后的游戏主逻辑的代码一般都用动态链接库保存。修改较多的是代码段和只读数据段,只读数据段的话存的一般是固定的一系列数据,一般是某些固定的参数。代码段自不用说。
修改配置和修改资源差不多,一般配置文件打包的时候都是加密的,但是一些游戏还是不加密,这样很容易达到篡改的目的。
动态篡改逻辑常规的动态篡改逻辑都会伴随着注入的操作,注入就是将动态链接库加载至目标进程,让目标进程执行动态链接库的代码,实现篡改逻辑
android平台的注入一般分为两种,一种是通过Zygote进程(xposed)渗透到目标进程之中,另一种是直接注入到目标进程之中。
IOS平台一般用MobileSubStrate组件将动态链接库注入游戏进程。
修改数据安卓可以通过”/proc/<pid>/maps”文件遍历有r标识的模块,然后读写”/proc/<pid>/ ...