- 博客(128)
- 资源 (3)
- 收藏
- 关注
原创 【2023.10.24】使用 ObRegisterCallBack 对CE进行提权
ustrAltitude找个ARK工具比如pchunter看一下反作弊挂的钩子层级是多少,比它低就行。需要注意 g_PromotePid 以及 ustrAltitude 这两处需要修改一下。
2023-10-24 16:41:26
428
原创 UE4逆向篇-2_各类数据的查找方式
1.通过前面的文章,相信各位已经能够自己找到GNames并使用DUMP工具导出GNames了。2.本篇文章将介绍各种所需数据的查找方法。
2023-10-20 17:15:50
4567
3
原创 UE4逆向篇-1_FNamePool
1.GNames 指的是 alignas(FNamePool) static uint82.也就是。3.它是一个数组结构。
2023-10-19 19:39:14
3874
原创 【2021.04.27】API函数的调用过程(保存现场)
内容回顾前文提到了API进入0环以后会调用的函数:KiSystemService()、KiFastCallEntry()。前文的练习进入0环后,原来的寄存器存在哪里? 如何根据系统调用号(EAX寄存器中储存)找到要执行的内核函数? 调用时的参数是储存到3环的堆栈,如何传递给内核函数? 2种调用方式入口(KiSystemService()、KiFastCallEntry())是不一样的,它们是如何返回到3环的?进入0环后,原来的寄存器存在哪里?本文将以KiSystemService(
2021-04-27 21:20:43
837
原创 【2021.04.26】API函数的调用过程(Ring3进Ring0):下
内容回顾在前文讲到,如果CPU支持sysenter/sysexit指令,那么API调用时,会通过sysenter指令进入0环,如果不支持sysenter指令,就会通过中断门进入0环。默认的中断号:0x2E(IDT表)。INT 0x2E进Ring0在IDT表中找到0x2E号的门描述符。 分析CS/SS/ESP/EIP的来源。 分析EIP是什么。首先来看一下IDT表:当通过中断门进入0环的时候,对应的就是 804dee00`0008f631,它具体对应哪个门呢?IDT存储了3种门,
2021-04-26 20:37:53
664
原创 【2021.04.26】API函数的调用过程(Ring3进Ring0):上
内容回顾kernel32.dll(ReadProcessMemory)->ntdll.dll(NtReadVirtualMemory)mov eax, 0BA //提供一个内核函数编号mov edx, 7FFE0300 //然后提供一个函数的地址,这个函数地址存储在7FFE0300这个位置。本文将重点介绍该函数到底是什么,要了解该函数到底是什么还需要弄清楚7FFE0000这块内存有什么特殊含义。_KUSER_SHARED_DATA在user层和kernel层分别定义了一个.
2021-04-26 19:19:57
738
原创 【2021.04.25】API函数的调用过程(Ring3)
WindowsAPIApplication Programming Interface,简称API函数。 Windows有多少个API?主要是存放在 C:\WINDOWS\System32 文件夹下所有的dll。 几个重要的DLL如下:Kernel32.dll:最核心的功能模块,比如管理内存、进程和线程相关的函数等。 User32.dll:是Windows用户界面相关应用程序接口,如创建窗口和发送消息等。 GDI32.dll:全称是Graphical Device Interface(图形设备
2021-04-25 22:21:53
316
原创 【2021.04.25】保护模式阶段测试
关于保护模式的更多细节可以参考Intel白皮书,从第3章到第11章,不同版本可能章节顺序不一样,请参考章节标题。保护模式阶段测试给定一个线性地址,和长度,读取内容。int ReadMemory(OUT BYTE* buffer, IN DWORD dwAddr, IN DWORD dwLeght)要求:可以自己指定分页方式。 页不存在,要提示,不能报错。 可以正确读取数据。申请长度为100的DWORD的数组,且每项用该项的地址初始化。把这个数组所在的物理页挂到0x1
2021-04-25 16:59:41
227
原创 【2021.04.25】PDE、PTE属性:PWT、PCD
CPU缓存CPU缓存是位于CPU与物理内存之间的临时储存器,它的容量比内存小的多,但是交换速度却比内存要快得多。 CPU缓存可以做的很大,有几KB、几十KB、几百KB甚至达到MB的都有。CPU缓存与TLB的区别:TLB:线性地址<----->物理地址 缓存了线性地址和物理地址的对应关系,当再次读取数据的时候就不需要每次都做解析,只需要去查TLB表即可。 CPU缓存:物理地址<----->内容 当CPU在读取某个物理页的时候,可以先查TLB找到物理地址,再查CPU缓存找
2021-04-25 16:40:24
487
原创 【2021.04.04】控制寄存器
控制寄存器控制寄存器用于控制和确定CPU的操作模式。CR0、CR1、CR2、CR3、CR4CR1:保留CR3:页目录表基址,其在10-10-12和2-9-9-12分页形式中是不一样的。CR0寄存器PE:CR0的位0是启用保护(Protection Enable)标志。PE=1:保护模式、PE=0:实模式。这个标志仅开启段级保护,而并没有启用分页机制。若要启用分页机制,那么PE和PG标志都要置位。PG:当设置该位时,即开启了分页机制。在开启这个标志之前必须已经或者同时
2021-04-04 19:57:59
892
原创 【2021.04.04】TLB(Translation Lookaside Buffer)
TLB(Translation Lookaside Buffer)是什么?通过一个线性地址访问一个物理页。比如:一个DWORD,其实未必真正读取的是4个字节。先读取的PDE再读取PTE,最后才读取的4个字节的页。 在2-9-9-12分页中会读取24个字节,如果跨页,可能会读取的更多。为了提高效率,只能做记录。 CPU内部做了一个表,来记录这些东西,这个表格是存储在CPU内部的,它的读写速度和寄存器一样快,TLB(Translation Lookaside Buffer)。TLB结构LA(线性
2021-04-04 18:22:20
316
原创 【2021.04.03】中断与异常
什么是中断中断通常是由CPU外部的输入输出设备(硬件)所触发的,供外部设备通知CPU "有事情需要处理",因此又叫做中断请求(Interrupt Request)。 中断请求的目的是希望CPU暂时停止执行当前正在执行的程序,转去执行中断请求所对应的中断处理例程(中断处理程序在哪里由IDT(中断描述符表)决定)。 80x86由两条中断请求线:非屏蔽中断线,称为NMI(NonMaskable Interrupt) 可屏蔽中断线,称为INTR(Interrupt Require)非可屏蔽中断如何处理
2021-04-03 22:04:37
853
原创 【2021.04.02】分页:2-9-9-12
要点回顾前文中已经讲解了10-10-12分页形式,在这种分页方式下,物理地址最多可以达到4GB。但是随着硬件发展,4GB的物理地址范围已经无法满足要求,Intel在1996年就已经意识到这个问题了,所以设计了全新的分页方式。也就是接下来将要讲解的2-9-9-12分页形式,又称为PAE(物理地址扩展)分页。为什么是10-10-12先确定了页的大小 4KB,所以后面的12位的功能就确定了。 当初的物理内存比较小,所以4个字节的PTE就够了,加上页的尺寸是4KB,所以一个页能储存1024个
2021-04-02 21:53:52
882
原创 【2021.03.31】页表基址
要点回顾前文提到了也目标基址,也就是说通过0xC0300000这个线性地址可以访问页目录表(PDT),有了这个地址,就可以任意修改页目录表。但是,如果要设置某个线性地址PDE和PTE,且还要能够访问PTT,该如何访问呢?任何一个线性地址是由PDT和PTE决定的。能访问PDT就说明能访问任意一个线性地址的PDE,但如果仅仅能访问PDE的话,还没有办法控制任意一个线性地址。也就是说还需要访问页表(PTT),那么该怎么访问PTT呢?如果没有一个线性地址能访问PTT的话,就没有意义,那么操作系
2021-03-31 21:34:54
916
原创 【2021.03.31】页目录表基址
要点回顾在前文中提到,如果系统要保证某个线性地址是有效的,那么必须为其填充正确的PDE与PTE。如果想填充PDE与PTE,那么必须能够访问PDT与PTT。这样就存在两个问题:一定已经有 "人" 为我们访问PDT与PTT挂好了PDE与PTE,我们只要找到这个线性地址就可以。 这个位我们挂好PDE与PTE的 "人" 是谁?页目录表基址(XP系统 10-10-12分页模式)页目录表基址:0xC0300000。拆分0xC03000001.!process 0 02
2021-03-31 20:35:41
643
原创 【2021.03.31】PDE、PTE属性:US、PS、A、D
要点回顾物理页的属性 = PDE属性 &(与运算) PTE属性U/S位U/S = 0:该物理页只允许特权用户访问。U/S = 1:该物理页普通用户也可以访问。实验修改一个高2G线性地址的PDE/PTE属性,实现R3可读,比如:0x8003F00C。#include "stdafx.h"#include <windows.h>int main(int argc, char* argv[]){ PDWORD p = (PDWORD)0x800
2021-03-31 20:05:10
518
原创 【2021.03.26】PDE、PTE属性:P、RW
要点回顾通过前文简单了解了PDE、PTE,本文来了解一下PDE、PTE的属性。物理页的属性物理页的属性 = PDE属性 &(与运算) PTE属性通过前文的实验可以发现,PDE与PTE的后12位,也就是二进制的低12位,是属性。其中存储的内容代表着属性。PDE与PTE的后12位有很多是重叠的,属性类型都是一样的,只有一部分不一样。P位线性地址0为什么不能访问?没有指定物理页。指定物理页就一定能访问?看PDE与PTE的P位,P = 1,才是有效的物理页。如地址0,
2021-03-26 22:01:17
884
原创 【2021.03.26】PDE、PTE
要点回顾前文简单了解了80x86的 10-10-12 分页机制,本篇文章继续学习。PDE与PTECR3:唯一一个存储物理地址的寄存器。在Windows中,页大小是4KB。在后期会接触到另一种页,有4MB大小,称为大页。CR3里面存储的地址,指向的是页目录表(PDT),表中每个成员称为PDE(页目录表项/页目录项)。页目录表(PDT)中每个成员(PDE)又指向另一张表,该表称为页表(PTT)。页表(PTT)的大小与页目录表(PDT)一样是4KB,其中存储的成员有1024个,每
2021-03-26 21:14:59
1841
原创 【2021.03.26】分页:10-10-12
要点回顾前文主要讲解段的机制,其实段的机制还有很多细节,需要在实验的过程中详细总结。从本文开始,开始进入页的机制的学习。4GB内存空间每个进程都有自己的4GB的内存空间,如果开启两个进程那么就是2x4=8GB。那么当前计算机的内存条是多少呢?可能是4GB,或者更少。那么这样就会有一个问题,内存不够,明显是不正常的。也就是说,每个进程都有4GB的内存空间的时候,进程的4GB空间是不是真实存在的?每个进程的4GB进程空间是假的,并不存在的。操作系统为每个进程分配了4GB的虚假内存
2021-03-26 18:34:54
521
原创 【2021.03.24】任务门
要点回顾前文中讲解了如何通过CALL、JMP指令访问任务段。本文主要介绍如何通过任务门访问任务段。既然已经可以通过JMP、CALL访问任务段了,那么为什么还要有任务门呢?IDT(中断描述符表)IDT表可以包含3种门描述符:任务门描述符。 中断门描述符。 陷阱门描述符。任务门描述符注意:TYPE位现在应该是5(任务门)。前文提过,当为9或B的时候代表什么。低4字节16-31位存储的是一个TSS段的描述符选择子。既不是地址也不是偏移,而是TSS段的描述符。任
2021-03-24 23:50:17
632
原创 【2021.03.24】任务段:下
要点回顾前文提到,TSS、TSS段描述符以及TR段寄存器。 TSS是一块内存,大小104字节。通过TSS可以同时替换"一堆"寄存器,包括通用寄存器和段寄存器等。 CPU通过TR段寄存器来找到TSS。如果想用自己的TSS段描述符来替换原来的寄存器,就需要修改TR段寄存器,TR段寄存器的值又是来自TSS段描述符。 TR段寄存器的BASE指向了TSS(也就是这104个字节)在哪里,TR.LIMIT指定了当前的TSS的大小。 TR段寄存器的值又是从GDT表加载的,GDT表中存储了某个所谓的TSS段描述符
2021-03-24 23:16:00
301
原创 【2021.03.23】任务段:上
要点回顾在调用门、中断门与陷阱门中,一旦出现权限切换,就会有堆栈的切换。同时,由于CS的CPL发生改变,导致了SS也必须切换。 切换时,会有新的ESP和SS(CS是由中断门或调用门指定),这两个值从哪里来的呢? 答案是TSS(Task-state segment),任务状态段。TSS的结构TSS是一块内存,大小104字节,存储的是一堆寄存器的值。TSS的作用Intel的设计思想:在操作系统运行的时候,进行任务的切换。Intel提到的任务对应的是操作系统的线程。它在CPU层面叫任务,
2021-03-23 20:16:09
278
原创 【2021.03.23】陷阱门
要点回顾IDT表可以包含3种门描述符:任务门描述符。 中断门描述符。 陷阱门描述符。陷阱门描述符陷阱门与中断门的区别中断门执行时,会将IF位清零,但陷阱门不会。如果IF位为0,意味着不再接收可屏蔽中断。IF位:eflag寄存器下标为9的位置。中断分为可屏蔽中断、不可屏蔽中断。是在硬件上的概念。可屏蔽中断如程序正在执行,突然按下键盘快捷键锁定屏幕,程序还没执行完就通过快捷键锁定了屏幕,而CPU是如何知道的? 虽然程序在运行,但是按下键盘的时候CPU可以感觉到,就是通过
2021-03-23 19:14:11
196
原创 【2021.03.23】中断门
要点回顾Windows系统没有使用调用门,但是使用了中断门。系统调用:当在开发应用层程序的时候,使用的API在执行过程中通过3环进入0环,这个过程就是系统调用。而从3环是如何进入0环的过程,就使用到了中断门。需要注意的是,老的CPU是通过中断门进入的0环,而现在的CPU都是通过快速调用。 调试:例如OD使用F2下断点,下断点其实就是把某个字节修改为了0xCC,0xCC硬编码对应的汇编指令就是INT3,INT3就是用来执行中断门的。IDTIDT即中断描述符表,其中存储的是系统段描述符。同GDT
2021-03-23 18:46:09
262
原创 【2021.03.21】调用门:下
要点回顾前文提到了调用门的执行过程,那么本篇文章就一起来了解一下:调用门的参数传递。代码回顾void __declspec(naked) GetRegister(){ __asm { pushad pushfd mov eax,0x8003f00c //读取高2G内存 mov ebx,[eax] mov dwH2GValue,ebx sgdt GDT;
2021-03-21 22:10:34
675
原创 【2021.03.19】调用门:上
要点回顾前文提到 CALL FAR 指令,该指令的格式如下:CALL CS:EIP(EIP是废弃的)调用门指令格式:CALL CS:EIP(EIP是废弃的)执行步骤根据CS段寄存器中储存的段选择子查询GDT表,找到对应的段描述符,这个段描述符是一个调用门(也就是说是一个系统段描述符)。 在调用门描述符中储存了另一个代码段的段选择子。 段选择子指向的段:段.BASE + 偏移地址,就是真正要执行的地址。门描述符如果是一个门描述符,它的结构如下:首先S位,必须为0。只
2021-03-19 23:11:07
618
原创 【2021.03.19】长调用与短调用
要点回顾通过前文知道JMP FAR可以实现段间跳转,如果要实现跨段的调用就必须要学习CALL FAR,也就是长调用。 CALL FAR 比 JMP FAR 要复杂,JMP并不影响堆栈,而CALL指令会影响。短调用指令格式:CALL 立即数/寄存器/内存发生改变的寄存器:ESP、EIP长调用(跨段不提权)指令格式:CALL CS:EIP(EIP是废弃的)并不使用后面的EIP,EIP是被废弃的。主要是CS段寄存器中的段选择子,通过段选择子去查询GDT表找一个段描述符,且该段
2021-03-19 18:24:30
1003
1
原创 【2021.03.16】代码跨段跳转实验
本节内容通过 JMP FAR 指令修改CS段寄存器要点回顾前文以 JMP 0x20:0x004183D7 为例,提到了代码跨段跳转的五个步骤,分别是:拆分段选择子:确认RPL、TI、索引。 查询GDT表得到段描述符。 权限检查:一致代码段与非一致代码段检查方式不一样。 加载段描述符:加载段描述符至段寄存器,真正修改CS段寄存器。 代码执行:修改EIP(新CS.BASE + EIP),赋值给EIP寄存器并且执行。构造段描述符如何区分是否为数据段/代码段?如 00cf9b00
2021-03-16 22:54:50
437
原创 【2021.03.14】代码跨段
要点回顾段寄存器ES、CS、SS、DS、FS、GS、LDTR、TR段寄存器读写除CS外,其他的段寄存器都可以通过:MOV、LES、LSS、LDS、LFS、LGS 指令进行修改。CS为什么不可以直接修改?CS的改变意味着EIP的改变,改变CS的同时必须修改EIP,所以无法使用上面的指令来修改CS。代码跨段本质就是修改CS段寄存器。代码间的跳转(段内跳转,非调用门之类)段间跳转有2种情况,即要跳转的段是一致代码段还是非一致代码段(如何区分请参见前文)。同时修改CS与EIP
2021-03-14 20:41:15
218
原创 【2021.03.14】段权限检查
要点回顾如:MOV DS, AXAX中是一个16位的数,又称为段选择子,段选择子中包含了一个索引,可以通过该索引找到段描述符。 并不是说段描述符指向谁,就一定会将这个段描述符加载到当前的段寄存器中。 它在加载之前,会有一系列的检查,比如有没有权限,允不允许把段描述符加载到段寄存器中。 如果想要了解检查的细节,还要了解一些其他概念。CPU分级为什么要分级?因为对CPU来说,有些特权指令是只有在0环(Ring 0)才可以使用的。 Windows系统只使用了CPU中的两个环,R0和R3。
2021-03-14 18:03:50
266
原创 【2021.03.13】段描述符属性:DB位
段描述符结构DB位对三种段的影响对CS段的影响:D = 1,采用32位寻址方式。 D = 0,采用16位寻址方式。 硬编码指令前缀67:改变寻址方式。对SS段的影响:D = 1,隐式对战访问指令(会修改ESP,如:PUSH、POP、CALL)使用32位堆栈指针寄存器ESP。 D = 0,隐式对战访问指令(会修改SP,如:PUSH、POP、CALL)使用16位堆栈指针寄存器SP。对向下扩展的数据段的影响:D = 1,段上限为4GB。 D = 0,段上限为64KB。...
2021-03-13 19:48:23
262
原创 【2021.03.13】段描述符属性:S位、TYPE域
段描述符结构段描述符的类别在整个GDT表中的段描述符分为两大类:数据段或代码段描述符。 系统段描述符。S位S位处于段描述符高4字节的第12位。当S位为0则说明该段描述符是系统段的描述符; 当S位为1则说明该段描述符是代码段或数据段的描述符。TYPE域TYPE域处于段描述符高4字节的第8至11位。注意:在数据段或代码段中,TYPE域中的四位的含义是不一样的,在系统段描述符中,它的含义又变成了另外的情况。小结当想拆分一个段描述符属性的时候:首先判断P位,P
2021-03-13 18:26:25
770
原创 【2021.03.12】段描述符属性:P位、G位
要点回顾段寄存器的值是通过段描述符填充的。 但是段描述符只有64位,如何从64位变成80位?段描述符的结构P位P位位于高4字节下标为15的位置。P = 0:段描述符无效。 P = 1:段描述符有效。通过指令将段描述符加载至段寄存器的时候,CPU第一件事就是检查该段描述符的P位。如果P位等于0,那么其他的检查就不做了。只有当P位为1的时候才会做后续的其他检查。G位G位位于高4字节下标为23的位置。在了解G位之前,先来回顾一下段寄存器的结构。段寄存器的结构s
2021-03-12 20:17:44
2618
原创 【2021.03.10】段描述符与段选择子、GDT、LDT
要点回顾前文提到,当写入一个段寄存器的时候,只给了一个16位的数值,但是段寄存器有96位。 那么剩下的80位从哪里来的?这个16位的数值是随便写的吗?Windbg指令指令 功能 r 查看寄存器 dd 以四字节为一组读取并显示数据 dq 以八字节为一组读取并显示数据 GDT与LDTGDT:全局描述符表 LDT:局部描述符表当执行类似 MOV DS, AX 指令的时候,CPU会进行一个查表的操作。 根据AX的值来决定查找GDT表还是LDT表,查找表的
2021-03-10 18:51:03
1406
原创 【2021.02.26】段寄存器属性探测
要点回顾struct SetMent{ WORD Selector; // 16位Selector 可见部分 WORD Attributes; // 16位Attributes 表示当前段寄存器是可读还是可写 DWORD Base; // 32位Base 表示当前段寄存器是从哪里开始的 DWORD Limit; // 32位Limit 表示当前段寄存器整个的长度有多少}上篇文章中提到,段寄存器有96
2021-02-27 00:00:42
234
原创 【2021.02.26】段寄存器结构
什么是段寄存器?当使用汇编读写某一个地址时:mov dword ptr ds:[0x123456], eax。真正读写的地址是:ds.base + 0x123456。ds:段寄存器。base:ds段寄存器中的某一个成员。有哪些段寄存器?ES、CS、SS、DS、FS、GS、LDTR、TR段寄存器的结构对通用寄存器可能都有一定的了解,比如EAX寄存器可以分为8位、16位和32位的。EAX最大就是32位。 但是段寄存器不是这样的,段寄存器相对来说要复杂,它有96位。 段
2021-02-26 21:09:54
477
原创 【2021.02.26】什么是保护模式
x86 CPU的3个模式:实模式:DOS系统的CPU用的系统就是实模式,里面用的地址就是真实的物理地址。现在的系统已经没有使用实模式的了,只是在启动的瞬间是实模式,然后进入保护模式。 保护模式:保护模式中的地址是假的,如果要从保护模式到实模式的地址,无论是低2G还是高2G都要经过转换。除了CR3寄存器存储的是物理地址,其他的寄存器全是线性地址。 虚拟8086模式:如果在保护模式下,想运行实模式的代码,也是可以运行的,就是虚拟8086模式。虚拟8086模式仍然是保护模式,而不是实模式。保护模式有什么
2021-02-26 20:43:54
389
原创 【2021.01.20】C++进程名称获取进程PID、获取指定进程模块句柄
进程名称获取进程PID#include <Windows.h>#include <TlHelp32.h>DWORD GetProcessId(WCHAR* szProcessName){ HANDLE hProcessSnapShot = NULL; PROCESSENTRY32 pe32 = { 0 }; hProcessSnapShot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hPr
2021-01-20 18:38:43
6462
1
原创 【2021.01.16】HOOK攻防、瞬时(临时)HOOK
常用手段阶段一防守:检测JMP(E9)、检测跳转范围。 攻击:想方设法绕开。阶段二防守:线程全代码校验/CRC校验。 攻击:修改检测代码、挂起检测线程。阶段三防守:相关API进行全代码校验,多个线程互相检测,并检测线程是否活动。 攻击:使用瞬时钩子/硬件钩子。...
2021-01-16 18:30:13
743
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人