34. 고급 글로벌 API 후킹 - IE 접속 제어
후킹 대상 API
후킹 대상이 되는 API는 주로 프로세스의 동작을 제어하거나 모니터링하는 데 사용됨. 예를 들어, wininet.dll의 InternetConnectW() API는 인터넷 연결을 설정하는 데 사용되며, 이를 후킹함으로써 특정 사이트로의 접속을 가로채거나 리디렉션할 수 있음. 또한, ntdll.dll의 ZwResumeThread()는 스레드를 재개하는 함수로, 이를 후킹하여 프로세스의 실행 흐름을 제어하거나 악성 스레드의 행동을 조작할 수 있음. 이러한 API 후킹을 통해 특정 웹사이트 접속을 차단하거나 리디렉션하고, 접속 관련 정보를 수집하는 등의 작업을 할 수 있음. IE 접속 제어의 경우, wininet.dll의 InternetConnectW()와 ntdll.dll의 ZwResumeThread() 같은 API가 후킹 대상이 됨. 이러한 API를 후킹하여 특정 웹사이트 접속을 차단하거나 리디렉션하거나, 심지어 접속 관련 정보를 수집하는 등의 작업을 할 수 있음.
InternetConnectW()는 인터넷 연결을 처리하는 API로, 클라이언트가 특정 서버에 접속할 때 사용됨. 후킹을 통해 연결 정보를 가로채고, 원래 연결하려던 서버 대신 다른 서버로 연결을 유도하는 등 접속 경로를 변경할 수 있음. 또한, 악성 행위 감시 및 제어를 위해 서버 연결을 임의로 변경하는 등의 용도로 사용될 수 있음. 후킹된 API가 적용되면 원본 서버와 통신하는 대신 후킹된 서버로 트래픽을 전송하게 되며, 이로 인해 데이터 전송 내용을 감시하거나 특정 행동을 조작할 수 있음.
ZwResumeThread()는 일시 중지된 스레드를 다시 실행 상태로 전환하는 API로, 프로세스 제어의 중요한 역할을 함. 이 API를 후킹하여 악성코드 분석 시 특정 스레드의 재개 시점을 조작하거나 해당 스레드가 수행하는 작업을 감시할 수 있음. 악성코드가 프로세스를 숨기거나 중요한 작업을 수행할 때 이를 지연시켜 분석 기회를 얻는 데 유용함. 또한, 특정 작업을 강제 중단하거나 재개할 수 있는 기능을 통해 프로그램의 실행 흐름을 원하는 대로 제어할 수 있음.
검증 - IE 프로세스 디버깅
디버깅 도구 사용: 후킹이 제대로 적용되었는지 확인하기 위해 Process Explorer로 현재 로드된 모든 DLL을 모니터링하고, OllyDbg나 x64dbg와 같은 디버깅 도구를 사용해 후킹된 API의 호출 흐름을 추적하는 절차를 수행함. 예를 들어, Process Explorer로 DLL 목록을 확인하고, OllyDbg에서 브레이크포인트를 설정하여 특정 API가 호출될 때 후킹된 함수로 분기되는지를 직접 검증하는 방식임. 또한, 호출된 API의 스택 정보를 통해 후킹이 올바르게 수행되고 있는지 확인함. Process Explorer, OllyDbg, x64dbg와 같은 디버깅 도구를 사용하여 후킹된 함수가 의도한 대로 실행되고 있는지 정확하게 확인함. 이러한 도구들은 프로세스의 메모리, 로드된 모듈(DLL), 스레드 상태 등을 확인할 수 있게 해줌. 후킹된 API가 예상대로 적용되었는지 디버깅 과정을 통해 검증하며, 후킹 후의 동작을 모니터링함으로써 발생할 수 있는 예기치 않은 오류나 문제점을 해결함.
예를 들어 Process Explorer를 사용하여 현재 IE 프로세스가 로드하고 있는 DLL 목록을 확인하고, 후킹된 API가 포함된 DLL(wininet.dll, ntdll.dll 등)이 제대로 로드되었는지 검증함. 후킹 작업 후에는 해당 DLL의 함수 호출이 예상대로 이루어지는지 모니터링하여 후킹 결과를 확인함. 또한, x64dbg를 사용해 브레이크포인트를 설정하고 후킹된 함수가 제대로 호출되는지, 그 흐름이 어떻게 변하는지를 관찰함. 이는 후킹 과정에서 발생할 수 있는 오류를 최소화하고 예상하지 못한 동작을 미리 방지하기 위함임.
OllyDbg를 사용한 후킹 검증: 후킹한 함수의 주소로 분기되는지 확인함. 특히 ZwResumeThread()와 같은 함수가 호출될 때 설정된 브레이크포인트가 트리거되는지를 관찰하여 후킹의 성공 여부를 판단함. 이를 통해 후킹한 코드가 올바르게 실행되고 있는지, 그리고 예상대로 후킹 동작을 제어하고 있는지를 확인할 수 있음. 후킹된 함수가 의도한 대로 동작하지 않을 경우, 원인을 파악하고 후킹 로직을 수정해야 함. 예를 들어, 함수의 시작 지점에 적절한 JMP 명령어가 삽입되었는지, 후킹된 코드로의 흐름이 제대로 이어지는지를 확인하여 문제 발생 시 해결책을 마련함.
IE 프로세스 구조
Internet Explorer는 네트워크 연결, 콘텐츠 다운로드 및 렌더링을 위해 여러 개의 DLL을 로드하여 사용함. 예를 들어, wininet.dll은 네트워크 연결을 관리하고, urlmon.dll은 URL 관련 처리를 담당함. ntdll.dll은 시스템 레벨의 함수를 제공하여 기본적인 운영체제와의 인터페이스 역할을 함. 각 모듈은 특정 기능을 수행하며, 후킹을 통해 각 모듈에서 수행되는 기능을 조작하거나 감시할 수 있음. 이러한 DLL 구조는 IE가 웹 콘텐츠를 효율적으로 다운로드하고 렌더링할 수 있도록 지원하며, 이를 통해 웹사이트의 동작을 분석하거나 조작하는 데 활용될 수 있음.
IE 프로세스의 모듈 구조: IE는 다양한 기능을 수행하기 위해 여러 개의 모듈을 로드함. wininet.dll은 HTTP, FTP 등의 프로토콜 처리를 담당하며, 후킹을 통해 이러한 프로토콜 사용을 제어할 수 있음. 예를 들어, InternetConnectW() 후킹을 통해 특정 사이트로의 접속을 다른 사이트로 리디렉션하는 방식으로 네트워크 트래픽을 조작할 수 있음. 이러한 조작을 통해 악성 트래픽을 차단하거나 특정 사이트로의 접근을 제한할 수 있음. 후킹은 IE 프로세스 내에서 호출되는 API의 동작을 바꾸거나 그 호출을 가로채어 사용자의 의도대로 조작할 수 있는 중요한 기술임. 이러한 후킹을 통해 네트워크 접근을 제어하고 특정 조건을 기반으로 한 트래픽 필터링을 수행할 수 있음. 예를 들어, 특정 키워드가 포함된 요청을 차단하거나 특정 사이트로만 트래픽을 제한하는 방식으로 활용 가능함.
또한, urlmon.dll을 후킹함으로써 콘텐츠 다운로드를 제어하고, 특정 파일 형식의 다운로드를 차단하거나 특정 파일만 다운로드하도록 유도할 수 있음. 이러한 방식은 보안 위협으로부터 사용자를 보호하거나, 관리자가 허용하는 콘텐츠만 접근하게 하는 데 유용하게 사용됨. 후킹을 통해 API가 반환하는 데이터를 변조하거나, 그 동작을 수정함으로써 원하는 제어를 달성할 수 있음
글로벌 API 후킹 개념 정리
글로벌 API 후킹은 시스템 전체에서 발생하는 특정 API 호출을 가로채는 기술임. 단일 프로세스에서만 작동하는 로컬 후킹과 달리, 글로벌 후킹은 시스템 전반에 걸쳐 모든 프로세스에 동일한 후킹을 적용함. 이 방법을 사용하면 시스템에서 발생하는 특정 이벤트를 전역적으로 제어하거나 감시할 수 있음. 예를 들어 네트워크 관련 API가 모든 프로세스에서 호출될 때 이를 가로채어 트래픽을 통제하거나 로그를 남기는 작업을 수행할 수 있음.
예를 들어, SetWindowsHookEx() 함수를 사용해 키보드 후킹을 설정하면, 모든 프로세스에서 발생하는 키 입력을 가로챌 수 있음. 이를 통해 사용자가 입력하는 모든 키보드 입력을 감시하거나 필요에 따라 특정 키 입력을 차단하는 등의 동작을 수행할 수 있음. 이처럼 글로벌 후킹은 보안 소프트웨어에서 키로깅 방지, 네트워크 모니터링 등을 위해 사용되며, 시스템 전역의 행위를 감시할 수 있어 매우 강력한 기능을 제공함. 특히 악성 행위를 차단하거나, 특정 동작을 전체적으로 금지할 때 매우 유용하게 사용됨
글로벌 API 후킹의 구체적인 적용 예시: 예를 들어, 기업의 네트워크 보안을 강화하기 위해 모든 HTTP 요청을 감시하고, 비인가된 사이트로의 접근을 차단하는 글로벌 후킹을 구현할 수 있음. 이러한 방식은 보안 정책을 중앙에서 강제하고 네트워크 사용을 통제하는 데 매우 효과적임. 또한, 시스템 관리자가 전체 네트워크 사용 패턴을 분석하고 이상 행동을 감지하는 데 유용함. 이를 통해 특정 사용자가 허가되지 않은 프로그램을 실행하려는 시도를 막거나, 비정상적인 네트워크 활동을 탐지할 수 있음
후킹은 프로세스의 메모리 구조를 수정하고, 특정 API 호출이 후킹된 코드로 분기되도록 조작함으로써 이루어짐. 이를 통해 후킹된 코드는 API 호출 시점에 원본 호출을 제어하거나 다른 동작을 수행할 수 있음. 이를 통해 네트워크 요청을 차단하거나 스레드의 실행을 지연시키는 등의 다양한 조작을 수행할 수 있음. 예를 들어, SendMessage()와 같은 윈도우 메시지 처리 함수를 후킹하여 특정 키 입력이 발생할 때마다 사용자에게 경고 메시지를 출력하거나, 네트워크에 기록을 남기는 방식으로 활용할 수 있음.
일반적인 API 후킹
일반적인 API 후킹은 특정 프로세스의 특정 API를 후킹하는 것을 의미함. 이 경우 후킹은 특정 애플리케이션 내에서만 유효하며, 그 애플리케이션의 행위만을 제어하는 데 중점을 둠. 주로 디버깅이나 악성코드 분석, 특정 프로그램의 동작 수정 등 특정 목적을 위해 사용됨. 일반적인 후킹은 프로세스의 일부 기능을 감시하거나, 필요한 경우 그 기능을 변경하는 방식으로 사용됨.
후킹 방법
IAT(Import Address Table) 수정: 프로세스가 사용하는 함수 주소를 가지고 있는 IAT를 수정하여 원하는 함수로 대체함. 이를 통해 특정 DLL의 함수가 호출될 때 원본 함수가 아닌 후킹된 함수가 호출되도록 만듦. IAT 수정은 특정 DLL이 로드될 때 그 주소를 변경함으로써, 원래 의도한 동작을 후킹 함수로 바꿀 수 있음. 이러한 방법은 비교적 간단하면서도 효과적임. 예를 들어, 특정 애플리케이션에서 MessageBoxW() 호출을 후킹하여, 모든 메시지 창에 추가적인 정보를 표시하도록 하는 등의 작업이 가능함.
프롤로그 덮어쓰기: API 함수의 시작 부분을 덮어써서 원본 호출을 가로채는 방식임. 주로 JMP 명령어를 사용해 호출 흐름을 후킹 코드로 보내는 방식으로 구현됨. 이를 통해 함수가 호출될 때 항상 후킹된 코드로 흐름이 이동하며, 후킹된 코드에서 원본 함수를 호출하거나 해당 호출을 변경함. 프롤로그 덮어쓰기는 메모리 보호 속성을 변경해야 하기 때문에 관리 권한이 필요함. 예를 들어, JMP 명령어를 사용하여 함수 시작 부분에 후킹된 함수의 주소로 점프하도록 수정하면, 해당 API 호출은 후킹된 함수로 이동하게 됨. 이 과정에서 원래 함수의 일부 바이트를 백업하고 후킹 해제 시 복원하는 작업이 필요함
그렇담.. 글로벌 후킹은..
글로벌 API 후킹
글로벌 후킹은 시스템 전체에 걸쳐 API를 후킹하는 방식으로, 여러 프로세스에서 공통적으로 발생하는 특정 동작을 제어할 때 사용됨. 예를 들어, 특정 키보드 입력에 대한 감시나 시스템 전역의 네트워크 활동을 추적하기 위해 사용됨. 시스템의 모든 애플리케이션에서 발생하는 API 호출을 감시하고, 이를 통해 전역적인 보안 정책을 적용할 수 있음. 특히 시스템 내의 모든 HTTP 트래픽을 감시하여 악성 웹사이트로의 접근을 차단하거나 모든 키보드 입력을 기록하여 보안 감사 로그를 생성하는 등의 작업을 수행할 수 있음.
구현 방식: SetWindowsHookEx() API를 사용하여 특정 이벤트(예: 키보드, 마우스 입력)를 후킹하고, 이를 처리하는 후킹 함수를 시스템 전역에 적용함. 이를 통해 시스템 전체에서 동일한 동작을 가로채거나 특정 처리를 추가함. 후킹된 API 호출은 후킹된 함수로 전달되어 동작을 변경하거나 추가적인 처리를 수행함. 이러한 방식은 보안 소프트웨어가 전체 시스템을 보호하고, 불법적인 사용이나 악의적인 행동을 감시하는 데 유용함.
적용 예시: 보안 프로그램에서 특정 사이트 접속을 차단하거나 모든 프로세스의 파일 접근을 모니터링하는 등의 기능을 수행할 때 유용하게 사용됨. 글로벌 후킹은 모든 프로세스의 행위를 통제할 수 있기 때문에 강력하지만, 시스템 자원 소모가 크고 잘못 구현하면 시스템 불안정을 초래할 수 있음. 또한, 악성 행위를 수행하기 위해 이러한 후킹 기법이 악용될 수 있으므로 보안적인 측면에서 주의가 필요함. 예를 들어, 악성코드가 글로벌 후킹을 통해 모든 네트워크 요청을 가로채고 민감한 정보를 탈취하는 데 악용될 수 있음. 이러한 위험성을 최소화하기 위해 후킹 코드의 안전성을 높이고, 필요할 경우 사용자에게 알림을 주는 방식으로 투명성을 유지해야 함.
ntdll!ZwResumeThread() API
- ZwResumeThread()는 일시 중지된 스레드를 다시 실행 상태로 복귀시키는 함수임. 이 API는 프로세스의 스레드 제어에 있어 중요한 역할을 함. 예를 들어 디버깅 목적으로 특정 스레드를 일시 정지시키거나, 악성 코드의 실행 흐름을 중단하고 분석하는 데 사용됨. 후킹을 통해 이 API 호출 시점을 가로채어 스레드가 언제 실행될지를 조작할 수 있음.
- 후킹 활용: 후킹을 통해 스레드가 재개되는 시점을 조작하여 원치 않는 동작을 막거나, 분석 목적에 맞게 동작을 지연시킬 수 있음. 특히 악성코드 분석 시, 악성코드가 실행되는 스레드를 잠시 중단한 후 그 스레드가 하는 작업을 모니터링하거나, 행동을 변경하는 데 유용하게 사용됨. 악성코드가 중요한 정보를 외부로 유출하려는 시도나 프로세스를 조작하는 동작을 할 때 이를 지연시키거나 차단함으로써 보안성을 높일 수 있음. 또한, 사용자 몰래 실행되는 백그라운드 스레드를 조작하여 악의적인 행동을 막을 수 있음
실습 예제 - IE 접속 제어
IE 실행: Internet Explorer를 실행하고 특정 DLL을 인젝션하여 API 후킹을 통한 동작을 제어함 이를 통해 사용자가 특정 웹사이트에 접속하는 것을 제어하거나, 특정 사이트로 리디렉션할 수 있음 특히 보안 목적으로 허용되지 않은 사이트로의 접속을 막거나, 모든 트래픽을 특정 모니터링 서버로 리디렉션하는 데 사용될 수 있음 이를 통해 기업 네트워크 환경에서 비인가된 사이트 접속을 통제하거나 사용자의 네트워크 사용을 모니터링할 수 있음
DLL 인젝션: 후킹을 위해 DLL을 타깃 프로세스에 인젝션함 DllMain() 함수에서 DLL_PROCESS_ATTACH 이벤트를 이용해 후킹 작업을 수행함 DLL 인젝션 방법으로는 다양한 기법이 있지만, 주로 CreateRemoteThread()를 사용하거나 AppInit_DLLs 레지스트리 키를 사용하는 방법이 있음 이러한 방법을 통해 특정 프로세스의 실행 시점에 후킹을 시작할 수 있음 또한, 프로세스에 접근 권한을 부여하여 런타임 중 동적으로 후킹을 적용할 수 있음
새로운 탭 생성 및 포털 사이트 접속: 후킹된 상태에서 IE에서 새로운 탭을 열어 포털 사이트(예: 네이버, 다음 등)에 접속을 시도함 이때 InternetConnectW() API를 후킹하여, 사용자가 특정 사이트에 접속하려는 시도를 다른 사이트(www.reversecore.com)로 리디렉션함 이 과정에서 사용자는 원래 의도한 사이트가 아닌 후킹된 서버로 연결되며, 이를 통해 트래픽을 감시하거나 차단할 수 있음 이를 통해 사용자가 접속하는 모든 사이트를 제어하고, 보안 정책에 따라 적절히 제한함으로써 보다 안전한 인터넷 사용 환경을 제공할 수 있음
추가 실습: 여러 개의 탭을 열어 다양한 사이트에 접속하면서 후킹된 API의 작동을 테스트함 후킹된 ZwResumeThread()를 사용하여 스레드의 실행을 조작하고, 이를 통해 특정 작업의 실행 타이밍을 지연시키거나 중단함 예를 들어, 특정 스레드가 중요 작업을 수행하기 전에 해당 스레드를 중단시켜 메모리 상태를 확인하거나, 다른 스레드의 작업 결과를 바탕으로 실행을 재개하는 식으로 제어함 이러한 후킹 동작은 악성코드 분석, 보안 프로그램 개발 등 다양한 실무 환경에서 활용될 수 있음 또한, 실시간으로 실행 흐름을 조작함으로써 특정 기능을 테스트하거나, 보안 취약점을 찾아내기 위한 시나리오를 적용하는 등 다양한 응용 가능성을 가짐
네트워크 트래픽 리디렉션 예시: 실습 예제에서 InternetConnectW()를 후킹함으로써 사용자가 접속하는 네트워크 트래픽을 특정 서버로 리디렉션하는 기능을 구현함 예를 들어, 사용자가 네이버에 접속하려고 할 때, 이를 reversecore.com으로 리디렉션하여 네트워크 트래픽을 분석하거나 감시할 수 있음 이를 통해 특정 웹사이트 접속을 차단하거나 사용자를 안전한 사이트로 유도할 수 있음 또한, 이러한 후킹을 통해 사용자의 네트워크 활동을 모니터링하고 보안 위협을 예방하는 데 도움이 됨
ZwResumeThread()를 활용한 스레드 제어: ZwResumeThread() API를 후킹하여 프로세스 내의 스레드 동작을 제어함 이를 통해 특정 스레드가 재개되기 전이나 후에 추가적인 작업을 수행하도록 설정할 수 있음 예를 들어, 특정 스레드가 민감한 작업을 수행하기 전, 후킹된 코드에서 스레드의 메모리 상태를 덤프하거나, 로그를 남겨 분석할 수 있음 이는 악성코드가 특정 시점에서 실행되는 것을 지연시키거나 해당 스레드의 행위를 조작함으로써 악성 행위를 차단하는 데 유용하게 활용될 수 있음
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
// 프로세스가 시작될 때 후킹을 수행함
hook_by_code("ntdll.dll", "ZwResumeThread", (PROC)NewZwResumeThread, g_pZWRT)
hook_by_code("wininet.dll", "InternetConnectW", (PROC)NewInternetConnectW, g_pICW)
break
case DLL_PROCESS_DETACH:
// 프로세스가 종료될 때 후킹을 해제함
unhook_by_code("ntdll.dll", "ZwResumeThread", g_pZWRT)
unhook_by_code("wininet.dll", "InternetConnectW", g_pICW)
break
}
return TRUE
}
위의 코드에서 DLL_PROCESS_ATTACH는 DLL이 프로세스에 로드될 때 호출되며, 이때 후킹을 설정함 ZwResumeThread와 InternetConnectW를 후킹하여 스레드와 네트워크 연결을 제어함
DLL_PROCESS_DETACH는 DLL이 언로드될 때 호출되며, 이때 후킹을 해제하여 원래의 동작으로 복원함 이를 통해 프로세스 종료 시 시스템 안정성을 유지함
추가 후킹 시나리오: 후킹 기술을 활용하여 특정 조건에서만 후킹된 코드를 실행하는 방식으로 조건부 후킹을 구현할 수 있음 예를 들어, 사용자가 특정 프로그램을 실행할 때만 후킹을 활성화하거나, 특정 네트워크 트래픽이 감지될 때만 후킹을 수행하여 불필요한 자원 소모를 줄이고 보안성을 높일 수 있음 이러한 조건부 후킹은 보안 소프트웨어의 효율성을 높이는 데 매우 유용하게 활용될 수 있음
보안 측면에서의 응용..? 후킹 기술을 보안 측면에서 활용할 수 있는 다양한 방안이 존재함 예를 들어, 사용자가 의도하지 않은 악성 웹사이트에 접속하려고 할 때 이를 탐지하고 안전한 사이트로 리디렉션하거나, 악성 스레드가 특정 작업을 수행하지 못하도록 스레드 실행을 중지시킬 수 있음 이를 통해 사용자의 시스템을 보호하고 네트워크 보안을 강화하는 데 후킹 기술이 중요한 역할을 할 수 있음
위에 예제들같은거 뭐냐 저런 후킹 실습 예제는 후킹 기술의 기본적인 개념뿐만 아니라 이를 실무에서 어떻게 활용할 수 있는지를 보여줌 후킹 기술은 강력한 도구로, 네트워크 보안, 악성코드 분석, 소프트웨어 디버깅 등 다양한 분야에서 활용 가능함 후킹의 구현 및 적용 시에는 시스템의 안정성과 보안성을 유지하기 위한 신중한 접근이 필요하며, 잘못된 후킹은 시스템에 예기치 않은 오류를 발생시킬 수 있으므로 반드시 충분한 테스트와 검증을 거쳐야 함..
내용정리랑 시ㄹ습이랑 같이 못하겠음 ㅠㅠ 정신사납다
그 머냐 일단 가상머신에서 돌렸음 윈도우 7..
그거 IE 알아내고 API 형태 보면된다.
그러고 나서 올리디버거로 wininet.InternetConnectW()API에 BP 설정함. 그냥 정처없이 떠돌거나.. 검색하거나..
아무튼 이런식으로 나옴 여기다가 설치하고 나서
사이트 접속 시도하면 BP 걸리는거 볼 수 ㅣㅇㅆ다. 대충 BP설정한거 맞았다는 거겠져 머?
그러고 나서 스택창에도 쌓이는데 그 주소에서 다른데 내가 이동하고싶은데로 덤프에서 edit해보면 글로 이동하는 것 ㄱ까지 확인 가능함.
IE 접속 제어 실습
예제파일에서 IE 프로세스가 포털사이트 들어갈때 다른사이트로 들어가도록 후킹한거
이거 확인해보면 원래 네이버 들어가려던거를 reversecore.com
오 일로 이동한다. 와우
소스코드
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
char szCurProc[MAX_PATH] = {0,};
char *p = NULL;
switch( fdwReason )
{
case DLL_PROCESS_ATTACH :
DebugLog("DllMain() : DLL_PROCESS_ATTACH\n");
GetModuleFileNameA(NULL, szCurProc, MAX_PATH);
p = strrchr(szCurProc, '\\');
if( (p != NULL) && !_stricmp(p+1, "iexplore.exe") )
{
DebugLog("DllMain() : current process is [iexplore.exe]\n");
// wininet!InternetConnectW() API 를 후킹하기 전에
// 미리 wininet.dll 을 로딩시킴
if( NULL == LoadLibrary(L"wininet.dll") )
{
DebugLog("DllMain() : LoadLibrary() failed!!! [%d]\n",
GetLastError());
}
}
// hook
hook_by_code("ntdll.dll", "ZwResumeThread",
(PROC)NewZwResumeThread, g_pZWRT);
hook_by_code("wininet.dll", "InternetConnectW",
(PROC)NewInternetConnectW, g_pICW);
break;
case DLL_PROCESS_DETACH :
DebugLog("DllMain() : DLL_PROCESS_DETACH\n");
// unhook
unhook_by_code("ntdll.dll", "ZwResumeThread",
g_pZWRT);
unhook_by_code("wininet.dll", "InternetConnectW",
g_pICW);
break;
}
return TRUE;
}
이거는 DllMain임
ZwResumeThrea()API랑 internetConnectW API있는거 볼 수 있다
핫패치는안된다~~
HINTERNET WINAPI NewInternetConnectW
(
HINTERNET hInternet,
LPCWSTR lpszServerName,
INTERNET_PORT nServerPort,
LPCTSTR lpszUsername,
LPCTSTR lpszPassword,
DWORD dwService,
DWORD dwFlags,
DWORD_PTR dwContext
)
{
HINTERNET hInt = NULL;
FARPROC pFunc = NULL;
HMODULE hMod = NULL;
// unhook
if( !unhook_by_code("wininet.dll", "InternetConnectW", g_pICW) )
{
DebugLog("NewInternetConnectW() : unhook_by_code() failed!!!\n");
return NULL;
}
// call original API
hMod = GetModuleHandle(L"wininet.dll");
if( hMod == NULL )
{
DebugLog("NewInternetConnectW() : GetModuleHandle() failed!!! [%d]\n",
GetLastError());
goto __INTERNETCONNECT_EXIT;
}
pFunc = GetProcAddress(hMod, "InternetConnectW");
if( pFunc == NULL )
{
DebugLog("NewInternetConnectW() : GetProcAddress() failed!!! [%d]\n",
GetLastError());
goto __INTERNETCONNECT_EXIT;
}
if( !_tcsicmp(lpszServerName, L"www.naver.com") ||
!_tcsicmp(lpszServerName, L"www.daum.net") ||
!_tcsicmp(lpszServerName, L"www.nate.com") ||
!_tcsicmp(lpszServerName, L"www.yahoo.com") )
{
DebugLog("[redirect] naver, daum, nate, yahoo => reversecore\n");
hInt = ((PFINTERNETCONNECTW)pFunc)(hInternet,
L"www.reversecore.com",
nServerPort,
lpszUsername,
lpszPassword,
dwService,
dwFlags,
dwContext);
}
else
{
DebugLog("[no redirect]\n");
hInt = ((PFINTERNETCONNECTW)pFunc)(hInternet,
lpszServerName,
nServerPort,
lpszUsername,
lpszPassword,
dwService,
dwFlags,
dwContext);
}
__INTERNETCONNECT_EXIT:
// hook
if( !hook_by_code("wininet.dll", "InternetConnectW",
(PROC)NewInternetConnectW, g_pICW) )
{
DebugLog("NewInternetConnectW() : hook_by_code() failed!!!\n");
}
return hInt;
}
NewInternetConnectW() API이다..
IpszServerName이 지정한 포털 문자열이랑 맞으면 아까 그 리버싱핵심원리 사이트로 변ㄱ경하는거임
NTSTATUS WINAPI NewZwResumeThread(HANDLE ThreadHandle, PULONG SuspendCount)
{
NTSTATUS status, statusThread;
FARPROC pFunc = NULL, pFuncThread = NULL;
DWORD dwPID = 0;
static DWORD dwPrevPID = 0;
THREAD_BASIC_INFORMATION tbi;
HMODULE hMod = NULL;
TCHAR szModPath[MAX_PATH] = {0,};
DebugLog("NewZwResumeThread() : start!!!\n");
hMod = GetModuleHandle(L"ntdll.dll");
if( hMod == NULL )
{
DebugLog("NewZwResumeThread() : GetModuleHandle() failed!!! [%d]\n",
GetLastError());
return NULL;
}
// call ntdll!ZwQueryInformationThread()
pFuncThread = GetProcAddress(hMod, "ZwQueryInformationThread");
if( pFuncThread == NULL )
{
DebugLog("NewZwResumeThread() : GetProcAddress() failed!!! [%d]\n",
GetLastError());
return NULL;
}
statusThread = ((PFZWQUERYINFORMATIONTHREAD)pFuncThread)
(ThreadHandle, 0, &tbi, sizeof(tbi), NULL);
if( statusThread != STATUS_SUCCESS )
{
DebugLog("NewZwResumeThread() : pFuncThread() failed!!! [%d]\n",
GetLastError());
return NULL;
}
dwPID = (DWORD)tbi.ClientId.UniqueProcess;
if ( (dwPID != GetCurrentProcessId()) && (dwPID != dwPrevPID) )
{
DebugLog("NewZwResumeThread() => call InjectDll()\n");
dwPrevPID = dwPID;
// change privilege
if( !SetPrivilege(SE_DEBUG_NAME, TRUE) )
DebugLog("NewZwResumeThread() : SetPrivilege() failed!!!\n");
// get injection dll path
GetModuleFileName(GetModuleHandle(STR_MODULE_NAME),
szModPath,
MAX_PATH);
if( !InjectDll(dwPID, szModPath) )
DebugLog("NewZwResumeThread() : InjectDll(%d) failed!!!\n", dwPID);
}
// call ntdll!ZwResumeThread()
if( !unhook_by_code("ntdll.dll", "ZwResumeThread", g_pZWRT) )
{
DebugLog("NewZwResumeThread() : unhook_by_code() failed!!!\n");
return NULL;
}
pFunc = GetProcAddress(hMod, "ZwResumeThread");
if( pFunc == NULL )
{
DebugLog("NewZwResumeThread() : GetProcAddress() failed!!! [%d]\n",
GetLastError());
goto __NTRESUMETHREAD_END;
}
status = ((PFZWRESUMETHREAD)pFunc)(ThreadHandle, SuspendCount);
if( status != STATUS_SUCCESS )
{
DebugLog("NewZwResumeThread() : pFunc() failed!!! [%d]\n", GetLastError());
goto __NTRESUMETHREAD_END;
}
__NTRESUMETHREAD_END:
if( !hook_by_code("ntdll.dll", "ZwResumeThread",
(PROC)NewZwResumeThread, g_pZWRT) )
{
DebugLog("NewZwResumeThread() : hook_by_code() failed!!!\n");
}
DebugLog("NewZwResumeThread() : end!!!\n");
return status;
}
이거는 NewZwResumeThread() API..
앞에거 Zw어쩌구로 만들어지는 프로세스 PID 계산하고 그거 가지고 redirect.dll을 삽입한다. 그리고 나서 Zw어쩌구 다시 호출해서 후킹된걸로 실행ㄷ되게하는 거..