본문 바로가기
étude/reverse engineering

dreamhack : rev_basic_1

by mummoo 2023. 1. 12.

문자열 참조로 Wrong을 찾은 후
 
x64dbg로 실행파일을 연다. 그와 동시에 콘솔창이 켜진다. 
 
F7을 누르다 보면
1. 콘솔창에 Input : 이 뜨고, 00007FF6158517B4 이후로 넘어가지지 않는다.

2. entrypoint
=> entrypoint는 프로그램이 실행될 때 시작하는 메인함수의 위치를 나타낸다.
프로그램이 실행되고, Input : 이 떴으니 당연히 이 부분이 entrypoint

**메인함수가 뭐냐 하면, 프로그램의 실행이 시작되는 함수!
디버거는 프로그램 실행 흐름을 읽기 위해 사용하는 툴이므로, 메인함수를 찾아야 프로그램을 뜯어볼 수가 있다
 
**프로그램이 실행될 때, 운영 체제는 해당 프로그램을 메모리에 로드하고, 실행을 시작할 지점을 찾아야 한다. 
== 이 지점이 entrypoint
보통 c나 c++에서는 entrypoint로 메인 함수가 사용된다. 
컴파일러에서 프로그램의 시작 지점으로 메인 함수를 설정하고 프로그램 실행이 시작되면 코드가 실행된다. 
 
**entrypoint 찾는 방법 
: 디버거를 열고, 프로그램을 디버깅했을 때 어떤 코드가 처음으로 실행되는지를 알아야 한다.
이 프로그램에서는 input : 의 출력으로 프로그램이 실행되었음을 알 수 있다. 
 

수능 등급같네
ㄹㅇㅋㅋ
 
암튼 콘솔창에 아무거나 일단 입력을 해본다.
근데 바로 꺼진다. 
왜일까? 
stdin stream에 맞게 작성되지 않아서 그런가? 
리버싱 전 트랙장 훈련 갔다 오면 한번 봐달라고 해야겠다
 
메인함수는 찾았으나, F7로만 입력 함수 찾으려면 시간이 너무 오래 걸릴 것 같으니 문자열 검색을 한다.
문자열 Wrong!을 찾아보기로 했다.
 
다음을 찾기 > 모든 참조 > 문자열 참조
 

 
클릭하면 아래와 같은 함수를 찾을 수 있다.
 

test eax, eax에서 eax == 0이면 wrong으로 점프하는 것을 볼 수 있다. (밑의 명령어 je)
따라서 test eax, eax 위의 함수에서 eax 에 0이 아닌 값이 저장되어 있어야 한다.
 
해당 함수로 들어가서 사용자 입력값이 어떤 조건을 가져야 eax != 0을 가질 수 있는지 봐야 한다.

이 함수에서 알아내야 할 건, 어떤 조건을 갖춰야 eax != 0이 되는지이다.
 
코드를 위에서부터 확인해보면 
 

1. 첫 번째 줄에서, rcx에 저장되어 이 함수 안까지 들어온 사용자 입력값은 rsp+8 주소에 저장된다.
2. eax = 1을 넣고
3. rax = rax * 0 의 값을 저장한다.


4. rsp + 8 주소에 저장해놓았던 사용자 입력값을 rcx에 다시 저장한다. 
 
5. rcx +rax의 값을 rax에 저장한다. 
=> 여기서 rax == 0이기에, rcx의 첫 번째 문자를 저장하는 것이다.

 

** 왜냐하면!

c언어에서 문자열을 저장할 때, 문자열은 연속적으로 저장되기 때문

그래서 하나의 문자열이 메모리에 저장될 때, 각 문자들은 인접한 주소에 저장됨 

 

e.g.

 

hello라는 문자열을 str[10] 에 저장할 때, str[0] = 'h', str[1] = 'e', ..., 

주소 0 1 2 3 4
h e l l o

C언어에서 문자열이 저장될 때, 문자들은 연속적으로 인접한 주소에 저장됨

 

=> 따라서 rcx (문자열 / 사용자 입력값) + rax (0, 1, ... 순으로 더해지는 형태 )

 
6. 그리고 eax와 0x43을 비교한다 (0x43 == 'C')
cmp 연산자는 '-' 연산자를 이용하는데, 이때 eax - 43의 값이 0이라서
=> ZF==1 (참)이 되면 
     je 활성화 
     je 명령어가 있는 코드를 더블클릭해보면 
     eax = 1 을 저장하는 코드로 이동한다. 
=> ZF == 0 (거짓)이라면, 
     xor eax, eax 연산을 통해 eax 값이 0으로 초기화되고 
    밑의 코드가 실행되어 ret으로 간다. 
 
따라서 여기까지,
eax != 0 이 되지 않은 채로 ret하려면 사용자 입력값의 첫 번째 문자가 0x43, 즉 'C'이어야 함을 알 수 있다. 
 
그리고 같은 코드가 C, o, m, ....에 대해서 반복되는 흐름을 가진다.
 
결국 옆에 적힌 주석의 값을 나열한 것이 플래그임을 알 수 있다. 
하나라도 잘못된 값을 입력하면 바로 eax = 0 후 ret으로 넘어가서 함수가 끝난다는 것!
 
아무튼 따라서, 플래그값은 
 
Compar3_the_ch4ract3r
 

플래그 : Compar3_the_ch4ract3r

'étude > reverse engineering' 카테고리의 다른 글

dreamhack : rev_basic_3  (0) 2023.08.06
dreamhack : rev_basic_2  (0) 2023.08.05
dreamhack : rev_basic_0  (0) 2023.01.10
easy_crackme1  (0) 2023.01.07
rev_basic_1  (0) 2022.11.02