no image
네트워크 패킷 캡처 (Windows)
개요 네트워크 패킷을 캡처하기 위한 방법에 대해 알아보고 이에 대해 대응방안이 무엇이 있을지 고민한 내용 네트워크 캡처 라이브러리 실제 wireshark와 같이 네트워크 패킷을 직접 캡처하여 패킷 내용 및 통신 IP 등을 확인 Packet.dll (Npcap) NMAPI.dll (MS - Microsoft Network Monitor3) wpcap.dll (Winpcap) 이러한 방식의 경우 동작 중인 Process의 DLL 목록을 확인하여 대상 프로세스를 확인 할 수 있다. ETW (Event Tracing for Windows) ETW의 경우 Windows에서 제공해주는 기본 기능으로 관련 DLL은 ADVAPI32.dll로 위와 같이 탐지하기에는 너무 보편적인 경우이다. 이를 탐지하기 위해서 고려할 ..
2020.11.25
no image
Windows Event Message
Windows Application일반적으로 프로그램이란 실행하면 작성한 코드의 순서대로 동작하는 것으로 생각할 수 있다. 하지만 Windows GUI 응용프로그램은 실행된 후에 단지 윈도우를 출력할 뿐이며, 일반적으로 아무것도 하지 않는다. 이런 프로그램은 사용자가 키보드 입력이나 마우스 버튼 클릭으로 ‘이벤트’가 발생되면 그때마다 대응되는 처리를 하는 방식으로 동작한다.이러한 ‘이벤트 반응형’ 프로그램이 동작하기 위해서는 우선 이벤트가 발생했음을 프로그램에 알리는 구조가 필요하다. Windows에서는 각각의 응용프로그램이 마우스나 키보드로부터 직접 입력을 받지 않는다. 대신 이러한 이벤트가 발생하는지 Windows가 확인한 뒤, 이벤트가 발생했을 때 응용프로그램에 통지한다.[그림 1] 이벤트 전달 과..
2016.07.13
no image
Windows Multi Task
개요 우리는 학교 과제를 하기 위해 HWP나 Word, Excel, PPT 등의 응용프로그램을 실행해야 한다. 하지만 단순히 이러한 동작만을 하는 것이 아니라 노래를 듣는 동시에 코드를 짜거나, 이에 더해 PC 톡으로 친구들에게 물어보기도 한다. 우리가 이러한 프로그램들을 실행하면 결과적으로 CPU에서 명령어를 처리하게 된다. 그렇다면 어떻게 CPU가 하나뿐이더라도 동시에 여러 작업이 가능해지는 것일까? 이를 위해 프로세스와 스레드가 어떻게 동작하는지에 대하여 알아보자. 프로그램은 일반적으로 하드 디스크 등에 저장되어 있는 실행코드를 뜻하고, 프로세스는 프로그램을 구동하여 프로그램 자체와 프로그램의 상태가 메모리 상에서 실행되는 작업 단위를 지칭한다. 예를 들어, 하나의 프로그램을 여러 번 구동하면 여러..
2016.07.08
Windows Service
Introdution윈도우 운영체제에 있어 우리가 흔히 직접 실행할 수 있는 프로그램 이외에 우리가 직접 실행하지 않아도 실행되는 프로세스가 있다. 이 중 서비스는 보통 시스템의 시작과 함께 시작되어 윈도우의 핵심 프로세스의 기능을 수행한다. 중요한 만큼 사용자의 개입을 최소화하기 위해 백그라운드에서 동작한다. 프로세스에 대한 제어권을 우리가 갖지 않고 윈도우의 서비스 제어 관리자가 가지고 있기 때문에 일반적인 방법으로 서비스를 분석할 수 없다. 이러한 요인들로 인해 악성코드 제작자는 서비스를 통해 백그라운드라는 점, 사용자 개입의 최소화 등의 이점을 누릴 수 있다. 따라서 이번 문서에서는 서비스가 어떻게 동작하는지, 그리고 이를 분석하기 위해서는 어떠한 방식을 사용해야 하는지에 대하여 알아보자. Ser..
2016.06.21
Windows Boot Process (Vista 이상ver 부팅 과정)
Intro컴퓨터가 어떠한 과정으로 부팅되는지 알고 있는 것은 이후에 어떠한 악성코드가 어떤 부팅 과정에서 실행될 수 있는지에 대해 이해할 수 있는 중요한 요소이다. 부트킷과 같은 강력한 악성코드는 MBR을 변조하여 자신을 먼저 부팅시키기도 하며, 윈도우 운영체제가 실행됨과 동시에 여러 모듈을 로드할 때 로드되기도 한다. 따라서 이러한 요소들을 이해하기 위해 컴퓨터 부팅 절차에 대하여 알아보자. Power On우선 전원이 공급되지 않는다면 고철 덩어리에 불과하기 때문에 전원이 공급되어야 하는 것이 당연히 첫 번째 순서이다. 이러한 순서가 바로 "Power On" 단계로 전원이 공급되면 Power Supply가 외부 전압을 시스템에서 사용 가능한 전압으로 변환해준다. 이 변환된 전기 흐름은 CPU로 전달되어..
2016.04.13
CSIDL 값
CSIDL_DESKTOP = 0 CSIDL_INTERNET = 1 CSIDL_PROGRAMS = 2 CSIDL_CONTROLS = 3 CSIDL_PRINTERS = 4 CSIDL_MY_DOCUMENTS = 5 CSIDL_PERSONAL = 0x5 CSIDL_FAVORITES = 6 CSIDL_STARTUP = 7 CSIDL_RECENT = 8 CSIDL_SENDTO = 9 CSIDL_BITBUCKET = 0xA CSIDL_STARTMENU = 0xB CSIDL_MYMUSIC = 0xD CSIDL_MYVIDEO = 0xE CSIDL_DESKTOPDIRECTORY = 0x10 CSIDL_DRIVES = 0x11 CSIDL_NETWORK = 0x12 CSIDL_NETHOOD = 0x13 CSIDL_FONTS ..
2016.02.20
no image
Write Protection - Registry Setting
쓰기 방지 외부 장치를 연결하여 해당 장치를 분석하고자 할 경우 해당 볼륨에 파일이나 디렉터리를 생성, 변경, 삭제 하지 않는 이상 흔적이 남지 않는 줄 알았다. 하지만 직접 해본 결과, 연결 후 몇 가지 읽기 작업만 했을 뿐인데, $MFT, $LogFile, $UsnJrnl 등을 통해 확인할 수가 있었다. 따라서 외부 장치를 연결하여 분석하고자 할 때 무결성을 최대한 유지하기 위하여 쓰기 방지 작업을 선행하여야 한다. 쓰기 방지를 위한 툴들이 존재하지만 간단한 방법을 통해 쓰기 방지를 설정하는 방법에 대하여 알아보자. 여기서 사용할 방법은 레지스트리를 이용한 방법이다. 레지스트리 편집을 위해 Win+R에 regedit를 입력하여 레지스트리 편집기를 실행하자. 위 그림의 경로 HKLM\System\Cur..
2016.01.17
no image
Windows USB Autorn 설정
USB 자동실행 방지 USB가 대중화된 시점에 USB를 꽂으면 자동적으로 실행되는 AutoRun을 통해 악성코드가 유포되기도 한다. 이러한 USB 자동실행을 방지하기 위하여 설정하는 방법에 대하여 간략히 알아보자. 윈도우 + R을 통해 'gpedit.msc'를 입력해주자. 그렇다면 아래와 같은 창이 뜨는 것을 확인할 수가 있다. 여기서 우리가 찾아 들어가야 할 곳은 'Administrative Templatres'이다. 해당 부분에 들어가 윈도우 구성 요소인 'Windows Components'에 들어가 'AutoPlay Policies'에 들어가보자. 위의 그림과 같이 Turn off Autoplay이 항목이 존재하고 있는 것을 확인할 수가 있다. 저 부분이 바로 AutoRun의 실행 여부를 담당하고 ..
2016.01.04

개요

  • 네트워크 패킷을 캡처하기 위한 방법에 대해 알아보고 이에 대해 대응방안이 무엇이 있을지 고민한 내용

 

네트워크 캡처 라이브러리

실제 wireshark와 같이 네트워크 패킷을 직접 캡처하여 패킷 내용 및 통신 IP 등을 확인

  • Packet.dll (Npcap)

  • NMAPI.dll (MS - Microsoft Network Monitor3) 

  • wpcap.dll (Winpcap)

이러한 방식의 경우 동작 중인 Process의 DLL 목록을 확인하여 대상 프로세스를 확인 할 수 있다.

 

ETW (Event Tracing for Windows)

ETW의 경우 Windows에서 제공해주는 기본 기능으로 관련 DLL은 ADVAPI32.dll로 위와 같이 탐지하기에는 너무 보편적인 경우이다. 이를 탐지하기 위해서 고려할 수 있는 방안 중 하나는 TraceSession을 이용하여 탐지하는 방식이 있을 것 같다.

1) 레지스트리 내 Autologger 목록 획득

  • 해당 프로그램(게임, 악성코드 등) 실행 시 레지스트리 Autologger에 등록된 리스트(목록1)을 획득하여 이후 비교에 사용

  • Autologger에 등록된 각 키의 ‘Start’의 값이 1인 경우 부팅 시 자동으로 실행되어 TraceSession이 생성

 

Step2) ETW TraceSession 목록을 획득하여 1번 과정에서 획득한 목록과 주기적으로 비교

게임 실행 후 Windows 기본 유틸리티인 ‘logman’ 등을 활용하여 주기적으로 활성화된 ETW TraceSession을 획득(목록2)

Autologger 레지스트리(목록1)에는 존재하지 않지만 logman을 통해 확인(목록2)했을 때 존재하는 항목을 선별하여 추가된 세션이 있는 경우 이에 대해 해당 유저 및 세션 이름을 로깅

Autologger 레지스트리에는 존재하지 않지만 활성화된 TracecSession의 경우 Privatelogger/Systemlogger 등을 통해 생성됨.

이와 같이 동작하기 위해선 registry 정보 조회, windows 기본 유틸리티인 logman 사용의 과정이 필요

 

ETC.

P2P 통신의 경우 UDP 방식을 주로 사용하고 있기에 (참고 : https://gpgstudy.com/forum/viewtopic.php?t=7421), 상대방과의 통신을 확인하기 위해 netstat 같은 명령어를 사용해도 확인할 수 없음(상대와 세션을 맺지 않기(?)때문).

그렇기에 상대방 IP 및 Port 등을 확인하려면 패킷 캡쳐 필요

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

Windows Event Message  (0) 2016.07.13
Windows Multi Task  (0) 2016.07.08
Windows Service  (0) 2016.06.21
Windows Boot Process (Vista 이상ver 부팅 과정)  (0) 2016.04.13
CSIDL 값  (0) 2016.02.20

Windows Event Message

Kail-KM
|2016. 7. 13. 09:51

 

Windows Application

일반적으로 프로그램이란 실행하면 작성한 코드의 순서대로 동작하는 것으로 생각할 수 있다. 하지만 Windows GUI 응용프로그램은 실행된 후에 단지 윈도우를 출력할 뿐이며, 일반적으로 아무것도 하지 않는다. 이런 프로그램은 사용자가 키보드 입력이나 마우스 버튼 클릭으로 이벤트가 발생되면 그때마다 대응되는 처리를 하는 방식으로 동작한다.

이러한 이벤트 반응형프로그램이 동작하기 위해서는 우선 이벤트가 발생했음을 프로그램에 알리는 구조가 필요하다. Windows에서는 각각의 응용프로그램이 마우스나 키보드로부터 직접 입력을 받지 않는다. 대신 이러한 이벤트가 발생하는지 Windows가 확인한 뒤, 이벤트가 발생했을 때 응용프로그램에 통지한다.

[그림 1] 이벤트 전달 과정

좀 더 자세히 알아보면, 이러한 각 이벤트는 하드웨어의 장치 드라이버가 처리해야 할 일이다. 장치 드라이버는 이벤트를 감지했을 경우 이를 Windows에 알린다. 하지만 Windows가 각 하드웨어의 모든 부분까지 알지는 못하므로 이벤트를 좀 더 단일화된 형태로 변환한 뒤 시스템에 이를 넣는다. 시스템 큐에 추가 된 각 이벤트는 선입선출 방식으로 Windows가 하나씩 꺼내어 해당 응용프로그램에 이벤트를 넘겨준다.

 

Windows Message

사용자로부터 발생한 이벤트에 대해 각 응용프로그램의 큐에 전달된다고 하였다. 좀더 정확하게는 응용프로그램보다도 응용프로그램의 특정 윈도우에 이벤트를 알려준다고 해야한다. 이는 아래 그림과 같이, 하나의 응용프로그램이지만 여러 윈도우를 가진 경우를 생각하면 된다. 사용자가 입력한 키보드 이벤트(WM_KEYDOWN)‘Proc.exe’이란 프로세스에 도착하더라도, 어떤 윈도우가 이를 받아야하는지 나타나지 않는다면 처리가 복잡해진다.

[그림 2] 여러 윈도우를 가진 응용프로그램

이 때문에 사용자 입력 등의 이벤트는 특정 윈도우와 연관된다. Windows 에서 각각의 윈도우에 이벤트를 알리기 위해선 “Window Message”라는 구조체를 이용한다. 구조체의 첫 번째 인자를 보면 각 메시지가 윈도우 핸들을 담고 있다. 이 값을 통해 조작 대상 윈도우를 구별할 수 있다. 그리고 두 번째 인자 Message ID를 통해 어떤 이벤트가 발생했는지 알 수 있다.

typedef struct tagMSG {

  HWND        hwnd;          // Window Handle

  UINT          message;       // Message ID

  WPARAM      wParam;        // Additional information about the message

  LPARAM       lParam;         // Additional information about the message

  DWORD       time;          

  POINT         pt;             // Cursor position

} MSG, *PMSG, *LPMSG;

[코드 1] 윈도우 메시지 구조체

그렇다면 자신에게 온 메시지를 어떻게 확인할까? 위에서 말했다시피 이벤트가 발생하면 해당 응용프로그램 큐(Application Queue)에 메시지가 추가된다고 하였다. 큐에 들어가 있는 메시지는 GetMessage API를 통해 꺼내어 온다. 여기서 주목해야할 인자는 바로 첫 번째 인자로, 인자로 넘겨준 주소에 메시지 정보들을 담아 반환해준다.

BOOL WINAPI GetMessage(

  _Out_    LPMSG  lpMsg,

  _In_opt_  HWND  hWnd,

  _In_      UINT   wMsgFilterMin,

  _In_      UINT   wMsgFilterMax

);

[코드 2] GetMessage API

OllyDBG를 통해 GetMessage API 호출 부분을 확인해보자. 아래의 코드를 보면 함수를 호출하기 위해 각 인자를 Stack에 넣어주는 것을 확인할 수 있다. 여기서 확인해야 할 것은 바로 밑에서 두 번째 줄에 위치한 ‘PUSH EAX’이다. EAX에는 메시지에 대한 정보가 저장될 주소를 담고 있다. 아래 코드에서는 0x4FF8A0인 것을 직접 확인할 수 있다.

Address       Command                             Comments

00B418A1  | PUSH 0                               ; |MsgFilterMax = 0

00B418A3  | PUSH 0                               ; |MsgFilterMin = 0

00B418A5  | PUSH 0                               ; |hWnd = NULL

00B418A7  | LEA EAX,[LOCAL.24]                    ; |

00B418AA  | PUSH EAX                            ; |pMsg : 0x4FF8A0

00B418AB  | CALL DWORD PTR DS:[GetMessage]     ; \USER32.GetMessageW

[코드 3] Disassembly GetMessage

메시지 정보가 반환될 주소를 확인하고 GetMessage API를 호출해보자. 아래의 두 덤프 중 상단의 내용이 하단의 내용으로 바뀌는 것을 확인할 수 있다. 여기서 가장 중요한 것은 바로 메시지 ID0x4FF8A40x100 (WM_KEYDOWN) 메시지가 있는 것을 확인할 수 있다.

Address   Hex dump                                         ASCII

004FF8A0  CC CC CC CC|CC CC CC CC|CC CC CC CC|CC CC CC CC| ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ

004FF8B0  CC CC CC CC|CC CC CC CC|CC CC CC CC|CC CC CC CC| ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ

Address   Hex dump                                         ASCII

004FF8A0  52 0B 35 00| 00 01 00 00 | 11 00 00 00|01 00 1D 00|   R5       

004FF8B0  68 3B 3B 0D | 7E 03 00 00 |81 01 00 00|CC CC CC CC|    h;;

~ÌÌÌÌ

[코드 4] GetMessage Dump

Hex                 Decimal           Symbolic

0000                0                    WM_NULL

0001                1                    WM_CREATE

0002                2                    WM_DESTROY

0003                3                    WM_MOVE

0100                256                 WM_KEYDOWN

0201                513                 WM_LBUTTONDOWN

020a                522                 WM_MOUSEWHEEL

[ 1] 주요 Message Numbers

결국 메시지 큐에서 꺼내온 메시지는 Window Handle이 가리키는 윈도우에 전송되어 윈도우 프로시저에서 처리한다. 윈도우 프로시저는 Windows에 의해 직접 호출되기 때문에 “CALLBACK” 이라는 타입을 지정해주어야 한다. 첫 번째 인자를 통해 어떠한 Window Handle인지 알 수 있고, 두 번째 인자는 GetMessage를 통해 받은 메시지 ID가 인자로 들어오게 된다..

LRESULT CALLBACK WindowProc(

    HWND   hWnd,        // Window Handle

    UINT     uMsg,        // Message ID

    WPARAM wParam,      // argv 1

    LPARAM  lParam       // argv 2

);

[코드 5] Window Procedure

윈도우 프로시저 처리는 비교문을 통해 프로그래머가 지정한 번호의 메시지가 오는지 확인한다. 아래의 코드를 보면 CMP 명령어를 통해 GetMessage로 받은 Message ID(Local.49)0x100 (WM_KEYDOWN)인지 확인한다. 맞을 경우 사용자가 지정해 놓은 MessageBox 출력을 수행한다.

Address        Command                                  Comments

00B44ED0  |.  CMP DWORD PTR SS:[LOCAL.49], 100        ; WM_KEYDOWN

00B44EDA  |.  JE SHORT 00B44EFF

00B44EFF  |   MOV ESI,ESP

00B44F01  |.  PUSH 40

00B44F03  |.  PUSH OFFSET 00B46C08                  ; |Caption = "Message"

00B44F08  |.  PUSH OFFSET 00B46D08                  ; |Text = "Key Down!"

00B44F0D  |.  MOV EAX,DWORD PTR SS:[ARG.1]         ; |

00B44F10  |.  PUSH EAX                               ; |hOwner => [ARG.1]

00B44F11  |.  CALL DWORD PTR DS:[<MessageBox>     ; \USER32.MessageBox

[코드 6] Disassembly Window Procedure

 

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

네트워크 패킷 캡처 (Windows)  (0) 2020.11.25
Windows Multi Task  (0) 2016.07.08
Windows Service  (0) 2016.06.21
Windows Boot Process (Vista 이상ver 부팅 과정)  (0) 2016.04.13
CSIDL 값  (0) 2016.02.20

Windows Multi Task

Kail-KM
|2016. 7. 8. 18:53

 

개요

우리는 학교 과제를 하기 위해 HWP나 Word, Excel, PPT 등의 응용프로그램을 실행해야 한다. 하지만 단순히 이러한 동작만을 하는 것이 아니라 노래를 듣는 동시에 코드를 짜거나, 이에 더해 PC 톡으로 친구들에게 물어보기도 한다. 우리가 이러한 프로그램들을 실행하면 결과적으로 CPU에서 명령어를 처리하게 된다. 그렇다면 어떻게 CPU가 하나뿐이더라도 동시에 여러 작업이 가능해지는 것일까? 이를 위해 프로세스와 스레드가 어떻게 동작하는지에 대하여 알아보자.

프로그램은 일반적으로 하드 디스크 등에 저장되어 있는 실행코드를 뜻하고, 프로세스는 프로그램을 구동하여 프로그램 자체와 프로그램의 상태가 메모리 상에서 실행되는 작업 단위를 지칭한다. 예를 들어, 하나의 프로그램을 여러 번 구동하면 여러 개의 프로세스가 메모리 상에서 실행된다. 프로세스란 단순히 사용자가 실행시킨 실행 파일만을 필요로 하는 것이 아니라 프로그램을 읽어 들일 메모리와 데이터를 보관할 메모리, CPU의 레지스터 그리고 Windows의 경우 윈도우와 파일 등의 리소스도 사용하여 프로그램을 작동시킨다. 이처럼 프로그램을 관리하기 위한 환경을 묶어서 'Context'라고 한다.

 

멀티 태스크

어떻게 여러 작업을 동시에 처리할 수 있을까? 위에서 말했다시피 모든 명령어는 CPU에서 처리해주므로 동작하게 된다. CPU가 두 개일 경우 동시에 두 가지의 작업을 각각의 CPU에서 처리할 수 있겠지만, 하나의 CPU만 쓰는 PC에서는 어떻게 이러한 동시 작업이 가능해지는가에 대답은 바로 우리가 그렇게 느끼도록 하는 것이다. 사실 동시에 작업을 한다고는 하지만 정확히 말하자면 아주 짧은 시간마다 작업을 전환하여 모든 작업이 동시에 처리되는 것마냥 느끼도록 한다.

예를 들어 위의 그림과 같이 몇 개의 프로세스가 메모리에 올라와 있다고 하자. 이때 CPU가 처리할 수 있는 것은 하나의 작업뿐이다. 그렇기에 먼저 프로세스 A를 처리하고, 처리가 끝나면 이를 다시 중지하고 프로세스 B를 처리한다. 마찬가지로 B를 처리하다가 다음엔 C를 처리하는 방식으로 동작하게 된다. 이렇게만 이야기하면 당연히 멀티 태스크라는 말이 안 어울리며 단일 태스크인 것 같지만, 아주 빠른 시간 내에 이런 작업이 이루어진다면 사용자가 느끼기에는 충분히 멀티 태스크가 되는 것이다.

그렇다면 태스크의 전환은 어떻게 이루어지는지에 대하여 프로세스를 예로 알아보자. 우선 응용프로그램이 자발적으로 운영체제에게 제어를 넘기는 것이다. 이를 '비선점형 멀티 태스크'라고 하며 응용프로그램의 처리가 끝나서 함수에서 빠져나오면 Windows로 제어권이 반환되고 이 시점에서 다른 응용프로그램으로 전환하는 경우가 예이다. 하지만 이러한 협조 방식에는 문제가 있다. 바로 하나의 응용프로그램에서 제어를 반환하지 않는다면 다른 모든 응용프로그램은 동작할 기회를 갖지 못하게 된다. 운영체제는 제어권을 응용프로그램으로부터 기다려야 하기 때문에 이는 결국 운영체제가 프로세스의 실행을 제어한다고 하기 어렵다고 할 수 있다.

이러한 단점으로 인해 나온 것이 바로 '선점형 멀티 태스크' 구조로 운영체제는 응용프로그램이 제어를 넘겨줄 때까지 기다릴 필요 없이 강제적으로 실행을 중단시켜 다른 응용프로그램으로 전환 시킬 수 있다. 이는 프로세스 실행의 제어권을 운영체제가 가지고 있다고 할 수 있으며, 강제적으로 실행을 중단시키는 방법에 사용되는 것이 바로 'Interrupt'로 이는 하드웨어로부터 제어신호와 CPU 명령 처리 중에 일어나는 여러 가지 이벤트를 계기로 강제로 특정 코드를 실행하도록 하는 CPU 기능의 일종이다. 인터럽트 처리에도 여러 종류가 있지만 그 중 하드웨어 타이머(클럭)에서 정기적으로 인터럽트를 거는 것이 있다. 운영체제는 이를 설정해서 정기적으로 인터럽트를 받고, 필요에 따라 프로세스 전환에 사용한다.

선점형 태스크 전환은 태스크의 작업이 완료되지 않아도 CPU를 선점하므로 이를 위해선 태스크 스위칭이 일어날 때 기존에 실행중인 태스크의 상태를 보존하고 있다가, 이후 재선점 시에 이를 가지고 올 필요가 있다. 이러한 작업 내용 저장 위치는 작업 단위에 따라 달라지게 된다. 프로세스를 하나의 작업 단위로 볼 경우 PCB(Process Control Block)에 대하여 알아야 한다. PCB에는 프로세스에 대한 다양한 정보들이 저장되어 있는데 스위칭이 일어날 때 바로 이 PCB와 관련된 동작을 수행한다.

만약 현재 Process #A가 CPU에서 실행 중인 상태에서 Process #B로 전환이 일어나면 Process #A가 Ready 상태가 되면서 해당 프로세스의 상태나 레지스터 값 등이 Process #A의 PCB에 저장된다. 반대로 Process #B는 Running 상태가 되면서 Process #B의 PCB에 저장된 내용들을 CPU로 적재 시킨다. 이와 같은 작업을 통해 Context Switching을 진행한다.

하지만 이러한 Process의 Context Switching은 상대적으로 많은 내용을 메모리에서 CPU로 옮기고 다시 CPU에서 메모리로 옮기는 작업을 수행해야 한다. 이에 반해 Thread를 작업 단위로 볼 경우 훨씬 용이한 Context Switching가 가능해진다. Thread는 Process 보다 작은 작업 단위임을 위에서 언급하였다. 이는 Process 마다 하나의 PCB와 주소 공간을 가지는 반면에 Thread의 경우 하나의 Process 안에서 많은 내용을 공유한다. 아래의 그림을 보자.

Case #1의 경우 Process A가 Process B를 생성한 것으로 두 프로세스 간에 전혀 공유되는 요소가 없이 각각의 요소를 서로 갖고 있는 것을 확인할 수 있다. 이에 반해 Case #2의 경우 Process C가 Thread #1과 Thread #2를 생성한 경우로 두 Thread 간에 Code, Data, Heap을 Process 안에서 공유하고 있다. 다시 말해 각각의 Thread는 Stack 영역만을 개별적으로 갖는다. 아래는 실제 프로그램의 메모리를 나타낸 것으로 네 개의 Thread가 각각의 Stack 공간을 갖고 있는 것을 확인할 수 있다.

Memory map

Address Size Owner Section Contains Type Access Initial >Mapped as

006FE000 00002000 > > Stack of main thread Priv >RW RW

00A8C000 00002000 > >

00A8E000 00002000 > > Stack of thread 2. >Priv >RW RW

00B8D000 00002000 > >

00B8F000 00001000 > > Stack of thread 3. >Priv >RW RW

00C8D000 00002000 > >

00C8F000 00001000 > > Stack of thread 4. >Priv >RW RW

 

이에 관련하여 Thread를 생성하는 API인 CreateThread()에도 해당 Thread에게 할당하고자 하는 Stack의 크기를 지정해줄 수가 있다. 이와 같이 Thread릁 통한 태스크 전환은 프로세스 기준 태스크 전환보다 훨씬 교환해야 할 요소가 적어 리소스를 덜 사용하게 된다. Context Switching이 일어나는 동안 CPU는 아무런 일을 하지 못한다는 점을 고려했을 때, 이러한 시간을 줄이는 것은 당연히 중요한 요소가 된다. 따라서 유사한 동작을 하는 두 개의 Task를 만들 경우 굳이 새로운 Process로 하는 것보단 데이터를 공유하는 Thread로 하는 것이 효율적이다.


HANDLE WINAPI CreateThread(

_In_opt_   LPSECURITY_ATTRIBUTES   lpThreadAttributes,

_In_       SIZE_                  dwStackSize,

_In_        LPTHREAD_START_ROUTINE lpStartAddress,

_In_opt_   LPVOID                  lpParameter,

_In_       DWORD                   dwCreationFlags,

_Out_opt_ LPDWORD                 lpThreadId

);

 

우선 순위

마지막으로 스케줄링 우선 순위에 대하여 알아보자. 여러 개의 응용프로그램을 좋은 효율로 동작하게 하려면 어떤 것을 먼저 어느 만큼 실행할 지가 매우 중요하다. 이러한 조절을 '스케줄링'이라고 하며 이는 운영체제에 따라 조금씩 방식이 다르다. Windows의 경우 Thread 우선 순위에 기반한 방식과 라운드-로빈 방식을 조합한 것이다. 우선 순위는 어떤 Thread를 우선해서 실행할 것인가를 나타내는 정수 값으로 0~31까지의 우선 순위가 있으며, Windows 에서는 Process 마다 기본적인 우선순위를 나타내는 Priority Class를 지정하고 있다. 물론 이러한 Thread 우선순위는 Process와 Thread를 생성할 때 지정되며, 실행 도중 SetThreadPriority API를 호출하여 우선순위를 변경할 수 있다. 

 

상수

 

기본 우선 순위

 

REALTIME_PRIORITY_CLASS

 

24

 

HIGH_PRIRITY_CLASS

 

13

 

ABOVE_NORMAL_PRIORITY_CLASS

 

10

 

NORMAL_PRIORITY_CLASS

 

8

 

BELOW_NORMAL_PRIORITY_CLASS

 

6

 

IDLE_PRIORITY_CLASS

 

4

 

Windows는 실행 큐를 우선 순위가 높은 것부터 조사해서 실행 큐의 앞쪽으로 옮긴다. 그리고 CPU에 있는 Thread가 대기 상태로 넘어가게 되면 새로운 우선순위가 높은 실행 큐를 CPU로 가지고 와서 실행한다. 그리고 대기 중인 Thread에 있는 Thread가 실행 준비가 되면 실행 Queue로 옮겨져 CPU에 의해 동작되길 다시 기다린다. 이와 같은 전환은 Thread가 주어진 시간 간격을 사용한 경우 외에도 디스크 접근이나 동기화 등을 위해 자발적인 대가 상태에 들어간 경우와 실행 도중에 우선순위가 더 높은 Thread의 실행 준비가 끝났을 경우 발생한다.

하지만 이처럼 규칙에 충실한 스케줄링이 안 좋을 때가 있다. 예를 들어 우선순위가 높은 Thread가 하나일 경우에는 남겨진 Thread가 영원히 실행되지 않는다. 그래서 실행 준비를 마친 Thread가 일정시간 동안 실행 기회를 얻지 못했을 경우 Windows에서는 그 Thread의 우선순위를 일시적으로 올려주도록 되어 있다. 또한 디스크 접근이 완료되어 실행준비가 되었을 때나 GUI Thread가 동작을 시작했을 때도 그 Thread의 우선순위를 일시적으로 올려준다. 이런 조작을 'Priority Boosts'라고 한다.

 

Reference

+ [API로 배우는 Windows 구조와 원리] p.33 ~ p.38

+ "컨텍스트 스위칭", http://blog.eairship.kr/257

+ "스레드 다루기 (기초편)", http://www.jiniya.net/wp/archives/7194    

+ "x86에서 TSS", http://onestep.tistory.com/31

+ MSDN, " https://msdn.microsoft.com/"

+ "프로세스가 뭐지?", http://bowbowbow.tistory.com/16

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

네트워크 패킷 캡처 (Windows)  (0) 2020.11.25
Windows Event Message  (0) 2016.07.13
Windows Service  (0) 2016.06.21
Windows Boot Process (Vista 이상ver 부팅 과정)  (0) 2016.04.13
CSIDL 값  (0) 2016.02.20

Windows Service

Kail-KM
|2016. 6. 21. 08:59
Introdution

윈도우 운영체제에 있어 우리가 흔히 직접 실행할 수 있는 프로그램 이외에 우리가 직접 실행하지 않아도 실행되는 프로세스가 있다. 이 중 서비스는 보통 시스템의 시작과 함께 시작되어 윈도우의 핵심 프로세스의 기능을 수행한다. 중요한 만큼 사용자의 개입을 최소화하기 위해 백그라운드에서 동작한다. 프로세스에 대한 제어권을 우리가 갖지 않고 윈도우의 서비스 제어 관리자가 가지고 있기 때문에 일반적인 방법으로 서비스를 분석할 수 없다. 이러한 요인들로 인해 악성코드 제작자는 서비스를 통해 백그라운드라는 점, 사용자 개입의 최소화 등의 이점을 누릴 수 있다. 따라서 이번 문서에서는 서비스가 어떻게 동작하는지, 그리고 이를 분석하기 위해서는 어떠한 방식을 사용해야 하는지에 대하여 알아보자.


Service Control Manager(SCM)

Windows에서 서비스를 실행할 때 중요한 역할을 수행하는 것이 SCM이다. SCM은 Boot시에 시작되는 시스템 프로세스의 일종으로, 서비스를 제공하는 프로그램의 등록, 시작, 종료, 삭제 등과 같은 모든 관리를 담당한다.  일반적으로 아래의 그림과 같이 우리는 Controller를 통해 SCM에게 서비스의 실행, 중지 등을 요청하여 서비스 프로그램을 시작하고 종료할 수 있다. 이렇듯 사용자나 다른 프로그램이 Service를 조작할 경우에는 반드시 SCM을 통해야만 한다. 이를 반대로 말하면 서비스 프로그램은 SCM에서 제어할 수 있는 장치를 넣어둔 프로그램이라 할 수 있다.

서비스 프로그램은 SCM에서 제어할 수 있는 장치를 가지고 있다는 것은 서비스 프로그램의 내부에 SCM에 제어를 요청하거나 연결을 요청하는 API가 존재하고 있다는 것이다. 만약 해당 API들이 없다면 서비스 프로그램은 단순히 일반 프로그램과 다를 바가 없다. 아래는 서비스 프로그램의 간략화된 main()으로 일반적인 프로그램의 main()과는 약간 다른 코드를 갖고 있다. 일반적인 프로그램의 경우 Main()에서부터 메인 스레드를 통해 독자적으로 처리하면 되지만, 이와는 다르게 서비스 프로그램의 경우에는  Main 함수에서 프로그램과 SCM을 연결해주는 StartServiceCtrlDispatcher API를 호출해주어야 한다. 여기서 연결이란 서비스의 진입점을 SCM에게 등록해주는 것으로, 해당 API를 통해 SCM은 서비스의 제어를 가지게 되고 서비스가 정지할 때까지 제어를 돌려주지 않는다.


해당 API의 인자로 지정된 services는 배열의 형태를 가지고 있다. 아래의 코드에서 "TestSvc"는 서비스의 이름을 지정해주는 것이고, TestSvcMain은 해당 서비스 프로그램이 SCM에게 실행을 요청할 내용의 코드이다. 이는 다시 말해 서비스 전용 메인 함수로 SCM은 새롭게 스레드를 생성해서 서비스 메인의 함수를 호출한다. 따라서 우리가 이후에 분석을 할 때에 중점적으로 확인해야 할 부분이 바로 TestSvcMain이 위치한 곳이 된다.

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

int main()
{
    SERVICE_TABLE_ENTRY services[] = {{"TestSvc", TestSvcMain}, {NULL, NULL}};
    if(!StartServiceCtrlDispatcher(services))
    {
        printf("서비스 연결 실패");
        return -1;
    }
    return 0;
}


ServiceMain & Control Handler

서비스 프로그램의 전용 메인 함수(위 예의 TestSvcMain)가 SCM과 연결되어 프로세스가 생성되었지만, SERVICE_START_PENDING 상태가 된다. 이는 정식 서비스로 동작하는 것은 아니며 이를 동작시키기 위해선 자신의 서비스 상태를 지정해주어야 한다. 서비스의 상태를 제어하기 위해 서비스의 메인 함수에서는 RegisterServiceCtrlHandler API를 호출해야 한다. 이는 SCM에 제어 핸들러를 등록하기 위한 API로, SCM은 서비스를 제어할 필요가 있을 때 이 핸들러를 호출하는 방법으로 서비스에 통지한다. 이것이 등록되어야 SCM이 서비스 프로그램을 제어할 수 있다. 

SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandler( 
    _In_ LPCTSTR            lpServiceName,  
    _In_ LPHANDLER_FUNCTION lpHandlerProc
);

제어 핸들러를 등록하고 SetServiceStatus API를 통해 서비스가 시작 상태가 된 것을 SCM에 통지해야 한다. 시작된 것을 알리고자 할 때는 SERVICE_RUNNING을 인자로 해당 API를 호출하면 된다. 이러한 과정은 서비스 프로세스가 생성되고 1초 이내에 완료될 것을 기대학 때문에 그 이상 시간이 걸릴 경우 미리 설정해주어야 한다. 만약 지정한 시간이 지나도 상태가 갱신되지 않을 경우 SCM은 초기화에 실패했다고 판단하고 서비스를 종료한다. 시간 내에 SetServiceStatus를 통해 SERVICE_RUNNIGN을 지정해주었다면 비로소 정상적인 서비스 프로세스로 동작할 수 있게 된다.

BOOL WINAPI SetServiceStatus(  
    In_ SERVICE_STATUS_HANDLE hServiceStatus,  
    In_ LPSERVICE_STATUS      lpServiceStatus
);



Reference


https://ko.wikipedia.org/wiki/윈도우_서비스

[API로 배우는 Windows 구조와 원리]

[리버싱 핵심원리]



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

Windows Event Message  (0) 2016.07.13
Windows Multi Task  (0) 2016.07.08
Windows Boot Process (Vista 이상ver 부팅 과정)  (0) 2016.04.13
CSIDL 값  (0) 2016.02.20
Write Protection - Registry Setting  (0) 2016.01.17
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

CSIDL 값

Kail-KM
|2016. 2. 20. 20:40
CSIDL_DESKTOP = 0
CSIDL_INTERNET = 1
CSIDL_PROGRAMS = 2
CSIDL_CONTROLS = 3
CSIDL_PRINTERS = 4
CSIDL_MY_DOCUMENTS = 5
CSIDL_PERSONAL 	 = 0x5

CSIDL_FAVORITES = 6
CSIDL_STARTUP = 7
CSIDL_RECENT = 8
CSIDL_SENDTO = 9
CSIDL_BITBUCKET = 0xA
CSIDL_STARTMENU = 0xB
CSIDL_MYMUSIC = 0xD
CSIDL_MYVIDEO = 0xE
CSIDL_DESKTOPDIRECTORY = 0x10
CSIDL_DRIVES = 0x11
CSIDL_NETWORK = 0x12
CSIDL_NETHOOD = 0x13
CSIDL_FONTS = 0x14
CSIDL_TEMPLATES = 0x15
CSIDL_COMMON_STARTMENU = 0x16
CSIDL_COMMON_PROGRAMS = 0x17
CSIDL_COMMON_STARTUP = 0x18
CSIDL_COMMON_DESKTOPDIRECTORY = 0x19
CSIDL_APPDATA = 0x1A
CSIDL_PRINTHOOD = 0x1B
CSIDL_LOCAL_APPDATA = 0x1C
CSIDL_ALTSTARTUP = 0x1D
CSIDL_COMMON_ALTSTARTUP = 0x1E
CSIDL_COMMON_FAVORITES = 0x1F
CSIDL_INTERNET_CACHE = 0x20
CSIDL_COOKIES = 0x21
CSIDL_HISTORY = 0x22
CSIDL_COMMON_APPDATA = 0x23
CSIDL_WINDOWS = 0x24
CSIDL_SYSTEM = 0x25
CSIDL_PROGRAM_FILES = 0x26
CSIDL_MYPICTURES = 0x27
CSIDL_PROFILE = 0x28
CSIDL_SYSTEMX86 = 0x29
CSIDL_PROGRAM_FILESX86 = 0x2A
CSIDL_PROGRAM_FILES_COMMON = 0x2B
CSIDL_PROGRAM_FILES_COMMONX86 = 0x2C
CSIDL_COMMON_TEMPLATES = 0x2D
CSIDL_COMMON_DOCUMENTS = 0x2E
CSIDL_COMMON_ADMINTOOLS = 0x2F
CSIDL_ADMINTOOLS = 0x30
CSIDL_CONNECTIONS = 0x31
CSIDL_COMMON_MUSIC = 0x35
CSIDL_COMMON_PICTURES = 0x36
CSIDL_COMMON_VIDEO = 0x37
CSIDL_RESOURCES = 0x38
CSIDL_RESOURCES_LOCALIZED = 0x39
CSIDL_COMMON_OEM_LINKS = 0x3A
CSIDL_CDBURN_AREA = 0x3B
CSIDL_COMPUTERSNEARME = 0x3D

CSIDL_FLAG_CREATE 	 = 0x8000

# CSIDL_DESKTOP = 0x0
# CSIDL_INTERNET = 0x1
# CSIDL_PROGRAMS 	 = 0x2
# CSIDL_COMMON_PROGRAMS 	 = 0x17
# CSIDL_PRINTERS 	 = 0x4
# CSIDL_PERSONAL 	 = 0x5
# CSIDL_COMMON_DOCUMENTS 	 = 0x2E
# CSIDL_FAVORITES 	 = 0x6
# CSIDL_COMMON_FAVORITES 	 = 0x1F
# CSIDL_STARTUP 	 = 0x7
# CSIDL_COMMON_STARTUP 	 = 0x18
# CSIDL_RECENT 	 = 0x8
# CSIDL_SENDTO 	 = 0x9
# CSIDL_STARTMENU 	 = 0xB
# CSIDL_COMMON_STARTMENU 	 = 0x16
# CSIDL_DESKTOPDIRECTORY 	 = 0x10
# CSIDL_COMMON_DESKTOPDIRECTORY 	 = 0x19
# CSIDL_NETHOOD 	 = 0x13
# CSIDL_FONTS 	 = 0x14
# CSIDL_TEMPLATES 	 = 0x15
# CSIDL_COMMON_TEMPLATES 	 = 0x2D
# CSIDL_APPDATA 	 = 0x1A
# CSIDL_COMMON_APPDATA 	 = 0x23
# CSIDL_LOCAL_APPDATA 	 = 0x1C
# CSIDL_PRINTHOOD 	 = 0x1B
# CSIDL_ALTSTARTUP 	 = 0x1D
# CSIDL_COMMON_ALTSTARTUP 	 = 0x1E
# CSIDL_INTERNET_CACHE 	 = 0x20
# CSIDL_COOKIES 	 = 0x21
# CSIDL_HISTORY 	 = 0x22
# CSIDL_WINDOWS 	 = 0x24
# CSIDL_SYSTEM 	 = 0x25
# CSIDL_PROGRAM_FILES 	 = 0x26
# CSIDL_PROGRAM_FILES_COMMON 	 = 0x2B
# CSIDL_MYPICTURES 	 = 0x27
# CSIDL_COMMON_PICTURES 	 = 0x36
# CSIDL_PROFILE 	 = 0x28
# CSIDL_ADMINTOOLS 	 = 0x30
# CSIDL_COMMON_ADMINTOOLS 	 = 0x2F
# CSIDL_MYMUSIC 	 = 0xD
# CSIDL_COMMON_MUSIC 	 = 0x35
# CSIDL_MYVIDEO 	 = 0xE
# CSIDL_COMMON_VIDEO 	 = 0x37
# CSIDL_RESOURCES 	 = 0x38
# CSIDL_RESOURCES_LOCALIZED 	 = 0x39
# CSIDL_CDBURN_AREA 	 = 0x3B

csidl_names = {
    CSIDL_DESKTOP: "CSIDL_DESKTOP",
    CSIDL_INTERNET: "CSIDL_INTERNET",
    CSIDL_PROGRAMS: "CSIDL_PROGRAMS",
    CSIDL_CONTROLS: "CSIDL_CONTROLS",
    CSIDL_PRINTERS: "CSIDL_PRINTERS",
    CSIDL_MY_DOCUMENTS: "CSIDL_MY_DOCUMENTS",
    CSIDL_FAVORITES: "CSIDL_FAVORITES",
    CSIDL_STARTUP: "CSIDL_STARTUP",
    CSIDL_RECENT: "CSIDL_RECENT",
    CSIDL_SENDTO: "CSIDL_SENDTO",
    CSIDL_BITBUCKET: "CSIDL_BITBUCKET",
    CSIDL_STARTMENU: "CSIDL_STARTMENU",
    CSIDL_MYMUSIC: "CSIDL_MYMUSIC",
    CSIDL_MYVIDEO: "CSIDL_MYVIDEO",
    CSIDL_DESKTOPDIRECTORY: "CSIDL_DESKTOPDIRECTORY",
    CSIDL_DRIVES: "CSIDL_DRIVES",
    CSIDL_NETWORK: "CSIDL_NETWORK",
    CSIDL_NETHOOD: "CSIDL_NETHOOD",
    CSIDL_FONTS: "CSIDL_FONTS",
    CSIDL_TEMPLATES: "CSIDL_TEMPLATES",
    CSIDL_COMMON_STARTMENU: "CSIDL_COMMON_STARTMENU",
    CSIDL_COMMON_PROGRAMS: "CSIDL_COMMON_PROGRAMS",
    CSIDL_COMMON_STARTUP: "CSIDL_COMMON_STARTUP",
    CSIDL_COMMON_DESKTOPDIRECTORY: "CSIDL_COMMON_DESKTOPDIRECTORY",
    CSIDL_APPDATA: "CSIDL_APPDATA",
    CSIDL_PRINTHOOD: "CSIDL_PRINTHOOD",
    CSIDL_LOCAL_APPDATA: "CSIDL_LOCAL_APPDATA",
    CSIDL_ALTSTARTUP: "CSIDL_ALTSTARTUP",
    CSIDL_COMMON_ALTSTARTUP: "CSIDL_COMMON_ALTSTARTUP",
    CSIDL_COMMON_FAVORITES: "CSIDL_COMMON_FAVORITES",
    CSIDL_INTERNET_CACHE: "CSIDL_INTERNET_CACHE",
    CSIDL_COOKIES: "CSIDL_COOKIES",
    CSIDL_HISTORY: "CSIDL_HISTORY",
    CSIDL_COMMON_APPDATA: "CSIDL_COMMON_APPDATA",
    CSIDL_WINDOWS: "CSIDL_WINDOWS",
    CSIDL_SYSTEM: "CSIDL_SYSTEM",
    CSIDL_PROGRAM_FILES: "CSIDL_PROGRAM_FILES",
    CSIDL_MYPICTURES: "CSIDL_MYPICTURES",
    CSIDL_PROFILE: "CSIDL_PROFILE",
    CSIDL_SYSTEMX86: "CSIDL_SYSTEMX86",
    CSIDL_PROGRAM_FILESX86: "CSIDL_PROGRAM_FILESX86",
    CSIDL_PROGRAM_FILES_COMMON: "CSIDL_PROGRAM_FILES_COMMON",
    CSIDL_PROGRAM_FILES_COMMONX86: "CSIDL_PROGRAM_FILES_COMMONX86",
    CSIDL_COMMON_TEMPLATES: "CSIDL_COMMON_TEMPLATES",
    CSIDL_COMMON_DOCUMENTS: "CSIDL_COMMON_DOCUMENTS",
    CSIDL_COMMON_ADMINTOOLS: "CSIDL_COMMON_ADMINTOOLS",
    CSIDL_ADMINTOOLS: "CSIDL_ADMINTOOLS",
    CSIDL_CONNECTIONS: "CSIDL_CONNECTIONS",
    CSIDL_COMMON_MUSIC: "CSIDL_COMMON_MUSIC",
    CSIDL_COMMON_PICTURES: "CSIDL_COMMON_PICTURES",
    CSIDL_COMMON_VIDEO: "CSIDL_COMMON_VIDEO",
    CSIDL_RESOURCES: "CSIDL_RESOURCES",
    CSIDL_RESOURCES_LOCALIZED: "CSIDL_RESOURCES_LOCALIZED",
    CSIDL_COMMON_OEM_LINKS: "CSIDL_COMMON_OEM_LINKS",
    CSIDL_CDBURN_AREA: "CSIDL_CDBURN_AREA",
    CSIDL_COMPUTERSNEARME: "CSIDL_COMPUTERSNEARME"
}

csidl_display_names = {
    CSIDL_ADMINTOOLS: "Administrative Tools",
    CSIDL_CDBURN_AREA: "CD Burning",
    CSIDL_COMMON_ADMINTOOLS: "Administrative Tools",
    CSIDL_COMMON_OEM_LINKS: "OEM Links",
    CSIDL_COMMON_PROGRAMS: "Programs",
    CSIDL_COMMON_STARTMENU: "Start Menu",
    CSIDL_COMMON_STARTUP: "Startup",
    CSIDL_COMMON_ALTSTARTUP: "Startup",
    CSIDL_COMMON_TEMPLATES: "Templates",
    CSIDL_DRIVES: "My Computer",
    CSIDL_CONNECTIONS: "Network Connections",
    CSIDL_CONTROLS: "Control Panel",
    CSIDL_COOKIES: "Cookies",
    CSIDL_DESKTOP: "Desktop",
    CSIDL_DESKTOPDIRECTORY: "Desktop",
    CSIDL_FAVORITES: "Favorites",
    CSIDL_COMMON_FAVORITES: "Favorites",
    CSIDL_FONTS: "Fonts",
    CSIDL_HISTORY: "History",
    CSIDL_INTERNET_CACHE: "Temporary Internet Files",
    CSIDL_INTERNET: "Internet Explorer",
    CSIDL_LOCAL_APPDATA: "Application Data",
    CSIDL_MYMUSIC: "My Music",
    CSIDL_NETHOOD: "NetHood",
    CSIDL_NETWORK: "My Network Places",
    CSIDL_COMPUTERSNEARME: "My Network Places",
    CSIDL_MYPICTURES: "My Pictures",
    CSIDL_PRINTHOOD: "PrintHood",
    CSIDL_PRINTERS: "Printers and Faxes",
    CSIDL_PROFILE: "The user's username (%USERNAME%)",
    CSIDL_COMMON_APPDATA: "Application Data",
    CSIDL_PROGRAM_FILES: "Program Files",
    CSIDL_PROGRAM_FILES_COMMON: "Common Files",
    CSIDL_PROGRAM_FILES_COMMONX86: "Common Files",
    CSIDL_PROGRAM_FILESX86: "Program Files",
    CSIDL_PROGRAMS: "Programs",
    CSIDL_COMMON_DESKTOPDIRECTORY: "Desktop",
    CSIDL_COMMON_DOCUMENTS: "Shared Documents",
    CSIDL_COMMON_MUSIC: "Shared Music",
    CSIDL_COMMON_PICTURES: "Shared Pictures",
    CSIDL_COMMON_VIDEO: "Shared Video",
    CSIDL_RECENT: "My Recent Documents",
    CSIDL_BITBUCKET: "Recycle Bin",
    CSIDL_RESOURCES: "Resources",
    CSIDL_APPDATA: "Application Data",
    CSIDL_SENDTO: "SendTo",
    CSIDL_STARTMENU: "Start Menu",
    CSIDL_STARTUP: "Startup",
    CSIDL_ALTSTARTUP: "Startup",
    CSIDL_SYSTEM: "system32",
    CSIDL_SYSTEMX86: "system32",
    CSIDL_TEMPLATES: "Templates",
    CSIDL_WINDOWS: "WINDOWS"
}


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

Windows Service  (0) 2016.06.21
Windows Boot Process (Vista 이상ver 부팅 과정)  (0) 2016.04.13
Write Protection - Registry Setting  (0) 2016.01.17
Windows USB Autorn 설정  (0) 2016.01.04
Windows 10 _HANDLES_TABLE, _HADNLES_TABLE_ENTRY  (0) 2015.11.09

쓰기 방지


  외부 장치를 연결하여 해당 장치를 분석하고자 할 경우 해당 볼륨에 파일이나 디렉터리를 생성, 변경, 삭제 하지 않는 이상 흔적이 남지 않는 줄 알았다. 하지만 직접 해본 결과, 연결 후 몇 가지 읽기 작업만 했을 뿐인데, $MFT, $LogFile, $UsnJrnl 등을 통해 확인할 수가 있었다. 따라서 외부 장치를 연결하여 분석하고자 할 때 무결성을 최대한 유지하기 위하여 쓰기 방지 작업을 선행하여야 한다.

  쓰기 방지를 위한 툴들이 존재하지만 간단한 방법을 통해 쓰기 방지를 설정하는 방법에 대하여 알아보자. 여기서 사용할 방법은 레지스트리를 이용한 방법이다. 레지스트리 편집을 위해 Win+R에 regedit를 입력하여 레지스트리 편집기를 실행하자.

  위 그림의 경로 HKLM\System\CurrrentControlSet\Control\StorageDevicePolicies 를 확인해보자. 위와 같이 WriteProtect라는 항목이 존재하고 있는 것을 확인할 수가 있다. 현재 값이 0으로 설정되어 있는 것을 확인할 수가 있다. 만약 값이 1일 경우 외부 장치를 연결하였을 때 쓰기 방지를 통하여 쓰기 작업을 할 수가 없다.

  만약 위의 그림과 같이 "StorageDevicePolicies"라는 항목이 없을 경우 명령어를 통해 추가해주어야한다. 관리자 권한으로 CMD를 실행 시킨 뒤, 다음과 같은 명령어를 입력해주면 된다.

Admin>reg add "HKLM\System\CurrentControlSet\Control\StorageDevicePolicies" /t Reg_dword /v WriteProtect /f /d 1


  값이 1로 설정되면 외부 장치 쓰기 방지가 설정된 것으로 기존과는 다르게 파일의 복사하여 외부 장치에 옮기려 할 경우 아래와 같이 출력되는 것을 확인할 수가 있다. "The disk is write-protected"라는 문구를 확인할 수가 있다.



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

Windows Boot Process (Vista 이상ver 부팅 과정)  (0) 2016.04.13
CSIDL 값  (0) 2016.02.20
Windows USB Autorn 설정  (0) 2016.01.04
Windows 10 _HANDLES_TABLE, _HADNLES_TABLE_ENTRY  (0) 2015.11.09
Control registers - wiki  (0) 2015.11.07

USB 자동실행 방지


 USB가 대중화된 시점에 USB를 꽂으면 자동적으로 실행되는 AutoRun을 통해 악성코드가 유포되기도 한다. 이러한 USB 자동실행을 방지하기 위하여 설정하는 방법에 대하여 간략히 알아보자.

 윈도우 + R을 통해 'gpedit.msc'를 입력해주자. 그렇다면 아래와 같은 창이 뜨는 것을 확인할 수가 있다. 여기서 우리가 찾아 들어가야 할 곳은 'Administrative Templatres'이다. 해당 부분에 들어가 윈도우 구성 요소인 'Windows Components'에 들어가 'AutoPlay Policies'에 들어가보자.

 위의 그림과 같이 Turn off Autoplay이 항목이 존재하고 있는 것을 확인할 수가 있다. 저 부분이 바로 AutoRun의 실행 여부를 담당하고 있는 정책 항목이다. 따라서 현재 No라고 설정이 되어 있는 것을 확인할 수가 있으므로 이 부분을 변경해주면 된다.

Not Configured를 Enabled로 변경해주면 USB를 꽂았을때 자동실행이 되는 일은 없게 된다.


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

CSIDL 값  (0) 2016.02.20
Write Protection - Registry Setting  (0) 2016.01.17
Windows 10 _HANDLES_TABLE, _HADNLES_TABLE_ENTRY  (0) 2015.11.09
Control registers - wiki  (0) 2015.11.07
_TEB, _PEB Windows 10  (0) 2015.11.05