일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Neural Network
- 삼성
- Python
- 삼성소프트웨어멤버십
- 신경회로망
- 갤럭시탭S8울트라
- 동아리
- 빅데이터
- Bidirectional Associative Memory
- 구글 앱 엔진
- 고려대학교
- BAM
- SSM
- 인공지능
- 증강현실
- Friendship
- 신경망
- 나르왈프레오
- 삼성전자 소프트웨어멤버십 SSM
- 하이퍼바이저
- Google App Engine
- 가상화
- NarwalFreo
- 물걸레로봇청소기추천
- 멤버십
- hopfield network
- 물걸레자동세척로봇청소기
- 패턴 인식
- 패턴인식
- 파이썬
- Today
- Total
정보공간_1
[6기 대구 허정욱] Detours 3.0 Express #2.Class Member Hooking 본문
[6기 대구 허정욱] Detours 3.0 Express #2.Class Member Hooking
알 수 없는 사용자 2014. 9. 13. 03:25#2. Class Member Hooking
Detours 오픈소스를 사용해서의 이로운 점은,
사용자는 내부의 프로세스 전체를 이해하지 않아도, 원하는 서비스를 자신의 프로젝트에 주입 시킬 수 있다는 것입니다.
이전에 사용했던 방식은 API 후킹 방법입니다.
즉 Function후킹방식을 이용하여, 함수의 주소를 가로채는 방식이였습니다.
이번에는 Class Member Function 후킹방법을 알아보겠습니다.
Class Member Function Hooking 하기
지난번의 함수 후킹방식처럼, 클래스도 클래스 멤버함수를 똑같은 방식으로 후킹할 수 있을까요?
먼저 아래와 같은 소스를 Visual Studio에 타이핑합니다.
위의 소스는 아래의 파일을 받으시면 됩니다.
detours_class_hooking.cpp
위의 소스는 아래의 그림과 같습니다.
하나의 HookingTest 클래스를 만들었으며,
test1, test2라는 객체를 생성하는 동시에, 각 객체에 있는 변수 number에 숫자 5와 6을 초기화해줍니다.
여기서 저희는 C++ 기초적인 지식중의 하나인 의문점을 생각해볼 수 있습니다.
test1에 있는 함수와 test2의 함수의 메모리 주소는 과연 같을까요?
만약 같다면, 하나의 Hooking함수로 여러 개의 객체의 멤버함수를 후킹할 수 있을 것입니다.
만약 다르다면 각 객체의 메모리 주소를 컨트롤하여 멤버 함수를 후킹해야 합니다.
먼저다음부터 보여지는 것은 어셈블리 코드가 많이 보일 것입니다.
아래 정도의 어셈블리 명령어를 인지하고 있다면 어셈블리 코드를 쉽게 보실 수 있을 것입니다.
명령어 | 설명 | |
PUSH | (Data Transfer) Push | 오퍼랜드의 내용을 스택에 쌓는다. |
POP | (Data Transfer) Pop | 스택으로부터 값을 뽑아낸다. |
LEA | (Data Transfer) Load Effective Address to Register | 메모리의 오프셋값을 레지스터로 로드 |
CALL | (Control Transfer) Call | 프로시저 호출 |
MOV | (Data Transfer) Move | 데이터 이동(전송) |
EAX | 범용 레지스터 | 함수 리턴값 저장 및 계산에 이용 |
EBX | 범용 레지스터 | 계산속도높이기, 일반적인 값 저장 |
ECX | 범용 레지스터 | 루프 카운터 및 함수의 파라미터로 사용 |
ESP, EBP | 범용 레지스터 | 함수 호출과 스택 연산에 사용 |
EDI | 범용 레지스터 | 데이터 연산의 결과가 저장되는 위치 |
좀 더 많은 명령어를 알고 싶으시면
어셈블리 명령어 정리Visual Studio에서 어셈블리 코드를 보는 방법 중 가장 많이 쓰는 두 가지의 방법을 소개하겠습니다.
한 가지는 출력 파일을 .asm파일로도 출력하는 것입니다.
[1] 현재 프로젝트의 속성을 누릅니다.
[2] 구성속성을 선택
[3] C/C++ 선택
[4] 출력파일선택
[5] 어셈블러 출력 에 디렉토리를 정해 줍니다.
[6] 그리고 가장 오른쪽의 선택 옵션에서 소스코드로된 어셈블리를 선택합니다.
그리고 빌드를 하면 됩니다.
빌드를 하게 되면, 위와 같은 asm파일이 Debug 폴더 안에 있는 것을 볼 수 있습니다.
위와 같이 .asm 파일을 통해서 어셈블리를 확인할 수 있습니다.
다른 한 가지는 디버그 탭에 있는 [디스어셈블리]를 이용하는 것입니다.
[1] 디버그 클릭
[2] 창 클릭
[3] 디스어셈블리 클릭
두 번째 방법을 이용해서 어셈블리를 확인하면, 첫 번째 방법과 달리 메모리 주소값도 나오는 것을 볼 수 있습니다.
우리는 두 번째 방법을 통해 확인한 어셈블리 코드를 통해서 확인할 수 있는 한 가지가 있습니다.
test1 객체에서 부르는 HookingTest 클래스의 주소와
test2 객체에서 부르는 HookingTest 클래스의 주소가 0F9143Dh로 같다는 것을 알 수 있습니다.
이것은 동일한 클래스의 인스턴스가 여러 개가 존재하더라도 해당 클래스의 멤버 함수는 같은 메모리의 주소를 부른다는 것을 의미합니다.
이제 클래스의 멤버함수를 후킹하려면, 색칠한 부분을 이해하셔야 합니다.
위 색칠한 부분은 클래스의 인스턴스의 주소를 ecx에 넣고, 해당 함수를 콜한다는 규칙을 의미합니다.
ecx는 휘발성 메모리이므로 일반 후킹 함수에서 HookingTestFunction함수의 주소값을 알 수가 없습니다.
만약 ecx값이 보존이 된다면, 일반 후킹함수처럼 HookingTestFunction의 주소값을 가지고 우리가 만든 후킹함수로 jmp할 수 있을 것입니다.
이렇게 이해하시면 이제 우리는 일반 함수로 후킹하는 것이 아니라, 클래스의 멤버함수로 후킹을 해야한다는 방법을 생각해볼 수 있습니다.
[위의 어셈블리는 illeft의 이야기 블로그를 참조하였습니다.]
위와 같은 소스코드를 보면, 어셈블리코드로 __asm mov ecs, [this];를 통해서 멤버함수의 주소를 가져오는 것을 알 수 있습니다. 이러한 방식을 통해서 후킹 클래스 멤버함수로 내가 후킹하려고 하는 멤버 함수를 찾을 수 있습니다.
이렇게만 만들어준다면, 이전 #1.API Hooking과 같은 방식으로 후킹을 진행하면 됩니다.
이외에도 Detours에서는 멤버함수 후킹을 할 수 있는 예제를 제공하고 있습니다.
이번에는 클래스 멤버 함수 후킹에 대해 알아보았습니다.
MyHookingJMP는 위의 member.cpp의 방식을 좀 더 이해하기 쉽도록 만든 것입니다.
Detours API의 예제들은 대부분이 위와 같은 방식이며, 어셈블리 코드로 디버깅을 하며 분석해보는 것이 더 빨리 이해가 될 것입니다.
'IT 놀이터 > Elite Member Tech & Talk' 카테고리의 다른 글
[6기 수원 최웅엽] c++ 을 이용한 디자인패턴 (0) | 2014.09.13 |
---|---|
[6기 수원 정재윤] Hardware 기초#2 _ 3D Printer의 세계page.1 (0) | 2014.09.13 |
[6기 대전 민창기] Control System #2 (0) | 2014.09.13 |
[6기 대구 류지현] Window Device Driver #2 (0) | 2014.09.12 |
[6기 강북 홍진우] 64비트 멀티코어 OS#2 - 레지스터 분석 및 역할 (0) | 2014.09.12 |