본문 바로가기

dreaMhack/Reverse Engineering

[드림핵] rev_basic_0 풀이/어셈블리어 해석

https://dreamhack.io/

 

https://dreamhack.io/wargame/challenges/14/

 

드림핵 리버싱 강의를 듣고 나면 마지막 트랙에서

드림핵이 제공하는 리버싱 베이직 문제들을 풀어볼 수 있게 된다

 

rev_basic_0 문제 이전에 있는 patch 문제는

단순히 한 함수를 무시하게 조작해주면 끝나는 것이기 때문에

자세히 어셈블리어를 다루지 않아도 된다고 생각해 0부터 시작합니다

 

블로그 작성자 본인도 어셈블리어를 해석해본 경험이 적어 많이 부족하겠지만

할 수 있는 선까지의 해석해보겠습니다

 

 

 

1. x64bug 해석

ctrl+f9 버튼을 누르고 진행하다 wrong 부분 출력되는 순간의 코드

 

본 함수의 코드들인데 여기에서 주목해야 할 점은 correct와 wrong을 출력해주는 부분이다

이 이전에 있는 함수에서 해당 문자열을 고를 반환값을 줬을 가능성이 높기 때문이다

call challo.7ff796861000

따라서 위의 코드 속 함수 주소를 더블 클릭 해주면 우리가 해석해야하는 함수의 코드들이 나오게 된다

 

이번 문제는 0번 문제답게 오른쪽에 바로 정답이 존재하지만

어셈블리어 학습을 위해 굳이 어셈블리어를 해석해보자

 

이 함수에서 쓰이는 어셈블리어 함수 종류

mov 두 번째에서 첫 번째로 데이터 이동
sub 캐리 포함하지 않은 뺄셈
lea 오프셋(데이터 영역) 값을 레지스터로 로드
call 프로시저 호출(함수 호출)
test and 연산 결과 값 플래그로
jne 결과 값 0 아니면 분기(이동)
jmp 무조건 분기
add 캐리 포함하지 않은 덧셈
ret 스택에 push된 주소로 복귀(리턴)

 

(이전 포스트의 레지스터 목록 참고)

rcx에 있던 값을 rsp+8에 이동시키고 rsp에 38을 뺀 값을 적용한다

= 이 함수를 위한 스택 위치로 변경

 

7FF7...에 위치한 데이터 값(Compar3_the_str1ng)을 rdx에 로드한다

rsp+40에 있는 입력한 문자를 rcx에 로드한다

그리고 JMP & strcmp를 진행해, strcmp(문자가 같으면 0을 반환함) 반환 값을 eax에 불러온다

 

함수의 반환 값을 and 연산하는데, 이때 문자열이 같으면 0을 플래그에 저장하게 된다

jne는 값이 0이 아닐 때 분기하는 명령어로, 문자열이 같으면 분기하지 않고 rsp+20에 1을 넣는다

이후 무조건 분기인 jmp를 만나 rsp+20에 0을 넣는 코드를 뛰어넘어 다음 코드로 진입한다

 

마지막으로 rsp+20에 저장한 문자열 비교 값을 eax에 넣어 함수 반환값으로 설정한다

그리고 rsp에 38을 더해서 해당 함수에서 사용한 스택을 놓고 이전에 사용하던 스택 위치로 이동한다

ret(return)으로 함수가 끝나게 된다.

 

즉, 이 함수에서는 오른쪽에 대놓고 나와 있는 값(Compar3_the_str1ng)을 입력값으로 들어오면

반환값으로 1을 설정해 correct를 프린트하게 만든다.

 

 

 

2. Ida 해석

프로그램을 시작하고 f5(디컴파일)를 누르면 나오는 화면

ida는 익숙한 C언어 형태로 디컴파일해줘서 x64dbg보다 훨씬 쉽게 해석할 수 있다

위의 코드를 봐도 correct를 프린트해주는 곳의 if문만 잘 보면 해결할 수 있을 것 같다는 생각이 든다

 

if 문 안에 있는 함수(sub_140001000)를 더블클릭하면 내부로 들어와진다

함수의 디컴파일 버전을 보니까 x64dbg보다 훨씬 이해하기 쉬운 형태를 보여주고 있다

 여기에서 strcmp(a1, "Compar3_the_str1ng")은 입력값과 문자열이 동일하면 0을 리턴한다

strcmp가 0을 리턴하게 되면 == 연산으로 0과 동일한 것을 확인하고 1을 리턴한다

 

 

 

 

정답: DH{Compar3_the_str1ng}