반응형

antisniff.exe
0.71MB
Debugger Detected.exe
0.00MB
HideDebugger.dll
0.01MB
Keyfile.dat
0.00MB
ReverseMe.A.exe
0.01MB
ReverseMe.B.exe
0.01MB
ReverseMe.C.exe
0.01MB
ReverseMe.D.exe
0.01MB

 

주제

- Debugger detected and anti-anti-techniques

- 디버거 탐지 및 안티 안티 디버깅 기법 설명

 


ReverseMe.A 분석

 

프로그램을 실행하면 위와 같이 "You really did it! Congratz !!!" 문자열이 뜬다.

 

 

프로그램을 실행하면 위와 같이 

 

401073 주소에서 CreateFileA() 함수를 통해 keyfile.dat 파일이 있는지 검사한다.

 

keyfile.dat 파일이 없으면 CreateFileaA() 함수는 -1을 반환하고 -1은 0xFFFFFFFF이므로 401078 주소에서 비교했을 때 ZF 플래그가 1로 설정되고 40107B 주소의 조건 분기문은 수행되지 않은 채 에러 메세지 창을 띄우게 된다.

 

하지만 files 폴더에 keyfile.dat 파일이 있기 때문에 에러 메세지 창이 띄워지지 않고 40109A 주소로 점프한다.

 

40109A 주소로 점프한 후 4010A9 주소에서 ReadFile 함수를 호출한다.

 

 

그리고 ReadFile 함수를 이용해 파일 안의 데이터를 읽어와 비교를 한 뒤 4010D3 주소에서 4010FB 주소의 함수를 호출한다.

 

 

4010FB 주소의 함수를 실행하면 위와 같이 keyfile is not valid. Sorry 문자열이 뜬다.

 

위의 메세지가 뜨는 경우는 키 파일이 올바르지 않을 경우 나타나는 메세지 창인데 원래는 성공 메세지 창이 뜨다가 4010FB 주소의 함수가 수행되고 위의 메세지 창이 뜬 것으로 보아 안티 디버깅 기법이 적용된 것이다.

 

소프트웨어 개발자들이 자신이 개발한 프로그램이 리버싱에 당하지 않도록 일종의 방해 공작으로 자신의 프로그램에 안티 디버깅 기법을 적용하는데, 이렇게 안티 디버깅이 적용되면 프로그램을 분석하는 사람들은 바이너리를 분석하는 것이 어렵게 된다.

 

 

Ctrl + F2 키를 눌러 재실행 후 4010D3 주소에 BP를 걸고 F9를 누른 뒤 F7 키를 눌러 4010FB 주소의 함수 내부로 들어오면 위와 같다.

 

IsDebuggerPresent() 함수를 호출하는데 이 함수는 현재 실행되는 프로세스가 디버깅 중인지를 검사하는 함수이다.

 

반환값이 1이면 디버깅 중인 것으로 판단하고, 4010E2 주소로 점프하는데 4010E2 주소에는 keyfile is not valid. Sorry 문자열을 띄우는 부분이다.

 

반환값이 0이면 디버깅 중이지 않은 것으로 판단하고 4010FB 주소의 함수는 끝나게 된다.

 

 

ReverseMe.A 패치

 

그렇다면 4010FB 주소의 함수 내에서 IsDebuggerPresent 함수의 결과가 1이면, 즉 디버깅 중이면 401103 주소에서 4010E2 주소로 점프하고, keyfile is not valid. Sorry 문자열을 띄우는데

 

 

위와 같이 je 명령어 부분인 401103 주소의 값을 NOP으로 채우면 점프하지 않고 그냥 함수가 종료될 것이다.

 


Debugger Detected 분석

 

 

프로그램을 실행하면 위와 같이 뜬다.

 

 

Verify 버튼을 누르면 위와 같이 디버거가 탐지되지 않았다고 뜬다.

 

 

디버거에 올린 후 F9 키를 눌러 실행해봤는데 위와 같이 디버거가 탐지되지 않았다고 뜬다?

 

뭔가 이상하다..

 

프로그램 실행 환경이 XP 환경이 아니라서 그런가 싶다

 

ollydbg에서 열고 실행해도 탐지 되지 않았다고 뜬다

 

 

이번 문제를 인터넷에 검색해보니 위와 같이 OllyDbg로 열었을 때 Your debugger is detected !!! 메시지 창이 뜬다고 한다.

 

 

디버거에 올린 후 F8 키를 눌러 진행하면 401080 주소에서 호출하는 DialogBoxParamA 함수를 호출 후 창이 뜨게 된다.

 

그렇다면 DialogBoxParamA 함수를 호출하는 과정에서 디버거 탐지를 할 것이다.

 

https://learn.microsoft.com/ko-kr/windows/win32/api/winuser/nf-winuser-dialogboxparama

INT_PTR DialogBoxParamA(
  [in, optional] HINSTANCE hInstance,
  [in]           LPCSTR    lpTemplateName,
  [in, optional] HWND      hWndParent,
  [in, optional] DLGPROC   lpDialogFunc,
  [in]           LPARAM    dwInitParam
);

DialogBoxParamA 함수의 인자 중 lpDialogFunc 인자는 대화 상자 프로시저에 대한 포인터로 화면에 띄울 대화 상자의 주소 값을 의미한다.

 

즉, 함수 내에서 디버거 탐지를 하고 탐지가 되면 lpDialogFunc 인자에 에러 대화 상자 주소를 push 하는 것이다.

 

 

lpDialogFunc 인자에 해당하는 부분은 40106E 주소 부분이다.

 

스택에 40108C 주소를 넣고 있는데

 

40108C 주소는 위와 같이 40108B 주소에서의 ret 명령 다음 주소이다.

 

40108C 주소에 BP를 걸고 Ctrl + F2 키를 눌러 재실행 후 F9 키를 눌러 실행한다.

 

 

그럼 위와 같이 40108C 주소에서 멈추게 되는데

 

 

F8 키를 눌러 진행하다보면 위와 같이 dll 파일의 주소 영역으로 오게 된다.

 

User code 영역으로 가기 위해 Alt + F9 키를 누른다.

 

 

그러면 위와 같이 다시 40108C 주소로 이동된다.

 

 

그리고 나서 F8 키를 눌러 진행하다보면

 

401097 주소에서 4010D4 주소로 점프하지 않고, 401099 주소에서 40109C 주소로 점프한다.

 

그리고는 40109E 주소에서 4011CB 주소에 있는 함수를 호출한 뒤 LoadIconA 함수를 호출하고

 

4010BA 주소에서 SendMessageA 함수를 호출하는데 F8 키를 누르면 다시 40108C 주소로 이동한다.

 

 

40109E 주소에서 4011CB 주소에 있는 함수를 호출하는데 이 4011CB 주소에 있는 함수가 바로 디버거 탐지 함수이다.

 

 

4011CB 주소의 함수 내부로 들어가보면 위와 같은데

 

4011DB 주소에서 CreateToolhelp32Snapshot() 함수를 호출한다.

 

https://learn.microsoft.com/ko-kr/windows/win32/toolhelp/taking-a-snapshot-and-viewing-processes

 

https://learn.microsoft.com/ko-kr/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot

 

HANDLE CreateToolhelp32Snapshot(
  [in] DWORD dwFlags,
  [in] DWORD th32ProcessID
);

/*
dwFlags - 스냅샷에 포함할 시스템의 부분
th32ProcessID - 스냅샷에 포함할 프로세스의 프로세스 식별자

반환값 - 성공하면 지정된 스냅샷에 대한 열린 핸들을 반환 / 실패하면 INVALID_HANDLE_VALUE 반환
*/

 

위의 링크 중 두 번째 링크를 참고하면 CreateToolhelp32Snapshot() 함수는 프로세스에서 사용되는 힙, 모듈 및 스레드뿐만 아니라 지정된 프로세스의 스냅샷을 만드는 함수이다.

 

CreateToolhelp32Snapshot() 함수 호출 후 반환값을 ebp-4 주소에 저장하는데 ebp-4는 첫 번째 지역 변수를 의미한다.

 

그리고 ebp-12C 주소에 있는 데이터인 주소값을 esi에 담고, 40304C 주소에 있는 데이터인 주소값을 edi에 담는데 40304C 주소에 있는 데이터는 OLLYDBG.EXE 문자열이다.

 

 

그리고 나서 4011F3 주소에서 Process32First 함수를 호출하는데 이 함수는 현재 실행되고 있는 프로세스의 목록 중 첫 번째를 반환한다.

 

이 함수의 반환값이 0이면 401227 주소로 점프하는데401227 주소는 CloseHandle() 함수를 호출하는 곳이다.

 

 

Process32First 함수가 성공적으로 호출되었다면 4011FC 주소의 명령이 수행되는데

 

Process32First 함수의 반환값인 프로세스의 이름이 담긴 eax와 edi를 스택에 넣고 lstrcmpiA 함수로 비교한다.

 

비교 결과가 일치하면 401234 주소로 점프하여 디버거가 탐지되었다는 메세지 창을 띄운다.

 

 

비교 결과가 일치하지 않으면 40120A 주소의 명령이 수행되는데 Process32Next 함수를 호출한다.

 

 Process32Next 함수는 프로세스 목록 중 다음 프로세스를 가져오는 함수이다.

 

이 함수의 결과로 성공적으로 프로세스를 가져왔다면 lstrcmpiA 함수로 비교한 뒤 같으면 401234 주소로 점프하여 디버거가 탐지되었다는 메세지 창을 띄우고, 같지 않으면 40120A 주소로 점프하여 Process32Next 함수를 다시 호출한다.

 

즉, 위의 루프에서는 스냅샷 된 프로세스 목록에서 OLLYDBG.EXE 문자열과 일치한 프로세스가 나올 때까지 프로세스 정보를 가져와 비교한다.

 

비교 후 같으면 디버거가 탐지되었다는 메세지 창을 띄우는 것이다.

 

 

Debugger Detected 패치

 

 

4011CB 주소에 있는 함수 프롤로그 부분을

 

위와 같이 ret 명령으로 수정함으로써 바로 리턴되게 한다.

 

 

그러면 디버거에서 실행하더라도 위와 같이 뜬다.

 


다른 파일들도 모두 디버거 탐지 실습 파일인데 실행 결과는 같지만 OllyDbg에 올려보면 다른 결과가 나온다고 한다.

 

반응형

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

[Lenatuts4you] 21. Imports rebuilding  (2) 2022.11.05
[Lenatuts4you] 20. unpacking  (7) 2022.11.04
[Lenatuts4you] 18. ReverseMe  (0) 2022.11.02
[Lenatuts4you] 17. KeygenMe  (0) 2022.11.02
[Lenatuts4you] 16. Urlegal, movgear  (0) 2022.11.02

+ Recent posts