반응형

 

Write-up 쓴 날짜 : 2022-10-09 02:01

 

XoftSpy413_96.exe
1.55MB
ollydbg_patched_XoftSpy.exe
2.31MB
x32dbg_patched_XoftSpy.exe
2.31MB

 

Windows 프로그램은 API를 사용하여 커널과 상호 작용한다.

 

DialogBoxes : DialogBoxParamA, GetDlgItem, GetDlgItemInt, GetDlgItemTextA, GetWindowTextA, GetWindowWord

MessageBoxes : MessageBeep, MessageBoxA, MessageBoxExA, SendMessageA, SendDlgItemMessageA

Registry Access : RegCreateKeyA, RegDeleteKeyA, RegQueryValueA, RegQueryValueExA, RegCloseKeyA, RegOpenKeyA

Reading/Writing files : ReadFile, WriteFile, CreateFileA

Reading data from INI file : GetPrivateProfileStringA, GetPrivateProfileIntA, WritePrivateProfileStringA

Reading data (other) : LoadStringA, lstrcmpA, MultiByteToWideChar, WideCharToMultiByte, wsprintfA

Time And Date : GetFileTime, GetLocalTime, GetSystemTime, GetSystemTimeAsFileTime, SetTimer, SystemTimeToFileTime
Creating a NAG-window : CreateWindowExA, ShowWindow, UpdateWindow

Find messageboxtext : SendDlgItemMessageA, SendMessageA, SetDlgItemTextA, SetWindowTextA

 

주로 BP를 거는 함수들 : GetdlgItemTextA, GetWindowTextA, lstrcmpA, GetPrivateProfileStringA, GetPrivateProfileIntA, RegQueryValueExA, WritePrivateProfileStringA, WritePrivateProfileIntA

 

주제 - The use of API's in software, avoiding doublechecking tricks

 


분석 1

 

 

프로그램을 설치하고 실행한 뒤 About -> Enter Registration Code

 

아무것도 입력을 안하고 OK 버튼을 누르면 "Please fill all the details" 메시지 창이 뜨고, 모두 입력한 후 OK 버튼을 누르면 "Invalid code" 메시지 창이 뜬다.

 

 

이번 write up 에서는 OllyDbg와 x32dbg 각각의 디버거에서 분석하고 풀이한 것을 다룬다.


 

OllyDbg 분석

 

 

Ollydbg에 설치된 XoftSpy 파일을 올리면 위와 같이 412434 주소에서 예외가 발생하면서 진행 할 수 없다.

 

 

OllyDbg를 관리자모드로 연 뒤 설치된 XoftSpy 실행 파일을 올린다.

 

그 다음 XoftSpy의 .text 섹션으로 이동한다.

 

 

.text 섹션에서 Ctrl + N을 누른 후 바로 "getwindowtext" 문자열을 치면 위와 같이 검색이 된다.

 

해당 문자열 "GetWindowTextA" 함수을 선택 후 우클릭 한 후 Set Breakpoint on every reference를 눌러 해당 함수를 참조하는 곳에 모두 BP를 설정한다.

 

그리고 바로 F9 키를 눌러 프로그램을 실행한 뒤 조금 기다리면 

 

 

위와 같이 461E51 주소에서 멈추게 되는데, 아직 Registration Key를 입력 안 한 상태인데 GetWindowTextA 함수를 호출하겠다는 것이므로 461E51 주소는 상관이 없다.

 

그러므로 461E51 주소의 BP는 해제한다.

 

그리고 F9 키를 눌러 진행한다.

 

 

그러면 GetWindowTextA 함수를 참조하는 두 번째 호출 부분인 45B75D 주소에서 멈춘다.

 

해당 주소도 아직 어떠한 값을 입력 안 한 상태에서 호출하는 것이므로 상관이 없는 부분이기 때문에 BP를 해제한다.

 

그리고 이어서 F9 키를 눌러 진행한다.

 

 

만약 예외가 발생하여 진행이 안된다면 위와 같이 Options -> Exceptions -> Add range -> 위와 같이 00000000 ~ FFFFFFFF로 설정하여 프로그램 전체 영역에서 일어나는 예외를 처리하지 않게 한다.

 

예외가 발생하지 않았다면 이어서 아래와 같이 진행한다.

 

 

실행 된 프로그램에서 About -> Enter Registration Code -> 위와 같이 입력 -> OK 버튼 클릭

 

 

그럼 위와 같이 4625AB 주소에서 멈춘다.

 

이 상태에서 스택을 보면 11H 글자 즉, 17글자를 읽어서 58E6DB8 주소에 넣는다.

 

F8 키를 눌러 계속 진행한다.

 

 

F8 키를 눌러 진행하다 보면 위와 같이 4173CD 주소에서 호출하는 함수의 반환값이 Registration Code에서 name  항목에 입력했던 "sean"이다.

 

 

F8 키를 눌러 이어서 진행하면 위와 같이 4173E5 주소에서 호출하는 함수의 결과로 EDX 레지스터에 Registration Code 항목에 입력했던 값이 들어가 있다.

 

 

F8 키를 눌러 진행하여 4173F0 주소까지 실행 했을 때 ZF 플래그의 값이 0이므로 

 

점프가 취해지지 않는다.

 

그리고 그 밑에 명령어들도 EAX의 값과 EAX의 값을 연산하여 조건 분기를 하는데 

 

4173F2 주소에서의 조건 분기와 4173FD 주소에서의 조건 분기에서 같은 주소인 4175B2 주소로 점프한다.

 

 

4175B2 주소에서는 항목에 아무런 값을 적지 않았을 때 출력되는 메시지들이 있다.

 

즉, 4173EA 주소부터 4173FF 주소까지의 조건 분기는 Name과 Registration Code 항목에 값이 적혀졌는지 체크하는 곳이다.

 

 

이전에 두 항목에 값을 입력했기에 위의 조건 분기는 패스된다.

 

이어서 F8 키를 눌러 진행한다.

 

 

진행하다보면 위와 같이 두 부분이 비슷하다.

 

그리고 4174E3 주소로 조건 분기 하는 것도 같다.

 

그렇다면 조건 분기 하기 전 최근에 호출하는 417690 함수의 내부를 봐보자

 

 

위의 부분이 함수의 시작 부분이다.

 

 

스크롤을 쭉 내리면 위와 같이 함수의 끝 부분을 의미하는 retn 명령어가 보이는데

 

4178AC 주소의 RETN 명령어는 41789B 주소에서 EAX 레지스터의 값을 1로 만들고 실행된다.

 

417927 주소의 RETN 명령어는 41791A 주소에서 EAX 레지스터의 값을 0으로 만들고 실행된다.

 

 

' - ' (대쉬) 키를 눌러 417690 주소의 함수를 호출하기 전의 코드로 돌아가서 봐보면 al의 값이 0인지 검사하여 0이 아니면 4174E3 주소로 점프한다.

 

 

4174E3 주소는 등록에 성공했을 때의 메시지가 나오는 부분이다.

 

 

다시 417690 주소의 함수를 보면 EAX의 값을 1로 만들고 함수를 종료하는 위의 부분으로 가야 한다.

 

 

스크롤을 조금 위로 올려보면 417832 주소에서 ZF 플래그의 값이 0이면 EAX를 0으로 만들고 함수를 종료하는 4178AF 주소로 점프한다.

 

 

여기서 스크롤을 조금 더 위로 올려보면 또 4178AF 주소로 점프하는 조건 분기 3곳 417800, 417808, 417810 주소가 있다.

 

그리고 이 조건 분기의 조건은 4177F4 주소의 cmp 명령에서 정해진다.

 

4177F4 주소에 BP를 설치하고, F9 키를 누른다.

 

 

그리고 4177F4 주소의 명령을 실행하고 4177FF 주소까지 실행하면 ZF 플래그의 값은 0이고, 그러므로 JNZ 명령은 조건이 성립되어 4178AF 주소로 점프한다.

 

 

Ctrl + F2 키를 눌러 재실행 한 뒤 F9를 눌러 프로그램을 실행하고 About -> Enter Registration Code -> 항목들에 값을 채운 후 -> Ok 버튼 클릭

 

그러면 4177F4 주소에서 멈추게 되는데, 417800 주소의 JNZ 004178AF 명령어를 위와 같이 JMP 417899로 바꾸고 남은 Byte는 NOP으로 채우도록 한다.

 

 

그리고 F8 키 또는 F9 키로 진행하면 위와 같이 등록 성공 메시지 창을 띄우는 부분으로 간다.

 

 

하지만 아직 프로그램을 보면 "This XoftSpy license has not been registered" 문자열이 뜬다.

 

 

다시 OllyDbg에서 디스어셈블러 창에 우클릭 -> Search for -> All referenced text strings -> 우클릭 -> Search for text -> "This XoftSpy license has not been registered" 검색

 

4014AD 주소로 간다.

 

 

4014AD 주소로 조건 분기 하는 곳은 401499이다.

 

그리고 등록 되었다는 문자열인 "This license of XoftSpy has been registered" 문자열은 40149B 주소로 가야 한다.

 

 

위와 같이 401499 주소의 JE 4014AD 명령어를 JMP 40149B로 수정한다.

 


Ollydbg에서 풀이

 

 

417800 주소의 명령어를 위와 같이 JMP 41899로 바꾸고 남은 byte는 NOP으로 채운다.

 

 

401499 주소의 명령어를 위와 같이 JMP 40149B 명령어로 수정한다.

 

패치된 파일을 저장하고 실행한다.

 

 

그럼 위와 같이 뜬다.

 

"This license of XoftSpy has been registered"

 


x32dbg 분석 및 풀이

 

 

x32dbg를 관리자 모드로 연 후 설치된 XoftSpy 실행 파일을 올린 뒤 문자열 검색을 통해 Invalid Code를 검색한다.

 

해당 문자열을 더블 클릭하여 이동한다.

 

 

그럼 위와 같이 4174A5 주소에서 해당 문자열을 참조하고 있는데

 

41749C 주소에서 조건 분기를 하여 ZF 플래그의 값이 0이면 4174E3 주소로 점프한다.

 

 

4174E3 주소는 위와 같이 등록 키가 일치했을 때 출력하는 메시지 부분이다.

 

 

41749C 주소의 JNE 명령어를 위와 같이 jmp 명령어로 바꾼다.

 

 

다시 문자열 검색을 통해 This XoftSpy license has not been registered 문자열을 검색하고 해당 문자열을 더블 클릭하여 이동한다.

 

 

그럼 위와 같이 4014AD 주소에서 해당 문자열을 참조하는데

 

401499 주소의 조건 분기에서 ZF 플래그의 값이 1이면 등록되지 않았다는 메시지 부분으로 점프한다.

 

 

위와 같이 401499 주소의 je 4014AD명령어를 jmp 40149B 명령어로 바꾼다.

 

패치된 파일을 저장하고 실행한다.

 

 

그러면 위와 같이 잘 패치되었다.

반응형

 

반응형

'전쟁 > lena tuts4you' 카테고리의 다른 글

[Lenatuts4you] 15. ReverseMe(Inline patch)  (0) 2022.11.02
[Lenatuts4you] 14. DVDMenuStudio  (0) 2022.11.02
[Lenatuts4you] 12. Teksched  (0) 2022.11.02
[Lenatuts4you] 11. fjprodsetup  (0) 2022.11.02
[Lenatuts4you] 10-3. CConvert  (0) 2022.11.02

+ Recent posts