2011.12.24 13:49 System

[+]Introduction


아주 간만에 포스팅입니다.

1,2주 안하다보니 한달이 되고 두달이 되고..

 

<Fig0. 하라는 공부는 안하고!>

좀 더 심도있는 내용을 올리고 싶었는데 그게 또 핑계거리가 되서 블로그에 글을 안쓰고 있네요.

그래서 간단한 내용이라도 올리고자 합니다.

Global Hooking 을 거는 손쉬운 방법으로는 SetWindowHookEx가 있죠.

Windows 에서 자동으로 Injection을 시켜주기 떄문에 Process의 생성을 catch 해서 따로 Injection 해줄필요도 없구요.

이 부분에 관해서는 Reversecore님 Blog에 아주 자세히 설명되어있기 떄문에 참조하시길 바랍니다.

제가 이번에 쓸 내용은 SetWindowsHookEX를 이용해서 Hooking 을 걸고 UnHookWindowHookEx를 이용하여 해제했는데도 

박혀있는 DLL 을 강제로 Ejection 시키는 방법입니다.

[ 추후 UnHookWindowsHookEx를 이용하지 않고 Hooking을 해제하는 방법도 올리도록 하겠습니다 :D 

Windows7 에 올라와서 물리 메모리에 접근하는게 좀 까다로워져서 고생중이네요. Driver 없이 User 모드에서 가능한지를 살펴보고 있습니다

XP는 되는데 음.. ]



[+]Problem



UnHookWindowsEx만 호출한 경우 대부분의 Process에서는 DLL이 Ejection 되지 않습니다.

[ 물론 해제가 되는 Process도 있습니다. Process 내부에서 Message 처리를 열심히 하는 녀석들이죠.

대부분 UI 가 사용자에게 보여지고 있는 상태의 녀석들이구요. ]

보통 UnHook 후에 SendMessage 를 Broadcasting 하게 뿌려서 Process에 해제하게 되죠.

이 Message는 의미있는 Message 일 필요는 없습니다. 

Message가 오면 Hook Chain을 알아서 갱신하니까요.

아무튼 이렇게 Message 를 뿌려줘도 DLL이 빠지지 않는 Process가 존재하게 됩니다.

대표적으로 AdobeARM.exe Chrome의 Rundll32.exe가 있죠.

물론 항상 빠지지 않는건 아니고 간혹 빠지지 않는 현상을 보게 됩니다.

이런 Process들은 대부분 단일 Thread라는 점을 확인할 수 있는데요.

정리하자면

1. UnHook할 때는 Message를 뿌려서 받은 Process들은 해제가 된다.

2. UnHook 되지 않는 녀석들은 대부분 단일 Thread이다.

3. 위 Process 들도 항상 DLL이 Ejection 안되는건 아니다.

이 부분에서 문제점을 유추할 수 있습니다. 

Process에 외부에서 들어온 Message를 처리할 Thread가 없으면 DLL이 Ejection 되지 않는다.

라는 점입니다.



[+]Solution


그렇다면 위 문제는 어떻게 해결해야 할까요?

많은 분들이 FreeLibrary를 CreateRemoteThread를 이용해서 삽입하는 방법을 생각하셨을겁니다.

흠, 하지만 이 방법에는 문제점이 있는데

FreeLibrary시에 해당 DLL에 접근하고 있는 Thread가 있으면 그대로 프로그램이 뻗어버린다는 것이죠.

DLL Unload 뭐 이런 Error가 났던걸로 기억합니다.

결국 DLL이 자동으로 Ejection 되게 하려면 Message를 처리하도록 만들어야한다는거죠.

Message 처리 루틴 Thread를 Process에 삽입하고 다시 Message를 보내볼까요?

너무 번거롭습니다.

생각해보면 Process 자체에서 Ejection 해주는게 아님을 파악할 수 있습니다.

빈 Message를 받았을 때 Hook Chain에 없는 DLL을 빼주는게 Process 자체 역할을 아니니까요.

Process는 단순히 Message를 받는 것이고 이 때 발생한 특정 Event를 Windows에서 받고 Ejection 해준다고 판단 내릴 수 있겠군요.

그렇다면 직접 Message를 발생시키면 어떨까요?

Code Injection을 통해서 DLL이 빠지지 않는 Process에서 Message를 발생하도록 하는거죠.

아래 Code Inejction Code는 Reversecore님의 Code를 상당부분 인용했습니다.

http://www.reversecore.com/82 

먼저 사용할 함수를 정의합니다.




다음은 실행코드입니다.

함수 호출에 필요한 String을 먼저 삽입하고 그곳을 참조하는 방법입니다.



SendMessage를 쓰기 보다 SendMssageTimeOut을 썼고

Parameter 간소화를 위해 Broadcasting을 합니다.

위와 같은 방법을 이용하면 DLL이 정상적으로 잘 Ejection되는 것을 확인하실 수 있을겁니다.

어때요 참 쉽죠?


글이 올라온 날이 12월 24일이라는 건 신경안쓰셔도 됩니다








Posted by LinkC

2010.08.03 19:24 System

얼마전에 ReverseCore님께서 Windows 7 에서 Injection 하는 방법을 포스팅 하셨죠

얼마전이라기 보단 꽤 됐지만..

http://www.reversecore.com/73

굉장히 정리가 잘되어있으니 한번 보시면 큰 도움이 될겁니다 :D

아무튼 요는 Windows7 에서 Session 관리 정책이 변경되면서

CreateRemoteThread()가 먹히지 않게 되었고

ntdll!ZwCreateThreadEx()를 직접 호출함으로써 해결 할 수 있다는 것입니다

하지만 이 방법도 64bit 에서는 되지 않더군요

64bit OS에 Global API Hooking을 할 때 , 이건 문제가 되겠죠

64bit process를 차근차근히 보시면  , 64bit 에는 64bit dll만 로드 되어 있는 것을 볼 수 있습니다



그림1. 64bit Process 내에 Load 되어 있는 kernel32.dll 의 정보


*32bit process 에서 사용 되는 시스템 dll 의 경우 syswow64 폴더의 dll을 쓰게 됩니다


그림2. 32bit Process 내에 Load 되어 있는 kernel32.dll 의 정보

그리고 이 64bit dll 을 Injection 할 때 32bit Program 으로는 되지 않는 것 까지 확인했습니다


그림3. 32bit Program 에서 64bit dll 을 Injection 할 때 실패하는 모습



64bit dll 을 Injection 할 때는 64bit Program 이 필요한게 아닌가 싶었습니다

64bit 로 컴파일 하여 시도해보니


그림4. 64bit Process 내에 성공적으로 Injection 된 모습

네, 제대로 Injection 이 성공한 것을 볼 수 있습니다

즉, 64Bit Process 에 Injection 을 하고자 하면

64Bit Injection Program 으로 64Bit dll 을 Injection 해야 한다


는 것이 이 포스팅의 요입니다

고로 , Global API hooking 등을 하고자 할 때는

64bit용, 32bit 용으로 나눠

32bit injection program, 32bit dll

64bit injection program, 64bit dll

이렇게 제작해야 올바르게 작동합니다

64bit dll 은 64bit로

아, 어찌보면 정말 당연한 건지도 모르겠지만

처음에 부딪혔을 때는 왜안되나 했네요 :D



How to Compile a 64bit application or dll?

64bit 용 dll 과 application을 얻고자 하신다면

64bit 용으로 compile 하셔야 합니다

찾아보니 대략 2가지 정도가 있던데요

물론 더 있는데 제가 못본거겠지만..

Microsoft Platform SDK 의 64bit Build Enviorment 를 이용하시는 방법과

Visual Studio 2005 이상의 버전을 이용하시는 법이 있습니다

전자의 경우 Visual Studio 6에서도 적용가능한 방법이지만

MakeFile 을 작성해서 64bit Build Enviroment 창에서 Compile을 시키는 형태입니다

필자의 경우 후자의 경우가 더 편해보여서 이를 이용했습니다

다만, Visual Studio 설치 시 별달리 건드린게 없으시다면

64bit Compile Tool 이 깔려있지 않을 겁니다

그런분은 제어판의 프로그램 추가/제거에서 Visual Studio 2005 이상의 버전을 누르셔서

메뉴를 보시면~

다음과 같이 x64 Compilers and Tools를 발견하실수 있습니다

이를 체크하시고 설치하시면 됩니다 :D




이 설정을 해 주셨다면 Visual Studio 를 실행하시고

Compile 시에 상단의



Platform 의 new 부분에 들어가셔서

x64로 설정하시면 됩니다

다만, Compile 시에 64bit 와 32bit 의 차이점은 고려하셔야 겠죠? :D



'System' 카테고리의 다른 글

DLL Hijaking Exploit in Windows Movie Maker  (0) 2010.09.06
Memory protection mechanisms in Windows  (4) 2010.08.17
DLL injection on 64 Bit OS  (2) 2010.08.03
Screen Capture with DLL injection  (2) 2010.07.27
서비스 프로그래밍  (3) 2010.04.27
System Information 을 가져오는 API  (2) 2010.04.21
Posted by LinkC

2010.07.27 22:26 System



네 몇몇 분들은 알아보셨을지 모르겠지만

게임 촬영등에 자주 쓰이는 Fraps 란 녀석입니다

어쩌다보니 이 프로그램이 찍는 스크린샷의 방법에 대해 볼 일이 생겼습니다

대략 뒤적거리다 보니 인터넷에서는 이런 소스를 볼 수 있었습니다



문제는 IDirect3DDevice9 인터페이스 참조인 g_pd3dDevice 인데요

보통의 경우 CreateDevice()나 new Device()를 이용하면 됐습니다만

Fraps의 경우, 현재 프로세스에서 대상 프로세스의 Device를 얻어오는 방법이 좀 특이하더군요

화면 전체를 찍는 경우와는 달리 대상 프로세스의 핸들을 얻어와야 했는데

이를 넘기면 오류가 발생합니다

흠 대상 프로세스에서 직접 핸들을 전해주면 해결될텐데 말이죠

Process Explorer로 살펴보다 보니 , 다른 프로세스에 fraps.dll 이 로딩되어 있는 것을 볼 수 있었습니다

 


그러니까 fraps.dll 이 DLL injection 되었다고 볼 수 있죠

아마 Fraps는 fraps.dll 을 injection 하고 대상 프로세스에서 캡처에 필요한 정보를 받은다음

이를 토대로 파일을 생성하는 식일껍니다

실제로 Fraps 를 attach 시킨 후에

kernel32.dll 에 있는 CreateFile에 BP를 걸고 확인해보면

맞다는 것을 볼 수 있죠

그렇다면 Injection 된 dll이 어떤 역할을 하는지

잠깐 살펴보겠습니다

fraps32.dll [ 64bit 에서는 fraps64.dll 이 Injection 되겠죠? ]





뭐 대략 이런 DLL 입니다

아마 Fraps.dll 이 Loading 됨과 동시에 FrapsSetup을 통해서 가능한 Process에 Injection 을 할 겁니다

그리고 Screen shot 이나 동영상 촬영등을 할 때 필요한 단축키들을 잡아내야 하니까

Key Hooking도 하겠죠

의외로 하는일이 많군요

처음보시는 분이라면 ReverseCore님의 강좌를 보고 오시면 좀 더 쉽게 이해하실 수 있을겁니다

http://www.reversecore.com/30

그러니까 요는 Injection 된 프로세스 내부에서 입력된 Key Message 를 후킹한다는 거죠

설정된 키가 아니면 CallNextHookEx 을 통해서 통과시켜주구요

이렇게 잡은 Key 중에서 Screen shot 키를 걸러내서 따라가 보면

다음과 같은 부분을 보실 수 있습니다




OpenFileMapping 이라..

FileMapping는 메모리를 선언하고 선언한 메모리를 두개 이상의 모듈에서 서로 공유하여 사용할 때 쓰는 함수입니다.

기본적인 개념은 메모리를 파일처럼 오픈하고 한쪽에서는 데이터를 기록하고

한쪽에서는 데이터를 읽는 방식으로 데이터를 공유합니다.

서로 다른 모듈이 메모리를 공유할 수 있기 때문에 서로 다른 프로그램에서

데이터를 전송하고 전송 받고자 할 때 주로 사용하고 있습니다.

 즉, Fraps.exe와 Fraps32.dll이 Injection 된 프로그램간에 메모리를 공유하고 있다고 보시면 됩니다.

이를 좀 더 살펴보면 스크린샷 버튼을 눌렀을 때 , Injcetion된 프로그램에서
 
프로그램 내부에서 캡처된 화면의 정보를 Fraps.exe에 전달하고
 
이렇게 모은 정보를 Fraps.exe에서 Createfile을 통해 파일을 완성합니다.


뭐 Fraps는 이런 식입니다

다른 capture 프로그램도 이런 방식을 이용하는지는 모르겠네요

아마 영역을 지정해서 하는 프로그램이라면 DLL injection을 쓰지는 않을 거 같군요 흠흠

이런식으로 Capture를 구현할지는 몰랐네요

정말 배울게 너무나 많군요 :D





'System' 카테고리의 다른 글

Memory protection mechanisms in Windows  (4) 2010.08.17
DLL injection on 64 Bit OS  (2) 2010.08.03
Screen Capture with DLL injection  (2) 2010.07.27
서비스 프로그래밍  (3) 2010.04.27
System Information 을 가져오는 API  (2) 2010.04.21
What is VCP[Virtualized Code Protection]?  (0) 2010.01.29
Posted by LinkC

2010.06.22 18:07 Etc../잡담


한참 Dll injection 쪽 공부하고 있는데

실습 코드가 안먹히더랍니다

제가 코드를 잘못 작성했나 했는데

xp에서 돌려보니 잘 돌아갑니다 -.-

vista 에서 돌아가는 코드도 실험해봤는데

안되더군요


어느 정도 지나면 7에서 dll injection 하는 방법도 나오겠지만

[ 이미 나왔을지도...]

지금까지의 일반적인 injection은 돌아가지 않는거 같습니다

돌아가는 분 있다면 알려주세요 :)



P.S 현재는  reversecore 님께서 관련된 글을 홈페이지에 올리고 있답니다 :D



Reversecore 님께서 이미 7에서 성공하셨고, 그에 관한 포스팅을 하셨습니다

다만, 현재 64bit 에서는 정상 동작하지 않고 있는데요

이 부분은 Reversecore 님께서도 보시고 계시니 조만간 방법이 나올것 같네요~

64bit 에서도 성공하면 모아서 포스팅할 예정입니다 :D
Posted by LinkC
이전버튼 1 이전버튼

블로그 이미지
LinkC

태그목록

Tistory Cumulus Flash tag cloud by BLUEnLIVE requires Flash Player 9 or better.

공지사항

Yesterday73
Today54
Total320,227

달력

 « |  » 2018.10
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      

최근에 받은 트랙백

글 보관함


. .