首页
社区
课程
招聘
[原创]监控系统加载模块-猥琐流
发表于: 2013-3-14 11:17 21494

[原创]监控系统加载模块-猥琐流

2013-3-14 11:17
21494
#include <ntddk.h>
#include "nt_help.h"

DRIVER_INITIALIZE DriverEntry;

typedef struct _OBJECT_TYPE_INITIALIZER {
    USHORT Length;
    BOOLEAN UseDefaultObject;
    BOOLEAN CaseInsensitive;
#if WINVER>=0x0600
    ULONG ObjectTypeCode;
#endif
    ULONG InvalidAttributes;
    GENERIC_MAPPING GenericMapping;
    ULONG ValidAccessMask;
    BOOLEAN SecurityRequired;
    BOOLEAN MaintainHandleCount;
    BOOLEAN MaintainTypeList;
    POOL_TYPE PoolType;
    ULONG DefaultPagedPoolCharge;
    ULONG DefaultNonPagedPoolCharge;
    PVOID DumpProcedure;
    PVOID OpenProcedure;
    PVOID CloseProcedure;
    PVOID DeleteProcedure;
    PVOID ParseProcedure;
    PVOID SecurityProcedure;
    PVOID QueryNameProcedure;
    PVOID OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;

typedef struct _OBJECT_TYPE {
#if WINVER<0x0600
    ERESOURCE Mutex;
#endif
    LIST_ENTRY TypeList;
    UNICODE_STRING Name;            // Copy from object header for convenience
    PVOID DefaultObject;
    ULONG Index;
    ULONG TotalNumberOfObjects;
    ULONG TotalNumberOfHandles;
    ULONG HighWaterNumberOfObjects;
    ULONG HighWaterNumberOfHandles;
    OBJECT_TYPE_INITIALIZER TypeInfo;
} OBJECT_TYPE, *POBJECT_TYPE;

extern POBJECT_TYPE* MmSectionObjectType;
PVOID pNtCreateSection = NULL;
SYSTEM_MODULE_INFORMATION ntModInfo = {0};

#pragma alloc_text(INIT, DriverEntry)

NTSTATUS DevicePassthrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
        NTSTATUS status = STATUS_SUCCESS;
        PIO_STACK_LOCATION  irpSp;
        
        irpSp = IoGetCurrentIrpStackLocation(Irp);
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
}

VOID DriverUnload (IN PDRIVER_OBJECT DriverObject)
{
        (*MmSectionObjectType)->TypeInfo.OpenProcedure = NULL;
        KdPrint(("DriverUnload Done!\n"));
}

#if WINVER>=0x0600
NTSTATUS HookSectionOpen(
    IN ULONG OpenReason,
    IN ULONG AccessMode,
    IN PEPROCESS Process OPTIONAL,
    IN PVOID Object,
    IN ACCESS_MASK* GrantedAccess,
    IN ULONG HandleCount
    )
#else
NTSTATUS HookSectionOpen(
    IN ULONG OpenReason,
    IN PEPROCESS Process OPTIONAL,
    IN PVOID Object,
    IN ACCESS_MASK GrantedAccess,
    IN ULONG HandleCount
    )
#endif
{
        PVOID* esp = (PVOID*)&esp;
        PVOID* esp_end = (PVOID*)((((DWORD64)esp>>12) + 1)<<12);        //4k round up
        PVOID* p = esp;
        ULONG SectionPageProtection, AllocationAttributes;
        HANDLE FileHandle;
        NTSTATUS Status;

        /* 
         * do stack walk back to NtCreateSection function
         */
        while (p < esp_end && 
                (*p < pNtCreateSection || 
                 *p > (PVOID)((PBYTE)pNtCreateSection + 0x300)))
                p++;

        if (p >= esp_end){
                //KdPrint(("no found NtCreateSection %p -> %p\n", esp, esp_end));
                return STATUS_SUCCESS;
        }

        //KdPrint(("%p HookSectionOpen-Object:%p esp:%p %p\n", pNtCreateSection, Object, esp, *p));
#ifdef _WIN64
        /* 
         * esp layout look likes[2003 X64 DUMP]:
         fffff800`0104113d nt!KiSystemServiceCopyEnd+0x3 retaddr <-------call nt!NtCreateSection
         fffffadf`f662ec00  00000000`00000000 param1
         fffffadf`f662ec08  00000000`000f001f param2 DesiredAccess
         fffffadf`f662ec10  00000000`00000000
         fffffadf`f662ec18  00000000`00000000
         fffffadf`f662ec20  00000100`00000010 SectionPageProtection
         fffffadf`f662ec28  00000000`01000000 AllocationAttributes
         fffffadf`f662ec30  00000000`0000054c FileHandle
         * - ... 
         */
        p++;
        /*
         * search retaddr -> nt!KiSystemServiceCopyEnd
         */
        while (p < esp_end &&
                (*p < ntModInfo.ImageBase || 
                 *p > (PVOID)((PBYTE)ntModInfo.ImageBase + ntModInfo.ImageSize)))
                p++;

        if (p >= esp_end){
                //KdPrint(("no found nt!KiSystemxxxx %p -> %p\n", esp, esp_end));
                return STATUS_SUCCESS;
        }
#else
        /* stack DUMP from 2003/x86 
         * ebp = p - 1
         fa06f4d8  fa06f540
         fa06f4dc  80908715 nt!NtCreateSection+0x15c
         ...
         fa06f540  fa06f564
         fa06f544  808234cb nt!KiFastCallEntry+0xf8
         fa06f548  fa06f668 param1
         */
        p = (PVOID*)*(p - 1);
        p++;
#endif

        SectionPageProtection = (ULONG)*(p + 5);
        AllocationAttributes = (ULONG)*(p + 6);
        FileHandle = *(p + 7); 

        //KdPrint(("%x %x %p\n", SectionPageProtection, AllocationAttributes, FileHandle));

        if (FileHandle 
                && SectionPageProtection == PAGE_EXECUTE
                && (AllocationAttributes == SEC_IMAGE || AllocationAttributes == 0x100000)){
                /* windows7 AllocationAttributes = 0x100000 to LoadDriver */
                PFILE_OBJECT File;

                Status = ObReferenceObjectByHandle (FileHandle, 
                                0, 
                                NULL,
                                KernelMode,
                                (PVOID *)&File,
                                NULL);

                if (!NT_SUCCESS(Status)) {
                        return STATUS_SUCCESS;
                }
                KdPrint(("FileName:%wZ\n", &File->FileName));
                ObDereferenceObject(File);
        }

        return STATUS_SUCCESS;
}

BOOL GetNtImgBase(PSYSTEM_MODULE_INFORMATION modInfo)
{
        PSYSMODULELIST sysModuleList = NULL;
        ULONG size, i;

        NtQuerySystemInformation(SystemModuleInformation, &size, 0, &size);
        sysModuleList = ExAllocatePoolWithTag(PagedPool, size, 'hlpm');

        if (sysModuleList){
                NtQuerySystemInformation(SystemModuleInformation, sysModuleList, size, NULL);
                /* nt module should be the first one */
                *modInfo = *sysModuleList->Modules;
                ExFreePool(sysModuleList);
                return TRUE;
        }
        return FALSE;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
        DWORD i;
        UNICODE_STRING sFuncName;
        
        RtlInitUnicodeString(&sFuncName, L"NtCreateSection");
        pNtCreateSection = MmGetSystemRoutineAddress(&sFuncName);

        if (!GetNtImgBase(&ntModInfo)){
                KdPrint(("EnumSysModule nt base failed!\n"));
                return STATUS_UNSUCCESSFUL;
        }

        KdPrint(("nt:%p pNtCreateSection:%p\nMmSectionObjectType:%p %p %p\n", 
                                ntModInfo.ImageBase, 
                                pNtCreateSection, 
                                *MmSectionObjectType,
                                (*MmSectionObjectType)->TypeInfo.OpenProcedure,
                                (*MmSectionObjectType)->TypeInfo.DeleteProcedure));
        
        (*MmSectionObjectType)->TypeInfo.OpenProcedure = HookSectionOpen;

        for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
                DriverObject->MajorFunction[i] = DevicePassthrough;

        DriverObject->DriverUnload = DriverUnload;

        return STATUS_SUCCESS;
} 

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 6
支持
分享
最新回复 (38)
雪    币: 163
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
谢谢lz分享,收藏了!
2013-3-14 11:21
0
雪    币: 297
活跃值: (265)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
3

谢谢分享
2013-3-14 11:52
0
雪    币: 76
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
这个没有数字签名的问题吗, 在 windows2008 R2 x64 上?
2013-3-14 12:38
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
5
巧妙的利用了stack~~真心给力~
2013-3-14 13:05
0
雪    币: 63
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
mark 留名
2013-3-14 13:14
0
雪    币: 219
活跃值: (783)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
7
老V最近一直都在~紧跟老v
2013-3-14 13:50
0
雪    币: 2314
活跃值: (2205)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
8
学习了,不过话说windows2008 R2 x64 下hook Object OpenProcedure 例程,不会引发Patch guard?
2013-3-14 14:06
0
雪    币: 371
活跃值: (72)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
学习了~~~
2013-3-14 14:15
0
雪    币: 65
活跃值: (112)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
10
一个回调搞定的事情,非得用hook搞这么麻烦干啥。。。。。没hook做不了事情么?
2013-3-14 14:56
0
雪    币: 1233
活跃值: (907)
能力值: ( LV12,RANK:750 )
在线值:
发帖
回帖
粉丝
11
好吧,你要的答案,加上数字签名,正常模式启动windows 2008 R2 64
运行了30多分钟,没有任何异常,PG被无视了
上传的附件:
  • 1.PNG (75.67kb,13次下载)
2013-3-14 15:18
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
12
这不科学啊,竟然有数字签名。
2013-3-14 15:22
0
雪    币: 1233
活跃值: (907)
能力值: ( LV12,RANK:750 )
在线值:
发帖
回帖
粉丝
13
你是说PsSetLoadImageNotifyRoutine吗?我现在是在研究猥琐的办法
我测试了下正统的PsSetLoadImageNotifyRoutine,效果还挺好的哈,建议正规的开发用那个咯
这个属于猥琐技术流派,上不了大堂的,hacker们喜欢就用吧,over
2013-3-14 15:25
0
雪    币: 60
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
真需要啊,顺便问下NP在调试环境下一开就重启,有什么办法?
2013-3-14 15:35
0
雪    币: 143
活跃值: (263)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
15
这几天的精华不少啊 ,表示消化不了
2013-3-14 15:37
0
雪    币: 27
活跃值: (127)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
16
猥琐流派。。
2013-3-14 16:19
0
雪    币: 140
活跃值: (70)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
弱弱的问一句 nt_help.h 哪里搞的?
很久没有摸驱动了。
2013-3-14 17:02
0
雪    币: 1040
活跃值: (1293)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
object HOOK应该是不会触发PG的吧~MJ还是V大以前说过……
2013-3-14 19:21
0
雪    币: 1626
活跃值: (148)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
19
very good

mark
2013-3-14 19:55
0
雪    币: 558
活跃值: (73)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
这个就是object Hook吗?学习了

不过,这里有几点不明白的地方,还望高手指点:

1. HookSectionOpen函数,第一句 这里是为了得到esp变量的堆栈地址?

PVOID* esp = (PVOID*)&esp;


2. 这里的while循环,是为了找出pNtCreateSection 的地址?
那么为什么还要加上*p > (PVOID)((PBYTE)pNtCreateSection + 0x300,p < esp_end 不是已经限制了结束指针?

while (p < esp_end &&
(*p < pNtCreateSection ||
*p > (PVOID)((PBYTE)pNtCreateSection + 0x300)))
p++;


3.  Hook时候,不需要保持原来OpenProcedure的地址,以用于恢复?

4.  HookSectionOpen的返回值,能不能对原来函数的行为进行干预?也就是说可以进行阻止?
2013-3-14 20:49
0
雪    币: 97697
活跃值: (200829)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
21
Thanks for share.
2013-3-14 20:51
0
雪    币: 1233
活跃值: (907)
能力值: ( LV12,RANK:750 )
在线值:
发帖
回帖
粉丝
22
看来你还没有看懂猥琐代码,或者对堆栈结构不是很清楚
1、是获取esp地址
2、pNtCreateSection 是NtCreateSection函数里Call ObInsertObject的返回地址,
NtCreateSection <    pNtCreateSection  < NtCreateSection + 0x300
3、SectionObject本来OpenProcedure就是NULL,就没必要保存了
4、可以阻止,返回不成功即可!
2013-3-14 20:57
0
雪    币: 558
活跃值: (73)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
非常感谢,看来需要点时间消化一下

1. esp是堆栈当前指针,而PVOID* esp = (PVOID*)&esp; 看来对堆栈理解的还不够深入

2. 这里的0x300是一个经验值?看到好多查找函数都这么写的
2013-3-14 21:03
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
24
  看来你没有在64位系统下调过游戏哈,N多保护都是选择object hook来防止打开进程。
2013-3-15 09:08
0
雪    币: 2314
活跃值: (2205)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
25
eg. HP.
2013-3-15 09:48
0
游客
登录 | 注册 方可回帖
返回
//