Index
문제
실행 파일(exe)이 주어진다. 실행시키면 Input :
이라는 문자열을 출력하고, 사용자가 입력을 하면 프로그램이 종료된다. IDA 도구를 이용해서 이 파일을 분석해보자.
문제풀이
IDA 도구로 디컴파일한 main 함수
이다. 프로그램을 실행시켰을 때와 같이 6번째 라인에서 Input :
문자열이 보인다. sub_1400011b0
으로 더블클릭을 하여 들어가보면, printf
함수인 것을 알 수 있다. 이후 7번째 라인에서 사용자 입력을 받는다. 따라서 sub_140001210
은 scanf
함수이다.
8번째 라인에서 sub_140001000
함수의 리턴 값에 따라 Correct
또는 Wrong
를 출력한다.
입력받은 v4
배열 변수 시작 주소를 넘기기 때문에, 무엇인가 비교하는 구문이라고 예상할 수 있다. 이 함수로 더블클릭으로 들어가서 분석해보자.
인자로 넘긴 v4
의 배열 변수 시작 주소를 함수 안에서는 a1
으로 사용한다. 이때 __int64
자료형으로 디컴파일 됐지만, 포인터 변수로 예상할 수 있다.
5번째 라인에서 for문으로 i
가 0부터 23까지 24번 반복하고, 배열 인덱스로 i
를 사용하여 byte_140003000
의 값을 1바이트씩 불러온다.
byte_140003000
은 1바이트씩 32개인 배열로 선언되어 있고, 값들로 추정되는 값들이 나열되어 있다. 직접 메모리에 적재된 값을 확인하기 위해 비교하는 구문에 F2
로 브레이크 포인터를 걸고, F9
로 실행시켜보자.
메모리에 올라가면서 주소가 바뀌었다. 아까 위에서 byte_140003000
가 프로그램이 실행되면서 byte_7ff75f213000
이 되었다. 이 값을 Hex View에서 g
키를 통해 7ff75f213000
을 검색하면 아까 보았던 값들이 실제로 메모리에 적재된 것을 확인할 수 있다. 총 32byte
길이 중, 24byte
가 입력되어 있다. 이 값을 1byte
씩 가져와서 비교를 하는 것임을 우리는 이해했다.
다시 코드로 돌아가서 문제를 풀어보자.
이 함수의 리턴 값에 따라 Correct
또는 Wrong
이 출력된다고 했다. Correct
를 위해서는 for문이 도는 동안 if 구문이 참(true)이 되면 안된다.
byte_14003000[i]의 값과 오른쪽 항의 값이 같지 않다면 참이 된다. 즉, 오른쪽 항의 연산 결과 값이 왼쪽과 같아야 한다.
오른쪽 항에서는 우리가 입력받은 값을 1byte
씩 참조하고, 이 값을 2*i
만큼 더하고, 마지막으로 i
의 값과 XOR
연산을 한다. 이 값이 아까 우리가 확인했던 byte_140003000
인덱스 값마다 일치하면 된다.
정리하면, 미리 연산해논 결과 값이 프로그램 안에 배열로 존재한다. 이 값을 주어진 식으로 역연산하는 문제가 되겠다. 간단한 파이썬 코드로 역연산된 값을 출력하면 플래그로 추정되는 값을 얻을 수 있다.
파이썬 풀이 코드
str = [0x49, 0x60, 0x67, 0x74, 0x63, 0x67, 0x42, 0x66, 0x80, 0x78, 0x69, 0x69, 0x7b, 0x99, 0x6d, 0x88, 0x68, 0x94, 0x9f, 0x8d, 0x4d, 0xa5, 0x9d, 0x45]
for i in range(0,24):
print(chr((str[i]-(2*i))^i),end="")
실행 결과
Uploaded by N2T