Hubeen's Home

DLL Injection



이번 글 내용 한 줄 요약할 수 있는 사진을 만들어버렸다...

DLL 인젝션은 말 그대로 다른 프로세서에 DLL을 강제로 박아버리는 것이다.

LoadLibrary() API를 호출하여 DLL을 로딩(Loading) 시키는 것인데.


DLL Injection은 다른 프로세서에 DLL을 삽입시키느냐, 자신의 프로세스에 삽입시키느냐에 따라 로딩시키는 대상에 따라 달라집니다.


What is DLL?

DLL은 Dynamic Linked Library의 약자로서 동적 연결 라이브러리입니다.
흔히 디엘엘 파일 이라고 읽고 드르르라고 읽기도 합니다.
이 DLL 파일은 프로그램 실행 후 동적으로 로드되고, 정적라이브러리에 비해 크기를 줄일 수 있습니다.
게다가 패치, 기능 개선에 효율성이 높습니다.

Purpose of DLL file use

보통 대게 DLL 파일의 사용 목적은 여러가지가 있습니다.

1. 크기

정적 라이브러리에 비해 동적 라이브러리가 크기가 작기 때문에,
실행 파일의 크기를 줄일 수 있습니다.

2. 악성 코드

정상적인 프로세스에 DLL 파일을 삽입하여 악의적인 행위를 합니다.

3. 패치

어떠한 프로그램의 패치가 필요할 때에 DLL Injection을 이용하여 문제가 있는 Data 수정할 수 있습니다.
그 패치가 필요한 프로세스에 침투한 DLL은 메모리들에 접근이 가능하기에 패치가 가능합니다.

그외에도 많겠지만...

Make DLL File in VS2015

New Project - Visual C++ - Win32 Project - DLL(D) - End


이제 코드를 작성하시고 빌드를 하고 DLL을 사용하면 됩니다.


Injector

Code는 아래와 같다.
출처 : http://www.reversecore.com/40


#include "stdio.h"
#include "windows.h"
#include "tlhelp32.h"

#define DEF_PROC_NAME ("notepad.exe")
#define DEF_DLL_PATH ("c:\\Malware.dll")

DWORD FindProcessID(LPCTSTR szProcessName);
BOOL InjectDll(DWORD dwPID, LPCTSTR szDllName);

int main(int argc, char* argv[])
{
    DWORD dwPID = 0xFFFFFFFF;
 
    // find process
    dwPID = FindProcessID(DEF_PROC_NAME);
    if( dwPID == 0xFFFFFFFF )
    {
        printf("There is no <%s> process!\n", DEF_PROC_NAME);
        return 1;
    }

    // inject dll
    InjectDll(dwPID, DEF_DLL_PATH); 

    return 0;
}

DWORD FindProcessID(LPCTSTR szProcessName)
{
    DWORD dwPID = 0xFFFFFFFF;
    HANDLE hSnapShot = INVALID_HANDLE_VALUE;
    PROCESSENTRY32 pe;

    // Get the snapshot of the system
    pe.dwSize = sizeof( PROCESSENTRY32 );
    hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, NULL );

    // find process
    Process32First(hSnapShot, &pe);
    do
    {
        if(!_stricmp(szProcessName, pe.szExeFile))
        {
            dwPID = pe.th32ProcessID;
            break;
        }
    }
    while(Process32Next(hSnapShot, &pe));

    CloseHandle(hSnapShot);

    return dwPID;
}

BOOL InjectDll(DWORD dwPID, LPCTSTR szDllName)
{
    HANDLE hProcess, hThread;
    HMODULE hMod;
    LPVOID pRemoteBuf;
    DWORD dwBufSize = lstrlen(szDllName) + 1;
    LPTHREAD_START_ROUTINE pThreadProc;

    if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )
        return FALSE;

    pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);

    WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName, dwBufSize, NULL);

    hMod = GetModuleHandle("kernel32.dll");
    pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryA");

    hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
    WaitForSingleObject(hThread, INFINITE); 

    CloseHandle(hThread);
    CloseHandle(hProcess);

    return TRUE;


DWORD FindProcessID(LPCTSTR szProcessName)

LPCTSTR szProcessName : 프로세스 이름 [ Ex) notepad.exe, kakaotalk.exe ]

Return : 프로세스 PID 값을 반환합니다.


BOOL InjectDll(DWORD dwPID, LPCTSTR szDllName) 

DWORD dwPID : 프로세스의 PID 값 

LPCTSTR szDllName : DLL 경로 [ Ex) C:\dsadasdas.dll, d:\asdasdas.dll ]

Return : 무조건 True를 반환하나, Handle을 구하지 못할 경우에는 False를 반환합니다.


InjectDll() 함수 코드 설명


if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )
        return FALSE;


먼저 OpenProcess에서 PID의 핸들을 구합니다.

핸들을 구하여 이 프로세스를 제어할 수 있습니다.


pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);

VirtualAllocEx() 함수로 그 프로세스의 메모리 공간에 버퍼를 할당합니다.

dll을 인젝션할 경로의 길이 만큼 할당합니다.


WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName, dwBufSize, NULL);


할당 받은 주소가 담긴 pRemoteBuf에 WriteProcessMemory 함수로 DLL 경로 문자열 #define DEF_DLL_PATH ("c:\\Malware.dll") 를 써줍니다.

이로서 원하는 프로세서 메모리 공간에 DLL 파일의 경로가 적재되었습니다.


hMod = GetModuleHandle("kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryA");

LoadLibraryA를 호출하기 위해서는 그주소가 필요합니다.
그러기 위해 kernel32.dll의 핸들을 구해와서 LoadLibraryA() 의 주소를 얻어냈습니다.


hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
WaitForSingleObject(hThread, INFINITE); 

pThreadProc : 프로세으의 kernel32.dll LoadLibraryA() 주소
pRemoteBuf : 프로세스 메모리에 적재된 dll 경로가 담긴 주소

그 뒤에 CreateRemoteThread로 프로세스에 kernel32.dll LoadLibraryA()를 호출합니다.


'0x30 Study > 0x31 Reverse Lab' 카테고리의 다른 글

[Reverse Lab 스터디] Ada Cracked(0)  (1) 2016.08.10
[Reverse Lab 스터디] DLL Injection  (0) 2016.08.10
[ReverseLab 스터디] UPX Packing  (0) 2016.07.26

Comment 0