리버싱 엔지니어링/리버싱 핵심 원리
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 입력