본문 바로가기
CS & Reversing

[book]리버싱과 시스템 해킹의 원리(x64dbg 디버거)

by m_.9m 2023. 5. 4.

1. x64dbg 디버거

1.1 설치 및 사용

- 링크: https://sourceforge.net/projects/x64dbg/

최신 버전 설치 후 압축을 해제하면 “release” 폴더에 있는 exe로 실행이 가능하다. 

실행시 다음과 같은 창을 볼 수 있는데 메인 창에 해당하는 기능은 다음과 같다.

idx 구분 설명
(1) 프로그램 코드 어셈블리어 코드와 명령어 코드를 나타내고 있는 목적 코드
(2) 레지스터 CPU의 레지스터의 값을 보여주는 창이며, 실행 단계에서 값의 변화를 확인 가능
(3) 메모리 메모리 공간의 값을 HEX 코드(16진수)와 ASCII 코드로 보여주며, 관심 있는 주소를 설정해 값의 변화를 확인 가능
(4) 스택 함수에서 사용하는 스택을 보여줌. 지정 확인 가능
(5) 실행 상태 값 프로그램 코드 부분에서 실행되고 있는 각 해당 위치의 오프셋 값과 변경된 메모리 주소, 레지스터 내용 등의 힌트 정보를 나타냄.
(6) 함수 스택 변수 프로그램 코드에서 사용되는 매개변수와 지역변수의 위치를 레지스터 변위 값으로 표현

 

프로그램의 설정 창에서는 시스템 중단점, TLS 콜백, 진입전 중단점, DLL 진입점, 부착 중단점, 스레드 진입점, DLL 로드/DLL 언로드, 스레드 시작/끝에 대한 설정을 지정할 수 있다.

  • 시스템 중단점 - 프로세스가 초기화되어 사용자 코드를 아직 실행하지 않았을 때 발생하며, 사용자 코드를 실행하기 위한 준비 코드를 볼 수 있음
  • TLS 콜백 - TLS 콜백에서 일시 중지하며, main 함수가 실행되기 전에 파라미터를 설정할 수 있고 anti-debug 기술을 시행하기 위한 보호 기능들을 불러옴
  • 진입점 중단점 - 프로그램의 시작 지점으로 이동시켜주는 기능
  • DLL 진입점 - 디버깅 중인 프로세스가 가져온 어떠한 DLL의 시작 지점으로 이동하는 기능
  • 부착 중단점 - 실행되는 프로세스를 열었을 때, DbgUiRemoteBreakin() 함수로 들어갈 수 있도록 하는 기능
  • 스레드 진입점 - 현재의 프로세스에서 실행되었던 새로운 스레드의 처음 명령으로 이동하는 기능

1.2 디버거 기본 명령어와 단축키

1.2.1 디버거의 실행기능

1.2.2 디버거의 보조 기능

 

1.2 실습


1.2.1 실행파일

#include <windows.h>
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstanse, LPSTR IpCmdShow){
	MessageBox(NULL, "Hello World!!", "Welcome Message", MB_OK);
	return 0;
}

컴파일된 실행 파일이 32비트이기 때문에 32비트로 디버거를 실행시키고 파일을 연다.

 

명령어 코드 한 줄씩 실행

디버깅은 분석이 필요한 코드를 찾아가고 그 코드의 의미를 파악하는 것이다. 코드의 진입점부터 코드를 잘 이해하기 위해선 [F7], [F8] 코드를 활용해 코드를 한 줄씩 실행시켜야한다. “Call” 명령어 위에서 두 단축키를 비교하자면 [F7]을 사용하면 함수 내부에 따라 들어가는 반면에, [F8]은 Call 함수를 하나의 명령어로 수행한다.

 

특정 위치까지 실행

  • [F9]나 진행 아이콘으로 프로그램을 실행시키면 결과 값을 확인할 수 있는데 실행 과정에서 임의의 지점까지만 수행하고 싶다면 [F2]로 중단점을 설정하고 [F9]로 그 곳까지 실행할 수 있다. 이러한 중단점은 디버깅 동안 저장되어 있어 재시작해도 유지된다.
  • [F7] 키로 함수 내부를 실행하던 중 함수에서 벗어나고 싶을 경우 [Ctrl+F9]로 함수 끝까지 실행해 벗어날 수 있다.
  • 재시작의 경우 [Ctrl+F2]나 아이콘을 이용해 처음으로 돌아가 재 실행이 된다.
  • 프로그램 재 시작의 경우 실행 결과와 메모리를 수정한 내용은 사라지지만 중단점, 주석, 레이블 등의 정보는 사라지지 않는다.

베이스 캠프 설정하기

디버깅을 중단했다 다시 시작하는 경우 다시 시작하는 지점을 기억할 필요가 있는데, 이 지점을 베이스캠프(base camp)라고 한다. 설정하는 방법은 몇가지가 있다.

  • 중단점 설정: [F2]
  • 가장 많이 사용하는 방법으로 토글 키로 작동하느로 설정과 해제를 할 수있다. [Del]으로 중단점을 해제한다.
  • 레이블 달기: [:]
  • 디버거에서 원하는 주소에 레이블을 달 수 있다. 해당 주소에서 [:]를 사용하면 레이블이 설정된 것을 볼 수 있다. 참조는 우클릭을 통해 참조 찾기로 해당 주소를 참조하는 코드를 찾을 수 있다.
  • 주석 달기[;]
  • 원하는 위치에 주석을 달 수 있고 이런 레이블과 주석은 검색하여 찾아볼 수 있다. 보기(V)의 메뉴에서 주석이나 레이블 메뉴에서 확인 가능하다
  • 주소로 직접 이동하기
  • [Ctrl+G]키와 같은 주소 이동 단축키를 사용하면, 윈하는 위치로 바로 이동할 수 있다. 주소를 직접 알아야 사용이 가능하다.

원하는 코드 위치로 이동하기

실행코드의 메인함수와 관심있는 코드를 찾기위해선 커널 함수부터 여러번 함수의 스택을 찾아가야하는데 원래는 [F8]로 원하는 기능을 확인한 후 그 앞에 중단점을 설정하고 [Ctrl+F2]로 다시 시작한 후 [F9]로 중단점까지 실행한다. 그 뒤로 [F7]을 이용해 함수 내부로 들어가는데 이는 효율적이지 못하기 때문에 요령이 필요하다.

 

문자열 검색 방법

만약 프로그램 실행하는 결과에 특정 문자열이 표시된다면 찾는 방법이 있다. 다음을 찾기에서 3가지 검색 범위가 표시되는데 “현재 구역”은 현재 섹션, “모든 모듈”은 DLL 라이브러리까지 포함하여 선택한다.

 

문자열 검색 결과창

 

API 검색 방법

문자열은 ASCII 코드 기준 영어 문자열 위주로 검색된다. 따라서 한글은 검색되지 않는데 이럴 때 유용한 방법이 API 검색이다. 특정 API 검색은 “모듈간 호출(I)”를 선택해 다음과 같은 API가 사용된 곳의 코드가 나타난다.

대부분의 윈도우 프로그램에서 사용하는 msvcrt.dll아너 user232.dll에서 제공하는 주요 API 내용에 익숙해지는 것이 좋다.