首页
社区
课程
招聘
[旧帖] [原创]一个PsSetLoadImageNotifyRoutine回调内核注入DLL,支持xp ~ win7源码 0.00雪花
发表于: 2011-9-11 10:43 7351

[旧帖] [原创]一个PsSetLoadImageNotifyRoutine回调内核注入DLL,支持xp ~ win7源码 0.00雪花

2011-9-11 10:43
7351

一个PsSetLoadImageNotifyRoutine回调内核注入DLL,支持xp ~ win7源码

最近看sudimi大牛写的《一个有趣的内核注DLL的sys》文章,确实很有趣,可惜没开源,俺也写个,把完整代码也贴上来了,欢迎拍砖。

安装驱动,打开dbgview.exe,注入mydll.dll!!

VOID Start (
                        IN PUNICODE_STRING  FullImageName,
                        IN HANDLE  ProcessId, // where image is mapped
                        IN PIMAGE_INFO  ImageInfo
                        )
{

        NTSTATUS ntStatus;
        PIMAGE_IMPORT_DESCRIPTOR pImportNew;

        HANDLE hProcessHandle;
        int nImportDllCount = 0;

        int size;

        // PID改变时,可以说明已经注入DLL了。
        if(g_ulPid != (ULONG)ProcessId && g_ulPid != 0 && g_psaveDes != NULL)
        {
                KAPC_STATE apcState;
                BOOLEAN bAttached = FALSE;

                //_asm int 3;

                if(g_psaveDes!= NULL)
                {
                        if(PsGetCurrentProcess() != g_eprocess) {
                                KeStackAttachProcess((PRKPROCESS)g_eprocess, &apcState);
                                bAttached = TRUE;
                        }

                        //
                        __asm {
                                cli;
                                mov eax, cr0;
                                mov oldCr0, eax;
                                and eax, not 10000h;
                                mov cr0, eax
                        }

                        // 改导出表
                        pHeader->OptionalHeader.DataDirectory[1].Size -= sizeof(IMAGE_IMPORT_DESCRIPTOR);
                        pHeader->OptionalHeader.DataDirectory[1].VirtualAddress = (ULONG)g_psaveDes - ulBaseImage;

                        __asm {
                                mov eax, oldCr0;
                                mov cr0, eax;
                                sti;
                        }
                        g_psaveDes = NULL;

                        if(bAttached)
                                KeUnstackDetachProcess(&apcState);

                }
       
                return ;
        }
        // 注入进程没退出。
        if(g_eprocess != NULL)
                return;

        if(_stricmp(PsGetProcessImageFileName(PsGetCurrentProcess()), "dbgview.exe") == 0)
        {
                //_asm int 3;
                g_eprocess = PsGetCurrentProcess();

                g_ulPid = (ULONG )ProcessId;

                ulBaseImage = (ULONG)ImageInfo->ImageBase;// 进程基地址

                pDos =(PIMAGE_DOS_HEADER) ulBaseImage;
                pHeader = (PIMAGE_NT_HEADERS)(ulBaseImage+(ULONG)pDos->e_lfanew);
                pImportDesc  = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)pHeader->OptionalHeader.DataDirectory[1].VirtualAddress + ulBaseImage);

                // 导入DLL个数               
                nImportDllCount = pHeader->OptionalHeader.DataDirectory[1].Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);

                // 把原始值保存。
                g_psaveDes = pImportDesc;

                ntStatus = ObOpenObjectByPointer(g_eprocess, OBJ_KERNEL_HANDLE, NULL, 0x008, //PROCESS_VM_OPERATION
                        NULL, KernelMode, &hProcessHandle);

                if(!NT_SUCCESS(ntStatus))  
                        return ;
                //                                                                                                        加上一个自己的结构。
                size = sizeof(IMAGE_IMPORT_DESCRIPTOR) * (nImportDllCount + 1);

                //  分配导入表
                ntStatus = ZwAllocateVirtualMemory(hProcessHandle, &lpBuffer, 0, &size,
                        MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                if(!NT_SUCCESS(ntStatus)) {
                        ZwClose(hProcessHandle);
                        return ;
                }
                RtlZeroMemory(lpBuffer,sizeof(IMAGE_IMPORT_DESCRIPTOR) * (nImportDllCount + 1));

                size = 20;
                // 分配当前进程空间。
                ntStatus = ZwAllocateVirtualMemory(hProcessHandle, &lpDllName, 0, &size,
                        MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                if(!NT_SUCCESS(ntStatus)) {

                        ZwClose(hProcessHandle);
                        return ;
                }
                RtlZeroMemory(lpDllName,20);

                /* 分配导出函数的进程地址空间。
                        注意这里是分配高位地址的。如分配低位地址,得到PIMAGE_IMPORT_BY_NAME结构的地址会以,如ff等开头的负数地址,
                        这样,系统就会默认按序号查找API地址,会弹出找不到序号的框框。

                */
                size = 20;
                ntStatus = ZwAllocateVirtualMemory(hProcessHandle, &lpExportApi, 0, &size,
                        MEM_COMMIT|MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
                if(!NT_SUCCESS(ntStatus)) {

                        ZwClose(hProcessHandle);
                        return ;
                }
                RtlZeroMemory(lpExportApi,20);

                // 分配当前进程空间。
                size = 20;
                ntStatus = ZwAllocateVirtualMemory(hProcessHandle, &lpTemp, 0, &size,
                        MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                if(!NT_SUCCESS(ntStatus)) {

                        ZwClose(hProcessHandle);
                        return ;
                }
                RtlZeroMemory(lpTemp,20);

                // 分配当前进程空间。
                size = 20;
                ntStatus = ZwAllocateVirtualMemory(hProcessHandle, &lpTemp2, 0, &size,
                        MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                if(!NT_SUCCESS(ntStatus)) {

                        ZwClose(hProcessHandle);
                        return ;
                }
                RtlZeroMemory(lpTemp2,20);

                pImportNew = lpBuffer;

                // 把原来数据保存好。
                RtlCopyMemory(pImportNew+1, pImportDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR) * nImportDllCount );

                // 构造自己的DLL    IMAGE_IMPORT_DESCRIPTOR结构
                {
                        IMAGE_IMPORT_DESCRIPTOR Add_ImportDesc;
                        PULONG ulAddress;
                        ULONG oldCr0;
                        ULONG Func;
                        PIMAGE_IMPORT_BY_NAME ptmp;
                        IMAGE_THUNK_DATA        *pThunkData=(PIMAGE_THUNK_DATA)lpTemp2;

                        //_asm int 3;
                        //
                        // ThunkData结构的地址
                        //
                        ptmp        =        (PIMAGE_IMPORT_BY_NAME)lpExportApi;
                        ptmp->Hint=0;
                        // 至少要一个导出API
                        RtlCopyMemory(ptmp->Name,"ExportedFunction",18);

                        *(PULONG)lpTemp =(DWORD)ptmp-ulBaseImage;
                        pThunkData->u1.AddressOfData        =(DWORD)ptmp-ulBaseImage;
                        //pThunkData[1].u1.AddressOfData        =        0;//导出函数截断
                        Add_ImportDesc.Characteristics = (DWORD)pThunkData-ulBaseImage;

                        Add_ImportDesc.TimeDateStamp = 0;
                        Add_ImportDesc.ForwarderChain = 0;

                        //
                        // DLL名字的RVA
                        //               
                        RtlCopyMemory(lpDllName,"mydll.dll",20);
                        Add_ImportDesc.Name = (DWORD)lpDllName-ulBaseImage;
                        Add_ImportDesc.FirstThunk = Add_ImportDesc.Characteristics;

                        RtlCopyMemory(pImportNew, &Add_ImportDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR));

                        __asm {
                                cli;
                                mov eax, cr0;
                                mov oldCr0, eax;
                                and eax, not 10000h;
                                mov cr0, eax
                        }

                        // 改导出表
                        pHeader->OptionalHeader.DataDirectory[1].Size += sizeof(IMAGE_IMPORT_DESCRIPTOR);
                        pHeader->OptionalHeader.DataDirectory[1].VirtualAddress = (ULONG)pImportNew - ulBaseImage;

                        __asm {
                                mov eax, oldCr0;
                                mov cr0, eax;
                                sti;
                        }

                }
                ZwClose(hProcessHandle);
                hProcessHandle = NULL;
        }
}


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

上传的附件:
收藏
免费 6
支持
分享
最新回复 (12)
雪    币: 280
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
额  又是好大一堆代码  谢谢楼主分享  我在仔细研究下  看能看懂不
2011-9-13 11:34
0
雪    币: 213
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
楼主,请教一下,这种方法为什么每个进程启动的时候第一次修改了, 后面几次不修改,但是导入表的地址也是被修改了的?
2011-12-7 14:05
0
雪    币: 203
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
izc
4
测试 XP WIN7,全部一加载就天蓝蓝
2013-5-29 21:36
0
雪    币: 77
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
mark
2014-1-28 14:32
0
雪    币: 341
活跃值: (85)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
6
能不蓝么= =
2014-6-8 15:31
0
雪    币: 42
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
在研究注入,谢谢奉献
2014-7-20 19:55
0
雪    币: 15
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
远线程注入也不错
2014-7-21 00:15
0
雪    币: 130
活跃值: (402)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
make~~~
2014-10-19 02:53
0
雪    币: 75
活跃值: (105)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
真帅 修改输入表
2014-10-22 11:09
0
雪    币: 59
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
新人前来支持一下
2014-10-22 14:43
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
谢谢楼主,学习中
2014-10-22 15:26
0
雪    币: 42
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
额  又是好大一堆代码
2014-12-4 03:21
0
游客
登录 | 注册 方可回帖
返回
//