Intro

컴퓨터가 어떠한 과정으로 부팅되는지 알고 있는 것은 이후에 어떠한 악성코드가 어떤 부팅 과정에서 실행될 수 있는지에 대해 이해할 수 있는 중요한 요소이다. 부트킷과 같은 강력한 악성코드는 MBR을 변조하여 자신을 먼저 부팅시키기도 하며, 윈도우 운영체제가 실행됨과 동시에 여러 모듈을 로드할 때 로드되기도 한다. 따라서 이러한 요소들을 이해하기 위해 컴퓨터 부팅 절차에 대하여 알아보자.


Power On

우선 전원이 공급되지 않는다면 고철 덩어리에 불과하기 때문에 전원이 공급되어야 하는 것이 당연히 첫 번째 순서이다. 이러한 순서가 바로 "Power On" 단계로 전원이 공급되면 Power Supply가 외부 전압을 시스템에서 사용 가능한 전압으로 변환해준다. 이 변환된 전기 흐름은 CPU로 전달되어 CPU에 남아 있는 불필요한 내용을 제거하고 PC(Program Counter)를 초기화시킨다. 


초기화되는 값은 보통 0xF000 값을 가지는데 이 값은 메인보드에 위치한 ROM BIOS의 부트 프로그램의 주소 값을 가리킨다. 따라서 기존 PC의 값은 사라지고 ROM BIOS의 부트 프로그램의 주소가 해당 자리에 오게 되는 것이다.


ROM BIOS

위 Power On 과정을 통해 PC(Program Counter)에 존재하고 있는 ROM BIOS로 넘어오게 된다. 여기서 BIOS(Basic Input Output System)란, 하드웨어 입출력을 제어하는 컴퓨터의 가장 기본적인 프로그램이며 하드웨어와 소프트웨어가 처음으로 만나는 지점이다. ROM BIOS는 다음 동작(POST)을 수행하는데 필요한 기본적인 테스트를 먼저 수행한다. 우선 CPU의 이상 유무를 확인하고 CPU 테스트 결과가 ROM BIOS에 저장된 값과 일치하면 다음의 본격적인 POST 작업을 수행한다.


POST

ROM BIOS에서 CPU의 이상 유무를 확인한 다음 이상이 없을 경우 본격적인 POST 과정을 진행한다. POST는 Power On Self-Test로 단계별로 해당 장치에 이상이 있는지 없는지 확인하는 과정을 진행한다. 만약 이 과정을 수행하는데 문제가 있을 경우 우리가 가끔씩 들을 수 있었던 비프음 소리를 내어 우리에게 인지할 수 있도록 한다. 총 8 단계로 나뉘며 각 항목에 대하여 알아보자.


1. 시스템 버스 테스트, 시스템 버스란 CPU와 메인 메모리 간에 데이터 전송을 컨트롤하며 컴퓨터 버스 중에서 가장 중요한 역할을 수행한다. 시스템 버스는 각기 다른 3 가지 타입의 정보를 전송하는데 아래의 그림과 같이 컨트롤, 주소, 데이터이다. 프로세서와 메모리 간의 통신, 프로세서와 I/O 장치 간 데이터 전송, I/O가 DMA를  통해 메모리와 하는 통신을 담당한다.

이와 같이 시스템 버스는 데이터가 CPU와 메모리 간을 여행하기 위한 고속도로라고 생각하면 된다. 그리고 이러한 시스템 버스가 정상적으로 동작하는지 확인하기 위해 특정 시그널을 보내 테스트하여 이상이 없다면 다음 단계로 넘어가게 된다.


2. RTC 테스트, RTC는 Real Time Clock으로 "실시간 시계"라는 말 그대로의 의미를 갖고 있다. 이는 CMOS에 위치하여 컴퓨터의 전원이 꺼지더라도 설정된 시간 값을 유지하고 있으며 이후에 다시 시스템에 시간을 제공하기 위한 모듈이다. 시간 값을 유지하고 있는 것은 생각보다 중요한 요소이기 때문에 POST 과정에서 RTC의 이상 유무를 확인하고 이상이 없을 경우 다음 단계로 넘어가게 된다.


3. 시스템 비디오 구성요소 테스트, 일반적으로 그래픽 카드를 테스트하며 과정이 완료되면 모니터와 같은 표준 출력을 통해 부팅 과정을 출력한다. 부팅 시 모니터를 보면 제일 먼저 나오는 정보가 바로 그래픽 정보라는 것을 알 수가 있다. 이러한 항목들의 이상 여부를 확인한 뒤, 다음 단계로 넘어간다.


4. RAM 테스트, RAM을 테스트하는 단계로 메모리 용량만큼 숫자를 카운트하며 이와 같은 테스트를 통해 현재 RAM이 정상적인지 확인한다. 


5. 키보드 테스트, 키보드가 정상적으로 연결되었는지와 눌러진 Key가 없는지를 테스트하며, 이때 에러가 발생하면 도중에 중단되고 에러 메시지를 나타낸다. 만약 특정 키보드의 키가 눌려 있는 경우 비프음을 출력될 것이다.


6. 드라이브 테스트, 다음 단계로 시스템에 연결된 플로피나 CD, HDD와 같은 모든 드라이브에 신호를 보내 정상적인지 확인하며, 이상이 있을 경우 에러 메시지를 나타낸다. 그 후, 기타 PnP(Plug and Play) 장치나 메인보드에 연결된 장치를 검색하며 검사한다.


7~8. POST 결과 테스트 및 추가적인 BIOS Load, 앞서 수행한 POST의 결과가 BIOS에 저장된 값과 일치하는지 검사한다. 그 후 추가적인 BIOS(자체적으로 BIOS를 가진 하드웨어)가 있을 경우 해당 BIOS를 RAM으로 올린다. 


MBR

POST 과정을 아무 이상 없이 완료하게 되면 부트 프로그램이 운영체제를 로드하기 위해, 인식한 드라이브 내에서 첫 번째 섹터를 읽는다. 드라이브의 첫 번째 섹터에는 MBR(Master Boot Record)이 위치하고 있다. MBR의 첫 번째 명령어인 JMP 0x63을 통해 해당 MBR의 코드를 진행하는 동안 오류가 발생하는지 확인한다.  

MBR의 코드 내용이 정상적으로 실행이 되었다면 이제 파티션 테이블에서 부팅 가능한 파티션을 찾는다. 파티션 테이블은 위 그림에서 붉게 표시한 부분으로 부팅 가능한 파티션은 각 16바이트 중 첫 번째의 값이 0x80이 위치하고 있다. 위 예에서는 세 번째 파티션이 부팅 가능함을 알 수가 있으며 해당 VBR로 JMP 하게 된다.


VBR

VBR은 부팅 가능한 파티션의 첫 번째 섹터로, 해당 파티션에 대한 정보가 들어있다. 또한 운영체제를 로드하는 파일들이 저장되어 있는데 이후 BIOS는 파일에 부팅 권한을 넘겨주게 되고, VBR은 해당 운영체제의 커널을 메모리에 로드하는 작업을 수행하게 된다.


윈도우 운영체제의 VBR에는 클러스터 크기, MFT의 위치, 전체 섹터 등 해당 볼륨의 추가적인 정보 외에 부팅에 필요한 시스템 파일의 위치와 실행할 수 있는 코드가 포함되어 있다. 이러한 코드는 Windows Vista 이전엔 NT Loader(NTLDR)를 실행하였지만, Windows Vista부터는 BOOTMGE.EXE를 실행하게 된다. 아래의 그림을 보자.


BOOTMGR.EXE


VBR에는 BOOTMGR.EXE를 실행시키는 코드가 포함되어 있으므로 이에 따라 실행된다. BOOTMGR.EXE는 NT 부트 섹터의 system32/boot 위치를 기반으로 로드되며 자신의 체크섬을 계산한 후 0x4000000에 맵핑된다. 32비트 BmMain() 함수를 수행한 뒤 부수적인 두 개의 과정을 수행하는데 우선 흔히 노트북의 절전모드와 같이 하이버네이션 상태의 경우 WINRESUME.EXE를 로드한다. 다른 하나의 과정은 위 그림과 같이 BCD(Boot Configuration Data)를 통해 부팅을 준비한다. BCD는 NT 계열의 Boot.ini와 같은 역할로, 기본적인 부팅 정보를 획득하며 부팅을 준비한다.


WINLOAD.EXE


윈도우 비스타 이전의 NTLDR과 비슷한 기능을 수행하며 Boot Loader라고 부른다. 부트 관리자가 BCD를 참조하여 해당 위치에 있는 윈도우 로드 파일인 WINLOAD.EXE를 실행하며 제어권을 이 파일에 넘긴다. 이 파일이 실행되면 드라이버 및 기타 필요 파일과 함께 커널을 읽는다. WINLOAD.EXE가 드라이버 및 기타 필요 파일을 읽은 후 윈도우를 시작하기 위해 NTOSKRNL.EXE를 읽어 NT 커널을 로드한다.


NTOSKRNL.EXE


NTOSKRNL.EXE는 커널과 HAL(Hardware Abstraction Layer), 시스템 레지스트리 정보들을 가지고 핵심 파일들을 실행하며 OslArchTransferToKernel을 사용하여 커널로 제어를 전환시킨다. NTOSKRNL.EXE을 로드하는 단계에서 시스템 프로세스가 생성되는데 시스템 프로세스는 커널에서만 실행되는 시스템 스레드들을 호스팅 하는 프로세스로 커널과 연결되는 서브시스템을 구동하거나 관리하는 역할을 한다. 추가적으로 실행되는 파일의 목록은 아래와 같다.

이후 두 단계의 시스템 초기화 과정을 거친다. 첫 번째 과정(Phase 0)은 커널 자체를 초기화한 다음, HallInitializeBios를 호출한다. 그리고 Display Driver를 초기화하며 디버거를 시작한 뒤, 마지막으로 KillInitializeKernel을 호출한다. 두 번째 과정(Phase 1)은 InitializationDiscard, HallInitSystem, ObInitSystem, ASLR set이 진행되며 그다음으로  PsInitialisystemProcess를 호출한 다음 StartFirstUserProcess의 순서로 진행된다. 이 단계에서 그래픽 모드로 전환하게 되며, 윈도우를 시작하는 화면이 출력된다.


SMSS.EXE


기본적인 초기화가 완료되면 사용자의 세션을 만들기 위한 환경을 구성하는 SMSS.EXE(Session Manager SubSystem)를 실행한다. 이는 시스템 스레드에서 시작되며 WINLOGON 및 WIN32(CSRSS.EXE) 프로세스의 시작과 시스템 변수 설정을 비롯한 다양한 작업을 수행한다. 커널 생성 이후 최초로 생성되는 시스템 프로세스로 이후 WINLOG.EXE를 실행한다.


WINLOGON.EXE


드라이브가 모두 로드되면 WINLOGON.EXE를 로드하고 LSASS.EXE(Local Security Authority)를 실행하여 로그온 화면을 표시한다. 이후 로그온 화면에 정보를 입력하면 userinit.exe가 실행되어 사용자 정보를 읽어 승인처리를 진행한다. 성공적으로 로딩되면 HKLM\SYSTEM\LastKnownGoodRecovery에 갱신된다. 


로그온이 되면서 동시에 장치 감지 과정이 일어나는데 새로운 장치가 감지되면 Plug n Play 기능은 드라이브 파일인 CAB을 설치하고 시스템 자원을 할당한 후 장치를 마운팅 하고 설정을 완료한다. 이 과정이 모두 끝나면 사용자는 소프트웨어와 하드웨어 사이의 특별한 환경과 시스템의 상호 작용을 연결하는 GUI(Graphic User Interface)를 가지게 된다.


Reference


http://cafe.naver.com/boanproject/book1293232/16953

http://proneer.tistory.com/entry/Windows-윈도우-부팅-순서

http://forensic-proof.com/archives/178

https://neosmart.net/wiki/mbr-boot-process/

http://muhan56.tistory.com/archive/20130426

http://schoolofweb.net/컴퓨터-버스란-시스템-버스-편

https://ko.wikipedia.org/wiki/실시간_시계


'O / S > Window' 카테고리의 다른 글

Windows Multi Task  (0) 2016.07.08
Windows Service  (0) 2016.06.21
CSIDL 값  (0) 2016.02.20
Write Protection - Registry Setting  (0) 2016.01.17
Windows USB Autorn 설정  (0) 2016.01.04