본문 바로가기
보안/리버싱

[리버싱] IDA _ HelloWorld.exe 간단 파일 분석 실습

by Nobb 2024. 2. 25.

내용

 : HelloWorld.exe 분석 실습

목차

 : 1 정적분석 -> 2 동적분석

 

사전지식

 -일반적으로 C에서 main함수는 프로그램 실행 시, 프로그래머가 작성한 코드 중 가장 먼저 실행되는 코드

   > 그러나 OS는 Binary 실행 시, 거기에 명시된 진입점부터 프로그램 실행됨.(main함수 아닐수도 있음)

   >>진입점-main함수  채우는 건 컴파일러의 몫! -- 둘 사이에 여러 함수 삽입하여 binary실행될 환경 먼저 구성 후

         main함수 호출되게함. (진입점 위치 함수를 start 함수라고 하자.)

---------->start함수 스스로 분석 연습하기!! (-> 나중엔 start함수 보고 main함수가 어디서 호출될지 쉽게 찾가능.)

 

 

 

0. HelloWorld.exe는?

  [ 1초 대기-> 'Hello,World!' 출력 ] 프로그램

/*
    File: hello-world.cpp
    Build opts:
      - /MT -> Library Static Linking
      - /DYNAMICBASE:NO -> Disable ASLR
      - /od -> Disable Optimization
*/

#include <Windows.h>
#include <stdio.h>

char* str;
int main() {
  int delay = 1000;
  Sleep(delay);  // 1000ms(1초)를 대기합니다.
  str = (char*)"Hello, world!\n";
  printf(str);
  return 0;
}

 

 

 

 

 

1. 정적분석

    *정적분석 -악성프로그램일 가능성 대비 먼저 시도하기 좋음

 - 차례: 파일열기 -> main함수 찾기 -> 문자열 검색 -> 상호 참조 -> main함수 분석 -> 함수 분석

 

 

(1) IDA로 파일 열기

HelloWorld.exe를 드래그해서 놓으면 나옴

 > 바로 OK 누르기

 

 

(2) main 함수 찾기

* 정적분석 - 주로 main함수를 찾아 분석하며 시작

    > main함수는 IDA가 자동으로 찾아주지만, 이번 실습에선 도움 안 받고 직접 찾아봄

 

--Binary에서 특정 함수 찾는 방법 2가지

  1_ 프로그램의 시작지점인 진입점부터 분석 시작 (~ 원하는 함수 찾을때까지) --분석 소요시간 큼

  2_ 대상 함수의 특성이나 프로그램의 여러 외적인 정보 이용 탐색 (이거 이용 -- 문자열검색으로)

 

 

(3) 문자열 검색

  *문자열(디버깅메세지, 로그파일생성 목적 등) -- 특성상 유용한 정보 제공 경우 많음

   1_ Shift + F12 -- Binary에 포함된 문자열 열거된 창 나타남

    2_ 그 중 'Hello, world!\n'라는 문자열 보임 --(컴파일과정 삽입X, 프로그래머가 추가했을것으로추측)

        > 더블클릭!

더블클릭 시 나오는 화면

   

 

(4) 상호 참조 (xRef)

 : 정적 분석 중 수상한 값/함수 발견 시, 이를 참조하는 함수 분석하도록 해주는 도구

    > 이걸로 'Hello, world!/n'라는 문자열이 어디서 사용되는지 추적할 예정

 -'aHelloWorld' 클릭단축키 X 누르면,

 <xref 창>이 나타남. ---> 해당 변수를 참조하는 모든 주소가 출력됨

 

 

 -첫번째 항목 더블 클릭 --> main함수 찾음

main함수

 

 

 

(5) main함수 분석

#1 F5 --> 디컴파일

main함수

 

#2 인자 분석

 *IDA  - argc, argv, envp 3개의 인자를 받음

 

/동작

 1. Sleep 함수 호출 >> 1초 대기

 2. qword_14001DE0 에 'Hello, world!\n' 문자열의 주소 넣음

 3. sub_140001060 함수 에 'Hello, world!\n' 을 인자로 전달하여 호출함 --이게 메인함수 

 4. 0 반환 

 

/sub함수 디컴파일 결과 

[ 먼저 va_start 함수를 통해 가변 인자를 처리하는 함수임을 알 수 있습니다. __acrt_iob_func 함수는 스트림을 가져올 때 사용되는 함수인데, 인자로 들어가는 1은 stdout 을 의미합니다. 따라서 문자열 인자를 받고 stdout 스트림을 내부적으로 사용하는 가변 함수임을 알 수 있습니다. 이러한 모든 정황을 통해 sub_140001060 함수는 printf 함수로 추정할 수 있습니다.]

>>>https://learn.dreamhack.io/572#7

 

/스트림이란?

 데이터가 조금씩 흘러들어온다는 의미

 > 데이터 - 스트림의 형식으로 프로세스에서 프로세스, 프로세스에서 파일 등으로 이동함.

 > OS는 stdin, stdout, stderr 같은 기본 스트림들을 프로세스마다 생성해줌

    > > 사용자-프로세스 연결해주기 위함

 > printf 함수 - stdout 을 통해 출력 데이터를 우리가 볼 수 있게 해줌

 >  scanf 함수- 키보드 입력을 stdin으로 받아서 프로세스에 전달해줌 

 

 

 

 

 

 

2. 동적분석 

    *동적분석 : 프로그램 실행하면서 분석하는 방법

 

 - 차례: main함수 진입 -> 한단계 실행 -> 함수 내부로 진입 -> 실행 중인 프로세스 조작

 

(1) main함수 진입

 -중단점 설정 및 실행 기능(디버거 필수 기능)    :필요한 실행 과정 생략 기능

  1_ 중단점 설정(Break Point, F2) -- 특정 주소로 

  2_ 실행(Run, F9)

 

 

 

(2) 한 단계 실행 (Step Over, F8)

 : 관심있는 부분 코드 정밀 분석하기 위해 사용하는 기능 

1. sub rsp, 38을 통해 main 함수가 사용할 스택 영역을 확보합니다.

2. rsp+0x20에 4 바이트 값인 0x000003e8을 저장합니다.

3. rsp+0x20에 저장된 값을 ecx에 옮깁니다. 이는 함수의 첫 번째 인자를 설정하는 것입니다.

4. Sleep함수를 호출합니다. ecx가 0x3e8이므로, Sleep(1000)이 실행되어 1초간 실행이 멈춥니다.

5. "Hello, world!\n" 문자열의 주소를 rax에 옮깁니다.

6. 아래의 메모리 덤프 창을 이용하여 0x14001a140의 데이터를 보면 실제로 해당 문자열이 저장되어 있음을 확인할 수 있습니다.

7. rax의 값을 data세그먼트의 주소인 0x14001dbe0에 저장합니다.

8. 0x14001dbe0에 저장된 값을 rcx에 옮깁니다. 이는 다음 호출할 함수의 첫번째 인자로 사용될 것입니다.

9. 0x140001060함수를 호출합니다. 우리는 정적 분석을 통해 이 함수를 printf함수라고 추측했습니다.

10. 프로그램을 확인하면, Hello, world!가 출력되어 있습니다. 정적 분석을 할 때는 함수의 기능을 추측하기 어려웠지만, 동적 분석으로는 문자열을 출력하는 함수라는 사실을 쉽게 알 수 있습니다.

11. 시작할 때 확장한 스택 영역을 add rsp, 38을 통해 다시 축소하고, ret으로 원래 실행 흐름으로 돌아갑니다.

 

 

 

(3) 함수 내부 진입 (Step Into, F7)

(Step Over가 함수의 내부로 진입 안함)

    > 어떤 함수 분석 위해 다른 함수까지 정밀 분석해야하는 경우 이용 기능

 

'보안 > 리버싱' 카테고리의 다른 글

[드림핵] rev-basic-0 실습  (0) 2024.03.03
[리버싱] IDA 기초  (0) 2024.02.25
[리버싱] x64 어셈블리어 기초 02  (0) 2024.02.25
[리버싱] x64 어셈블리어 기초 01  (0) 2024.02.25
[어셈블리어] Hello World 코드 해석  (0) 2024.02.12