미친해커

[Reversing] DLL Injection Step 1 본문

Reversing/DLL Injection

[Reversing] DLL Injection Step 1

미친해커 2022. 1. 18. 15:22
반응형

DLL Injection을 하기 위해서 DLL Injector가 필요하다. DLL Injector란 다른 프로세스에 DLL Injection을 하게해주는 프로그램이다. DLL Injection을 하기위해 DLL Injector는 다음과 같은 함수들을 사용한다.

 

OpenProcess function (processthreadsapi.h) - Win32 apps

Opens an existing local process object.

docs.microsoft.com

 

VirtualAllocEx function (memoryapi.h) - Win32 apps

Reserves, commits, or changes the state of a region of memory within the virtual address space of a specified process. The function initializes the memory it allocates to zero.

docs.microsoft.com

 

WriteProcessMemory function (memoryapi.h) - Win32 apps

Writes data to an area of memory in a specified process. The entire area to be written to must be accessible or the operation fails.

docs.microsoft.com

 

GetModuleHandleA function (libloaderapi.h) - Win32 apps

Retrieves a module handle for the specified module. The module must have been loaded by the calling process.

docs.microsoft.com

 

GetProcAddress function (libloaderapi.h) - Win32 apps

Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL).

docs.microsoft.com

 

CreateRemoteThread function (processthreadsapi.h) - Win32 apps

Creates a thread that runs in the virtual address space of another process.

docs.microsoft.com

DLL Injector가 DLL Injection 하는 과정은 다음과 같다.

 

1. OpenProcess API 함수를 호출하여 타겟 프로세스에 대한 Handle을 획득

2. VirtualAllocEx API 함수를 호출해 타겟 프로세스에 공간을 할당

3. WriteProcessMemory API 함수를 호출해 타겟 프로세스에 할당된 공간에 DLL 경로를 작성

4. GetModuleHandleA API 함수를 호출해 kernel32.dll의 Handle을 가져옴

5. GetProcAddress API 함수를 호출해 LoadLibraryA의 주소를 알아냄

6. CreateRemoteThread API 함수를 호출해 타겟 프로세스 내에 LoadLibraryA 함수를 호출해 DLL을 로드시킴

위 순서를 바탕으로 DLL Injection을 해주는 DLL Injector를 제작해보자

#include <stdio.h>
#include <windows.h>

#define DesiredAccess (PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD)

LPCSTR GetBaseName(LPCSTR path)
{
    ssize_t length = strlen(path);

    for (; length > -1; length--)
    {
        if (path[length] == '\\')
            return path + length + 1;
    }

    return path;
}

void error(LPCSTR FunctionName)
{
    printf("[-] %s Failed\n", FunctionName);
    printf("[*] GetLastError : %d\n", GetLastError());
}

int main(int argc, char *argv[])
{
    if (argc < 3)
    {
        printf("Usage : %s [PID] [DLL Path]\n", GetBaseName(argv[0]));
        printf("ex : %s 1234 C:\\Hack.dll", GetBaseName(argv[0]));
        return -1;
    }

    DWORD PID = atoi(argv[1]);
    LPCSTR Path = argv[2];
    size_t length = strlen(Path);

    printf("[*] Attempting get target process permissions...\n");

    HANDLE hProcess = OpenProcess(DesiredAccess, FALSE, PID);

    if (hProcess == NULL)
    {
        error("OpenProcess");
        return -1;
    }

    printf("[*] OpenProcess success!\n");
    printf("[+] Get process handle : 0x%X\n", hProcess);

    PVOID PathAddress = VirtualAllocEx(hProcess, NULL, length, MEM_COMMIT, PAGE_READWRITE);

    if (PathAddress == NULL)
    {
        error("VirtualAllocEx");
        return -1;
    }

    printf("[*] Allocate buffer to target process success!\n");
    printf("[+] Buffer address is 0x%p\n", PathAddress);

    printf("[*] DLL path writing...\n");

    SIZE_T NumberOfBytesWritten;

    if (WriteProcessMemory(hProcess, PathAddress, Path, length, NULL) == FALSE)
    {
        error("WriteProcessMemory");
        return -1;
    }

    printf("[*] Written DLL Path\n");

    printf("[*] HMODULE of kernel32.dll finding...\n");

    HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
    
    if (hKernel32 == NULL)
    {
        error("GetModuleHandleA");
        return -1;
    }

    printf("[*] HMODULE of kernel32.dll found!\n");
    printf("[+] HMODULE of kernel32.dll is 0x%p\n", hKernel32);

    printf("[*] LoadLibraryA address of kernel32.dll finding...\n");

    FARPROC lpLoadLibraryA = GetProcAddress(hKernel32, "LoadLibraryA");

    if (lpLoadLibraryA == NULL)
    {
        error("GetProcAddress");
        return -1;
    }

    printf("[*] LoadLibraryA address of kernel32.dll found!\n");
    printf("[+] LoadLibraryA address is 0x%p\n", lpLoadLibraryA);

    HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL, lpLoadLibraryA, PathAddress, 0, NULL);

    if (hThread == NULL)
    {
        error("CreateRemoteThread");
        return -1;
    }

    printf("[+] DLL Injection Success!\n");

    return 0;
}

Injector.exe
0.06MB

이렇게 DLL Injector가 완성되었다.

반응형

'Reversing > DLL Injection' 카테고리의 다른 글

[Reversing] DLL Injection Step 3  (0) 2022.01.18
[Reversing] DLL Injection Step 2  (0) 2022.01.18
[Reversing] DLL Injection Step 0  (0) 2022.01.18
Comments