1. DLL(Dynamic Link Library)이란?
→ 동적 링크 라이브러리
→ 컴파일 시 함수의 코드가 실행 파일에 복사되는 것이 아닌 실행 중 라이브러리에 있는 함수를 호출
- 컴파일러 : 함수의 실제 주소가 저장될 위치만 준비 후 CALL
- PE로더 : 준비한 위치에 실제 함수의 주소를 입력
→ 자주 사용되는 표준 함수를 미리 만들어서 모아 놓은 파일
장점 : 응용프로그램의 모듈화 및 쉬운 기능 업데이터, 중복 코드 사용의 감소로 인한 적은 리소스 사용 등
- DLL 호출 방법
1) 암시적(Implicit linking)
→ 실행 파일 자체에 어떤 dll의 어떤 함수를 사용할지에 대한 정보를 포함시킨 후 운영체제가 프로그램 실행 시 해당 함수들을 초기화한 후 이용
2) 명시적(Explicit linking)
→ 프로그램이 실행 중일 때 API를 이용하여 DLL 파일이 있는지 검사하고 동적으로 원하는 함수만 불러와서 사용
2. DLL Injection
→ 다른 프로세스에 특정 dll 파일을 강제로 삽입시키는 것
→ 다른 프로세스에게 LoadLibrary( ) API를 호출하도록 명령하여 원하는 dll을 Loading시키는 것
※ 사용 목적
- LoadLibrary() API를 이용하여 어떤 dll을 로딩시키면 dllmain()함수가 실행됨
- 강제 삽입된 dll의 DllMain() 함수가 실행되면 해당 프로세스의 메모리에 대한 접근 권한을 갖기 때문에 사용자가 원하는 다양한 일을 수행할 수 있음
→ 악의적인 용도로 사용될 가능성이 있음
1. 제어권 얻기 - OpenProcess()
→ 주입할 대상 프로세스에 대한 handle을 얻는다.
OpenProcess() API를 이용하여 notepad.exe 프로세스의 handle을 얻는다.
2. DLL 경로를 프로세스에 기록 - VirtualAllocEX(), WriteProcessMemory()
→ 대상 프로세스 내의 DLL 경로를 넣기 위한 메모리를 할당하고, 할당된 메모리에 DLL 경로를 기록한다.
notepad.exe에 로딩할 DLL 파일의 경로를 알려주기 위해 VirtualAllocEx() API를 이용하여 메모리를 할당한다.
WriteProcessMemory() API를 이용하여 DLL 경로를 써준다.
3. DLL 로드 작업 - LoadLibraryW()
→ 원하는 DLL을 로드한다.
notepad.exe 프로세스가 LoadLibraryW() API를 이용하여 myhack.dll을 불러내야 하기 때문에 LoadLibraryW() API 주소를 알아내야 한다.
→ 실제로는 운영체제에서 kernel32.dll은 프로세스마다 같은 주소에 로딩되므로 InjectDll 프로세스에 임포트된 LoadLibraryW()와 notepad 프로세스에 임포트된 LoadLibraryW() 주소는 동일하다.
4. 원격 스레드 생성을 통한 프로세스에서 로드 - CreateRemoteThread(), NtCreateThreadEx()
→ 대상 프로세스에 Thread를 생성하고, LoadLibaryW() 함수를 실행시킨다.
CreateRemoteThread()는 다른 프로세스에게 스레드를 실행시키도록 하는 함수이다.
이를 이용하여 notepad.exe가 LoadLibraryW() API를 호출하도록 한다.
→ IpStartAddress는 스레드 함수 주소, IpParameter는 스레드 파라미터 주소이다.
→ 이 주소들은 대상 프로세스(hProcess)의 메모리 내의 공간의 주소여야 한다.
3. DLL Ejection
→ 다른 프로세스에 특정 DLL 파일을 강제로 빼내는 것
→ 다른 프로세스에게 FreeLibrary() API를 스스로 호출하도록 명령하는 것
1. 프로세스에 로딩된 DLL 정보 구하기 - CreateToolhelp32Snapshot()
→ 프로세스에 로딩된 DLL의 정보를 얻는다.
CreateToolhelp32Snapshot() API를 통해 프로세스에 로딩된 DLL의 정보를 얻을 수 있다.
2. 대상 프로세스 핸들 구하기 - OpenProcess()
→ 프로세스 ID를 이용하여 대상 프로세스의 프로세스 핸들을 구한다. 추후에 이를 이용하여 CreateRemoteThread() API를 호출한다.
3. FreeLibrary() API 구하기 - GetModuleHandle(), GetProcAddress()
→ hModule(모듈핸들)로 DLL의 핸들 값을 받아온다.
모든 프로세스에서 FreeLibrary()의 주소는 동일하기 때문에 EjectionDll.exe에서 로딩된 API의 주소를 불러오고 있다.
4. 대상 프로세스에 스레드를 실행 - CreateRemoteThread(), NtCreateThreadEx()
→ 외부 프로세스에 스레드 함수(FreeLibrary)를 실행시킨다.
스레드 함수로 FreeLibrary()를 지정하고 Ejection할 DLL의 주소를 넘겨주면 대상 프로세스에서는 FreeLibrary() API가 호출된다.
※ 출처
https://fistki.tistory.com/6
https://fistki.tistory.com/9
'2021-2 STUDY > Reversing Study' 카테고리의 다른 글
Week05_Lab06-03, Lab06-04 (0) | 2021.11.20 |
---|---|
Week04_Dreamhack rev-basic-7, rev-basic-8 (0) | 2021.11.13 |
Week03_Dreamhack rev-basic-4, rev-basic-5, rev-basic-6 (0) | 2021.10.02 |
Week03_IAT, EAT (0) | 2021.10.02 |
Week02_패킹&UPX (0) | 2021.09.25 |