qq56705857 发表于 2015-9-8 13:29:01

过驱动例子

#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;
}

醉酒恋红尘 发表于 2016-4-29 21:30:36

感觉是个好东东,谢谢
页: [1]
查看完整版本: 过驱动例子