首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
编程技术
发新帖
3
19
[原创]windows内核免杀学习2-手剥 PE 到节区表
发表于: 2026-9-3 17:49
1149
[原创]windows内核免杀学习2-手剥 PE 到节区表
aln1lam
2026-9-3 17:49
1149
# MZ 到 Section 偏移全手算 一个 PE 文件加载进内存后,它自己的 DOS 头、NT 头、节区表就摊在进程地址空间的开头,用户态直接能读。不用 `LoadLibrary`,不用 `MapViewOfFile`,一个 `GetModuleHandle(NULL)` 拿到基址,剩下的全靠加法一层层剥下去。这篇记的是从 `MZ` 一路剥到节区表、打印每个节区的名字地址属性、再拆出 R/W/X 的完整过程,代码自己写、能编译能跑,文末有真实输出。 剥的过程中我把所有宏都拆掉了——`IMAGE_FIRST_SECTION` 这种现成宏能一步到位,但它把"节区表到底怎么算出来的"藏掉了。手写 `(BYTE*)nt + 4 + 20 + SizeOfOptionalHeader`,每一步加的是什么看得清清楚楚。过程中卡过、想错过的地方单独成节,留着当时怎么想错的。内容均在合法授权的隔离靶场环境内学习验证。 环境:Windows 11 家庭中文版 10.0.26200,MSYS2 gcc 16.1.0,x64。 ## PE 文件一层套一层每层只跳过一段固定长度 PE 文件从头到尾一层套一层:DOS Header 在最前,里面 `e_lfanew` 字段告诉你 PE 头在哪;PE 头又是三层内嵌——PE 签名、COFF File Header、Optional Header;Optional Header 走完,紧跟着才是节区表。 ``` 0x000 DOS Header (64B) e_magic=MZ, e_lfanew=0x80 0x040 DOS Stub (可变长) 加载器不看 0x080 PE 签名 "PE\0\0" (4B) 0x084 COFF File Header IMAGE_FILE_HEADER (固定20B) 0x098 Optional Header IMAGE_OPTIONAL_HEADER (变长) 0x188 Section Headers 每个40B ← 目标在这里 ```  上面这张是整体套娃。要手算偏移,还得换成阶梯视角——每一层在什么地址、到下一层跳多远、哪些是固定大小、哪些必须读字段才知道:  阶梯图里只有两处是变长:DOS Stub,加载器不看,靠 `e_lfanew` 直接绕过;和 Optional Header,靠 COFF 头里的 `SizeOfOptionalHeader` 字段绕过。其余每层长度写死,加固定数即可。下面这张速查卡把写代码时要用到的 `<windows.h>` 结构体和容易踩的坑列在一起,后面每段代码对照着看。 ## 写代码前先记住这几个结构体 写 PE 解析不靠 `struct.unpack`,`<windows.h>` 已经把所有结构体定义好了,强转指针就能按字段读。要记的只有下面五个,和每个上头容易栽的坑。 | 结构体 | 大小 | 关键字段 | 用途 / 坑 | | ----------------------- | ------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | `IMAGE_DOS_HEADER` | 64B 固定 | `e_magic`(MZ=0x5A4D)、`e_lfanew`(PE 头偏移) | 64 字节里只有这两个活字段,其余 16 个旧 DOS 字段加载器不看。`e_lfanew` 是偏移数字,不是地址也不是内容 | | `IMAGE_NT_HEADERS` | 三层内嵌 | `Signature`(DWORD)、`FileHeader`、`OptionalHeader` | **`FileHeader` / `OptionalHeader` 是内嵌本体不是指针**:`nt->FileHeader.Machine` 用 `.`,不是 `nt->FileHeader->Machine` | | `IMAGE_FILE_HEADER` | 20B 固定(COFF 头) | `Machine`、`NumberOfSections`、`SizeOfOptionalHeader` | 固定 20 字节,`sizeof(IMAGE_FILE_HEADER)` 能直接用。`SizeOfOptionalHeader` 是算节区表起点要用的那个变长 | | `IMAGE_OPTIONAL_HEADER` | 变长(PE32=224 / PE32+=240,但以字段为准) | `Magic`(PE32=0x10B / PE32+=0x20B)、`AddressOfEntryPoint`、`ImageBase`、`SectionAlignment` / `FileAlignment` | **`ImageBase` 运行时被 ASLR 回填**:内存里读到的不是文件里的 `0x140000000`,而是实际加载地址==`hMod`。长度不能写死,必须读 `SizeOfOptionalHeader` | | `IMAGE_SECTION_HEADER` | 40B 固定 × N | `Name[8]`、`Misc.VirtualSize`、`VirtualAddress`、`SizeOfRawData`、`PointerToRawData`、`Characteristics` | 三个坑见下文:`Name` 用 `%.8s`、`VirtualSize` 走 `Misc.VirtualSize`、`VirtualAddress`/`PointerToRawData` 是两套坐标系 | **五个坑,写之前过一遍:** 1. `->` 还是 `.`,看是指针还是内嵌本体。`nt` 是指针 → `nt->FileHeader`;`FileHeader` 是内嵌本体 → `nt->FileHeader.Machine`。`section[i]` 已解引用成本体 → `section[i].Name` 用 `.`。 2. 指针做加法必须先 `(BYTE*)` 强转。`HMODULE` 是句柄,不能 `+ 整数`;`(BYTE*)hMod + n` 加几就是前进几字节。不强转编译器直接拒。 3. 节区名 `%.8s` 不是 `%s`。`Name[8]` 定长 8 字节不保证有 `\0`,`%s` 会越界读到下一个节区头。 4. `VirtualSize` 走 `Misc.VirtualSize`。`Misc` 是联合体,`VirtualSize` 和 `SizeOfRawData` 共用 4 字节,访问必须带 `Misc.` 前缀。 5. `Characteristics` 用位运算掩码拆 R/W/X,不是 `==` 比较。掩码 `0x20000000/0x40000000/0x80000000` 各只开一位,`&` 之后非 0 即有权限。`ImageBase` 别信文件值,运行时被 ASLR 改过。 > 关于节区表起点:`<windows.h>` 提供了 `IMAGE_FIRST_SECTION(nt)` 宏,内部就是 `(BYTE*)nt + 4 + 20 + SizeOfOptionalHeader` 这一行。本文刻意不用宏、手写加法,是为了把"节区表到底怎么算出来的"摊开看清楚——写生产代码时用宏更简洁,但要懂它藏了什么。 节区表起点的手算链,没有减法,没有宏,每一步都是"跳过某段长度": ``` 基址 (hMod) + e_lfanew 跳到 PE 头 + 4 跳过 PE 签名 (DWORD) + 20 跳过 COFF File Header (固定20B) + SizeOfOptionalHeader 跳过 Optional Header (变长,必须读字段) = 节区表起点 ``` 关键在最后一步:Optional Header 长度不固定。PE32(32位)标准 224 字节,PE32+(64位)标准 240 字节,但实际长度由 COFF 头里的 `SizeOfOptionalHeader` 字段说了算——加载器信这个字段。所以你不能写死 `+240`,必须读字段。 ## GetModuleHandle(NULL) 给的是运行时实际基址 第一步拿基址。`GetModuleHandle(NULL)` 返回的是 EXE 自身在当前进程地址空间里的加载基址。注意这是运行时实际地址,受 ASLR 影响,每次启动都不同,不能写死。 ```c HMODULE hMod = GetModuleHandle(NULL); IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)hMod; ``` 把 `hMod` 强转成 `IMAGE_DOS_HEADER*`,就能按结构体字段读 DOS 头了。DOS Header 64 字节里只有两个活字段:`e_magic`(`MZ` 标志)和 `e_lfanew`(PE 头偏移)。其余 16 个旧 DOS 字段加载器不看。 ```c printf("e_magic: 0x%X\n", dosHeader->e_magic); // 0x5A4D = "MZ" printf("e_lfanew: 0x%X\n", dosHeader->e_lfanew); // 0x80 ``` `e_lfanew` 存的是个偏移数字(0x80),不是地址也不是内容。它告诉你"PE 签名在距文件开头第 0x80 字节处"。 ## 跳到 NT 头看三层内嵌结构 `e_lfanew` 加上基址,就到了 NT 头。NT 头是个三层内嵌结构体 `IMAGE_NT_HEADERS`: ```c IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)((BYTE*)hMod + dosHeader->e_lfanew); ``` 这里必须 `(BYTE*)hMod` 强转。`HMODULE` 是句柄,不能直接 `+ 整数`;强转成单字节指针后,加几就是前进几字节。不加这步强转,编译器直接拒。 `IMAGE_NT_HEADERS` 内部三层: ``` Signature DWORD "PE\0\0" FileHeader IMAGE_FILE_HEADER (内嵌本体,不是指针) OptionalHeader IMAGE_OPTIONAL_HEADER (内嵌本体,不是指针) ``` ### `->` 还是 `.` 看内嵌还是指针 我一开始分不清什么时候用 `->` 什么时候用 `.`。规则其实简单: - `nt` 是指针 → 访问它直挂的字段用 `->`:`nt->FileHeader`、`nt->OptionalHeader` - `FileHeader` 是 `IMAGE_NT_HEADERS` 里内嵌的本体(不是指针)→ 访问它的字段用 `.`:`nt->FileHeader.Machine`、`nt->FileHeader.NumberOfSections` 判断依据是"这个字段是指针还是内嵌结构体"。指针用 `->`,内嵌本体用 `.`。`nt->FileHeader` 拿到的是本体,本体上取字段就是 `.`。 NT 头里 COFF File Header 固定 20 字节,7 个字段,我用到 3 个: ```c printf("Signature: 0x%08X\n", nt->Signature); // 0x00004550 = "PE\0\0" printf("Machine: 0x%X\n", nt->FileHeader.Machine); // 0x8664 = x64 printf("NumberOfSections: %d\n", nt->FileHeader.NumberOfSections); // 19 printf("SizeOfOptionalHeader: 0x%X\n", nt->FileHeader.SizeOfOptionalHeader); // 0xF0 ``` `NumberOfSections` 告诉我节区有几个(19),`SizeOfOptionalHeader` 告诉我 Optional Header 多长(0xF0=240)——后者正是算节区表起点要用的那个变长。 ## 节区表起点由四个加数串起来 到节区表这一步,把前面的加法链写成一行: ```c IMAGE_SECTION_HEADER* section = (IMAGE_SECTION_HEADER*)( (BYTE*)nt + sizeof(nt->Signature) + sizeof(IMAGE_FILE_HEADER) + nt->FileHeader.SizeOfOptionalHeader); ```  `sizeof(nt->Signature)` = 4,`sizeof(IMAGE_FILE_HEADER)` = 20,加 `SizeOfOptionalHeader`。等价于 `(BYTE*)nt + 4 + 20 + 0xF0`。我没用 `IMAGE_FIRST_SECTION` 宏——那个宏内部就是这一行,但写出来每一步加的是啥一目了然,宏把它藏了。 拿到 `section` 指针后,它指向第一个节区头。节区头每个 40 字节,`NumberOfSections` 个连排,所以 `section[i]` 就是第 i 个节区。这里 `section` 是指针,`section[i]` 已经解引用成本体,所以下面访问字段全用 `.`。 ## IMAGE_SECTION_HEADER 的三个坑 节区头 40 字节,关键字段:`Name[8]`、`Misc.VirtualSize`、`VirtualAddress`、`SizeOfRawData`、`PointerToRawData`、`Characteristics`。下面三个是反复踩过的。 节区名用 `%.8s` 不是 `%s`。`Name` 是定长 8 字节数组,不保证有 `\0` 结尾。`.text` 只有 5 个字符,剩下 3 字节是别的数据。用 `%s` 会一直读直到碰到 `\0`,越界读到下一个节区头。`%.8s` 强制最多打 8 字符,安全。 ```c printf("Name: %.8s\n", section[i].Name); ``` VirtualSize 走 `Misc.VirtualSize`。`Misc` 是个联合体(union),`VirtualSize` 和 `SizeOfRawData` 共用同一片 4 字节内存。访问必须 `section[i].Misc.VirtualSize`,不能 `section[i].VirtualSize`,那是联合体本身的名字,不是字段。 ```c printf("VirtualSize: 0x%X\n", section[i].Misc.VirtualSize); ``` 内容/偏移/地址三分。`VirtualAddress` 是节区加载到内存后的 RVA(相对基址的位置),`PointerToRawData` 是节区在文件里的偏移,`SizeOfRawData` 是文件里的大小。这三个是不同坐标系的东西,别混。D8 的时候我反复栽在这——把"在文件第几字节"和"加载到内存哪里"搅在一起。`VirtualAddress` 是内存坐标,`PointerToRawData` 是文件坐标。 ## 拆 R/W/X 靠只开一位的掩码 节区属性全在 `Characteristics` 字段里,32 位,每一位/几位代表一个属性。执行/读/写看高三位: | 位 | 值 | 含义 | | ---- | ---------- | ------ | | 2^29 | 0x20000000 | 可执行 | | 2^30 | 0x40000000 | 可读 | | 2^31 | 0x80000000 | 可写 | 拆权限的代码: ```c int X = (section[i].Characteristics & 0x20000000) ? 1 : 0; int R = (section[i].Characteristics & 0x40000000) ? 1 : 0; int W = (section[i].Characteristics & 0x80000000) ? 1 : 0; ``` ### `&` 不是运算了就算成功 这句话我卡了很久。我一开始以为 `&` "运算了就算成功=1"——"1与1还是1与0他不都是相当于计算成功了吗 怎么不应该都是1吗"。 错在没分清"运算执行了"和"运算结果是多少"。`&` 是按位与,逐位比较: - `1 & 1 = 1` - `1 & 0 = 0` ← 结果是 0,不是 1 - `0 & 0 = 0` `? 1 : 0` 判断的是运算结果的数值:结果非 0 → 输出 1,结果等于 0 → 输出 0。不是"运不运算"。 `0x20000000` 这个掩码只开第 29 位,其余 31 位全是 0。按位与时,被测值第 29 位是 1 → `1&1=1` → 结果非 0 → 输出 1(有权限);被测值第 29 位是 0 → `0&1=0` → 结果 0 → 输出 0(无权限)。其余位被掩码的 0 全部屏蔽成 0,不影响判断。  拿 `.text` 的 `0x60000020` 验证一遍: | 被测值 | 掩码 | 结果 | 判定 | | ---------- | ---------- | ----------------- | -------- | | 0x60000020 | 0x20000000 | 0x20000000(非0) | 可执行 ✓ | | 0x60000020 | 0x40000000 | 0x40000000(非0) | 可读 ✓ | | 0x60000000 | 0x80000000 | 0 | 不可写 ✗ | `.text` = R-X,正常代码段。掩码像一张只开一个孔的挡板,挡住其他位,只让目标那一位的值透过来。 ### "第30位"还是"第29位" 我口语说过"第30位=可执行",但严格按 2^N 标准编号 `0x20000000 = 2^29 = 第 29 位`(从 0 数)。从 1 数就是"第 30 位"。指同一个位,两种数法。以后用 2^N 标准更精确,避免歧义。 ## 出现 RWX 节区就是恶意特征 把 X/R/W 三个拼起来,就能看一个节区是 R-X / RW- / R-- 还是 RWX。正常程序: - `.text`(代码段)= R-X:可读可执行,不可写 - `.data`(数据段)= RW-:可读写,不可执行 - `.rdata`(只读数据)= R--:只读 代码段不可写、数据段不可执行。一旦出现 RWX 节区——既能写又能执行——说明这段内存可以边写边跑:壳的解密器把代码写进去再执行、Shellcode loader 注入后改属性执行,都需要 RWX。杀软和 EDR 扫到 RWX 节区会标记。 ```c if (X == 1 && R == 1 && W == 1) { printf("WARNING!!!\n"); } ``` 我的 demo 没有 RWX,正常程序。 ## ImageBase 运行时被 ASLR 回填 代码跑出来 `ImageBase: 0x7FF7917D0000`,不是预期的 `0x140000000`。一开始以为取错字段了,后来想明白这是 ASLR。 ```c printf("ImageBase: 0x%llX\n", nt->OptionalHeader.ImageBase); ```  EXE 编译时,链接器在 Optional Header 的 `ImageBase` 字段写死一个期望基址(MSVC 默认 `0x140000000`)。运行时加载器为了防攻击,把它加载到随机地址(`0x7FF7917D0000`)。加载器把实际基址回填写进了内存里的 `OptionalHeader.ImageBase` 字段——所以运行时读这个字段,拿到的是回填后的实际值,恰好等于 `GetModuleHandle(NULL)`。 这正好印证 D9 那个薄弱点: - 静态分析文件时,`ImageBase` 字段 = `0x140000000`(期望值),但换算文件偏移用不上它(用 RVA→Offset) - 运行时调试器里,`ImageBase` 字段 = 实际加载地址,== hMod 文件里的 `ImageBase` 是链接器写的期望值,内存里的 `ImageBase` 在加载时被 ASLR 改成了实际加载地址。我这个程序运行时读的是内存里被改过的那个,所以是 `0x7FF7917D0000`。 ## 代码 ```c #include<stdio.h> #include<windows.h> int main() { HMODULE hMod = GetModuleHandle(NULL); IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)hMod; printf("e_magic: 0x%X\n", dosHeader->e_magic); printf("e_lfanew: 0x%X\n", dosHeader->e_lfanew); IMAGE_NT_HEADERS* nt = (IMAGE_NT_HEADERS*)((BYTE*)hMod + dosHeader->e_lfanew); printf("Signature: 0x%08X\n", nt->Signature); printf("Machine: 0x%X\n", nt->FileHeader.Machine); printf("NumberOfSections: %d\n", nt->FileHeader.NumberOfSections); printf("SizeOfOptionalHeader: 0x%X\n", nt->FileHeader.SizeOfOptionalHeader); printf("Magic: 0x%X\n", nt->OptionalHeader.Magic); printf("AddressOfEntryPoint: 0x%X\n", nt->OptionalHeader.AddressOfEntryPoint); printf("ImageBase: 0x%llX\n", nt->OptionalHeader.ImageBase); printf("SectionAlignment: 0x%X\n", nt->OptionalHeader.SectionAlignment); printf("FileAlignment: 0x%X\n", nt->OptionalHeader.FileAlignment); IMAGE_SECTION_HEADER* section = (IMAGE_SECTION_HEADER*)((BYTE*)nt + sizeof(nt->Signature) + sizeof(IMAGE_FILE_HEADER) + nt->FileHeader.SizeOfOptionalHeader); for (int i = 0; i < nt->FileHeader.NumberOfSections; i++) { printf("Section %d:\n", i + 1); printf("Name: %.8s\n", section[i].Name); printf("VirtualAddress: 0x%X\n", section[i].VirtualAddress); printf("VirtualSize: 0x%X\n", section[i].Misc.VirtualSize); printf("SizeOfRawData: 0x%X\n", section[i].SizeOfRawData); printf("PointerToRawData: 0x%X\n", section[i].PointerToRawData); printf("Characteristics: 0x%X\n", section[i].Characteristics); int X = (section[i].Characteristics & 0x20000000) ? 1 : 0; int R = (section[i].Characteristics & 0x40000000) ? 1 : 0; int W = (section[i].Characteristics & 0x80000000) ? 1 : 0; printf("Executable: %d, Readable: %d, Writable: %d\n", X, R, W); if(X == 1 && R == 1 && W == 1){ printf("WARNING!!!\n"); } } return 0; } ``` ## 运行输出 ``` $ gcc week2.c -o 1.exe $ ./1.exe e_magic: 0x5A4D e_lfanew: 0x80 Signature: 0x00004550 Machine: 0x8664 NumberOfSections: 19 SizeOfOptionalHeader: 0xF0 Magic: 0x20B AddressOfEntryPoint: 0x1490 ImageBase: 0x7FF7917D0000 SectionAlignment: 0x1000 FileAlignment: 0x200 Section 1: Name: .text VirtualAddress: 0x1000 VirtualSize: 0x1A60 SizeOfRawData: 0x1C00 PointerToRawData: 0x600 Characteristics: 0x60000020 Executable: 1, Readable: 1, Writable: 0 Section 2: Name: .data Characteristics: 0xC0000040 Executable: 0, Readable: 1, Writable: 1 Section 3: Name: .rdata Characteristics: 0x40000040 Executable: 0, Readable: 1, Writable: 0 ... Section 6: Name: .bss Characteristics: 0xC0000080 Executable: 0, Readable: 1, Writable: 1 Section 10: Name: .reloc Characteristics: 0x42000040 Section 11: Name: /4 Characteristics: 0x42000040 ...(/19 /31 /45 /57 /70 /81 /97 /113,gcc 调试节) ``` 输出解读: - `ImageBase: 0x7FF7917D0000`——ASLR 回填值,不是文件里的 `0x140000000`。 - `.text` = `0x60000020` → R-X,正常代码段,不可写。 - `.data` = `0xC0000040` → RW-,可读写不可执行。 - `.rdata` = `0x40000040` → R--,只读。 - `.bss` = `0xC0000080` → RW-,`0x80` 那位是"未初始化数据"(`.bss` 存未初始化的全局变量)。 - 无 RWX,正常程序。 - `/4 /19 /31 ...` 这些是 gcc/MinGW 编译的 PE 带的 COFF 符号调试节,属性 `0x42000040`,非恶意。MSVC 编译的 EXE 不会有这些。 19 个节区比正常 5~8 个多,是 gcc 默认带调试信息 + CRT 静态链接摊开的。用 `/MD /RELEASE /MERGE` 可以压到 3~4 个,但压缩节区数本身也是启发式特征——节区太少同样会被杀启发式规则标记。 ## 改 NumberOfSections 能藏东西杀软不一定信字段 既然能读 `NumberOfSections`,就能想到动手脚。加载器信这个字段:它读前 N 个节区头、只映射前 N 个节区。把 19 改成 5,文件照样能跑(前 5 节区够用),后面 14 节区的数据还在文件里,但加载器视而不见。 藏东西的空间就出来了:恶意代码放进"加载器不读的第 6~19 节区",杀软若只信 `NumberOfSections` 就扫不到。 检测器破法:不盲信这个字段,用 `SizeOfOptionalHeader` 自己重算节区头起点,一路扫到文件末尾——加载器不读的节区,杀软独立重算能全看到。同理 `SizeOfOptionalHeader` 也能篡改:加载器按假值算节区头起点(读到垃圾或错位),杀软可独立重算看真相。这条对抗思路 D8 记过,这里用代码走了一遍。 --- 下一篇从节区表走进 Data Directory,解析导入表和导出表——把 PE 里那些"表"怎么查讲清楚。
回复或点赞可查看完整内容
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
最后于
2026-9-4 10:59 被aln1lam编辑 ,原因:
#系统内核
收藏
・
3
点赞
・
19
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
mb_fexzsdzi
谢谢你的细致分析,受益匪浅!
18小时前
WinDos2K
感谢你分享这么好的资源!
20小时前
孤独的街
为你点赞!
23小时前
马来
为你点赞!
1天前
git_99440qimingminimax
为你点赞!
1天前
mb_zzncjovh
感谢你分享这么好的资源!
2天前
wx_OvO
非常支持你的观点!
2天前
一吻江山
+1
这个讨论对我很有帮助,谢谢!
6天前
寻影星尘
为你点赞!
6天前
mb_pmhzceow
为你点赞!
2026-9-16 19:17
amethyspro
这个讨论对我很有帮助,谢谢!
2026-9-10 14:09
git_51951meggadf3df
非常支持你的观点!
2026-9-10 10:54
晨曦。
为你点赞!
2026-9-9 07:11
爱吃蔬菜饺子
+1
感谢你的积极参与,期待更多精彩内容!
2026-9-5 11:15
cloudhoter
感谢你的贡献,论坛因你而更加精彩!
2026-9-4 17:26
UserXCh
为你点赞!
2026-9-4 08:16
huangyalei
期待更多优质内容的分享,论坛有你更精彩!
2026-9-3 23:09
mb_dtidoewd
你的分享对大家帮助很大,非常感谢!
2026-9-3 19:29
我的小拇指啊
感谢你的积极参与,期待更多精彩内容!
2026-9-3 18:35
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
7
)
啊你好哇123
雪 币:
739
能力值:
( LV1,RANK:0 )
在线值:
发帖
0
回帖
366
粉丝
0
关注
私信
啊你好哇123
2
楼
学习学习
2026-9-3 23:53
0
xingbing
雪 币:
158
活跃值:
(5711)
能力值:
( LV2,RANK:10 )
在线值:
发帖
2
回帖
1381
粉丝
2
关注
私信
xingbing
3
楼
学习!!!
2026-9-4 15:17
0
git_243707AM7
雪 币:
能力值:
( LV1,RANK:0 )
在线值:
发帖
0
回帖
8
粉丝
0
关注
私信
git_243707AM7
4
楼
Thanks
2026-9-5 08:44
0
yuanyouran
雪 币:
286
活跃值:
(3090)
能力值:
( LV2,RANK:10 )
在线值:
发帖
5
回帖
184
粉丝
0
关注
私信
yuanyouran
5
楼
学习学习
2026-9-9 09:49
0
BlackShip_329828
雪 币:
0
活跃值:
(30)
能力值:
( LV2,RANK:10 )
在线值:
发帖
0
回帖
3
粉丝
0
关注
私信
BlackShip_329828
6
楼
6
2026-9-10 10:41
0
wx_Christopher_719
雪 币:
0
能力值:
( LV1,RANK:0 )
在线值:
发帖
0
回帖
2
粉丝
0
关注
私信
wx_Christopher_719
7
楼
继续学习第二篇
2026-9-17 11:41
0
TkBinary
雪 币:
6562
活跃值:
(13309)
能力值:
(RANK:385 )
在线值:
发帖
26
回帖
527
粉丝
249
关注
私信
TkBinary
5
8
楼
等你下一篇
1天前
0
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
aln1lam
6
发帖
7
回帖
10
RANK
关注
私信
他的文章
[原创]windows内核免杀学习2-手剥 PE 到节区表
1146
[原创]windows内核免杀学习1-不调 API 找 ntdll 基址
4453
[原创]Forti8.0固件解包
1291
[原创]KCTF 2026 - Rosetta Calibration Writeup
581
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部