首页
社区
课程
招聘
[原创]如何InlineHook IoCallDriver来保护文件
发表于: 2010-2-2 11:05 7036

[原创]如何InlineHook IoCallDriver来保护文件

2010-2-2 11:05
7036

以前的看雪,老Y发表了一篇《从内核层保护文件不被删除》,他由于部分原因,只提供了部分代码碎片,但是还是要感谢老Y的无私,有兴趣的朋友可以去看看此文,我在此基础上通过自己的编写和调试,终于完整实现,与老Y的给的代码还是有不少地方不同,不敢私藏,特贡献给大家,方便有需要的朋友,本文已发表在黑客防线2010年2期上。

完整的代码如下:
#include <ntddk.h>
#include <stdio.h>
                  
NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject);
int IsNeedProtect(DEVICE_OBJECT *DeviceObject, PIRP Irp);
ULONG GetFunctionAddr(IN PCWSTR FunctionName);
VOID InlineHook();

typedef NTSTATUS (FASTCALL *pIofCallDriver)(
                                           IN PDEVICE_OBJECT DeviceObject,
                                           IN OUT PIRP Irp);
pIofCallDriver OldAddress;

NTSTATUS FASTCALL MyIofCallDriver(IN PDEVICE_OBJECT DeviceObject,
                                  IN OUT PIRP Irp)
{
        NTSTATUS stat;
//先保存所有寄存器的原来状态,到时好恢复现场环境,跟加壳软件开始的指令也是一样
  __asm
  {
    pushad
        pushfd       
  }

   if(IsNeedProtect(DeviceObject,Irp))
  {
        //返回删除失败的提示
    __asm
        {
      popfd
      popad
          mov eax,0xC000000D
      mov stat,eax
        }
    return stat;  
  }
  
   //先恢复现场环境,跳转回原地址
  __asm
  {
   popfd
   popad
   mov ecx,DeviceObject
   mov edx,Irp
   call OldAddress;
   mov stat,eax
  }
return stat;

}

int IsNeedProtect(DEVICE_OBJECT *DeviceObject, PIRP Irp)
{
  NTSTATUS status;
  int nResult=FALSE;
  DRIVER_OBJECT *DriverObject=DeviceObject->DriverObject;
  WCHAR *pwsz=NULL;
  IO_STACK_LOCATION *sp;
  FILE_OBJECT *FileObject=NULL;
  
  status=STATUS_INVALID_PARAMETER;
  sp=IoGetNextIrpStackLocation(Irp);;
  

  switch(sp->MajorFunction)
  {
  case IRP_MJ_SET_INFORMATION:
  goto Continue11;
  
  case IRP_MJ_WRITE:
  goto Continue11;
  
  default:
  goto Exit00;
  }
  
  Continue11:
  FileObject=sp->FileObject;
  _try
  {
    pwsz=wcsrchr(DriverObject->DriverName.Buffer,L'\\');
        pwsz++;
       
        //判断Irp是不是发往ntfs和fastfat驱动的,不是则跳出
        if (_wcsnicmp(pwsz,L"ntfs",4)&&_wcsnicmp(pwsz,L"fastfat",7))
        {
        goto Exit00;
        }
       
   DbgPrint("IofCallDriver:Delete File:%ws\n",FileObject->FileName.Buffer);

   pwsz=wcsrchr(FileObject->FileName.Buffer,L'\\');
   if (pwsz!=NULL)
   {
   pwsz++;
   }
  

   if (!_wcsnicmp(pwsz,L"IceSword122cn.exe",34))  //保护的文件名xxxxx
   {
    Irp->IoStatus.Information=0;
        Irp->IoStatus.Status=STATUS_ACCESS_DENIED;
        IoCompleteRequest(Irp,IO_NO_INCREMENT);
        nResult=TRUE;
        goto Exit00;
   }

  }

  except(1)
  {
  goto Exit00;
  }

Exit00:
  return nResult;
}

ULONG GetFunctionAddr(IN PCWSTR FunctionName)
{
UNICODE_STRING HookFunctionName;
RtlInitUnicodeString(&HookFunctionName,FunctionName);
return (ULONG)MmGetSystemRoutineAddress(&HookFunctionName);
}

//inlineHook IofCallDriver函数
VOID InlineHook()
{
KIRQL oldIrql;
ULONG Address;

Address=(ULONG)GetFunctionAddr(L"IofCallDriver");
  __asm
  {
   mov eax,Address
   mov esi,[eax+2]
   mov eax,[esi]
   mov OldAddress,eax
  }

//提升中断层次
  oldIrql=KeRaiseIrqlToDpcLevel();
  __asm
  {
   cli
   mov eax,cr0
   and eax,not 10000h
   mov cr0,eax
  }
  //进行地址替换  
  _asm
  {
  mov eax,Address
  mov esi,[eax+2]
  mov dword ptr [esi],offset MyIofCallDriver
  }
  _asm
  {
  mov eax,cr0
  or eax,10000h
  mov cr0,eax
  sti
  }

//恢复中断层次
KeLowerIrql(oldIrql);
return ;
}

VOID UninlineHook()
{
KIRQL oldIrql;
ULONG Address;

Address=(ULONG)GetFunctionAddr(L"IofCallDriver");
//提升中断层次
  oldIrql=KeRaiseIrqlToDpcLevel();
  __asm
  {
   cli
   mov eax,cr0
   and eax,not 10000h
   mov cr0,eax
  }
  //进行地址替换  
  _asm
  {
  mov eax,Address
  mov esi,[eax+2]
  mov eax,OldAddress
  mov dword ptr [esi],eax
  }
  
  _asm
  {
  mov eax,cr0
  or eax,10000h
  mov cr0,eax
  sti
  }

//恢复中断层次
KeLowerIrql(oldIrql);
return ;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,
                                         IN PUNICODE_STRING theRegistryPath)
{
                                            
        DbgPrint("Hook Called!\n");
        theDriverObject->DriverUnload=DriverUnload;
        InlineHook();
        return STATUS_SUCCESS ;
}

NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
NTSTATUS status=STATUS_SUCCESS ;
DbgPrint("OnUnload called!\n");
UninlineHook();
return status;
}


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (3)
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
很好很有趣,膜拜
2010-2-3 10:27
0
雪    币: 492
活跃值: (53)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
3
支持放血~~~
2010-2-3 11:31
0
雪    币: 167
活跃值: (136)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
好东西要支持
2010-2-3 11:32
0
游客
登录 | 注册 方可回帖
返回
//