x64dbg

  • x64dbg: 오픈소스로, 32비트와 64비트 둘 다 지원하는 윈도우 디버거

image

x64dbg의 시작화면

image

x64dbg의 사용법

기본적인 UI

  • 상단바
  1. 분석할 프로그램을 엽니다.
  2. 프로그램을 재시작합니다.
  3. 프로그램을 완전히 정지합니다.
  4. 프로그램을 실행(재개)합니다.
  5. 프로그램을 일시정지 시킵니다. 실행중인 상태에서 임의로 중단시키고 싶을 때 사용합니다.
  6. 어셈블리 코드를 한 줄 실행합니다. 만약 call을 실행하려 하면 call한 함수 내부로 진입합니다. (Step Into)
  7. 어셈블리 코드를 한 줄 실행합니다. 만약 call을 실행하려 하면 call한 함수가 ret 명령어를 실행할 때까지(리턴할 때까지) 실행한 다음 멈춥니다. (Step Over)

image

  • CPU 탭 구성

    1. 주소와 어셈블리 코드와 x64dbg나 사용자가 단 주석이 여기에 표시됨 왼쪽서부터

      1. 주소
      2. 옵코드
      3. 기계어 코드
      4. 주석

      의 순서로 표시됨 => 주소 부분에는 함수명을 알고 있을경우 함수명이 표시 이곳에서 jmpcall같은 실행 흐름을 바꾸는 어셈블리 코드를 선택하고 enter 키를 누르면 해당 부분으로 이동합니다. 되돌아올땐 -키를 사용함

    2. 현재 CPU의 레지스터 상태 표시 아래로 스크롤하면 xmm과 같은 부동소수점 관련 레지스터의 상태도 볼 수 있습니다.

    3. 1번창에서 선택한 부분에 대한 정보가 여기에 표시

    4. 현재 레지스터 상태중 rcx, rdx, r8, r9값을 보여줌 2번창과 별도로 보여주는 이유는 해당 레지스터 순서가 Windows 64비트 운영체제에서 기본적으로 사용하는 함수 호출 규약(Calling Convention)의 인자 순서이기 때문

      => 이를 통해 call 명령어에서 쉽게 인자로 어떤값들이 넘어가는지 확인함

    5. 핵스값을 보여줌

    6. 스택값을 보여줌 => 기본적으로 rsp값을 따라서 보여줌

    image

브레이크 포인트

  • 브레이크 포인트:

    리버싱에 있어서 필수적인 도구 중 하나로, 프로그램 실행 중 원하는 지점이나 특정 조건을 만족할 경우 프로그램을 멈추게 할 수 있는 기능

  • 용도:

    이를 통해 리버서는 프로그램의 시작지점부터가 아닌 분석을 원하는 특정 지점부터 분석을 하는게 가능

  • 종류:

    • 소프트웨어 브레이크 포인트,
    • 하드웨어 브레이크 포인트,
    • 메모리 브레이크 포인트

필수 단축키

  • F2
    • 소프트웨어 브레이크 포인트를 걸 때 사용하는 단축키입니다. 이미 브레이크 포인트가 걸려있는 주소에서 누를 경우 브레이크 포인트를 삭제합니다.
  • F7
    • 어셈블리 코드를 한 줄 실행합니다. 만약 call을 실행하려 하면 call한 함수 내부로 진입합니다.
  • F8
    • 어셈블리 코드를 한 줄 실행합니다. 만약 call을 실행하려 하면 call한 함수가 ret 명령어를 실행할 때까지(리턴할 때까지) 실행한 다음 멈춥니다.
  • F9
    • 프로그램의 실행을 재개합니다.
  • ctrl + g
    • 현재 창이 보여주는 주소를 바꿉니다. 디스어셈블 창에서 사용하면 디스어셈블 창이 해당 주소로 가고, 헥스덤프 창에서 사용하면 헥스덤프 창이 해당 주소로 가는 식입니다. 주소값 말고도 간단한 사칙 연산이나 함수명도 인식합니다.
  • -, +
    • 이전 또는 다음 주소로 이동합니다. call 이나 jmp 명령어의 주소로 이동했을 때, 이전 주소로 돌아가거나 다시 이동할 때 자주 쓰입니다.
    • call이나 jcc와 같은 PC(program counter)를 변경시키는 명령어를 선택한 상태에서 누르면 해당되는 주소로 이동합니다. ex) call 0x11223344` → 0x11223344로 이동
    • 선택한 어셈블리어를 수정합니다. 잔존 바이트를 NOP로 채우기를 선택하면 수정된 코드 길이가 기존 코드의 길이보다 작을 때 남는 공간을 NOP으로 자동으로 채워줍니다.

x64dbg 사용법

x64dbg로 main함수 찾는법

// hello-world.cpp
#include <stdio.h>
void main(){
    puts("hello world!\n");
}

정해진 패턴

-> Windows에서 Visual Studio 2019로 64비트 릴리즈 모드를 통해 컴파일 된 바이너리에 대해서만 쓸 수 있는 방법

  • main함수의 인자인 argc, argv, envp를 Windows API를 통해 설정하는 코드
140001222 | call <JMP.&_get_initial_narrow_environment> |
140001227 | mov rdi,rax                                 |
14000122A | call <JMP.&__p___argv>                      |
14000122F | mov rbx,qword ptr ds:[rax]                  |
140001232 | call <JMP.&__p___argc>                      |
140001237 | mov r8,rdi                                  |
14000123A | mov rdx,rbx                                 |
14000123D | mov ecx,dword ptr ds:[rax]                  |
14000123F | call hello-world.140001000                  |

함수의 호출결과 값을 함수 인자의 첫번째(ecx), 두번째(rdx), 세번째(r8)에 넣는 것을 확인할 수 있음 이를 통해 그 다음 호출하는 hello-world.140001000main함수라는것을 알 수 있음

문자열 검색

-> main함수에서 사용할법한 문자열을 검색하여 main함수를 찾는 방법

  • Az라 써져있는 아이콘을 누르면 현재 창에서 보고있는 모듈(여기서는 hello-world.exe)에 있는 문자열들을 참조하는 어셈블리어를 검색

    => hello world\n문자열을 참조하는 줄을 더블클릭하면 main함수로 이동

임포트한 함수(모듈간 호출 찾기)

-> main함수에서 사용할법한 함수를 검색하여 main함수를 찾는 방법

  • 상단 메뉴 아이콘중 옛날 핸드폰 모양으로 생긴 아이콘을 누르면 현재 창에서 보고 있는 모듈(여기서는 hello-world.exe)에 있는 모듈간 함수 호출을 검색

    => puts 함수를 호출하는 줄을 더블클릭하면 main함수로 이동

    출처: https://dreamhack.io/lecture/curriculums/3