ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 24 DLL 이젝션
    리버싱 엔지니어링/리버싱 핵심 원리 2022. 4. 5. 01:46

    : 프로세스에 강제로 삽입한 DLL을 빼내는 기법

     

     DLL 이젝션 동작 원리 

    • DLL 인젝션의 동작 원리 : 대상 프로세스로 하여금 LoadLibrary() API를 호출하도록 만드는 것
      • CreateRemoteThread() API를 이용
    • DLL 이젝션 동작 원리 : 대상 프로세스로 하여금 FreeLibrary() API를 호출하도록 만드는 것
      • DLL 이젝션 또한 인젝션과 동일하게 CreateRemoteThread() API 이용

     

     DLL 이젝션 구현 

    : EjectDll.cpp의 EjectDll() 함수

    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)) )
        {
            _tprintf(L"OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError());
            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;
    }

    프로세스에 로딩된 DLL 정보 구하기

    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);

    • CreateToolhelp32Snapshot() API를 이용하면 프로세스에 로딩된 모듈(DLL)의 정보를 얻을 수 있음
    • hSnapshot을 Module32First()/Module32Next() 함수에 넘겨주면 MODULEENTRY32 구조체에 해당 모듈의 정보가 세팅됨

     

    대상 프로세스 핸들 구하기

    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)

    • 프로세스 ID를 이용해 대상 프로세스(notepad)의 프로세스 핸들을 구함

     

    FreeLibrary() API 주소 구하기

    hModule = GetModuleHandle(L"kernel32.dll");
    pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");

    • Kernel32!FreeLibrary 주소를 통해 주소 구하기
      • FreeLibrary 주소는 모든 프로세스에 대해 동일

     

    대상 프로세스에 스레드를 실행시킴

    hThread = CreateRemoteThread(hProcess, NULL, 0,  pThreadProc, me.modBaseAddr, 0, NULL);

    •  pThreadProc : FreeLibrary() API 주소
    • me.modBaseAddr : 에젝하길 원하는 DLL의 로딩 주소
    • 다음과 같이 설정하면, 스레드 함수가 FreeLibrary가 됨

     

     DLL 이젝션 간단 실습 

    : notepad에 인젝션된 myhack.dll을 이젝션

     

    notepad 실행 및 인젝션

    (참고 : https://wh514.tistory.com/40)

     

    이젝션

    cmd 창에 EjectDll.exe 입력

     

     

    댓글

Designed by Tistory.