Windows 回调监控 <二>
在之前的文章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 回调监控 <二>的更多相关文章
- Windows 回调监控 <一>
在x86的体系结构中,我们常用hook关键的系统调用来达到对系统的监控,但是对于x64的结构,因为有PatchGuard的存在,对于一些系统关键点进行hook是很不稳定的,在很大几率上会导致蓝屏的发生 ...
- paip.windows io监控总结
paip.windows io监控总结 io的主要参数是个.disk queue length 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专 ...
- C# Windows IPSEC监控(仅此一家,别无分店)
Windows IPSEC监控,使用C#编写,输出为一行字符串,可以按照既有IPSEC规则生成模板 using System; using System.Diagnostics; using Syst ...
- windows 进程监控 Procmon.exe
windows 进程监控 Procmon.exe window下一个程序打开太慢,可以用此程序监控.在哪一步慢了,读取文件还是注册表. ProcessMonitor3.2 Process Monito ...
- Windows性能计数器监控实践
Windows性能计数器(Performance Counter)是Windows提供的一种系统功能,它能实时采集.分析系统内的应用程序.服务.驱动程序等的性能数据,以此来分析系统的瓶颈.监控组件的表 ...
- python对 windows系统监控插件
在python编程的windows系统监控中,需要监控监控硬件信息需要两个模块:WMI 和 pypiwin32 .
- Win64 驱动内核编程-15.回调监控注册表
回调监控注册表 在 WIN32 平台上,监控注册表的手段通常是 SSDT HOOK.不过用 SSDT HOOK 的方式监控注册表实在是太麻烦了,要 HOOK 一大堆函数,还要处理一些 NT6 系统有而 ...
- Win64 驱动内核编程-14.回调监控文件
回调监控文件 使用 ObRegisterCallbacks 实现保护进程,其实稍微 PATCH 下内核,这个函数还能实现文件操作监视.但可惜只能在 WIN7X64 上用.因为在 WIN7X64 上 P ...
- Win64 驱动内核编程-12.回调监控进线程创建和退出
回调监控进线程创建和退出 两个注册回调的函数:PsSetCreateProcessNotifyRoutine 进程回调PsSetCreateThreadNotifyRoutine 线程回调分 ...
随机推荐
- iOS学习之UI可视化编程-XIB
一.Interface Builder可视化编程 1.Interface Builder简介: GUI:图形用户界面(Graphical User Interface,简称GUI,又称图形用户接口)是 ...
- 取精华、去糟粕!适合iOS开发者的15大网站推荐
iOS开发者若想使技艺达到炉火纯青的地步,就要不断借鉴他人的有益经验,紧跟新兴科技和工具的步伐.除了Apple的开发者中心,其他网站上的文章和资源也具备参考价值,若能学得一二,必能锦上添花.不过,时间 ...
- Swift Tips - 当 Swift 遇上 CocoaPods
CocoaPods 作为 iOS 开发的包管理工具,几乎成为了 Objective-C 的行业标准.它为我们提供了非常方便的包管理功能.而苹果正式发布 Swift 语言也已经有半年多时间了,Swift ...
- MVC4.0 利用HandleErrorAttribute和log4net实现记录异常日志功能
1.MVC4.0中HandleErrorAttribte已经帮我们处理了异常问题,当我们新建一个非空的MVC项目时候,在FilterConfig中会发现这样的代码 public class Filte ...
- 在线演示平台 | Highcharts中文网 (曲线图、区域图、3D图等等)
http://www.hcharts.cn/ 在线演示平台 | Highcharts中文网
- [转]ubuntu server上网配置
[转]ubuntu server上网配置 http://blog.sina.com.cn/s/blog_6c9d65a101011pyt.html 今天我的ubuntu server上不去网了,所以重 ...
- [转]Linux Ubuntu上架设FTP
Linux Ubuntu上架设FTP http://www.blogjava.net/stonestyle/articles/369104.html 操作系统:ubuntu (GNU/Linux) 为 ...
- 12.Warning (15714): Some pins have incomplete I/O assignments. Refer to the I/O Assignment Warnings report for details
解释:对于一些管脚,缺少了部分描述,需要再添加一些设置,比如current strength,slew rate等: 措施:打开pin plannel界面,在current strength和slew ...
- JAVA类与对象(十)-----抽象类
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类除了不能实例化对象之外, ...
- linux - 自动删除n天前日志
1.删除文件命令: find 对应目录 -mtime +天数 -name "文件名" -exec rm -rf {} \; 实例命令: find /opt/soft/log/ -m ...