OLD 2018 ~ 2021/BASIC → Hacking
170111_REVERSING(1)_whereami
pogn
2018. 1. 14. 23:24
Concept |
Windows MFC Reversing WndProc 함수 ( =메시지 처리 함수 ) : 특정 메시지가 발생했을 때 그것을 처리하는 함수로, WinMain과는 별개로 WndProc 이라는 이름으로 존재한다. WinMain 내의 메시지 루프는 메시지를 메시지 처리 함수로 보내주기만 할 뿐이며, WndProc은 메시지가 입력되면 윈도우즈에 의해 호출되어 메시지를 처리한다. 이렇게 운영체제에 의해 호출되는 응용프로그램 내의 함수를 Callback(콜백) 함수라고 한다. 보통 winProc 함수는 위와 같은 양상을 띄며, message를 인자로 넘겨받고 이러한 메시지 번호에 따라 분기하는 구조를 띈다. WM_DESTORY는 창을 닫는 메시지이며, 안의 코드를 작성하여 해당 메시지가 발생했을 때 어떠한 코드를 실행시킬 것인지 지정할 수 있다. 그 이후의 DefWindowsProc은 default 값으로 메시지를 처리한다는 의미이다. 해당 문제에서 WinMain 함수는 아래의 subCB1000 함수로 추정된다. WndProc 함수는 아래의 sub_CB1140함수이며, line 6의 dword_CB3020에서 sub_CB1220 함수의 주소를 참조한다. ( 인자를 보면 WndProc의 양상을 띄고 있음을 통해 확신할 수 있다. -> hWnd, 4개의 인자) sub_CB1220함수에서 you find me 라는문자열이 있었는데, IDA를 이용한 패치 F2 누르면 고치고, [ edit ->patch -> add to binary ]에서 바이너리에 직접 적용할 수는 있다. F2, ctrl + w 하면 그냥 idb 파일에 저장된다. IDA의 String view 활용 [ ctrl + F12 ] 다만, 지역변수로 박혀있지 않고 연산을 통해서 생성되는 문자열은 미리 보이지 않는다. @ 초기설정 추천 - String 창에서 오른쪽 클릭을 한 후, 아래와 같이 ASCII(1byte) 외에 Unicode(2byte)에도 체크를 해주고 - Minimum string length는 2byte로 설정해 두는 것이 좋다. IDA의 Xref 기능 [ x ] 변수에서 x 를 누르면 해당 변수를 참조하는 모든 함수들을, 함수에서 x 를 누르멶 해당 함수를 호출하는 부모 함수를 볼 수 있다. cf) IMP_들어간거 말고 그 위에 있는거로 들어가야한다. IDA의 IMPORT view 활용 어떤 dll을 import 하여 어떤 함수를 쓰는지 미리 보고 행위를 예측할 때 먼저 보면 좋다. |
Hands-on Practice |
(그림 1) 먼저, 동적분석을 통해 line 25에서 while문을 돌면서 윈도우 안의 요소들이 하나씩 만들어진다는것을 알았다. 따라서, line 27의 IsDebuggerPresent 의 jnz exit_addr --> jz exit_addr 로 패치하여 안티디버깅을 우회하였다. (그림 2) CreateWindowEx, ShowWindow 함수 이후에, (그림 1)의 line 24에서 특이한 식이 보여서 dword_E633A0 변수를 XREF 해보니 다른 함수에서 참조하고 있었다. 동적 디버깅 결과, 아래의 함수는 help 메뉴를 클릭했을 때 실행되는 함수였다. 함수의 인자로 받은 a2와 dword_E633A0 변수를 비교하여, 같으면 메시지가 뜨는데, (그림 2)의 line 7과 line 14에서 a2를 각자 다른 메시지를 띄우는데 쓰는 것으로 미루어 보았을 때, a2는 일종의 메시지를 구분하는 숫자이다. ---------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------- 이렇게 푸는 건줄 알았으나..... key가 문자열로 박혀있는 것도 이상하고, 인증이 되지 않았다. 동적 분석을 통해 알아본 결과, WndProc 함수에서는 데이터영역에 배열 메시지 번호(4bit)+함수주소(4bit)를 8bit의 배열로 나열해 둔 후, while 문 안에서 인자로 넘어온 메시지 번호( 변수 a2)와의 비교를 통해 해당하는 함수를 실행하고 있었다. (그림 3) WndProc 함수 (그림 4) 해당 데이터 영역의 값 등록된 모든 함수들을 살펴본 결과, sub_1320에서 어떤한 조건을 만족시키면 Message Box를 띄워주는 부분을 찾아볼 수 있었다. sub_1320에 비교문이 상당히 많았지만(헷갈리게 하기 위한것 같다) , MessageBox의 인자를 참조하는 부분은 아래의 두개가 전부였기에, 레지스터 조작을 통해 LABEL _23으로 넘어온 뒤, line 62의 return 을 NOP 처리하고 해당 함수를 실행시켰다. (그림 5) 해당 조건문 부분 (그림 6) Text가 비어있는 MesssageBoxW (그림 6) 해당 분기분을 지나서 나온 결과 KEY : gaegang_is_soon_T.T |
Reference |
- 윈도우 바이너리 패치 및 적용법 - idb 파일에만 적용이 되고 exe는 변경되지 않는다. - WndProc과 메시지 |