[原创]HOOK ObjectType 干涉文件访问

8 29, 2008

前几日在网上看到MJ0011大虾写的一篇《ObjectType HOOK干涉注册表操作(bypass Icesword,gmer,NIAP,etc.)》的文章,感觉很有兴趣。MJ大虾的文章给出的代码主要是干涉注册表的。而ObjectType 可以干涉的不只是注册表,所以就想到用同样的方法去干涉文件的访问,举一反三嘛。

在前辈的文章,Google,WinDbg的帮助下完成了一下代码。(在windows2000,windowsXp sp2上测试通过。Bypass Icesword,其他的没有试)

 

  1. // StopOpen.c
  2. #include <ntddk.h>
  3. #define MAX_PATH 266
  4. #define NUMBER_HASH_BUCKETS 37
  5. #define LINK_NAME L"\\DosDevices\\StopOpenLink"
  6. #define DEVICE_NAME L"\\Device\\StopLinkName"
  7. PVOID pOldParseProcedure = NULL;
  8.  
  9.  
  10. typedef struct _OBJECT_DIRECTORY_ENTRY {
  11.     struct _OBJECT_DIRECTORY_ENTRY *ChainLink;
  12.     PVOID Object;
  13. } OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
  14.  
  15. typedef struct _OBJECT_DIRECTORY {
  16.     struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[ NUMBER_HASH_BUCKETS ];
  17.     struct _OBJECT_DIRECTORY_ENTRY **LookupBucket;
  18.     BOOLEAN LookupFound;
  19.     USHORT SymbolicLinkUsageCount;
  20.     struct _DEVICE_MAP *DeviceMap;
  21. } OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
  22.  
  23. typedef struct _DEVICE_MAP {
  24.     ULONG ReferenceCount;
  25.     POBJECT_DIRECTORY DosDevicesDirectory;
  26.     ULONG DriveMap;
  27.     UCHAR DriveType[ 32 ];
  28. } DEVICE_MAP, *PDEVICE_MAP;
  29.  
  30.  
  31. typedef struct _OBJECT_TYPE_INITIALIZER {
  32.         USHORT Length;
  33.         BOOLEAN UseDefaultObject;
  34.         BOOLEAN CaseInsensitive;
  35.         ULONG InvalidAttributes;
  36.         GENERIC_MAPPING GenericMapping;
  37.         ULONG ValidAccessMask;
  38.         BOOLEAN SecurityRequired;
  39.         BOOLEAN MaintainHandleCount;
  40.         BOOLEAN MaintainTypeList;
  41.         POOL_TYPE PoolType;
  42.         ULONG DefaultPagedPoolCharge;
  43.         ULONG DefaultNonPagedPoolCharge;
  44.         PVOID DumpProcedure;
  45.         PVOID OpenProcedure;
  46.         PVOID CloseProcedure;
  47.         PVOID DeleteProcedure;
  48.         PVOID ParseProcedure;
  49.         PVOID SecurityProcedure;
  50.         PVOID QueryNameProcedure;
  51.         PVOID OkayToCloseProcedure;
  52. } OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
  53.  
  54.  
  55. typedef struct _OBJECT_TYPE {
  56.         ERESOURCE Mutex;
  57.         LIST_ENTRY TypeList;
  58.         UNICODE_STRING Name; // Copy from object header for convenience
  59.         PVOID DefaultObject;
  60.         ULONG Index;
  61.         ULONG TotalNumberOfObjects;
  62.         ULONG TotalNumberOfHandles;
  63.         ULONG HighWaterNumberOfObjects;
  64.         ULONG HighWaterNumberOfHandles;
  65.         OBJECT_TYPE_INITIALIZER TypeInfo;
  66. #ifdef POOL_TAGGING
  67.         ULONG Key;
  68. #endif //POOL_TAGGING
  69. } OBJECT_TYPE, *POBJECT_TYPE;
  70. typedef struct _OBJECT_CREATE_INFORMATION {
  71.         ULONG Attributes;
  72.         HANDLE RootDirectory;
  73.         PVOID ParseContext;
  74.         KPROCESSOR_MODE ProbeMode;
  75.         ULONG PagedPoolCharge;
  76.         ULONG NonPagedPoolCharge;
  77.         ULONG SecurityDescriptorCharge;
  78.         PSECURITY_DESCRIPTOR SecurityDescriptor;
  79.         PSECURITY_QUALITY_OF_SERVICE SecurityQos;
  80.         SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
  81. } OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;
  82.  
  83.  
  84.  
  85. typedef struct _OBJECT_HEADER {
  86.         LONG PointerCount;
  87.         union {
  88.                 LONG HandleCount;
  89.                 PSINGLE_LIST_ENTRY SEntry;
  90.         };
  91.         POBJECT_TYPE Type;
  92.         UCHAR NameInfoOffset;
  93.         UCHAR HandleInfoOffset;
  94.         UCHAR QuotaInfoOffset;
  95.         UCHAR Flags;
  96.         union
  97.         {
  98.                 POBJECT_CREATE_INFORMATION ObjectCreateInfo;
  99.                 PVOID QuotaBlockCharged;
  100.         };
  101.        
  102.         PSECURITY_DESCRIPTOR SecurityDescriptor;
  103.         QUAD Body;
  104. } OBJECT_HEADER, *POBJECT_HEADER;
  105. HANDLE hFile;
  106. POBJECT_TYPE pObHeader= NULL;
  107. NTSTATUS pNewParseProcedure(POBJECT_DIRECTORY RootDirectory,
  108.                                           POBJECT_TYPE ObjectType,
  109.                                           PACCESS_STATE AccessState,
  110.                                           KPROCESSOR_MODE AccessCheckMode,
  111.                                           ULONG Attributes,
  112.                                           PUNICODE_STRING ObjectName,
  113.                                           PUNICODE_STRING RemainingName,
  114.                                           PVOID ParseContext ,
  115.                                           PSECURITY_QUALITY_OF_SERVICE SecurityQos ,
  116.                                           PVOID *Object)
  117. {
  118.         NTSTATUS ntStatus = STATUS_SUCCESS;
  119.         WCHAR wOpenName[MAX_PATH] = {0};
  120.         RtlCopyMemory(wOpenName,ObjectName->Buffer,ObjectName->MaximumLength);
  121.         if (wcsstr(wOpenName,L"1.txt"))
  122.         {
  123.                 return STATUS_OBJECT_NAME_NOT_FOUND;
  124.         }
  125.         __asm
  126.         {
  127.                 push eax
  128.                         push Object
  129.                         push SecurityQos
  130.                         push ParseContext
  131.                         push RemainingName
  132.                         push ObjectName
  133.                         push Attributes
  134.                         movzx eax, AccessCheckMode
  135.                         push eax
  136.                         push AccessState
  137.                         push ObjectType
  138.                         push RootDirectory
  139.                         call pOldParseProcedure
  140.                        
  141.                         mov ntStatus, eax
  142.                         pop eax
  143.                        
  144.         }
  145.         return ntStatus;
  146.  
  147. }
  148.  
  149.  
  150. NTSTATUS InstallHook()
  151. {
  152.         NTSTATUS  ntStatus;
  153.         UNICODE_STRING StName;
  154.         OBJECT_ATTRIBUTES obAttrib;
  155.         IO_STATUS_BLOCK ioStaBlock;
  156.         PVOID pObject = NULL;
  157.  
  158.         KdPrint(("it start now!\n"));
  159.         RtlInitUnicodeString(&StName,L"\\DosDevices\\C:\\1.txt");
  160.         InitializeObjectAttributes(&obAttrib,&StName,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE ,\
  161.                 0,NULL);
  162.         ntStatus = ZwCreateFile(&hFile,GENERIC_ALL,&obAttrib,&ioStaBlock,0,FILE_ATTRIBUTE_NORMAL,\
  163.                 0,FILE_OPEN ,FILE_NON_DIRECTORY_FILE,NULL,0);
  164.         if (!NT_SUCCESS(ntStatus))
  165.         {
  166.                 KdPrint(("File Not Open\n"));
  167.                 return ntStatus;
  168.         }
  169.         KdPrint(("File Open\n"));
  170.         ntStatus = ObReferenceObjectByHandle(hFile,GENERIC_ALL,NULL,KernelMode,&pObject,NULL);
  171.         if (!NT_SUCCESS(ntStatus))
  172.         {
  173.                 KdPrint(("Object Not Open\n"));
  174.                 return ntStatus;
  175.         }
  176.         KdPrint(("Object Open\n"));
  177.         __asm
  178.         {
  179.                 cli;
  180.                 mov eax, cr0;
  181.                 and eax, not 10000h;
  182.                 mov cr0, eax;
  183.         }
  184.         __asm
  185.         {
  186.                 push eax;
  187.                 mov eax,pObject;
  188.                 mov eax,[eax-0x10];
  189.                 mov pObHeader,eax;
  190.                 pop eax;
  191.         }
  192.         pOldParseProcedure = pObHeader->TypeInfo.ParseProcedure;
  193.         pObHeader->TypeInfo.ParseProcedure = pNewParseProcedure;
  194.         __asm
  195.         {
  196.                 mov eax, cr0;
  197.                 or eax, 10000h;
  198.                 mov cr0, eax;
  199.                 sti;
  200.         }
  201.         return ntStatus;
  202. }
  203.  
  204. NTSTATUS soDispatch(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
  205. {
  206.         NTSTATUS ntStatus = STATUS_SUCCESS;
  207.         PIO_STACK_LOCATION pIrpSt = NULL;
  208.         pIrpSt = IoGetCurrentIrpStackLocation(pIrp);
  209.  
  210.         ntStatus = pIrp->IoStatus.Status;
  211.         IoCompleteRequest(pIrp,IO_NO_INCREMENT);
  212.         return ntStatus;
  213. }
  214. void soUnload(IN PDRIVER_OBJECT  DriverObject)
  215. {
  216.         UNICODE_STRING uTempString;
  217.         NTSTATUS  ntStatus;
  218.         ntStatus = ZwClose(hFile);
  219.         __asm
  220.         {
  221.                 cli;
  222.                 mov eax, cr0
  223.                 and eax, not 10000h
  224.                 mov cr0, eax
  225.         }
  226.         pObHeader->TypeInfo.ParseProcedure = pOldParseProcedure;
  227.         __asm
  228.         {
  229.                 mov eax, cr0;
  230.                 or eax, 10000h
  231.                 mov cr0, eax;
  232.                 sti;
  233.         }
  234.         RtlInitUnicodeString(&uTempString,LINK_NAME);
  235.         IoDeleteSymbolicLink(&uTempString);
  236.         IoDeleteDevice(DriverObject->DeviceObject);
  237. }
  238.  
  239.  
  240. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
  241. {
  242.         NTSTATUS ntStatus = STATUS_SUCCESS;
  243.         UNICODE_STRING uLinkName;
  244.         UNICODE_STRING uDeviceName;
  245.         PDEVICE_OBJECT ObDevice;
  246.  
  247.         RtlInitUnicodeString(&uDeviceName,DEVICE_NAME);
  248.         ntStatus = IoCreateDevice(DriverObject,0,&uDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&ObDevice);
  249.         if (!NT_SUCCESS(ntStatus))
  250.         {
  251.                 return ntStatus;
  252.         }
  253.         RtlInitUnicodeString(&uLinkName,LINK_NAME);
  254.         ntStatus = IoCreateSymbolicLink(&uLinkName,&uDeviceName);
  255.         if (!NT_SUCCESS(ntStatus))
  256.         {
  257.                 return ntStatus;
  258.         }
  259.         DriverObject->MajorFunction[IRP_MJ_CREATE] = soDispatch;
  260.         DriverObject->MajorFunction[IRP_MJ_CLOSE] = soDispatch;
  261.         DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = soDispatch;
  262.  
  263.         DriverObject->DriverUnload = soUnload;
  264.         InstallHook();
  265.  
  266.         return ntStatus;
  267.  
  268. }

[原创]类成员操作符重载

8 21, 2008

在CSDN上看到有人问关于C++类成员操作符重载的问题,于是发现自己似乎也没关心过东西,于是研究了一些,写下了这篇学习笔记。
我们知道在C++中,+、-、+=,<<等等都是一些重要的操作符。有时候我们想让我们自己的类中的操作符有一些特殊的功能,该怎么办呢!
我们都知道函数重载,其实操作符重载也是基于这一机制的,他让我们能够给这些操作符赋予与原来不同的功能,而使用起来和我们原始的操作符没有什么区别。操作符重载分为类成员重载操作符和非类成员操作符重载。类成员重载操作符在类内部定义,而非类成员操作符重载在类外定义。
OK,啰嗦了这么多,来点实用的。这里我就写了一个我自己的cout。

代码如下:

 

  1. #include <stdio.h>
  2.  
  3. class MyIo      //这个是我自定义的类
  4. {
  5. public:
  6.         const MyIo& operator<<(int dwInt) const ;       //这两行就是我们所关心的
  7.         const MyIo& operator<<(char* str) const ;       //操作符重载
  8. };
  9.  
  10. const MyIo& MyIo::operator<<(int dwInt) const           //重载的实现
  11. {
  12.         printf("Num : %d",dwInt);
  13.         return *this;
  14. }
  15.  
  16. const MyIo& MyIo::operator<<(char* str) const
  17. {
  18.         printf("String : %s",str);
  19.         return *this;
  20. }
  21.  
  22. void main()
  23. {
  24.         MyIo myout;             //类声明,然后就像一般的操作符调用
  25.         myout<<123;
  26.         myout<<"NightXie";
  27. }

这段代码写的很简单,但是重载的功能确实很强大也很有趣。和我一样平时没太注意但是很兴趣的朋友不妨一试。

做一个自己定时器

8 18, 2008

大家都知道,玩电脑时间过得N快无比。有时候计划好了做什么事情,但是玩起游戏就一下忘光了。这两天就是经常忘了看奥运会的重要比赛。虽然系统中有个叫做计划任务的东西。但是我觉得没必要用它。所以抽了点时间写了一个小程序。

具体方法就是在程序中创建了一个新线程,用他来判断时间到了没。由于是小程序,不能占用太多资源,我让他没1s判断一次。

 

  1. typedef struct _MYTIME
  2. {
  3.         DWORD dwHours;
  4.         DWORD dwMinutes;
  5.         DWORD dwSecond;
  6. }MYTIME,*LPMYTIME;
  7.  
  8. HWND hwnd;
  9.  
  10. DWORD WINAPI RingThreadProc(LPVOID lpParameter)
  11. {
  12.         LPMYTIME lpMytime = LPMYTIME(lpParameter);
  13.         SYSTEMTIME stSysTime;
  14.         do
  15.         {       
  16.                 Sleep(1000);
  17.                 GetLocalTime(&stSysTime);
  18.  
  19.         } while(stSysTime.wHour != lpMytime->dwHours || \
  20.                         stSysTime.wMinute != lpMytime->dwMinutes || \
  21.                         stSysTime.wSecond < lpMytime->dwSecond);
  22.        
  23.         PlaySound("djft.wav",NULL,SND_APPLICATION);
  24.  
  25.         HWND hText = GetDlgItem(hwnd,IDC_TEXT);
  26.         EnableWindow(hText,TRUE);
  27.  
  28.         return TRUE;
  29. }
  30.  
  31. void CTimeRingDlg::OnOK()
  32. {
  33.         // TODO: Add extra validation here
  34.         UpdateData();
  35.         hwnd = this->m_hWnd;
  36.         m_Text.EnableWindow(FALSE);
  37.         static MYTIME stMytime;
  38.         stMytime.dwHours = m_Hours;
  39.         stMytime.dwMinutes = m_Minutes;
  40.         stMytime.dwSecond = m_Seconds;
  41.         //ShowWindow(SW_MINIMIZE);
  42.         HANDLE hHandle = CreateThread(NULL,0,RingThreadProc,(LPVOID)&stMytime,0,NULL);
  43.         //CDialog::OnOK();
  44. }

关键的代码就是这些,很简单。

不过那个PlaySound函数可以研究一下,应该很好玩的。

是男人就撑过20秒的游戏分析+无敌Patch的实现

8 13, 2008

先简单说说《是男人就撑过20秒》这个游戏,就是操纵一架飞机躲避飞来的N多子弹,看你能支撑多长时间。(真的很变态 ) 好,言归正传。 首先,观察游戏,发现一点,那就是每当进入游戏后鼠标就会消失。当游戏结束之后,显示你支撑的时间时,鼠标又出现了。OK,这是一个很好的线索。

新的Blog之旅

8 13, 2008

            原来的博客放在了CSDN上,因为其代码高亮功能让人还算是觉得满意。不信的是,CSDN的Blog有时候会出一些问题,甚至无法访问。所以闲着没事,看看网上还有什么好的程序员blog,起初看了一些cnblog和chinaunix的blog,但是cnblog界面和排版方面觉得不适应,chinaunix是专注于unix的网站。我虽然有学习unix的意思,但是现在主要的平台还是windows。无意中发现有人介绍这个网站,所以就进来试了试。感觉无论是界面和代码高亮都要胜出CSDN一筹。于是就有了我在这里的第一篇文章

Back to Top