windows机制初探

news2024/10/5 11:58:03

Windows内存管理

EPROCESS结构体:在内核中表示一个进程

VAD树

二叉树,存储进程在内核层申请的虚拟内存信息

(x86 EPROCESS+0x11c) (x64 EPROCESS+0x7d8)指向VadRoot(VAD树)

可以看到两种内存:Private(私有内存)、 Mapped(映射内存)

私有内存

通过VirtualAlloc、VirtualAllocEx等申请(malloc、new是在用户层申请虚拟内存,所以不是)

独享物理页,可读可写可执行的 Private 会被杀软重点关注

映射内存

通过 CreateFileMapping 等映射

可能与其他进程共享物理页,可以防止多个进程访问DLL时死锁

操作系统通过 VirtualAlloc 预先分配好的一大块内存

malloc和new的调用链: malloc -> _nh_malloc_dbg -> _heap_alloc_dbg -> _heap_alloc_base -> HeapAlloc new -> _nh_malloc -> _nh_malloc_dbg -> _heap_alloc_dbg -> _heap_alloc_base -> HeapAllocHeapAlloc的作用就是在堆里分一些出来

SystemCall 系统调用(x86)

用户层地址0-7开头,内核层8-f

用户层(x86 0x7ffe0000 可读)和内核层(x86 0xffdf0000 可读可写)分别有一个KUSER_SHARED_DATA结构体(用于共享数据,指向同一物理页)

操作系统在系统启动时在 KUSER_SHARED_DATA+0x300 写入 KiFastSystemCallKiIntSystemCall

快速调用:sysenter/sysexit(返回用户层),ntdll 中的 KiFastSystemCall 函数

中断门(老版本):int 0x2E,ntdll 中的 KiIntSystemCall 函数

通过汇编判断支持的方式:

; 将CPU的信息存入寄存器
mov eax,0x1
cpuid
; 

之后edx的SEP位(从右向左从0开始数第11位)为1则支持快速调用,为0则支持中断门

进入内核后,CS由3变为0(0环权限)、SS也改变权限、换栈,然后找SSDT表(系统服务描述符表,KSERVICE_TABLE_DESCRIPTOR结构体,存储真正函数实现的地址)

两个SSDT表(结构相同):

KeServiceDescriptorTable 主要处理 kernel32,在ntoskrnl.exe是导出的

KeServiceDescriptorTableShadow 主要处理 user32、gdi32,没有被Windows导出

双机调试看结构:

kd> dd KeServiceDescriptorTable 80553fa0 80502b8c 00000000 0000011c 80503000 ... 

一行是一个KSYSTEM_SERVICE_TABLE结构体

参数1指向当前内核函数地址(位于所有内核函数地址的数组中)

参数2指向当前内核函数使用次数的地址(位于所有内核函数使用次数的数组中)

参数3代表所有内核函数个数(284)

参数4代表当前内核函数参数个数(0x18/0x4=0x6)

kd> db 80503000
80503000  18 20 2c 2c 40 2c 40 44-0c 08 18 18 08 04 04 0c
...

用Ollydbg找函数在SSDT表中的调用号

底部Command(bp 函数名),下断点

直到跟进Call ntdll,看到调用号(0x7A)ntdll.ZwOpenProcess mov eax,0x7A偏移到函数

kd> dd 80502b8c + 7A*4
80502d74  805c2296 805e49fc 805e4660 805a0722
...
kd> u 805c2296
nt!NtOpenProcess:
805c2296 68c4000000      push    0C4h
805c229b 68a8aa4d80      push    offset nt!FsRtlLegalAnsiCharacterArray+0x2008 (804daaa8)
805c22a0 e86b6cf7ff      call    nt!wctomb+0x45 (80538f10)
805c22a5 33f6            xor     esi,esi
805c22a7 8975d4          mov     dword ptr [ebp-2Ch],esi
805c22aa 33c0            xor     eax,eax
805c22ac 8d7dd8          lea     edi,[ebp-28h]
805c22af ab              stos    dword ptr es:[edi]
3.驱动(x86)

驱动程序(.sys):让内核兼容不同硬件,在加载时会在注册表注册服务

每个进程有4GB内存空间:低2GB是独立的,高2GB位于内核层是公共的

DRIVER_OBJECT结构体代表驱动程序(一种内核模块)

DRIVER_OBJECT+0x10 为 DriverSize(驱动大小)

DRIVER_OBJECT+0x1c 为 DriverName(驱动名称)

DRIVER_OBJECT+0x14 为 DriverSection(指向LDR_DATA_TABLE_ENTRY结构体)

LDR_DATA_TABLE_ENTRY+0x0 为 InLoadOrderLinks结构体(LIST_ENTRY双向链表结构体,可以遍历内核模块)

LDR_DATA_TABLE_ENTRY+0x18 为 DllBase(当前模块首地址)

LDR_DATA_TABLE_ENTRY+0x20 为 SizeOfImage(当前模块大小)

LDR_DATA_TABLE_ENTRY+0x24 为 FullDllName(驱动文件完整路径)

遍历模块输出信息,例:

#include <ntddk.h>

typedef struct _LDR_DATA_TABLE_ENTRY {
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;
    PVOID EntryPoint;
    UINT32 SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    UINT32 Flags;
    UINT16 LoadCount;
    UINT16 TlsIndex;
    LIST_ENTRY HashLinks;
    PVOID SectionPointer;
    UINT32 CheckSum;
    UINT32 TimeDateStamp;
    PVOID LoadedImports;
    PVOID EntryPointActivationContext;
    PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

VOID DriverUnload(PDRIVER_OBJECT driver) { // 卸载驱动时调用
    DbgPrint("Unload\n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path) { // 加载驱动时调用
    DbgPrint("驱动地址:%x\n注册表路径:%wZ", driver, reg_path);

    PLDR_DATA_TABLE_ENTRY phead = (PLDR_DATA_TABLE_ENTRY)(driver->DriverSection); // 头节点
    PLDR_DATA_TABLE_ENTRY pcur = phead; // 当前节点

    do {
        pcur = (PLDR_DATA_TABLE_ENTRY)(pcur->InLoadOrderLinks.Flink);
        DbgPrint("DllBase:%p,SizeOfImage:%08X,BaseDllName:%wZ\n", pcur->DllBase, pcur->SizeOfImage, &(pcur->BaseDllName));
    } while (phead != pcur);

    driver->DriverUnload = DriverUnload; // 指定卸载函数
    return STATUS_SUCCESS;
}

EDR回调监控

1.x86:用jmp进行hook

2.x64:在0环通过回调函数,挂驱动(.sys)来实现监控

系统会随机对内存和快照进行比对,导致用jmp进行hook可能触发PG(Patch Guard)导致蓝屏

微软提供了CmRegisterCallback回调函数来监控注册表操作

加下方wx,拉你一起进群学习

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/513227.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch 入门

Elasticsearch 是一种开源搜索引擎&#xff0c;它基于 Apache Lucene 构建&#xff0c;提供了一个分布式、多租户、全文搜索和分析引擎。Elasticsearch 可以处理海量数据&#xff0c;能够快速、准确地搜索、分析和可视化数据。 Elasticsearch 最初是为了解决日志搜索和分析而开…

2018年下半年 软件设计师 答案及详解

2018年下半年 软件设计师 答案详解 主要记录刷题相关笔记&#xff0c;方便日后温习&#xff01;&#xff01;&#xff01; 一、选择题 CPU 在执行指令的过程中&#xff0c;会自动修改_____的内容&#xff0c;以使其保存的总是将要执行的下一条指令的地址。 A.指令寄存器B.程…

makefile 变量的扩展

文章目录 前言一、环境变量&#xff08;全局变量&#xff09;二、目标变量&#xff08;局部变量&#xff09;三、模式变量总结 前言 一、环境变量&#xff08;全局变量&#xff09; Makefile 中的环境变量&#xff0c;是指在执行 Makefile 时&#xff0c;从外部传入 Make 命令…

m4a音频怎么转换成mp3?

m4a音频怎么转换成mp3&#xff1f;如果你遇到了m4a音频格式的文件&#xff0c;但却无法在音频播放器中打开它&#xff0c;通常我们会将其转换成mp3格式。因为M4A属于苹果专用的音频格式&#xff0c;而MP3则是一种通用音频格式。M4A属于高品质压缩类型的音乐文件&#xff0c;而M…

Django框架之使用Session保持HTTP状态

HTTP协议是无状态的&#xff0c;每次请求都是新的请求&#xff1b; 客户端与服务器端的一次通信就是一次会话。 可使用cookie和session在客户端或者服务端存储有关会话的数据&#xff0c;来进行状态保持&#xff1b; cookie使用在上篇。本篇是使用session进行状态保持及使用Red…

外观数列----2023/5/11

外观数列----2023/5/11 给定一个正整数 n &#xff0c;输出外观数列的第 n 项。 「外观数列」是一个整数序列&#xff0c;从数字 1 开始&#xff0c;序列中的每一项都是对前一项的描述。 你可以将其视作是由递归公式定义的数字字符串序列&#xff1a; countAndSay(1) “1”…

Omniverse Replicator环境配置和使用说明

Omniverse Replicator使用说明 本教程将介绍Omniverse Replicator的环境配置和使用说明, 参加Sky Hackathon的同学可以参考本教程来合成训练数据集. 文章目录 Omniverse Replicator使用说明1. Omniverse环境配置1.a.安装Omniverse Launcher1.a.1.在下面的地址下载Omniverse La…

案例分享:ChatGPT写python脚本,轻松文本处理

大家好&#xff0c;我是可夫小子&#xff0c;关注AIGC、读书和自媒体。解锁更多ChatGPT、AI绘画玩法。加&#xff1a;keeepdance&#xff0c;备注&#xff1a;chatgpt&#xff0c;拉你进群。 在工作中&#xff0c;需要对数据进行筛选、分割和整理&#xff0c;当你接受到一个长长…

浅谈Android PMS解析APP信息流程

前言 前面我们了解了Zygote的启动流程&#xff0c;知道AMS、PMS都是由SystemServer进程启动的&#xff0c;我们都知道PMS主要负责App管理工作&#xff0c;这里我们简单从源码角度分析下PMS是如何解析APP解析的&#xff1b; 源码分析(API 30为例) 我们还是从PackageManagerSe…

SpringBoot缓存技术详解

文章目录 一、 缓存技术介绍1. 缓存技术简介2. JSR107核心接口3. JSR107 图示3. SpringBoot缓存抽象4. 缓存常用注解和接口 一、 缓存技术实战1. Cacheable注解2. 缓存的工作原理4. Cacheable注解的工作流程 一、 缓存技术介绍 1. 缓存技术简介 缓存技术主要分为两大类缓存可…

6 进程的环境

6.1 main函数 C程序总是从main函数开始执行。main函数的原型是&#xff1a; int main(int argc, char *argv[]) 6.2 进程终止 有五种方式使进程终止&#xff1a; &#xff08;1&#xff09;正常终止&#xff1a; &#xff08;a&#xff09;从main返回。 &#xff08;b&…

Pycharm十种不为人所知的技巧,不得不知道

Pycharm是Python语言开发中的一个非常强大的IDE工具&#xff0c;其高度的定制能力、日常开发中常用的工具和各种快捷键等功能&#xff0c;都能帮助Pycharm用户提高开发效率。但是&#xff0c;Pycharm中的许多功能并不为人所知。因此&#xff0c;以下是十种Pycharm技巧&#xff…

【MCS-51】51单片机指令系统大全

指令是指挥微型计算机工作的的计算机命令&#xff0c;对于51单片机来说&#xff0c;其主要使用的指令有两种形式&#xff1a;机器语言指令和汇编语言指令。 机器语言指令是指使用二进制代码表示的指令&#xff1b; 汇编语言指令是指使用容易我们记忆的缩写符号表示的机器语言…

YOLO入门指南:理解YOLO原理及构建第一个目标检测模型

YOLO&#xff08;You Only Look Once&#xff09;是一种快速且准确的目标检测算法&#xff0c;可以在图像或视频中检测出多个对象的位置和类别。在本篇文章中&#xff0c;我们将介绍YOLO的基本原理&#xff0c;并使用TensorFlow构建第一个目标检测模型。 YOLO的基本原理 YOLO的…

linux 安装jdk、tomcat

文章目录 前言一、Linux上安装jdk1、jdk安装与配置过程2、linux查看jdk安装路径 二、Linux上安装tomcat1、tomcat安装与配置过程2、对外开放访问的端口、重启防火墙、查看日志 三、在window系统中通过浏览器访问 前言 先检察是否安装jdk java -jar ## 查看是否安装jdk java -…

K8S—Helm

一、Helm介绍 helm通过打包的方式&#xff0c;支持发布的版本管理和控制&#xff0c;很大程度上简化了Kubernetes应用的部署和管理。 Helm本质就是让k8s的应用管理&#xff08;Deployment、Service等&#xff09;可配置&#xff0c;能动态生成。通过动态生成K8S资源清单文件&a…

文笔润色-文本校对改写工具

文段改写软件 写作是一项对于很多人来说都需要频繁进行的活动&#xff0c;无论是工作中的商业写作还是学术写作&#xff0c;在完成优质内容的同时也需要付出大量的时间和精力进行语言润色和修改。然而&#xff0c;现在有了147ChatGPT改写润色软件&#xff0c;该软件可以全自动…

近期分享学习心得

1、数据类型 原始类型undefined null number string boolean symbol bigint 引用类型 对象 2、大厂为什么不允许赋值undifined&#xff1f; 必须let avoid 0;效果一样 void是关键字&#xff0c;后面跟表达式&#xff0c;无论跟啥最终制造undefined&#xff0c;但是习惯写0。…

动态规划设计

文章目录 动态规划设计一、什么是最长递增子序列&#xff1f;[300. 最长递增子序列](https://leetcode.cn/problems/longest-increasing-subsequence/)注意子序列和子串的区别&#xff1a; 二、动态规划解法2.1什么是数学归纳法&#xff1f;2.2最长递增子序列中数学归纳的实际应…

simulink电力系统仿真(1):电力系统库+(电力系统基础知识)

文章目录 基础知识仿真库搭建一个简单的电路 基础知识 ★三相交流电&#xff1a;三相电是三组幅值相等、频率相等、相位互相差120的交流电&#xff0c;由有三个绕组的三相发电机产生&#xff0c;是工业上常用的电源&#xff0c;可提供超过数千瓦或以上功率的电力。★电力系统暂…