본문 바로가기
Reverse Engineering/리버싱 핵심 원리

1부 1장: 문자열 패치

by Ken out of ken 2024. 12. 29.

들어가기 앞서

이 당시에는 실습 예제의 존재를 몰라서 직접 코드를 작성하여 구현하였습니다

#include <iostream>

int main()
{
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

실습에 사용된 코드


문자열 패치(바꾸기)

코드의 시작인 main문은 디버깅의 시작에 위치해 있지 않는걸 알 수 있다

 

책에서는 이를 컴파일러가 임의로 추가시킨 stub code 라고하는데, Hello World의 main문을 찾기 위해 천천히 읽어 본 결과,  stub code에 가깝지는 않은 것 같다

Method Stub

소프트웨어 개발에 쓰이고 다른 프로그래밍 기능을 대리하는 코드
기존 코드를 시뮬레이션하거나 아직 개발되지 않은 코드를 임시로 대치하는 역할을 수행

 

오히러 커널 동작이 많고 어떤 것은 해당 프로그램이 위치하고 있는 디렉토리를 여는 것처럼 보이는 명령어도 있었으므로 내가 보기에는 CRT 초기화 코드에 더 가까워 보였다

CRT initialization

Microsoft의 C/C++ 어셈블러는 기본적으로 링커가 CRT 라이브러리를 포함하도록 설정되어 있다
이 라이브러리는 자체적인 시작 코드를 제공하며, 이 코드가 CRT 라이브러리를 초기화하고, 전역 초기화 함수들을 호출한 후 사용자가 정의한 main함수를 호출한다

 

물론 컴파일러가 대체한 stub code도 있었겠으나 알아보지 못했고 책에서도 중요한 내용은 아니라 했으니 넘어가자

 

기존 책에 나와있는 내용과는 달리 message box가 아닌 std::cout을 출력에 사용 했으므로 다른 키워드를 가지고 찾아야 했고 그 키워드가 모르는 나로서는 불안함과 함께 끝없는 F7, F2 와 Ctrl + F2를 사용해가며 천천히 찾아 갔다

찾았다!

 

"Hello Wolrd" 문자열이 바로 comment 자리에 마중나와 있어서 딱보자마자 알아볼 수 있었다

이제 문자열의 주소를 찾아 변경하면 된다

 

 

1C4044 에 문자열이 저장되어 있다고 한다

Dump window에서 Ctrl + G를 통해 해당 위치로 가면...

 

 

 이렇게 저장되어 있는것을 볼 수 있다!

 

Hello, Reversing!

 

 

이렇게 하나하나 찾기보다 더 쉬운 방법이 있다

 

 

방법 1

문자열 참조 검색

 

 

 

 

방법 2

API 모듈 검색

 

 


 

P.S.

 

1. 위험한 방식

사실 위의 방식은 굉장히 위험하다고 볼 수 있는데 이는 기존 문자열보다 더 긴 문자열로 패치하는 행위는 뒤에 있는 메모리를 덮어쓰기 때문에 다른 곳에서 문제가 생길 수 있다

일반적으로 문자열 뒤에 널널한 공간을 남겨두기 때문에 저런 동작이 가능할 뿐이지 계속해서 뒤의 메모리 영역을 침범하게되면 결국 프로그램에 문제가 생기게 된다


2. Name Mangling

C++은 기본적으로 네임 맹글링을 통해 함수들을 구분하므로 평범한 이름을 가지고 있지 않다

 

_ZST4cout <----- 이게바로 std::cout의 진짜 이름이다!