# 코드 엔진 문제 : Basic 8
패킹을 확인해보았으나, 패킹은 되어있지 않았다.
시작하자마자 바로 OEP부터 시작하는 것으로 보인다.
문제에서는 문자의 길이는 두자리라고 하였으므로
문자를 2자리로 입력하고, 출력되는 문자열 근처에 브레이크 포인트를 걸고 실행해본다.
쭉 따라가다보니 CMP 명령이 보이고 EAX,3 비교와 EAX, 1E 비교가 보인다.
그 전에 EAX에는 이미 입력한 문자열 길이인 숫자 2가 들어가 있는 것으로보아
문자열을 검증하여, 길이가 짧을 경우 경고문을 출력하게끔 되어있는거 같다.
어셈블리를 수정하여 CMP EAX,2로 바꿔준다.
쭉 진행하다보면 의심스러운 동작을 하는 주소를 발견할 수 있는데
0045BB9B 로 들어가서 코드를 보다보면
특정 시리얼을 만들어내는 것으로 추정되는 반복문들을 볼 수 있다.
아래는 그 시리얼들을 찾아가는 과정이며,
해당 함수를 나가서 코드를 진행하다보면 00818E08 주소에 총 시리얼이 들어가 있는 것을 알 수 있다.
해당 덤프창을 그대로 두기 위해 프로그램에 name에 aa를 입력하고 다시 실행하였고
이제 덤프창에 언제 무슨 문자열이 쓰여지는지 확인할 수 있게 된다.
다시 0045BB9B에 들어가 코드 진행중에 45BA7D 주소의 콜을 지난 후 00818E38에 총 시리얼 값이 들어가는 것을 확인하였다.
또한 진행중에 스택에 들어간 3번째 시리얼의 값이 들어가있는 주소를 따라가보니 0059C700에
4898F8F2 값이 들어가 있는 것을 확인하였다. 이 값이 어디서 들어가는지 확인해보자
확인해보니 45BA19의 콜을 실행하니 0059C700에 3번째 시리얼 값이 들어가는 것을 확인하였다.
최종적으로 어디서 0059C700으로 들어가는지는 알았으나, 그 8자리 문자열의 원본이 어디서 생성되는지를 알아봐야한다
이동하던 중 EBP-8이 가르키는 주소의 값을 EAX에 넣었더니 최종 문자열 원본을 발견했고
0018F578 주소에 0058DA88이란 값(3번째 시리얼 8자리를 추출하기 위한 문자열 원본)을 발견했다.
0058DA88 주소를 덤프창에 띄워놓고 이 문자열이 어디서 생성되는지 확인하기 위해
F9를 눌러 다시 프로그램을 실행시키고, aa를 입력해보자.
그러면 미리 설정해둔 브레이크포인트에서 멈추고 덤프창도 그대로 남겨져 있다.
(이렇게 하지 않고, 덤프창에서 바로 가기를 눌러 해당 주소를 입력하면 이동이 되지 않음)
이동하다보니 45B90F주소의 콜을 넘어가니 해당 주소에 문자열이 생기는 것을 확인할 수 있었다.
안에 들어가서 이동하다보니 45B58A 주소의 콜 후 문자열이 생성되었다.
들어와서 확인해보니 반복문이 보인다
1C (EDX)
EDX 초기화
EDX에 1 삽입
EAX의 주소에 1(DL)을 삽입
EBX 1 증가 (EBX는 1)
EAX 1 증가 (EAX는 0018F4E5)
이것을 16번 반복
// 이 작업은 18F4E4에 16개 자리의 공간을 초기화한다
그 다음 반복문 ECX에 0018F488 삽입
ESI 0018F4E4 의 주소에 있는 값을 EAX에 삽입 (48)
후 2를 EDX에 삽입하고 두개의 콜이 보인다 0045B50E와 0045B519
여기서 값을 입력한다.
0045B519의 안에 00404B03 과 00404B11의 콜 이후 값이 변하는 것을 확인하였다
45BB9B 안에 45B90F 안에 45B58A 안에 두번째 반복문의 0045B519 안에 404B03 / 404B11
404B03 안에 들어가니 ECX에 5D라는 아스키 값(00595148)이 저장되었다.
그리고 계속 이동하다보면 EBX(0018F570)의 주소의 값인 아스키값 5D가 EAX에 저장된다
그리고 404F56의 콜로 0058DA88에 5D라는 값(3번째 시리얼 8 자리를 추출하기 위한 원본 문자열 중 첫번째)이 저장되었다.
또한 45BB9B 안에 45B90F 안에 45B58A 안에 두번째 반복문 안의 첫번째 함수 45B50E의 콜 바로 밑에
mov EDX, EBP-70의 주소값 명령을 지나니 EDX (595148, 아스키로 5D) 에 값이 저장
두번째로 반복하여 지나니 EDX (595138, 아스키로 11) 에 값이 저장
세번째 595148, A5 저장
네번째 58DA8E, 63 저장
다섯번째 595148, 32
그래서 45B50E로 들어가보니 , 바로 앞에 4086DB 콜 안에 408585부터 반복문이 보이는데
여기서 해당 시리얼을 만들어 내는 것을 확인할 수 있다.
구체적인 연산은
EDX 2를 초기화 한 후
DIV ECX (ECX는 10이 들어있었다)
그리고 시리얼이 담겨지는 0048F466 보다 2 값이 더 들어가 있는 (ESI = 0018F468) ESI의 값을 1 빼고
DIV ECX로 2가 된 EDX(정확히는 DL)에 30을 더한다.
그리고 DL과 3A를 비교하여 jb 점프 (왼쪽인자가 오른쪽보다 작으면 점프) 왼쪽이 크면 7을 더한다
이 값을 ESI가 가르키는 곳 (즉 시리얼이 담겨지는 18F466 다음인 18F467에 저장)
그 다음 반복시에는 첫째 자리 즉 18F466에 저장한다.
또한 45B58A 안에 두번째 반복문에서 45B506에서 ESI의 주소에 담겨진 값을 EAX로 가져오고,
그 값을 아스키로 쪼개어 18F466에 저장하는 것을 알 수 있다.
ESI의 주소는 18F4E4부터 시작이다
ESI의 주소를 덤프창에 열어두고, 이 값이 언제 쓰여지는지 확인해보자
45BB9B 안에 45B90F 안에 45B58A 안에
45B4C8부터 16번 반복하며 18F4E4의 자리를 비운다.
그런 후 45B4EE에서 해당 시리얼을 18F4E4에 쓴다.
해당 함수로 쭉 들어가다보면
45ABF9 콜 내부에서 값을 쓰는 것을 알 수 있다.
이 매커니즘은 곧 다시
----------------------------------------------------------------------------------------------------------------------------
아래는 1,2,4,5 번째 시리얼 찾는 곳
----------------------------------------------------------------------------
aa (61 61)
7A69-7DD8-4898F8F2-1B46-8F71
61 + 0 + 772 = 그 결과 a라 한다.
그 후 a * a를 한 후 그 곱한 결과를 다시 a에 더한다.
그 결과를 b라고 하고, b에 다시 474를 곱한다.
그 결과를 c라 하고, 다시 c + c를 다른 변수 (EDX)에 저장한다.
인덱스값 ECX를 1 늘리고
인덱스값 EAX를 1 줄인다
그리고 다시
61 + EDX값 (c)하고
그 값 d를 다시 * 772한 값을 e라고 하면
그 다음엔 e * e를 한 값 f를
e + f = g라고 하면
g * 474를 하고 이 값을 h라고 하면
h + h를 한다.
이 값이 앞의 4자리가 7A69가 된다.
다음은
61 + 11 - 5 = a라고 하면
a * 92를 하고 이 값을 b라고 하면
그 다음은 b + b 이 값을 c 라고 하면
그 다음은 c * 819한 값 d를
EBP-10 (0018F568)의 주소에 저장하고
EAX 인덱스값을 1 감소
이 작업을 2번 진행하여 0018F568 주소에 값을 더하여
07 DD 88 68이 된다.
여기서 두번째부터 자리 값 7DD8이 두번째 시리얼이다.
세번째 시리얼 구하는 반복문에서
61 + 929 + 767 = a
a * 8392 = b
b - 33 = c
c * b = d
d + b = e
e와 별개로 다시
두번째 반복에서
61 + b = f
f + 929 + 767 = g
g + e = h
h * 8392 = i
i - 33 = j
j * i = k
k + i = 99A33758가 나오는데
여기서 i가 1B46FC76이며, 여기서 앞에 4자리가 4번째 시리얼이다
그 다음은 4번째 구문에서
61 + 61 = a
a * a = b (edx)
a * b = c
xor c , 10 = d
or d, 44 = e (ebx = d)
e * b * 373 = f
f + 443 = g (g = ebx , edx)
g + 61 = h
h * h = i (i = ebx = 79E23040)
i + 61 = j
j + j = k
k = ebx, edx (F3C46142)
k * k = a' (EDX, 5E031504)
a' * k = b' (EBX, 4AD1EF08)
xor b', 10 = (c', 4AD1EF18)
or c', 44 = (d', 4AD1EF5C)
a' * d' * 373 = (e' , EDX , 121C9A54)
e' + 443 = f'(EBX, EDX, 121C9E97)
f' + 61 = g'(EBX)
g' * g' = 08F71040
여기서 2번째 자리부터 4자리를 구하면 8F71
5번째 시리얼이다.