看流星社区

 找回密码
 注册账号
查看: 1702|回复: 0

Windows 回调监控

[复制链接]

该用户从未签到

发表于 2017-6-1 17:25:37 | 显示全部楼层 |阅读模式
在之前的文章Windows 回调监控 <一>总结了关于CreateProcessNotify,CreateProcessNotifyEx和LoadImageNotify一些用法,之后产生了一个思路,既然在进程创建的时候加载.exe文件会执行我们的回调函数,那么如果在我们回调函数之中对内存中的.exe文件的导入表增加一个项,这样进程会不会加载我们事先准备好的.dll文件,如果成功加载我们的dll话,就注入成功了。



#pragma once

#include <ntifs.h>
#include <ntimage.h>
#include <WINDEF.H>

VOID WPOFF();
VOID WPON();
VOID UnloadDriver(PDRIVER_OBJECT DriverObject);
VOID LoadImageNotifyRoutine(PUNICODE_STRING FullImageName,HANDLE  ProcessId,PIMAGE_INFO  ImageInfor);
extern CHAR*  PsGetProcessImageFileName(PEPROCESS EProcess);
VOID UnicodeToChar(PUNICODE_STRING uniSource, CHAR *szDest);

#include "LoadImage.h"


PIMAGE_IMPORT_DESCRIPTOR g_OldImportDesc;
KIRQL Irql;
PEPROCESS g_TargetProcess;
HANDLE    g_TargetProcessId;

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegisterPath)
{

    DbgPrint("驱动加载\r\n");
    DriverObject->DriverUnload = UnloadDriver;
    PsSetLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)LoadImageNotifyRoutine);
    return STATUS_SUCCESS;
}

VOID UnloadDriver(PDRIVER_OBJECT DriverObject)
{
    PsRemoveLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)LoadImageNotifyRoutine);
    DbgPrint("驱动卸载\r\n");
}



VOID LoadImageNotifyRoutine(PUNICODE_STRING FullImageName,HANDLE  ProcessId,PIMAGE_INFO  ImageInfor)
{
    NTSTATUS Status;
    PVOID DriverEntryAddress = NULL;
    char szFullImageName[260]={0};
    PEPROCESS TatgetProcess = NULL;
    KAPC_STATE apcState;
    BOOLEAN       bAttached =FALSE;
    HANDLE    hProcess;
    Status  = PsLookupProcessByProcessId(ProcessId,&amp;TatgetProcess);
    if (!NT_SUCCESS(Status))
    {
        return ;
    }
    if (strstr(PsGetProcessImageFileName(TatgetProcess),"cc.exe")) //当前进程是cc.exe
    {
        UnicodeToChar(FullImageName,szFullImageName);

        if (strstr(szFullImageName,"cc.exe"))  //加载的是cc.exe
        {
            g_TargetProcessId = ProcessId;
            Status = ObOpenObjectByPointer(TatgetProcess,
                OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                NULL,
                GENERIC_ALL,
                *PsProcessType,
                KernelMode,
                &amp;hProcess
                );
            if (!NT_SUCCESS(Status))
            {
                ObDereferenceObject(TatgetProcess);
                return;
            }
            g_TargetProcess = TatgetProcess;
            __try
            {
                //KeStackAttachProcess(TatgetProcess,&amp;apcState);
                if (MmIsAddressValid(ImageInfor->ImageBase))
                {
                    PIMAGE_DOS_HEADER pDos;
                    PIMAGE_NT_HEADERS pHeader = NULL;
                    PIMAGE_IMPORT_DESCRIPTOR  pImportDesc;
                    //ZwUnmapViewOfSection(hProcess,ImageInfor->ImageBase);
                    ULONG nImportDllCount;
                    PVOID ulImageBase = ImageInfor->ImageBase;
                    ULONG nNewImportSize;
                    ULONG nNewDllNameSize = 0x20;
                    PIMAGE_IMPORT_DESCRIPTOR lpNewImportDesc = NULL;
                    PVOID lpDllName = NULL;
                    IMAGE_IMPORT_DESCRIPTOR Add_ImportDesc;
                    PIMAGE_THUNK_DATA        lpNewThunkData = NULL;
                    ULONG nNewThunkDataSize = 0x20;
                    PIMAGE_IMPORT_BY_NAME lpImportApi = NULL;
                    ULONG nNewImportApiSize  = 0x20;
                    pDos =(PIMAGE_DOS_HEADER) ulImageBase;

                    pHeader = (PIMAGE_NT_HEADERS)((ULONG)ulImageBase+(ULONG)pDos->e_lfanew);
                    pImportDesc  = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress \
                        + (ULONG)ulImageBase);
                    //导入表项个数
                    nImportDllCount = pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);

                    g_OldImportDesc = pImportDesc;//原始的导入表

                    nNewImportSize = sizeof(IMAGE_IMPORT_DESCRIPTOR)*(nImportDllCount+1);//加上自己的

                    Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &amp;lpNewImportDesc, 0, &amp;nNewImportSize,
                        MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                    if (!NT_SUCCESS(Status))
                    {
                        ObDereferenceObject(TatgetProcess);
                        ObDereferenceObject(TatgetProcess);
                        return;
                    }
                    RtlZeroMemory(lpNewImportDesc,nNewImportSize);

                    Status = ZwAllocateVirtualMemory(hProcess, &amp;lpDllName, 0, &amp;nNewDllNameSize,
                        MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                    if (!NT_SUCCESS(Status))
                    {
                        ZwFreeVirtualMemory(hProcess,&amp;lpNewImportDesc,0,MEM_RELEASE);
                        ObDereferenceObject(TatgetProcess);
                        ObDereferenceObject(TatgetProcess);
                        return;
                    }

                    RtlZeroMemory(lpDllName,nNewDllNameSize);

                    //ThunkData
                    Status = ZwAllocateVirtualMemory(hProcess, &amp;lpNewThunkData, 0, &amp;nNewThunkDataSize,
                        MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                    if (!NT_SUCCESS(Status))
                    {
                        ZwFreeVirtualMemory(hProcess,&amp;lpNewImportDesc,0,MEM_RELEASE);
                        ZwFreeVirtualMemory(hProcess,&amp;lpDllName,0,MEM_RELEASE);
                        ObDereferenceObject(TatgetProcess);
                        ObDereferenceObject(TatgetProcess);
                        return;
                    }
                    RtlZeroMemory(lpNewThunkData,nNewThunkDataSize);                    
                    //IMAGE_IMPORT_BY_NAME
                    Status = ZwAllocateVirtualMemory(hProcess, &amp;lpImportApi, 0, &amp;nNewImportApiSize,
                        MEM_COMMIT|MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
                    if (!NT_SUCCESS(Status))
                    {
                        ZwFreeVirtualMemory(hProcess,&amp;lpNewImportDesc,0,MEM_RELEASE);
                        ZwFreeVirtualMemory(hProcess,&amp;lpDllName,0,MEM_RELEASE);
                        ZwFreeVirtualMemory(hProcess,&amp;lpNewThunkData,0,MEM_RELEASE);
                        ObDereferenceObject(TatgetProcess);
                        ObDereferenceObject(TatgetProcess);
                        return;
                    }
                    RtlZeroMemory(lpImportApi,nNewImportApiSize);
                    //原始的导入表,留出一个表项
                    RtlCopyMemory(lpNewImportDesc+1,pImportDesc,sizeof(IMAGE_IMPORT_DESCRIPTOR)*nImportDllCount);
                    lpImportApi->Hint = 0;
                    RtlCopyMemory(lpImportApi->Name,"DllMain",0x20);
                    lpNewThunkData->u1.AddressOfData = (ULONG)lpImportApi-(ULONG)ulImageBase;               
                    Add_ImportDesc.OriginalFirstThunk = (ULONG)lpNewThunkData-(ULONG)ulImageBase;
                    Add_ImportDesc.TimeDateStamp = 0;
                    Add_ImportDesc.ForwarderChain = 0;
                    RtlCopyMemory(lpDllName,"test.dll",0x20);
                    Add_ImportDesc.Name = (ULONG)lpDllName-(ULONG)ulImageBase;
                    Add_ImportDesc.FirstThunk = Add_ImportDesc.OriginalFirstThunk;                    
                    RtlCopyMemory(lpNewImportDesc,&amp;Add_ImportDesc,sizeof(IMAGE_IMPORT_DESCRIPTOR));
                    WPOFF(); //修改Descriptor
                    pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size += sizeof(IMAGE_IMPORT_DESCRIPTOR);
                    pHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = (ULONG_PTR)lpNewImportDesc - (ULONG_PTR)ulImageBase;
                    WPON();

                }
                //KeUnstackDetachProcess(&amp;apcState);
            }__except(EXCEPTION_EXECUTE_HANDLER){
            }
            ObDereferenceObject(TatgetProcess);
        }
    }

    ObDereferenceObject(TatgetProcess);
}

VOID WPOFF()
{
    ULONG_PTR cr0 = 0;
    Irql = KeRaiseIrqlToDpcLevel();
    cr0 =__readcr0();
    cr0 &amp;= 0xfffffffffffeffff;
    __writecr0(cr0);

}


VOID WPON()
{

    ULONG_PTR cr0=__readcr0();
    cr0 |= 0x10000;
    __writecr0(cr0);
    KeLowerIrql(Irql);
}

VOID UnicodeToChar(PUNICODE_STRING uniSource, CHAR *szDest)
{                                                  
    ANSI_STRING ansiTemp;                                
    RtlUnicodeStringToAnsiString(&amp;ansiTemp,uniSource,TRUE);   

    strcpy(szDest,ansiTemp.Buffer);
    RtlFreeAnsiString(&amp;ansiTemp);
}[/code]
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 16:33

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表