在之前的文章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[]={};
PEPROCESS TatgetProcess = NULL;
KAPC_STATE apcState;
BOOLEAN bAttached =FALSE;
HANDLE hProcess;
Status = PsLookupProcessByProcessId(ProcessId,&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,
&hProcess
);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(TatgetProcess);
return;
}
g_TargetProcess = TatgetProcess;
__try
{
//KeStackAttachProcess(TatgetProcess,&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+);//加上自己的 Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &lpNewImportDesc, , &nNewImportSize,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(TatgetProcess);
ObDereferenceObject(TatgetProcess);
return;
}
RtlZeroMemory(lpNewImportDesc,nNewImportSize); Status = ZwAllocateVirtualMemory(hProcess, &lpDllName, , &nNewDllNameSize,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
ZwFreeVirtualMemory(hProcess,&lpNewImportDesc,,MEM_RELEASE);
ObDereferenceObject(TatgetProcess);
ObDereferenceObject(TatgetProcess);
return;
} RtlZeroMemory(lpDllName,nNewDllNameSize); //ThunkData
Status = ZwAllocateVirtualMemory(hProcess, &lpNewThunkData, , &nNewThunkDataSize,
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
ZwFreeVirtualMemory(hProcess,&lpNewImportDesc,,MEM_RELEASE);
ZwFreeVirtualMemory(hProcess,&lpDllName,,MEM_RELEASE);
ObDereferenceObject(TatgetProcess);
ObDereferenceObject(TatgetProcess);
return;
}
RtlZeroMemory(lpNewThunkData,nNewThunkDataSize);
//IMAGE_IMPORT_BY_NAME
Status = ZwAllocateVirtualMemory(hProcess, &lpImportApi, , &nNewImportApiSize,
MEM_COMMIT|MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
ZwFreeVirtualMemory(hProcess,&lpNewImportDesc,,MEM_RELEASE);
ZwFreeVirtualMemory(hProcess,&lpDllName,,MEM_RELEASE);
ZwFreeVirtualMemory(hProcess,&lpNewThunkData,,MEM_RELEASE);
ObDereferenceObject(TatgetProcess);
ObDereferenceObject(TatgetProcess);
return;
}
RtlZeroMemory(lpImportApi,nNewImportApiSize);
//原始的导入表,留出一个表项
RtlCopyMemory(lpNewImportDesc+,pImportDesc,sizeof(IMAGE_IMPORT_DESCRIPTOR)*nImportDllCount);
lpImportApi->Hint = ;
RtlCopyMemory(lpImportApi->Name,"DllMain",0x20);
lpNewThunkData->u1.AddressOfData = (ULONG)lpImportApi-(ULONG)ulImageBase;
Add_ImportDesc.OriginalFirstThunk = (ULONG)lpNewThunkData-(ULONG)ulImageBase;
Add_ImportDesc.TimeDateStamp = ;
Add_ImportDesc.ForwarderChain = ;
RtlCopyMemory(lpDllName,"test.dll",0x20);
Add_ImportDesc.Name = (ULONG)lpDllName-(ULONG)ulImageBase;
Add_ImportDesc.FirstThunk = Add_ImportDesc.OriginalFirstThunk;
RtlCopyMemory(lpNewImportDesc,&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(&apcState);
}__except(EXCEPTION_EXECUTE_HANDLER){
}
ObDereferenceObject(TatgetProcess);
}
} ObDereferenceObject(TatgetProcess);
} VOID WPOFF()
{
ULONG_PTR cr0 = ;
Irql = KeRaiseIrqlToDpcLevel();
cr0 =__readcr0();
cr0 &= 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(&ansiTemp,uniSource,TRUE); strcpy(szDest,ansiTemp.Buffer);
RtlFreeAnsiString(&ansiTemp);
}

Windows 回调监控 <二>的更多相关文章

  1. Windows 回调监控 <一>

    在x86的体系结构中,我们常用hook关键的系统调用来达到对系统的监控,但是对于x64的结构,因为有PatchGuard的存在,对于一些系统关键点进行hook是很不稳定的,在很大几率上会导致蓝屏的发生 ...

  2. paip.windows io监控总结

    paip.windows io监控总结 io的主要参数是个.disk queue length 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专 ...

  3. C# Windows IPSEC监控(仅此一家,别无分店)

    Windows IPSEC监控,使用C#编写,输出为一行字符串,可以按照既有IPSEC规则生成模板 using System; using System.Diagnostics; using Syst ...

  4. windows 进程监控 Procmon.exe

    windows 进程监控 Procmon.exe window下一个程序打开太慢,可以用此程序监控.在哪一步慢了,读取文件还是注册表. ProcessMonitor3.2 Process Monito ...

  5. Windows性能计数器监控实践

    Windows性能计数器(Performance Counter)是Windows提供的一种系统功能,它能实时采集.分析系统内的应用程序.服务.驱动程序等的性能数据,以此来分析系统的瓶颈.监控组件的表 ...

  6. python对 windows系统监控插件

    在python编程的windows系统监控中,需要监控监控硬件信息需要两个模块:WMI 和 pypiwin32 .

  7. Win64 驱动内核编程-15.回调监控注册表

    回调监控注册表 在 WIN32 平台上,监控注册表的手段通常是 SSDT HOOK.不过用 SSDT HOOK 的方式监控注册表实在是太麻烦了,要 HOOK 一大堆函数,还要处理一些 NT6 系统有而 ...

  8. Win64 驱动内核编程-14.回调监控文件

    回调监控文件 使用 ObRegisterCallbacks 实现保护进程,其实稍微 PATCH 下内核,这个函数还能实现文件操作监视.但可惜只能在 WIN7X64 上用.因为在 WIN7X64 上 P ...

  9. Win64 驱动内核编程-12.回调监控进线程创建和退出

    回调监控进线程创建和退出 两个注册回调的函数:PsSetCreateProcessNotifyRoutine   进程回调PsSetCreateThreadNotifyRoutine    线程回调分 ...

随机推荐

  1. iOS学习之事件处理

    一.事件的基本概念      1.事件概述 事件是当用户手指触击屏幕及在屏幕上移动时,系统不断发送给应用程序的对象. 系统将事件按照特定的路径传递给可以对其进行处理的对象. 在iOS汇总,一个UITo ...

  2. C#中的委托与事件

    1,委托? 通俗来讲,就是一个能存放符合某种格式(签名)的方法的指针 的容器  (可以将方法作为一个参数来传递到另一个方法内执行) 定义委托:delegate string DelegateSayHi ...

  3. [超简洁]EasyQ框架-应对WEB高并发业务(秒杀、抽奖)等业务

    背景介绍 这几年一直在摸索一种框架,足够简单,又能应付很多高并发高性能的需求.研究过一些框架思想如DDD DCI,也实践过CQRS框架. 但是总觉得复杂度高,门槛也高,自己学都吃力,如果团队新人更难接 ...

  4. 失败的数据库迁移UDB

    公司采用的是ucloud的云主机,数据库也是架设在云主机上.由于数据越来越多数据查询数据越来越慢,所以我决定往 UDB上迁移.当时考虑的理由如下: (1)云主机底层架设在虚拟机上IO性能有折损,而UD ...

  5. Android编程: MVC模式、应用的生命周期

    学习内容:Android的应用剖析.MVC模式.应用的生命周期 ====Android的应用剖析==== 一个Android应用程序会使用如下组件: Android Activities   界面 A ...

  6. Capacity Scheduler 队列设置

    先附一个官网地址 Capacity Scheduler是YARN中默认的资源调度器. 相关参数配置: 资源分配相关参数 ``` (1) capacity:队列的资源容量(百分比). 当系统非常繁忙时, ...

  7. Html5 常见的新增API详解

    1. getElementsByClassName()方法 getElementsByClassName()方法接收一个参数,即一个包含一或多个类名的字符串,返回带有指定类的所有元素的NodeList ...

  8. mysql 触发器的使用(备忘)

    触发器创建语法四要素: 1.监视地点(table) 2.监视事件(insert/update/delete) 3.触发时间(after/before) 4.触发事件(insert/update/del ...

  9. 怎么将java项目打包成双击就可以运行的jar包---fatjar

    fatjar下载地址:http://pan.baidu.com/s/1cQ01o 下载fatJar插件,解压缩后是一个.../plugins/(net...)把plugins下面的(net..)文件夹 ...

  10. Careercup - Google面试题 - 5377673471721472

    2014-05-08 22:42 题目链接 原题: How would you split a search query across multiple machines? 题目:如何把一个搜索que ...