선릉역 1번 출구

Hello World! Reversing 본문

Hacking & Security/Malicious code and Reversing

Hello World! Reversing

choideu 2021. 12. 24. 03:08
#include "windows.h"
#include "tchar.h"

int _tmain(int argc, TCHAR* argv[])
{
	MessageBox(NULL,
		L"Hello World!",
		L"www.reversecore.com",
		MB_OK);

	return 0;
}

이 코드를 visual studio에서 x86, release로 build를 해준다.

 

그럼 파일안에 Release라는 이름의 폴더가 생성되고 그 안의 HelloWorld.exe라는 응용 프로그램 파일이 하나 생성됨

백신이 깔려있다면 이를 악성파일로 보고 삭제하기 때문에 악성코드 분석을 진행할 때는 가상 머신에서 진행하든가 아님 백신을 잠시 꺼두자

 

그럼 이제 기계어를 어셈블리어로 변환해주는 디버거 유틸리티인 OllyDbg를 사용해 디버깅을 진행한다.

OllyDbg는 이렇게 총 4개의 window로 구성이 되는데 차례대로(code window, register window, dump window, stack window)로 구성되어 있다. 이름을 보면 각 윈도우에서 하는일이 유추가 된다.

 

사용법은 아래를 참고하자

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=cnkgh&logNo=221055602773 

 

OllyDbg 사용법

실행 화면 p.s) OllyDbg를 실행시에 아래와 같은 오류메시지가 발생하면 UDD와 Plugin의 경로가 잘못...

blog.naver.com

 

디버거가 멈춘 곳은 EP(entry point) 코드로 HelloWorld.exe의 실행 시작 주소(시작점)이다.

-EP(프로그램이 실행될 때 CPU에 의해 가장 먼저 실행되는 코드 시작 위치)

EP code에는 CALL명령어와 그 다음 명령어 JMP가 있는데 해석하면 00401636을 호출한 후, 004010EA로 점프하라는 뜻이다.

첫 디버깅에서의 목표는 main함수를 찾는 것이고 그 안에 선언된 MessageBox()함수 호출을 확인하는 것이다.

 

*맨 오른쪽에 빨간 글씨는 코드에서 호출하는 API 함수 이름임

읽어보면 소스 코드에 작성하지 않은 함수 이름들이 적혀있는데 이 말은 우리가 찾는 main 함수가 아니라는 뜻이다.

이 부분은 visual C++에서 프로그램 실행을 위해 추가시킨 visual C++ stub code임(컴파일러 종류와 버전별로 stub code 모양이 달라짐)

다양한 call함수 내부를 F7 key를 통해 들어가서 확인한 결과 00401000이 Main함수의 주소임을 확인함

 

*계속해서 디버깅을 하다보면 처음 EP코드부터 새로 시작하기 때문에 불편함 -> 중간중간 코드에서 분석을 원하는 중요 포인트를 지정해 그 포인트로 빠르게 갈 수 있는 방법을 잘 기록해 둠

1. Goto 명령[ctrl+G]

2. BP(break point)설치[ctrl+F2] + [F9]

3. 주석[;]

4. 레이블[:]

 

원하는 코드 빨리 찾아내기

1. 코드 실행해 보기(위 코드에서 main이 실행되면 messageBox()함수가 실행돼 Hello World메시지 박스가 출력됨)

-프로그램의 기능이 명확한 경우 명령어를 하나하나 실행하면서 원하는 위치를 찾아감

-코드의 크기가 크고 복잡한 경우 적절하지 않음

2. 문자열 검색[all reference text strings]

ollydbg의 경우 디버깅할 프로그램을 처음 로딩할 때 사전 분석 과정을 거침 -> 프로세스 메모리를 흝어서 참조되는 문자열과 호출되는 API들을 뽑아 따로 목록 정리를 함

dump window에서 주소 검색[ctrl+G]

//코드와 데이터 영역이 나눠져 있음

3. API 검색 방법 [all intermodular calls]

코드에서 사용된 API 호출 목록만 보고 싶을 때 사용

이 코드는 프로그램에 무언가를 출력하는 코드이기 때문에 Win32 API를 사용했다고 짐작이 가능함(windows 프로그래밍에서 모니터 화면에 뭔가를 출력하려면 win32 api를 사용해야하기 때문) -> 사용되었을 법한 Win32 API 호출을 예상해 API 호출 목록을 봄 

all intermodular calls

4. api 코드에 직접 BP

packer/protector를 사용하면 파일 구조가 변경되어 API호출이 보이지 않고 디버깅이 어려워짐

이때는 process memory에 loading된 library에 직접 BP를 걸어야함 

//API라는 것은 OS에서 제공한 함수이고, 실제로 API는 C:\Windows\system32 폴더에 *.dll 파일 내부에 구현되어 있음

->우리가 만든 프로그램이 어떤 의미 있는 일(I/O)을 하려면 반드시 OS에서 제공된 API를 사용해 OS에게 요청하고, 그 API가 실제 구현된 시스템 DLL file이 process memory에 로딩되어야 함! 

memory map을 확인해보면 아래 표시한 영역이 USER32 라이브러리가 로딩된 메모리 영역임을 알 수 있다.

stack window에서 CALL to MessageBoxW from HelloWor.0040100E는 MessageBoxW는 40100E 주소에서 호출되었으며, 함수 실행이 종료되면 401014주소로 리턴한다는 의미이다.

 

문자열 패치

패치는 중요한 주제임

기존 응용 프로그램의 버그를 수정하거나, 새로운 기능을 추가시킬 수 있음

패치 대상은 파일 혹은 메모리가 될 수 있고, 프로그램의 코드와 데이터 모두 패치가 가능함

*목표(Hello world -> 다른 문자열로 바꾸기)

1. 문자열 버퍼 직접 수정

dump window에서 [ctrl+G]를 사용해서 아까 구한 주소로 이동

문자열이 차지하는 영역을 [ctrl+E]를 사용해 새로운 문자열로 덮어씀

UNICODE는 2byte가 필요함. NULL은 유니코드에서 입력 불가 -> HEX에서 NULL 입력하기

text 영역이 바뀜

제대로 실행이 됨

2. 다른 메모리 영역에 새로운 문자열을 생성해 전달

원본보다 더 긴 문자열로 패치해야 한다면 1.번 방법은 적절하지 않음

Hello World라는 문자열을 410D24라는 주소를 사용해 파라미터로 전달하고 있음

그럼 메모리 영역에 새로운 문자열을 적고 그 주소를 PUSH에 적어주면 됨

dump 영역을 내리다보면 NULL로 padding되어 있는 곳을 찾을 수 있는데 여기에 문자열을 적어주면 됨

긴 문자열도 패치 가능

 

 

//원하는 코드 빨리 찾아내기 참고 사이트

https://reversecore.com/5

'Hacking & Security > Malicious code and Reversing' 카테고리의 다른 글

Stack  (0) 2021.12.24
Endian  (0) 2021.12.24
Reverse Engineering  (0) 2021.12.23
Code Injection  (0) 2021.12.16
DLL Injection  (0) 2021.12.15
Comments