Reversing

[Reversing.kr] Easy Keygen

chimita 2023. 5. 13. 02:57

문제를 클릭하고 파일을 다운 받았다.

 

파일이 .exe라서 ExeInfo 툴을 사용해 확인해봤다.

Easy Keygen.exe
실행 환경 32bit
제작 언어 C++
패킹 여부 NOT

readme
실행 파일

주어진 문제 파일을 보니 시리얼 값에 대응하는 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