Reversing.kr Replace
by St1tch실행을 시키고 입력을 하면 이렇게 문제가 발생해서 종료된다.
올리디버거로 실행시켜보니 40466F에서 접근할 수 없는 메모리에 90이라는 데이터를 써서 예외가 발생하는 것을 알 수 있다.
따라서 이 부분을 해결해야 한다고 생각하고 이제 입력하는 숫자를 기준으로 어떻게 프로그램이 진행 되는지 알아 보았다.
위 함수는 입력한 숫자를 받는 함수이다. 이 함수에 브레이크를 걸었다.
브레이크를 걸고 진행을 하면 위 그림과 같이 40105A에서 멈춘다.
위 과정을 간략히 설명하자면 아래와 같다.
1. [4084D0]에 EAX저장 (입력한 값)
2. 40466F 함수 호출
40466F 함수안에서는
[4084D0] 1증가 -> [4084D0] 1증가 -> [4084D0] 601605C7증가 -> [4084D0] 1증가 -> [4084D0] 1증가
위 과정이 차례대로 발생한다 .
즉 내가 입력한 숫자에서 (0x601605C7 + 4) 만큼 더해지는 것이다.
3. EAX 0으로 초기화
4. 404690으로 분기
404690으로 이동하면 위와 같은 명령어들이 있다.
이것도 중요한 부분을 간략히 말하면
1. [4084D0]값을 eax에 넣음
2. 404689함수호출
[4084D0] 1 증가 (필요 x 이미 eax에 값을넣었음)
3. [40466F]에 특정 명령어 덮어씀
이 명령어는 아까 예외를 발생시킨 부분으로
EAX의 값 1바이트를 0x90(NOP) 으로 덮어쓰는 역할
4. 40466F 호출
5. EAX + 1
6. 40466F 호출
7. 401071로 분기
이 부분으로 다시 오는데 바로 아래 401073 ~ 40107E 까지가 Success!를 출력해주는 명령어이다.
근데 401071에서 JMP를 하기 때문에 지금 이상태로는 절대로 Success!를 출력할 수가 없다.
하지만 생각을 해보면 401071의 OPCODE가 2바이트이고,
아까 위에서 40466F함수를 두번 호출할 때 EAX의 연속적인 2바이트를 NOP으로 바꿀수 있었다.
따라서 401071 ~ 72의 값이 NOP이 되면 JMP가 없어지며 Success!가 출력되게 할 수 있다.
401071이 NOP이 되려면
MOV EAX, DWORD [4084D0]
이 명령어가 실행될 때의 [4084D0]가 401071이 되어야 한다.
아까 위에서 계산한 식을 이용하면
x + 601605C7 + 4 = 401071
이러한 식을 세울 수 있다.
계산을 하면 위와 같이 값이 음수이다.
하지만 입력한 값을 대입 할때는 DWORD만큼 사용을 하기 때문에
FFFFFFFF는 필요 없이 A02A 0AA6만 필요하다.
이 값을 10진수로 바꾸면 끝 !
블로그의 정보
튜기's blogg(st1tch)
St1tch