스레드 – ETHREAD, KTHREAD

스레드 구조체는 ETHREAD에 정의되어 있다. dt _ETHREAD, dt _KTHREAD 명령을 실행하면 아래와 같이 ETHREAD의 각 구조체 정의를 확인 할 수 있게 된다.

ETHTEAD에서 중요한 필드는 다음과 같다.

KTHREAD 블록:

KTHREAD 데이터 구조체

스레드 시간 정보:

스레드 생성과 종료 시간

프로세스 식별:

프로세스의 ID와 스레드 ID

시작주소:

스레드 시작 루틴이 있는 주소

가장정보:

엑세스 토큰과 가장 수준

LPC정보:

본 스레드에서 LPC 메시지 주소

I/O정보:

대기중인 IRP 리스트

그럼 ETHREAD의 전체 구조체를 확인해 보자.

kd> dt _ETHREAD

nt!_ETHREAD

+0x000 Tcb : _KTHREAD
ß 스레드 동기화 개체

+0x200 CreateTime : _LARGE_INTEGER ß 스레드 생성 시간

+0x208 ExitTime : _LARGE_INTEGER ß 스레드 종료 시간

+0x208 KeyedWaitChain : _LIST_ENTRY

+0x210 ExitStatus : Int4B

+0x214 PostBlockList : _LIST_ENTRY
ß 현 스레드가 참조하는 모든 오브젝트 목록

+0x214 ForwardLinkShadow : Ptr32 Void

+0x218 StartAddress : Ptr32 Void
ß 실제 스레드 시작 주소

+0x21c TerminationPort : Ptr32 _TERMINATION_PORT

+0x21c ReaperLink : Ptr32 _ETHREAD

+0x21c KeyedWaitValue : Ptr32 Void

+0x220 ActiveTimerListLock : Uint4B

+0x224 ActiveTimerListHead : _LIST_ENTRY

+0x22c Cid : _CLIENT_ID
ß 프로세스 ID와 스레드 ID를 확인할 수 있다.

+0x234 KeyedWaitSemaphore : _KSEMAPHORE

+0x234 AlpcWaitSemaphore : _KSEMAPHORE

+0x248 ClientSecurity : _PS_CLIENT_SECURITY_CONTEXT

+0x24c IrpList : _LIST_ENTRY ß 현 스레드에서 실행 중인 IRP 리스트

+0x254 TopLevelIrp : Uint4B

+0x258 DeviceToVerify : Ptr32 _DEVICE_OBJECT

+0x25c CpuQuotaApc : Ptr32 _PSP_CPU_QUOTA_APC

+0x260 Win32StartAddress : Ptr32 Void
ß 유저모드 스레드 시작 주소

+0x264 LegacyPowerObject : Ptr32 Void

+0x268 ThreadListEntry : _LIST_ENTRY ß 프로세스가 가지고 있는 모든 스레드 목록

+0x270 RundownProtect : _EX_RUNDOWN_REF

+0x274 ThreadLock : _EX_PUSH_LOCK

+0x278 ReadClusterSize : Uint4B

+0x27c MmLockOrdering : Int4B

+0x280 CrossThreadFlags : Uint4B

+0x280 Terminated : Pos 0, 1 Bit

+0x280 ThreadInserted : Pos 1, 1 Bit

+0x280 HideFromDebugger : Pos 2, 1 Bit

+0x280 ActiveImpersonationInfo : Pos 3, 1 Bit

+0x280 Reserved : Pos 4, 1 Bit

+0x280 HardErrorsAreDisabled : Pos 5, 1 Bit

+0x280 BreakOnTermination : Pos 6, 1 Bit

+0x280 SkipCreationMsg : Pos 7, 1 Bit

+0x280 SkipTerminationMsg : Pos 8, 1 Bit

+0x280 CopyTokenOnOpen : Pos 9, 1 Bit

+0x280 ThreadIoPriority : Pos 10, 3 Bits ß 스레드 I/O 우선 순위

+0x280 ThreadPagePriority : Pos 13, 3 Bits ß 스레드 페이지 우선 순위

+0x280 RundownFail : Pos 16, 1 Bit

+0x280 NeedsWorkingSetAging : Pos 17, 1 Bit

+0x284 SameThreadPassiveFlags : Uint4B

+0x284 ActiveExWorker : Pos 0, 1 Bit

+0x284 ExWorkerCanWaitUser : Pos 1, 1 Bit

+0x284 MemoryMaker : Pos 2, 1 Bit

+0x284 ClonedThread : Pos 3, 1 Bit

+0x284 KeyedEventInUse : Pos 4, 1 Bit

+0x284 RateApcState : Pos 5, 2 Bits

+0x284 SelfTerminate : Pos 7, 1 Bit

+0x288 SameThreadApcFlags : Uint4B

+0x288 Spare : Pos 0, 1 Bit

+0x288 StartAddressInvalid : Pos 1, 1 Bit

+0x288 EtwPageFaultCalloutActive : Pos 2, 1 Bit

+0x288 OwnsProcessWorkingSetExclusive : Pos 3, 1 Bit

+0x288 OwnsProcessWorkingSetShared : Pos 4, 1 Bit

+0x288 OwnsSystemCacheWorkingSetExclusive : Pos 5, 1 Bit

+0x288 OwnsSystemCacheWorkingSetShared : Pos 6, 1 Bit

+0x288 OwnsSessionWorkingSetExclusive : Pos 7, 1 Bit

+0x289 OwnsSessionWorkingSetShared : Pos 0, 1 Bit

+0x289 OwnsProcessAddressSpaceExclusive : Pos 1, 1 Bit

+0x289 OwnsProcessAddressSpaceShared : Pos 2, 1 Bit

+0x289 SuppressSymbolLoad : Pos 3, 1 Bit

+0x289 Prefetching : Pos 4, 1 Bit ß 프리패칭기능 활성화 유무 3부에서 다룬다.

+0x289 OwnsDynamicMemoryShared : Pos 5, 1 Bit

+0x289 OwnsChangeControlAreaExclusive : Pos 6, 1 Bit

+0x289 OwnsChangeControlAreaShared : Pos 7, 1 Bit

+0x28a OwnsPagedPoolWorkingSetExclusive : Pos 0, 1 Bit

+0x28a OwnsPagedPoolWorkingSetShared : Pos 1, 1 Bit

+0x28a OwnsSystemPtesWorkingSetExclusive : Pos 2, 1 Bit

+0x28a OwnsSystemPtesWorkingSetShared : Pos 3, 1 Bit

+0x28a TrimTrigger : Pos 4, 2 Bits

+0x28a Spare1 : Pos 6, 2 Bits

+0x28b PriorityRegionActive : UChar

+0x28c CacheManagerActive : UChar

+0x28d DisablePageFaultClustering : UChar

+0x28e ActiveFaultCount : UChar

+0x28f LockOrderState : UChar

+0x290 AlpcMessageId : Uint4B ß ALPC 메시지 ID

+0x294 AlpcMessage : Ptr32 Void ß ALPC 메시지

+0x294 AlpcReceiveAttributeSet : Uint4B

+0x298 AlpcWaitListEntry : _LIST_ENTRY ß ALPC 대기 리스트

+0x2a0 CacheManagerCount : Uint4B

+0x2a4 IoBoostCount : Uint4B

+0x2a8 IrpListLock : Uint4B

+0x2ac ReservedForSynchTracking : Ptr32 Void

+0x2b0 CmCallbackListHead : _SINGLE_LIST_ENTRY

+0x2b4 KernelStackReference : Uint4B

[내용] Windbg를 통해 확인한 ETHREAD 구조체

각 KTHREAD는 커널에서 스레드 스케줄링에 필요한 정보들을 가지고 있다. 내 주요 구조체 필드는 다음과 같다.

디스패처 해더:

디스패처를 동작할 수 있도록 기본 디스 패처 헤더 정보를 가지고 있다.

실행시간:

CPU에서 실행된 전체 시간

커널스택정보:

현 스레드의 기본/상위 커널 스택 주소

시스템서비스테이블정보:

시스템 서비스 테이블 주소

스케줄링 정보:

현재 우선순위와 퀀텀, 스케줄링 상태등의 정보

대기중인 블록:

스레드 생성시 4개의 대기 블록 리스트 가짐

대기 정보:

대기 이유와 시간

뮤덱스 리스트:

본 스레드의 뮤덱스 개체 리스트

APC 큐:

대기중인 APC 리스트

타이머 블록:

내장된 타이머 블록으로 4개의 대기중인 블록에 포함된다.

큐 리스트:

스레드가 이용하는 큐 개체의 포인터

TEB 포인터:

TEB의 위치를 가르킨다.

그럼 KTHREAD의 전체 구조체에 대해 확인해 보자.

kd> dt _KTHREAD

nt!_KTHREAD

+0x000 Header : _DISPATCHER_HEADER ß 디스패처 헤더 7장에 관련 내용을 확인 할 수 있다.

+0x010 CycleTime : Uint8B

+0x018 HighCycleTime : Uint4B

+0x020 QuantumTarget : Uint8B

+0x028 InitialStack : Ptr32 Void ß 스택시작주소

+0x02c StackLimit : Ptr32 Void ß 스택사용제한주소

+0x030 KernelStack : Ptr32 Void ß 현 스택 사용위치 포인터

+0x034 ThreadLock : Uint4B

+0x038 WaitRegister : _KWAIT_STATUS_REGISTER

+0x039 Running : UChar ß 실행 상태

+0x03a Alerted : [2] UChar ß 알람

+0x03c KernelStackResident : Pos 0, 1 Bit

+0x03c ReadyTransition : Pos 1, 1 Bit

+0x03c ProcessReadyQueue : Pos 2, 1 Bit

+0x03c WaitNext : Pos 3, 1 Bit

+0x03c SystemAffinityActive : Pos 4, 1 Bit

+0x03c Alertable : Pos 5, 1 Bit ß 유저 APC 가능 사용 유무

+0x03c GdiFlushActive : Pos 6, 1 Bit

+0x03c UserStackWalkActive : Pos 7, 1 Bit

+0x03c ApcInterruptRequest : Pos 8, 1 Bit

+0x03c ForceDeferSchedule : Pos 9, 1 Bit

+0x03c QuantumEndMigrate : Pos 10, 1 Bit

+0x03c UmsDirectedSwitchEnable : Pos 11, 1 Bit

+0x03c TimerActive : Pos 12, 1 Bit

+0x03c SystemThread : Pos 13, 1 Bit

+0x03c Reserved : Pos 14, 18 Bits

+0x03c MiscFlags : Int4B

+0x040 ApcState : _KAPC_STATE

+0x040 ApcStateFill : [23] UChar

+0x057 Priority : Char ß 스레드 우선 순위

+0x058 NextProcessor : Uint4B ß 다음 실행시 사용될 프로세서

+0x05c DeferredProcessor : Uint4B ß 지연된 프로세서

+0x060 ApcQueueLock : Uint4B

+0x064 ContextSwitches : Uint4B ß 컨텍스 스위치 횟수

+0x068 State : UChar ß 스레드 상태

+0x069 NpxState : Char

+0x06a WaitIrql : UChar

+0x06b WaitMode : Char

+0x06c WaitStatus : Int4B ß 대기 상태

+0x070 WaitBlockList : Ptr32 _KWAIT_BLOCK

+0x074 WaitListEntry : _LIST_ENTRY ß 대기 스레드 리스트

+0x074 SwapListEntry : _SINGLE_LIST_ENTRY

+0x07c Queue : Ptr32 _KQUEUE ß 큐 리스트

+0x080 WaitTime : Uint4B ß 대기 시간

+0x084 KernelApcDisable : Int2B ß 커널 APC 사용 유무

+0x086 SpecialApcDisable : Int2B ß 특별 APC 사용 유무

+0x084 CombinedApcDisable : Uint4B

+0x088 Teb : Ptr32 Void
ß TEB 포인터

+0x090 Timer : _KTIMER

+0x0b8 AutoAlignment : Pos 0, 1 Bit

+0x0b8 DisableBoost : Pos 1, 1 Bit

+0x0b8 EtwStackTraceApc1Inserted : Pos 2, 1 Bit

+0x0b8 EtwStackTraceApc2Inserted : Pos 3, 1 Bit

+0x0b8 CalloutActive : Pos 4, 1 Bit

+0x0b8 ApcQueueable : Pos 5, 1 Bit

+0x0b8 EnableStackSwap : Pos 6, 1 Bit

+0x0b8 GuiThread : Pos 7, 1 Bit

+0x0b8 UmsPerformingSyscall : Pos 8, 1 Bit

+0x0b8 VdmSafe : Pos 9, 1 Bit

+0x0b8 UmsDispatched : Pos 10, 1 Bit

+0x0b8 ReservedFlags : Pos 11, 21 Bits

+0x0b8 ThreadFlags : Int4B

+0x0bc ServiceTable : Ptr32 Void

+0x0c0 WaitBlock : [4] _KWAIT_BLOCK

+0x120 QueueListEntry : _LIST_ENTRY ß 큐 리스트

+0x128 TrapFrame : Ptr32 _KTRAP_FRAME ß 예외 발생시 사용될 트랩 프레임 포인터

+0x12c FirstArgument : Ptr32 Void

+0x130 CallbackStack : Ptr32 Void

+0x130 CallbackDepth : Uint4B

+0x134 ApcStateIndex : UChar

+0x135 BasePriority : Char ß 스레드 기본 우선 순위

+0x136 PriorityDecrement : Char

+0x136 ForegroundBoost : Pos 0, 4 Bits

+0x136 UnusualBoost : Pos 4, 4 Bits

+0x137 Preempted : UChar ß 스레드가 선점하였을시 설정된다.

+0x138 AdjustReason : UChar

+0x139 AdjustIncrement : Char

+0x13a PreviousMode : Char

+0x13b Saturation : Char

+0x13c SystemCallNumber : Uint4B

+0x140 FreezeCount : Uint4B ß 대기 횟수

+0x144 UserAffinity : _GROUP_AFFINITY

+0x150 Process : Ptr32 _KPROCESS ß 스레드가 속한 프로세스의 KPROCESS 포인터

+0x154 Affinity : _GROUP_AFFINITY ß 선호 프로세서

+0x160 IdealProcessor : Uint4B

+0x164 UserIdealProcessor : Uint4B

+0x168 ApcStatePointer : [2] Ptr32 _KAPC_STATE

+0x170 SavedApcState : _KAPC_STATE

+0x170 SavedApcStateFill : [23] UChar

+0x187 WaitReason : UChar

+0x188 SuspendCount : Char ß 일시중지 횟수

+0x189 Spare1 : Char

+0x18a OtherPlatformFill : UChar

+0x18c Win32Thread : Ptr32 Void ß 유저모드 스레드 주소

+0x190 StackBase : Ptr32 Void ß 스택 베이스 주소

+0x194 SuspendApc : _KAPC

+0x194 SuspendApcFill0 : [1] UChar

+0x195 ResourceIndex : UChar

+0x194 SuspendApcFill1 : [3] UChar

+0x197 QuantumReset : UChar ß 현스레드에 할당된 퀀텀값 6장에서 다룬다.

+0x194 SuspendApcFill2 : [4] UChar

+0x198 KernelTime : Uint4B ß 커널모드에서의 현 스레드 실행 시간

+0x194 SuspendApcFill3 : [36] UChar

+0x1b8 WaitPrcb : Ptr32 _KPRCB

+0x194 SuspendApcFill4 : [40] UChar

+0x1bc LegoData : Ptr32 Void

+0x194 SuspendApcFill5 : [47] UChar

+0x1c3 LargeStack : UChar

+0x1c4 UserTime : Uint4B ß 유저모드에서의 현 스레드 실행 시간

+0x1c8 SuspendSemaphore : _KSEMAPHORE

+0x1c8 SuspendSemaphorefill : [20] UChar

+0x1dc SListFaultCount : Uint4B

+0x1e0 ThreadListEntry : _LIST_ENTRY ß 프로세스가 가지고 있는 모든 스레드 목록

+0x1e8 MutantListHead : _LIST_ENTRY

+0x1f0 SListFaultAddress : Ptr32 Void

+0x1f4 ThreadCounters : Ptr32 _KTHREAD_COUNTERS

+0x1f8 XStateSave : Ptr32 _XSTATE_SAVE

[내용] ] Windbg를 통해 확인한 KTHREAD 구조체

각 스레드의 TEB 정보는 Windbg 명령 !thread 명령을 통해 확인 할 수 있다.

이 정보를 확인해서 프로세스의 스레드 스케줄링 상태라거나, 스레드에서 처리중이였던 정보들을 확인 할 수 있다.

// 먼저 프로세스 정보를 확인해, PEB 주소를 확인하자.

Kd> !process 81c9a458

PROCESS 81c9a458 SessionId: 0 Cid: 0284 Peb: 7ffd6000 ParentCid: 01a4

DirBase: 0af6e000 ObjectTable: e12e4bb0 HandleCount: 462.

Image: csrss.exe

VadRoot 81e7d940 Vads 94 Clone 0 Private 308. Modified 405. Locked 0.

DeviceMap e10087c0

Token e141d990

ElapsedTime 00:28:24.259

UserTime 00:00:00.440

KernelTime 00:00:00.280

QuotaPoolUsage[PagedPool] 56760

QuotaPoolUsage[NonPagedPool] 4840

Working Set Sizes (now,min,max) (970, 50, 345) (3880KB, 200KB, 1380KB)

PeakWorkingSetSize 979

VirtualSize 33 Mb

PeakVirtualSize 46 Mb

PageFaultCount 1907

MemoryPriority BACKGROUND

BasePriority 13

CommitCharge 386

// 현재 프로세스에서 실행중인 스레드 정보를 함께 출력한다. TEB 위치와 스레드에서 호출해 처리중이던 스택 정보도 확인 할 수 있다.

THREAD 81e1bda8 Cid 0284.028c Teb: 7ffde000 Win32Thread: 00000000 WAIT: (WrLpcReply) UserMode Non-Alertable

81e1bf9c Semaphore Limit 0x1

Waiting for reply to LPC MessageId 00000cf6:

Current LPC port e1084758

Not impersonating

DeviceMap e10087c0

Owning Process 0 Image: <Unknown>

Attached Process 81c9a458 Image: csrss.exe

Wait Start TickCount 7312 Ticks: 163500 (0:00:27:17.354)

Context Switch Count 4

UserTime 00:00:00.000

KernelTime 00:00:00.000

Start Address 0x764c7d63

Stack Init f89e4000 Current f89e3c50 Base f89e4000 Limit f89e1000 Call 0

Priority 15 BasePriority 15 PriorityDecrement 0 DecrementCount 0

Kernel stack not resident.

ChildEBP RetAddr

f89e3c68 804de0f7 nt!KiSwapContext+0x2e (FPO: [Uses EBP] [0,0,4])

f89e3c74 804de143 nt!KiSwapThread+0x46 (FPO: [0,0,0])

f89e3c9c 80578fc6 nt!KeWaitForSingleObject+0x1c2 (FPO: [Non-Fpo])

f89e3d50 804e07ec nt!NtRequestWaitReplyPort+0x63d (FPO: [Non-Fpo])

f89e3d50 7c93e4f4 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ f89e3d64)

0050fff4 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])

[내용] Windbg에서 !process 명령어로 확인한 PEB, TEB 주소

특정 프로세스의 구조체 내용을 확인 하고자 할 때 에는 확인하고자 하는 구조체와 구조체 필드를 입력하고 해당 메모리 위치를 기입하면 된다.

예로 이미지 파일의 이름을 확인하고 싶다면, 아래와 같이 입력하면. 해당 필드에 입력된 값을 확인할 수 있다. 특정 필드를 지정하지 않으면 각 구조체에 정의된 내용 전체를 볼 수 있다.

dt nt!_EPROCESS ImageFileName 0x81bde940

[내용] dt 명령을 이용한 구조체 확인

[그림]Windbg로 확인한 EPROCESS 구조체 일부

이는 디버깅 시에도 많이 사용 되며, Windbg의 x 명령과 더불어 강력한 기능중 하나이므로 숙달하여 자신의 것으로 소화하고, 윈도우 내부의 수 많은 구조체를 계속 접해보기 바란다. (각 구조체를 모른 상태에서는 모래에서 바늘 찾기와 같다.)

-박스시작-

dt(Display Type) 사용하기

Windbg에서 지원하는 dt명령은 앞서 애기하였듯, 윈도우 커널 내부를 이해하고, 데이터를 확인하는데 있어 많이 사용되는 명령어 중에 하나이다. 계속 dt 명령이 나왔지만, dt와 함께 사용할 수 있는 유용한 옵션 몇가지를 집고 넘어가도록 하겠다.

-b: 확인하는 구조체와 연결된 하위 구조체도 표시하게 된다.

// dt –b 명령을 통해 PCB 구조체까지 한번에 확인 할 수 있다.

kd> dt -b _EPROCESS

ntdll!_EPROCESS

+0x000 Pcb : _KPROCESS

+0x000 Header : _DISPATCHER_HEADER

+0x000 Type : UChar

+0x001 Absolute : UChar

+0x002 Size : UChar

+0x003 Inserted : UChar

+0x004 SignalState : Int4B

+0x008 WaitListHead : _LIST_ENTRY

+0x000 Flink : Ptr32

+0x004 Blink : Ptr32

+0x010 ProfileListHead : _LIST_ENTRY

+0x000 Flink : Ptr32

+0x004 Blink : Ptr32

+0x018 DirectoryTableBase : Uint4B

+0x020 LdtDescriptor : _KGDTENTRY

+0x000 LimitLow : Uint2B

+0x002 BaseLow : Uint2B

+0x004 HighWord : __unnamed

+0x000 Bytes : __unnamed

+0x000 BaseMid : UChar

+0x001 Flags1 : UChar

+0x002 Flags2 : UChar

+0x003 BaseHi : UChar

+0x000 Bits : __unnamed

+0x000 BaseMid : Pos 0, 8 Bits

+0x000 Type : Pos 8, 5 Bits

+0x000 Dpl : Pos 13, 2 Bits

+0x000 Pres : Pos 15, 1 Bit

+0x000 LimitHi : Pos 16, 4 Bits

+0x000 Sys : Pos 20, 1 Bit
….중략

[내용] 하위 구조체 확인에 유용하다

-d: 확인하고자 하는 구조체 끝에 *를 통해 검색할 경우 검색된 구조체들의 유형을 표시해 준다.

kd> dt -d nt!_EPRO*

struct _EPROCESS, 107 elements, 0x260 bytes

+0x000 Pcb : struct _KPROCESS, 29 elements, 0x6c bytes

+0x06c ProcessLock : struct _EX_PUSH_LOCK, 5 elements, 0x4 bytes

+0x070 CreateTime : union _LARGE_INTEGER, 4 elements, 0x8 bytes

+0x078 ExitTime : union _LARGE_INTEGER, 4 elements, 0x8 bytes

+0x080 RundownProtect : struct _EX_RUNDOWN_REF, 2 elements, 0x4 bytes

+0x084 UniqueProcessId : Ptr32 to Void

+0x088 ActiveProcessLinks : struct _LIST_ENTRY, 2 elements, 0x8 bytes

+0x090 QuotaUsage : [3] Uint4B

+0x09c QuotaPeak : [3] Uint4B

+0x0a8 CommitCharge : Uint4B

+0x0ac PeakVirtualSize : Uint4B

+0x0b0 VirtualSize : Uint4B

…..중략

+0x258 Cookie : Uint4B

struct _EPROCESS_QUOTA_BLOCK, 4 elements, 0x40 bytes

+0x000 QuotaEntry : [3] struct _EPROCESS_QUOTA_ENTRY, 4 elements, 0x10 bytes

+0x030 QuotaList : struct _LIST_ENTRY, 2 elements, 0x8 bytes

+0x038 ReferenceCount : Uint4B

+0x03c ProcessCount : Uint4B

struct _EPROCESS_QUOTA_ENTRY, 4 elements, 0x10 bytes

+0x000 Usage : Uint4B

+0x004 Limit : Uint4B

+0x008 Peak : Uint4B

// nt!EPRO로 시작하는 모든 구조체를 표시

kd> dt nt!_EPRO*

ntoskrnl!_EPROCESS

ntoskrnl!_EPROCESS_QUOTA_BLOCK

ntoskrnl!_EPROCESS_QUOTA_ENTRY

[내용] Windbg를 이용하여 구조체 검색

-r: 확인하는 구조체와 연결된 하위 구조체를 표시하는데 해당 깊이를 숫자로 지정할 수 있다.

kd> dt -r5 _EPROCESS

ntdll!_EPROCESS

+0x000 Pcb : _KPROCESS

+0x000 Header : _DISPATCHER_HEADER

+0x000 Type : UChar

+0x001 Absolute : UChar

+0x002 Size : UChar

+0x003 Inserted : UChar

+0x004 SignalState : Int4B

+0x008 WaitListHead : _LIST_ENTRY

+0x000 Flink : Ptr32 _LIST_ENTRY

+0x000 Flink : Ptr32 _LIST_ENTRY

+0x000 Flink : Ptr32 _LIST_ENTRY

+0x004 Blink : Ptr32 _LIST_ENTRY

+0x004 Blink : Ptr32 _LIST_ENTRY

+0x000 Flink : Ptr32 _LIST_ENTRY

+0x004 Blink : Ptr32 _LIST_ENTRY

+0x004 Blink : Ptr32 _LIST_ENTRY

+0x000 Flink : Ptr32 _LIST_ENTRY

+0x000 Flink : Ptr32 _LIST_ENTRY

+0x004 Blink : Ptr32 _LIST_ENTRY

+0x004 Blink : Ptr32 _LIST_ENTRY

+0x000 Flink : Ptr32 _LIST_ENTRY

+0x004 Blink : Ptr32 _LIST_ENTRY

…중략

[내용] 하위 구조체까지 세부적으로 확인 가능하다

-박스종료-

지금까지 운영체제에서 작업의 단위로 사용하는 프로세스와 스레드의 이론과, 실제 구조체와 연관 관계에 대해 알아보았다. 지금 당장 위 내용을 다 이해하기는 무리일 것이다. 여기에서는 이러한 구조로 프로세스와 스레드과 관계되어 있다는 정도만으로 이해하고 넘어가기 바란다. 프로세스와 스레드가 윈도우 작업의 전부인 만큼 위 필드들은 주기적으로 나오게 되어 있어, 자연스럽게 익숙해질 것이다. 그리고 다음으로 진행할 내용은 프로세서에 대해 진행할 예정이다.

그리고 이 프로세스와 스레드 구조체 이해에 아래 함수들을 확인하면, 쉽게 각 구조체들에 대해 파악 할 수 있을 것이다.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms684847(v=vs.85).aspx

윈도우 내부구조인 커널은 하드웨어 처리와 직접 관리하는 만큼, CPU, 메모리등과 같은 하드웨어의 제어와 밀접하게 관련되어 있다. 따라서 그들이 사용하는 동작방식에 대해 이해가 필요하다, 그 중 가장 중요한 부분이 스레드들의 요청 작업을 처리하는 CPU라 할 수 있다. CPU를 이해하기 위해서는 CPU에서 자료 저장에 사용되는 스택 구조에 대해서도 이해해야 하며, 이 스택의 처리 방식을 이해하기 위해서, 어셈블리언어도 함께 이해하여야 한다. (어셈블리는 프로그램 역분석에도 사용된다.) 스택은 CPU에서 사용하는 데이터 처리에 필요한 값을 보관하기 위한 메커니즘으로써, 차후 역분석하고도 관계가 있다. 윈도우 내부 구조와 역분석 이해에 있어 스택을 이해하지 못하면, 윈도우 내부 구조는 물론 역분석을 진행하기가 어려워진다. (CPU를 이해하지 못하므로, 당연히 내부 처리 과정을 디버깅하는 역분석은 이해가 되지 않게 된다.) 그래서 여러 역분석 책에서도 스택과 레지스터, 어셈블리언어에 대해 매번 빠지지 않고 나왔을 것이다.

이 책에서도 이부분을 빼지는 못하겠다. 다만 내용을 최소화 하여 독자분들이 빠르게 이해할 있도록 구성하고자 노력하였다.

그럼 먼저 CPU 처리 데이터를 저장하는 레지스터에 대해 알아보도록 하자.

Facebook Comments

Leave A Reply

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.