請問如果要實時監視註冊表的改動,有哪些方法?
如果用API鈎子,是不是要鈎住所有與註冊表有關的API呢?
還有修改註冊表一定會調用到WIN32的API函數嗎?regedit註冊表編輯器裏修改會不會調用API函數

解决方案 »

  1.   

    建议使用驱动,可以参考RegMon的源码。
      

  2.   

    卡巴6就有注册表监控的功能 ,它的做法就是驱动中挂接了注册表操作函数(SSDT中)
    修改注册表一定会用到API函数,也包括注册表编辑器
      

  3.   

    能詳細說一下用驅動來挂接註冊表函數嗎
    如果使用DLL注入來挂接全局的系統消息鈎子
    那RegSetValue()和RegSetValueEX()等函數是不是要全部都替換成自己的函數
      

  4.   

    关于api hook可以查询关于detours方面的资料,微软的网站有detours库下载
      

  5.   

    监视注册表还要用hook?
    用它RegNotifyChangeKeyValue不行吗?
      

  6.   

    偶是在用户模式下hook了ZwSetValueKey.
    需要遍历所有进程,然后还要挂钩ZwCreateProcessEx以便对新创建的进程监视。具体见:
    http://redcoder.blog.sohu.com/14217977.html//////////////////////////////////////////////////////////////////////////
    //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
        }
    }