Snowming04's Blog
一颗红❤
Toggle navigation
Snowming04's Blog
主页
Cobalt Strike
Accelerated C++
区块链安全
友链
关于我
常用工具
代码积累
归档
标签
shellcode windows 编程(一)
2021-03-29 19:52:12
1831
0
0
snowming
本文希望通过 shellcode 编程获取 kernel32.dll 的内存地址。获取 kernel32 的内存地址是通过 LoadLibraryA -> GetProcAddress 调用链进行 shellcode win32 编程的基本步骤。 ---------------- # ① kernel32.dll 的内存地址 首先通过 windows c 代码获取 kernel32.dll 的内存地址,用于后续的结果验证。  注:编译环境为 win32/x86。 ------------------ # ② peb 中寻找 kernel32.dll 的内存地址 已知 peb 中加载的第三个模块是 kernel32.dll。所以 shellcode 作为一段 PIC (位置无关)代码,我们是希望从 peb 中获取 kernel32.dll 的内存地址。 将 WinDbg attach 到 `C:\Windows\SysWOW64\notepad.exe`(x86) 程序上。 将 `PEB` 数据结构覆盖在所指向的内存上,以查看该结构成员,在此重点关注 `Ldr`:  `Ldr` 是一个 `_PEB_LDR_DATA` 类型的成员,包含有关当前进程加载模块的信息。  看到偏移 +0x014 处的成员 `InMemoryOrderModuleList`。这是一个 `_LIST_ENTRY` 类型的成员。  可以看到这其实是一个双向链表的指针,其有两个成员变量: - Flink 指向前一个结点,其大小为一个 x86 指针长度4。 - Blink 指向下一个结点,其大小为一个 x86 指针长度4。 我们都知道,链表的一个结点,既包含了指针信息,也包含了数据。  将此地址覆盖到 `LDR_DATA_TABLE_ENTRY` 结构查看其数据:  可以看到其 Flink(前一个结点)的 FullDllName 为 `notepad.exe`。但是要注意这是头节点,要获得当前节点的 FullDllName 需要 -8(一个结点长度8字节,因为双向链表结点两个指针 4 bytes *2):  可以看到为当前 exe,即为第1个模块。而我们的目的是查看第3个模块并获取其内存地址。 重新回到 `InMemoryOrderModuleList` 链表,两次点击 `Flink`(解引用偏移 +0x000 处地址指针):  现在相当于:  验证一下是否为 ntdll.dll:  的确为 ntdll.dll 模块。那么要获得 kernel32.dll 的内存继续解引用偏移 `+0x000` 处的地址:  然后查看结构体,发现偏移 +0x010 处的成员即为指向 kernel32.dll 地址的指针,对此指针解引用即可获得 kernel32.dll 模块的函数地址。 这个过程: 1. 获取 InMemoryOrderModuleList 链表的地址 2. 解引用偏移 +0x000 处的地址获取当前 exe 模块结点地址 3. 解引用偏移 +0x000 处的地址获取 ntdll.dll 模块结点地址 4. 解引用偏移 +0x010 处的地址获取 kernel32.dll 模块函数指针 用汇编表示就是: ``` mov ebx, [Addr of InMemoryOrderModuleList] mov ebx, [ebx + 0x00] mov ebx, [ebx + 0x00] mov ebx, [ebx + 0x10] ``` ----------------- # ③ 汇编代码 x86 编译环境中内联 `_asm` 实现这个过程: ``` #include "windows.h" #include "stdio.h" int main() { int kernel32 = 0; _asm { xor ebx, ebx mov ebx, fs: [0x30] mov ebx, [ebx + 0xc] mov ebx, [ebx + 0x14] mov ebx, [ebx + 0x00] mov ebx, [ebx + 0x00] mov ebx, [ebx + 0x10] mov kernel32, ebx } printf("kernel32=0x%x", kernel32); return 0; } ``` 可以看到 kernel32.dll 地址获取正确。  ------------------- # ④ 一些汇编语句的解释 清零 ebx 通用寄存器: ``` xor ebx, ebx ``` 获取 `PEB` 地址: ``` mov ebx, fs:[0x30] ``` 如图:在 TEB 偏移 30 字节的指针解引用即为 PEB 的地址。而 FS 段寄存器指向当前的 TEB结构:  获取 `Ldr` 地址: ``` mov ebx, [ebx + 0xc] ```  获取 `InMemoryOrderModuleList` 链表的地址(此链表中结点按照模块[exe 或 dll]加载到内存中的顺序排列,是固定的顺序): ``` mov ebx, [ebx + 0x14] ```  其他语句在第②节中做过解释,故不再重复。 # ⑤ 参考文档 - https://www.ired.team/miscellaneous-reversing-forensics/windows-kernel-internals/exploring-process-environment-block
上一篇:
shellcode windows 编程(二)
下一篇:
一个无厘头问题
0
赞
1831 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
提交评论
立即登录
, 发表评论.
没有帐号?
立即注册
0
条评论
More...
文档导航
没有帐号? 立即注册