首页
社区
课程
招聘
[原创]Windows内核编程来实现注册表还原保护的一种方法
发表于: 2011-3-19 10:39 17862

[原创]Windows内核编程来实现注册表还原保护的一种方法

2011-3-19 10:39
17862
来源于一个注册表保护工具的逆向,主要利用CmpParseKey函数的Object HOOK实现注册表操作重定向来实现注册表还原保护,驱动代码如下:
/*一个简单的注册表还原驱动
来源于某工具逆向,主要解决以下两个问题:
一、理解HIVE文件,这个被system进程独占
二、CmpParseKey函数的挂钩,object HOOK 

by:liuke_blue
E-mail:liuke_blue@126.com
*/

#include <ntddk.h>
#include <windef.h>
#include <stdio.h>

extern POBJECT_TYPE *IoFileObjectType; 

#define KeyValueFullInformation 1 
#define RegHiveFileName  L"\\WINDOWS\\system32\\config\\system"
#define RepointRegItem   L"\\REGISTRY\\USER\\.DEFAULT\\Volatile\\"   
#define ObjectTypeName   L"\\ObjectTypes\\Key"
#define  itemlen 0x0E


 
typedef enum _SYSTEM_INFORMATION_CLASS { 
SystemBasicInformation,      // 0 
   SystemProcessorInformation,     // 1 
   SystemPerformanceInformation,     // 2
   SystemTimeOfDayInformation,     // 3
   SystemNotImplemented1,      // 4
   SystemProcessesAndThreadsInformation,    // 5
   SystemCallCounts,       // 6
   SystemConfigurationInformation,     // 7
   SystemProcessorTimes,      // 8
   SystemGlobalFlag,       // 9
   SystemNotImplemented2,      // 10
   SystemModuleInformation,      // 11
   SystemLockInformation,      // 12
   SystemNotImplemented3,      // 13
   SystemNotImplemented4,      // 14
   SystemNotImplemented5,      // 15
   SystemHandleInformation,      // 16
   SystemObjectInformation,      // 17
   SystemPagefileInformation,      // 18
   SystemInstructionEmulationCounts,     // 19
   SystemInvalidInfoClass1,      // 20
   SystemCacheInformation,      // 21
   SystemPoolTagInformation,      // 22
   SystemProcessorStatistics,      // 23
   SystemDpcInformation,      // 24
   SystemNotImplemented6,      // 25
   SystemLoadImage,       // 26
   SystemUnloadImage,      // 27
   SystemTimeAdjustment,      // 28
   SystemNotImplemented7,      // 29
   SystemNotImplemented8,      // 30
   SystemNotImplemented9,      // 31
   SystemCrashDumpInformation,     // 32
   SystemExceptionInformation,     // 33
   SystemCrashDumpStateInformation,     // 34
   SystemKernelDebuggerInformation,     // 35
   SystemContextSwitchInformation,     // 36
   SystemRegistryQuotaInformation,     // 37
   SystemLoadAndCallImage,      // 38
   SystemPrioritySeparation,      // 39
   SystemNotImplemented10,      // 40
   SystemNotImplemented11,      // 41
   SystemInvalidInfoClass2,      // 42
   SystemInvalidInfoClass3,      // 43
   SystemTimeZoneInformation,      // 44
   SystemLookasideInformation,     // 45
   SystemSetTimeSlipEvent,      // 46
   SystemCreateSession,      // 47
   SystemDeleteSession,      // 48
   SystemInvalidInfoClass4,      // 49
   SystemRangeStartInformation,     // 50
   SystemVerifierInformation,      // 51
   SystemAddVerifier,      // 52
   SystemSessionProcessesInformation     // 53
} SYSTEM_INFORMATION_CLASS;



typedef struct _SYSTEM_HANDLE_INFORMATION
{
    ULONG            ProcessId;
    UCHAR            ObjectTypeNumber;
    UCHAR            Flags;
    USHORT           Handle;
    PVOID            Object;
    ACCESS_MASK      GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;



NTSYSAPI
NTSTATUS 
NTAPI
NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
                         OUT PVOID SystemInformation,
                         IN ULONG SystemInformationLength,
                         OUT PULONG ReturnLength OPTIONAL);

NTSYSAPI
NTSTATUS 
NTAPI ObOpenObjectByPointer(IN PVOID Object,
                            IN ULONG HandleAttributes,
                            IN PACCESS_STATE PassedAccessState,
                            IN  ACCESS_MASK DesiredAccess,
                            IN  POBJECT_TYPE ObjectType,
                            IN  KPROCESSOR_MODE AccessMode,
                            OUT PHANDLE Handle);


NTSYSAPI
NTSTATUS
NTAPI
ZwRestoreKey(IN HANDLE KeyHandle,
             IN HANDLE FileHandle,
             IN ULONG  Flags);


NTSYSAPI 
NTSTATUS 
NTAPI 
NtClose(IN HANDLE ObjectHandle );


NTSYSAPI
NTSTATUS
NTAPI
ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
                   IN POBJECT_TYPE ObjectType,
                   IN KPROCESSOR_MODE AccessMode,
                   IN PACCESS_STATE PassedAccessState,
                   IN ACCESS_MASK DesiredAccess,
                   IN OUT PVOID ParseContext,
                   OUT PHANDLE Handle);


NTSYSAPI
NTSTATUS
NTAPI
ObReferenceObjectByHandle(IN HANDLE Handle,
                          IN ACCESS_MASK DesiredAccess,
                          IN POBJECT_TYPE ObjectType,
                          IN KPROCESSOR_MODE AccessMode,
                          OUT PVOID* Object,
                          OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL);

//记得设置为全局变量
ULONG  PID; 
ULONG Orig_CmpParseKey;

NTSTATUS MyCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
ULONG InstallObjectTypeHook(BOOLEAN IsHook);
VOID RestoreReg(PVOID CurrentId);
NTSTATUS Restorssymbol();


//重定向指向打开项或者键值
NTSTATUS  fake_CmpParseKey(
                           IN PVOID ParseObject,
                           IN PVOID ObjectType,
                           IN OUT PACCESS_STATE AccessState,
                           IN KPROCESSOR_MODE AccessMode,
                           IN ULONG Attributes,
                           IN OUT PUNICODE_STRING CompleteName,
                           IN OUT PUNICODE_STRING RemainingName,
                           IN OUT PVOID Context OPTIONAL,
                           IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
                           OUT PVOID *Object)
{
   wchar_t ItemName[10];
   unsigned short  fullnamelen;
   WORD  name1Len;
   PVOID repoint_pool;
   ULONG name2Len;
   unsigned short poollen;
   unsigned int  childlen;  
   DWORD  tmppos;
   ULONG repoint_len;
   DWORD CompleteName_;
   NTSTATUS status;
   
   
   CompleteName_=CompleteName;
   fullnamelen=CompleteName->Length;
   name1Len=(WORD)(itemlen-2);

   if (fullnamelen<itemlen)
   { 
      if (fullnamelen==name1Len)  //不含"\\"的字符串长度
      {	      
		  //将L"SOFTWARE"拷贝至ItemName; 
		  memcpy(ItemName,(void*)(CompleteName->Buffer),name1Len);
          //最后一位'\0'结尾
		  ItemName[name1Len>>1]=0;
          //字符串转换为大写
		  _wcsupr(ItemName);
          //如果匹配字符串"SOFTWARE"
		  if (RtlCompareMemory(ItemName,L"SYSTEM\\",name1Len)==name1Len)
          {
             //分配重定向缓冲区
			  repoint_pool=ExAllocatePool(PagedPool,0x40u);
			  memcpy(repoint_pool,L"\\REGISTRY\\USER\\.DEFAULT\\Volatile\\",0x40u);		 
              repoint_len=0x00420040;
			  goto Over;
		  }
	  } 
   }
   else
   {
      memcpy(ItemName,(void*)(CompleteName->Buffer),itemlen);  
      ItemName[itemlen>>1]=0;
	  _wcsupr(ItemName);
	  name2Len=RtlCompareMemory(ItemName,L"SYSTEM\\",itemlen);
	  fullnamelen=itemlen;
      if (name2Len==itemlen)
      {
         poollen=(WORD)CompleteName->Length-itemlen+0x42;
		 repoint_pool=ExAllocatePool(PagedPool,poollen);
         memcpy(repoint_pool,L"\\REGISTRY\\USER\\.DEFAULT\\Volatile\\",0x42);		 
         //后面子项的长度,除去前面"SOFTWARE\"的字符串剩下长度
		 childlen=CompleteName->Length-(WORD)itemlen;
         tmppos=*(DWORD*)(CompleteName_+4);
		 //把"SOFTWARE\\"后面所接的字符子串拷贝到重定向值后面
		 memcpy((CHAR*)repoint_pool+0x42,(const void *)(tmppos+2*((WORD)(WORD)itemlen>>1)),childlen); 		 
	     repoint_len=( ((DWORD)(poollen+2)<<16) | ((WORD)poollen) );	 
Over:		 
	    ExFreePoolWithTag(*(PVOID*)(CompleteName_+4),0);
        *(DWORD*)CompleteName_=repoint_len;
        *(DWORD*)(CompleteName_+4)=(DWORD)repoint_pool;
	    
		//重新解析
	     return STATUS_REPARSE;
	  }


  }

   __asm{
         push eax
	     push Object
         push SecurityQos
		 push Context
		 push RemainingName
		 push CompleteName_
         push Attributes
		 push AccessMode
         push AccessState
         push ObjectType
         push ParseObject
		 call Orig_CmpParseKey
         mov status,eax  
         pop eax
   }
 return status;
 
}




NTSTATUS  DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
   PDEVICE_OBJECT DeviceObject;
   UNICODE_STRING devicename;
   UNICODE_STRING linkname;
   NTSTATUS status;
   HANDLE Threadhandle=NULL;


   RtlInitUnicodeString(&devicename,L"\\Device\\RevertHive_2010");
   RtlInitUnicodeString(&linkname,L"\\DosDevices\\RevertHive_2010");
   
   status=IoCreateDevice(DriverObject,0,&devicename,FILE_DEVICE_UNKNOWN,0x600,FALSE,&DeviceObject);
   if (NT_SUCCESS(status))
   {
       status=IoCreateSymbolicLink(&linkname, &devicename);
	   if (NT_SUCCESS(status))
	   {
	       
		    DriverObject->MajorFunction[IRP_MJ_CREATE] = MyCreateClose;
            DriverObject->MajorFunction[IRP_MJ_CLOSE]  = MyCreateClose;
		    PID=PsGetCurrentProcessId(); 
			if (NT_SUCCESS(PsCreateSystemThread(&Threadhandle,0x1F03FFu, 0, 0, 0, RestoreReg, (PVOID)&PID)))
            ZwClose(Threadhandle); 
			InstallObjectTypeHook(1);         
			status=STATUS_SUCCESS;
	   }else
	   {
		    IoDeleteDevice(DeviceObject);
	   }
	    
   }

return status;

}



ULONG InstallObjectTypeHook(BOOLEAN IsHook)
{
  OBJECT_ATTRIBUTES objAttr;
  UNICODE_STRING uObjName;
  NTSTATUS status;
  HANDLE KeyHandle;
  PVOID  keyObject;
  BYTE*  ParseProcedureOfObject;

  RtlInitUnicodeString(&uObjName,ObjectTypeName); 
  InitializeObjectAttributes(&objAttr,&uObjName,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE ,NULL,NULL);
  
  status=ObOpenObjectByName(&objAttr,NULL,KernelMode,NULL,0,NULL,&KeyHandle);
  
  if (NT_SUCCESS(status))
  {
      status= ObReferenceObjectByHandle(KeyHandle,0x80000000u,NULL,KernelMode,(PVOID)&keyObject,0);
      if (NT_SUCCESS(status))
      {
        /*
          OBJECT_TYPE+0x60-->OBJECT_TYPE_INITIALIZER
          OBJECT_TYPE_INITIALIZER+0x3c-->ParseProcedure(nt!CmpParseKey)
          而且KeyObject指向OBJECT_TYPE,因此可以进行OBJECT HOOK
         */
		  
		ParseProcedureOfObject=(BYTE*)keyObject+0x9C;
	    if (!MmIsAddressValid((*(DWORD*)ParseProcedureOfObject)))
	    {
	      ObfDereferenceObject(keyObject);  
		  ZwClose(KeyHandle);
		  return status;
		}
		KdPrint(("CmpParseKey funcaddr=0x%X\n",*(DWORD*)ParseProcedureOfObject));
		//开始OBJECT HOOK
		if (IsHook)
		{
			__asm{
				   push eax
                   push ecx
		           mov  ecx,ParseProcedureOfObject
				   mov  eax,offset fake_CmpParseKey
				   xchg eax,[ecx]
			       mov  Orig_CmpParseKey,eax
				   pop ecx
				   pop eax
			}
		    
		
		}else
		{
			__asm{
                  push eax
                  push ecx
                  mov  eax,Orig_CmpParseKey                 
                  mov  ecx,ParseProcedureOfObject  
				  xchg eax,[ecx] 
                  pop ecx
				  pop eax
			}
			
		}
	    
	   ObfDereferenceObject(keyObject);
	  }
    ZwClose(KeyHandle);
  }

return status;  
}


/*得到system进程里所独占的文件句柄(windows\system32\config\system),
然后重新装载在L"\\REGISTRY\\USER\\.DEFAULT\\Volatile\"下,实现注册表hive文件重定向
*/
VOID  RestoreReg(PVOID CurrentId)
{
  NTSTATUS status;
  PVOID pool;
  ULONG dwNeedsize;
  ULONG ReturnLength;
  unsigned int nCount;
  ULONG Object;
  ULONG PID;
  UNICODE_STRING *filetype;
  UNICODE_STRING szfile;
  PFILE_OBJECT FileObject=NULL;
  ULONG  current_handle_info_pos;
  UNICODE_STRING Hivename;
  HANDLE regedit_software_fileHandle;
  UNICODE_STRING volatile_reg;
  PUNICODE_STRING filename;
  OBJECT_ATTRIBUTES oa;
  ULONG numofhandles;


  RtlInitUnicodeString(&szfile,L"File");
  RtlInitUnicodeString(&Hivename,RegHiveFileName);
  dwNeedsize=0x1000;
  do 
  {
    pool=ExAllocatePool(PagedPool,dwNeedsize);
    if (pool)
	{ 
	    current_handle_info_pos=(ULONG)pool; 
		status= NtQuerySystemInformation(SystemHandleInformation, pool, dwNeedsize, &ReturnLength);	
	}else
    return NULL;
	
	if (status==STATUS_INFO_LENGTH_MISMATCH)
	{
	    ExFreePoolWithTag(pool,0);
		dwNeedsize*=2;
	} 
  } while(status == STATUS_INFO_LENGTH_MISMATCH);
 /*+++
 这里注意pool指向的缓冲区的内容,查看文档如下:
 The data returned to the SystemInformation buffer is a ULONG count of the number of
 handles followed immediately by an array of SYSTEM_HANDLE_INFORMATION.很显然是指句柄的数量,
 紧接着就是SYSTEM_HANDLE_INFORMATION的数组,还是的看文档,才清楚.
  ++*/
  if (pool)
  {
	  if (NT_SUCCESS(status))
     {
         numofhandles=*(ULONG*)current_handle_info_pos;
		 nCount=0;
	     Object=((ULONG)pool+0xC);
		 while (nCount<numofhandles)
		 {
			 PID=*(DWORD*)(Object-0x8);	
			  //如果是system进程,并且匹配文件,则打印
		    if((PID==(*(DWORD*)CurrentId))&&(!RtlCompareUnicodeString(&szfile,(PUNICODE_STRING)(*(DWORD*)(*(DWORD*)Object-0x10)+64),TRUE)))
			{
               	   filetype=(PUNICODE_STRING)(*(DWORD*)(*(DWORD*)Object-0x10)+64);
                   
				   FileObject=*(PULONG)Object;	
				  //KdPrint(("filename=%wZ,vpb=0x%X\n",(PUNICODE_STRING)(&FileObject->FileName),*(DWORD *)(FileObject + 8)));	       
		             filename=(PUNICODE_STRING)(&FileObject->FileName);
		             if (filename)
					 {	 
						 //找到HIVE文件:software
						 if (!RtlCompareUnicodeString(filename,&Hivename,TRUE))
						 {
						     KdPrint(("filetye=%wZ,Filename=%wZ,filelen=%d\n",filetype,filename,filename->Length));
							 status=ObOpenObjectByPointer(FileObject,512,NULL,0,0,KernelMode,®edit_software_fileHandle);   
						     if (NT_SUCCESS(status))
						     {
						         if (regedit_software_fileHandle)
						         {
						             
									RtlInitUnicodeString(&volatile_reg,RepointRegItem);
									InitializeObjectAttributes(&oa,&volatile_reg,OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,NULL,NULL);
									//REG_OPTION_VOLATILE表示创建的项存放在在内存中
                                    status=ZwCreateKey((PHANDLE)(&CurrentId),0xF003Fu,&oa,0,0,5u,¤t_handle_info_pos);
                                    if (NT_SUCCESS(status))
                                    {
                                      //把hive文件临时恢复在设定下的注册表项
									   status=ZwRestoreKey((HANDLE)CurrentId,regedit_software_fileHandle,8u);
									   if (NT_SUCCESS(status))
                                         Restorssymbol();   
                                      ZwClose((HANDLE)CurrentId);
									}
                                   	ZwClose(regedit_software_fileHandle);
									goto while_break;
								 }
							 
							 }
						 
						 }
						 
		
					 }	 		   
			} 
		    ++nCount;
			Object+=0x10;
		 }


 
	 }
  
  
  
  }
while_break:
 ExFreePoolWithTag(pool,0);
return;

}



/*开起一个线程时刻监测是否被HOOK,防止被修复,猥琐的写法
VOID ProtectHook()
{
  ULONG Oldaddress; 
  LARGE_INTEGER Interval; 

  Interval.QuadPart=100*10000; 

  while (1)
  {
     Oldaddress=*(ULONG*)ParseKeyAddress;
	 if (Oldaddress == Orig_CmpParseKey) 
     *(ULONG*)ParseKeyAddress=(ULONG)fake_CmpParseKey;
     
	  KeDelayExecutionThread(0,0,&Interval);//延缓时间 
  }
    

}*/

NTSTATUS MyCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{

  	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
	return Irp->IoStatus.Status;
}


//恢复符号连接
NTSTATUS Restorssymbol()
{
  UNICODE_STRING DestinationString;
  NTSTATUS status;
  OBJECT_ATTRIBUTES oa;
  HANDLE handle;
  HANDLE KeyHandle;
  UNICODE_STRING valuename; 
  PVOID KeyValueInformation;
  ULONG ResultLength;
  ULONG Disposition;
  UNICODE_STRING setvalue;
  CHAR unitevalue[50]={0}; 
  int controlvalue;
  ANSI_STRING ansistring;
  ANSI_STRING ansistring2;  
  UNICODE_STRING subkeyname;
  HANDLE  subkey;
  int currentconfigvalue;
  CHAR unitevalue2[160]={0}; 

  KeyValueInformation=ExAllocatePool(NonPagedPool,0x100);
  RtlInitUnicodeString(&DestinationString, L"\\Registry\\Machine\\System\\Select");
  InitializeObjectAttributes(&oa,&DestinationString,OBJ_CASE_INSENSITIVE,NULL,NULL);
  
  status= ZwOpenKey(&handle, 0x20019u, &oa);
  
  if (NT_SUCCESS(status))
  {
    RtlInitUnicodeString(&valuename, L"Current");

    status= ZwQueryValueKey(handle,&valuename,KeyValueFullInformation,KeyValueInformation,0x80,&ResultLength);  
    NtClose(handle);
    if (NT_SUCCESS(status))
    {
       //得到current的值
		controlvalue=*(int *)((char*)KeyValueInformation+0x24);
		RtlInitUnicodeString(&valuename,L"\\REGISTRY\\USER\\.DEFAULT\\Volatile\\CurrentControlSet"); 
	   
		InitializeObjectAttributes(&oa,&valuename,OBJ_CASE_INSENSITIVE,NULL,NULL);	
		status= ZwCreateKey(&KeyHandle,KEY_CREATE_LINK,&oa, 0, 0,  REG_OPTION_VOLATILE |REG_OPTION_CREATE_LINK , &Disposition); 
	    if (NT_SUCCESS(status))
	    {
	       RtlInitUnicodeString(&setvalue, L"SymbolicLinkValue");
		   sprintf(&unitevalue,"\\REGISTRY\\USER\\.DEFAULT\\Volatile\\ControlSet%03d",controlvalue);
		   RtlInitAnsiString(&ansistring,&unitevalue);  
		   valuename.MaximumLength=256;         
		   RtlAnsiStringToUnicodeString(&valuename,&ansistring, FALSE);
           status=ZwSetValueKey(KeyHandle, &setvalue, 0, REG_LINK, valuename.Buffer, valuename.Length);
		   if (NT_SUCCESS(status))
		   {
		       RtlInitUnicodeString(&subkeyname, L"Control\\IDConfigDB");  
		       InitializeObjectAttributes(&oa,&subkeyname,OBJ_CASE_INSENSITIVE,KeyHandle,NULL);
		       
			    status=ZwOpenKey(&subkey,0x20019u,&oa);
		        NtClose(KeyHandle);
				if (NT_SUCCESS(status))
		        {
		            RtlInitUnicodeString(&valuename, L"CurrentConfig");
					status=ZwQueryValueKey(subkey,&valuename,KeyValueFullInformation,KeyValueInformation,0x80,&ResultLength);
					
				    NtClose(subkey);
                    if (NT_SUCCESS(status))
                    {
                      currentconfigvalue= *(int *)((char *)KeyValueInformation + 0x30);  
					  
					  RtlInitUnicodeString(&subkeyname,L"\\REGISTRY\\USER\\.DEFAULT\\Volatile\\CurrentControlSet\\Hardware Profiles\\Current"); 
					             
					                                      
					  InitializeObjectAttributes(&oa,&subkeyname,OBJ_CASE_INSENSITIVE,KeyHandle,NULL);
					  status= ZwCreateKey(&KeyHandle, KEY_CREATE_LINK, &oa, 0, 0, REG_OPTION_VOLATILE |REG_OPTION_CREATE_LINK, &Disposition);	  
					 if (NT_SUCCESS(status))
					  {
					      sprintf(&unitevalue2,"\\REGISTRY\\USER\\.DEFAULT\\Volatile\\CurrentControlSet\\Hardware Profiles\\%04d",currentconfigvalue);
                          RtlInitAnsiString(&ansistring2,&unitevalue2);
		                  valuename.MaximumLength=256;
                          RtlAnsiStringToUnicodeString(&valuename,&ansistring2, FALSE); 
						  ZwSetValueKey(KeyHandle,&setvalue,0,REG_LINK,valuename.Buffer,valuename.Length);
                          
						  NtClose(KeyHandle);  					  		
					}
                     
				}
		      
		   }
		   		
	       status= STATUS_SUCCESS;
		}
	    else
	     NtClose(KeyHandle);

	}
  
	}

  }

ExFreePool(KeyValueInformation);

return status;
	
}


ring3的代码我就不提供了,文章后提供该小工具的bin下载,本文已发表在黑客防线2011年第2期,
在此十分感谢sudami牛,目前对磁盘还原十分有兴趣,希望能够继续学习,谢谢!!
具体效果示意图如下:


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (16)
雪    币: 1259
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
stu
2
学习了,很实用
2011-3-19 11:45
0
雪    币: 471
活跃值: (3703)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
3
非常不錯,謝謝了
2011-3-19 13:32
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
4
我顶啊。
2011-3-19 19:28
0
雪    币: 141
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
学习中  ~~
2011-3-19 20:38
0
雪    币: 192
活跃值: (44)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
object hook干涉注册表操作~我现在也学磁盘和文件系统啊~
2011-3-19 22:43
0
雪    币: 227
活跃值: (120)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
7
学习了~~~~~~·
直接蓝掉了。我擦
2011-3-20 14:31
0
雪    币: 379
活跃值: (152)
能力值: ( LV12,RANK:330 )
在线值:
发帖
回帖
粉丝
8
补充一下,本人的测试环境是xp系统,别的系统没有测试,无法保证;如果你在xp系统下有问题,请把你的dump发上来,我帮你分析一下
2011-3-20 14:45
0
雪    币: 27
活跃值: (90)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
9
学习
2011-3-20 15:11
0
雪    币: 27
活跃值: (90)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
10
btw: 黑客防线 貌似快被封闭了,不知内情
2011-3-20 15:14
0
雪    币: 2177
活跃值: (2045)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
11
好文章.Mark一下,可能以后有用,谢谢LZ.
2011-3-22 11:42
0
雪    币: 191
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
谢谢分享,mark!
2011-3-22 11:59
0
雪    币: 3
活跃值: (81)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
能把源代码放压缩包里就好了。
2011-3-22 22:13
0
雪    币: 52
活跃值: (56)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
楼主的开源精神值得敬佩
2011-3-23 16:18
0
雪    币: 220
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
仅以回复表示支持与感谢。
2011-3-23 17:01
0
雪    币: 220
活跃值: (701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
黑客防线,好象已经打不开了
2011-3-23 18:15
0
雪    币: 78
活跃值: (1698)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
好贴~HIVE啊 顶
2011-3-24 13:31
0
游客
登录 | 注册 方可回帖
返回
//