With 리버싱 핵심원리
리버싱을 하기에 앞서 필요한 파일들을 다운로드하자.
Hello World!.exe (exex 파일의 확장자를 exe로 바꿔주면 된다.) -> 리버싱할 프로그램
OllyDbg -> 디버깅 프로그램
파일을 분석하는 데는 두 가지 방법이 있다.
1. 정적 분석
파일의 겉모습을 관찰하여 분석하는 방법이다.
말 그대로 멈춰있는 프로그램의 구성을 분석하는 방법으로 동적 분석 전 미리 프로그램의 구조와 흐름을 확인할 수 있다.
2. 동적 분석
파일을 실행시켜서 파일의 행동을 분석하고 코드의 흐름, 메모리 상태 등을 실시간으로 분석하는 방법이다.
보통의 경우 정적 분석을 통해 해당 프로그램의 기본 정보를 수집하고, 프로그램의 동작 원리와 구조를 분석한 뒤 동적 분석을 통해 추가적인 프로그램의 흐름을 실시간으로 분석한다.
OllyDBG 써보기
두 파일을 다운로드하고 Ollydbg를 열고, HelloWorld.exe를 열면 무언가 뜬다. (상단 File -> Open)
작게 뜬 창의 모서리를 끌어 창을 키워주자
보이는 화면을 설명해주자면,
좌측상단(Code Window) : 기본적으로 disassembly code를 표시해주고, 실질적인 코드 분석이 진행되는 창
우측상단(Register Window) : CPU의 Register 값을 실시간으로 표시해주고 수정도 가능하다.
좌측하단(Dump Window) : 프로세스에서 원하는 메모리 주소 위치를 Hex와 ASCII/Unicode 값으로 표시하고 수정도 가능하다.
우측하단(Stack Window) : ESP register가 가르키는 프로세스 Stack 메모리를 실시간으로 표시해주고 수정도 가능하다.
HelloWorld.exe 디버깅
다운로드한 HelloWorld.exe를 OllyDBG에서 열어보자.
먼가 엄청 복잡한 코드+화면이 보여서 엄청 어지럽다...
(설명이 편하도록 숫자를 매겼다.)
우리는 주로 1번 창을 보면서 리버싱을 할 것이다. 코드가 있는 창이고, 코드의 주 흐름이 보이기 때문이다.
2,3,4는 코드에서 메모리를 사용한다거나, Stack을 사용한다거나, Registry를 사용하는 경우에만 보면 된다.
까맣게 강조된 부분은 실행 전 현재 EIP(Instruction Point : 실행 포인트)이다. 여기서 F8혹은 F7를 이용하면 해당 코드를 실행하게 되는데, F8(Step Over)은 어떤 함수를 부를 때 호출하는 함수 코드 내부로 들어가는 것이고, F7(Step Into)는 호출 함수 코드 내부로 따라 들어가는 것이다.
CALL 0040270C를 보면 어셈블리어를 모르더라도 40270C를 '부른다'라는 것을 알 수 있다.
JMP 0040104F는 어딘가로 '점프'한다는 것을 알 수 있다.
그럼 무엇을 부르고 어디로 점프하는 것인지 천천히 분석해보자.
F7로 호출하는 함수를 보자.
먼가 엄청 복잡한 코드와 함수가 호출되는 것을 알 수 있는데, 이 부분은 Visual C++ Stub Code다. Visual C++에서 프로그램 실행을 위해 자체적으로 넣은 코드로 프로그램마다 Stub Code가 다를 수 있다. 즉, 우리가 분석할 필요가 없는 부분인 것이다. F8로 이 부분을 넘어가거나 Ctrl+F2로 다시 실행해 Call 부분을 건너뛰어보자.
CALL 부분 이후 JMP를 실행하여 40104F로 오면 우리가 찾던 main으로 온 것이다.
사실 main은 아니고 이곳 어딘가 main이 있다.
어떻게 하면 복잡한 곳에서 main을 찾을 수 있을까?
아직은 초보이기 때문에 분석하는 실력이 늘 겸 F7을 이용하여 호출되는 함수를 하나하나씩 분석해보자.
이상한 함수에 들어왔다고 생각되면 Ctrl+F9를 하면 해당 함수의 끝부분까지 실행된다.
(RETN은 함수의 끝 즉, return이라고 생각하면 편하다.)
계속 노가다를 하다 보면 그냥 프로그램을 실행했을 때 띄워지는 창의 문자열들이 있는 부분을 찾을 수 있다.
(못 찾겠으면 401000으로 JMP하는 코드를 찾아보자. Hint: GetCommandLineW 이후에 있다.)
드디어 main 함수를 찾은 것이다.
main함수 부분을 다시 찾아오기 위해, 잊지 않기 위해 여러 가지 방법을 할 수 있다.
1. GoTo 명령: 401000을 기억해두었다가 Ctrl+G로 이동한 후 F4(커서까지 실행)을 하면 된다.
2. BP(Break Point) 설치: BP를 F2로 설치하고 F9(실행)을 하면 BP가 설치된 부분에서 멈춘다.
(ALT+B를 하면 Breakpoints 목록이 나타난다.)
3. 주석: ;으로 주석을 달고 주석을 찾아가는 방법이 있다.
4. 레이블: 원하는 위치에 커서를 올리고 :를 이용하여 레이블을 입력하면 직관적으로 보인다.
위 방법들로 원하는 부분을 기억해두어 필요할 때 이용할 수 있다.
주로 F2나 주석을 이용하여 기억해둔다.
앞서 일일이 함수마다 들어가서 분석하였지만, 문자열 검색을 이용하여 찾을 수도 있다.
마우스 우클릭-Search for-All referenced text strings
문자열 검색을 하면 정말 쉽게 찾을 수도 있다.
혹은 Win32 API를 이용하여 찾을 수도 있다.
창을 띄우기 위해선 Win32 API 중 user32.MessageBoxW() API를 사용해 창을 띄웠을 거라는 추측을 하고 해당 API가 호출될 때 BP를 걸거나 해당 위치로 이동하여 분석할 수 도 있다.
더 깊숙이 들어가서 DLL 코드에 직접 BP를 걸어 보는 것이다. API는 OS에서 제공한 함수이고, 실제로 API 는 .dll 파일 내부에 구현되어 있다.
View-Memory 메뉴로 가보자.
프로세스의 메모리 중 USER32 라이브러리가 로딩되어 있는 메모리 영역을 확인할 수도 있고, 프로그램 자체의 메모리를 확인할 수도 있다.
USER32 라이브러리에서 MessageBoxW 코드가 위치한 곳으로 가보자.
Search for-Name in all modules 창을 켜고 MessageBoxW를 치면 해당 함수를 찾을 수 있다.
여기서 MessageBoxW를 더블클릭하면 해당 함수의 실제 코드가 나온다.
만약 이 부분에서 BP를 걸게 된다면 프로그램이 메시지 박스를 띄우려고 해당 함수를 호출할 때 멈출 것이다.
이제 실습을 할 겸 창이 띄우는 문자열을 패치하여 다른 문자열을 띄우도록 해보자.
문자열을 패치하기 위해선 두 가지 방법이 있다.
1. 문자열 버퍼를 직접 수정
2. 다른 메모리 영역에 새로운 문자열을 생성하여 전달
1번 방법을 우선 해보자.
아까 MessageBoxW가 호출될 때 문자열 버퍼를 수정하기 위해 해당 부분에 BP를 걸어보자.
이제 F9로 실행해보자.
실행을 한 뒤 3번 창에서 4092A0로 Go to 해보자.
그러면 Hello World! 문자열이 저장된 버퍼를 볼 수 있다.
(4092A0 주소는 4번 창에서 인자로 전달된 문자열 버퍼 주소를 보면 알 수 있다.)
이제 Hexdump에서 드래그하여 수정할 부분을 선택한 뒤 Ctrl+E로 수정한다.
Hex 항목에서 00을 입력하여 NULL 을 주자.
이제 F9를 하면
이렇게 패치를 한 후 디버거가 종료되면 패치된 내용도 사라지기 때문에 파일로 저장해야 한다.
dump 창에서 변경된 내용을 선택한 후 우클릭 후 Copy to executable file 선택 후
나오는 창에서 다시 우클릭 후 save file 선택하여 저장하면 된다.
2번 방법으로도 실습해보자.
원래는 PUSH 4092A0 를 하여 Stack에 해당 문자열 주소를 넣어 파라미터로 전달한다.
그럼 여기서 4092A0 대신 원하는 문자열이 있는 주소로 바꿔주면 된다.
Dump 창에서 스크롤을 내리다 보면 00으로 도배돼있는 부분을 볼 수 있다.
이 부분은 사용하지 않는 NULL padding 영역으로 문자열을 넣어서 전달해주기 좋은 부분이다.
이렇게 적당히 문자열을 넣어준 후 PUSH 4092A0를 클릭하고 space를 누르면 명령을 수정할 수 있다.
이제 F9로 실행하면 이번 챕터는 끝이다!!
원하는 대로 패치해보고 리버싱 하고, 검색해보며 실력을 키워보자
'Reversing > 리버싱핵심원리' 카테고리의 다른 글
P2 - Unpackme #1 (0) | 2022.09.18 |
---|---|
P2 - 13 PE File Format 정리 #2 (0) | 2022.09.12 |
P2 - 13 PE File Format 정리 #1 (0) | 2022.09.11 |