首页
社区
课程
招聘
3
[原创]破译A盾禁止加载驱动失效之谜
发表于: 2015-9-21 10:27 8985

[原创]破译A盾禁止加载驱动失效之谜

2015-9-21 10:27
8985
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
//禁止驱动加载
NTSTATUS DisEnableDriverLoading()
{
    int bRet;
 
    ulZwSetSystemInformationBase = GetSystemRoutineAddress(1,L"ZwSetSystemInformation");
    ulNtLoadDriverBase = GetSystemRoutineAddress(1,L"ZwLoadDriver");
    if (ulNtLoadDriverBase &&
        ulZwSetSystemInformationBase)
    {
        ulNtLoadDriverSize = SizeOfProc(ulNtLoadDriverBase);
        ulZwSetSystemInformationSize = SizeOfProc(ulZwSetSystemInformationBase);
    }
 
    ulSeSinglePrivilegeCheck = GetSystemRoutineAddress(1,L"SeSinglePrivilegeCheck");
    if (!ulSeSinglePrivilegeCheck ||
        !ulNtLoadDriverBase ||
        !ulZwSetSystemInformationBase)
    {
        return STATUS_UNSUCCESSFUL;
    }
    //计算reload后的地址,不然判断不对
    ulNtLoadDriverBase = ulNtLoadDriverBase - SystemKernelModuleBase+ImageModuleBase;
    ulZwSetSystemInformationBase = ulZwSetSystemInformationBase - SystemKernelModuleBase+ImageModuleBase;
    ulReloadSeSinglePrivilegeCheck = ulSeSinglePrivilegeCheck - SystemKernelModuleBase+ImageModuleBase;
 
    //hook reload SeSinglePrivilegeCheck
 
    bRet = HookFunctionByHeaderAddress(ulReloadSeSinglePrivilegeCheck,ulSeSinglePrivilegeCheck,SeSinglePrivilegeCheckHookZone,&SeSinglePrivilegeCheckPatchCodeLen,&SeSinglePrivilegeCheckRet);
    if(bRet)
    {
        bRet = FALSE;
        bRet = HookFunctionByHeaderAddress(
            NewSeSinglePrivilegeCheck,
            ulReloadSeSinglePrivilegeCheck,
            SeSinglePrivilegeCheckHookZone,
            &SeSinglePrivilegeCheckPatchCodeLen,
            &SeSinglePrivilegeCheckRet
            );
        if (bRet)
        {
            SeSinglePrivilegeCheckHooked = TRUE;
            //DbgPrint("hook SeSinglePrivilegeCheck success\n");
        }
    }
    return STATUS_SUCCESS;
}
 
//权限检查的时候返回失败来达到禁止加载驱动
BOOLEAN __stdcall NewSeSinglePrivilegeCheck(
    __in  LUID PrivilegeValue,
    __in  KPROCESSOR_MODE PreviousMode
    )
{
    ULONG ulPage;
 
    if (!bIsInitSuccess)
        goto _FunctionRet;
 
    //取返回地址
    [COLOR="Red"]_asm
    {
        mov eax,dword ptr[ebp+4]
        mov ulPage,eax
    }[/COLOR]
    //KdPrint(("ulPage:%08x\r\n",ulPage));
    //RPsGetCurrentProcess = ReLoadNtosCALL(L"PsGetCurrentProcess",SystemKernelModuleBase,ImageModuleBase);
    if (!RPsGetCurrentProcess)
    {
        goto _FunctionRet;
    }
    if (RPsGetCurrentProcess() == ProtectEProcess)
    {
        goto _FunctionRet;
    }
 
    [COLOR="red"]if (ulPage >= ulNtLoadDriverBase && ulPage <= ulNtLoadDriverBase+ulNtLoadDriverSize)
        return FALSE;[/COLOR]
     
    if (ulPage >= ulZwSetSystemInformationBase && ulPage <= ulZwSetSystemInformationBase+ulZwSetSystemInformationSize)
        return FALSE;
 
_FunctionRet:
    OldSeSinglePrivilegeCheck = (SeSinglePrivilegeCheck_1)SeSinglePrivilegeCheckHookZone;
    return OldSeSinglePrivilegeCheck(
        PrivilegeValue,
        PreviousMode
        );
}
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
#include <windows.h>
#include <stdio.h>
 
typedef struct _LSA_UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PVOID Buffer;
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING;
 
typedef LSA_UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;
 
// 申明ntdll中使用的函数
typedef DWORD (CALLBACK* RTLANSISTRINGTOUNICODESTRING)(PVOID, PVOID,DWORD);
RTLANSISTRINGTOUNICODESTRING RtlAnsiStringToUnicodeString;
typedef DWORD (CALLBACK* RTLFREEUNICODESTRING)(PVOID);
RTLFREEUNICODESTRING RtlFreeUnicodeString;
typedef DWORD (CALLBACK* ZWLOADDRIVER)(PVOID);
ZWLOADDRIVER ZwLoadDriver;
 
int LoadDriver(char * szDrvName, char * szDrvPath)
{
    //修改注册表启动驱动程序
    char szSubKey[200], szDrvFullPath[256];
    LSA_UNICODE_STRING buf1;
    LSA_UNICODE_STRING buf2;
    int iBuffLen;
    HKEY hkResult;
    char Data[4];
    DWORD dwOK;
    iBuffLen = sprintf(szSubKey,"System//CurrentControlSet//Services//%s",szDrvName);
    szSubKey[iBuffLen]=0;
    dwOK = RegCreateKey(HKEY_LOCAL_MACHINE,szSubKey,&hkResult);
    if(dwOK!=ERROR_SUCCESS)
        return false;
    Data[0]=1;
    Data[1]=0;
    Data[2]=0;
    Data[3]=0;
    dwOK=RegSetValueEx(hkResult,"Type",0,4,(const unsigned char *)Data,4);
    dwOK=RegSetValueEx(hkResult,"ErrorControl",0,4,(const unsigned char *)Data,4);
    dwOK=RegSetValueEx(hkResult,"Start",0,4,(const unsigned char *)Data,4);
    GetFullPathName(szDrvPath, 256, szDrvFullPath, NULL);  
    printf("Loading driver: %s/r/n", szDrvFullPath);
    iBuffLen = sprintf(szSubKey,"//??//%s",szDrvFullPath);
    szSubKey[iBuffLen]=0;
    dwOK=RegSetValueEx(hkResult,"ImagePath",0,1,(const unsigned char *)szSubKey,iBuffLen);
    RegCloseKey(hkResult);
    iBuffLen = sprintf(szSubKey,"//Registry//Machine//System//CurrentControlSet//Services//%s",szDrvName);
    szSubKey[iBuffLen]=0;
    buf2.Buffer = (PVOID)szSubKey;
    buf2.Length = iBuffLen;
    RtlAnsiStringToUnicodeString(&buf1,&buf2,1);
    //加载驱动程序
    dwOK = ZwLoadDriver(&buf1);
    RtlFreeUnicodeString(&buf1);
    iBuffLen=sprintf(szSubKey,"%s%s//Enum","System//CurrentControlSet//Services//",szDrvName);
    szSubKey[iBuffLen]=0;
    //删除注册表项
    RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey);
    iBuffLen=sprintf(szSubKey,"%s%s//Security","System//CurrentControlSet//Services//",szDrvName);
    szSubKey[iBuffLen]=0;
    RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey);
    iBuffLen=sprintf(szSubKey,"%s%s","System//CurrentControlSet//Services//",szDrvName);
    szSubKey[iBuffLen]=0;
    RegDeleteKey(HKEY_LOCAL_MACHINE,szSubKey);
    iBuffLen=sprintf(szSubKey,"////.//%s",szDrvName);
    szSubKey[iBuffLen]=0;
    return true;
}
 
int main(int argc, char *argv[])
{
    printf("Load driver with ZwLoadDriver( )/r/n");
    printf("Date: 8th May 2007/r/n");
    printf("Modifed by: GaRY <wofeiwo_at_gmail_dot_com>/r/n/r/n");
    if(argc != 3)
    {
        printf("Usage: %s <DriverFilename> <DriverPath>/r/n", argv[0]);
        exit(-1);
    }
    HMODULE hNtdll = NULL;
    hNtdll = LoadLibrary( "ntdll.dll" );
     
    //从ntdll.dll里获取函数
    if ( !hNtdll )
    {
        printf( "LoadLibrary( NTDLL.DLL ) Error:%d/n", GetLastError() );
        return false;
    }
 
    RtlAnsiStringToUnicodeString = (RTLANSISTRINGTOUNICODESTRING)
        GetProcAddress( hNtdll, "RtlAnsiStringToUnicodeString");
    RtlFreeUnicodeString = (RTLFREEUNICODESTRING)
        GetProcAddress( hNtdll, "RtlFreeUnicodeString");
    ZwLoadDriver = (ZWLOADDRIVER)
        GetProcAddress( hNtdll, "ZwLoadDriver");
 
    //注册驱动程序
    if(LoadDriver(argv[1], argv[2]) == false) return false;
    return true;
}

[注意]看雪招聘,专注安全领域的专业人才平台!

上传的附件:
收藏
免费 3
支持
分享
赞赏记录
参与人
雪币
留言
时间
飘零丶
为你点赞~
2024-5-31 05:42
shinratensei
为你点赞~
2024-5-31 05:34
PLEBFE
为你点赞~
2023-2-25 04:40
最新回复 (9)
雪    币: 1372
活跃值: (5722)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
2
太监了?
2015-9-21 10:43
0
雪    币: 334
活跃值: (92)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
没有啊,正在编辑你就来了
2015-9-21 10:47
0
雪    币: 220
活跃值: (831)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
能再兼容下X64就好了
2015-9-21 11:00
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
学习了.............
2015-9-21 11:07
0
雪    币: 334
活跃值: (92)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
6
听说win7以后64位不太好hook,也不知道真假
2015-9-21 11:08
0
雪    币: 1372
活跃值: (5722)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
7
有pg保护 半小时监测一下,改了就蓝屏
2015-9-21 11:13
0
雪    币: 300
活跃值: (2692)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
mark
2015-9-21 11:19
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
原来是半小时监测一下
2015-9-21 14:10
0
雪    币: 334
活跃值: (92)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
10
印象中都不记得写过这个帖子了
2018-3-1 14:35
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册