[모각코] Reversing(4~5강)
08-11
x64dbg
x64dbg는 윈도우 디버거로, UI나 기능 등 많은 면에서
ollydbg를 닮았지만, ollydbg는 소스 코드가 공개되어 있지 않고,
32비트만 지원하는데 x64dbg는 오픈소스이며, 32비트와 64비트 둘다 지원함
x64dbg는 강력한 디스어셈블 엔진을 가지고 있으며, 그래프 뷰, 플러그인 등
리버싱에 있어 편리한 기능들이 내장되어 있음
사용법
-
기본 UI
- 분석할 프로그램을 염
- 프로그램을 재시작
- 프로그램을 완전히 정지
- 프로그램을 실행(재개)
- 프로그램 일시정지, 실행 중인 상태에서 임의로 중단시키고 싶을 때 사용
- 어셈블리 코드를 한 줄 실행. 만약 call을 실행하려 하면 함수 내부로 진입
- 어셈블리 코드를 한 줄 실행. 만약 call을 실행하려 하면 함수가 rect명령어를
실행할 때 까지 실행한 다음 멈춤
- UI
-
주소와 어셈블리 코드와 x64dbg나 사용자가 단 주석 표시
왼쪽에서 부터
- 주소
- 옵코드
- 기계어 코드
- 주석
rip(instruction pointer)
가 가리키는 부분은 검은색 배경으로 표시해주며
브레이크 포인트가 걸려있는 경우 빨간색 배경으로 표시됨주석 부분에 x64dbg가 주석을 다는 경우로는 여러 가지가 있는데, 가장 흔한 경우는
어셈블리 코드에서 가리키는 주소가 문자열이거나 익스포트된 함수일 경우1번에서
jmp
나call
같은 실행 흐름을 바꾸는 어셈블리 코드를 선택하고
enter
키를 누르면 해당 부분으로 이동하며 되돌아올땐-
키를 사용 -
현재 CPU의 레지스터 상태
xmm
과 같은 부동소수점 관련 레지스터의 상태도 볼 수 있음 -
1번창에서 선택한 부분에 대한 정보 표시
1번창 주석에 표시되지 않은 내용까지 상세히 표시
-
현재 레지스터 상태중
rcx
,rdx
,r8
,r9
값2번창과 별도로 보여주는 이유는 해당 레지스터 순서가 Windows
64비트 운영체제에서 기본적으로 사용하는 함수 호출 규약의 인자 순서이기 때문
이를 통해call
명령어에게 쉽게 인자로 어떤값들이 넘어가는지 확인 가능 -
헥스값
프로그램 실행에 따라 자동으로 보여주지는 않으며 다른 창에서
헥스값을 보는 명령을 내리면 이 창에서 보여지게 됨 -
스택값
기본적으로
rsp
값을 따라서 보여줌.
가운데 부분의 파란색 선은 한 함수의 스택 영역
브레이크 포인트
브레이크 포인트는 리버싱에 있어 필수적인 도구 중 하나로, 프로그램 실행 중
원하는 지점이나 특정 조건을 만족할 경우 프로그램을 멈추게 하는 기능
브레이크 포인트는 다음과 같이 3종류로 나눠짐
- 소프트웨어 브레이크 포인트
- 하드웨어 브레이크 포인트
- 메모리 브레이크 포인트
x64dbg는 3가지 종류의 브레이크 포인트 모두를 지원하며 조건을 설정하는 것 또한 가능
디스어셈브랑, 헥스덤프창, 스택창에서 오른쪽 클릭시 메뉴를 통해 브레이크 포인트를 걸 수 있음
대부분 소프트웨어 브레이크 포인트를 걸게 되는데, 보통 F2
단축기를 통해 걺
x64dbg 필수 단축키
-
F2
- 소프트웨어 브레이크 포인트를 걸 때 사용하는 단축키
이미 브레이크 포인트가 걸려있는 주소에서 누를 경우 브레이크 포인트를 삭제
- 소프트웨어 브레이크 포인트를 걸 때 사용하는 단축키
-
F7
- 어셈블리 코드르 한 줄 실행, 만약
call
을 실행하려 하면call
한 함수 내부로 진입
- 어셈블리 코드르 한 줄 실행, 만약
-
F8
- 어셈블리 코드를 한 줄 실행, 만약
call
을 실행하려 하면call
한 함수가ret
명령어를 실행할 때 까지 실행한 다음 멈춤
- 어셈블리 코드를 한 줄 실행, 만약
-
F9
- 프로그램 실행을 재개
-
ctrl + g
- 현재 창이 보여주는 주소를 바꿈. 디스어셈블 창에서 사용하면 디스어셈블 창이
해당 주소로 가는 방식, 주소값 말고도 간단한 사칙 연산이나 함수명도 인식
- 현재 창이 보여주는 주소를 바꿈. 디스어셈블 창에서 사용하면 디스어셈블 창이
-
-, +
- 이전 또는 다음 주소로 이동,
call
이나jmp
명령어의 주소로 이동했을 때,
이전 주소로 돌아가거나 다시 이동할 때 자주 쓰임
- 이전 또는 다음 주소로 이동,
-
enter 키
call
이나jcc
와 같은 PC(program counter)를 변경시키는 명령어를
선택한 상태에서 누르면 해당 주소로 이동
-
space 키
- 선택한 어셈블리어를 수정. 잔존 바이트를 NOP로 채우기를 선택하면 수정된
코드 길이가 기존 코드의 길이보다 작을 때 남는 공간을NOP
로 자동으로 채워줌
- 선택한 어셈블리어를 수정. 잔존 바이트를 NOP로 채우기를 선택하면 수정된
x64dbg 사용법
x64dbg로 main(with hello-world.exe) 함수 찾는 법
#include <stdio.h>
void main()
{
puts("hello world!\n");
}
main
함수를 찾는 방법은 여러가지가 있음
-
정해진 패턴
Visual Stuido 2019로 64비트 릴리즈 모드를 통해 컴파일 된 바이너리에
대해서만 쓸 수 있는 방법처음 시작 부분에서 4번째 라인에 있는 JMP에서
enter
를 통해 이동
이동하면 함수가 길게 있는데 해당 부분에서 조금 내려가면 다음과 같은 코드를 찾을 수 있음
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 |
-
문자열 검색
hello-world.exe
가hello world\n
을 출력한다는 점 이용상단 메뉴 아이콘 중
Az
라 써져있는 아이콘을 누르면 현재 창에서 보고있는
모듈에 있는 문자열들을 참조하는 어셈블리어를 검색x64dbg를 통해 작성한 hello-world에서 main 부분 찾기
-
임포트한 함수(모듈간 호출 찾기)
상단 메뉴 아이콘중 옛날 핸드폰 모양으로 생긴 아이콘을 누르면 현재 창에서
보고 있는 모듈에 있는 모듈간 함수 호출을 검색해줌가장 위에 있는
puts
함수를 호출하는 줄을 더블클릭하면main
함수로
이동하는 것을 볼 수 있음해당 아이콘은
Az
옆에 있음
#앞서 발견한 부분과 동일
00D01723 | E8 E0FAFFFF | call hello-world.D01208 |
00D01728 | 8BF4 | mov esi,esp | hello-world.cpp:5, esi:__enc$textbss$end+32A
00D0172A | 68 307BD000 | push hello-world.D07B30 | D07B30:"hello world!\n"
...
...
-
응용
앞서 사용한 방법들은 Windows 뿐만 아니라 Linux나 Android 등 대부분의 프로그램을
분석할 때 사용할 수 있는 방법이며, main 뿐만 아니라 원하는 함수를 찾을 때에도
사용할 수 있는 범용적이고 편리한 방법다만 찾기 원하는 팜수의 동작을 알고 있거나 유추할 수 있는 상황에서만 사용 가능
ex)
-
TCP 패킷을 처리하는 함수를 찾고 싶다
- Windows 라면
WSARecv
, Linux라면recv
나recvform
함수를 호출하는
부분을 찾아 분석을 시작
- Windows 라면
-
PDF를 처리하는 함수를 찾고 싶다
- PDF의 시그니쳐인
%PDF
문자열을 찾아 분석 시작 - Windows라면
ReadFile
, Linux면read
등의 파일을 읽어 오는 함수를
호출하는 부분을 찾아 분석 시작
- PDF의 시그니쳐인
-
x64dbg로 함수 찾는 법 - 1
디스어셈블창에서 오른쪽 클릭을 하면 나오는 메뉴
분석
- 모듈 분석
을 사용해 이용
분석이 완료되면 함수가 인식되고 인식된 함수나 반복문 부분이 진한 막대기로 표시됨
함수 찾는 법 - 2
fx
아이콘을 눌러 확인
x64dbg 따라가기 기능
-
call
,jmp
,jcc
와 같은 PC를 변경하는 명령어enter키를 사용해 이동 가능
-
mov
나lea
같은 명령어가 주소를 참조하는 경우해당 주소에서 오른쪽 클릭을 눌러 나오는 메뉴에서 이동이 가능
x64dbg 레이블과 주석
리버싱에 있어서 함수에 이름을 붙이거나 변수에 이름을 붙이는 작업은 큰 프로그램을
분석할 때 매우 중요한 작업 중 하나
x64dbg는 레이블이라는 이름오로 해당 작업을 지원
:
를 통해 레이블을 붙일 수 있음
레이블을 붙인다는 것은 곧 해당 주소의 별칭을 지정하는 것과 같다고 생각하면 됨
만약 함수의 시작점에 레이블을 붙인다면 함수의 이름이 되는 것이고,
전역 변수의 시작 주소에 레이블을 붙일 경우 변수의 이름이 되는 방식
레이블 말고도 주석을 지원하며 ;
를 통해 주석을 달 수 있음
주석은 해당 주소에 설명을 다는 개념
만약 주석과 레이블이 동시에 달려있는 경우 주석만 보이지만, 실제로는 레이블이
사라지지 않음
참고자료
dreamHack Reverse Engineering