Winxp下拦截所有进程的写注册表操作以及进程创建的监控

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/winnuke/archive/2007/03/19/1534122.aspx

 

原理介绍:

 

  Nt系统下用户层(Ring3)下写注册表的程序大都调用ntdll.dll导出的ZwSetValueKey,该API简单通过int 2e并传递一个服务号进入内核调用同名系统服务(NTSetValueKey)。所以在用户层(Ring3)下拦截写注册表的操作最后的也是最底层的方法便是拦截该API。

 

  同时为了实时监控系统中当前运行的所有进程对该API的直接或者间接调用,需要对所有进程进行代码注入。对于新创建的进程,Xp系统下用户层最后一道入口是ZwCreateProcessEx,他也是由ntdll.dll导出。在枚举出系统中所有进程之后,便可以通过对该API的拦截第一时间对新创建的进程进行拦截。需要补充说明的是在用户层创建进程执行到这个API时,进程空间已经创建,且仅仅加载了ntdll.dll模块以及进程自身的映象。这时可以通过修改ntdll.dll中该API的入口实现对其创建的子进程拦截。

 

  关于 API拦截的具体原理分析和简单实现,前面的文章已经说得很清楚了。这里只是给出大体流程图和代码。

 

测试方法:

 

  程序运行后,输入你想要监视的进程ID,这时该进程,以及该进程所创建的任何进程都将被监视,并且在其修改注册表的时候弹出对话框询问是否允许进行该次注册表修改操作,点'y'允许操作,否则拒绝操作. (刚刚修改了一下,可以查看进程id和名称,同时从控制台接受进程id的输入,从而对指定的进程监控)

 

流程图:

 

流程图

源代码:

 

#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;

    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;

}

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值