
Reverse Engineering 로드맵 혼자실습 문제이다. 다른 실습 문제들은 로드맵 자료에 풀이가 다 나와있으므로 이 문제만 write-up을 작성해보겠다.
로드맵을 따라 IDA로 문제를 풀어본다.
IDA로 파일을 열고 main을 찾으면 다음과 같다.

Input과 %256s 문자열이 보인다. F5를 눌러 디컴파일 해보면

이런 화면을 볼 수 있다.
sub_1400011B0과 sub_140001210 함수를 따라들어가 살펴보면


각각 printf 함수, scanf 함수라는 것을 알 수 있다. 알아보기 편하게 main 함수를 조금 변경해주자.

이제 sub_14000100 함수를 살펴봐야한다. sub_140001000의 리턴값이 1이면 Correct를 출력한다.

sub_140001000 함수 내부이다. for문을 총 0x18, 즉 24번 반복하므로 flag는 24글자라는 것을 알 수 있다. if 조건문을 보면 byte_140003000의 i번째 원소가 (i^입력값)+2*i와 같아야 for문을 빠져나가 1을 리턴한다.

byte_140003000이다. 16진수로
49, 60, 67, 74, 63, 67, 42, 66, 80, 78, 69, 69, 7B, 99, 6D, 88, 68, 96, 9F, 8D, 4D, A5, 9D, 45, 00, 00, 00, 00, 00, 00, 00, 00
이 저장되어있다.
각 수들과 (i^입력값)+2*i이 같아야하므로, 입력값은 (수-2*i)^i 여야한다. 자바로 코드 작성하였다.
public class rev {
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] aa= {"49", "60", "67", "74", "63", "67", "42", "66", "80", "78", "69", "69", "7B", "99", "6D", "88", "68", "94", "9F", "8D", "4D", "A5", "9D", "45"};
for(int i=0;i<Integer.parseInt("18", 16);++i) {
int h=((Integer.parseInt(aa[i], 16))-2*i)^i;
char ch=(char)h;
System.out.print(ch);
}
}
}
결과는
마지막 네모는 공백이다.
flag: DH{I_am_X0_xo_Xor_eXcit1ng}
flag 얻긴 했지만... EVI$ION 리버싱 세션 진행해주신 선배님께 공부 방법 여쭤보려고 연락 드리니까 최대한 IDA를 쓰지 않고 공부하는 게 좋다고 하셔서 x64 dbg로도 풀어봤다.

시작 포인트 찾고 F8 눌러가며 printf, scanf 함수 호출하는 부분을 찾아본다.

요기다~! 중단점 걸어둔 부분을 보면 eax를 비교하여 같으면 Correct를 출력하고, 다르면 Wrong으로 점프한다는 것을 알 수 있다. 따라서 바로 위 call에서 리턴되는 값이 무엇인지 확인해야한다.

call 함수 내부이다. 중간 부분을 보면 아까 IDA에서 봤던 (i^입력값)+2*i 부분을 확인할 수 있다. 그 값은 ecx에 저장된다. 그럼 ecx와 비교되는 eax에는 어떤 값이 저장되어있나 확인해봐야 하는데, 덤프에서 eax 저장되는 주소로 따라가보면

이렇게 IDA에서 확인한 것과 같은 Hex 값이 나온다. 이후 풀이는 1번과 같다.~~