PE구조

Sirius·2023년 9월 24일
0

윈도우 -exe, dll(다이나믹 링크): 여러 exe파일에서 사용가능

리눅스 -elf, 바이너리

PE파일포맷(Portable Executable File Format)
1) 파일이(File)
2) 이식가능한 다른곳에 옮겨져도(Portable)
3) 실행가능하도록(Executable)
4) 만든 포맷(Format)

-> 리눅스에서도 exe실행가능은한데 wine이라는 프로그램을 설치해야함
exe는 여기에 정의되어있는 파일들을 묶어서 실행되거나 하는것임, 여러가지 정보들이 들어가 있음(캡술화된 데이터 구조)

exe파일이 만들어지는법

1) Source.h

#include <window.h>
void main()

2) Source.obj(Source.h 컴파일시 모든 헤더파일과 소스 파일을 합쳐 하나의 기계어 코드를 생성한다.)

ox18, 0x19, 0x01, 0x02, 0x03

DLL, 리소스 데이터, Import, Export 데이터들을 처리할 수 있는 정보를 윈도우에 약속된 규약에 맞춰 기입
-> 윈도우의 기능을 사용하다보니 윈도우의 API함수를 알아야함... -> msdn레퍼런스
-> 화면 캡처를 하고 싶으면 거기 관련된 dll파일 가져와서 그안에 있는 함수 사용해야함, 즉 소스에서 그렇게 정보 정의 해주면이제 source.obj 거쳐서 dll이 링크를 해준다.

3) Binary.exe

-> 리소스같은거를 다묶고 싶음(dll, 리소스) 이것을 압축형태로 캡슐화 함 그렇게 되면 exe로 만들어짐
-> Binary.exe에는
1) PE Header라는게 있음(이거는 exe파일이야)
2) 그 아래는 메모리의 어느위치에 있는지 정의해줌(0x18, 0x19, 0x01)
3) Footer

-PE파일 정적분석
exe파일 실행안하고 들어가있는 정보들을가지고 어떤 파일인지 이해
의심되는 문자열, 사이트주소 분석

PE파일분석


헤더가 나오고 그다음 섹션정보가 나온다.
헤더정보 외울필요 없음

1) Dos Header

  1. MZ : 이미지도스헤더는 MZ(마크 즈비코프스키)헤더를 통해 MS-DOS 헤더의 시작을알림(이 바이너리가 PE파일인지 검사)

  2. PE : 이미지 NT 헤더의 구조체 위치를 알려주는 파트
    (50 45 00 00 4C)

2) Dos Stub Program

콘솔

3) NT 헤더

  1. PE: 이미지 NT 헤더의 시작 "PE\0\0"
    4바이트 바이러스에 자신의 시그니처를 심기도함

1. 파일헤더

: 이미지의 정보

  1. i386: i386에서돌아갈수있는 프로그램이다.
  2. NumberOfSections : 이파일이 가진 섹션의 개수(일반적으로 .text, .rdata, .data, .rs) 4개의 섹션이 존재함
  3. Time Data Stamp: 파일 생성날짜가 표시됨
  4. Size optional Header: 뒤에 올 옴셔너헤더 사이즈
  5. Characteristics:

2. 옵셔너 헤더

: 추가적인 정보
1. Magic

  1. MajorLinkerVersion

  2. MinorLinkerVersion

  3. SizeOfCode
    초기데이터 사이즈가 얼마냐 이런 정보들이 담겨있음
    악성코드는 이 값을 참고해서 자신의 코드를 복제할 위치 기준을 잡는다.

  4. AddressOfEntryPoint
    : 파일이 메모리에서 시작되는 지점이 바로 엔트리 포인트이다.
    물리적인 메모리에 이 실행파일들이 배치가 된다.
    어느 시작점이 분명 있다.
    A라는 프로그램이 실행될때 이 시작점을 알고 메모리에서 읽어서 동작을 한다.

6.BaseOfCode(파일이 시작되는 지점)
: 실행코드위치 -> Image Base
따라서 Image Base 와 BaseofCode를 더한 값부터 코드들이 시작된다. 여기서 코드들이 동작하게 됨

  1. ImageBase
    : 로드할 가상메모리 주소

  2. FileAlignment
    : 각 세션을 정렬하기 위한 정렬 단위

  3. SizeOfImage
    : EXE/DLL이 메모리에 로딩됐을 때 전체크기

  4. SizeOfHeaders
    : PE헤더의 크기를 알림(기본값 0x1000)

  5. IMAGE_DATA_DIRECTORY 구조체(중요)

  • VirtualAddress와 Size필드
  • Export, Import, Rsrc 디렉터리와 IAT 등의 가상 주소와 크기 정보
  1. Import -> 동적 라이브러리(dll)을 사용할 수 있게됨

    import 파일만 봐도 어느정도 어떤 기능을 하는지 예측할 수 있다.
    ex>
    -CreateFileA -> 파일에 접근한다.
    '더블클릭'하면 MSDN으로 넘어가서 확인할수있다.
    스트럭처 정보보면 파라미터 정의를 볼 수 있다.
    -CopyFileA -> 파일 복제한다.

MSDN에서 기본적으로 사용할수있는 dll을 사용할 수 있음
dll파일의 어떤 함수를 쓰겠다는 것이 다 기록되어있음

오른쪽 보면 라이브러리파일(dll)들이 배치 되어있다.
kernel32.dll은 윈도우스에서 기본적인 dll파일이다
커널모드: 운영체제이다. 드라이버나 기능들을 제어하는 기능들이 있는 함수의 집합
이거만 봐도 exe파일이 어떤 기능을 하는지 예측할 수 있다.

결론: Import 테이블을 통해 "아 이런 함수 쓰고 있구나" 이정도를 확인할 수 있다. 그다음은 아이다나 올리dbg를 쓴다.

  1. libraries
    dll파일들을 분석할 수 있는곳
    1) kernel32.dll
    2) msvcrt.dll
    3) wininet.dll : 인터넷을 하기위해서 가지고 옴, 인터넷이 연결된것임, 파일을 보내기위한 목적일수도?
    4) CreateServiceA: 서비스 등록함

  2. Sections
    PE파일에서 섹션은 프로그램의 실제 내용을 담고 있는 블록
    PE가 가상 주소 공간에 로드된 후 섹션 내용이 참고되고 실행

    파일은 다 정의가 되어있고, 실행하면 가상환경에 다 올라간다.
    실행의 실질적인 코드들은 PEBody에 들어간다.
    PE는 압축파일이다. 이 압축파일이 메모리에 올라가면서 내용들이 쫙 풀린다.(배치한다.)

1) .text : 코드섹션이라고한다.
1. 프로그램 실행을 하기위한 코드를 담는 섹션
2. CPU의 명령 포인터가 되는 IP 레지스터는 이 섹션 내에 존재하는 번지를 가짐
3. 32비트의 경우 VC++ 7.0부터 실행 기능을 가진 동시에 초기화 되지 않은 데이터를 담은 .textss섹션이 존재

2) .data : 데이터 섹션이라고 한다.
1. 초기화된 전역 변수들을 담고 있는 읽고 쓰기가 가능한 섹션
2. 64비트에서는 PE파일에서부터 .bss섹션과 .data 섹션에 병합

3) .rdata : 읽기 전용 데이터 섹션
1. 문자열 상수나 C++ 가상 함수 테이블 등을 배치
2. 코드 상에 참조하는 읽기 전용 데이터(.edata, .debug 등)도 이 섹션에 병합

4) .reloc: 기준 재배치 섹션
실행파일에 대한 기준 재배치 정보를 담고 있는 섹션

5) .edata : Export 섹션
1. 내보낼 함수에 대한 정보를 담고 있는 섹션
2. .rdata에 병합되기 때문에 DLL에서 별도의 섹션이 존재하지 않음

6) .idata : Import 섹션
1. 가져올 dll과 그 함수 및 변수에 대한 정보를 담고 있는 섹션
2. IAT(Import Address Table)이 존재
3. .rdata에 병합

7) .rsrc : 리소스 섹션
대화상자, 아이콘, 커서, 버전 정보 등의 윈도우 PE파일이 담고 있는 리소스 관련 데이터들이 배치

-> 이런 요소들이 안보이면 패킹되어있는것임(난독화)


-> 커널 32dll에서 import table을 가져왔다.

0개의 댓글