윈도우 -exe, dll(다이나믹 링크): 여러 exe파일에서 사용가능
리눅스 -elf, 바이너리
PE파일포맷(Portable Executable File Format)
1) 파일이(File)
2) 이식가능한 다른곳에 옮겨져도(Portable)
3) 실행가능하도록(Executable)
4) 만든 포맷(Format)
-> 리눅스에서도 exe실행가능은한데 wine이라는 프로그램을 설치해야함
exe는 여기에 정의되어있는 파일들을 묶어서 실행되거나 하는것임, 여러가지 정보들이 들어가 있음(캡술화된 데이터 구조)
#include <window.h>
void main()
ox18, 0x19, 0x01, 0x02, 0x03
DLL, 리소스 데이터, Import, Export 데이터들을 처리할 수 있는 정보를 윈도우에 약속된 규약에 맞춰 기입
-> 윈도우의 기능을 사용하다보니 윈도우의 API함수를 알아야함... -> msdn레퍼런스
-> 화면 캡처를 하고 싶으면 거기 관련된 dll파일 가져와서 그안에 있는 함수 사용해야함, 즉 소스에서 그렇게 정보 정의 해주면이제 source.obj 거쳐서 dll이 링크를 해준다.
-> 리소스같은거를 다묶고 싶음(dll, 리소스) 이것을 압축형태로 캡슐화 함 그렇게 되면 exe로 만들어짐
-> Binary.exe에는
1) PE Header라는게 있음(이거는 exe파일이야)
2) 그 아래는 메모리의 어느위치에 있는지 정의해줌(0x18, 0x19, 0x01)
3) Footer
-PE파일 정적분석
exe파일 실행안하고 들어가있는 정보들을가지고 어떤 파일인지 이해
의심되는 문자열, 사이트주소 분석
헤더가 나오고 그다음 섹션정보가 나온다.
헤더정보 외울필요 없음
MZ : 이미지도스헤더는 MZ(마크 즈비코프스키)헤더를 통해 MS-DOS 헤더의 시작을알림(이 바이너리가 PE파일인지 검사)
PE : 이미지 NT 헤더의 구조체 위치를 알려주는 파트
(50 45 00 00 4C)
콘솔
: 이미지의 정보
: 추가적인 정보
1. Magic
MajorLinkerVersion
MinorLinkerVersion
SizeOfCode
초기데이터 사이즈가 얼마냐 이런 정보들이 담겨있음
악성코드는 이 값을 참고해서 자신의 코드를 복제할 위치 기준을 잡는다.
AddressOfEntryPoint
: 파일이 메모리에서 시작되는 지점이 바로 엔트리 포인트이다.
물리적인 메모리에 이 실행파일들이 배치가 된다.
어느 시작점이 분명 있다.
A라는 프로그램이 실행될때 이 시작점을 알고 메모리에서 읽어서 동작을 한다.
6.BaseOfCode(파일이 시작되는 지점)
: 실행코드위치 -> Image Base
따라서 Image Base 와 BaseofCode를 더한 값부터 코드들이 시작된다. 여기서 코드들이 동작하게 됨
ImageBase
: 로드할 가상메모리 주소
FileAlignment
: 각 세션을 정렬하기 위한 정렬 단위
SizeOfImage
: EXE/DLL이 메모리에 로딩됐을 때 전체크기
SizeOfHeaders
: PE헤더의 크기를 알림(기본값 0x1000)
IMAGE_DATA_DIRECTORY 구조체(중요)
MSDN에서 기본적으로 사용할수있는 dll을 사용할 수 있음
dll파일의 어떤 함수를 쓰겠다는 것이 다 기록되어있음
오른쪽 보면 라이브러리파일(dll)들이 배치 되어있다.
kernel32.dll은 윈도우스에서 기본적인 dll파일이다
커널모드: 운영체제이다. 드라이버나 기능들을 제어하는 기능들이 있는 함수의 집합
이거만 봐도 exe파일이 어떤 기능을 하는지 예측할 수 있다.
결론: Import 테이블을 통해 "아 이런 함수 쓰고 있구나" 이정도를 확인할 수 있다. 그다음은 아이다나 올리dbg를 쓴다.
libraries
dll파일들을 분석할 수 있는곳
1) kernel32.dll
2) msvcrt.dll
3) wininet.dll : 인터넷을 하기위해서 가지고 옴, 인터넷이 연결된것임, 파일을 보내기위한 목적일수도?
4) CreateServiceA: 서비스 등록함
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을 가져왔다.