COM컴포넌트의 객체 멤버함수를 후킹할 일이 생겨 공부했던 부분들을 정리해 본다.
COM
- COM(Component Object Model)이란 한마디로 어떤 프로그램이나 시스템을 이루는 컴포넌트들이 상호 통신할 수 있
도록 하는 메커니즘이라고 할 수 있다.
- 서로 다른 프로세스 혹은 머신 사이에서 어떤 객체를 쉽게 다루기 위한 기술
라고한다^^
COM Interface
위 사진은 IFileOpenDialog의 인터페이스 이다. 가상 멤버함수로 선언된 것들 중 GetResults를 후킹하려 한다.
[참고] 여기서, 인터페이스 이름 FileOpenDialog 앞에 I를 붙인 것을 볼 수 있는 데, MFC에서 CWnd처럼 클래스 이름 앞에 C를 붙이는 것과 마찬가지로 인터페이스는 이름 앞에 I를 붙여서 표현한다.
본격적인 후킹
GetResults는 가상함수이니 vtable에서 offset을 가지고 참조해서 주소를 가져겠죠.
그 offset은 코드를 짠다음 비쥬얼 스튜디오 디버깅을 통해 offset을 찾는 방식을 사용했다.
그 코드는 위 사진 처럼 어셈블리어를 보고 똑같이 코드로 짜주었다.. (무지성으로,,,,)
사실 여기까지는 그렇게 어려운 일이 아니었다.
삽질 시작...
먼저, 왜?어떤 문제 때문에? 삽질을 했는지 요약해 보면 내가 원하는 시나리오는 다음과 같다.
특정 함수를 후킹해서 내가 원하는 함수로 jmp를 하게 한다음 원하는 코드를 실행시켜준 후 원본함수를 call
------
하지만
어셈이 꼬인다
ㅜㅜㅜㅜㅜ
------
예를들어 그림-1처럼 Messagebox를 띄우고, 원본 함수를 Call한다고 가정하자.
그러면 '그림-2'처럼 꼬인다!
이제
이 문제를 해결하기 위해 삽질을 통해 얻어낸 중요한 개념 몇가지를 정리한다.
[*] 첫번째
먼저 우리가 후킹하려는 프로세스는 x64이다.
x64 프로그램을 후킹하기 위해서는 "x64 Calling Convention의 개념"이 엄청 중요하다 !!!
나는 이 64비트 콜링컨벤션 개념을 제대로 알지 못해서 삽질을 엄~청 오래 했다. ㅠㅠ
위 문서를 꼭 정독하는 것을 추천한다!!
[중요] 결론은 함수를 call할때 rcx,rdx,r8,r9,스택.. 이 순으로 간다
[*] 두번째
다음으로 중요한것이 멤버함수를 call할때 ecx에 this 포인터가 들어간다는 것이다.
자세한 내용은 위 사진을 참조!
내 코드가 잘못 된점
이제 멤버함수을 하기 위한 개념은 끝마쳤다. 그러면 내 코드에서 잘못된 점을 보자.
위 사진은 원래 내가 멤버함수인 GetResults를 후킹하기 위해 작성한 코드이다.
후킹된 함수로 들어와서 원본 함수를 call해주는 흐름이다.
결 론
함수 인자로 this포인터를 코드로 넣어줘야하는데 넣어주지 않아서 내부적으로 어셈이 꼬였다.ㅋㅋㅋㅋㅋㅋ
'ETC' 카테고리의 다른 글
LLVM 난독화 (feat. 기법 3가지) (0) | 2022.01.26 |
---|---|
COM(Component Object Model)의 개념 잡기 (0) | 2021.11.21 |
OSCP 준비] cheat sheet (0) | 2021.09.25 |
[할 일] 앱이 실행되는 과정 분석 (apk데이터를 어떻게 EP까지 로드하는지) (0) | 2021.08.09 |
Proxy DLL Hijacking for kernel32.dll 삽질 (0) | 2021.08.01 |