1. 문제 이해
우선 simple_patch_me 파일을 실행시켜서 동적분석을 하게되면
1년이 지난 후 플래그를 알려주는 프로그램이라는 것을 알 수 있다.
그러면 우리는 I will show you the flag after 1 year :p 라는 문자열을 찾기만 하면 main 함수로 이동할 수 있을 것이다.
2. 문자열 검색
Search - Search for Strings 를 클릭해서 문자열의 길이가 15 바이트가 넘으니 최소 길이를 15로 설정하고 검색해주면 우리가 찾고자하는 문자열을 찾을 수 있다. 마찬가지로 한 번 클릭해주고 창을 닫아준다.
3. 문자열 참조
그러면 어셈블리 코드에서 해당 문자열이 사용된 위치로 이동해있는데, 그 상태에서 우클릭을하여 그 문자열을 참조하고 있는 함수를 찾아 해당 함수의 위치로 이동해준다.
4. 함수 분석
그러면 어셈블리 코드와 디컴파일된 소스코드에서 해당 함수의 위치와 코드들을 볼 수 있다.
undefined8 main(void)
{
puts("I will show you the flag after 1 year :p");
hours = 0;
while (hours < 8760) {
sleep(3600);
hours = hours + 1;
if (hours == 1) {
puts("1 hour passed");
}
else {
printf("%u hours passed\n",(ulong)hours);
}
if (hours % 24 == 0) {
if (hours == 24) {
puts("1 day has paased.");
}
else {
printf("%u days have passed.\n",(ulong)(hours % 0x18));
}
}
}
printf("Great xD 1 year has passed! The flag is: ");
printFlag();
return 0;
}
해당 함수를 보기쉽게 바꾸어 보았다.
시간이 8760시간(365일)을 넘지 않으면 1시간 동안 sleep하게 하고,
1시간이 지난 후에야 hours 변수에 1을 증가시키는 프로그램인 것을 알게 되었다.
이 프로그램의 문제는 3600초 동안 sleep 상태에 머물게되는 것이므로
우리는 슬립의 매개변수를 수정해주어야 한다.
5. 바이너리 패치
어셈블리 코드에서 지우고자 하는 sleep 함수의 위치로 이동해주면 sleep 함수에 사용되는 매개변수는 EDI 레지스터에 저장되어 사용되는 것을 알 수 있다. 따라서 우리는 EDI의 값을 0초로 바꾸어 주는 패치를 해야한다.
오른쪽의 화면과 같이 3600을 0으로 바꾸어 주었다면 Export 해주어 패치 결과를 반영한 바이너리를 생성해준다.
6. 패치 확인
이렇게 패치된 바이너리를 실행하면 반복문이 빠르게 실행되면서 바로 플래그 값을 얻을 수 있게 된다.