본문 바로가기

공부/리버싱 핵심원리

DLL 인젝션

 a. 악성 DLL을 인젝션하는 injector.exe 만들기
          i. PID를 입력하면 해당 프로세스에 inject.dll을 삽입하도록

#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
#include <string>

// 함수 원형
BOOL InjectDLL(DWORD dwPID, const char* dllPath);

int main() {
    DWORD dwPID;
    std::string dllPath;

    // 사용자로부터 PID 입력 받기
    std::cout << "PID: ";
    std::cin >> dwPID;

    dllPath="(dll 주소)";
    // 예시: dllPath="C:\\Users\\BSBS\\Downloads\\inject.dll";

    // DLL 삽입 시도
    if (InjectDLL(dwPID, dllPath.c_str())) {
        std::cout << "Success!" << std::endl;
    } else {
        std::cerr << "Fail!" << std::endl;
    }

    return 0;
}

BOOL InjectDLL(DWORD dwPID, const char* dllPath) {
    HANDLE hProcess, hThread;
    LPVOID pRemoteBuf;
    DWORD dwBufSize = strlen(dllPath) + 1;
    LPTHREAD_START_ROUTINE pThreadProc;

    // 타겟 프로세스 핸들 얻기
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
    if (hProcess == NULL) {
        std::cerr << "프로세스를 열지 못했습니다!" << std::endl;
        return FALSE;
    }

    // 타겟 프로세스의 메모리에 DLL 경로 문자열 할당
    pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
    if (pRemoteBuf == NULL) {
        std::cerr << "대상 프로세스에서 메모리를 할당하지 못했습니다!" << std::endl;
        CloseHandle(hProcess);
        return FALSE;
    }

    // DLL 경로 쓰기
    if (!WriteProcessMemory(hProcess, pRemoteBuf, dllPath, dwBufSize, NULL)) {
        std::cerr << "대상 프로세스 메모리에 DLL 경로를 쓰지 못했습니다!" << std::endl;
        VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return FALSE;
    }

    // LoadLibrary 함수의 주소 가져오기
    pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
    if (pThreadProc == NULL) {
        std::cerr << "LoadLibraryA 함수의 주소를 가져오지 못했습니다!" << std::endl;
        VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return FALSE;
    }

    // 원격 스레드 생성하여 DLL 적재
    hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
    if (hThread == NULL) {
        std::cerr << "대상 프로세스에서 원격 스레드를 만들지 못했습니다!" << std::endl;
        VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return FALSE;
    }

    // 스레드 실행 완료까지 대기
    WaitForSingleObject(hThread, INFINITE);

    // 정리 작업
    CloseHandle(hThread);
    VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
    CloseHandle(hProcess);

    return TRUE;
}

 

 

b. 악성 DLL 역할을 할 inject.dll 만들기
          i. 현재 PID를 MessageBox로 출력
          ii. MessageBox를 실행하는 코드는 DLLMain에 작성

// dllmain.cpp : DLL 응용 프로그램의 진입점을 정의합니다.
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH: {
        // 프로세스의 PID를 얻습니다.
        DWORD processID = GetCurrentProcessId();

        // PID를 문자열로 변환합니다.
        TCHAR message[256];
        _stprintf_s(message, _T("PID: %u"), processID);

        // MessageBox로 PID를 출력합니다.
        MessageBox(NULL, message, _T("DLL Injection"), MB_OK);

        break;
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

실행 결과

 

 

*"대상 프로세스에서 원격 스레드를 만들지 못했습니다!" 오류 발생 시 >> 32비트인지 64비트인지 확인. 호환되는 프로세스여야 함.

'공부 > 리버싱 핵심원리' 카테고리의 다른 글

메모장 WriteFile 함수 후킹  (0) 2024.06.01
DLL Injection&코드 인젝션  (0) 2024.05.22
Windows 메시지 후킹  (0) 2024.05.21
인라인 패치 실습  (0) 2024.05.14
UPX 언패킹  (0) 2024.05.12