【编程技术-SysWhispers3学习】此文章归类为:编程技术。
基础知识
在操作系统中分为用户态与内核态,而一些安全软件是通过对一些api进行挂钩进行行为监控的,而使用未挂钩函数或更底层api就成为一种免杀的方式。

api从用户态进入内核态的方式为(以CreateFile为例):
1、找到一些如Kernel32.dll,从dll导出表中查找CreateFile的地址。
2、找到ntdll.dll,找到NtCreateFile或ZwCreateFIle函数的调用号。
3、在x64下使用syscall分发,x86下为sysentry
4、若为Zw开头函数会通过SSDT表间接找到系统服务例程,而Nt开头函数是直接执行代码的。
syscall
在学习SysWhispers3前首先认识syscall,这也是学习地狱门的基础。
1
2
3
4
5
6
7
8
|
/
/
首先使用一段代码看系统是如何使用syscall的
int
main() {
FARPROC addr
=
GetProcAddress(LoadLibraryA(
"ntdll"
),
"NtCreateFile"
);
const char
*
a
=
"qwe"
;
}
|
打上断点后,运行查看反汇编,查找addr

1
2
3
4
5
|
;关键汇编代码
mov r10,rcx
mov eax,
55h
;
55h
是NtCreateFile调用号
syscall
ret
|
通过PE查找服务号
在知道了如何使用地狱门后,那么如何满足程序的通用性,而不是调用某个函数就改一次调用号呢?可以使用PE,通过查找ntdll.dll的导出表,通过对比需要的函数来查找服务号。
查找ntdll.dll基地址
1、首先查找PEB结构地址(!peb)

2、反汇编0x000000dbd4fb4000(dt 0x000000dbd4fb4000 ntdll!_PEB)

3、找到ldr地址(dx -r1 ((ntdll!_PEB_LDR_DATA *)0x7ffb95fdb4c0))

4、查询链(dx -r1 (*((ntdll!_LIST_ENTRY *)0x7ffb95fdb4d0)))
注意的是这三条链都是可以查的,并不是只能查询第一条,但对应的代码中查找的地址是要确定的

5、查找链内容(dt _ldr_data_table_entry 0x2b2b8684470)
注意FullDllName是第几个出现了ntdll的,一般是第二个


6、找到ntdll后看0x30这个偏移上是ntdll的地址(注意32位与64位这个地址是不同的)
7、通过查询dll导出表,对比函数名称,就可以找到对应的服务号了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
.data
SyscallIndex DWORD
000h
;用于保存传入的服务号,并且每次刷新用于保存下个服务号
.code
Gate proc; Gate函数用于查找函数对应服务号
mov SyscallIndex,
000h
mov SyscallIndex,ecx
ret
Gate endp
function proc
mov r10, rcx
mov eax,SyscallIndex
syscall
ret
function endp
end
|
SysWhispers3
有了这些前置知识后,就可以学习SysWhispers3,一种对syscall的静态查杀绕过。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
;截取一段函数汇编进行分析
NtTestAlert PROC
mov [rsp
+
8
], rcx ; Save registers.
mov [rsp
+
16
], rdx
mov [rsp
+
24
], r8
mov [rsp
+
32
], r9
sub rsp,
28h
mov ecx,
00E94313Eh
; Load function
hash
into ECX.
call SW3_GetSyscallAddress ; Resolve function
hash
into syscall offset.
mov r15, rax ; Save the address of the syscall
mov ecx,
00E94313Eh
;Re
-
Load function
hash
into ECX
call SW3_GetSyscallNumber ;Resolve function
hash
into syscall number.
add rsp,
28h
mov rcx, [rsp
+
8
] ; Restore registers.
mov rdx, [rsp
+
16
]
mov r8, [rsp
+
24
]
mov r9, [rsp
+
32
]
mov r10, rcx
jmp r15 ; Jump to
-
> Invoke system call.
NtTestAlert ENDP
|
SW3_GetSyscallAddress为查找syscall基地址,并将结果保存在r15寄存器中并在最后jmp r15调用syscall,SW3_GetSyscallNumber为找到函数对应的服务号。
函数hash如何知道对应的函数是什么?
1、下断点,查看SyscallAddress

2、将地址进行反汇编(u 地址)

那么就知道这串hash对应的函数为NtAccessCheck
更多【编程技术-SysWhispers3学习】相关视频教程:www.yxfzedu.com