ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

逆向工程核心原理——第三十四章

2020-10-16 16:00:44  阅读:509  来源: 互联网

标签:逆向 GetLastError return FALSE failed DebugLog 原理 NULL 第三十四章


高级全局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\n", 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\n", 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\n", GetLastError());
        return FALSE;
    }

    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
    {
        _tprintf(L"The token does not have the specified privilege. \n");
        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]\n",
                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]\n",
                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]\n",
                GetLastError());
            return FALSE;
        }
    }

    if (WAIT_FAILED == WaitForSingleObject(hThread, INFINITE))
    {
        _tprintf(L"MyCreateRemoteThread() : WaitForSingleObject() failed!!! [%d]\n",
            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]\n",
            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]\n",
            dwPID, GetLastError());
        goto INJECTDLL_EXIT;
    }

    pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,
        MEM_COMMIT, PAGE_READWRITE);
    if (pRemoteBuf == NULL)
    {
        _tprintf(L"InjectDll() : VirtualAllocEx() failed!!! [%d]\n",
            GetLastError());
        goto INJECTDLL_EXIT;
    }

    if (!WriteProcessMemory(hProcess, pRemoteBuf,
        (LPVOID)szDllPath, dwBufSize, NULL))
    {
        _tprintf(L"InjectDll() : WriteProcessMemory() failed!!! [%d]\n",
            GetLastError());
        goto INJECTDLL_EXIT;
    }

    hMod = GetModuleHandle(L"kernel32.dll");
    if (hMod == NULL)
    {
        _tprintf(L"InjectDll() : GetModuleHandle(\"kernel32.dll\") failed!!! [%d]\n",
            GetLastError());
        goto INJECTDLL_EXIT;
    }

    pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
    if (pThreadProc == NULL)
    {
        _tprintf(L"InjectDll() : GetProcAddress(\"LoadLibraryW\") failed!!! [%d]\n",
            GetLastError());
        goto INJECTDLL_EXIT;
    }

    if (!MyCreateRemoteThread(hProcess, pThreadProc, pRemoteBuf))
    {
        _tprintf(L"InjectDll() : MyCreateRemoteThread() failed!!!\n");
        goto INJECTDLL_EXIT;
    }

    bRet = CheckDllInProcess(dwPID, szDllPath);

INJECTDLL_EXIT:

    wsprintf(szProcName, L"%s", GetProcName(dwPID));
    if (szProcName[0] == '\0')
        _tcscpy_s(szProcName, L"(no_process)");

    _tprintf(L"%s(%d) %s!!! [%d]\n", 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]\n",
            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!!!\n",
            szDllPath, dwPID);
        goto EJECTDLL_EXIT;
    }

    dwDesiredAccess = PROCESS_ALL_ACCESS;
    if (!(hProcess = OpenProcess(dwDesiredAccess, FALSE, dwPID)))
    {
        _tprintf(L"EjectDll() : OpenProcess(%d) failed!!! [%d]\n",
            dwPID, GetLastError());
        goto EJECTDLL_EXIT;
    }

    hMod = GetModuleHandle(L"kernel32.dll");
    if (hMod == NULL)
    {
        _tprintf(L"EjectDll() : GetModuleHandle(\"kernel32.dll\") failed!!! [%d]\n",
            GetLastError());
        goto EJECTDLL_EXIT;
    }

    pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "FreeLibrary");
    if (pThreadProc == NULL)
    {
        _tprintf(L"EjectDll() : GetProcAddress(\"FreeLibrary\") failed!!! [%d]\n",
            GetLastError());
        goto EJECTDLL_EXIT;
    }

    if (!MyCreateRemoteThread(hProcess, pThreadProc, me.modBaseAddr))
    {
        _tprintf(L"EjectDll() : MyCreateRemoteThread() failed!!!\n");
        goto EJECTDLL_EXIT;
    }

    bRet = TRUE;

EJECTDLL_EXIT:

    _tcscpy_s(szProcName, GetProcName(dwPID));
    _tprintf(L"%s(%d) %s!!! [%d]\n", 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!\n",
                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"\n %s (Ver 1.1.1) - Dll Injection/Ejection Utility!!!\n"\
            L"   www.reversecore.com\n"\
            L"   reversecore@gmail.com\n"\
            L"\n USAGE  : %s <procname|pid|*> <-i|-e> <dll path>\n\n",
            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!\n", 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\n", GetLastError());
        return FALSE;
    }

    if (!LookupPrivilegeValue(NULL,             // lookup privilege on local system  
        lpszPrivilege,    // privilege to lookup   
        &luid))          // receives LUID of privilege  
    {
        DebugLog("LookupPrivilegeValue error: %u\n", 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\n", GetLastError());
        return FALSE;
    }

    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
    {
        DebugLog("The token does not have the specified privilege. \n");
        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]\n",
            szDllName, GetLastError());
        return FALSE;
    }

    pFunc = (FARPROC)GetProcAddress(hMod, szFuncName);
    if (pFunc == NULL)
    {
        DebugLog("hook_by_code() : GetProcAddress(\"%s\") failed!!! [%d]\n",
            szFuncName, GetLastError());
        return FALSE;
    }

    pByte = (PBYTE)pFunc;
    if (pByte[0] == 0xE9)
    {
        DebugLog("hook_by_code() : The API is hooked already!!!\n");
        return FALSE;
    }

    if (!VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect))
    {
        DebugLog("hook_by_code() : VirtualProtect(#1) failed!!! [%d]\n", 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]\n", 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]\n",
            szDllName, GetLastError());
        return FALSE;
    }

    pFunc = (FARPROC)GetProcAddress(hMod, szFuncName);
    if (pFunc == NULL)
    {
        DebugLog("unhook_by_code() : GetProcAddress(\"%s\") failed!!! [%d]\n",
            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]\n", GetLastError());
        return FALSE;
    }

    memcpy(pFunc, pOrgBytes, 5);

    if (!VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect))
    {
        DebugLog("unhook_by_code() : VirtualProtect(#2) failed!!! [%d]\n", 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]\n",
                GetLastError());
            return FALSE;
        }

        ((PFNTCREATETHREADEX)pFunc)(&hThread,
            0x1FFFFF,
            NULL,
            hProcess,
            pThreadProc,
            pRemoteBuf,
            FALSE,
            NULL,
            NULL,
            NULL,
            NULL);
        if (hThread == NULL)
        {
            DebugLog("MyCreateRemoteThread() : NtCreateThreadEx() failed!!! [%d]\n", GetLastError());
            return FALSE;
        }
    }
    else                    // 2000, XP, Server2003  
    {
        hThread = CreateRemoteThread(hProcess, NULL, 0,
            pThreadProc, pRemoteBuf, 0, NULL);
        if (hThread == NULL)
        {
            DebugLog("MyCreateRemoteThread() : CreateRemoteThread() failed!!! [%d]\n", GetLastError());
            return FALSE;
        }
    }

    if (WAIT_FAILED == WaitForSingleObject(hThread, INFINITE))
    {
        DebugLog("MyCreateRemoteThread() : WaitForSingleObject() failed!!! [%d]\n", 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]\n", dwPID, GetLastError());
        goto INJECTDLL_EXIT;
    }

    pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,
        MEM_COMMIT, PAGE_READWRITE);
    if (pRemoteBuf == NULL)
    {
        DebugLog("InjectDll() : VirtualAllocEx() failed!!! [%d]\n", GetLastError());
        goto INJECTDLL_EXIT;
    }

    if (!WriteProcessMemory(hProcess, pRemoteBuf,
        (LPVOID)szDllPath, dwBufSize, NULL))
    {
        DebugLog("InjectDll() : WriteProcessMemory() failed!!! [%d]\n", GetLastError());
        goto INJECTDLL_EXIT;
    }

    hMod = GetModuleHandle(L"kernel32.dll");
    if (hMod == NULL)
    {
        DebugLog("InjectDll() : GetModuleHandle() failed!!! [%d]\n", GetLastError());
        goto INJECTDLL_EXIT;
    }

    pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
    if (pThreadProc == NULL)
    {
        DebugLog("InjectDll() : GetProcAddress() failed!!! [%d]\n", GetLastError());
        goto INJECTDLL_EXIT;
    }

    if (!MyCreateRemoteThread(hProcess, pThreadProc, pRemoteBuf))
    {
        DebugLog("InjectDll() : MyCreateRemoteThread() failed!!!\n");
        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!!!\n");

    hMod = GetModuleHandle(L"ntdll.dll");
    if (hMod == NULL)
    {
        DebugLog("NewZwResumeThread() : GetModuleHandle() failed!!! [%d]\n",
            GetLastError());
        return NULL;
    }

    // call ntdll!ZwQueryInformationThread()  
    pFuncThread = GetProcAddress(hMod, "ZwQueryInformationThread");
    if (pFuncThread == NULL)
    {
        DebugLog("NewZwResumeThread() : GetProcAddress() failed!!! [%d]\n",
            GetLastError());
        return NULL;
    }

    statusThread = ((PFZWQUERYINFORMATIONTHREAD)pFuncThread)
        (ThreadHandle, 0, &tbi, sizeof(tbi), NULL);
    if (statusThread != STATUS_SUCCESS)
    {
        DebugLog("NewZwResumeThread() : pFuncThread() failed!!! [%d]\n",
            GetLastError());
        return NULL;
    }

    dwPID = (DWORD)tbi.ClientId.UniqueProcess;
    if ((dwPID != GetCurrentProcessId()) && (dwPID != dwPrevPID))
    {
        DebugLog("NewZwResumeThread() => call InjectDll()\n");

        dwPrevPID = dwPID;

        // change privilege  
        if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
            DebugLog("NewZwResumeThread() : SetPrivilege() failed!!!\n");

        // get injection dll path  
        GetModuleFileName(GetModuleHandle(STR_MODULE_NAME),
            szModPath,
            MAX_PATH);

        if (!InjectDll(dwPID, szModPath))
            DebugLog("NewZwResumeThread() : InjectDll(%d) failed!!!\n", dwPID);
    }

    // call ntdll!ZwResumeThread()  
    if (!unhook_by_code("ntdll.dll", "ZwResumeThread", g_pZWRT))
    {
        DebugLog("NewZwResumeThread() : unhook_by_code() failed!!!\n");
        return NULL;
    }

    pFunc = GetProcAddress(hMod, "ZwResumeThread");
    if (pFunc == NULL)
    {
        DebugLog("NewZwResumeThread() : GetProcAddress() failed!!! [%d]\n",
            GetLastError());
        goto __NTRESUMETHREAD_END;
    }

    status = ((PFZWRESUMETHREAD)pFunc)(ThreadHandle, SuspendCount);
    if (status != STATUS_SUCCESS)
    {
        DebugLog("NewZwResumeThread() : pFunc() failed!!! [%d]\n", GetLastError());
        goto __NTRESUMETHREAD_END;
    }

__NTRESUMETHREAD_END:

    if (!hook_by_code("ntdll.dll", "ZwResumeThread",
        (PROC)NewZwResumeThread, g_pZWRT))
    {
        DebugLog("NewZwResumeThread() : hook_by_code() failed!!!\n");
    }

    DebugLog("NewZwResumeThread() : end!!!\n");

    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!!!\n");
        return NULL;
    }

    // call original API  
    hMod = GetModuleHandle(L"wininet.dll");
    if (hMod == NULL)
    {
        DebugLog("NewInternetConnectW() : GetModuleHandle() failed!!! [%d]\n",
            GetLastError());
        goto __INTERNETCONNECT_EXIT;
    }

    pFunc = GetProcAddress(hMod, "InternetConnectW");
    if (pFunc == NULL)
    {
        DebugLog("NewInternetConnectW() : GetProcAddress() failed!!! [%d]\n",
            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\n");
        hInt = ((PFINTERNETCONNECTW)pFunc)(hInternet,
            L"www.reversecore.com",
            nServerPort,
            lpszUsername,
            lpszPassword,
            dwService,
            dwFlags,
            dwContext);
    }
    else
    {
        DebugLog("[no redirect]\n");
        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!!!\n");
    }

    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\n");

        GetModuleFileNameA(NULL, szCurProc, MAX_PATH);
        p = strrchr(szCurProc, '\\');
        if ((p != NULL) && !_stricmp(p + 1, "iexplore.exe"))
        {
            DebugLog("DllMain() : current process is [iexplore.exe]\n");

            // 钩取wininet!InternetConnectW() API之前  
            // 预先加载wininet.dll  
            if (NULL == LoadLibrary(L"wininet.dll"))
            {
                DebugLog("DllMain() : LoadLibrary() failed!!! [%d]\n",
                    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\n");

        // unhook  
        unhook_by_code("ntdll.dll", "ZwResumeThread",
            g_pZWRT);
        unhook_by_code("wininet.dll", "InternetConnectW",
            g_pICW);
        break;
    }

    return TRUE;
}

标签:逆向,GetLastError,return,FALSE,failed,DebugLog,原理,NULL,第三十四章
来源: https://www.cnblogs.com/lex-shoukaku/p/13826958.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有