[rev] 리버싱 핵심원리 1부) 기초 리버싱 8장~11장

2023. 3. 6. 02:47리버스 엔지니어링/1부) 기초 리버싱

이번 글은 8장 abex' crackme #2 부터 시작됩니다.

https://baebenzene.tistory.com/3

 

[rev] 리버싱 핵심원리 1부) 기초 리버싱 5장~7장

이번 글은 5장 스택 부터 시작됩니다. https://baebenzene.tistory.com/2 [rev] 리버싱 핵심원리 1부) 기초 리버싱 1장~4장 리버싱 핵심원리 2022년 1월부터 이 책을 공부하면서 정리를 목적으로 이 글을 작성

baebenzene.tistory.com

 


abex' crackme #2

abexcm2-voiees.exex 파일

IDA로 실행

다음과 같은 창이 생성된다.

아무 값이나 입력하고 Check를 누르면 "Nope, This serial is wrong!"이란 메세지가 출력된다.

먼저 "Nope, This serial is wrong!"이란 문자열을 출력하는 구간을 찾아본다.

alt+t로 문자열 찾기를 이용한 후, Xref를 통해 해당 문자를 참조한 구역을 찾을 수 있다.

alt+t로 문자열 찾은 후 Xref로 역참조

아래 구역에서 문자열을 봤을 때 정답으로 추측되고 위의 jz 분기점으로 넘어가는 것을 알기에

위의 명령어에 BP를 걸고 어떻게 ax값이 나오는지 확인한다.

.text:00403321 lea     edx, [ebp+var_44]
.text:00403324 lea     eax, [ebp+var_34]
.text:00403327 push    edx
.text:00403328 push    eax
.text:00403329 call    ds:__imp___vbaVarTstEq

 

ds:__imp___vbaVarTstEq는 serial 값이 맞는지 검사하는 함수이고 인자로 edx와 eax를 받는다.

따라서 우리는 edx와 eax 을 통해 serial을 알 수 있음을 추측할 수 있다.

edx: 0019F288 , eax: 0019F298

각각 00501EAC, 0051CD7C를 저장하고 있으므로 각 값을 주소로 찾아가보면

왼쪽이 0051CD7C, 오른쪽이 00501EAC

따라서 왼쪽이 입력한 serial값이므로 오른쪽이 정답 serial값임을 알 수 있다.

정답문구 출력


함수 호출 규약

앞에서 함수를 호출 할 때 인자를 PUSH하여 스택에 저장하고 호출시 EBP를 통해 값을 불러와 사용하였다.

이번 장에서는 함수를 호출할 때 인자를 어떤 방식으로 전달하는지를 알아본다.

 

주요한 함수 호출 규약은 세가지이다

  • cdecl
  • stdcall
  • fastcall

1) cdecl

cdecl 방식은 주로 C언어에서 사용되며 Caller 스택을 정리한다.

위 사진은 지난 스택 프레임 때 실습코드이다. 코드의 00401023 과 00401041을 보면

esp를 8 더했다가 8을 빼줌으로써 스택을 정리하는 걸 볼 수 있다. 이와 같은게 cdecl이다.

 

2) stdcall

stdcall은 Win32 API에서 사용되며, 마지막 반환 때 RETN 명령어를 사용해 스택을 정리한다.

 

3) fastcall

stdcall 방식과 같지만, 파라미터 2개까지는 레지스터를 활용해 전달한다.

이후  x64 CPU에선 변형된 fastcall 방식으로 4개의 레지스터를 사용해 전달한다.

 


Lena's Reversing for Newbies

파일을 실행해보자

"Get rid of all Nags and find the right registration code!" 메세지 출력 이후 키를 입력하는 창이 뜬다.

따라서 해야 할 일은 1) Nag 메세지 삭제  2) registration code 찾기

 

1) Nag 메세지 삭제

alt+t로 문자열 검색을 시도해본다.

.text:00402C85 mov     [ebp+var_7C], offset aGetRidOfAllNag ; "Get rid of all Nags and find the right "...
.text:00402C8C mov     [ebp+var_84], ebx
.text:00402C92 call    __vbaVarCopy
.text:00402C97 push    3
.text:00402C99 lea     edx, [ebp+var_84]
.text:00402C9F pop     edi
.text:00402CA0 lea     ecx, [ebp+var_24]
.text:00402CA3 mov     [ebp+var_7C], 21h ; '!'
.text:00402CAA mov     [ebp+var_84], edi
.text:00402CB0 call    __vbaVarMove
.text:00402CB5 lea     edx, [ebp+var_84]
.text:00402CBB lea     ecx, [ebp+var_34]
.text:00402CBE mov     [ebp+var_7C], offset aNagScreen ; "Nag Screen "
.text:00402CC5 mov     [ebp+var_84], ebx
.text:00402CCB call    __vbaVarCopy
.text:00402CD0 push    0Ah
.text:00402CD2 mov     ecx, 80020004h
.text:00402CD7 pop     eax
.text:00402CD8 mov     [ebp+var_6C], ecx
.text:00402CDB mov     [ebp+var_74], eax
.text:00402CDE mov     [ebp+var_64], eax
.text:00402CE1 lea     eax, [ebp+var_74]
.text:00402CE4 mov     [ebp+var_5C], ecx
.text:00402CE7 push    eax
.text:00402CE8 lea     eax, [ebp+var_64]
.text:00402CEB push    eax
.text:00402CEC lea     eax, [ebp+var_34]
.text:00402CEF push    eax
.text:00402CF0 lea     eax, [ebp+var_24]
.text:00402CF3 push    eax
.text:00402CF4 call    __vbaI4Var
.text:00402CF9 push    eax
.text:00402CFA lea     eax, [ebp+var_54]
.text:00402CFD push    eax
.text:00402CFE call    rtcMsgBox

마지막 00402CFE에서 해당 문자열을 메세지 박스로 출력하는 것을 알 수 있다.

따라서 마지막 메세지 박스 호출을 제거하면 된다.

 

rtcMsgBox 호출 이후 스택이 0019F1D8 에서 0019F1EC로 이동했다. 따라서 파라미터의 크기는 14인 것을 알 수 있다.

call  rtcMsgBox >> add esp,14h 와 같이 변경 시, 반환값인 eax가 변경되지 않아 에러가 발생한다.

 

따라서 rtcMsgBox함수를 제거하기 보단, 상위 함수를 호출하지 못하게 해야 한다.

위로 올라가다 보면 스택 프레임을 생성하는 부분이 나오는데 그곳을 RETN 명령어로 반환해버린다.

.text:00402C17 push    ebp              >>            .text:00402C17 retn  4
.text:00402C18 mov     ebp, esp         >>

 

위의 패치를 적용하면 메세지 박스가 출력되지 않는다.

 

2) registration code 찾기

위에서 했던 방식과 동일하게 alt+t로 문자열을 찾고 참조하여 해당하는 text영역까지 도달한다.

 

위의 코드를 보면 "I 'mlena151"이란 값을 받고 __vbaStrCmp 함수를 통해 비교하는 걸 알 수 있다.

 

값을 입력했더니 성공한 것을 알 수 있다.

 


 

참고서적

이승원, 「리버싱 핵심원리」, 인사이트, 2012, 95p ~ 134p

http://www.yes24.com/Product/Goods/7529742

 

리버싱 핵심 원리 - YES24

리버서라면 꼭 알아야 할 핵심 원리를 모두 담았다리버싱이란 프로그램의 내부를 깊이 들여다보고 조작할 수 있는 기법이다. 이는 우리가 흔히 사용하는 상용 프로그램 등에도 가능하기 때문에

www.yes24.com