逆向工程核心原理读书笔记-API钩取之IE浏览器连接控制

来源:互联网 发布:部分图片来源于网络 编辑:程序博客网 时间:2024/06/01 07:59

我们通过一个示例来练习钩取IE8的InternetConnect函数,用IE8连接指定网站时,使之连接到另一个网站。和以前钩取CreateProcess不同,这次我们钩取更低级的ZwResumeThread来实现全局API钩取。


我们来分析一下源代码,看看是怎么实现的。
InjDll.cpp源代码与DLL注入的代码基本结构类似。

[cpp] view plain copy
  1. // InjDll.cpp  
  2. // reversecore@gmail.com  
  3. // www.reversecore.com  
  4.   
  5. #include "windows.h"  
  6. #include "stdio.h"  
  7. #include "tlhelp32.h"  
  8. #include "io.h"  
  9. #include "tchar.h"  
  10.   
  11. enum {INJECTION_MODE = 0, EJECTION_MODE};  
  12.   
  13. BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)   
  14. {  
  15.     TOKEN_PRIVILEGES tp;  
  16.     HANDLE hToken;  
  17.     LUID luid;  
  18.   
  19.     if( !OpenProcessToken(GetCurrentProcess(),  
  20.                           TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,   
  21.                           &hToken) )  
  22.     {  
  23.         _tprintf(L"OpenProcessToken error: %u\n", GetLastError());  
  24.         return FALSE;  
  25.     }  
  26.   
  27.     if( !LookupPrivilegeValue(NULL,           // lookup privilege on local system  
  28.                               lpszPrivilege,  // privilege to lookup   
  29.                               &luid) )        // receives LUID of privilege  
  30.     {  
  31.         _tprintf(L"LookupPrivilegeValue error: %u\n", GetLastError() );   
  32.         return FALSE;   
  33.     }  
  34.   
  35.     tp.PrivilegeCount = 1;  
  36.     tp.Privileges[0].Luid = luid;  
  37.     if( bEnablePrivilege )  
  38.         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
  39.     else  
  40.         tp.Privileges[0].Attributes = 0;  
  41.   
  42.     // Enable the privilege or disable all privileges.  
  43.     if( !AdjustTokenPrivileges(hToken,   
  44.                                FALSE,   
  45.                                &tp,   
  46.                                sizeof(TOKEN_PRIVILEGES),   
  47.                                (PTOKEN_PRIVILEGES) NULL,   
  48.                                (PDWORD) NULL) )  
  49.     {   
  50.         _tprintf(L"AdjustTokenPrivileges error: %u\n", GetLastError() );   
  51.         return FALSE;   
  52.     }   
  53.   
  54.     if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )  
  55.     {  
  56.         _tprintf(L"The token does not have the specified privilege. \n");  
  57.         return FALSE;  
  58.     }   
  59.   
  60.     return TRUE;  
  61. }  
  62.   
  63. BOOL IsVistaLater()  
  64. {  
  65.     OSVERSIONINFO osvi;  
  66.   
  67.     ZeroMemory(&osvi, sizeof(OSVERSIONINFO));  
  68.     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);  
  69.   
  70.     GetVersionEx(&osvi);  
  71.   
  72.     if( osvi.dwMajorVersion >= 6 )  
  73.         return TRUE;  
  74.   
  75.     return FALSE;  
  76. }  
  77.   
  78. typedef DWORD (WINAPI *PFNTCREATETHREADEX)  
  79. (   
  80.     PHANDLE                 ThreadHandle,     
  81.     ACCESS_MASK             DesiredAccess,    
  82.     LPVOID                  ObjectAttributes,     
  83.     HANDLE                  ProcessHandle,    
  84.     LPTHREAD_START_ROUTINE  lpStartAddress,   
  85.     LPVOID                  lpParameter,      
  86.     BOOL                    CreateSuspended,      
  87.     DWORD                   dwStackSize,      
  88.     DWORD                   dw1,   
  89.     DWORD                   dw2,   
  90.     LPVOID                  Unknown   
  91. );   
  92.   
  93. BOOL MyCreateRemoteThread  
  94. (  
  95.     HANDLE hProcess,   
  96.     LPTHREAD_START_ROUTINE pThreadProc,   
  97.     LPVOID pRemoteBuf  
  98. )  
  99. {  
  100.     HANDLE      hThread = NULL;  
  101.     FARPROC     pFunc = NULL;  
  102.   
  103.     if( IsVistaLater() )    // Vista, 7, Server2008  
  104.     {  
  105.         pFunc = GetProcAddress(GetModuleHandle(L"ntdll.dll"),   
  106.                                "NtCreateThreadEx");  
  107.         if( pFunc == NULL )  
  108.         {  
  109.             _tprintf(L"MyCreateRemoteThread() : "\  
  110.                      L"GetProcAddress(\"NtCreateThreadEx\") failed!!! [%d]\n",  
  111.                       GetLastError());  
  112.             return FALSE;  
  113.         }  
  114.   
  115.         ((PFNTCREATETHREADEX)pFunc)(&hThread,  
  116.                                     0x1FFFFF,  
  117.                                     NULL,  
  118.                                     hProcess,  
  119.                                     pThreadProc,  
  120.                                     pRemoteBuf,  
  121.                                     FALSE,  
  122.                                     NULL,  
  123.                                     NULL,  
  124.                                     NULL,  
  125.                                     NULL);  
  126.         if( hThread == NULL )  
  127.         {  
  128.             _tprintf(L"MyCreateRemoteThread() : NtCreateThreadEx() failed!!! [%d]\n",   
  129.                       GetLastError());  
  130.             return FALSE;  
  131.         }  
  132.     }  
  133.     else                    // 2000, XP, Server2003  
  134.     {  
  135.         hThread = CreateRemoteThread(hProcess, NULL, 0,   
  136.                                      pThreadProc, pRemoteBuf, 0, NULL);  
  137.         if( hThread == NULL )  
  138.         {  
  139.             _tprintf(L"MyCreateRemoteThread() : CreateRemoteThread() failed!!! [%d]\n",   
  140.                      GetLastError());  
  141.             return FALSE;  
  142.         }  
  143.     }  
  144.   
  145.     if( WAIT_FAILED == WaitForSingleObject(hThread, INFINITE) )  
  146.     {  
  147.         _tprintf(L"MyCreateRemoteThread() : WaitForSingleObject() failed!!! [%d]\n",   
  148.                  GetLastError());  
  149.         return FALSE;  
  150.     }  
  151.   
  152.     return TRUE;  
  153. }  
  154.   
  155. LPCTSTR GetProcName(DWORD dwPID)  
  156. {  
  157.     HANDLE                  hSnapshot = INVALID_HANDLE_VALUE;  
  158.     PROCESSENTRY32          pe;  
  159.     BOOL                    bMore = FALSE;  
  160.   
  161.     // Get the snapshot of the system  
  162.     pe.dwSize = sizeof(PROCESSENTRY32);  
  163.     hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);  
  164.     if( hSnapshot == INVALID_HANDLE_VALUE )  
  165.     {  
  166.         _tprintf(L"GetProcName() : CreateToolhelp32Snapshot() failed!!! [%d]",   
  167.                   GetLastError());  
  168.         return NULL;  
  169.     }  
  170.   
  171.     // find process  
  172.     bMore = Process32First(hSnapshot, &pe);  
  173.     for( ; bMore; bMore = Process32Next(hSnapshot, &pe) )  
  174.     {  
  175.         if( dwPID == pe.th32ProcessID )  
  176.         {  
  177.             CloseHandle(hSnapshot);  
  178.             return pe.szExeFile;  
  179.         }  
  180.     }  
  181.   
  182.     CloseHandle(hSnapshot);  
  183.   
  184.     return NULL;  
  185. }  
  186.   
  187. BOOL CheckDllInProcess(DWORD dwPID, LPCTSTR szDllPath)  
  188. {  
  189.     BOOL                    bMore = FALSE;  
  190.     HANDLE                  hSnapshot = INVALID_HANDLE_VALUE;  
  191.     MODULEENTRY32           me = { sizeof(me), };  
  192.   
  193.     if( INVALID_HANDLE_VALUE ==   
  194.         (hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID)) )  
  195.     {  
  196.         _tprintf(L"CheckDllInProcess() : CreateToolhelp32Snapshot(%d) failed!!! [%d]\n",  
  197.                   dwPID, GetLastError());  
  198.         return FALSE;  
  199.     }  
  200.   
  201.     bMore = Module32First(hSnapshot, &me);  
  202.     for( ; bMore ; bMore = Module32Next(hSnapshot, &me) )  
  203.     {  
  204.         if( !_tcsicmp(me.szModule, szDllPath) ||   
  205.             !_tcsicmp(me.szExePath, szDllPath) )  
  206.         {  
  207.             CloseHandle(hSnapshot);  
  208.             return TRUE;  
  209.         }  
  210.     }  
  211.   
  212.     CloseHandle(hSnapshot);  
  213.     return FALSE;  
  214. }  
  215.   
  216. BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)  
  217. {  
  218.     HANDLE                  hProcess = NULL;  
  219.     HANDLE                  hThread = NULL;  
  220.     LPVOID                  pRemoteBuf = NULL;  
  221.     DWORD                   dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);  
  222.     LPTHREAD_START_ROUTINE  pThreadProc = NULL;  
  223.     BOOL                    bRet = FALSE;  
  224.     HMODULE                 hMod = NULL;  
  225.     DWORD                   dwDesiredAccess = 0;  
  226.     TCHAR                   szProcName[MAX_PATH] = {0,};  
  227.   
  228.     dwDesiredAccess = PROCESS_ALL_ACCESS;  
  229.     //dwDesiredAccess = MAXIMUM_ALLOWED;  
  230.     if ( !(hProcess = OpenProcess(dwDesiredAccess, FALSE, dwPID)) )  
  231.     {  
  232.         _tprintf(L"InjectDll() : OpenProcess(%d) failed!!! [%d]\n",   
  233.                   dwPID, GetLastError());  
  234.         goto INJECTDLL_EXIT;  
  235.     }  
  236.   
  237.     pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,   
  238.                                 MEM_COMMIT, PAGE_READWRITE);  
  239.     if( pRemoteBuf == NULL )  
  240.     {  
  241.         _tprintf(L"InjectDll() : VirtualAllocEx() failed!!! [%d]\n",   
  242.                   GetLastError());  
  243.         goto INJECTDLL_EXIT;  
  244.     }  
  245.   
  246.     if( !WriteProcessMemory(hProcess, pRemoteBuf,   
  247.                            (LPVOID)szDllPath, dwBufSize, NULL) )  
  248.     {  
  249.         _tprintf(L"InjectDll() : WriteProcessMemory() failed!!! [%d]\n",  
  250.                   GetLastError());  
  251.         goto INJECTDLL_EXIT;  
  252.     }  
  253.   
  254.     hMod = GetModuleHandle(L"kernel32.dll");  
  255.     if( hMod == NULL )  
  256.     {  
  257.         _tprintf(L"InjectDll() : GetModuleHandle(\"kernel32.dll\") failed!!! [%d]\n",  
  258.                   GetLastError());  
  259.         goto INJECTDLL_EXIT;  
  260.     }  
  261.   
  262.     pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");  
  263.     if( pThreadProc == NULL )  
  264.     {  
  265.         _tprintf(L"InjectDll() : GetProcAddress(\"LoadLibraryW\") failed!!! [%d]\n",   
  266.                   GetLastError());  
  267.         goto INJECTDLL_EXIT;  
  268.     }  
  269.   
  270.     if( !MyCreateRemoteThread(hProcess, pThreadProc, pRemoteBuf) )  
  271.     {  
  272.         _tprintf(L"InjectDll() : MyCreateRemoteThread() failed!!!\n");  
  273.         goto INJECTDLL_EXIT;  
  274.     }  
  275.   
  276.     bRet = CheckDllInProcess(dwPID, szDllPath);  
  277.   
  278. INJECTDLL_EXIT:  
  279.   
  280.     wsprintf(szProcName, L"%s", GetProcName(dwPID));  
  281.     if( szProcName[0] == '\0' )  
  282.         _tcscpy_s(szProcName, L"(no_process)");  
  283.   
  284.     _tprintf(L"%s(%d) %s!!! [%d]\n", szProcName, dwPID, bRet ? L"SUCCESS" : L"-->> FAILURE", GetLastError());  
  285.   
  286.     if( pRemoteBuf )  
  287.         VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);  
  288.   
  289.     if( hThread )  
  290.         CloseHandle(hThread);  
  291.   
  292.     if( hProcess )  
  293.         CloseHandle(hProcess);  
  294.   
  295.     return bRet;  
  296. }  
  297.   
  298. BOOL EjectDll(DWORD dwPID, LPCTSTR szDllPath)  
  299. {  
  300.     BOOL                    bMore = FALSE, bFound = FALSE, bRet = FALSE;  
  301.     HANDLE                  hSnapshot = INVALID_HANDLE_VALUE;  
  302.     HANDLE                  hProcess = NULL;  
  303.     HANDLE                  hThread = NULL;  
  304.     MODULEENTRY32           me = { sizeof(me), };  
  305.     LPTHREAD_START_ROUTINE  pThreadProc = NULL;  
  306.     HMODULE                 hMod = NULL;  
  307.     DWORD                   dwDesiredAccess = 0;  
  308.     TCHAR                   szProcName[MAX_PATH] = {0,};  
  309.   
  310.     if( INVALID_HANDLE_VALUE ==   
  311.         (hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID)) )  
  312.     {  
  313.         _tprintf(L"EjectDll() : CreateToolhelp32Snapshot(%d) failed!!! [%d]\n",  
  314.                   dwPID, GetLastError());  
  315.         goto EJECTDLL_EXIT;  
  316.     }  
  317.   
  318.     bMore = Module32First(hSnapshot, &me);  
  319.     for( ; bMore ; bMore = Module32Next(hSnapshot, &me) )  
  320.     {  
  321.         if( !_tcsicmp(me.szModule, szDllPath) ||   
  322.             !_tcsicmp(me.szExePath, szDllPath) )  
  323.         {  
  324.             bFound = TRUE;  
  325.             break;  
  326.         }  
  327.     }  
  328.   
  329.     if( !bFound )  
  330.     {  
  331.         _tprintf(L"EjectDll() : There is not %s module in process(%d) memory!!!\n",   
  332.                   szDllPath, dwPID);  
  333.         goto EJECTDLL_EXIT;  
  334.     }  
  335.   
  336.     dwDesiredAccess = PROCESS_ALL_ACCESS;  
  337.     if( !(hProcess = OpenProcess(dwDesiredAccess, FALSE, dwPID)) )  
  338.     {  
  339.         _tprintf(L"EjectDll() : OpenProcess(%d) failed!!! [%d]\n",   
  340.                   dwPID, GetLastError());  
  341.         goto EJECTDLL_EXIT;  
  342.     }  
  343.   
  344.     hMod = GetModuleHandle(L"kernel32.dll");  
  345.     if( hMod == NULL )  
  346.     {  
  347.         _tprintf(L"EjectDll() : GetModuleHandle(\"kernel32.dll\") failed!!! [%d]\n",   
  348.                   GetLastError());  
  349.         goto EJECTDLL_EXIT;  
  350.     }  
  351.   
  352.     pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "FreeLibrary");  
  353.     if( pThreadProc == NULL )  
  354.     {  
  355.         _tprintf(L"EjectDll() : GetProcAddress(\"FreeLibrary\") failed!!! [%d]\n",   
  356.                   GetLastError());  
  357.         goto EJECTDLL_EXIT;  
  358.     }  
  359.   
  360.     if( !MyCreateRemoteThread(hProcess, pThreadProc, me.modBaseAddr) )  
  361.     {  
  362.         _tprintf(L"EjectDll() : MyCreateRemoteThread() failed!!!\n");  
  363.         goto EJECTDLL_EXIT;  
  364.     }  
  365.   
  366.     bRet = TRUE;  
  367.   
  368. EJECTDLL_EXIT:  
  369.   
  370.     _tcscpy_s(szProcName, GetProcName(dwPID));  
  371.     _tprintf(L"%s(%d) %s!!! [%d]\n", szProcName, dwPID, bRet ? L"SUCCESS" : L"-->> FAILURE", GetLastError());  
  372.   
  373.     if( hThread )  
  374.         CloseHandle(hThread);  
  375.   
  376.     if( hProcess )  
  377.         CloseHandle(hProcess);  
  378.   
  379.     if( hSnapshot != INVALID_HANDLE_VALUE )  
  380.         CloseHandle(hSnapshot);  
  381.   
  382.     return bRet;  
  383. }  
  384.   
  385. BOOL InjectDllToAll(int nMode, LPCTSTR szDllPath)  
  386. {  
  387.     DWORD                   dwPID = 0;  
  388.     HANDLE                  hSnapShot = INVALID_HANDLE_VALUE;  
  389.     PROCESSENTRY32          pe;  
  390.     BOOL                    bMore = FALSE;  
  391.   
  392.     // Get the snapshot of the system  
  393.     pe.dwSize = sizeof(PROCESSENTRY32);  
  394.     hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);  
  395.     if( hSnapShot == INVALID_HANDLE_VALUE )  
  396.     {  
  397.         _tprintf(L"InjectDllToAll() : CreateToolhelp32Snapshot() failed!!! [%d]",   
  398.                   GetLastError());  
  399.         return FALSE;  
  400.     }  
  401.   
  402.     // find process  
  403.     bMore = Process32First(hSnapShot, &pe);  
  404.     for( ; bMore; bMore = Process32Next(hSnapShot, &pe) )  
  405.     {  
  406.         dwPID = pe.th32ProcessID;  
  407.   
  408.         if( dwPID < 100 ||  
  409.             !_tcsicmp(pe.szExeFile, L"smss.exe") ||  
  410.             !_tcsicmp(pe.szExeFile, L"csrss.exe") )  
  411.         {  
  412.             _tprintf(L"%s(%d) => System Process... DLL %s is impossible!\n",   
  413.                    pe.szExeFile, dwPID, nMode==INJECTION_MODE ? L"Injection" : L"Ejection");  
  414.             continue;  
  415.         }  
  416.   
  417.         if( nMode == INJECTION_MODE )  
  418.             InjectDll(dwPID, szDllPath);  
  419.         else  
  420.             EjectDll(dwPID, szDllPath);  
  421.     }  
  422.   
  423.     CloseHandle(hSnapShot);  
  424.   
  425.     return TRUE;  
  426. }  
  427.   
  428. BOOL InjectDllToOne(LPCTSTR szProc, int nMode, LPCTSTR szDllPath)  
  429. {  
  430.     int                     i = 0, nLen = (int)_tcslen(szProc);  
  431.     DWORD                   dwPID = 0;  
  432.     HANDLE                  hSnapShot = INVALID_HANDLE_VALUE;  
  433.     PROCESSENTRY32          pe;  
  434.     BOOL                    bMore = FALSE;  
  435.   
  436.     // check if ProcName or PID  
  437.     for(i = 0; i < nLen; i++)  
  438.         if( !_istdigit(szProc[i]) )  
  439.             break;  
  440.   
  441.     if( i == nLen )     // PID  
  442.     {  
  443.         dwPID = (DWORD)_tstol(szProc);  
  444.           
  445.         if( nMode == INJECTION_MODE )  
  446.             InjectDll(dwPID, szDllPath);  
  447.         else  
  448.             EjectDll(dwPID, szDllPath);  
  449.     }  
  450.     else                // ProcName  
  451.     {  
  452.         // Get the snapshot of the system  
  453.         pe.dwSize = sizeof(PROCESSENTRY32);  
  454.         hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);  
  455.         if( hSnapShot == INVALID_HANDLE_VALUE )  
  456.         {  
  457.             _tprintf(L"InjectDllToOne() : CreateToolhelp32Snapshot() failed!!! [%d]",   
  458.                       GetLastError());  
  459.             return FALSE;  
  460.         }  
  461.   
  462.         // find process  
  463.         bMore = Process32First(hSnapShot, &pe);  
  464.         for( ; bMore; bMore = Process32Next(hSnapShot, &pe) )  
  465.         {  
  466.             dwPID = pe.th32ProcessID;  
  467.   
  468.          
  469.             if( dwPID < 100 )  
  470.                 continue;  
  471.   
  472.             if( !_tcsicmp(pe.szExeFile, szProc) )  
  473.             {  
  474.                 if( nMode == INJECTION_MODE )  
  475.                     InjectDll(dwPID, szDllPath);  
  476.                 else  
  477.                     EjectDll(dwPID, szDllPath);  
  478.             }  
  479.         }  
  480.   
  481.         CloseHandle(hSnapShot);  
  482.     }  
  483.   
  484.     return TRUE;  
  485. }  
  486.   
  487. BOOL Initialize(LPCTSTR szOption, LPCTSTR szDllPath)  
  488. {  
  489.     // check Option (Injection/Ejection)  
  490.     if( _tcsicmp(szOption, L"-i") &&  
  491.         _tcsicmp(szOption, L"-e") )  
  492.         return FALSE;  
  493.   
  494.     // check DLL Path  
  495.     if( _taccess(szDllPath, 0) == -1 )  
  496.         return FALSE;  
  497.   
  498.     return TRUE;  
  499. }  
  500.   
  501. int _tmain(int argc, TCHAR *argv[])  
  502. {  
  503.     #define BUFSIZE         (1024)  
  504.     int     nMode           = INJECTION_MODE;  
  505.     TCHAR   szPath[BUFSIZE]   = L"";   
  506.       
  507.     if( (argc != 4) ||   
  508.         ( _tcsicmp(argv[2], L"-i") && _tcsicmp(argv[2], L"-e")) )  
  509.     {  
  510.         _tprintf(L"\n %s (Ver 1.1.1) - Dll Injection/Ejection Utility!!!\n"\  
  511.                  L"   www.reversecore.com\n"\  
  512.                  L"   reversecore@gmail.com\n"\  
  513.                  L"\n USAGE  : %s <procname|pid|*> <-i|-e> <dll path>\n\n",   
  514.                  argv[0], argv[0]);  
  515.         return 1;  
  516.     }  
  517.       
  518.     if( !GetFullPathName(argv[3], BUFSIZE, szPath, NULL) )      
  519.     {  
  520.         _tprintf(L"GetFullPathName() failed! [%d]", GetLastError());  
  521.         return 1;  
  522.     }  
  523.   
  524.     // check DLL Path  
  525.     if( _taccess(szPath, 0) == -1 )  
  526.     {  
  527.         _tprintf(L"There is no \"%s\" file!\n", szPath);  
  528.         return FALSE;  
  529.     }  
  530.   
  531.     // change privilege  
  532.     if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )  
  533.         return 1;  
  534.   
  535.     // Mode (Injection/Ejection)  
  536.     if( !_tcsicmp(argv[2], L"-e") )  
  537.         nMode = EJECTION_MODE;  
  538.   
  539.     // Inject Dll  
  540.     if( !_tcsicmp(argv[1], L"*") )  
  541.         InjectDllToAll(nMode, szPath);  
  542.     else  
  543.         InjectDllToOne(argv[1], nMode, szPath);  
  544.   
  545.     return 0;  
  546. }  
下面详细讲解redirect.dll的源代码(redirect.cpp)。
DLLMain的代码非常简单。若模块未加载就钩取其内部API,将导致失败。为防止出现这类问题,进程为iexplore.exe时,钩取InternetConnectW之前必须加载wininet.dll文件。
[cpp] view plain copy
  1. BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)  
  2. {  
  3.     char            szCurProc[MAX_PATH] = {0,};  
  4.     char            *p = NULL;  
  5.   
  6.     switch( fdwReason )  
  7.     {  
  8.         case DLL_PROCESS_ATTACH :   
  9.             DebugLog("DllMain() : DLL_PROCESS_ATTACH\n");  
  10.   
  11.             GetModuleFileNameA(NULL, szCurProc, MAX_PATH);  
  12.             p = strrchr(szCurProc, '\\');  
  13.             if( (p != NULL) && !_stricmp(p+1, "iexplore.exe") )  
  14.             {  
  15.                 DebugLog("DllMain() : current process is [iexplore.exe]\n");  
  16.   
  17.                 // 钩取wininet!InternetConnectW() API之前  
  18.                 // 预先加载wininet.dll  
  19.                 if( NULL == LoadLibrary(L"wininet.dll") )  
  20.                 {  
  21.                     DebugLog("DllMain() : LoadLibrary() failed!!! [%d]\n",  
  22.                              GetLastError());  
  23.                 }  
  24.             }  
  25.   
  26.             // hook  
  27.             hook_by_code("ntdll.dll""ZwResumeThread",   
  28.                          (PROC)NewZwResumeThread, g_pZWRT);  
  29.             hook_by_code("wininet.dll""InternetConnectW",   
  30.                          (PROC)NewInternetConnectW, g_pICW);  
  31.             break;  
  32.   
  33.         case DLL_PROCESS_DETACH :  
  34.             DebugLog("DllMain() : DLL_PROCESS_DETACH\n");  
  35.   
  36.             // unhook  
  37.             unhook_by_code("ntdll.dll""ZwResumeThread",   
  38.                            g_pZWRT);  
  39.             unhook_by_code("wininet.dll""InternetConnectW",   
  40.                            g_pICW);  
  41.             break;  
  42.     }  
  43.   
  44.     return TRUE;  
  45. }  
下面看看NewInternetConnect函数。函数的第二个参数lpszServerName字符串即是要连接的网站地址。监视该连接地址,IE连接特定网站时,就把连接地址修改为www.reversecore.com。
[cpp] view plain copy
  1. HINTERNET WINAPI NewInternetConnectW  
  2. (  
  3.     HINTERNET hInternet,  
  4.     LPCWSTR lpszServerName,  
  5.     INTERNET_PORT nServerPort,  
  6.     LPCTSTR lpszUsername,  
  7.     LPCTSTR lpszPassword,  
  8.     DWORD dwService,  
  9.     DWORD dwFlags,  
  10.     DWORD_PTR dwContext  
  11. )  
  12. {  
  13.     HINTERNET hInt = NULL;  
  14.     FARPROC pFunc = NULL;  
  15.     HMODULE hMod = NULL;  
  16.   
  17.     // unhook  
  18.     if( !unhook_by_code("wininet.dll""InternetConnectW", g_pICW) )  
  19.     {  
  20.         DebugLog("NewInternetConnectW() : unhook_by_code() failed!!!\n");  
  21.         return NULL;  
  22.     }  
  23.   
  24.     // call original API  
  25.     hMod = GetModuleHandle(L"wininet.dll");  
  26.     if( hMod == NULL )  
  27.     {  
  28.         DebugLog("NewInternetConnectW() : GetModuleHandle() failed!!! [%d]\n",  
  29.                   GetLastError());  
  30.         goto __INTERNETCONNECT_EXIT;  
  31.     }  
  32.   
  33.     pFunc = GetProcAddress(hMod, "InternetConnectW");  
  34.     if( pFunc == NULL )  
  35.     {  
  36.         DebugLog("NewInternetConnectW() : GetProcAddress() failed!!! [%d]\n",  
  37.                   GetLastError());  
  38.         goto __INTERNETCONNECT_EXIT;  
  39.     }  
  40.   
  41.     if( !_tcsicmp(lpszServerName, L"www.naver.com") ||  
  42.         !_tcsicmp(lpszServerName, L"www.daum.net") ||  
  43.         !_tcsicmp(lpszServerName, L"www.nate.com") ||   
  44.         !_tcsicmp(lpszServerName, L"www.yahoo.com") )  
  45.     {  
  46.         DebugLog("[redirect] naver, daum, nate, yahoo => reversecore\n");  
  47.         hInt = ((PFINTERNETCONNECTW)pFunc)(hInternet,  
  48.                                            L"www.reversecore.com",  
  49.                                            nServerPort,  
  50.                                            lpszUsername,  
  51.                                            lpszPassword,  
  52.                                            dwService,  
  53.                                            dwFlags,  
  54.                                            dwContext);  
  55.     }  
  56.     else  
  57.     {  
  58.         DebugLog("[no redirect]\n");  
  59.         hInt = ((PFINTERNETCONNECTW)pFunc)(hInternet,  
  60.                                            lpszServerName,  
  61.                                            nServerPort,  
  62.                                            lpszUsername,  
  63.                                            lpszPassword,  
  64.                                            dwService,  
  65.                                            dwFlags,  
  66.                                            dwContext);  
  67.     }  
  68.   
  69. __INTERNETCONNECT_EXIT:  
  70.   
  71.     // hook  
  72.     if( !hook_by_code("wininet.dll""InternetConnectW",   
  73.                       (PROC)NewInternetConnectW, g_pICW) )  
  74.     {  
  75.         DebugLog("NewInternetConnectW() : hook_by_code() failed!!!\n");  
  76.     }  
  77.       
  78.     return hInt;  
  79. }  
接下来分析NewZwResumeThread函数,它用来对ZwResumeThread进行全局钩取。先调用ZwQueryInformationThread获取子进程的PID,然后使用该PID注入redirect.dll文件,最后正常调用ZwResumeThread将子进程的主线程恢复运行。
[cpp] view plain copy
  1. NTSTATUS WINAPI NewZwResumeThread(HANDLE ThreadHandle, PULONG SuspendCount)  
  2. {  
  3.     NTSTATUS status, statusThread;  
  4.     FARPROC pFunc = NULL, pFuncThread = NULL;  
  5.     DWORD dwPID = 0;  
  6.     static DWORD dwPrevPID = 0;  
  7.     THREAD_BASIC_INFORMATION tbi;  
  8.     HMODULE hMod = NULL;  
  9.     TCHAR szModPath[MAX_PATH] = {0,};  
  10.   
  11.     DebugLog("NewZwResumeThread() : start!!!\n");  
  12.   
  13.     hMod = GetModuleHandle(L"ntdll.dll");  
  14.     if( hMod == NULL )  
  15.     {  
  16.         DebugLog("NewZwResumeThread() : GetModuleHandle() failed!!! [%d]\n",  
  17.                   GetLastError());  
  18.         return NULL;  
  19.     }  
  20.   
  21.     // call ntdll!ZwQueryInformationThread()  
  22.     pFuncThread = GetProcAddress(hMod, "ZwQueryInformationThread");  
  23.     if( pFuncThread == NULL )  
  24.     {  
  25.         DebugLog("NewZwResumeThread() : GetProcAddress() failed!!! [%d]\n",  
  26.                   GetLastError());  
  27.         return NULL;  
  28.     }  
  29.   
  30.     statusThread = ((PFZWQUERYINFORMATIONTHREAD)pFuncThread)  
  31.                    (ThreadHandle, 0, &tbi, sizeof(tbi), NULL);  
  32.     if( statusThread != STATUS_SUCCESS )  
  33.     {  
  34.         DebugLog("NewZwResumeThread() : pFuncThread() failed!!! [%d]\n",   
  35.                  GetLastError());  
  36.         return NULL;  
  37.     }  
  38.   
  39.     dwPID = (DWORD)tbi.ClientId.UniqueProcess;  
  40.     if ( (dwPID != GetCurrentProcessId()) && (dwPID != dwPrevPID) )  
  41.     {  
  42.         DebugLog("NewZwResumeThread() => call InjectDll()\n");  
  43.   
  44.         dwPrevPID = dwPID;  
  45.   
  46.         // change privilege  
  47.         if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )  
  48.             DebugLog("NewZwResumeThread() : SetPrivilege() failed!!!\n");  
  49.   
  50.         // get injection dll path  
  51.         GetModuleFileName(GetModuleHandle(STR_MODULE_NAME),   
  52.                           szModPath,   
  53.                           MAX_PATH);  
  54.   
  55.         if( !InjectDll(dwPID, szModPath) )  
  56.             DebugLog("NewZwResumeThread() : InjectDll(%d) failed!!!\n", dwPID);  
  57.     }  
  58.   
  59.     // call ntdll!ZwResumeThread()  
  60.     if( !unhook_by_code("ntdll.dll""ZwResumeThread", g_pZWRT) )  
  61.     {  
  62.         DebugLog("NewZwResumeThread() : unhook_by_code() failed!!!\n");  
  63.         return NULL;  
  64.     }  
  65.   
  66.     pFunc = GetProcAddress(hMod, "ZwResumeThread");  
  67.     if( pFunc == NULL )  
  68.     {  
  69.         DebugLog("NewZwResumeThread() : GetProcAddress() failed!!! [%d]\n",  
  70.                   GetLastError());  
  71.         goto __NTRESUMETHREAD_END;  
  72.     }  
  73.   
  74.     status = ((PFZWRESUMETHREAD)pFunc)(ThreadHandle, SuspendCount);  
  75.     if( status != STATUS_SUCCESS )  
  76.     {  
  77.         DebugLog("NewZwResumeThread() : pFunc() failed!!! [%d]\n", GetLastError());  
  78.         goto __NTRESUMETHREAD_END;  
  79.     }  
  80.   
  81. __NTRESUMETHREAD_END:  
  82.   
  83.     if( !hook_by_code("ntdll.dll""ZwResumeThread",   
  84.                       (PROC)NewZwResumeThread, g_pZWRT) )  
  85.     {  
  86.         DebugLog("NewZwResumeThread() : hook_by_code() failed!!!\n");  
  87.     }  
  88.   
  89.     DebugLog("NewZwResumeThread() : end!!!\n");  
  90.   
  91.     return status;  
  92. }  

完整的代码如下。

[cpp] view plain copy
  1. // redirect.cpp  
  2.   
  3. #include "windows.h"  
  4. #include "wininet.h"  
  5. #include "stdio.h"  
  6. #include "tchar.h"  
  7.   
  8. #define STR_MODULE_NAME                     (L"redirect.dll")  
  9. #define STATUS_SUCCESS                      (0x00000000L)   
  10.   
  11. typedef LONG NTSTATUS;  
  12.   
  13. typedef struct _CLIENT_ID {  
  14.     HANDLE UniqueProcess;  
  15.     HANDLE UniqueThread;  
  16. } CLIENT_ID;  
  17.   
  18. typedef struct _THREAD_BASIC_INFORMATION {  
  19.     NTSTATUS ExitStatus;  
  20.     PVOID TebBaseAddress;  
  21.     CLIENT_ID ClientId;  
  22.     ULONG AffinityMask;  
  23.     LONG Priority;  
  24.     LONG BasePriority;  
  25. } THREAD_BASIC_INFORMATION;  
  26.   
  27. typedef NTSTATUS (WINAPI *PFZWRESUMETHREAD)  
  28. (  
  29.     HANDLE ThreadHandle,   
  30.     PULONG SuspendCount  
  31. );  
  32.   
  33. typedef NTSTATUS (WINAPI *PFZWQUERYINFORMATIONTHREAD)  
  34. (  
  35.     HANDLE ThreadHandle,   
  36.     ULONG ThreadInformationClass,   
  37.     PVOID ThreadInformation,   
  38.     ULONG ThreadInformationLength,   
  39.     PULONG ReturnLength  
  40. );  
  41.   
  42. typedef HINTERNET (WINAPI *PFINTERNETCONNECTW)  
  43. (  
  44.     HINTERNET hInternet,  
  45.     LPCWSTR lpszServerName,  
  46.     INTERNET_PORT nServerPort,  
  47.     LPCTSTR lpszUsername,  
  48.     LPCTSTR lpszPassword,  
  49.     DWORD dwService,  
  50.     DWORD dwFlags,  
  51.     DWORD_PTR dwContext  
  52. );  
  53.   
  54. BYTE g_pZWRT[5] = {0,};  
  55. BYTE g_pICW[5] = {0,};  
  56.   
  57. void DebugLog(const char *format, ...)  
  58. {  
  59.     va_list vl;  
  60.     FILE *pf = NULL;  
  61.     char szLog[512] = {0,};  
  62.   
  63.     va_start(vl, format);  
  64.     wsprintfA(szLog, format, vl);  
  65.     va_end(vl);  
  66.   
  67.     OutputDebugStringA(szLog);  
  68. }  
  69.   
  70. BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)   
  71. {  
  72.     TOKEN_PRIVILEGES tp;  
  73.     HANDLE hToken;  
  74.     LUID luid;  
  75.   
  76.     if( !OpenProcessToken(GetCurrentProcess(),  
  77.                           TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,   
  78.                           &hToken) )  
  79.     {  
  80.         DebugLog("OpenProcessToken error: %u\n", GetLastError());  
  81.         return FALSE;  
  82.     }  
  83.   
  84.     if( !LookupPrivilegeValue(NULL,             // lookup privilege on local system  
  85.                               lpszPrivilege,    // privilege to lookup   
  86.                               &luid) )          // receives LUID of privilege  
  87.     {  
  88.         DebugLog("LookupPrivilegeValue error: %u\n", GetLastError() );   
  89.         return FALSE;   
  90.     }  
  91.   
  92.     tp.PrivilegeCount = 1;  
  93.     tp.Privileges[0].Luid = luid;  
  94.     if( bEnablePrivilege )  
  95.         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
  96.     else  
  97.         tp.Privileges[0].Attributes = 0;  
  98.   
  99.     // Enable the privilege or disable all privileges.  
  100.     if( !AdjustTokenPrivileges(hToken,   
  101.                                FALSE,   
  102.                                &tp,   
  103.                                sizeof(TOKEN_PRIVILEGES),   
  104.                                (PTOKEN_PRIVILEGES) NULL,   
  105.                                (PDWORD) NULL) )  
  106.     {   
  107.         DebugLog("AdjustTokenPrivileges error: %u\n", GetLastError() );   
  108.         return FALSE;   
  109.     }   
  110.   
  111.     if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )  
  112.     {  
  113.         DebugLog("The token does not have the specified privilege. \n");  
  114.         return FALSE;  
  115.     }   
  116.   
  117.     return TRUE;  
  118. }  
  119.   
  120. BOOL hook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes)  
  121. {  
  122.     FARPROC pFunc = NULL;  
  123.     DWORD dwOldProtect = 0, dwAddress = 0;  
  124.     BYTE pBuf[5] = {0xE9, 0, };  
  125.     PBYTE pByte = NULL;  
  126.     HMODULE hMod = NULL;  
  127.   
  128.     hMod = GetModuleHandleA(szDllName);  
  129.     if( hMod == NULL )  
  130.     {  
  131.         DebugLog("hook_by_code() : GetModuleHandle(\"%s\") failed!!! [%d]\n",  
  132.                   szDllName, GetLastError());  
  133.         return FALSE;  
  134.     }  
  135.   
  136.     pFunc = (FARPROC)GetProcAddress(hMod, szFuncName);  
  137.     if( pFunc == NULL )  
  138.     {  
  139.         DebugLog("hook_by_code() : GetProcAddress(\"%s\") failed!!! [%d]\n",  
  140.                   szFuncName, GetLastError());  
  141.         return FALSE;  
  142.     }  
  143.   
  144.     pByte = (PBYTE)pFunc;  
  145.     if( pByte[0] == 0xE9 )  
  146.     {  
  147.         DebugLog("hook_by_code() : The API is hooked already!!!\n");  
  148.         return FALSE;  
  149.     }  
  150.   
  151.     if( !VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect) )  
  152.     {  
  153.         DebugLog("hook_by_code() : VirtualProtect(#1) failed!!! [%d]\n", GetLastError());  
  154.         return FALSE;  
  155.     }  
  156.   
  157.     memcpy(pOrgBytes, pFunc, 5);  
  158.   
  159.     dwAddress = (DWORD)pfnNew - (DWORD)pFunc - 5;  
  160.     memcpy(&pBuf[1], &dwAddress, 4);  
  161.   
  162.     memcpy(pFunc, pBuf, 5);  
  163.   
  164.     if( !VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect) )  
  165.     {  
  166.         DebugLog("hook_by_code() : VirtualProtect(#2) failed!!! [%d]\n", GetLastError());  
  167.         return FALSE;  
  168.     }  
  169.   
  170.     return TRUE;  
  171. }  
  172.   
  173. BOOL unhook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes)  
  174. {  
  175.     FARPROC pFunc = NULL;  
  176.     DWORD dwOldProtect = 0;  
  177.     PBYTE pByte = NULL;  
  178.     HMODULE hMod = NULL;  
  179.   
  180.     hMod = GetModuleHandleA(szDllName);  
  181.     if( hMod == NULL )  
  182.     {  
  183.         DebugLog("unhook_by_code() : GetModuleHandle(\"%s\") failed!!! [%d]\n",  
  184.                   szDllName, GetLastError());  
  185.         return FALSE;  
  186.     }  
  187.   
  188.     pFunc = (FARPROC)GetProcAddress(hMod, szFuncName);  
  189.     if( pFunc == NULL )  
  190.     {  
  191.         DebugLog("unhook_by_code() : GetProcAddress(\"%s\") failed!!! [%d]\n",  
  192.                   szFuncName, GetLastError());  
  193.         return FALSE;  
  194.     }  
  195.   
  196.     pByte = (PBYTE)pFunc;  
  197.     if( pByte[0] != 0xE9 )  
  198.     {  
  199.         DebugLog("unhook_by_code() : The API is unhooked already!!!");  
  200.         return FALSE;  
  201.     }  
  202.   
  203.     if( !VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect) )  
  204.     {  
  205.         DebugLog("unhook_by_code() : VirtualProtect(#1) failed!!! [%d]\n", GetLastError());  
  206.         return FALSE;  
  207.     }  
  208.   
  209.     memcpy(pFunc, pOrgBytes, 5);  
  210.   
  211.     if( !VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect) )  
  212.     {  
  213.         DebugLog("unhook_by_code() : VirtualProtect(#2) failed!!! [%d]\n", GetLastError());  
  214.         return FALSE;  
  215.     }  
  216.   
  217.     return TRUE;  
  218. }  
  219.   
  220. BOOL IsVistaLater()  
  221. {  
  222.     OSVERSIONINFO osvi;  
  223.   
  224.     ZeroMemory(&osvi, sizeof(OSVERSIONINFO));  
  225.     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);  
  226.   
  227.     GetVersionEx(&osvi);  
  228.   
  229.     if( osvi.dwMajorVersion >= 6 )  
  230.         return TRUE;  
  231.   
  232.     return FALSE;  
  233. }  
  234.   
  235. typedef DWORD (WINAPI *PFNTCREATETHREADEX)  
  236. (   
  237.     PHANDLE                 ThreadHandle,     
  238.     ACCESS_MASK             DesiredAccess,    
  239.     LPVOID                  ObjectAttributes,     
  240.     HANDLE                  ProcessHandle,    
  241.     LPTHREAD_START_ROUTINE  lpStartAddress,   
  242.     LPVOID                  lpParameter,      
  243.     BOOL                    CreateSuspended,      
  244.     DWORD                   dwStackSize,      
  245.     DWORD                   dw1,   
  246.     DWORD                   dw2,   
  247.     LPVOID                  Unknown   
  248. );   
  249.   
  250. BOOL MyCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf)  
  251. {  
  252.     HANDLE      hThread = NULL;  
  253.     FARPROC     pFunc = NULL;  
  254.   
  255.     if( IsVistaLater() )    // Vista, 7, Server2008  
  256.     {  
  257.         pFunc = GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtCreateThreadEx");  
  258.         if( pFunc == NULL )  
  259.         {  
  260.             DebugLog("MyCreateRemoteThread() : GetProcAddress() failed!!! [%d]\n",  
  261.                    GetLastError());  
  262.             return FALSE;  
  263.         }  
  264.   
  265.         ((PFNTCREATETHREADEX)pFunc)(&hThread,  
  266.                                     0x1FFFFF,  
  267.                                     NULL,  
  268.                                     hProcess,  
  269.                                     pThreadProc,  
  270.                                     pRemoteBuf,  
  271.                                     FALSE,  
  272.                                     NULL,  
  273.                                     NULL,  
  274.                                     NULL,  
  275.                                     NULL);  
  276.         if( hThread == NULL )  
  277.         {  
  278.             DebugLog("MyCreateRemoteThread() : NtCreateThreadEx() failed!!! [%d]\n", GetLastError());  
  279.             return FALSE;  
  280.         }  
  281.     }  
  282.     else                    // 2000, XP, Server2003  
  283.     {  
  284.         hThread = CreateRemoteThread(hProcess, NULL, 0,   
  285.                                      pThreadProc, pRemoteBuf, 0, NULL);  
  286.         if( hThread == NULL )  
  287.         {  
  288.             DebugLog("MyCreateRemoteThread() : CreateRemoteThread() failed!!! [%d]\n", GetLastError());  
  289.             return FALSE;  
  290.         }  
  291.     }  
  292.   
  293.     if( WAIT_FAILED == WaitForSingleObject(hThread, INFINITE) )  
  294.     {  
  295.         DebugLog("MyCreateRemoteThread() : WaitForSingleObject() failed!!! [%d]\n", GetLastError());  
  296.         return FALSE;  
  297.     }  
  298.   
  299.     return TRUE;  
  300. }  
  301.   
  302. BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)  
  303. {  
  304.     HANDLE                  hProcess = NULL;  
  305.     HANDLE                  hThread = NULL;  
  306.     LPVOID                  pRemoteBuf = NULL;  
  307.     DWORD                   dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);  
  308.     LPTHREAD_START_ROUTINE  pThreadProc = NULL;  
  309.     BOOL                    bRet = FALSE;  
  310.     HMODULE                 hMod = NULL;  
  311.   
  312.     if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )  
  313.     {  
  314.         DebugLog("InjectDll() : OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError());  
  315.         goto INJECTDLL_EXIT;  
  316.     }  
  317.   
  318.     pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,   
  319.                                 MEM_COMMIT, PAGE_READWRITE);  
  320.     if( pRemoteBuf == NULL )  
  321.     {  
  322.         DebugLog("InjectDll() : VirtualAllocEx() failed!!! [%d]\n", GetLastError());  
  323.         goto INJECTDLL_EXIT;  
  324.     }  
  325.   
  326.     if( !WriteProcessMemory(hProcess, pRemoteBuf,   
  327.                            (LPVOID)szDllPath, dwBufSize, NULL) )  
  328.     {  
  329.         DebugLog("InjectDll() : WriteProcessMemory() failed!!! [%d]\n", GetLastError());  
  330.         goto INJECTDLL_EXIT;  
  331.     }  
  332.   
  333.     hMod = GetModuleHandle(L"kernel32.dll");  
  334.     if( hMod == NULL )  
  335.     {  
  336.         DebugLog("InjectDll() : GetModuleHandle() failed!!! [%d]\n", GetLastError());  
  337.         goto INJECTDLL_EXIT;  
  338.     }  
  339.   
  340.     pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");  
  341.     if( pThreadProc == NULL )  
  342.     {  
  343.         DebugLog("InjectDll() : GetProcAddress() failed!!! [%d]\n", GetLastError());  
  344.         goto INJECTDLL_EXIT;  
  345.     }  
  346.   
  347.     if( !MyCreateRemoteThread(hProcess, pThreadProc, pRemoteBuf) )  
  348.     {  
  349.         DebugLog("InjectDll() : MyCreateRemoteThread() failed!!!\n");  
  350.         goto INJECTDLL_EXIT;  
  351.     }  
  352.   
  353.     bRet = TRUE;  
  354.   
  355. INJECTDLL_EXIT:  
  356.   
  357.     if( pRemoteBuf )  
  358.         VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);  
  359.   
  360.     if( hThread )  
  361.         CloseHandle(hThread);  
  362.   
  363.     if( hProcess )  
  364.         CloseHandle(hProcess);  
  365.   
  366.     return bRet;  
  367. }  
  368.   
  369.   
  370.   
  371. NTSTATUS WINAPI NewZwResumeThread(HANDLE ThreadHandle, PULONG SuspendCount)  
  372. {  
  373.     NTSTATUS status, statusThread;  
  374.     FARPROC pFunc = NULL, pFuncThread = NULL;  
  375.     DWORD dwPID = 0;  
  376.     static DWORD dwPrevPID = 0;  
  377.     THREAD_BASIC_INFORMATION tbi;  
  378.     HMODULE hMod = NULL;  
  379.     TCHAR szModPath[MAX_PATH] = {0,};  
  380.   
  381.     DebugLog("NewZwResumeThread() : start!!!\n");  
  382.   
  383.     hMod = GetModuleHandle(L"ntdll.dll");  
  384.     if( hMod == NULL )  
  385.     {  
  386.         DebugLog("NewZwResumeThread() : GetModuleHandle() failed!!! [%d]\n",  
  387.                   GetLastError());  
  388.         return NULL;  
  389.     }  
  390.   
  391.     // call ntdll!ZwQueryInformationThread()  
  392.     pFuncThread = GetProcAddress(hMod, "ZwQueryInformationThread");  
  393.     if( pFuncThread == NULL )  
  394.     {  
  395.         DebugLog("NewZwResumeThread() : GetProcAddress() failed!!! [%d]\n",  
  396.                   GetLastError());  
  397.         return NULL;  
  398.     }  
  399.   
  400.     statusThread = ((PFZWQUERYINFORMATIONTHREAD)pFuncThread)  
  401.                    (ThreadHandle, 0, &tbi, sizeof(tbi), NULL);  
  402.     if( statusThread != STATUS_SUCCESS )  
  403.     {  
  404.         DebugLog("NewZwResumeThread() : pFuncThread() failed!!! [%d]\n",   
  405.                  GetLastError());  
  406.         return NULL;  
  407.     }  
  408.   
  409.     dwPID = (DWORD)tbi.ClientId.UniqueProcess;  
  410.     if ( (dwPID != GetCurrentProcessId()) && (dwPID != dwPrevPID) )  
  411.     {  
  412.         DebugLog("NewZwResumeThread() => call InjectDll()\n");  
  413.   
  414.         dwPrevPID = dwPID;  
  415.   
  416.         // change privilege  
  417.         if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )  
  418.             DebugLog("NewZwResumeThread() : SetPrivilege() failed!!!\n");  
  419.   
  420.         // get injection dll path  
  421.         GetModuleFileName(GetModuleHandle(STR_MODULE_NAME),   
  422.                           szModPath,   
  423.                           MAX_PATH);  
  424.   
  425.         if( !InjectDll(dwPID, szModPath) )  
  426.             DebugLog("NewZwResumeThread() : InjectDll(%d) failed!!!\n", dwPID);  
  427.     }  
  428.   
  429.     // call ntdll!ZwResumeThread()  
  430.     if( !unhook_by_code("ntdll.dll""ZwResumeThread", g_pZWRT) )  
  431.     {  
  432.         DebugLog("NewZwResumeThread() : unhook_by_code() failed!!!\n");  
  433.         return NULL;  
  434.     }  
  435.   
  436.     pFunc = GetProcAddress(hMod, "ZwResumeThread");  
  437.     if( pFunc == NULL )  
  438.     {  
  439.         DebugLog("NewZwResumeThread() : GetProcAddress() failed!!! [%d]\n",  
  440.                   GetLastError());  
  441.         goto __NTRESUMETHREAD_END;  
  442.     }  
  443.   
  444.     status = ((PFZWRESUMETHREAD)pFunc)(ThreadHandle, SuspendCount);  
  445.     if( status != STATUS_SUCCESS )  
  446.     {  
  447.         DebugLog("NewZwResumeThread() : pFunc() failed!!! [%d]\n", GetLastError());  
  448.         goto __NTRESUMETHREAD_END;  
  449.     }  
  450.   
  451. __NTRESUMETHREAD_END:  
  452.   
  453.     if( !hook_by_code("ntdll.dll""ZwResumeThread",   
  454.                       (PROC)NewZwResumeThread, g_pZWRT) )  
  455.     {  
  456.         DebugLog("NewZwResumeThread() : hook_by_code() failed!!!\n");  
  457.     }  
  458.   
  459.     DebugLog("NewZwResumeThread() : end!!!\n");  
  460.   
  461.     return status;  
  462. }  
  463.   
  464.   
  465.   
  466.   
  467. HINTERNET WINAPI NewInternetConnectW  
  468. (  
  469.     HINTERNET hInternet,  
  470.     LPCWSTR lpszServerName,  
  471.     INTERNET_PORT nServerPort,  
  472.     LPCTSTR lpszUsername,  
  473.     LPCTSTR lpszPassword,  
  474.     DWORD dwService,  
  475.     DWORD dwFlags,  
  476.     DWORD_PTR dwContext  
  477. )  
  478. {  
  479.     HINTERNET hInt = NULL;  
  480.     FARPROC pFunc = NULL;  
  481.     HMODULE hMod = NULL;  
  482.   
  483.     // unhook  
  484.     if( !unhook_by_code("wininet.dll""InternetConnectW", g_pICW) )  
  485.     {  
  486.         DebugLog("NewInternetConnectW() : unhook_by_code() failed!!!\n");  
  487.         return NULL;  
  488.     }  
  489.   
  490.     // call original API  
  491.     hMod = GetModuleHandle(L"wininet.dll");  
  492.     if( hMod == NULL )  
  493.     {  
  494.         DebugLog("NewInternetConnectW() : GetModuleHandle() failed!!! [%d]\n",  
  495.                   GetLastError());  
  496.         goto __INTERNETCONNECT_EXIT;  
  497.     }  
  498.   
  499.     pFunc = GetProcAddress(hMod, "InternetConnectW");  
  500.     if( pFunc == NULL )  
  501.     {  
  502.         DebugLog("NewInternetConnectW() : GetProcAddress() failed!!! [%d]\n",  
  503.                   GetLastError());  
  504.         goto __INTERNETCONNECT_EXIT;  
  505.     }  
  506.   
  507.     if( !_tcsicmp(lpszServerName, L"www.naver.com") ||  
  508.         !_tcsicmp(lpszServerName, L"www.daum.net") ||  
  509.         !_tcsicmp(lpszServerName, L"www.nate.com") ||   
  510.         !_tcsicmp(lpszServerName, L"www.yahoo.com") )  
  511.     {  
  512.         DebugLog("[redirect] naver, daum, nate, yahoo => reversecore\n");  
  513.         hInt = ((PFINTERNETCONNECTW)pFunc)(hInternet,  
  514.                                            L"www.reversecore.com",  
  515.                                            nServerPort,  
  516.                                            lpszUsername,  
  517.                                            lpszPassword,  
  518.                                            dwService,  
  519.                                            dwFlags,  
  520.                                            dwContext);  
  521.     }  
  522.     else  
  523.     {  
  524.         DebugLog("[no redirect]\n");  
  525.         hInt = ((PFINTERNETCONNECTW)pFunc)(hInternet,  
  526.                                            lpszServerName,  
  527.                                            nServerPort,  
  528.                                            lpszUsername,  
  529.                                            lpszPassword,  
  530.                                            dwService,  
  531.                                            dwFlags,  
  532.                                            dwContext);  
  533.     }  
  534.   
  535. __INTERNETCONNECT_EXIT:  
  536.   
  537.     // hook  
  538.     if( !hook_by_code("wininet.dll""InternetConnectW",   
  539.                       (PROC)NewInternetConnectW, g_pICW) )  
  540.     {  
  541.         DebugLog("NewInternetConnectW() : hook_by_code() failed!!!\n");  
  542.     }  
  543.       
  544.     return hInt;  
  545. }  
  546.   
  547. BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)  
  548. {  
  549.     char            szCurProc[MAX_PATH] = {0,};  
  550.     char            *p = NULL;  
  551.   
  552.     switch( fdwReason )  
  553.     {  
  554.         case DLL_PROCESS_ATTACH :   
  555.             DebugLog("DllMain() : DLL_PROCESS_ATTACH\n");  
  556.   
  557.             GetModuleFileNameA(NULL, szCurProc, MAX_PATH);  
  558.             p = strrchr(szCurProc, '\\');  
  559.             if( (p != NULL) && !_stricmp(p+1, "iexplore.exe") )  
  560.             {  
  561.                 DebugLog("DllMain() : current process is [iexplore.exe]\n");  
  562.   
  563.                 // 钩取wininet!InternetConnectW() API之前  
  564.                 // 预先加载wininet.dll  
  565.                 if( NULL == LoadLibrary(L"wininet.dll") )  
  566.                 {  
  567.                     DebugLog("DllMain() : LoadLibrary() failed!!! [%d]\n",  
  568.                              GetLastError());  
  569.                 }  
  570.             }  
  571.   
  572.             // hook  
  573.             hook_by_code("ntdll.dll""ZwResumeThread",   
  574.                          (PROC)NewZwResumeThread, g_pZWRT);  
  575.             hook_by_code("wininet.dll""InternetConnectW",   
  576.                          (PROC)NewInternetConnectW, g_pICW);  
  577.             break;  
  578.   
  579.         case DLL_PROCESS_DETACH :  
  580.             DebugLog("DllMain() : DLL_PROCESS_DETACH\n");  
  581.   
  582.             // unhook  
  583.             unhook_by_code("ntdll.dll""ZwResumeThread",   
  584.                            g_pZWRT);  
  585.             unhook_by_code("wininet.dll""InternetConnectW",   
  586.                            g_pICW);  
  587.             break;  
  588.     }  
  589.   
  590.     return TRUE;  
  591. }  
阅读全文
0 0
原创粉丝点击