2023腾讯游戏安全比赛总结
结果决赛最终是拿到了安卓方向第四名。获得了1500q币和腾讯的面试绿色通道
过程获奖是用电话通知的,当天刚好公司给团建费,leader带我们去吃饭。全程也没咋看手机一直在聊天吃饭,手机因为习惯也开着是静音,吃完准备走人的时候看了一眼手机才发现,20分钟前有个腾讯的未接来电。当时就有种预感了,问了一下赛事负责人,那边重新又打了一遍电话,我才意识到,卧槽,真拿奖了。告知了名次是第四,问了实习意向。不记得当时啥感觉了,和做梦一样。
讲实话,我做的时候完全不觉得自己会拿奖。首先是去年前三都在,还见到好几个打ctf的时候见到过的很厉害的师傅。学安卓还不到一年,这架势直接给看傻了。决赛拿到题的时候发现和初赛是一个模板,以为又是虚拟机分析,用frida尝试hook后发现有反调试需要绕过,心直接凉了半截——初赛的反调试我都没完全绕过,决赛的咋整。
想着不管会不会都做三天,实在没结果之后面试也有东西说。于是真的就在电脑前坐了三天逆了三天,啥别的没干。本身是要去参加广东省省赛,我也直接拒掉了,这里还是有点对不起二队的大哥们,因为决赛分刚好和前一名差5分,前进一名就是一等奖,如果我在的话应该是有可能一等 ...
idapython函数学习笔记
idapython函数学习笔记记录一波idapython的学习,加深印象,之后找起来也方便。
长期更新
ida_bytespatch_byte(一次patch一个byte)第一个参数是起始地址,第二个参数是用什么进行填充。
next_head(参数的下个指令的地址)一个参数
到达参数的下个指令的地址。用来从一个指令步入下一个指令,而不是单纯的前进一个字节。
print_insn_mnem(返回指令)一个参数
返回参数地址的指令。比如当前指令是mov a1,1,调用这个函数就会返回mov。
print_operand(返回对应操作数的字符串)返回该地址的汇编指令的操作数的字符串,并用列表存储。
比如当前地址是mov eax,1,返回的列表的元素从小到大分别是eax,1(都是字符串形式!)
idcwait_for_next_exent(等待下个事件)1234567891011r""" wait_for_next_event(wfne, timeout) -> dbg_event_code_t Wait for the next event. ...
c++ STL函数分析
看完R1mao大佬的文章后的拙劣复现与分析,本文基本上都是复制R1mao大佬的,少部分是自己分析,可以支持一下R1mao大佬
https://bbs.kanxue.com/thread-275133.htm
准备找时间把所有常用的stl全部研究一遍,所以应该也是长期更新,有时间就搞
deque基础知识概论deque(双端队列)是由一段一段的定量连续空间构成,可以向两端发展,因此不论在尾部或头部安插元素都十分迅速。 在中间部分安插元素则比较费时,因为必须移动其它元素。
定义使用之前必须加相应容器的头文件:
1#include <deque> // deque属于std命名域的,因此需要通过命名限定,例如using std::deque;
定义的实现代码如下:
12345deque<int> a; // 定义一个int类型的双端队列adeque<int> a(10); // 定义一个int类型的双端队列a,并设置初始大小为10deque<int> a(10, 1); // 定义一个int类型的双端队列a,并设置初始大小为10且初始值都为1d ...
程序员的自我修养阅读笔记-动态链接
前前后后看了俩遍了,但是总感觉过一会就会忘,于是决定重要的部分写个博客加深记忆。因为基本是以自己的话来解释,如果文章描述又不对的地方请读者斧正。长期更新,直到写完为止。
动态链接为什么要动态链接内存和磁盘空间静态链接占用的内存太多了,十分浪费空间。因为我们知道,静态链接会在预编译的时候将#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设置了,除了通过截断,符号扩展,或零扩 ...