Never Stop Running

[CodeEngn] BASIC 15 본문

Training/Codeengn

[CodeEngn] BASIC 15

Gyoran 2018. 9. 24. 23:46

리버싱 공부를 위한 문제풀이로

정답을 찾는 것과는 조금 다를 수 있습니다.

[CodeEngn] BASIC 15


문제 풀이 환경

Windows 10 / Intel / x32dbg / HxD

 문제 URL

https://www.codeengn.com/challenges/basic/15


BASIC 15번 문제.

문제는 Name이 CodeEngn일 때 Serial값을 구하는 것이다.


실행시키면 이러한 창이 뜬다. 여기에 'CodeEngn'을 넣고 맞는 Serial값을 넣으면 된다.


[다음을 찾기] - [현재 모듈] - [문자열 참조]를 이용하여 'CRACKED'라는 문자열이 움직이는 곳을 찾았다.


분기문에 Break Point를 걸었다. 그리고 그 앞에 함수 호출하기 전에 Break Point를 걸었다.


임의의 값을 넣었다. Name = CodeEngn, Serial = 123456.


함수를 지나고 나니 Name값인 'CodeEngn'이 메모리영역에 잘 들어갔다. 이 문자열의 주소는 EDX에 저장된다.


그 다음 함수를 지나고 나니 Serial값인 '123456'이 메모리에 잘 들어갔다. 이 문자열 값은 EAX에 저장된다.


EAX = 0x1E240 = 123456이다. CMP에서는 EAX와 [0045B844]의 값을 비교하는데 [0045B844]의 주소 내부 값을 보니 60610000이라고 쓰여있다. Intel은 리틀엔디언 방식이기 때문에 원래 값은 00006160이고 이걸 10진수로 바꾸면 24928이다.


Name = CodeEngn, Serial = 24928을 넣으면 성공이다.




추가적으로 시리얼이 어떻게 생성되는지 확인해보겠다.


확인 목적이므로 간단히 Name = abcd, Serial = 1234를 넣고 진행한다.


Name = abcd, Serial = 1234.


내가 입력한 값과 비교하는 값이 들어있는 [0045B844] 주소를 보니 아무것도 안 들어있다.

한번 첫 번째 함수를 F8로 지나가보니 이 주소에 값이 생겨있었다. 따라서 첫 번째 함수에서 Name을 받고, 이걸 이용하여 Serial값을 만들어낸다는 것을 알 수 있다.


그래서 첫 번째 함수로 들어갔다.


처음 두 개의 함수에서는 Name값을 받아오고 그 주소를 [0045B840]에 저장한다.


다음 표와 같은 과정을 거쳐 Serial값을 저장할 위치를 초기화한다.

주소

코드

분석

A2

 XOR EAX, EAX

 같은 값을 XOR 하면 0이 됨

A4

 MOV [EBX], EAX

 EBX = 0045B844의 주소 안에 EAX값을 넣음


[00403A64] 주소의 함수를 지나니 EAX 즉 함수의 리턴 값이 4로 바뀐 것을 알 수 있다. 이것을 통해 이 함수는 Name의 길이를 가져온다는 것을 알 수 있다.

그리고 밑의 루프문을 보면 뭔가 어떤 값이 만들어지는 것을 알 수 있다. 그래서 여기를 분석한다.

참고로 루프문 들어가기 전 ESI 주소 안에 1의 값을 넣는다.


주소

코드

분석

B7

 MOV EDX, [EDI]

 EDX = &"abcd"이므로 "abcd"의 주소 값을 EDX에 넣어줌.

B9

 MOV ECX, [ESI]

 [ESI] = 1이므로 ECX = 1

BB

 MOVZX EDX, [EDX+ECX-1]

 현재 ECX = 1이므로 EDX의 주소 값을 가져오는데 그 주소 1Byte의 값을 가져오므로 'a' 하나를 뜻함.

C5에서 ESI값을 증가시키고 B9에서 ECX로 넣어주기 때문에 ECX값이 증가함. 따라서 Name의 값을 하나씩 EDX로 넣어줌.

C0

 SHL EDX, 3

 110 0001(0x61) -> 11 0000 1000(0x308)

C3

 ADD [EBX], EDX

 [EBX] = 0, EDX = 0x308 -> [EBX] = 0x308

C5

 INC [ESI]

 [ESI]++

C7

 DEC EAX

 EAX--

이런식으로 모든 Name의 문자 하나하나를 연산하면 된다.


루프를 다 돌면 [004B844] = 0xC50의 값을 가진다.

그리고 다시 [00403A64] 위치 함수를 호출하여 Name의 길이 값을 가져온다.


그리고 그 가져온 값으로 또 연산을 한다.

주소

코드

분석

D1

 SHL EAX, 3

 100(0x4) -> 10 0000(0x20)

D4

 ADD [EBX], EAX

 [EBX] = 0xC50 ->0xC70

D6

 MOV EAX, [EBX]

 EAX = 0xC70

D8

 SHL EAX, 2

 1100 0111 0000(0xC70) -> 0011 0001 1100 0000(0x31C0)

DB

 MOV [EBX], EAX

 [EBX] = 0xC70 ->0x31C0

DD

 XOR EAX, EAX

 EAX 초기화


[0045B844] = 0x31C0 = 12736 이다. 따라서 Name = abcd의 Serial값은 12736이다.


이렇게 하여 최종적으로 Serial 값을 만드는 방법까지 찾았다.


'Training > Codeengn' 카테고리의 다른 글

[CodeEngn] BASIC 14  (0) 2018.09.24
[CodeEngn] BASIC 13  (0) 2018.09.24
[CodeEngn] BASIC 12  (0) 2018.09.24
[CodeEngn] BASIC 10  (0) 2018.09.24
[CodeEngn] BASIC 08  (0) 2018.09.24
Comments