Lena's Reversing for Newbie 01 Write-Up
파일 링크: https://tuts4you.com/e107_plugins/download/download.php?list.17
Downloads / Lenas Reversing for Newbies - Tuts 4 You
tuts4you.com
Tutorials Index: 01. Olly + assembler + patching a basic reverseme
사용도구: 올리디버거 2.01
Lena's Reversing for Newbie 01(이하 원본파일) 분석해보자.
원본파일을 실행하면 다음과 같은 창이 뜬다.
대충 평가기간이 만료되서 새로운 라이센스를 구입하라는 뜻이다. 확인 버튼을 클릭하면 프로그램은 종료된다.
올리디버거로 원본파일을 실행하면 위와 같은 루틴을 확인할 수 있다. 중간에 [사진 1]에서 확인했던 문자열들이 사용되는 것으로 보아 이 루틴을 분석하면 될 것 같다.
code 섹션에서 우클릭 - Search for - All referenced strings 기능을 클릭하면 위와 같이 사용되는 문자열들을 확인할 수 있다. 맨 아래의 "You really did it! Congratz !!!" 문자열이 있다. 이 문자열들의 메시지 박스 함수가 호출되도록 패치하면 될 것 같다.
먼저 CreateFileA 함수를 거치는데, 이 함수는 "Keyfile.dat"를 파일명으로 하는 파일을 읽기, 쓰기모드로 오픈한다. 해당 파일이 없을 경우 [사진 1]처럼 종료된다. 코드 패치만 해야하므로 "Keyfile.dat" 파일을 생성할 수 없다.
여기서 [사진 4]의 주소 401207로 바로 점프하거나 40109A 주소의 ReadFile 함수로 점프해야 한다.
위와 같이 CreateFile 함수가 종료된 후 바로 401207 주소로 점프하도록 패치할 수 있다.
또는 위와 같이 CreateFileA 함수가 반환하는 값에 상관없이 즉, "Keyfile.dat" 파일이 없어도 40109A 주소의 ReadFile 함수로 무조건 점프하도록 패치할 수 있다. 이렇게 패치하고 더 진행해보자.
다음으로 ReadFile 함수를 호출하는데, CreateFileA 함수에서 파일을 오픈하지 못했으므로 반환 값은 0이다. 즉 TEST 연산에서 ZF 플래그가 설정되고 4010F7 주소로 점프할 것이다.
4010F7 주소는 위와 같이 Keyfile이 유효하지 않다는 메시지와 함께 프로그램이 종료된다.
따라서 위와 같이 JNZ 명령어를 JMP 명령어로 패치하여 ReadFile 함수의 결과에 상관없이 4010B4 주소로 점프한다.
다음으로 402173 주소의 값과 값 0x10을 비교하는데, 402173 주소의 값은 ReadFile 함수에서 읽었어야 할 파일의 값의 길이이다. 하지만 읽지 못했기 때문에 0이 저장되어 있다. 즉 4010BF 주소의 JL 명령어로 인해 4010F7 주소로 점프하고 [사진 9]처럼 프로그램이 종료된다.
그래서 위와 같이 JL 명령어를 JG 명령어로 패치하여 402173 주소의 값이 0x10보다 클 경우에만 4010F7 주소로 점프하도록 하였다. 402173 주소의 값은 0이므로 점프하지 않는다.
다음으로 루프문을 거치는데 루프문의 기능은 다음과 같다.
1. "Keyfile.dat" 파일의 값에서 맨 앞의 1byte 값을 AL 레지스터에 저장
2. AL 레지스터에 저장된 값이 NULL인지 확인(문자열의 끝인지 확인)
3. 만약 NULL이면 4010D3 주소로 점프한다.
3-1. 4010D3 ESI 레지스터의 값과 값 0x8을 비교한다.
3-2. ESI 레지스터의 값이 0x8보다 작으면 4010F7 주소로 점프한다.
3-3. ESI 레지스터의 값이 0x8 이상이면 401205 주소로 점프한다.
4. AL 레지스터에 저장된 값과 값 0x47을 비교한다.
5. 값이 0x47과 다르면 4010D0 주소로 점프한다.
6. 값이 0x47과 같으면 ESI 레지스터의 값을 0x1 증가시킨다.
7. CMP 명령어의 결과에 상관없이 EBX 레지스터의 값을 0x1 증가시킨다.
8. 4010C1 주소로 점프하여 루프문을 반복한다.
"Keyfile.dat" 파일이 없기때문에 루프문 1번에 의해 AL 레지스터에는 0x0이 저장된다. 그리고 2번과 3번에 의해 4010D3 주소로 점프한다. 그리고 ESI 레지스터의 값은 0x0이기 때문에 4010F7 주소로 점프하고 [사진 9]처럼 프로그램이 종료된다.
따라서 [사진 12]와 마찬가지로 JL 명령어를 JG 명령어로 패치하여 4010F7 주소로 점프하지 않고 401205 주소로 점프하도록 한다.
401205 주소로 점프하면 위와 같이 성공 메시지 박스를 확인할 수 있다.