过驱动例子
#include "ntifs.h"#include "ntimage.h"
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //仅适用于checked build版本
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
//结构声明
typedef struct _SIGNATURE_INFO{
UCHAR cSingature;
intOffset;
}SIGNATURE_INFO,*PSIGNATURE_INFO;
typedef struct _LDR_DATA_TABLE_ENTRY // 24 elements, 0x78 bytes (sizeof)
{
/*0x000*/ struct _LIST_ENTRY InLoadOrderLinks; // 2 elements, 0x8 bytes (sizeof)
/*0x008*/ PVOID ExceptionTable;
/*0x00C*/ ULONG ExceptionTableSize;
/*0x010*/ struct _LIST_ENTRY InInitializationOrderLinks; // 2 elements, 0x8 bytes (sizeof)
/*0x018*/ VOID* DllBase;
/*0x01C*/ VOID* EntryPoint;
/*0x020*/ ULONG32 SizeOfImage;
/*0x024*/ struct _UNICODE_STRING FullDllName; // 3 elements, 0x8 bytes (sizeof)
/*0x02C*/ struct _UNICODE_STRING BaseDllName; // 3 elements, 0x8 bytes (sizeof)
/*0x034*/ ULONG32 Flags;
/*0x038*/ UINT16 LoadCount;
/*0x03A*/ UINT16 TlsIndex;
union // 2 elements, 0x8 bytes (sizeof)
{
/*0x03C*/ struct _LIST_ENTRY HashLinks; // 2 elements, 0x8 bytes (sizeof)
struct // 2 elements, 0x8 bytes (sizeof)
{
/*0x03C*/ VOID* SectionPointer;
/*0x040*/ ULONG32 CheckSum;
};
};
union // 2 elements, 0x4 bytes (sizeof)
{
/*0x044*/ ULONG32 TimeDateStamp;
/*0x044*/ VOID* LoadedImports;
};
/*0x048*/ VOID* EntryPointActivationContext;
/*0x04C*/ VOID* PatchInformation;
/*0x050*/ struct _LIST_ENTRY ForwarderLinks; // 2 elements, 0x8 bytes (sizeof)
/*0x058*/ struct _LIST_ENTRY ServiceTagLinks; // 2 elements, 0x8 bytes (sizeof)
/*0x060*/ struct _LIST_ENTRY StaticLinks; // 2 elements, 0x8 bytes (sizeof)
/*0x068*/ VOID* ContextInformation;
/*0x06C*/ ULONG32 OriginalBase;
/*0x070*/ union _LARGE_INTEGER LoadTime; // 4 elements, 0x8 bytes (sizeof)
}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef KAFFINITY
(*KESETAFFINITYTHREAD)(
__inout PKTHREAD Thread,
__in KAFFINITY Affinity
);
void PageProtectOn()
{
__asm{//恢复内存保护
moveax,cr0
or eax,10000h
movcr0,eax
sti
}
}
void PageProtectOff()
{
__asm{//去掉内存保护
cli
moveax,cr0
andeax,not 10000h
movcr0,eax
}
}
PLDR_DATA_TABLE_ENTRY SearchDriver(PDRIVER_OBJECT pDriverObject,wchar_t *strDriverName)
{
LDR_DATA_TABLE_ENTRY *pdata_table_entry,*ptemp_data_table_entry;
PLIST_ENTRY plist;
UNICODE_STRING str_module_name;
RtlInitUnicodeString(&str_module_name,strDriverName);
pdata_table_entry = (LDR_DATA_TABLE_ENTRY*)pDriverObject->DriverSection;
if (!pdata_table_entry)
{
return 0;
}
plist = pdata_table_entry->InLoadOrderLinks.Flink;
while(plist!= &pdata_table_entry->InLoadOrderLinks)
{
ptemp_data_table_entry = (LDR_DATA_TABLE_ENTRY *)plist;
//KdPrint(("%wZ",&pTempDataTableEntry->BaseDllName));
if (0==RtlCompareUnicodeString(&ptemp_data_table_entry->BaseDllName,&str_module_name,FALSE))
{
return ptemp_data_table_entry;
}
plist = plist->Flink;
}
return 0;
}
BOOLEAN Jmp_HookFunction(
IN ULONG Destination,
IN ULONG Source,
IN UCHAR *Ori_Code
)
{
ULONG jmp_offset;
UCHAR jmp_code = {0xE9};
KSPIN_LOCK lock;
KIRQL irql;
if (Destination==0||Source==0)
{
DbgPrint("Params error!");
return FALSE;
}
RtlCopyMemory(Ori_Code,(PVOID)Destination,5);
jmp_offset = Source - Destination-5;
*(ULONG*)&jmp_code = jmp_offset;
KeInitializeSpinLock (&lock );
KeAcquireSpinLock(&lock,&irql);
PageProtectOff();
RtlCopyMemory((PVOID)Destination,jmp_code,5);
PageProtectOn();
KeReleaseSpinLock (&lock,irql);
return TRUE;
}
VOID Res_HookFunction(
IN ULONG Destination,
IN UCHAR *Ori_Code,
IN ULONG Length
)
{
KSPIN_LOCK lock;
KIRQL irql;
if (Destination==0||Ori_Code==0){ return; }
KeInitializeSpinLock (&lock );
KeAcquireSpinLock(&lock,&irql);
PageProtectOff();
RtlCopyMemory((PVOID)Destination,Ori_Code,Length);
PageProtectOn();
KeReleaseSpinLock (&lock,irql);
}
ULONG SearchAddressForSign(ULONG uStartBase,ULONG uSearchLength,SIGNATURE_INFO SignatureInfo)
{
UCHAR *p;
ULONG u_index1,u_index2;
//ULONG uIndex;
PIMAGE_DOS_HEADER pimage_dos_header;
PIMAGE_NT_HEADERS pimage_nt_header;
PIMAGE_SECTION_HEADER pimage_section_header;
if(!MmIsAddressValid((PVOID)uStartBase))
{ return 0; }
pimage_dos_header = (PIMAGE_DOS_HEADER)uStartBase;
pimage_nt_header = (PIMAGE_NT_HEADERS)((ULONG)uStartBase+pimage_dos_header->e_lfanew);
pimage_section_header = (PIMAGE_SECTION_HEADER)((ULONG)pimage_nt_header+sizeof(IMAGE_NT_HEADERS));
for (u_index1 = 0;u_index1<pimage_nt_header->FileHeader.NumberOfSections;u_index1++)
{
if (pimage_section_header.Characteristics&0x60000000)
{
//可读可写的段
//DbgPrint("SectionName:%s----0x%X----0x%X",pSecHeader.Name,\
// pSecHeader.Misc.VirtualSize,uStartBase+pSecHeader.VirtualAddress);
p = (UCHAR*)uStartBase + pimage_section_header.VirtualAddress;
for (u_index2 = 0;u_index2<pimage_section_header.Misc.VirtualSize;u_index2++)
{
if (!MmIsAddressValid((p-SignatureInfo.Offset))||
!MmIsAddressValid((p-SignatureInfo.Offset)))
{
p++;
continue;
}
__try{
if (*(p-SignatureInfo.Offset)==SignatureInfo.cSingature&&
*(p-SignatureInfo.Offset)==SignatureInfo.cSingature&&
*(p-SignatureInfo.Offset)==SignatureInfo.cSingature&&
*(p-SignatureInfo.Offset)==SignatureInfo.cSingature&&
*(p-SignatureInfo.Offset)==SignatureInfo.cSingature)
{
return (ULONG)p;
}
}__except(EXCEPTION_EXECUTE_HANDLER){
DbgPrint("Search error!");
}
p++;
}
}
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
//global
PDRIVER_OBJECT g_LocalDriverObj;
BOOLEAN g_HookSuccess;
ULONG g_fnRtlDispatchException;
ULONG g_JmpOrigDisException;
UCHAR g_cDisExceptionCode;
ULONG g_TargDebugPort;
ULONG __stdcall FilterRtlDispatchException (
IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT ContextRecord
)
{
if (ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP)
{
KdPrint(("address:%X",ExceptionRecord->ExceptionAddress));
return 1;
}
return 0;
}
void __declspec(naked) NewRtlDispatchException()
{
__asm{
movedi,edi
push ebp
movebp,esp
pushad
pushfd
push
push
call FilterRtlDispatchException
test eax,eax
jz__SafeExit
popfd
popad
movesp,ebp
popebp
moveax,0x1
retn 0x8
__SafeExit:
popfd
popad
movesp,ebp
popebp
movedi,edi
push ebp
movebp,esp
jmpg_JmpOrigDisException
}
}
void UnHookRtlDispatchException()
{
if (g_HookSuccess)
{
Res_HookFunction(g_fnRtlDispatchException,g_cDisExceptionCode,0x5);
}
}
void HookRtlDispatchException()
{
PLDR_DATA_TABLE_ENTRY Ldr;
SIGNATURE_INFO SignCode = {{0x84,10},{0xC0,9},{0x57,2},{0x53,1},{0xE8,0}};
g_HookSuccess = FALSE;
Ldr = SearchDriver(g_LocalDriverObj,L"ntoskrnl.exe");
if (Ldr == NULL)
{
return;
}
g_fnRtlDispatchException = SearchAddressForSign((ULONG)Ldr->DllBase,Ldr->SizeOfImage,SignCode);
if (!MmIsAddressValid((PVOID)g_fnRtlDispatchException))
{
return;
}
g_fnRtlDispatchException = g_fnRtlDispatchException + *(ULONG*)(g_fnRtlDispatchException + 1) + 5;
g_JmpOrigDisException = g_fnRtlDispatchException + 5;
KdPrint(("RtlDispatchException:%X",g_fnRtlDispatchException));
g_HookSuccess = Jmp_HookFunction(g_fnRtlDispatchException,(ULONG)NewRtlDispatchException,g_cDisExceptionCode);
}
void CancelMonitor()
{
__asm{
moveax,0
movdr0,eax
movdr7,eax
}
}
void SetMonitor(ULONG Address)
{
__asm{
moveax,Address
movdr0,eax
moveax,0xF0002
movdr7,eax
}
}
BOOLEAN CreateMonitor(ULONG Address,BOOLEAN Remove)
{
ULONG Affinity,CurrentAffinity;
ULONG fnpKeSetAffinityThread;
UNICODE_STRING usFuncName;
RtlInitUnicodeString(&usFuncName,L"KeSetAffinityThread");
fnpKeSetAffinityThread = (ULONG)MmGetSystemRoutineAddress(&usFuncName);
if (fnpKeSetAffinityThread==0)
{
return FALSE;
}
Affinity = KeQueryActiveProcessors(); //KeQueryActiveProcessors获取处理器相关的位图(这里的位图可以理解为个数,比如返回1代表一个处理器,返回3表示两个处理器,返回7表示三个处理器,依此类推。也就是说从有多少个处理器,那么Affinity的值就会从低位到高位依此填充多少位)
CurrentAffinity = 1;
while(Affinity)
{
//下面只是个简单的算法,使当前线程运行到不同的处理器上
Affinity &= ~CurrentAffinity;
((KESETAFFINITYTHREAD)fnpKeSetAffinityThread)(PsGetCurrentThread(),(KAFFINITY)CurrentAffinity);
CurrentAffinity <<= 1;
if (Remove)
{
CancelMonitor();
}else{
SetMonitor(Address);
}
}
return TRUE;
}
void CreateProcessNotify(
__in HANDLE ParentId,
__in HANDLE ProcessId,
__in BOOLEAN Create
)
{
NTSTATUS Status;
PEPROCESS Process;
Status = PsLookupProcessByProcessId(ProcessId,&Process);
if (NT_SUCCESS(Status))
{
if (strstr((char*)Process+0x16c,"111") != NULL)
{
g_TargDebugPort = (ULONG)Process + 0xEC;
if (Create)
{
CreateMonitor(g_TargDebugPort,FALSE);
}else{
CreateMonitor(g_TargDebugPort,TRUE);
}
}
ObDereferenceObject(Process);
}
}
void DriverUnLoad(PDRIVER_OBJECT pDriverObject)
{
LARGE_INTEGER interval;
CreateMonitor(0,TRUE);
PsSetCreateProcessNotifyRoutine(CreateProcessNotify,TRUE);
/************************************************************************/
//延时处理
interval.QuadPart = 1000*(-10*1000);
KeDelayExecutionThread(KernelMode,FALSE,&interval);
/************************************************************************/
UnHookRtlDispatchException();
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING usRegistPath)
{
g_LocalDriverObj = pDriverObject;
g_TargDebugPort = 0;
HookRtlDispatchException();
PsSetCreateProcessNotifyRoutine(CreateProcessNotify,FALSE);
pDriverObject->DriverUnload = DriverUnLoad;
return STATUS_SUCCESS;
}
感觉是个好东东,谢谢
页:
[1]