[Reversing.kr] Easy Keygen
문제를 클릭하고 파일을 다운 받았다.
파일이 .exe라서 ExeInfo 툴을 사용해 확인해봤다.
Easy Keygen.exe | |
실행 환경 | 32bit |
제작 언어 | C++ |
패킹 여부 | NOT |
주어진 문제 파일을 보니 시리얼 값에 대응하는 name을 찾으면 될 것 같다.
이전 문제와 동일하게 문자열 참조로 correct 부분이 있나 확인해봤다.
correct 부분이 바로 보였다.
해당 부분을 더블 클릭하면 그 함수 위치로 이동하게 된다.
jne : 비교 결과가 같지 않으면 점프(ZF=0)
00401118에서 조건을 비교한 값이 같지 않으면 00401130 주소로 점프하는 것을 알 수 있다.
00401130 주소에서는 값이 틀리면 출력되는 'wrong'을 출력하고 있다.
그렇다면 입력받은 데이터를 어떻게 처리하는지 확인해봐야 할 것 같다.
위로 조금 올리면 입력받는 구간을 확인할 수 있다.
세 개의 mov 연산을 통해 10, 20, 30 데이터 값을 넣어주고 있다.
40102E를 통해 push 408060 ("Input Name: " 이 저장된 주소)를 스택에 쌓고 call 401189 로 printf 함수를 호출한다.
call 4011A2 로 scanf 함수를 호출하는 것을 확인할 수 있다.
movsx로 ecx에 위에서 확인한 mov 10,20,30을 넣어주고,
edx에는 입력한 문자열 Name 값을 넣어주고 있는 것을 알 수 있다.
(C 값을 보고 알았다.)
각각 값을 넣어준 뒤로 두 값을 xor 연산한다.
왠지 문제에서 주어진 시리얼 값을 반대로 xor 연산해주면 값을 구할 수 있을 것 같다는 단순한 생각이 들었다.
식을 가정한다면,,
Name[1] xor 10
Name[2] xor 20
Name[3] xor 30
Name[4] xor 10
.
.
.
= 시리얼
이런식으로 연산이 수행되는 것 같은데 시리얼 값은 이미 알고 있으니 쉽게 계산할 수 있을 것 같다.
xor 값은 한번 더 xor 연산 해주면 기존의 값을 얻을 수 있기 때문에 시리얼 값에 한번 더 연산해주면 될 것 같다.
serial = "5B134977135E7D13"
xor = [0x10, 0x20, 0x30]
length=2; #n자 지정
count = 0 #xor 순서 지정 위해 사용
num_str = list(map(''.join, zip(*[iter(serial)]*length))) #serial n자씩 자르기
num_hex = []
for j in range(len(num_str)): #10진수로 변환
num_hex = int(num_str[j], 16)
#print(bin(num_hex))
for i in range(len(num_hex)):
result = chr(num_hex ^ xor[count])
count = (count +1) % 3
print(result)
코드를 짰다.
이렇게 값이 잘 추출 되었다.
K3yg3nm3