windows内核——基石

article/2025/10/5 19:40:00

友链

内存布局

在这里插入图片描述
用户内存空间和内核内存空间之间的gap是为了避免不经意的越界而导致安全问题

CPU的初始化

系统启动期间,会对所有的处理器进行初始化操作

大部分初始化操作我们都不必了解,因为你了不了解都不影响你的逆向,毕竟你又不是开发操作系统的

但是艺多不压身,多知道点东西总没有坏处

处理器控制区PCR processor control region是一个结构体,每一个处理器都有一个对应的PCR结构体实例,它存储了CPU的重要信息

在x86中,它包含了IDT的基地址和当前的IRQL(interrupt request level——中断请求等级)

在PCR结构体中还有另一个结构体PRCB——processor region control block,他保存了CPU类型、模式、速率、当前运行的线程等信息

0: kd> dt nt!_KPCR+0x000 NtTib            : _NT_TIB+0x000 GdtBase          : Ptr64 _KGDTENTRY64+0x008 TssBase          : Ptr64 _KTSS64+0x010 UserRsp          : Uint8B+0x018 Self             : Ptr64 _KPCR+0x020 CurrentPrcb      : Ptr64 _KPRCB+0x028 LockArray        : Ptr64 _KSPIN_LOCK_QUEUE+0x030 Used_Self        : Ptr64 Void+0x038 IdtBase          : Ptr64 _KIDTENTRY64+0x040 Unused           : [2] Uint8B+0x050 Irql             : UChar+0x051 SecondLevelCacheAssociativity : UChar+0x052 ObsoleteNumber   : UChar+0x053 Fill0            : UChar+0x054 Unused0          : [3] Uint4B+0x060 MajorVersion     : Uint2B+0x062 MinorVersion     : Uint2B+0x064 StallScaleFactor : Uint4B+0x068 Unused1          : [3] Ptr64 Void+0x080 KernelReserved   : [15] Uint4B+0x0bc SecondLevelCacheSize : Uint4B+0x0c0 HalReserved      : [16] Uint4B+0x100 Unused2          : Uint4B+0x108 KdVersionBlock   : Ptr64 Void+0x110 Unused3          : Ptr64 Void+0x118 PcrAlign1        : [24] Uint4B+0x180 Prcb             : _KPRCB

偏移量0x180h处就是PRCB结构体

0: kd> dt nt!_KPRCB+0x000 MxCsr            : Uint4B+0x004 LegacyNumber     : UChar+0x005 ReservedMustBeZero : UChar+0x006 InterruptRequest : UChar+0x007 IdleHalt         : UChar+0x008 CurrentThread    : Ptr64 _KTHREAD+0x010 NextThread       : Ptr64 _KTHREAD+0x018 IdleThread       : Ptr64 _KTHREAD+0x020 NestingLevel     : UChar+0x021 ClockOwner       : UChar+0x022 PendingTickFlags : UChar+0x022 PendingTick      : Pos 0, 1 Bit+0x022 PendingBackupTick : Pos 1, 1 Bit+0x023 PrcbPad00        : [1] UChar+0x024 Number           : Uint4B+0x028 RspBase          : Uint8B+0x030 PrcbLock         : Uint8B+0x038 PriorityState    : Ptr64 Char+0x040 ProcessorState   : _KPROCESSOR_STATE+0x5f0 CpuType          : Char+0x5f1 CpuID            : Char+0x5f2 CpuStep          : Uint2B+0x5f2 CpuStepping      : UChar+0x5f3 CpuModel         : UChar+0x5f4 MHz              : Uint4B+0x5f8 HalReserved      : [8] Uint8B+0x638 MinorVersion     : Uint2B+0x63a MajorVersion     : Uint2B+0x63c BuildType        : UChar+0x63d CpuVendor        : UChar+0x63e CoresPerPhysicalProcessor : UChar+0x63f LogicalProcessorsPerCore : UChar+0x640 ParentNode       : Ptr64 _KNODE+0x648 GroupSetMember   : Uint8B+0x650 Group            : UChar+0x651 GroupIndex       : UChar+0x652 PrcbPad05        : [2] UChar+0x654 ApicMask         : Uint4B+0x658 CFlushSize       : Uint4B+0x660 AcpiReserved     : Ptr64 Void+0x668 InitialApicId    : Uint4B+0x670 LockQueue        : [17] _KSPIN_LOCK_QUEUE+0x780 PPLookasideList  : [16] _PP_LOOKASIDE_LIST+0x880 PPNxPagedLookasideList : [32] _GENERAL_LOOKASIDE_POOL+0x1480 PPNPagedLookasideList : [32] _GENERAL_LOOKASIDE_POOL+0x2080 PPPagedLookasideList : [32] _GENERAL_LOOKASIDE_POOL+0x2c80 PrcbPad20        : Uint8B+0x2c88 DeferredReadyListHead : _SINGLE_LIST_ENTRY+0x2c90 MmPageFaultCount : Int4B+0x2c94 MmCopyOnWriteCount : Int4B+0x2c98 MmTransitionCount : Int4B+0x2c9c MmDemandZeroCount : Int4B+0x2ca0 MmPageReadCount  : Int4B+0x2ca4 MmPageReadIoCount : Int4B+0x2ca8 MmDirtyPagesWriteCount : Int4B+0x2cac MmDirtyWriteIoCount : Int4B+0x2cb0 MmMappedPagesWriteCount : Int4B+0x2cb4 MmMappedWriteIoCount : Int4B+0x2cb8 KeSystemCalls    : Uint4B+0x2cbc KeContextSwitches : Uint4B+0x2cc0 LdtSelector      : Uint2B+0x2cc2 PrcbPad40        : Uint2B+0x2cc4 CcFastReadNoWait : Uint4B+0x2cc8 CcFastReadWait   : Uint4B+0x2ccc CcFastReadNotPossible : Uint4B+0x2cd0 CcCopyReadNoWait : Uint4B+0x2cd4 CcCopyReadWait   : Uint4B+0x2cd8 CcCopyReadNoWaitMiss : Uint4B+0x2cdc IoReadOperationCount : Int4B+0x2ce0 IoWriteOperationCount : Int4B+0x2ce4 IoOtherOperationCount : Int4B+0x2ce8 IoReadTransferCount : _LARGE_INTEGER+0x2cf0 IoWriteTransferCount : _LARGE_INTEGER+0x2cf8 IoOtherTransferCount : _LARGE_INTEGER+0x2d00 PacketBarrier    : Int4B+0x2d04 TargetCount      : Int4B+0x2d08 IpiFrozen        : Uint4B+0x2d10 IsrDpcStats      : Ptr64 Void+0x2d18 DeviceInterrupts : Uint4B+0x2d1c LookasideIrpFloat : Int4B+0x2d20 InterruptLastCount : Uint4B+0x2d24 InterruptRate    : Uint4B+0x2d28 PrcbPad41        : [22] Uint4B+0x2d80 DpcData          : [2] _KDPC_DATA+0x2dd0 DpcStack         : Ptr64 Void+0x2dd8 MaximumDpcQueueDepth : Int4B+0x2ddc DpcRequestRate   : Uint4B+0x2de0 MinimumDpcRate   : Uint4B+0x2de4 DpcLastCount     : Uint4B+0x2de8 ThreadDpcEnable  : UChar+0x2de9 QuantumEnd       : UChar+0x2dea DpcRoutineActive : UChar+0x2deb IdleSchedule     : UChar+0x2dec DpcRequestSummary : Int4B+0x2dec DpcRequestSlot   : [2] Int2B+0x2dec NormalDpcState   : Int2B+0x2dee ThreadDpcState   : Int2B+0x2dec DpcNormalProcessingActive : Pos 0, 1 Bit+0x2dec DpcNormalProcessingRequested : Pos 1, 1 Bit+0x2dec DpcNormalThreadSignal : Pos 2, 1 Bit+0x2dec DpcNormalTimerExpiration : Pos 3, 1 Bit+0x2dec DpcNormalDpcPresent : Pos 4, 1 Bit+0x2dec DpcNormalLocalInterrupt : Pos 5, 1 Bit+0x2dec DpcNormalSpare   : Pos 6, 10 Bits+0x2dec DpcThreadActive  : Pos 16, 1 Bit+0x2dec DpcThreadRequested : Pos 17, 1 Bit+0x2dec DpcThreadSpare   : Pos 18, 14 Bits+0x2df0 LastTimerHand    : Uint4B+0x2df4 LastTick         : Uint4B+0x2df8 ClockInterrupts  : Uint4B+0x2dfc ReadyScanTick    : Uint4B+0x2e00 TimerTable       : _KTIMER_TABLE+0x5000 DpcGate          : _KGATE+0x5018 PrcbPad52        : Ptr64 Void+0x5020 CallDpc          : _KDPC+0x5060 ClockKeepAlive   : Int4B+0x5064 PrcbPad60        : [2] UChar+0x5066 NmiActive        : Uint2B+0x5068 DpcWatchdogPeriod : Int4B+0x506c DpcWatchdogCount : Int4B+0x5070 KeSpinLockOrdering : Int4B+0x5074 PrcbPad70        : [1] Uint4B+0x5078 CachedPtes       : Ptr64 Void+0x5080 WaitListHead     : _LIST_ENTRY+0x5090 WaitLock         : Uint8B+0x5098 ReadySummary     : Uint4B+0x509c AffinitizedSelectionMask : Int4B+0x50a0 QueueIndex       : Uint4B+0x50a4 PrcbPad75        : [3] Uint4B+0x50b0 TimerExpirationDpc : _KDPC+0x50f0 ScbQueue         : _RTL_RB_TREE+0x5100 DispatcherReadyListHead : [32] _LIST_ENTRY+0x5300 InterruptCount   : Uint4B+0x5304 KernelTime       : Uint4B+0x5308 UserTime         : Uint4B+0x530c DpcTime          : Uint4B+0x5310 InterruptTime    : Uint4B+0x5314 AdjustDpcThreshold : Uint4B+0x5318 DebuggerSavedIRQL : UChar+0x5319 GroupSchedulingOverQuota : UChar+0x531a DeepSleep        : UChar+0x531b PrcbPad80        : [1] UChar+0x531c ScbOffset        : Uint4B+0x5320 DpcTimeCount     : Uint4B+0x5324 DpcTimeLimit     : Uint4B+0x5328 PeriodicCount    : Uint4B+0x532c PeriodicBias     : Uint4B+0x5330 AvailableTime    : Uint4B+0x5334 KeExceptionDispatchCount : Uint4B+0x5338 StartCycles      : Uint8B+0x5340 GenerationTarget : Uint8B+0x5348 AffinitizedCycles : Uint8B+0x5350 PrcbPad81        : [2] Uint8B+0x5360 MmSpinLockOrdering : Int4B+0x5364 PageColor        : Uint4B+0x5368 NodeColor        : Uint4B+0x536c NodeShiftedColor : Uint4B+0x5370 SecondaryColorMask : Uint4B+0x5374 PrcbPad83        : Uint4B+0x5378 CycleTime        : Uint8B+0x5380 CcFastMdlReadNoWait : Uint4B+0x5384 CcFastMdlReadWait : Uint4B+0x5388 CcFastMdlReadNotPossible : Uint4B+0x538c CcMapDataNoWait  : Uint4B+0x5390 CcMapDataWait    : Uint4B+0x5394 CcPinMappedDataCount : Uint4B+0x5398 CcPinReadNoWait  : Uint4B+0x539c CcPinReadWait    : Uint4B+0x53a0 CcMdlReadNoWait  : Uint4B+0x53a4 CcMdlReadWait    : Uint4B+0x53a8 CcLazyWriteHotSpots : Uint4B+0x53ac CcLazyWriteIos   : Uint4B+0x53b0 CcLazyWritePages : Uint4B+0x53b4 CcDataFlushes    : Uint4B+0x53b8 CcDataPages      : Uint4B+0x53bc CcLostDelayedWrites : Uint4B+0x53c0 CcFastReadResourceMiss : Uint4B+0x53c4 CcCopyReadWaitMiss : Uint4B+0x53c8 CcFastMdlReadResourceMiss : Uint4B+0x53cc CcMapDataNoWaitMiss : Uint4B+0x53d0 CcMapDataWaitMiss : Uint4B+0x53d4 CcPinReadNoWaitMiss : Uint4B+0x53d8 CcPinReadWaitMiss : Uint4B+0x53dc CcMdlReadNoWaitMiss : Uint4B+0x53e0 CcMdlReadWaitMiss : Uint4B+0x53e4 CcReadAheadIos   : Uint4B+0x53e8 MmCacheTransitionCount : Int4B+0x53ec MmCacheReadCount : Int4B+0x53f0 MmCacheIoCount   : Int4B+0x53f4 PrcbPad91        : [3] Uint4B+0x5400 PowerState       : _PROCESSOR_POWER_STATE+0x55e0 ScbList          : _LIST_ENTRY+0x55f0 PrcbPad92        : [19] Uint4B+0x563c KeAlignmentFixupCount : Uint4B+0x5640 DpcWatchdogDpc   : _KDPC+0x5680 DpcWatchdogTimer : _KTIMER+0x56c0 Cache            : [5] _CACHE_DESCRIPTOR+0x56fc CacheCount       : Uint4B+0x5700 CachedCommit     : Uint4B+0x5704 CachedResidentAvailable : Uint4B+0x5708 HyperPte         : Ptr64 Void+0x5710 WheaInfo         : Ptr64 Void+0x5718 EtwSupport       : Ptr64 Void+0x5720 InterruptObjectPool : _SLIST_HEADER+0x5730 HypercallPageList : _SLIST_HEADER+0x5740 HypercallPageVirtual : Ptr64 Void+0x5748 VirtualApicAssist : Ptr64 Void+0x5750 StatisticsPage   : Ptr64 Uint8B+0x5758 PackageProcessorSet : _KAFFINITY_EX+0x5800 SharedReadyQueueMask : Uint8B+0x5808 SharedReadyQueue : Ptr64 _KSHARED_READY_QUEUE+0x5810 CoreProcessorSet : Uint8B+0x5818 ScanSiblingMask  : Uint8B+0x5820 LLCMask          : Uint8B+0x5828 CacheProcessorMask : [5] Uint8B+0x5850 ScanSiblingIndex : Uint4B+0x5854 SharedReadyQueueOffset : Uint4B+0x5858 ProcessorProfileControlArea : Ptr64 _PROCESSOR_PROFILE_CONTROL_AREA+0x5860 ProfileEventIndexAddress : Ptr64 Void+0x5868 PrcbPad94        : [3] Uint8B+0x5880 SynchCounters    : _SYNCH_COUNTERS+0x5938 PteBitCache      : Uint8B+0x5940 PteBitOffset     : Uint4B+0x5948 FsCounters       : _FILESYSTEM_DISK_COUNTERS+0x5958 VendorString     : [13] UChar+0x5965 PrcbPad10        : [3] UChar+0x5968 FeatureBits      : Uint8B+0x5970 PrcbPad11        : Uint4B+0x5978 UpdateSignature  : _LARGE_INTEGER+0x5980 Context          : Ptr64 _CONTEXT+0x5988 ContextFlagsInit : Uint4B+0x5990 ExtendedState    : Ptr64 _XSAVE_AREA+0x5998 IsrStack         : Ptr64 Void+0x59a0 EntropyTimingState : _KENTROPY_TIMING_STATE+0x5af0 AbSelfIoBoostsList : _SINGLE_LIST_ENTRY+0x5af8 AbPropagateBoostsList : _SINGLE_LIST_ENTRY+0x5b00 AbDpc            : _KDPC+0x5b40 IoIrpStackProfilerCurrent : _IOP_IRP_STACK_PROFILER+0x5b94 IoIrpStackProfilerPrevious : _IOP_IRP_STACK_PROFILER+0x5be8 TimerExpirationTrace : [16] _KTIMER_EXPIRATION_TRACE+0x5ce8 TimerExpirationTraceCount : Uint4B+0x5d00 Mailbox          : Ptr64 _REQUEST_MAILBOX+0x5d40 RequestMailbox   : [1] _REQUEST_MAILBOX

this structure is fucking massive

PCR可以在内核模式中通过寄存器去访问到
在windows中,可以通过两个内核方法来获取到EPROCESS和ETHREAD,这两个方法就是通过查询PCR/PRCB来实现的

0: kd> uf nt!psgetcurrentthread
nt!KeGetCurrentThread:
fffff801`710dcc9c 65488b042588010000 mov   rax,qword ptr gs:[188h]
fffff801`710dcca5 c3              ret

在这里插入图片描述
因此我们可以判断出gs段寄存器就是PCR的地址,0x188h正好是0x180h+0x8h,也就是PRCB的CurrentThread成员

nt!PsGetCurrentProcess:
fffff801`711661b8 65488b042588010000 mov   rax,qword ptr gs:[188h]
fffff801`711661c1 488b80b8000000  mov     rax,qword ptr [rax+0B8h]
fffff801`711661c8 c3              ret

这个方法可真是套娃中的套娃
gs:[188h]是PCR结构体中的PRCB结构体的KTHREAD结构体

再加b8h就是KTHREAD结构体中的_KAPC_STATE结构体的_KPROCESS结构体

0: kd> dt nt!_KTHREAD+0x000 Header           : _DISPATCHER_HEADER+0x018 SListFaultAddress : Ptr64 Void+0x020 QuantumTarget    : Uint8B+0x028 InitialStack     : Ptr64 Void+0x030 StackLimit       : Ptr64 Void+0x038 StackBase        : Ptr64 Void+0x040 ThreadLock       : Uint8B+0x048 CycleTime        : Uint8B+0x050 CurrentRunTime   : Uint4B+0x054 ExpectedRunTime  : Uint4B+0x058 KernelStack      : Ptr64 Void+0x060 StateSaveArea    : Ptr64 _XSAVE_FORMAT+0x068 SchedulingGroup  : Ptr64 _KSCHEDULING_GROUP+0x070 WaitRegister     : _KWAIT_STATUS_REGISTER+0x071 Running          : UChar+0x072 Alerted          : [2] UChar+0x074 SpareMiscFlag0   : Pos 0, 1 Bit+0x074 ReadyTransition  : Pos 1, 1 Bit+0x074 ProcessReadyQueue : Pos 2, 1 Bit+0x074 WaitNext         : Pos 3, 1 Bit+0x074 SystemAffinityActive : Pos 4, 1 Bit+0x074 Alertable        : Pos 5, 1 Bit+0x074 UserStackWalkActive : Pos 6, 1 Bit+0x074 ApcInterruptRequest : Pos 7, 1 Bit+0x074 QuantumEndMigrate : Pos 8, 1 Bit+0x074 UmsDirectedSwitchEnable : Pos 9, 1 Bit+0x074 TimerActive      : Pos 10, 1 Bit+0x074 SystemThread     : Pos 11, 1 Bit+0x074 ProcessDetachActive : Pos 12, 1 Bit+0x074 CalloutActive    : Pos 13, 1 Bit+0x074 ScbReadyQueue    : Pos 14, 1 Bit+0x074 ApcQueueable     : Pos 15, 1 Bit+0x074 ReservedStackInUse : Pos 16, 1 Bit+0x074 UmsPerformingSyscall : Pos 17, 1 Bit+0x074 ApcPendingReload : Pos 18, 1 Bit+0x074 TimerSuspended   : Pos 19, 1 Bit+0x074 SuspendedWaitMode : Pos 20, 1 Bit+0x074 Reserved         : Pos 21, 11 Bits+0x074 MiscFlags        : Int4B+0x078 AutoAlignment    : Pos 0, 1 Bit+0x078 DisableBoost     : Pos 1, 1 Bit+0x078 UserAffinitySet  : Pos 2, 1 Bit+0x078 AlertedByThreadId : Pos 3, 1 Bit+0x078 QuantumDonation  : Pos 4, 1 Bit+0x078 EnableStackSwap  : Pos 5, 1 Bit+0x078 GuiThread        : Pos 6, 1 Bit+0x078 DisableQuantum   : Pos 7, 1 Bit+0x078 ChargeOnlySchedulingGroup : Pos 8, 1 Bit+0x078 DeferPreemption  : Pos 9, 1 Bit+0x078 QueueDeferPreemption : Pos 10, 1 Bit+0x078 ForceDeferSchedule : Pos 11, 1 Bit+0x078 SharedReadyQueueAffinity : Pos 12, 1 Bit+0x078 FreezeCount      : Pos 13, 1 Bit+0x078 TerminationApcRequest : Pos 14, 1 Bit+0x078 AutoBoostEntriesExhausted : Pos 15, 1 Bit+0x078 KernelStackResident : Pos 16, 1 Bit+0x078 EtwStackTraceApcInserted : Pos 17, 8 Bits+0x078 ReservedFlags    : Pos 25, 7 Bits+0x078 ThreadFlags      : Int4B+0x07c Spare0           : Uint4B+0x080 SystemCallNumber : Uint4B+0x084 Spare1           : Uint4B+0x088 FirstArgument    : Ptr64 Void+0x090 TrapFrame        : Ptr64 _KTRAP_FRAME+0x098 ApcState         : _KAPC_STATE+0x098 ApcStateFill     : [43] UChar
0: kd> dt _KAPC_STATE
nt!_KAPC_STATE+0x000 ApcListHead      : [2] _LIST_ENTRY+0x020 Process          : Ptr64 _KPROCESS+0x028 InProgressFlags  : UChar+0x028 KernelApcInProgress : Pos 0, 1 Bit+0x028 SpecialApcInProgress : Pos 1, 1 Bit+0x029 KernelApcPending : UChar+0x02a UserApcPending   : UChar

终极套娃

系统调用

windows对syscall的存储和描述位于这两个结构体中:service table descriptor和一个函数指针数组

service table descriptor结构体保存了一些元数据,这些数据描述了OS支持的syscall

这些东西都是没有官方文档的,但是很多人已经通过逆向总结出了他的一些重要字段,通过分析KiSystemCall64和KiSystemservice例程,你也能分析出来

typedef struct _KSERVICE_TABLE_DESCRIPTOR
{PULONG Base; // array of addresses or offsetsPULONG Count;ULONG Limit; // size of the arrayPUCHAR Number;...
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;

base是一个数组,里面全是函数指针

syscall number就是这个数组里的index

limit是数组的长度

内核会维护两个全局数组KSERVER_DESCRIPTOR和KSERIE_DESCRIPTORTableSHadow

在这里插入图片描述
可以看到后者比前者多了一部分,W32pservicetable里面都是GUI syscall

kiservicetabkle指向非GUI syscall,w32pservietable指向GUI syscall

下面是KiServiceTable的内容
在这里插入图片描述

不过在64bit的操作系统上就稍有不同了

在64bit操作系统上,kiservicetable指向的是一个成员为32bit的整型数的数组,该数字的高28bit是一个偏移量,指向syscall的位置,剩下的14bit表示要传给该syscall的参数个数,偏移量加上kiservicetable的地址就是syscall的真正地址

我们先看一下ntdll!ntcreatefile是如何调用syscall的

在这里插入图片描述
再看一下kiservicetable的base的地址

0: kd> x nt!kiservicetable
fffff803`12963cb0 nt!KiServiceTable = <no type information>

ntdll!ntcreatefile在调用syscall之前,给eax赋值0x55h,也就是kiservicetable指向的数组中的第0x55h个元素,每个元素占4bytes(32bit)

0: kd> dd nt!kiservicetable+(55*4) L1
fffff803`12963e04  01d3ed07

注意在windbg中进行混合算术运算需要使用括号

这里的L1用于限制结果数量,可以看到只输出了一组

016daf40的前28bit(右移4bit即可)加上kiservicetable即可获得syscall的真正地址

0: kd> u nt!kiservicetable+(01d3ed07>>4)
nt!NtCreateFile:
fffff803`12b37b80 4881ec88000000  sub     rsp,88h
fffff803`12b37b87 33c0            xor     eax,eax
fffff803`12b37b89 4889442478      mov     qword ptr [rsp+78h],rax
fffff803`12b37b8e c744247020000000 mov     dword ptr [rsp+70h],20h
fffff803`12b37b96 89442468        mov     dword ptr [rsp+68h],eax
fffff803`12b37b9a 4889442460      mov     qword ptr [rsp+60h],rax
fffff803`12b37b9f 89442458        mov     dword ptr [rsp+58h],eax
fffff803`12b37ba3 8b8424e0000000  mov     eax,dword ptr [rsp+0E0h]

参数个数是7,要想取得最低的4bit,直接和0xfh做与运算就行了,0xfh->1111b

0: kd> ? 01d3ed07&f
Evaluate expression: 7 = 00000000`00000007

用户模式下的API在底层都是通过多个syscall来实现的

syscall一般通过软件中断或者特定的指令实现

interrupt、traps、faults

外围设备和软件如何与处理器交互?

在当代的计算机系统中,处理器通常通过数据bus连接到外围设备

比如PCI总线、火线、或者USB
当一个设备需要引起处理器注意的时候,它会引发一个中断来强制处理器停止手头的工作转而去处理该设备的请求

那么处理器如何知道怎么去处理这个请求呢?

在高等级层面,你可以把中断想象为一个用于指示一个函数数组的index的数字,档处理器接收到终端的时候,他就会去指向该中断所指向的函数,执行完成之后处理器会返回到自己被中断的地方继续执行

这种被叫做硬件中断,因为他们是直接由外围硬件设备产生的,天生就是异步的

处理器在执行指令的时候可能会遇到exception(异常),比如除0、空指针等

异常可以被分为两种,一种叫做faults,一种叫做traps
fault是可以更正的错误,比如档处理器执行一条引用了合法内存地址的指令,但是该地址的数据不存在的时候(可能是所属内存页swap到硬盘上去了),那么此时一个page fault就会被生成,处理器会保存当前的执行状态,调用page fault handler来纠正这个错误(将page交换回内存中),然后重新执行那条引起fault的指令

trap是由执行特定的指令引起的,比如在64位中,syscall指令会导致处理器开始执行一段由MSR寄存器指向的地址处的指令,handler完了之后,执行会被恢复到syscall的下一条指令

可以看到fault和trap的最大区别就是代码在哪里恢复执行,前者会重复执行一次,后者会执行之后的代码

系统调用通常都是通过特殊的异常或者trap指令来实现的

interrupts

IDT interrupt descriptor table 中断描述符表,256项

每一项都是一个结构体,包含了中断handler的信息

IDT的地址由IDTR寄存器保存

在这256项中,只有32-255是可以由用户自己定义的,0~31是预定义的

32bit系统中,IDT是一个8bytes结构体,定义如下:

0: kd> dt nt!_kidtentry+0x000 Offset           : Uint2B+0x002 Selector         : Uint2B+0x004 Access           : Uint2B+0x006 ExtendedOffset   : Uint2B

在64bit中,IDT的定义和上面差不多,除了中断handler的地址被分成了三个成员

0: kd> dt nt!_kidtentry64+0x000 OffsetLow        : Uint2B+0x002 Selector         : Uint2B+0x004 IstIndex         : Pos 0, 3 Bits+0x004 Reserved0        : Pos 3, 5 Bits+0x004 Type             : Pos 8, 5 Bits+0x004 Dpl              : Pos 13, 2 Bits+0x004 Present          : Pos 15, 1 Bit+0x006 OffsetMiddle     : Uint2B+0x008 OffsetHigh       : Uint4B+0x00c Reserved1        : Uint4B+0x000 Alignment        : Uint8B

可以看到,offset被分成了high middle low三部分


http://chatgpt.dhexx.cn/article/idcGZo6e.shtml

相关文章

Windows内核原理与实现--Windows基本结构概述

一、Windows系统结构概述 1、Windows采用双模式来保护操作系统本身,内核模式和用户模式。在Windows中,用户代码和内核代码有各自的运行环境,而且它们可以访问的内存空间也并不相同。在x86中,内核代码可以访问当前进程的4GB虚拟地址空间,而用户代码只能访问底端2GB虚拟地址…

《Windows内核原理与实现笔记》(一)Windows系统结构和基本概念

Windows内核结构 上图是windows内核的组成结构 如图Windows内核分三层&#xff0c;与硬件直接打交道的是硬件抽象层HAL&#xff0c;这一层把所有与硬件相关代码逻辑隔离到一个专门模块中&#xff0c;从而是上层尽可能独立于硬件平台。HAL是一个独立动态链接库&#xff0c;wind…

windows内核基础

windows分层模型 硬件抽象层屏蔽了硬件实现功能的细节。 IRP为内核层重要的数据结构。 物理地址和虚拟地址 x64的cpu仅仅支持64位地址中的前48位。其中若虚拟地址为内核&#xff0c;则前16位为ffff&#xff1b;若虚拟地址为用户模式&#xff0c;则前16位为0000。用户能看到的…

WebService的工作原理

WebService的工作原理如下&#xff1a; 服务提供者WebService2和WebService3通过UDDI协议将服务注册WebService目录中服务消费者WebService1通过UDDI协议从WebService目录中查询服务&#xff0c;并获得服务的WSDL服务描述文件服务消费者WebService1通过WSDL语言远程调用WebSer…

WebService原理

1、WebService实际上就是两个应用程序之间的远程调用&#xff0c;而且这种调用是跨语言的。 2、应用程序调用WebService的接口&#xff0c;实际上就是解析XML语言。也就是说两个应用程序之间的交流实际上就是通过XML来交流的。 3、WebService内部的实现是基于HTTP协议的&…

Web Service 的工作原理

Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求&#xff0c;轻量级的独立的通讯技术。是:通过SOAP在Web上提供的软件服务&#xff0c;使用WSDL文件进行说明&#xff0c;并通过UDDI进行注册。…

JavaScript高级程序设计(第三版)pdf版 下载

分享关于JavaScript高级程序设计&#xff08;第3版&#xff09;[美] Nicholas C.Zakas著 李松峰 曹力 译 一书供大家学习&#xff01;&#xff01;&#xff01; 链接: https://pan.baidu.com/s/1RD4EXuQnTqH3kUfHWFaOYw 提取码: vias 复制这段内容后打开百度网盘手机App&#…

JS高级程序设计(14)

DOM 文档对象模型&#xff08;DOM&#xff09;是HTML和XML文档的编程借口。DOM表示由多层节点构成的文档&#xff0c;通过它开发者可以添加、删除和修改页面的各个部分。 文章目录 DOM一、节点层级1.Node类型2.Document类型3.Element类型4.Text类型5.Comment属性6.CDATASectio…

javascript高级程序设计(红宝书)记录

故心故心故心故心小故冲啊 文章目录 第3章.语法基础第4章.变量作用域与内存第5章.基本引用类型第6章.集合引用类型第8章.对象、类与面向对象编程第10章.函数第11章.期约与异步函数第12章.BOM第17章事件第24章.网络请求与远程资源第25章.客户端存储 第3章.语法基础 undefined 值…

JavaScript高级编程

原文地址&#xff1a; http://www.onlamp.com/pub/a/onlamp/2007/07/05/writing-advanced-javascript.html Web应用程序&#xff08;Web Applications&#xff09; 从计算机纪元的黎明刚刚来临开始&#xff0c;不同平台间软件的互用性就一直是关注的焦点。为了尽可能实…

javascript高级程序设计 第三版

网盘地址 提取码&#xff1a;vh81 笔记 第二章 2.1script标签 <script>元素属性&#xff1a;async、charset、defer、language、src、type async和defer只对外部脚本有效&#xff0c;language已废弃&#xff0c;type默认为“text/javascript”defer属性可以让脚本在文…

js高级程序设计(一) —— js简介

学习《JavaScript高级程序设计》的知识总结&#xff0c;以及对部分内容的扩展~ 1、一个完整的js实现的三个部分 核心&#xff08;ECMAScript) 文档对象模型&#xff08;DOM) 浏览器对象模型&#xff08;BOM) 1-1&#xff1a;ECMAScript ECMA-262的近一版是第 5版&#xf…

JS高级程序设计(12)

BOM 浏览器对象模型BOM提供了与网页无关的浏览器功能对象。 文章目录 BOM一、window对象1.Global作用域2.窗口关系3.窗口位置与像素比4.窗口大小5.视口位置6.导航与打开新窗口7.定时器8.系统对话框 二、location对象1.查询字符串2.操作地址 三、navigator对象1.检测插件2.注册…

JavaScript 高级程序设计

理解原型对象 无论什么时候&#xff0c;只要创建一个新函数&#xff0c;就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。 在默认的情况下,所有的原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个包含一个指向prototyp…

js高级程序设计(第一章)

1.什么是JavaScript 1.1 简短的历史回顾 出现背景&#xff1a;当时&#xff0c;验证简单的表单&#xff0c;需要大量与服务器的往返通信成为用户的痛点。 出现时间&#xff1a;1997 年&#xff0c;JavaScript 1.1 作为提案被提交给欧洲计算机制造商协会&#xff08;Ecma&…

JavaScript高级程序

文章目录 1. JavaScript 实现1.1 ECMAScript1.2 DOM1.3 BOM1.4 小结 1. JavaScript 实现 虽然 JavaScript 和 ECMAScript 基本上是同义词&#xff0c;但 JavaScript 远远不限于 ECMA-262 所定义的那样。 完整的 JavaScript 实现包含以下几个部分:  核心(ECMAScript)  文档…

JavaScript高级程序设计——读书笔记

文章目录 第1章 JavaScript简介第2章 在HTML中使用JavaScript第3章 基本概念第4章 变量、作用域、内存问题第5章 引用类型第6章 面向对象的程序设计第7章 匿名函数第8章 BOM第9章 客户端检测第10章 DOM第11章 DOM2和DOM3第12章 事件第13章 表单脚本第14章 错误处理与调试第15章…

javascript高级程序设计第四版(javascript高级程序设计第四版)

如何学习 JavaScript 先说说学js的条件 论条件&#xff0c;咱是文科生&#xff0c;大学专业工商管理&#xff0c;和计算机毛关系都没&#xff1b;有人说英语&#xff0c;读了四年大学&#xff0c;很遗憾&#xff0c;咱还四级没混过&#xff1b;就咱这条件都学得乐呵呵的&#x…

JavaScript高级程序设计学习笔记----初识JavaScript

一、JavaScript概述 1.JavaScript 介绍&#xff1a; 简称JS&#xff0c;是一种浏览器解释型语言&#xff0c;嵌套在HTML文件中交给浏览器解释执行。主要用来实现网页的动态效果&#xff0c;用户交互及前后端的数据传输等。 2.JavaScript 组成&#xff1a; 核心语法 - ECMAScr…

JavaScript高级程序设计 第4版

文章目录 第 1 章  什么是JavaScript1.2JavaScript1.2.1 ECMAScript1.2.2 DOM1.2.3 BOM 第 2 章 HTML中的JavaScript2.1 script元素2.1.1 标签占位符2.1.2 推迟执行脚本2.1.3 异步执行脚本2.1.4 动态加载脚本2.1.5 XHTML中的变化 2.2 noscript元素 第 3 章 语言基础3.1…