본문 바로가기
Reversing

[리버싱] x64dbg로 Hello World! 리버싱 해보기

by 태균맨 2025. 9. 26.

1. 준비 : x64dbg 설치 및 Hello World 컴파일

 

해당 링크에서 다운로드 할 수 있다. 32비트/ 64비트 모두 지원한다.

https://x64dbg.com/

 

x64dbg

Built on open-source libraries x64dbg uses Qt, TitanEngine, Zydis, Yara, Scylla, Jansson, lz4, XEDParse, asmjit and snowman.

x64dbg.com

 

 

 

다운을 받고 압축을 풀면 release\x64\x64dbg.exe 를 실행하면 된다.

(32비트는 64->32)

 

실행화면

 

 

기능은 제쳐두고 다음 C언어 코드를 디버깅해 보자

 

#include <stdio.h>

int main() {
    printf("Hello, World!");
    return 0;
}

 

Hello World! 를 출력하는 C를 빌드했다.

 

2. 분석 시작 : main 함수를 찾아보자.

 

열기 (F3)
불러오기

 

불러오면 기호(심볼)로 들어온다.

 

명령에 "main"을 입력해 보면 해당 심볼의 주소를 찾을 수 있다.

* 심볼(Symbol)은 컴파일러가 코드에 붙여준 이름표다, 그 덕분에 기계어 속에서 main을 쉽게 찾을 수 있다.

 

더블클릭하여 찾아가보자

주소, 바이트, 디스어셈블리, 주석 순으로 열이 있다.

 

3. main() 함수의 시작

 

해당 디스어셈블리를 번역해 보면

 

push rbp
push rdi
sub rsp, E8
lea rbp, qword ptr ss:[rsp+20]

 

push rbp : rbp의 레지스터의 값을 스택에 푸시

push rdi : rdi의 레지스터의 값을 스택에 푸시

sub rsp, E8 : 스택 포인터(rsp)를 0xE8 (232)만큼 공간 확보

lea rbp, qword ptr ss:[rsp+20] : 확보한 공간의 안쪽(rsp+20)을 기준점 (rbp)로 설정

 

main 함수의 시작점이라고 보면 될 것 같다.

 

4. 함수 분석 : 디버깅 함수

 

lea rcx,qword ptr ds:[<__1182F9CB_FileName@cpp>]
call project1.7FF7DE50136B

 

이 부분은 함수 호출 부분인데 project1.7FF7DE50136B를 타고 가보니

 

CheckForDebugger JustMyCode

 

 

이런 함수가 나왔는데 컴파일러(Visual Studio)에서 디버깅을 위해 추가한 함수라고 한다.

 

nop                                    

 

CPU에게 건너뛰라고 지시하는 명령이다.

5. 함수 분석 : printf("Hello, World!")

lea rcx,qword ptr ds:[<"Hello, World!"...>]
call project1.7FF7DE501195             

 

printf("Hello, World!");

를 드디어 찾았다.

 

lea rcx,qword ptr ds:[<"Hello, World!"...>] : rcx라는 곳에 64비트의 포인터 "Hello, World!"라는 문자열의 주소를 담는다.

call project1.7FF7DE501195 : project1.7FF7DE501195를 호출한다.

 

여기서 project1.7FF7DE501195를 더블클릭 해서 보면

 

project1.printf 로 점프하라는 어셈블리가 나오고 또 들어가 보면

 

printf의 함수도 나온다.

6. main() 함수의 마무리

xor eax,eax                           
lea rsp,qword ptr ss:[rbp+C8]          
pop rdi                                
pop rbp                                
ret                                    

 

main 함수의 마지막 부분이다.

 

xor eax,eax : eax 레지스터를 0으로 만든다. (return 0;) , (xor 연산, 서로 같은 값이면 0이 된다)

lea rsp,qword ptr ss:[rbp+C8] : sub로 확보했던 스택 공간을 해제

pop rdi : 함수시작에서 push rdi 했던 것을 복원

pop rbp : 함수시작에서 push rbp 했던 것을 복원

ret : 함수를 호출한 곳으로 되돌아간다.

 


 

 

입문할 때 배우는 간단한 출력 코드도 어셈블리로 번역하니까 하루 종일 걸리는 것 같다.

 

다음에는 printf가 출력한 hello world! 의 문자열을 바꾸는 메모리 변조를 해봐야겠다.

'Reversing' 카테고리의 다른 글

[리버싱] 어셈블리로 Hello, World! 변경해보기  (0) 2025.10.01