原本想寫個監控所有進程的注冊表添加的程序,但是在進行到快結束的時候,發現在我們平時的操作中注冊表操作太多了,過多的報警,反而覺得不好.最終是列出所有進程列表,從控制臺接受用戶輸入進程id來實現對進程及其子進程的注冊表修改以及進程創建的監控.
????該程序在用戶層下Hook了ZwCreateProcessEx和ZwSetValueKey兩個API,具體原理就不多說了,目標進程申請內存、代碼釋放、修改api入口、跳轉實現hook.感興趣的就看看吧..
????原先想實現的自動監控的功能沒有實現,不過大模塊已經完成了,原理很簡單,寫起代碼起來卻是很煩躁,動一發牽全身,實在有點痛苦,不愿意再去改這改那了,或許交給希望了解的人去測試,效果會好些^_^,最后請原諒代碼中出現的一些寫得非常糟糕的地方,我真的是不敢再去看自己的代碼了?
????測試方法:程序運行后,輸入你想要監視的進程ID,這時該進程,以及該進程所創建的任何進程都將被監視,并且在其修改注冊表的時候彈出對話框詢問是否允許進行該次注冊表修改操作,點'y'允許操作,否則拒絕操作.?(剛剛修改了一下,可以查看進程id和名稱,同時從控制臺接受進程id的輸入,從而對指定的進程監控)
簡單圖示:?

?編譯環境:winxp?sp2?+?vc6??
#include?<stdio.h>
#include?<windows.h>
#define?STATUS_SUCCESS??(0)
#define?ObjectNameInformation??(1)
#define?BLOCKSIZE?(0x1000)
#define?CurrentProcessHandle?????????????((HANDLE)(0xFFFFFFFF))
#define?NT_PROCESS_LIST??????????????????5
#define?STATUS_INFO_LEN_MISMATCH?????????0xC0000004
typedef?unsigned?long?NTSTATUS;
typedef?unsigned?long?SYSTEM_INFORMATION_CLASS;
typedef?unsigned?long?OBJECT_INFORMATION_CLASS;
typedef?struct{
????USHORT?Length;
????USHORT?MaxLen;
????USHORT?*Buffer;
}UNICODE_STRING,?*?PUNICODE_STRING;
typedef?struct?_OBJECT_NAME_INFORMATION?{?//?Information?Class?1
UNICODE_STRING?Name;
}?OBJECT_NAME_INFORMATION,?*POBJECT_NAME_INFORMATION;
typedef?struct?_RemoteParam{
????LPVOID??????????lpFunAddr;
????DWORD???????????dwParamSize;
????LPVOID??????????lpHeapAlloc;
????LPVOID??????????lpGetProcessHeap;
????LPVOID??????????lpHeapReAlloc;
????LPVOID??????????lpHeapFree;
????LPVOID??????????lpwsprintf;
????LPVOID??????????lpZwQueryObject;
????LPVOID??????????lpMessageBox;
????LPVOID??????????lpWriteProcessMemory;
????wchar_t?????????wProcessName[36];
????unsigned?char???szOldCode[12];
????unsigned?char???szNewCode[12];
????LPVOID??????????lpResumeThread;
????LPVOID??????????lpCreateEvent;
????LPVOID??????????lpOpenEvent;
????LPVOID??????????lpOpenFileMapping;
????LPVOID??????????lpMapViewOfFile;
????LPVOID??????????lpUnMapViewOfFile;
????LPVOID??????????lpOpenMutex;
????LPVOID??????????lpWaitForSingleObject;
????LPVOID??????????lpSetEvent;
????LPVOID??????????lpReleaseMutex;
????LPVOID??????????lpCloseHandle;
????LPVOID??????????lpGetProcessId;
????LPVOID??????????lpGetLastError;
}RemoteParam,?*?PRemoteParam;
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;???????????????//進程名稱;
??ULONG????????????BasePriority;??????????????//進程優先權;
??ULONG????????????ProcessId;?????????????????//進程標識符;
}SYSTEM_PROCESSES,?*?PSYSTEM_PROCESSES;
typedef
NTSTATUS
(__stdcall?*?NTQUERYSYSTEMINFORMATION)(?
IN??SYSTEM_INFORMATION_CLASS,?
OUT?PVOID,?
IN??ULONG,?
OUT?PULONG);
typedef
BOOL
(__stdcall?*?PFN_WRITEPROCESSMEMORY)(
IN??HANDLE?hProcess,
IN??LPVOID?lpBaseAddress,
IN??LPCVOID?lpBuffer,
IN??SIZE_T?nSize,
OUT?SIZE_T*?lpNumberOfBytesWritten
);
typedef
int
(__stdcall?*?PFN_MESSAGEBOX)(
IN??HWND?hWnd,
IN??LPCWSTR?lpText,
IN??LPCWSTR?lpCaption,
IN??UINT?uType
);
typedef
int
(__cdecl?*?PFN_WSPRINTF)(
IN??LPWSTR?lpOut,
IN??LPCWSTR?lpFmt,
...);
typedef
HANDLE
(__stdcall?*?PFN_GETPROCESSHEAP)(void);
typedef
LPVOID
(__stdcall?*?PFN_HEAPALLOC)(
IN??HANDLE?hHeap,
IN??DWORD?dwFlags,
IN??SIZE_T?dwBytes
);
typedef
LPVOID
(__stdcall?*?PFN_HEAPREALLOC)(
IN??HANDLE?hHeap,?
IN??DWORD?dwFlags,?
IN??LPVOID?lpMem,?
IN??DWORD?dwBytes?
);
typedef
BOOL
(__stdcall?*?PFN_HEAPFREE)(
IN??HANDLE?hHeap,
IN??DWORD?dwFlags,
IN??LPVOID?lpMem
);
typedef
NTSTATUS
(__stdcall?*?PFN_ZWSETVALUEKEY)(
IN??HANDLE?KeyHandle,
IN??PUNICODE_STRING?ValueName,
IN??ULONG?TitleIndex,
IN??ULONG?type1,
IN??PVOID?Data,
IN??ULONG?DataSize
);
typedef
NTSTATUS
(__stdcall?*?PFN_ZWQUERYOBJECT)(
IN??HANDLE?ObjectHandle,
IN??OBJECT_INFORMATION_CLASS?ObjectInformationClass,
OUT?PVOID?ObjectInformation,
IN??ULONG?ObjectInformationLength,
OUT?PULONG?ReturnLength
);
typedef
NTSTATUS
(__stdcall?*?PFN_ZWCREATEPROCESSEX)(
OUT?PHANDLE?ProcessHandle,
IN??ACCESS_MASK?DesiredAccess,
IN??LPVOID?ObjectAttributes,
IN??HANDLE?InheritFromProcessHandle,
IN??BOOLEAN?InheritHandles,
IN??HANDLE?SectionHandle,
IN??HANDLE?DebugPort,
IN??HANDLE?ExceptionPort,
IN??HANDLE?reserv
);
typedef
BOOL
(__stdcall?*?PFN_CREATEPROCESSW)(
IN??LPCTSTR?pszApplicationName,
IN??PTSTR?pszCommandLine,
IN??PSECURITY_ATTRIBUTES?psaProcess,
IN??PSECURITY_ATTRIBUTES?psaThread,
IN??BOOL?bInheritHandles,
IN??DWORD?fdwCreate,
IN??PVOID?pvEnvironment,
IN??LPCTSTR?pszCurDir,
OUT?LPSTARTUPINFO?psiStartInfo,
OUT?PPROCESS_INFORMATION?ppiProcInfo
);
typedef
DWORD
(__stdcall?*?PFN_RESUMETHREAD)(
IN??HANDLE?hThread
);
typedef
HANDLE
(__stdcall?*?PFN_CREATEEVENT)(
IN??LPSECURITY_ATTRIBUTES?lpEventAttributes,
IN??BOOL?bManualReset,
IN??BOOL?bInitialState,
IN??LPCTSTR?lpName
);
typedef
HANDLE
(__stdcall?*?PFN_OPENEVENT)(
IN??DWORD?dwDesiredAccess,
IN??BOOL?bInheritHandle,
IN??LPCTSTR?lpName
);
typedef
HANDLE
(__stdcall?*?PFN_OPENFILEMAPPING)(
IN??DWORD?dwDesiredAccess,
IN??BOOL?bInheritHandle,
IN??LPCTSTR?lpName
);
typedef
LPVOID
(__stdcall?*?PFN_MAPVIEWOFFILE)(
IN??HANDLE?hFileMappingObject,
IN??DWORD?dwDesiredAccess,
IN??DWORD?dwFileOffsetHigh,
IN??DWORD?dwFileOffsetLow,
IN??SIZE_T?dwNumberOfBytesToMap
);
typedef
BOOL?
(__stdcall?*?PFN_UNMAPVIEWOFFILE)(?
IN??LPCVOID?lpBaseAddress
);
typedef
HANDLE
(__stdcall?*?PFN_OPENMUTEX)(
IN??DWORD?dwDesiredAccess,
IN??BOOL?bInheritHandle,
IN??LPCTSTR?lpName
);
typedef
DWORD
(__stdcall?*?PFN_WAITFORSINGLEOBJECT)(
IN??HANDLE?hHandle,?
IN??DWORD?dwMilliseconds?
);?
typedef
BOOL
(__stdcall?*?PFN_SETEVENT)(
IN??HANDLE?hEvent
);
typedef
BOOL
(__stdcall?*?PFN_RELEASEMUTEX)(
IN??HANDLE?hMutex
);
typedef
BOOL
(__stdcall?*?PFN_CLOSEHANDLE)(
IN??HANDLE?hObject
);
typedef
DWORD
(__stdcall?*?PFN_GETPROCESSID)(
IN??HANDLE?Process
);
typedef
DWORD
(__stdcall?*?PFN_GETLASTERROR)(void);
//////////////////////////////////////////////////////////////////////////
//Hook?CreateProcessW
//Returns?True
//////////////////////////////////////////////////////////////////////////
void?HookCreateProcessW(LPVOID?lParam)
{
????RemoteParam*?Rpm?=?(RemoteParam*)lParam;
????PFN_CREATEPROCESSW?pfnCreateProcessW?=?(PFN_CREATEPROCESSW)Rpm->lpFunAddr;
????PFN_WRITEPROCESSMEMORY?pfnWriteProcessMemory?=?(PFN_WRITEPROCESSMEMORY)Rpm->lpWriteProcessMemory;
????PFN_MESSAGEBOX?pfnMessageBox?=?(PFN_MESSAGEBOX)Rpm->lpMessageBox;
????PFN_RESUMETHREAD?pfnResumeThread?=?(PFN_RESUMETHREAD)Rpm->lpResumeThread;
????
????LPCTSTR?pszApplicationName?=?NULL;
????PTSTR?pszCommandLine?=?NULL;
????PSECURITY_ATTRIBUTES?psaProcess?=?NULL;
????PSECURITY_ATTRIBUTES?psaThread?=?NULL;
????BOOL?bInheritHandles?=?TRUE;
????DWORD?fdwCreate?=?0;
????PVOID?pvEnvironment?=?NULL;
????LPCTSTR?pszCurDir?=?NULL;
????LPSTARTUPINFO?psiStartInfo?=?NULL;
????PPROCESS_INFORMATION?ppiProcInfo?=?NULL;
????
????BOOL?Retvalue?=?TRUE;?//定義要攔截的api的默認返回植
????DWORD?NextIpAddr?=?0;
????DWORD?dwParamaAddr?=?0;
????long?temp1?=?0;
????
????__asm?
????{
????????MOV?EAX,?[EBP?+?12]
????????MOV?[NextIpAddr],?EAX
????????MOV?EAX,?[EBP?+?16]
????????MOV?[pszApplicationName],?EAX
????????MOV?EAX,?[EBP?+?20]
????????MOV?[pszCommandLine],?EAX
????????MOV?EAX,?[EBP?+?24]
????????MOV?[psaProcess],?EAX
????????MOV?EAX,?[EBP?+?28]
????????MOV?[psaThread],?EAX
????????MOV?EAX,?[EBP?+?32]
????????MOV?[temp1],?EAX
????????MOV?EAX,?[EBP?+?36]
????????MOV?[fdwCreate],?EAX????????
????????MOV?EAX,?[EBP?+?40]
????????MOV?[pvEnvironment],?EAX
????????MOV?EAX,?[EBP?+?44]
????????MOV?[pszCurDir],?EAX
????????MOV?EAX,?[EBP?+?48]
????????MOV?[psiStartInfo],?EAX????
????????MOV?EAX,?[EBP?+?52]
????????MOV?[ppiProcInfo],?EAX
????}
????bInheritHandles?=?(BOOL)temp1;
//????fdwCreate?=?fdwCreate?|?CREATE_SUSPENDED;?
????//這里可以做你的事情了,比如我只想彈出一個對話框,其實也可以在讓api完成之后再做些東西
??????
????pfnWriteProcessMemory(CurrentProcessHandle,?Rpm->lpFunAddr,?(LPCVOID)Rpm->szOldCode,?12,?NULL);
????//讓api真正執行
????Retvalue?=?pfnCreateProcessW(
????????pszApplicationName,
????????pszCommandLine,
????????psaProcess,
????????psaThread,
????????bInheritHandles,
????????fdwCreate,
????????pvEnvironment,
????????pszCurDir,
????????psiStartInfo,
????????ppiProcInfo);?
????//再次恢復對他的攔截
????pfnWriteProcessMemory(CurrentProcessHandle,?Rpm->lpFunAddr,?(LPCVOID)Rpm->szNewCode,?12,?NULL);
????pfnMessageBox(NULL,?Rpm->wProcessName,?Rpm->wProcessName,?0);
//????pfnResumeThread(ppiProcInfo->hThread);
???
????DWORD?dwStackSize?=?12?+?Rpm->dwParamSize;
???
????//這里對攔截函數堆棧的恢復
????__asm
????{
???????POP?EDI?????
???????POP?ESI?????
???????POP?EBX
???????MOV?ECX,?[dwStackSize]
???????MOV?EDX,?[NextIpAddr]
???????MOV?EAX,?[Retvalue]
???????MOV?ESP,?EBP
???????POP?EBP
???????ADD?ESP,?ECX???//恢復堆棧
???????PUSH?EDX
???????RET
????}
}
//////////////////////////////////////////////////////////////////////////
//Hook?ZwCreateProcessEx
//Returns?STATUS_SUCCESS?or?an?error?status,?such?as?STATUS_ACCESS_DENIED?or
//STATUS_INVALID_HANDLE.
//////////////////////////////////////////////////////////////////////////
void?HookZwCreateProcessEx(LPVOID?lParam)
{
????RemoteParam*?Rpm?=?(RemoteParam*)lParam;
????PFN_ZWCREATEPROCESSEX?pfnZwCreateprocessEx?=?(PFN_ZWCREATEPROCESSEX)Rpm->lpFunAddr;
????PFN_WRITEPROCESSMEMORY?pfnWriteProcessMemory?=?(PFN_WRITEPROCESSMEMORY)Rpm->lpWriteProcessMemory;
????PFN_MESSAGEBOX?pfnMessageBox?=?(PFN_MESSAGEBOX)Rpm->lpMessageBox;
????PFN_WSPRINTF?pfnwsprintf?=?(PFN_WSPRINTF)Rpm->lpwsprintf;
//????wchar_t?wOut[32]?=?{'\0'};
//????wchar_t?wFmr[3]?=?{'%',?'x',?'\0'};
????PFN_CREATEEVENT?pfnCreateEvent?=?(PFN_CREATEEVENT)Rpm->lpCreateEvent;
????PFN_OPENEVENT?pfnOpenEvent?=?(PFN_OPENEVENT)Rpm->lpOpenEvent;
????PFN_OPENFILEMAPPING?pfnOpenFileMapping?=?(PFN_OPENFILEMAPPING)Rpm->lpOpenFileMapping;
????PFN_MAPVIEWOFFILE?pfnMapViewOfFile?=?(PFN_MAPVIEWOFFILE)Rpm->lpMapViewOfFile;
????PFN_UNMAPVIEWOFFILE?pfnUnMapViewOfFile?=?(PFN_UNMAPVIEWOFFILE)Rpm->lpUnMapViewOfFile;
????PFN_OPENMUTEX?pfnOpenMutex?=?(PFN_OPENMUTEX)Rpm->lpOpenMutex;
????PFN_WAITFORSINGLEOBJECT?pfnWaitForSingleObject?=?(PFN_WAITFORSINGLEOBJECT)Rpm->lpWaitForSingleObject;
????PFN_SETEVENT?pfnSetEvent?=?(PFN_SETEVENT)Rpm->lpSetEvent;
????PFN_RELEASEMUTEX?pfnReleaseMutex?=?(PFN_RELEASEMUTEX)Rpm->lpReleaseMutex;
????PFN_CLOSEHANDLE?pfnCloseHandle?=?(PFN_CLOSEHANDLE)Rpm->lpCloseHandle;
????PFN_GETPROCESSID?pfnGetProcessId?=?(PFN_GETPROCESSID)Rpm->lpGetProcessId;
????PFN_GETLASTERROR?pfnGetLastError?=?(PFN_GETLASTERROR)Rpm->lpGetLastError;
????HANDLE?hHookMainAliveEvent?=?NULL;
????HANDLE?hMapFileOperateMutex?=?NULL;
????HANDLE?hMapFileModifiedEvent?=?NULL;
????HANDLE?hHookNewProcessDoneEvent?=?NULL;
????HANDLE?hMapFileToNewProcessId?=?NULL;
????LPVOID?lpMapFileToNewProcessId?=?NULL;
????char?szHookMainAliveEvent[20]?=?{'H',?'o',?'o',?'k',?'M',?'a',?'i',?'n',?'A',
?????????????????????????????????????'l',?'i',?'v',?'e',?'E',?'v',?'e',?'n',?'t',?'\0'};
????char?szMapFileOperateMutex[21]?=?{'M',?'a',?'p',?'F',?'i',?'l',?'e',?'O',?'p',?'e',
??????????????????????????????????????'r',?'a',?'t',?'e',?'M',?'u',?'t',?'e',?'x',?'\0'};
????char?szMapFileModifiedEvent[22]?=?{'M',?'a',?'p',?'F',?'i',?'l',?'e',?'M',?'o',?'d',
???????????????????????????????????????'i',?'f',?'i',?'e',?'d',?'E',?'v',?'e',?'n',?'t',?'\0'};
????char?szHookNewProcessDoneEvent[25]?=?{'H',?'o',?'o',?'k',?'N',?'e',?'w',?'P',?'r',?'o',?'c',
??????????????????????????????????????????'e',?'s',?'s',?'D',?'o',?'n',?'e',?'E',?'v',?'e',?'n',?'t',?'\0'};
????char?szMapFileToNewProcessId[23]?={'M',?'a',?'p',?'F',?'i',?'l',?'e',?'T',?'o',?'N',?'e',
???????????????????????????????????????'w',?'P',?'r',?'o',?'c',?'e',?'s',?'s',?'I',?'d',?'\0'};
????PHANDLE?ProcessHandle?=?NULL;?
????ACCESS_MASK?DesiredAccess?=?0;
????LPVOID?ObjectAttributes?=?NULL;
????HANDLE?InheritFromProcessHandle?=?NULL;
????BOOLEAN?InheritHandles?=?TRUE;
????HANDLE?SectionHandle?=?NULL;
????HANDLE?DebugPort?=?NULL;
????HANDLE?ExceptionPort?=?NULL;
????HANDLE?reserv?=?NULL;
????
????NTSTATUS?Retvalue?=?STATUS_SUCCESS;?//定義要攔截的api的默認返回植
????DWORD?NextIpAddr?=?0;
????DWORD?dwParamaAddr?=?0;
????DWORD?temp1?=?0;
????
????__asm?
????{
????????MOV?EAX,?[EBP?+?12]
????????MOV?[NextIpAddr],?EAX
????????MOV?EAX,?[EBP?+?16]
????????MOV?[ProcessHandle],?EAX
????????MOV?EAX,?[EBP?+?20]
????????MOV?[DesiredAccess],?EAX
????????MOV?EAX,?[EBP?+?24]
????????MOV?[ObjectAttributes],?EAX
????????MOV?EAX,?[EBP?+?28]
????????MOV?[InheritFromProcessHandle],?EAX
????????MOV?EAX,?[EBP?+?32]
????????MOV?[temp1],?EAX
????????MOV?EAX,?[EBP?+?36]
????????MOV?[SectionHandle],?EAX????????
????????MOV?EAX,?[EBP?+?40]
????????MOV?[DebugPort],?EAX
????????MOV?EAX,?[EBP?+?44]
????????MOV?[ExceptionPort],?EAX
????????MOV?EAX,?[EBP?+?48]
????????MOV?[reserv],?EAX????????
????}
????InheritHandles?=?(BOOLEAN)temp1;
??????
????pfnWriteProcessMemory(CurrentProcessHandle,?Rpm->lpFunAddr,?(LPCVOID)Rpm->szOldCode,?12,?NULL);
????//讓api真正執行
????Retvalue?=?pfnZwCreateprocessEx(ProcessHandle,
????????????????????????????????????DesiredAccess,
????????????????????????????????????ObjectAttributes,
????????????????????????????????????InheritFromProcessHandle,
????????????????????????????????????InheritHandles,
????????????????????????????????????SectionHandle,
????????????????????????????????????DebugPort,
????????????????????????????????????ExceptionPort,
????????????????????????????????????reserv);
????DWORD?dwStackSize?=?12?+?Rpm->dwParamSize;
????
//新進程已經創建,此時進程空間中僅僅加載ntdll.dll和進程映象本身,主線程也尚未啟動,
//這里把返回的進程句柄轉換成進程id放到內存映射文件中去,交由主攔截進程對其進行攔截,
//此時該創建處于block狀態,等待主攔截進程攔截完畢的對象消息,然后再恢復進程的創建。
????hHookMainAliveEvent?=?pfnCreateEvent(NULL,?TRUE,?TRUE,?szHookMainAliveEvent);
????if(pfnGetLastError()?==?ERROR_ALREADY_EXISTS)?
????{
????????//再次恢復對他的攔截
????????pfnWriteProcessMemory(CurrentProcessHandle,?Rpm->lpFunAddr,?(LPCVOID)Rpm->szNewCode,?12,?NULL);
????????
????????hMapFileToNewProcessId?=?pfnOpenFileMapping(FILE_MAP_ALL_ACCESS,?NULL,?szMapFileToNewProcessId);
????????if(hMapFileToNewProcessId?==?NULL)
????????{
????????????__asm
????????????{
????????????????POP?EDI?????
????????????????POP?ESI?????
????????????????POP?EBX
????????????????MOV?ECX,?[dwStackSize]
????????????????MOV?EDX,?[NextIpAddr]
????????????????MOV?EAX,?[Retvalue]
????????????????MOV?ESP,?EBP
????????????????POP?EBP
????????????????ADD?ESP,?ECX???//恢復堆棧
????????????????PUSH?EDX
????????????????RET
????????????}
????????}
????????lpMapFileToNewProcessId?=?pfnMapViewOfFile(hMapFileToNewProcessId,?FILE_MAP_ALL_ACCESS,?0,?0,?0);
????????if(lpMapFileToNewProcessId?==?NULL)
????????{
????????????pfnCloseHandle(hMapFileToNewProcessId);
????????????__asm
????????????{
????????????????POP?EDI?????
????????????????POP?ESI?????
????????????????POP?EBX
????????????????MOV?ECX,?[dwStackSize]
????????????????MOV?EDX,?[NextIpAddr]
????????????????MOV?EAX,?[Retvalue]
????????????????MOV?ESP,?EBP
????????????????POP?EBP
????????????????ADD?ESP,?ECX???//恢復堆棧
????????????????PUSH?EDX
????????????????RET
????????????}
????????}
????????hMapFileOperateMutex?=?pfnOpenMutex(MUTEX_MODIFY_STATE,?FALSE,?szMapFileOperateMutex);
????????if(hMapFileOperateMutex?==?NULL)
????????{
????????????pfnUnMapViewOfFile(lpMapFileToNewProcessId);
????????????pfnCloseHandle(hMapFileToNewProcessId);
????????????__asm
????????????{
????????????????POP?EDI?????
????????????????POP?ESI?????
????????????????POP?EBX
????????????????MOV?ECX,?[dwStackSize]
????????????????MOV?EDX,?[NextIpAddr]
????????????????MOV?EAX,?[Retvalue]
????????????????MOV?ESP,?EBP
????????????????POP?EBP
????????????????ADD?ESP,?ECX???//恢復堆棧
????????????????PUSH?EDX
????????????????RET
????????????}
????????}
????????DWORD?dwPid?=?pfnGetProcessId(*ProcessHandle);
????????if(dwPid?==?0)
????????{
????????????pfnUnMapViewOfFile(lpMapFileToNewProcessId);
????????????pfnCloseHandle(hMapFileToNewProcessId);
????????????pfnCloseHandle(hMapFileOperateMutex);
????????????__asm
????????????{
????????????????POP?EDI?????
????????????????POP?ESI?????
????????????????POP?EBX
????????????????MOV?ECX,?[dwStackSize]
????????????????MOV?EDX,?[NextIpAddr]
????????????????MOV?EAX,?[Retvalue]
????????????????MOV?ESP,?EBP
????????????????POP?EBP
????????????????ADD?ESP,?ECX???//恢復堆棧
????????????????PUSH?EDX
????????????????RET
????????????}
????????}
????????pfnWaitForSingleObject(hMapFileOperateMutex,?INFINITE);
????????DWORD?*?temp2?=?(DWORD*)lpMapFileToNewProcessId;
????????*temp2?=?dwPid;
????????pfnUnMapViewOfFile(lpMapFileToNewProcessId);
????????pfnCloseHandle(hMapFileToNewProcessId);
????????
????????hMapFileModifiedEvent?=?pfnOpenEvent(EVENT_MODIFY_STATE,?NULL,?szMapFileModifiedEvent);
????????if(hMapFileModifiedEvent?==?NULL)
????????{
????????????pfnReleaseMutex(hMapFileOperateMutex);
????????????pfnCloseHandle(hMapFileOperateMutex);
????????????__asm
????????????{
????????????????POP?EDI?????
????????????????POP?ESI?????
????????????????POP?EBX
????????????????MOV?ECX,?[dwStackSize]
????????????????MOV?EDX,?[NextIpAddr]
????????????????MOV?EAX,?[Retvalue]
????????????????MOV?ESP,?EBP
????????????????POP?EBP
????????????????ADD?ESP,?ECX???//恢復堆棧
????????????????PUSH?EDX
????????????????RET
????????????}
????????}
????????pfnSetEvent(hMapFileModifiedEvent);
????????hHookNewProcessDoneEvent?=?pfnOpenEvent(EVENT_MODIFY_STATE,?NULL,?szHookNewProcessDoneEvent);
?????????if(hHookNewProcessDoneEvent?==?NULL)
????????{
????????????pfnReleaseMutex(hMapFileOperateMutex);
????????????pfnCloseHandle(hMapFileOperateMutex);
????????????pfnCloseHandle(hMapFileModifiedEvent);
????????????__asm
????????????{
????????????????POP?EDI?????
????????????????POP?ESI?????
????????????????POP?EBX
????????????????MOV?ECX,?[dwStackSize]
????????????????MOV?EDX,?[NextIpAddr]
????????????????MOV?EAX,?[Retvalue]
????????????????MOV?ESP,?EBP
????????????????POP?EBP
????????????????ADD?ESP,?ECX???//恢復堆棧
????????????????PUSH?EDX
????????????????RET
????????????}
????????}
????????pfnWaitForSingleObject(hHookNewProcessDoneEvent,?INFINITE);
????????pfnCloseHandle(hMapFileModifiedEvent);
????????pfnCloseHandle(hHookNewProcessDoneEvent);
????????pfnReleaseMutex(hMapFileOperateMutex);
????????pfnCloseHandle(hMapFileOperateMutex);
????}
????else
????{
????????pfnCloseHandle(hHookMainAliveEvent);
????}
????//這里對攔截函數堆棧的恢復
????__asm
????{
???????POP?EDI?????
???????POP?ESI?????
???????POP?EBX
???????MOV?ECX,?[dwStackSize]
???????MOV?EDX,?[NextIpAddr]
???????MOV?EAX,?[Retvalue]
???????MOV?ESP,?EBP
???????POP?EBP
???????ADD?ESP,?ECX???//恢復堆棧
???????PUSH?EDX
???????RET
????}????
}
//////////////////////////////////////////////////////////////////////////
//Hook?ZwSetValueKey
//Returns?STATUS_SUCCESS?or?an?error?status,?such?as?STATUS_ACCESS_DENIED,
//STATUS_INVALID_HANDLE,?STATUS_KEY_DELETED,?or?STATUS_NO_LOG_SPACE.
//////////////////////////////////////////////////////////////////////////
void?HookZwSetValueKey(LPVOID?lParam)
{
????RemoteParam*?Rpm?=?(RemoteParam*)lParam;
????PFN_ZWSETVALUEKEY?pfnZwSetValueKey?=?(PFN_ZWSETVALUEKEY)Rpm->lpFunAddr;
????PFN_WRITEPROCESSMEMORY?pfnWriteProcessMemory?=?(PFN_WRITEPROCESSMEMORY)Rpm->lpWriteProcessMemory;
????PFN_MESSAGEBOX?pfnMessageBox?=?(PFN_MESSAGEBOX)Rpm->lpMessageBox;
????PFN_ZWQUERYOBJECT?pfnZwQueryObject?=?(PFN_ZWQUERYOBJECT)Rpm->lpZwQueryObject;
????PFN_WSPRINTF?pfnwsprintf?=?(PFN_WSPRINTF)Rpm->lpwsprintf;
????PFN_GETPROCESSHEAP?pfnGetProcessHeap?=?(PFN_GETPROCESSHEAP)Rpm->lpGetProcessHeap;
????PFN_HEAPALLOC?pfnHeapAlloc?=?(PFN_HEAPALLOC)Rpm->lpHeapAlloc;
????PFN_HEAPREALLOC?pfnHeapReAlloc?=?(PFN_HEAPREALLOC)Rpm->lpHeapReAlloc;
????PFN_HEAPFREE?pfnHeapFree?=?(PFN_HEAPFREE)Rpm->lpHeapFree;
????PFN_CREATEEVENT?pfnCreateEvent?=?(PFN_CREATEEVENT)Rpm->lpCreateEvent;
????PFN_GETLASTERROR?pfnGetLastError?=?(PFN_GETLASTERROR)Rpm->lpGetLastError;
????PFN_CLOSEHANDLE?pfnCloseHandle?=?(PFN_CLOSEHANDLE)Rpm->lpCloseHandle;
????
????HANDLE?KeyHandle?=?NULL;
????PUNICODE_STRING?ValueName?=?NULL;
????ULONG?TitleIndex?=?0;
????ULONG?type1?=?0;
????PVOID?Data?=?NULL;
????ULONG?DataSize?=?0;
????
????NTSTATUS?Retvalue?=?STATUS_SUCCESS;?//定義要攔截的api的默認返回植
????DWORD?NextIpAddr?=?0;
????DWORD?dwParamaAddr?=?0;
????DWORD?dwStackSize?=?12?+?Rpm->dwParamSize;
????__asm?
????{
????????MOV?EAX,?[EBP?+?12]
????????MOV?[NextIpAddr],?EAX
????????MOV?EAX,?[EBP?+?16]
????????MOV?[KeyHandle],?EAX
????????MOV?EAX,?[EBP?+?20]
????????MOV?[ValueName],?EAX
????????MOV?EAX,?[EBP?+?24]
????????MOV?[TitleIndex],?EAX
????????MOV?EAX,?[EBP?+?28]
????????MOV?[type1],?EAX
????????MOV?EAX,?[EBP?+?32]
????????MOV?[Data],?EAX
????????MOV?EAX,?[EBP?+?36]
????????MOV?[DataSize],?EAX????????????
????}
????HANDLE?hHeap?=?pfnGetProcessHeap();
????DWORD?retSize?=?0;
????POBJECT_NAME_INFORMATION?pName?=?(POBJECT_NAME_INFORMATION)pfnHeapAlloc(hHeap,?HEAP_ZERO_MEMORY,?BLOCKSIZE);????
????NTSTATUS?ns?=?pfnZwQueryObject(KeyHandle,?ObjectNameInformation,?(PVOID)pName,?BLOCKSIZE,?&retSize);
????DWORD?i?=?1;
????while(ns?==?STATUS_INFO_LEN_MISMATCH)
????{
????????pName?=?(POBJECT_NAME_INFORMATION)pfnHeapReAlloc(hHeap,?HEAP_ZERO_MEMORY,?(LPVOID)pName,?BLOCKSIZE?*?i);
????????ns?=?pfnZwQueryObject(KeyHandle,?ObjectNameInformation,?(PVOID)pName,?BLOCKSIZE,?NULL);
????????i++;
????}
????char?szHookMainAliveEvent[20]?=?{'H',?'o',?'o',?'k',?'M',?'a',?'i',?'n',?'A',
?????????????????????????????????????'l',?'i',?'v',?'e',?'E',?'v',?'e',?'n',?'t',?'\0'};???
????wchar_t?wObjectPath[260]?=?{'\0'};
????wchar_t?wFmr1[21]?=?{'%',?'s',?'\',?'%',?'s',?'?',?'?',?'v',?'a',?'l',?'u',?'e',?':',?'%',
?????????????????????????'s',?'?',?'Y',?'/',?'N',?'?',?'\0'};
????wchar_t?wFmr2[27]?=?{'%',?'s',?'\',?'%',?'s',?'?',?'?',?'v',?'a',?'l',?'u',?'e',?':',?'%',
?????????????????????????'d',?'(',?'0',?'X',?'%',?'X',?')',?'?',?'Y',?'/',?'N',?'?',?'\0'};
????wchar_t?wFmr3[27]?=?{'%',?'s',?'\',?'%',?'s',?'?',?'?',?'t',?'y',?'p',?'e',?':',?'R',?'E',
?????????????????????????'G',?'_',?'B',?'I',?'N',?'A',?'Y',?'?',?'Y',?'/',?'N',?'?',?'\0'};
????wchar_t?wFmr4[35]?=?{'%',?'s',?'\',?'%',?'s',?'?',?'?',?'t',?'y',?'p',?'e',?':',?'R',?'E',
?????????????????????????'G',?'_',?'R',?'E',?'S',?'O',?'U',?'R',?'C',?'E',?'_',?'L',?'I',?'S',?
?????????????????????????'T',?'?',?'Y',?'/',?'N',?'?',?'\0'};
????if(type1?==?4?||?type1?==?5?||?type1?==?11)
????????pfnwsprintf(wObjectPath,?wFmr2,?pName->Name.Buffer,?ValueName->Buffer,?*(DWORD*)Data,?*(DWORD*)Data);
????else?if(type1?==?3)
????????pfnwsprintf(wObjectPath,?wFmr3,?pName->Name.Buffer,?ValueName->Buffer);
????else?if(type1?==?8)
????????pfnwsprintf(wObjectPath,?wFmr4,?pName->Name.Buffer,?ValueName->Buffer);
????else
????????pfnwsprintf(wObjectPath,?wFmr1,?pName->Name.Buffer,?ValueName->Buffer,?Data);
????pfnHeapFree(hHeap,?HEAP_ZERO_MEMORY,?pName);
????
????HANDLE?hHookMainAliveEvent?=?pfnCreateEvent(NULL,?TRUE,?TRUE,?szHookMainAliveEvent);
????DWORD?dwBeHooked?=?0;
????if(pfnGetLastError()?==?ERROR_ALREADY_EXISTS)
????{
????????dwBeHooked?=?1;
????????int?allowFlag?=?pfnMessageBox(NULL,?wObjectPath,?Rpm->wProcessName,?MB_ICONINFORMATION?|?MB_YESNO);
????????if(allowFlag?!=?IDYES)
????????{
????????????__asm
????????????{
????????????????POP?EDI?????
????????????????POP?ESI?????
????????????????POP?EBX
????????????????MOV?ECX,?[dwStackSize]
????????????????MOV?EDX,?[NextIpAddr]
????????????????MOV?EAX,?[Retvalue]
????????????????MOV?ESP,?EBP
????????????????POP?EBP
????????????????ADD?ESP,?ECX?//恢復堆棧
????????????????PUSH?EDX
????????????????RET
????????????}
????????}
????}????
????pfnWriteProcessMemory(CurrentProcessHandle,?Rpm->lpFunAddr,?(LPCVOID)Rpm->szOldCode,?12,?NULL);
????
????//讓api真正執行
????Retvalue?=?pfnZwSetValueKey(
????????KeyHandle,
????????ValueName,
????????TitleIndex,
????????type1,
????????Data,
????????DataSize);
????//如果主監視進程存活則再次恢復對他的攔截
????if(dwBeHooked?==?1)
????????pfnWriteProcessMemory(CurrentProcessHandle,?Rpm->lpFunAddr,?(LPCVOID)Rpm->szNewCode,?12,?NULL);
????pfnCloseHandle(hHookMainAliveEvent);
????//這里對攔截函數堆棧的恢復
????__asm
????{
???????POP?EDI?????
???????POP?ESI?????
???????POP?EBX
???????MOV?ECX,?[dwStackSize]
???????MOV?EDX,?[NextIpAddr]
???????MOV?EAX,?[Retvalue]
???????MOV?ESP,?EBP
???????POP?EBP
???????ADD?ESP,?ECX?//恢復堆棧
???????PUSH?EDX
???????RET
????}
}
//////////////////////////////////////////////////////////////////////////
//************************************************************************
//模塊名字:AdjustProcessPrivileges(LPCSTR)
//模塊功能:修改調用進程的權限
//返回數值:成功返回TRUE,失敗返回FALSE
//參數選項:?
//?#define?SE_BACKUP_NAME????????TEXT("SeBackupPrivilege")
//?#define?SE_RESTORE_NAME???????TEXT("SeRestorePrivilege")
//?#define?SE_SHUTDOWN_NAME??????TEXT("SeShutdownPrivilege")
//?#define?SE_DEBUG_NAME?????????TEXT("SeDebugPrivilege")
//////////////////////////////////////////////////////////////////////////
BOOL?AdjustProcessPrivileges(LPCSTR?lpPrivilegesName)
{
????HANDLE?hToken;?
????TOKEN_PRIVILEGES?tkp;
????if(!OpenProcessToken(CurrentProcessHandle,
????????TOKEN_ADJUST_PRIVILEGES?|?TOKEN_QUERY,?&hToken))
????{
????????return?FALSE;
????}
????if(!LookupPrivilegeValue(NULL,?lpPrivilegesName,?&tkp.Privileges[0].Luid))
????{
????????CloseHandle(hToken);
????????return?FALSE;
????}
????
????tkp.PrivilegeCount?=?1;
????tkp.Privileges[0].Attributes?=?SE_PRIVILEGE_ENABLED;
????if(!AdjustTokenPrivileges(hToken,?FALSE,?&tkp,?sizeof(tkp),?NULL,?NULL))
????{
????????CloseHandle(hToken);
????????return?FALSE;
????}
????CloseHandle(hToken);
????return?TRUE;
}
int?SetHook(DWORD?dwPid,?LPWSTR?lpProcessName,?LPCTSTR?lpApiName,?LPCTSTR?lpExportDllName,DWORD?dwParamNum,?DWORD?dwHookFunSize,?LPVOID?lpHookFunAddr)
{
????if(!AdjustProcessPrivileges(SE_DEBUG_NAME))
????{
????????printf("-----AdjustProcessPrivileges?error..\n");
????????return?-1;
????}
????printf("1:AdjustProcessPrivileges?ok\n");
????
????//獲取要攔截的api的地址
????HMODULE?hExportDll?=?LoadLibrary(lpExportDllName);
????if(hExportDll?==?NULL)
????{
????????printf("-----LoadLibrary?error..\n");
????????return?-1;
????}
????
????LPVOID?lpApiAddr?=?GetProcAddress(hExportDll,?lpApiName);
????if(lpApiAddr?==?NULL)
????{
????????printf("-----GetProcAddress?%s?error..\n",?lpApiName);
????????FreeLibrary(hExportDll);
????????return?-1;
????}
????
????//打開進程句柄
????HANDLE?hTargetProcess?=?OpenProcess(PROCESS_VM_OPERATION?|?PROCESS_VM_WRITE?|?PROCESS_VM_READ,
????????????????????????????????????????FALSE,?dwPid);
????if(hTargetProcess?==?NULL)
????{
????????printf("-----OpenProcess?%d?error..\n",?dwPid);
????????FreeLibrary(hExportDll);
????????return?-1;
????}
????
????//申請攔截函數內存空間
????LPVOID?lpFunAddr?=?VirtualAllocEx(hTargetProcess,?NULL,?dwHookFunSize,?
??????????????????????????????????????MEM_COMMIT?|?MEM_RESERVE,?PAGE_EXECUTE_READWRITE);
????if(lpFunAddr?==?NULL)
????{
????????printf("-----VirtualAllocEx?for?remotefuction?error..\n");
????????FreeLibrary(hExportDll);
????????CloseHandle(hTargetProcess);
????????return?-1;
????}
????
????//申請遠程參數空間
????LPVOID?lpParamaAddr?=?VirtualAllocEx(hTargetProcess,?NULL,?sizeof(RemoteParam),?
?????????????????????????????????????????MEM_COMMIT?|?MEM_RESERVE,?PAGE_EXECUTE_READWRITE);
????if(lpParamaAddr?==?NULL)
????{
????????printf("-----VirtualAllocEx?for?remoteparam?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????return?-1;
????}
????printf("2:Alloc?remote?memory?for?the?hook?fuction?and?param?ok\n");
????
????
????//設置遠程參數,下一步要把參數寫入要攔截的遠程進程地址空間
????RemoteParam?RParam;
????ZeroMemory(&RParam,?sizeof(RParam));
????wcscpy(RParam.wProcessName,?lpProcessName);
????
????unsigned?char?oldcode[12];
????unsigned?char?newcode[12];
????DWORD?dwError?=?0;
????if(!ReadProcessMemory(CurrentProcessHandle,
????????lpApiAddr,
????????oldcode,
????????12,
????????&dwError))
????{
????????printf("-----ReadProcessMemory?from?lpApiName?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????return?-1;
????}
????//生成跳轉指令,這將覆蓋要攔截的api的前十個字節?
????int?praadd?=?(int)lpParamaAddr;
????int?threadadd?=?(int)lpFunAddr;
????newcode[4]?=?praadd>>24;
????newcode[3]?=?(praadd<<8)>>24;
????newcode[2]?=?(praadd<<16)>>24;
????newcode[1]?=?(praadd<<24)>>24;
????newcode[0]?=?0x68;??//PUSH?lpParamaAddr
????int?offsetaddr?=?threadadd?-?(int)lpApiAddr?-?10?;
????newcode[9]?=?offsetaddr>>24;
????newcode[8]?=?(offsetaddr<<8)>>24;
????newcode[7]?=?(offsetaddr<<16)>>24;
????newcode[6]?=?(offsetaddr<<24)>>24;
????newcode[5]?=?0xE8;??//CALL?lpFunAddr
????newcode[10]?=?0x90;
????newcode[11]?=?0x90;
????
????for(int?j?=?0;?j?<?12;?j++)
????{
????????RParam.szOldCode[j]?=?oldcode[j];
????????RParam.szNewCode[j]?=?newcode[j];
????}
????RParam.lpFunAddr?=?lpApiAddr;
????RParam.dwParamSize?=?dwParamNum?*?4;
????
????HMODULE?hKernel32?=?LoadLibrary("Kernel32.dll");
????if(hKernel32?==?NULL)
????{
????????printf("-----LoadLibrary?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????return?-1;
????}
????
????RParam.lpWriteProcessMemory?=?GetProcAddress(hKernel32,?"WriteProcessMemory");
????if(RParam.lpWriteProcessMemory?==?NULL)
????{
????????printf("-----GetProcAddress?WriteProcessMemory?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????RParam.lpGetProcessHeap?=?GetProcAddress(hKernel32,?"GetProcessHeap");
????if(RParam.lpGetProcessHeap?==?NULL)
????{
????????printf("-----GetProcAddress?GetProcessHeap?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????RParam.lpHeapAlloc?=?GetProcAddress(hKernel32,?"HeapAlloc");
????if(RParam.lpHeapAlloc?==?NULL)
????{
????????printf("-----GetProcAddress?HeapAlloc?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????RParam.lpHeapReAlloc?=?GetProcAddress(hKernel32,?"HeapReAlloc");
????if(RParam.lpHeapReAlloc?==?NULL)
????{
????????printf("-----GetProcAddress?HeapReAlloc?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????RParam.lpHeapFree?=?GetProcAddress(hKernel32,?"HeapFree");
????if(RParam.lpHeapFree?==?NULL)
????{
????????printf("-----GetProcAddress?HeapFree?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????RParam.lpResumeThread?=?GetProcAddress(hKernel32,?"ResumeThread");
????if(RParam.lpHeapFree?==?NULL)
????{
????????printf("-----GetProcAddress?ResumeThread?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????
????RParam.lpCreateEvent?=?GetProcAddress(hKernel32,?"CreateEventA");
????if(RParam.lpCreateEvent?==?NULL)
????{
????????printf("-----GetProcAddress?CreateEventA?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????RParam.lpOpenEvent?=?GetProcAddress(hKernel32,?"OpenEventA");
????if(RParam.lpOpenEvent?==?NULL)
????{
????????printf("-----GetProcAddress?OpenEventA?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????
????RParam.lpOpenFileMapping?=?GetProcAddress(hKernel32,?"OpenFileMappingA");
????if(RParam.lpOpenFileMapping?==?NULL)
????{
????????printf("-----GetProcAddress?OpenFileMappingA?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????
????RParam.lpMapViewOfFile?=?GetProcAddress(hKernel32,?"MapViewOfFile");
????if(RParam.lpMapViewOfFile?==?NULL)
????{
????????printf("-----GetProcAddress?MapViewOfFile?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????RParam.lpUnMapViewOfFile?=?GetProcAddress(hKernel32,?"UnmapViewOfFile");
????if(RParam.lpUnMapViewOfFile?==?NULL)
????{
????????printf("-----GetProcAddress?UnMapViewOfFile?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????
????RParam.lpOpenMutex?=?GetProcAddress(hKernel32,?"OpenMutexA");
????if(RParam.lpOpenMutex?==?NULL)
????{
????????printf("-----GetProcAddress?OpenMutexA?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????
????RParam.lpWaitForSingleObject?=?GetProcAddress(hKernel32,?"WaitForSingleObject");
????if(RParam.lpWaitForSingleObject?==?NULL)
????{
????????printf("-----GetProcAddress?WaitForSingleObject?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????
????RParam.lpSetEvent?=?GetProcAddress(hKernel32,?"SetEvent");
????if(RParam.lpSetEvent?==?NULL)
????{
????????printf("-----GetProcAddress?SetEvent?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????
????RParam.lpReleaseMutex?=?GetProcAddress(hKernel32,?"ReleaseMutex");
????if(RParam.lpReleaseMutex?==?NULL)
????{
????????printf("-----GetProcAddress?ReleaseMutex?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????
????RParam.lpCloseHandle?=?GetProcAddress(hKernel32,?"CloseHandle");
????if(RParam.lpCloseHandle?==?NULL)
????{
????????printf("-----GetProcAddress?CloseHandle?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????RParam.lpGetProcessId?=?GetProcAddress(hKernel32,?"GetProcessId");
????if(RParam.lpGetProcessId?==?NULL)
????{
????????printf("-----GetProcAddress?GetProcessId?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????RParam.lpGetLastError?=?GetProcAddress(hKernel32,?"GetLastError");
????if(RParam.lpGetLastError?==?NULL)
????{
????????printf("-----GetProcAddress?GetLastError?from?Kernel32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hKernel32);
????????return?-1;
????}
????FreeLibrary(hKernel32);
????
????//以上皆為必須,下面可以為自己的攔截函數中所需要用的一些變量以及系統api放到參數中去
????HMODULE?hUser32?=?LoadLibrary("User32.dll");
????if(hUser32?==?NULL)
????{
????????printf("-----LoadLibrary?User32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????return?-1;
????}
????
????RParam.lpMessageBox?=?GetProcAddress(hUser32,?"MessageBoxW");
????if(RParam.lpMessageBox?==?NULL)
????{
????????printf("-----GetProcAddress?MessageBoxA?from?User32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hUser32);
????????return?-1;
????}
????RParam.lpwsprintf?=?GetProcAddress(hUser32,?"wsprintfW");
????if(RParam.lpwsprintf?==?NULL)
????{
????????printf("-----GetProcAddress?wsprintf?from?User32.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hUser32);
????????return?-1;
????}????
????FreeLibrary(hUser32);
????HMODULE?hNtdll?=?LoadLibrary("ntdll.dll");
????if(hNtdll?==?NULL)
????{
????????printf("-----LoadLibrary?ntdll.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????return?-1;
????}
????RParam.lpZwQueryObject?=?GetProcAddress(hNtdll,?"ZwQueryObject");
????if(RParam.lpwsprintf?==?NULL)
????{
????????printf("-----GetProcAddress?ZwQueryObject?from?ntdll.dll?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????FreeLibrary(hNtdll);
????????return?-1;
????}????
????FreeLibrary(hNtdll);
????
????printf("3:Generate?remoteparam?ok\n");????
????
????//下面為必須部分
????//把參數寫入要攔截的遠程進程地址空間
????if(!WriteProcessMemory(hTargetProcess,?lpParamaAddr,?(LPVOID)&RParam,?sizeof(RParam),?&dwError))
????{
????????printf("-----WriteProcessMemory?for?remoteparam?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????return?-1;
????}
????printf("4:WriteProcessMemory?for?remoteparam?ok\n");
????//把攔截函數體寫入目標進程地址空間
????if(!WriteProcessMemory(hTargetProcess,?lpFunAddr,?lpHookFunAddr,?dwHookFunSize,?&dwError))
????{
????????printf("-----WriteProcessMemory?for?remotefuction?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????return?-1;
????}
????printf("5:WriteProcessMemory?for?remotefuction?ok\n");
????//把新的跳轉指令寫入要攔截的目標進程的要攔截的api的函數的前十字節
????if(!WriteProcessMemory(hTargetProcess,?lpApiAddr?,?(LPVOID)newcode,?12,?&dwError))
????{
????????printf("-----Modify?remote?api?error..\n");
????????FreeLibrary(hExportDll);
????????VirtualFreeEx(hTargetProcess,?lpFunAddr,?0,?MEM_RELEASE);
????????VirtualFreeEx(hTargetProcess,?lpParamaAddr,?0,?MEM_RELEASE);
????????CloseHandle(hTargetProcess);
????????return?-1;
????}
????printf("6:Modify?remote?api?%s?ok\n",?lpApiName);
????//show..
????printf("---------------------------------------------------------------------------\n"
???????????"You?hava?hooked?pid:?%d?,and?the?infomation?of?this?hooking?are?as?follows:\n"
???????????"API?name:?%s\n"
???????????"API?addr:?0x%.8x\n"
???????????"API?Parm:?%d\n"
???????????"Module?name:?%s\n"
???????????"Module?addr:?0x%.8x\n"
???????????"Remote?parama?addr:?0x%.8x\n"
???????????"Remote?thread?addr:?0x%.8x\n"
???????????"RemoteParam.lpFunAddr:?0x%.8x\n"
???????????"RemoteParam.lpWriteProcessMemory:?0x%.8x\n"
???????????"RemoteParam.lpMessageBox:?0x%.8x\n"
???????????"RemoteParam.lpGetProcessHeap:?0x%.8x\n"
???????????"RemoteParam.lpHeapAlloc:?0x%.8x\n"
???????????"RemoteParam.lpHeapReAlloc:?0x%.8x\n"
???????????"RemoteParam.lpHeapFree:?0x%.8x\n"
???????????"RemoteParam.lpwsprintf:?0x%.8x\n"
???????????"RemoteParam.lpZwQueryObject:?0x%.8x\n"
???????????"RemoteParam.lpResumeThread:?0x%.8x\n"
???????????"RemoteParam.lpCreateEvent:?0x%.8x\n"
???????????"RemoteParam.lpOpenEvent:?0x%.8x\n"
???????????"RemoteParam.lpOpenFileMapping:?0x%.8x\n"
???????????"RemoteParam.lpMapViewOfFile:?0x%.8x\n"
???????????"RemoteParam.lpUnMapViewOfFile:?0x%.8x\n"
???????????"RemoteParam.lpOpenMutex:?0x%.8x\n"
???????????"RemoteParam.lpWaitForSingleObject:?0x%.8x\n"
???????????"RemoteParam.lpSetEvent:?0x%.8x\n"
???????????"RemoteParam.lpReleaseMutex:?0x%.8x\n"
???????????"RemoteParam.lpCloseHandle:?0x%.8x\n"
???????????"RemoteParam.lpGetProcessId:?0x%.8x\n"
???????????"RemoteParam.lpGetLastError:?0x%.8x\n",
???????????dwPid,
???????????lpApiName,
???????????lpApiAddr,
???????????RParam.dwParamSize,
???????????lpExportDllName,
???????????hExportDll,
???????????lpParamaAddr,
???????????lpFunAddr,
???????????RParam.lpFunAddr,
???????????RParam.lpWriteProcessMemory,
???????????RParam.lpMessageBox,
???????????RParam.lpGetProcessHeap,
???????????RParam.lpHeapAlloc,
???????????RParam.lpHeapReAlloc,
???????????RParam.lpHeapFree,
???????????RParam.lpwsprintf,
???????????RParam.lpZwQueryObject,
???????????RParam.lpResumeThread,
???????????RParam.lpCreateEvent,
???????????RParam.lpOpenEvent,
???????????RParam.lpOpenFileMapping,
???????????RParam.lpMapViewOfFile,
???????????RParam.lpUnMapViewOfFile,
???????????RParam.lpOpenMutex,
???????????RParam.lpWaitForSingleObject,
???????????RParam.lpSetEvent,
???????????RParam.lpReleaseMutex,
???????????RParam.lpCloseHandle,
???????????RParam.lpGetProcessId,
???????????RParam.lpGetLastError);
????wprintf(L"RemoteParam.wProcessName:?%s\n",?RParam.wProcessName);
????
????printf("OldCode:");
????for(int?i?=?0;?i?<?12;?i++)
????{
????????printf("0x%.2x?",?RParam.szOldCode[i]);
????}
????printf("\nNewCode:");
????for(i?=?0;?i?<?12;?i++)
????{
????????printf("0x%.2x?",?RParam.szNewCode[i]);
????}
????printf("\n");
????printf("---------------------------------------------------------------------------\n\n\n");????
????//收工,清理資源
????FreeLibrary(hExportDll);
????CloseHandle(hTargetProcess);
????return?0;
}
DWORD?dwRunning?=?1;
DWORD?WINAPI?getExit(PHANDLE?hExitEvent)
{
????char?exitCode?=?'\0';
????DWORD?dwCount?=?0;
????while(TRUE)
????{
????????printf("Input?q?to?exit?the?program...\n");
????????scanf("%c",?&exitCode);
????????if(exitCode?==?'q')
????????{
????????????dwRunning?=?0;
????????????SetEvent(*hExitEvent);
????????????break;
????????}
????}
????return?0;
}
void?showProcesses(void)
{
??size_t?blocklen?=?0;
??PSYSTEM_PROCESSES?bufForProcessesInfo?=?NULL,?bufNext?=?NULL;
????NTSTATUS?ns?=?0;
??DWORD?dwPcount?=?0;
??HANDLE?hHeap;
??int?i?=?2;
??HMODULE?hNtdll?=?LoadLibrary(TEXT("NTDLL.DLL"));
??if(hNtdll?==?NULL)
??{
????printf("LaodLibrary?ntddl.dll?error...\n");
????return;
??}
??NTQUERYSYSTEMINFORMATION?NtQuerySystemInformation?=?
????(NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll,?TEXT("NtQuerySystemInformation"));
??if(NtQuerySystemInformation?==?NULL)
??{
????printf("GetProcAddress?error...\n");
????return;
??}
??
??hHeap?=?GetProcessHeap();
??if(hHeap?==?NULL)
??{
????printf("Get?heap?error...\n");
????FreeLibrary(hNtdll);
????return;
??}
??bufForProcessesInfo?=?(PSYSTEM_PROCESSES)HeapAlloc(hHeap,?HEAP_ZERO_MEMORY,?BLOCKSIZE);
??if(bufForProcessesInfo?==?NULL)
??{
????printf("HeapAlloc?error...\n");
????FreeLibrary(hNtdll);
????return;
??}
??bufNext?=?bufForProcessesInfo;
??ns?=?NtQuerySystemInformation(NT_PROCESS_LIST,?bufForProcessesInfo,?BLOCKSIZE,?NULL);
????while(ns?==?STATUS_INFO_LEN_MISMATCH)
??{
????bufNext?=?(PSYSTEM_PROCESSES)HeapReAlloc(hHeap,?HEAP_ZERO_MEMORY,?bufNext,?BLOCKSIZE?*?i);
????if(bufForProcessesInfo?==?NULL)
????{
??????printf("Relloc?error..\n");
??????HeapFree(hHeap,?HEAP_ZERO_MEMORY,?bufForProcessesInfo);
????????????FreeLibrary(hNtdll);
??????return;
????}
????ns?=?NtQuerySystemInformation(NT_PROCESS_LIST,?bufNext,?BLOCKSIZE?*?i,?NULL);
????i++;
??}
??
??while(bufNext->NextEntryDelta?!=?0)
??{
????wprintf(L"PID:%.4d???BasePriority:%.2d???%s\n",?bufNext->ProcessId,?bufNext->BasePriority,?bufNext->ProcessName.Buffer);
????bufNext?=?(PSYSTEM_PROCESSES)((BYTE*)bufNext?+?bufNext->NextEntryDelta);
????dwPcount?++;
??}
??printf("------------------------------------------------"\
???????"\nAll?%d?processes?running...\n",?dwPcount);
??HeapFree(hHeap,?HEAP_ZERO_MEMORY,?bufForProcessesInfo);
??FreeLibrary(hNtdll);
??return;
}
int?main(void)
{
????HANDLE?hHookMainAliveEvent?=?CreateEvent(NULL,?TRUE,?TRUE,?"HookMainAliveEvent");
????if(hHookMainAliveEvent?==?NULL)
????{
????????printf("CreateEvent?hHookMainAliveEvent?error..\n");
????????return?-1;
????}
????HANDLE?hMapFileOperateMutex?=?CreateMutex(NULL,?FALSE,?"MapFileOperateMutex");
????if(hMapFileOperateMutex?==?NULL)
????{
????????printf("CreateMutex?hMapFileOperateMutex?error..\n");
????????CloseHandle(hHookMainAliveEvent);
????????return?-1;
????}
????HANDLE?hMapFileModifiedEvent?=?CreateEvent(NULL,?FALSE,?FALSE,?"MapFileModifiedEvent");
????if(hMapFileModifiedEvent?==?NULL)
????{
????????printf("CreateEvent?hMapFileModifiedEvent?error..\n");
????????CloseHandle(hHookMainAliveEvent);
????????CloseHandle(hMapFileOperateMutex);
????????return?-1;
????}
????HANDLE?hHookNewProcessDoneEvent?=?CreateEvent(NULL,?FALSE,?FALSE,?"HookNewProcessDoneEvent");
????if(hHookNewProcessDoneEvent?==?NULL)
????{
????????printf("CreateEvent?hHookNewProcessDoneEvent?error..\n");
????????CloseHandle(hHookMainAliveEvent);
????????CloseHandle(hMapFileOperateMutex);
????????CloseHandle(hMapFileModifiedEvent);
????????return?-1;
????}
????HANDLE?hMapFileToNewProcessId?=?CreateFileMapping(
????????(HANDLE)0xFFFFFFFF,
????????NULL,
????????PAGE_READWRITE,
????????0,
????????4,
????????"MapFileToNewProcessId");
????if(hMapFileToNewProcessId?==?NULL)
????{
????????printf("CreateFileMapping?NewCreatedProcessId?error..\n");
????????CloseHandle(hHookMainAliveEvent);
????????CloseHandle(hMapFileOperateMutex);
????????CloseHandle(hMapFileModifiedEvent);
????????CloseHandle(hHookNewProcessDoneEvent);
????????return?-1;
????}
????LPVOID?lpMapFileToNewProcessId?=?MapViewOfFile(hMapFileToNewProcessId,?FILE_MAP_READ,?0,?0,?0);
????if(lpMapFileToNewProcessId?==?NULL)
????{
????????printf("MapViewOfFile?NewCreatedProcessId?error..\n");
????????CloseHandle(hMapFileToNewProcessId);
????????CloseHandle(hHookMainAliveEvent);
????????CloseHandle(hMapFileOperateMutex);
????????CloseHandle(hMapFileModifiedEvent);
????????CloseHandle(hHookNewProcessDoneEvent);
????????return?-1;
????}
????
????DWORD?*?Ppid?=?(PDWORD)lpMapFileToNewProcessId;
????//在這里填入想要監控的進程id,稍作修改,可以監控所有進程,程序沒有作好,請原諒.
????//這里還是覺得就這樣,大家如果有興趣可以在自己的機器上測試,因為做到現在,忽然發現似乎功能的
????//真正實現不是那么重要了。
??DWORD?dwPid?=?0;
??wchar_t?wName[32]?=?{'\0'};
??showProcesses();
??printf("輸入想要監視的進程ID:");
??scanf("%d",?&dwPid);
??wsprintfW(wName,?L"PID:%d\0",?dwPid);
????SetHook(dwPid,?wName,?"ZwCreateProcessEx",?"ntdll.dll",?9,?4096?*?10,??&HookZwCreateProcessEx);
????SetHook(dwPid,?wName,?"ZwSetValueKey",?"ntdll.dll",?6,?4096?*?5,?&HookZwSetValueKey);
?
????DWORD?dwExitThread?=?0;
????HANDLE?hExitThread?=?CreateThread(NULL,?0,?(LPTHREAD_START_ROUTINE)&getExit,?&hMapFileModifiedEvent,?0,?&dwExitThread);
????
????while(dwRunning?==?1)
????{
????????WaitForSingleObject(hMapFileModifiedEvent,?INFINITE);
????????if(dwRunning?==?0)
????????????break;
????????DWORD?dwPid?=?*?Ppid;
????????//這里的傳遞的進程名字只是用來測試用,可以編程實現獲取進程名,并傳遞,注意這里為寬字符,
????????//抱歉本人沒有完成這里的自動獲取進程名字功能,寫這個代碼已經太煩躁了,請原諒.
????memset(wName,?0,?32?*?sizeof(wchar_t));
????????wsprintfW(wName,?L"PID:%d\0",?dwPid);
????????SetHook(dwPid,?wName,?"ZwCreateProcessEx",?"ntdll.dll",?9,?4096?*?10,??&HookZwCreateProcessEx);
????????SetHook(dwPid,?wName,?"ZwSetValueKey",?"ntdll.dll",?6,?4096?*?5,?&HookZwSetValueKey);
????????SetEvent(hHookNewProcessDoneEvent);
????}
????
????UnmapViewOfFile(lpMapFileToNewProcessId);
????CloseHandle(hMapFileToNewProcessId);
????CloseHandle(hHookMainAliveEvent);
????CloseHandle(hMapFileOperateMutex);
????CloseHandle(hMapFileModifiedEvent);
????CloseHandle(hHookNewProcessDoneEvent);
????CloseHandle(hExitThread);
????return?0;
}