1. 程式人生 > 實用技巧 >xxxx (二):DLL遠端注入

xxxx (二):DLL遠端注入

  要想改變目標程序執行流程的辦法有很多,最常見的就是hook。為了讓目標程序執行特定的程式碼,可以注入shellcode或dll;shellcode的優點是體積小,不容易被檢測到,但功能也相對單一;dll注入優點是可以包含的功能較多,但容易被檢測到。本次拿xxxx軟體舉例做個dll注入;

  要做注入,否先要再目標程序開闢一塊記憶體空間,然後寫入自己想要執行的程式碼,再想辦法讓eip跳轉到這裡。對於dll注入,大致的流程如下:

  openprocess->VirtualAllocEx->WriteProcessMemory->GetProcAddress->CreateRemoteThread

  核心思路:開啟目標程序,分配記憶體空間,寫入需要執行的dll地址,得到loadlibrary函式地址,最後呼叫createRemoteThread函式專門生成一個執行緒執行loadlibary函式。這種注入/HOOK方式多年前就爛大街了,這裡不再贅述,感興趣的小夥伴可google查閱相關資料;dll注入核心程式碼如下:

#include "windows.h"
#include "tchar.h"

BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
{
    HANDLE hProcess = NULL, hThread = NULL;
    HMODULE hMod 
= NULL; LPVOID pRemoteBuf = NULL; DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR); LPTHREAD_START_ROUTINE pThreadProc; if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) ) { _tprintf(L"OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError());
return FALSE; } pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL); hMod = GetModuleHandle(L"kernel32.dll"); pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW"); hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL); WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); CloseHandle(hProcess); return TRUE; } int _tmain(int argc, TCHAR *argv[]) { if( argc != 3) { _tprintf(L"USAGE : %s <pid> <dll_path>\n", argv[0]); return 1; } // inject dll if( InjectDll((DWORD)_tstol(argv[1]), argv[2]) ) _tprintf(L"InjectDll(\"%s\") success!!!\n", argv[2]); else _tprintf(L"InjectDll(\"%s\") failed!!!\n", argv[2]); return 0; }

  這裡需要輸入兩個引數:目標程序的PID和需要載入的dll全路徑。這裡為了突出重點(注入流程),省略了查詢目標程序的程式碼(感興趣的小夥伴可呼叫windows的API遍歷程序,查詢PID),這裡手動在工作管理員裡面查詢;

  為了測試dll是否載入成功,這裡先不執行其他程式碼,只彈個窗試試:

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        MessageBoxW(NULL,L"dll載入成功",L"dll載入測試", MB_OK);
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

 測試效果,說明dll載入成功了! 

  下一步就是通過動態除錯或靜態分析找各種功能call了!