锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 1) APCs鍏佽鐢ㄦ埛紼嬪簭鍜岀郴緇熷厓浠跺湪涓涓繘紼嬬殑鍦板潃絀洪棿鍐呮煇涓嚎紼嬬殑涓婁笅鏂囦腑鎵ц浠g爜銆?br>2) I/O綆$悊鍣ㄤ嬌鐢ˋPCs鏉ュ畬鎴愪竴涓嚎紼嬪彂璧風殑寮傛鐨処/O鎿嶄綔銆備緥濡傦細褰撲竴涓澶囬┍鍔ㄨ皟鐢↖oCompleteRequest鏉ラ氱煡I/O綆$悊鍣紝瀹冨凡緇忕粨鏉熷鐞嗕竴涓紓姝/O璇鋒眰鏃訛紝I/O綆$悊鍣ㄦ帓闃熶竴涓猘pc鍒板彂璧瘋姹傜殑綰跨▼銆傜劧鍚庣嚎紼嬪湪涓涓緝浣嶪RQL綰у埆錛屾潵鎵цAPC. APC鐨勪綔鐢ㄦ槸浠庣郴緇熺┖闂存嫹璐滻/O鎿嶄綔緇撴灉鍜岀姸鎬佷俊鎭埌綰跨▼铏氭嫙鍐呭瓨絀洪棿鐨勪竴涓紦鍐蹭腑銆?br>3) 浣跨敤APC鍙互寰楀埌鎴栬呰緗竴涓嚎紼嬬殑涓婁笅鏂囧拰鎸傝搗綰跨▼鐨勬墽琛屻?/p>
涓婇潰鏄綉涓婃壘鏉ョ殑錛屼笅闈㈡槸MSDN涓婄殑璇存槑錛?/p>
Each thread has its own APC queue. An application queues an APC to a thread by calling the QueueUserAPC function. The calling thread specifies the address of an APC function in the call to QueueUserAPC. The queuing of an APC is a request for the thread to call the APC function. 榪樺厛鐪嬩竴涓嬮偅浜涢噸瑕佺粨鏋勶細 kd> dt KTHREAD ………… 涓婇潰綰㈣壊閮ㄥ垎鏄疉PC鏈哄埗鐢ㄥ埌鐨勫嚑涓瓧孌碉紒錛?/p>
kd> dt _KAPC_STATE 鏄劇劧錛岃繖閲岀殑 ApcListHead 灝辨槸 APC 闃熷垪澶淬備笉榪囪繖鏄釜澶у皬涓?2 鐨勬暟緇勶紝璇存槑瀹為檯 SavedApcState涔熸槸涓猒KAPC_STATE緇撴瀯錛屽綋褰撳墠紼嬫殏鏃?#8220;鎸傞潬(Attach)”鍒板彟涓涓繘紼嬬殑鍦板潃絀洪棿鐨勬椂渚紝ApcState灝辨嫹璐濆埌SavedApcState鏆傛椂瀛樻斁錛?/p>
褰撶劧錛岃繕瑕佹湁鐘舵佷俊鎭鏄庢湰綰跨▼褰撳墠鏄浜?#8220;鍘熷鐜”榪樻槸“鎸傞潬鐜”錛岃繖灝辨槸 ApcStateIndex 鐨勪綔鐢紝浠g爜涓負 ApcStateIndex鐨勫煎畾涔変簡涓縐嶆灇涓劇被鍨嬶細 typedef enum _KAPC_ENVIRONMENT { 瀹為檯鍙敤浜?ApcStateIndex 鐨勫彧鏄?OriginalApcEnvironment鍜?AttachedApcEnvironment銆?/p>
KAPC_STATE 鎸囬拡鏁扮粍 ApcStatePointer[2]錛屽氨鐢ˋpcStateIndex 鐨勫綋鍓嶅間綔涓轟笅鏍囷紝鑰屾暟緇勪腑鐨勬寚閽堝垯鏍規嵁鎯呭喌鍙互鍒嗗埆鎸囧悜涓や釜APC_STATE 鏁版嵁緇撴瀯涓殑涓涓?/p>
kd> dt _KAPC ;APC瀵硅薄 KernelRoutine銆丷undownRoutine銆丯ormalRoutine銆傚叾涓彧鏈?NormalRoutine鎵嶆寚鍚?鎵ц)APC 鍑芥暟鐨勮姹傝呮墍鎻愪緵鐨勫嚱鏁幫紝鍏朵綑涓や釜閮芥槸杈呭姪鎬х殑錛?/p>
NTKERNELAPI 榪欎釜鍑芥暟涓昏鐢ㄦ潵鍒濆鍖朅pc錛坃KAPC錛夎繖涓粨鏋勭殑錛屽鏋淓nvironment==CurrentApcEnvironment,Apc->ApcStateIndex灝辯敱KTHREAD涓殑ApcStateIndex鍐沖畾錛屼絾Environment涓嶈兘澶т簬KTHREAD涓殑ApcStateIndex錛?/p>
鏈鍚庯紝APC 璇鋒眰鐨勬ā寮廝rocessorMode錛屼絾鏄湁涓緥澶栵紝閭e氨鏄細濡傛灉鎸囬拡NormalRoutine 涓?0錛岄偅涔堝疄闄呯殑妯″紡鍙樻垚浜?KernelMode銆傝繖鏄洜涓哄湪榪欑鎯呭喌涓嬫病鏈夌敤鎴風┖闂碅PC鍑芥暟鍙互鎵ц錛?鍞竴灝嗗緱鍒版墽琛岀殑鏄疜ernelRoutine錛?/p>
鏈鍚庯紝KeInitializeApc 璁劇疆Inserted鍩熶負FALSE銆傜劧鑰屽垵濮嬪寲APC瀵硅薄錛屽茍娌℃湁鎶婂畠瀛樻斁鍒扮浉搴旂殑APC闃熷垪涓?/p>
鎹瓵PC璇鋒眰鐨勫叿浣撴儏鍐碉紝鏈夋椂鍊欒鎻掑湪闃熷垪鐨勫墠澶達紝涓鑸垯鎸傚湪闃熷垪鐨勫熬閮ㄣ?/p>
_KiServiceExit: cli ; disable interrupts ; EXIT_ALL NoRestoreSegs, NoRestoreVolatile ;榪欎釜瀹忎互鍚庡啀璁?/p>
DISPATCH_USER_APC macro TFrame, ReturnCurrentEax test byte ptr [TFrame]+TsEflags+2, EFLAGS_V86_MASK/010000h ; is previous mode v86? mov ebx, TFrame ;DISPATCH_USER_APC ebp, ReturnCurrentEax錛屾樉鐒惰繖閲屾槸緙栬瘧鐨勶紒 ; sti ; Allow higher priority ints ; stdCall _KiDeliverApc, <1, 0, ebx> ;1灝辨槸UserMode pop ecx ; (ecx) = OldIrql ifnb <ReturnCurrentEax> ;鍚屼笂鍒嗘瀽 cli ALIGN 4 榪欐浠g爜涓昏媯鏌ワ細 鍗沖皢榪斿洖鐨勬槸鍚︾敤鎴風┖闂淬?br>鏄惁鏈夌敤鎴稟PC璇鋒眰姝e湪絳夊緟鎵ц 鏉′歡絎﹀悎鎵嶇敤KiDeliverApc鐪熸鎶曢扐PC銆傛敞鎰忎唬鐮乯mp b錛屽ソ鍍忓湪榪斿洖鐢ㄦ埛絀洪棿鍓岾iDeliverApc浼氳寰幆璋冪敤鐩村埌娌℃湁user APC錛屽叾瀹炰笉鏄殑錛孠iDeliverApc姣忓鐞嗗畬涓涓猆ser APC灝辨妸UserApcPending娓呴浂錛屾墍浠ser APCs鍦ㄨ繑鍥炵敤鎴風┖闂存椂榪樻槸鍙兘鎶曢掍竴嬈★紒KiDeliverApc涓敤while澶勭悊瀹屾墍鏈塊ernel Mode APCs錛屼絾User Mode APC鍗村彧澶勭悊涓涓紒浜嬪疄涓奤ser APC鐨勬姇閫掓槸寰堢壒孌婄殑錛屼互鍚庝細璁插埌錛岃屼笖姣忔鍙兘鎶曢掍竴嬈★紒 KiDeliverApc ( 榪欎釜鍑芥暟閲岄潰榪樻瘮杈冨鏉傦紝浠g爜涓嶅笘浜嗐?/p>
鍙傛暟PreviousMode琛ㄧず闇瑕?#8220;鎶曢?#8221;鍝竴縐?APC錛屽彲浠ユ槸UserMode錛屼篃鍙互鏄疜ernelMode銆備笉榪囷紝KernelMode 紜疄琛ㄧず鍙姹傛墽琛屽唴鏍?APC錛岃孶serMode 鍗磋〃紺哄湪鎵ц鍐呮牳 APC 涔嬪鍐嶆墽琛岀敤鎴稟PC銆?/p>
The Windows operating system uses three kinds of APCs: User APCs Normal kernel APCs _KAPC.ApcMode==KernelMode,_KAPC.KernelRoutine!=NULL,_KAPC.NormolRoutine!=NULL Special kernel APCs _KAPC.ApcMode==KernelMode,_KAPC.KernelRoutine!=NULL,_KAPC.NormolRoutine==NULL 鏈変竴鐐瑰畠浠殑_KAPC.KernelRoutine鑲畾涓嶄負絀恒傚茍涓旓紝濡傛灉NormolRoutine涔熶笉涓虹┖錛岄偅涔圞ernelRoutine閮藉湪NormolRoutine琚皟鐢ㄥ墠琚皟鐢紒錛?/p>
涓婃枃涓鍒版姇閫扷ser Mode APCs鏄緢鐗規畩鐨勶紝閬撶悊寰堢畝鍗曪紝鍥犱負User Mode APC鏄痳ing3涓嬬殑鍥炶皟鍑芥暟錛屾樉鐒秗ing0涓殑KiDeliverAPC錛堬級涓嶈兘鍍廗ernel Mode APC閭f牱鐩存帴call錛屽繀欏昏鍏堝洖鍒皉ing3鐜涓嬨傚綋鐒朵笉鑳藉儚鏅氭儏鍐甸偅鏍瘋繑鍥烇紙鍚﹀垯灝卞洖鍒皉ing3緋葷粺璋冪敤鐨勫湴鏂逛簡錛夛紝鍙湁涓涓姙娉曪紝閭e氨鏄慨鏀筎rapFrame 錛屾楠楃郴緇熻繑鍥?#8220;APC鍥炶皟鍑芥暟”錛並iInitializeUserApc灝辨槸榪欎箞鍋氱殑錛?/p>
璇ュ嚱鏁伴鍏堟妸TrapFrame杞寲涓篊ontextFrame錛岀劧鍚庣Щ鍔ㄧ敤鎴鋒丒SP鎸囬拡錛屽垎閰嶅ぇ綰izeof錛圕ONTEXT錛?sizeof錛圞APC_RECORD錛変釜瀛楄妭: UserStack-> …… KAPC_RECORD …… …… CONTEXT TopOfStack-> …… KAPC_RECORD灝辨槸KiInitializeUserApc鐨勬渶鍚庡洓涓弬鏁?/p>
nt!_KAPC_RECORD +0x000 NormalRoutine : Ptr32 void +0x004 NormalContext : Ptr32 Void +0x008 SystemArgument1 : Ptr32 Void +0x00c SystemArgument2 : Ptr32 Void CONTEXT緇撴瀯涓昏鏉ュ瓨鏀捐淇敼鍓嶇殑TrapFrame錛屼箣鎵浠ョ敤CONTEXT緇撴瀯鏄窡APC鍑芥暟榪斿洖鏈夊叧錛?/p>
TrapFrame->HardwareEsp = UserStack; TrapFrame->Eip = (ULONG)KeUserApcDispatcher; TrapFrame->ErrCode = 0; 浠庝笂闈㈢殑浠g爜鐪嬪埌紜疄淇敼浜員rapFrame錛屽茍涓旇繑鍥炲埌鐨勬槸ring3涓嬬殑KeUserApcDispatcher錛屽垰鎵嶈鐨刜KAPC_RECORD鍏跺疄涔熸槸瀹冪殑鍙傛暟錛佺湡姝f垜浠殑User APC鍥炶皟鍑芥暟鏄敱KeUserApcDispatcher璋冪敤鐨勶紒 .func KiUserApcDispatcher@16 .globl _KiUserApcDispatcher@16 /* Setup SEH stack */ lea eax, [esp+CONTEXT_ALIGNED_SIZE+16] mov ecx, fs:[TEB_EXCEPTION_LIST] mov edx, offset _KiUserApcExceptionHandler mov [eax], ecx mov [eax+4], edx /* Enable SEH */ mov fs:[TEB_EXCEPTION_LIST], eax /* Put the Context in EDI */ pop eax lea edi, [esp+12] /* Call the APC Routine */ call eax /* Restore exception list */ mov ecx, [edi+CONTEXT_ALIGNED_SIZE] mov fs:[TEB_EXCEPTION_LIST], ecx /* Switch back to the context */ push 1 ; TestAlert push edi ;edi->CONTEXT緇撴瀯 call _ZwContinue@8 ;;涓嶄細榪斿洖鍒拌繖閲岀殑 涓婇潰鐨勪唬鐮佸茍涓嶉毦鐞嗚В錛屾垜浠殑User APC鍥炶皟鍑芥暟榪斿洖鍚庯紝绔嬪嵆璋冪敤浜哯wContinue錛岃繖鏄釜ntdll涓殑瀵煎嚭鍑芥暟錛岃繖涓嚱鏁板張閫氳繃緋葷粺璋冪敤榪涘叆kernel涓殑NtContinue錛?/p>
NTSTATUS ; NtContinue ( ; IN PCONTEXT ContextRecord, ; IN BOOLEAN TestAlert ; ) ; ; Routine Description: ; ; This routine is called as a system service to continue execution after ; an exception has occurred. Its function is to transfer information from ; the specified context record into the trap frame that was built when the ; system service was executed, and then exit the system as if an exception ; had occurred. ; ; WARNING - Do not call this routine directly, always call it as ; ZwContinue!!! This is required because it needs the ; trapframe built by KiSystemService. ; ; Arguments: ; ; KTrapFrame (ebp+0: after setup) -> base of KTrapFrame ; ; ContextRecord (ebp+8: after setup) = Supplies a pointer to a context rec. ; ; TestAlert (esp+12: after setup) = Supplies a boolean value that specifies ; whether alert should be tested for the previous processor mode. ; ; Return Value: ; ; Normally there is no return from this routine. However, if the specified ; context record is misaligned or is not accessible, then the appropriate ; status code is returned. ; ;-- NcTrapFrame equ [ebp + 0] NcContextRecord equ [ebp + 8] NcTestAlert equ [ebp + 12] align dword cPublicProc _NtContinue ,2 push ebp ;ebp->TrapFrame ; ; Restore old trap frame address since this service exits directly rather ; than returning. ; mov ebx, PCR[PcPrcbData+PbCurrentThread] ; get current thread address mov edx, [ebp].TsEdx ; restore old trap frame address mov [ebx].ThTrapFrame, edx ; ; ; Call KiContinue to load ContextRecord into TrapFrame. On x86 TrapFrame ; is an atomic entity, so we don't need to allocate any other space here. ; ; KiContinue(NcContextRecord, 0, NcTrapFrame) ; mov ebp,esp mov eax, NcTrapFrame mov ecx, NcContextRecord stdCall _KiContinue, <ecx, 0, eax> or eax,eax ; return value 0? jnz short Nc20 ; KiContinue failed, go report error ; ; Check to determine if alert should be tested for the previous processor mode. ; cmp byte ptr NcTestAlert,0 ; Check test alert flag je short Nc10 ; if z, don't test alert, go Nc10 mov al,byte ptr [ebx]+ThPreviousMode ; No need to xor eax, eax. stdCall _KeTestAlertThread, <eax> ; test alert for current thread ;濡傛灉User APCs涓嶄負絀猴紝瀹冧細璁劇疆UserApcPending, ;璺烝lertable鏃犲叧 Nc10: pop ebp ; (ebp) -> TrapFrame mov esp,ebp ; (esp) = (ebp) -> trapframe jmp _KiServiceExit2 ; common exit Nc20: pop ebp ; (ebp) -> TrapFrame mov esp,ebp ; (esp) = (ebp) -> trapframe jmp _KiServiceExit ; common exit stdENDP _NtContinue NtContinue鎶奀ONTEXT緇撴瀯杞寲鎴怲rapFrame錛堝洖澶嶅師鏉ョ殑闄烽槺甯э級錛岀劧鍚庡氨浠嶬iServiceExit2澶勯鍑虹郴緇熻皟鐢紒 ;++ ; ; _KiServiceExit2 - same as _KiServiceExit BUT the full trap_frame ; context is restored ; ;-- public _KiServiceExit2 _KiServiceExit2: cli ; disable interrupts DISPATCH_USER_APC ebp ; ; Exit from SystemService ; EXIT_ALL ; RestoreAll KiServiceExit2璺烱iServiceExit宸笉澶氾紝鍙槸瀹忓弬鏁扮殑涓嶅悓!鍚屾牱濡傛灉榪樻湁User APC鍙堜細榪涘叆涓婃枃鎻忚堪鐨勬儏褰紝鐩村埌娌℃湁User APC錛岃嚦姝ゆ墠浼氳繑鍥炵湡姝e彂璧峰師濮嬬郴緇熻皟鐢ㄧ殑鍦版柟錛?/p>
An asynchronous procedure call (APC) is a function that executes asynchronously in the context of a particular thread. When an APC is queued to a thread, the system issues a software interrupt. The next time the thread is scheduled, it will run the APC function. An APC generated by the system is called a kernel-mode APC. An APC generated by an application is called a user-mode APC. A thread must be in an alertable state to run a user-mode APC.
nt!KTHREAD
+0x000 Header : _DISPATCHER_HEADER
+0x010 MutantListHead : _LIST_ENTRY
+0x018 InitialStack : Ptr32 Void
+0x01c StackLimit : Ptr32 Void
+0x020 KernelStack : Ptr32 Void
+0x024 ThreadLock : Uint4B
+0x028 ApcState : _KAPC_STATE
+0x028 ApcStateFill : [23] UChar
+0x03f ApcQueueable : UChar
+0x040 NextProcessor : UChar
+0x041 DeferredProcessor : UChar
+0x042 AdjustReason : UChar
+0x043 AdjustIncrement : Char
+0x044 ApcQueueLock : Uint4B
+0x048 ContextSwitches : Uint4B
+0x04c State : UChar
+0x04d NpxState : UChar
+0x04e WaitIrql : UChar
+0x04f WaitMode : Char
+0x050 WaitStatus : Int4B
+0x054 WaitBlockList : Ptr32 _KWAIT_BLOCK
+0x054 GateObject : Ptr32 _KGATE
+0x058 Alertable : UChar
+0x059 WaitNext : UChar
+0x05a WaitReason : UChar
+0x05b Priority : Char
+0x05c EnableStackSwap : UChar
+0x05d SwapBusy : UChar
+0x05e Alerted : [2] UChar
+0x060 WaitListEntry : _LIST_ENTRY
+0x060 SwapListEntry : _SINGLE_LIST_ENTRY
+0x068 Queue : Ptr32 _KQUEUE
+0x06c WaitTime : Uint4B
+0x070 KernelApcDisable : Int2B
+0x072 SpecialApcDisable : Int2B
+0x070 CombinedApcDisable : Uint4B
+0x074 Teb : Ptr32 Void
+0x078 Timer : _KTIMER
+0x078 TimerFill : [40] UChar
+0x0a0 AutoAlignment : Pos 0, 1 Bit
+0x0a0 DisableBoost : Pos 1, 1 Bit
+0x0a0 ReservedFlags : Pos 2, 30 Bits
+0x0a0 ThreadFlags : Int4B
+0x0a8 WaitBlock : [4] _KWAIT_BLOCK
+0x0a8 WaitBlockFill0 : [23] UChar
+0x0bf SystemAffinityActive : UChar
+0x0a8 WaitBlockFill1 : [47] UChar
+0x0d7 PreviousMode : Char
+0x0a8 WaitBlockFill2 : [71] UChar
+0x0ef ResourceIndex : UChar
+0x0a8 WaitBlockFill3 : [95] UChar
+0x107 LargeStack : UChar
+0x108 QueueListEntry : _LIST_ENTRY
+0x110 TrapFrame : Ptr32 _KTRAP_FRAME
+0x114 CallbackStack : Ptr32 Void
+0x118 ServiceTable : Ptr32 Void
+0x11c ApcStateIndex : UChar
+0x11d IdealProcessor : UChar
+0x11e Preempted : UChar
+0x11f ProcessReadyQueue : UChar
+0x120 KernelStackResident : UChar
+0x121 BasePriority : Char
+0x122 PriorityDecrement : Char
+0x123 Saturation : Char
+0x124 UserAffinity : Uint4B
+0x128 Process : Ptr32 _KPROCESS
+0x12c Affinity : Uint4B
+0x130 ApcStatePointer : [2] Ptr32 _KAPC_STATE
+0x138 SavedApcState : _KAPC_STATE
+0x138 SavedApcStateFill : [23] UChar
+0x14f FreezeCount : Char
+0x150 SuspendCount : Char
+0x151 UserIdealProcessor : UChar
+0x152 CalloutActive : UChar
+0x153 Iopl : UChar
+0x154 Win32Thread : Ptr32 Void
+0x158 StackBase : Ptr32 Void
+0x15c SuspendApc : _KAPC
+0x15c SuspendApcFill0 : [1] UChar
…………
nt!_KAPC_STATE
+0x000 ApcListHead : [2] _LIST_ENTRY錛屾瘡涓寚閽堟寚鍚慱KAPC緇撴瀯
+0x010 Process : Ptr32 _KPROCESS
+0x014 KernelApcInProgress : UChar
+0x015 KernelApcPending : UChar
+0x016 UserApcPending : UChar
涓?姣忎釜綰跨▼)鏈変袱涓?APC 闃熷垪銆傝繖鏄洜涓?APC 鍑芥暟鍒嗕負鐢ㄦ埛 APC 鍜屽唴鏍?APC 涓ょ錛屽悇鏈?br>鍚勭殑闃熷垪銆傛墍璋撶敤鎴?APC錛屾槸鎸囩浉搴旂殑 APC 鍑芥暟浣嶄簬鐢ㄦ埛絀洪棿銆佸湪鐢ㄦ埛絀洪棿鎵ц錛涜屽唴鏍?br>APC錛屽垯鐩稿簲鐨?APC 鍑芥暟涓哄唴鏍稿嚱鏁般?/p>
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment,
InsertApcEnvironment
} KAPC_ENVIRONMENT;
nt!_KAPC
+0x000 Type : UChar
+0x001 SpareByte0 : UChar
+0x002 Size : UChar
+0x003 SpareByte1 : UChar
+0x004 SpareLong0 : Uint4B
+0x008 Thread : Ptr32 _KTHREAD
+0x00c ApcListEntry : _LIST_ENTRY
+0x014 KernelRoutine : Ptr32 void
+0x018 RundownRoutine : Ptr32 void
+0x01c NormalRoutine : Ptr32 void
+0x020 NormalContext : Ptr32 Void
+0x024 SystemArgument1 : Ptr32 Void
+0x028 SystemArgument2 : Ptr32 Void
+0x02c ApcStateIndex : Char
+0x02d ApcMode : Char
+0x02e Inserted : UChar
VOID
KeInitializeApc (
__out PRKAPC Apc,
__in PRKTHREAD Thread,
__in KAPC_ENVIRONMENT Environment,
__in PKKERNEL_ROUTINE KernelRoutine,
__in_opt PKRUNDOWN_ROUTINE RundownRoutine,
__in_opt PKNORMAL_ROUTINE NormalRoutine,
__in_opt KPROCESSOR_MODE ProcessorMode,
__in_opt PVOID NormalContext
);
NTKERNELAPI
BOOLEAN
KeInsertQueueApc (
__inout PRKAPC Apc,
__in_opt PVOID SystemArgument1,
__in_opt PVOID SystemArgument2,
__in KPRIORITY Increment
);
DISPATCH_USER_APC ebp, ReturnCurrentEax
; Exit from SystemService
;
local a, b, c
c:
.errnz (EFLAGS_V86_MASK AND 0FF00FFFFh)
jnz short b ; if nz, yes, go check for APC
test byte ptr [TFrame]+TsSegCs,MODE_MASK ; is previous mode user mode?
jz a ; No, previousmode=Kernel, jump out
b: mov ebx, PCR[PcPrcbData+PbCurrentThread]; get addr of current thread
mov byte ptr [ebx]+ThAlerted, 0 ; clear kernel mode alerted
cmp byte ptr [ebx]+ThApcState.AsUserApcPending, 0
je a ; if eq, no user APC pending
ifnb <ReturnCurrentEax>;鏉′歡瀹忔眹緙栵紝濡傛灉ReturnCurrentEax鍙傛暟涓嶄負絀猴紝鍒欑紪璇戯紒
mov [ebx].TsEax, eax ; Store return code in trap frame
mov dword ptr [ebx]+TsSegFs, KGDT_R3_TEB OR RPL_MASK
mov dword ptr [ebx]+TsSegDs, KGDT_R3_DATA OR RPL_MASK
mov dword ptr [ebx]+TsSegEs, KGDT_R3_DATA OR RPL_MASK
mov dword ptr [ebx]+TsSegGs, 0
endif
; Save previous IRQL and set new priority level
;
RaiseIrql APC_LEVEL
push eax ; Save OldIrql
; call the APC delivery routine.
;
; ebx - Trap frame
; 0 - Null exception frame
; 1 - Previous mode
;
; call APC deliver routine
;
LowerIrql ecx
mov eax, [ebx].TsEax ; Restore eax, just in case
endif
jmp b ; 娉ㄦ剰榪欎釜寰幆錛侊紒
a:
endm
鍓嶉潰璁茶繃錛孠THREAD 涓湁涓や釜 KAPC_STATE 鏁版嵁緇撴瀯錛屼竴涓槸 ApcState錛屽彟涓涓槸SavedApcState錛屼簩鑰呴兘鏈堿PC 闃熷垪錛屼絾鏄鎶曢掔殑鍙槸ApcState 涓殑闃熷垪銆?/p>
IN KPROCESSOR_MODE PreviousMode,//鍐欐垚DeliverMode涓嶆槸鏇村ソ
IN PKEXCEPTION_FRAME ExceptionFrame,//榪欎釜鍙傛暟鍑犱箮灝辨槸0
IN PKTRAP_FRAME TrapFrame
)
User APCs run strictly in user mode and only when the current thread is in an alertable wait state. The operating system uses user APCs to implement mechanisms such as overlapped I/O and the QueueUserApc Win32 routine. 錛坮un IRQL = PASSIVE_LEVEL錛?br>Normal kernel APCs run in kernel mode at IRQL = PASSIVE_LEVEL. A normal kernel APC preempts all user-mode code, including user APCs. Normal kernel APCs are generally used by file systems and file-system filter drivers.
Special kernel APCs run in kernel mode at IRQL = APC_LEVEL. A special kernel APC preempts user-mode code and kernel-mode code that executes at IRQL = PASSIVE_LEVEL, including both user APCs and normal kernel APCs. The operating system uses special kernel APCs to handle operations such as I/O request completion.
浠庝唬鐮佺殑瑙掑害鐪嬫槸榪欐牱鐨勶細
_KAPC.ApcMode==UserMode,_KAPC.KernelRoutine!=NULL,_KAPC.NormolRoutine!=NULL
鏈枃鏉ヨ嚜CSDN鍗氬錛岃漿杞借鏍囨槑鍑哄錛?a >http://blog.csdn.net/better0332/archive/2009/06/29/4306683.aspx
1) APCs鍏佽鐢ㄦ埛紼嬪簭鍜岀郴緇熷厓浠跺湪涓涓繘紼嬬殑鍦板潃絀洪棿鍐呮煇涓嚎紼嬬殑涓婁笅鏂囦腑鎵ц浠g爜銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">2) I/O綆$悊鍣ㄤ嬌鐢ˋPCs鏉ュ畬鎴愪竴涓嚎紼嬪彂璧風殑寮傛鐨処/O鎿嶄綔銆備緥濡傦細褰撲竴涓澶囬┍鍔ㄨ皟鐢↖oCompleteRequest鏉ラ氱煡I/O綆$悊鍣紝瀹冨凡緇忕粨鏉熷鐞嗕竴涓紓姝/O璇鋒眰鏃訛紝I/O綆$悊鍣ㄦ帓闃熶竴涓猘pc鍒板彂璧瘋姹傜殑綰跨▼銆傜劧鍚庣嚎紼嬪湪涓涓緝浣嶪RQL綰у埆錛屾潵鎵цAPC. APC鐨勪綔鐢ㄦ槸浠庣郴緇熺┖闂存嫹璐滻/O鎿嶄綔緇撴灉鍜岀姸鎬佷俊鎭埌綰跨▼铏氭嫙鍐呭瓨絀洪棿鐨勪竴涓紦鍐蹭腑銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">3) 浣跨敤APC鍙互寰楀埌鎴栬呰緗竴涓嚎紼嬬殑涓婁笅鏂囧拰鎸傝搗綰跨▼鐨勬墽琛屻?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
灝界APCs鍦╪t浣撶郴緇撴瀯涓嬭騫挎硾浣跨敤錛屼絾鏄叧浜庢庢牱浣跨敤瀹冪殑鏂囨。鍗撮潪甯哥殑緙轟箯銆傛湰綃囨垜浠緇嗕粙緇嶄笅nt緋葷粺鏄庢牱澶勭悊APCs鐨勶紝騫朵笖璁板綍瀵煎嚭鐨刵t鍑芥暟錛屾柟渚胯澶囬┍鍔ㄥ紑鍙戣呭湪浠栦滑鐨勭▼搴忎腑浣跨敤APCs銆傛垜涔熶細灞曠ず涓涓潪甯稿彲闈犵殑NT鐨凙PC璋冨害瀛愮▼搴廗iDeliverApc鐨勫疄鐜幫紝鏉ュ府鍔╀綘鏇村ソ鐨勬帉鎻PC璋冨害鐨勫唴騫曘?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
APC瀵硅薄
鍦∟T涓紝鏈変袱縐嶇被鍨嬬殑APCs錛氱敤鎴鋒ā寮忓拰鍐呮牳妯″紡銆傜敤鎴稟PCs榪愯鍦ㄧ敤鎴鋒ā寮忎笅鐩爣綰跨▼褰撳墠涓婁笅鏂囦腑錛屽茍涓旈渶瑕佷粠鐩爣綰跨▼寰楀埌璁稿彲鏉ヨ繍琛屻傜壒鍒槸錛岀敤鎴鋒ā寮忕殑APCs闇瑕佺洰鏍囩嚎紼嬪鍦╝lertable絳夊緟鐘舵佹墠鑳借鎴愬姛鐨勮皟搴︽墽琛屻傞氳繃璋冪敤涓嬮潰浠繪剰涓涓嚱鏁幫紝閮藉彲浠ヨ綰跨▼榪涘叆榪欑鐘舵併傝繖浜涘嚱鏁版槸錛欿eWaitForSingleObject, KeWaitForMultipleObjects, KeWaitForMutexObject, KeDelayExecutionThread銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">瀵逛簬鐢ㄦ埛妯″紡涓嬶紝鍙互璋冪敤鍑芥暟SleepEx, SignalObjectAndWait, WaitForSingleObjectEx, WaitForMultipleObjectsEx,MsgWaitForMultipleObjectsEx 閮藉彲浠ヤ嬌鐩爣綰跨▼澶勪簬alertable絳夊緟鐘舵侊紝浠庤岃鐢ㄦ埛妯″紡APCs鎵ц,鍘熷洜鏄繖浜涘嚱鏁版渶緇堥兘鏄皟鐢ㄤ簡鍐呮牳涓殑KeWaitForSingleObject, KeWaitForMultipleObjects, KeWaitForMutexObject, KeDelayExecutionThread絳夊嚱鏁般傚彟澶栭氳繃璋冪敤涓涓湭鍏紑鐨刟lert-test鏈嶅姟KeTestAlertThread錛岀敤鎴風嚎紼嬪彲浠ヤ嬌鐢ㄦ埛妯″紡APCs鎵ц銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
褰撲竴涓敤鎴鋒ā寮廇PC琚姇閫掑埌涓涓嚎紼嬶紝璋冪敤涓婇潰鐨勭瓑寰呭嚱鏁幫紝濡傛灉榪斿洖絳夊緟鐘舵丼TATUS_USER_APC錛屽湪榪斿洖鐢ㄦ埛妯″紡鏃訛紝鍐呮牳杞幓鎺у埗APC渚嬬▼錛屽綋APC渚嬬▼瀹屾垚鍚庯紝鍐嶇戶緇嚎紼嬬殑鎵ц.
鍜岀敤鎴鋒ā寮廇PCs姣旇緝錛屽唴鏍告ā寮廇PCs鎵ц鍦ㄥ唴鏍告ā寮忎笅銆傚彲浠ヨ鍒掑垎涓哄父瑙勭殑鍜岀壒孌婄殑涓ょ被銆傚綋APCs琚姇閫掑埌涓涓壒孌婄殑綰跨▼錛岀壒孌婄殑鍐呮牳妯″紡APCs涓嶉渶瑕佷粠綰跨▼寰楀埌璁稿彲鏉ヨ繍琛屻傜劧鑰岋紝甯歌鐨勫唴鏍告ā寮廇PCs鍦ㄤ粬浠垚鍔熸墽琛屽墠錛岄渶瑕佹湁鐗瑰畾鐨勭幆澧冦傛澶栵紝鐗規畩鐨勫唴鏍窤PC琚敖鍙兘蹇湴鎵ц錛屾棦鍙APC_LEVEL綰т笂鏈夊彲璋冨害鐨勬椿鍔ㄣ傚湪寰堝鎯呭喌涓嬶紝鐗規畩鐨勫唴鏍窤PC鐢氳嚦鑳藉敜閱掗樆濉炵殑綰跨▼銆傛櫘閫氱殑鍐呮牳APC浠呭湪鎵鏈夌壒孌夾PC閮借鎵ц瀹岋紝騫朵笖鐩爣綰跨▼浠嶅湪榪愯錛屽悓鏃惰綰跨▼涓篃娌℃湁鍏跺畠鍐呮牳妯″紡APC姝f墽琛屾椂鎵嶆墽琛屻傜敤鎴鋒ā寮廇PC鍦ㄦ墍鏈夊唴鏍告ā寮廇PC鎵ц瀹屽悗鎵嶆墽琛岋紝騫朵笖浠呭湪鐩爣綰跨▼鏈塧lertable灞炴ф椂鎵嶆墽琛屻?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
姣忎竴涓瓑寰呮墽琛岀殑APC閮藉瓨鍦ㄤ簬涓涓嚎紼嬫墽琛屼綋錛岀敱鍐呮牳綆$悊鐨勯槦鍒椾腑銆傜郴緇熶腑鐨勬瘡涓涓嚎紼嬮兘鍖呭惈涓や釜APC闃熷垪錛屼竴涓槸涓虹敤鎴鋒ā寮廇PCs,鍙︿竴涓槸涓哄唴鏍告ā寮廇PCs鐨勩?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">NT閫氳繃涓涓垚涓篕APC鐨勫唴鏍告帶鍒跺璞℃潵鎻忚堪涓涓肌錛幫跡錛庡敖綆★激錛わ極涓病鏈夋槑紜殑鏂囨。鍖栵肌錛幫跡锝擄紝浣嗘槸鍦∟TDDK.H涓嵈闈炲父娓呮鐨勫畾涔変簡錛★及錛e璞°備粠涓嬮潰鐨凨APC瀵硅薄鐨勫畾涔夌湅錛屾湁浜涙槸涓嶉渶瑕佽鏄庣殑銆傚儚Type鍜孲ize銆俆ype琛ㄧず浜嗚繖鏄竴涓狝PC鍐呮牳瀵硅薄銆傚湪nt涓紝姣忎竴涓唴鏍稿璞℃垨鑰呮墽琛屼綋瀵硅薄閮芥湁Type鍜孲ize榪欎袱涓煙銆傜敱姝ゅ鐞嗗嚱鏁板彲浠ョ‘瀹氬綋鍓嶅鐞嗙殑瀵硅薄銆係ize琛ㄧず涓涓瓧瀵歸綈鐨勭粨鏋勪綋鐨勫ぇ灝忋備篃灝辨槸鎸囨槑浜嗗璞″崰鐨勫唴瀛樼┖闂村ぇ灝忋係pare0鐪嬭搗鏉ユ湁浜涙櫐娑╅毦鎳傦紝浣嗘槸瀹冩槸娌$敤浠涔堜換浣曟繁榪滅殑鎰忎箟錛屼粎浠呮槸涓轟簡鍐呭瓨琛ラ綈銆傚叾浠栫殑鍩熷皢鍦ㄤ笅闈㈢殑綃囧箙涓粙緇嶃?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
//-------------------------------------------------------------------------------------------------------
鍑犱釜鍑芥暟澹版槑鍜岀粨鏋勫畾涔夛細
typedef struct _KAPC {
CSHORT Type;
CSHORT Size;
ULONG Spare0;
struct _KTHREAD *Thread;
LIST_ENTRY ApcListEntry;
PKKERNEL_ROUTINE KernelRoutine;
PKRUNDOWN_ROUTINE RundownRoutine;
PKNORMAL_ROUTINE NormalRoutine;
PVOID NormalContext;
//
// N.B. The following two members MUST be together.
//
PVOID SystemArgument1;
PVOID SystemArgument2;
CCHAR ApcStateIndex;
KPROCESSOR_MODE ApcMode;
BOOLEAN Inserted;
} KAPC, *PKAPC, *RESTRICTED_POINTER PRKAPC;
//------
APC鐜
涓涓嚎紼嬪湪瀹冩墽琛岀殑浠繪剰鏃跺埢錛屽亣璁懼綋鍓嶇殑IRQL鏄湪Passive綰э紝瀹冨彲鑳介渶瑕佷復鏃跺湪鍏朵粬鐨勮繘紼嬩笂涓嬫枃涓墽琛屼唬鐮侊紝涓轟簡瀹屾垚榪欎釜鎿嶄綔錛岀嚎紼嬭皟鐢ㄧ郴緇熷姛鑳藉嚱鏁癒eAttachProcess錛屽湪浠庤繖涓皟鐢ㄨ繑鍥炴椂錛岀嚎紼嬫墽琛屽湪鍙︿竴涓繘紼嬬殑鍦板潃絀洪棿銆傚厛鍓嶆墍鏈夊湪綰跨▼鑷繁鐨勮繘紼嬩笂涓嬫枃涓瓑寰呮墽琛岀殑APCs,鐢變簬榪欐椂鍏舵墍灞炶繘紼嬬殑鍦板潃絀洪棿涓嶆槸褰撳墠鍙敤鐨勶紝鍥犳浠栦滑涓嶈兘琚姇閫掓墽琛屻傜劧鑰岋紝鏂扮殑鎻掑叆鍒拌繖涓嚎紼嬬殑APCs鍙互鎵ц鍦ㄨ繖涓柊鐨勮繘紼嬬┖闂淬傜敋鑷沖綋綰跨▼鏈鍚庝粠鏂扮殑榪涚▼涓垎紱繪椂錛屾柊鐨勬彃鍏ュ埌榪欎釜綰跨▼鐨凙PCs榪樺彲浠ュ湪榪欎釜綰跨▼鎵灞炵殑榪涚▼涓婁笅鏂囦腑鎵ц銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">涓轟簡杈懼埌鎺у埗APC浼犻佺殑榪欎釜紼嬪害錛孨T涓瘡涓嚎紼嬬淮鎶や簡涓や釜APC鐜鎴栬呰鏄姸鎬併傛瘡涓涓狝PC鐜鍖呭惈浜嗙敤鎴鋒ā寮忕殑APC闃熷垪鍜屽唴鏍告ā寮忕殑APC闃熷垪錛屼竴涓寚鍚戝綋鍓嶈繘紼嬪璞$殑鎸囬拡鍜屼笁涓帶鍒跺彉閲忥紝鐢ㄤ簬鎸囧嚭錛氭槸鍚︽湁鏈喅鐨勫唴鏍告ā寮廇PCs(KernelApcPending),鏄惁鏈夊父瑙勫唴鏍告ā寮廇PC鍦ㄨ繘琛屼腑(KernelApcInProgress)錛屾槸鍚︽湁鏈喅鐨勭敤鎴鋒ā寮忕殑APC(UserApcPending). 榪欎簺APC鐨勭幆澧冧繚瀛樺湪綰跨▼瀵硅薄鐨凙pcStatePointer鍩熶腑銆傝繖涓煙鏄敱2涓厓绱犵粍鎴愮殑鏁扮粍銆傚嵆錛?0x138 ApcStatePointer : [2] Ptr32 _KAPC_STATE
typedef struct _KAPC_STATE {
LIST_ENTRY ApcListHead[MaximumMode];
struct _KPROCESS *Process;
BOOLEAN KernelApcInProgress;
BOOLEAN KernelApcPending;
BOOLEAN UserApcPending;
} KAPC_STATE, *PKAPC_STATE, *PRKAPC_STATE;
lkd> dt _kthread
ntdll!_KTHREAD
+0x000 Header : _DISPATCHER_HEADER
+0x010 MutantListHead : _LIST_ENTRY
+0x018 InitialStack : Ptr32 Void
+0x01c StackLimit : Ptr32 Void
+0x020 Teb : Ptr32 Void
+0x024 TlsArray : Ptr32 Void
+0x028 KernelStack : Ptr32 Void
+0x02c DebugActive : UChar
+0x02d State : UChar
+0x02e Alerted : [2] UChar
+0x030 Iopl : UChar
+0x031 NpxState : UChar
+0x032 Saturation : Char
+0x033 Priority : Char
+0x034 ApcState : _KAPC_STATE
+0x04c ContextSwitches : Uint4B
+0x050 IdleSwapBlock : UChar
+0x051 Spare0 : [3] UChar
+0x054 WaitStatus : Int4B
+0x058 WaitIrql : UChar
+0x059 WaitMode : Char
+0x05a WaitNext : UChar
+0x05b WaitReason : UChar
+0x05c WaitBlockList : Ptr32 _KWAIT_BLOCK
+0x060 WaitListEntry : _LIST_ENTRY
+0x060 SwapListEntry : _SINGLE_LIST_ENTRY
+0x068 WaitTime : Uint4B
+0x06c BasePriority : Char
+0x06d DecrementCount : UChar
+0x06e PriorityDecrement : Char
+0x06f Quantum : Char
+0x070 WaitBlock : [4] _KWAIT_BLOCK
+0x0d0 LegoData : Ptr32 Void
+0x0d4 KernelApcDisable : Uint4B
+0x0d8 UserAffinity : Uint4B
+0x0dc SystemAffinityActive : UChar
+0x0dd PowerState : UChar
+0x0de NpxIrql : UChar
+0x0df InitialNode : UChar
+0x0e0 ServiceTable : Ptr32 Void
+0x0e4 Queue : Ptr32 _KQUEUE
+0x0e8 ApcQueueLock : Uint4B
+0x0f0 Timer : _KTIMER
+0x118 QueueListEntry : _LIST_ENTRY
+0x120 SoftAffinity : Uint4B
+0x124 Affinity : Uint4B
+0x128 Preempted : UChar
+0x129 ProcessReadyQueue : UChar
+0x12a KernelStackResident : UChar
+0x12b NextProcessor : UChar
+0x12c CallbackStack : Ptr32 Void
+0x130 Win32Thread : Ptr32 Void
+0x134 TrapFrame : Ptr32 _KTRAP_FRAME
+0x138 ApcStatePointer : [2] Ptr32 _KAPC_STATE
+0x140 PreviousMode : Char
+0x141 EnableStackSwap : UChar
+0x142 LargeStack : UChar
+0x143 ResourceIndex : UChar
+0x144 KernelTime : Uint4B
+0x148 UserTime : Uint4B
+0x14c SavedApcState : _KAPC_STATE
+0x164 Alertable : UChar
+0x165 ApcStateIndex : UChar
+0x166 ApcQueueable : UChar
+0x167 AutoAlignment : UChar
+0x168 StackBase : Ptr32 Void
+0x16c SuspendApc : _KAPC
+0x19c SuspendSemaphore : _KSEMAPHORE
+0x1b0 ThreadListEntry : _LIST_ENTRY
+0x1b8 FreezeCount : Char
+0x1b9 SuspendCount : Char
+0x1ba IdealProcessor : UChar
+0x1bb DisableBoost : UChar
涓籄PC鐜鏄綅浜庣嚎紼嬪璞$殑ApcState 鍩燂紝鍗籌細
+0x034 ApcState : _KAPC_STATE
綰跨▼涓瓑寰呭湪褰撳墠榪涚▼涓婁笅鏂囦腑鎵ц鐨凙PC淇濆瓨鍦ˋpcState鐨勯槦鍒椾腑銆傛棤璁轟綍鏃訛紝NT鐨凙PC媧懼彂鍣?dispatcher)鍜屽叾浠栫郴緇熷厓浠舵煡璇竴涓嚎紼嬫湭鍐崇殑APCs鏃? 浠栦滑閮戒細媯鏌ヤ富APC鐜錛屽鏋滆繖閲屾湁浠諱綍鏈喅鐨凙PCs,灝變細椹笂琚姇閫掞紝鎴栬呬慨鏀瑰畠鐨勬帶鍒跺彉閲忕◢鍚庢姇閫掋?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
絎簩涓狝PC鐜鏄綅浜庣嚎紼嬪璞$殑SavedApcState鍩燂紝褰撶嚎紼嬩復鏃舵寕鎺ュ埌鍏朵粬榪涚▼鏃訛紝瀹冩槸鐢ㄦ潵澶囦喚涓籄PC鐜鐨勩?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
褰撲竴涓嚎紼嬭皟鐢↘eAttachProcess錛屽湪鍙﹀鐨勮繘紼嬩笂涓嬫枃涓墽琛屽悗緇殑浠g爜鏃訛紝ApcState鍩熺殑鍐呭灝辮鎷瘋礉鍒癝avedApcState鍩熴傜劧鍚嶢pcState鍩熻娓呯┖錛屽畠鐨凙PC闃熷垪閲嶆柊鍒濆鍖栵紝鎺у埗鍙橀噺璁劇疆涓?錛屽綋鍓嶈繘紼嬪煙璁劇疆涓烘柊鐨勮繘紼嬨傝繖浜涙楠ゆ垚鍔熺殑紜繚鍏堝墠鍦ㄧ嚎紼嬫墍灞炵殑榪涚▼涓婁笅鏂囧湴鍧絀洪棿涓瓑寰呯殑APCs錛屽綋綰跨▼榪愯鍦ㄥ叾瀹冧笉鍚岀殑榪涚▼涓婁笅鏂囨椂錛岃繖浜汚PCs涓嶈浼犻佹墽琛屻傞殢鍚庯紝ApcStatePointer鍩熸暟緇勫唴瀹硅鏇存柊鏉ュ弽鏄犳柊鐨勭姸鎬侊紝鏁扮粍涓涓涓厓绱犳寚鍚慡avedApcState鍩燂紝絎簩涓厓绱犳寚鍚慉pcState鍩燂紝琛ㄦ槑綰跨▼鎵灞炶繘紼嬩笂涓嬫枃鐨凙PC鐜浣嶄簬SavedApcState鍩熴傜嚎紼嬬殑鏂扮殑榪涚▼涓婁笅鏂囩殑APC鐜浣嶄簬ApcState鍩熴傛渶鍚庯紝褰撳墠榪涚▼涓婁笅鏂囧垏鎹㈠埌鏂扮殑榪涚▼涓婁笅鏂囥?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
瀵逛簬涓涓狝PC瀵硅薄錛屽喅瀹氬綋鍓岮PC鐜鐨勬槸ApcStateIndex鍩熴侫pcStateIndex鍩熺殑鍊間綔涓篈pcStatePointer鍩熸暟緇勭殑绱㈠紩鏉ュ緱鍒扮洰鏍嘇PC鐜鎸囬拡銆傞殢鍚庯紝鐩爣APC鐜鎸囬拡鐢ㄦ潵鍦ㄧ浉搴旂殑闃熷垪涓瓨鏀綼pc瀵硅薄.
褰撶嚎紼嬩粠鏂扮殑榪涚▼涓劚紱繪椂(KeDetachProcess), 浠諱綍鍦ㄦ柊鐨勮繘紼嬪湴鍧絀洪棿涓瓑寰呮墽琛岀殑鏈喅鐨勫唴鏍窤PCs琚淳鍙戞墽琛屻傞殢鍚嶴avedApcState 鍩熺殑鍐呭琚嫹璐濆洖ApcState鍩熴係avedApcState 鍩熺殑鍐呭琚竻絀猴紝綰跨▼鐨凙pcStateIndex鍩熻璁句負OriginalApcEnvironment錛孉pcStatePointer鍩熸洿鏂幫紝褰撳墠榪涚▼涓婁笅鏂囧垏鎹㈠埌綰跨▼鎵灞炶繘紼嬨?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
浣跨敤APCs
璁懼椹卞姩紼嬪簭浣跨敤涓や釜涓昏鍑芥暟鏉ュ埄鐢ˋPCs, 絎竴涓槸KeInitializeApc錛岀敤鏉ュ垵濮嬪寲APC瀵硅薄銆傝繖涓嚱鏁版帴鍙椾竴涓┍鍔ㄥ垎閰嶇殑APC瀵硅薄錛屼竴涓洰鏍囩嚎紼嬪璞℃寚閽堬紝APC鐜绱㈠紩錛堟寚鍑篈PC瀵硅薄瀛樻斁浜庡摢涓狝PC鐜錛夛紝APC鐨刱ernel,rundown鍜宯ormal渚嬬▼鎸囬拡錛孉PC綾誨瀷錛堢敤鎴鋒ā寮忔垨鑰呭唴鏍告ā寮忥級鍜屼竴涓笂涓嬫枃鍙傛暟銆?鍑芥暟澹版槑濡備笅錛?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
NTKERNELAPI
VOID
KeInitializeApc (
IN PRKAPC Apc,
IN PKTHREAD Thread,
IN KAPC_ENVIRONMENT Environment,
IN PKKERNEL_ROUTINE KernelRoutine,
IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,
IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL,
IN KPROCESSOR_MODE ApcMode,
IN PVOID NormalContext
);
typedef enum _KAPC_ENVIRONMENT {
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment
} KAPC_ENVIRONMENT;
KeInitializeApc 棣栧厛璁劇疆APC瀵硅薄鐨凾ype鍜孲ize鍩熶竴涓傚綋鐨勫鹼紝鐒跺悗媯鏌ュ弬鏁癊nvironment鐨勫鹼紝濡傛灉鏄疌urrentApcEnvironment錛岄偅涔圓pcStateIndex鍩熻緗負鐩爣綰跨▼鐨凙pcStateIndex鍩熴傚惁鍒欙紝ApcStateIndex鍩熻緗負鍙傛暟Environment鐨勫箋傞殢鍚庯紝鍑芥暟鐩存帴鐢ㄥ弬鏁拌緗瓵PC瀵硅薄Thread錛孯undownRoutine錛孠ernelRoutine鍩熺殑鍊箋備負浜嗘紜湴紜畾APC鐨勭被鍨嬶紝KeInitializeApc 媯鏌ュ弬鏁癗ormalRoutine鐨勫鹼紝濡傛灉鏄疦ULL錛孉pcMode鍩熺殑鍊艱緗負KernelMode錛孨ormalContext鍩熻緗負NULL銆傚鏋淣ormalRoutine鐨勫間笉鏄疦ULL錛岃繖鏃跺欏畠涓瀹氭寚鍚戜竴涓湁鏁堢殑渚嬬▼錛屽氨鐢ㄧ浉搴旂殑鍙傛暟鏉ヨ緗瓵pcMode鍩熷拰NormalContext鍩熴傛渶鍚庯紝KeInitializeApc 璁劇疆Inserted鍩熶負FALSE.鐒惰屽垵濮嬪寲APC瀵硅薄錛屽茍娌℃湁鎶婂畠瀛樻斁鍒扮浉搴旂殑APC闃熷垪涓?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
浠庤繖涓В閲婄湅錛屼綘鍙互浜嗚В鍒癆PCs瀵硅薄濡傛灉緙哄皯鏈夋晥鐨凬ormalRoutine錛屽氨浼氳褰撲綔鍐呮牳妯″紡APCs.灝ゅ叾鏄畠浠細琚涓烘槸鐗規畩鐨勫唴鏍告ā寮廇PCs.
瀹為檯涓婏紝I/O綆$悊鍣ㄥ氨鏄敤榪欑被鐨凙PC鏉ュ畬鎴愬紓姝/O鎿嶄綔銆傜浉鍙嶅湴錛孉PC瀵硅薄瀹氫箟浜嗘湁鏁堢殑NormalRoutine錛屽茍涓擜pcMode鍩熸槸KernelMode錛屽氨浼氳褰撲綔甯歌鐨勫唴鏍告ā寮廇PCs,鍚﹀垯灝變細琚綋浣滄槸鐢ㄦ埛妯″紡APCs. NTDDK.H涓璌ernelRoutine, RundownRoutine, and NormalRoutine 鐨勫畾涔夊涓嬶細
typedef
VOID
(*PKKERNEL_ROUTINE) (
IN struct _KAPC *Apc,
IN OUT PKNORMAL_ROUTINE *NormalRoutine,
IN OUT PVOID *NormalContext,
IN OUT PVOID *SystemArgument1,
IN OUT PVOID *SystemArgument2
);
typedef
VOID
(*PKRUNDOWN_ROUTINE) (
IN struct _KAPC *Apc
);
typedef
VOID
(*PKNORMAL_ROUTINE) (
IN PVOID NormalContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
//------------------
閫氬父錛屾棤璁烘槸浠涔堢被鍨嬶紝姣忎釜APC瀵硅薄蹇呴』瑕佸寘鍚竴涓湁鏁堢殑KernelRoutine 鍑芥暟鎸囬拡銆傚綋榪欎釜APC琚玁T鐨凙PC dispatcher浼犻佹墽琛屾椂錛岃繖涓緥紼嬮鍏堣鎵ц銆傜敤鎴鋒ā寮忕殑APCs蹇呴』鍖呭惈涓涓湁鏁堢殑NormalRoutine 鍑芥暟鎸囬拡錛岃繖涓嚱鏁板繀欏誨湪鐢ㄦ埛鍐呭瓨鍖哄煙銆傚悓鏍風殑錛屽父瑙勫唴鏍告ā寮廇PCs涔熷繀欏誨寘鍚竴涓湁鏁堢殑NormalRoutine錛屼絾鏄畠灝卞儚KernelRoutine涓鏍瘋繍琛屽湪鍐呮牳妯″紡銆備綔涓哄彲閫夋嫨鐨勶紝浠繪剰綾誨瀷鐨凙PC閮藉彲浠ュ畾涔変竴涓湁鏁堢殑RundownRoutine錛岃繖涓緥紼嬪繀欏誨湪鍐呮牳鍐呭瓨鍖哄煙錛屽茍涓斾粎浠呭綋緋葷粺闇瑕侀噴鏀続PC闃熷垪鐨勫唴瀹規椂錛屾墠琚皟鐢ㄣ備緥濡傜嚎紼嬮鍑烘椂錛屽湪榪欑鎯呭喌涓嬶紝KernelRoutine鍜孨ormalRoutine閮戒笉鎵ц錛屽彧鏈塕undownRoutine鎵ц銆傛病鏈夎繖涓緥紼嬬殑APC瀵硅薄浼氳鍒犻櫎銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
璁頒綇錛屾姇閫扐PCs鍒頒竴涓嚎紼嬬殑鍔ㄤ綔錛屼粎浠呮槸鎿嶄綔緋葷粺璋冪敤KiDeliverApc瀹屾垚鐨勩傛墽琛孉PC瀹為檯涓婂氨鏄皟鐢ˋPC鍐呯殑渚嬬▼銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
涓鏃PC瀵硅薄瀹屾垚鍒濆鍖栧悗錛岃澶囬┍鍔ㄨ皟鐢↘eInsertQueueApc鏉ュ皢APC瀵硅薄瀛樻斁鍒扮洰鏍囩嚎紼嬬殑鐩稿簲鐨凙PC闃熷垪涓傝繖涓嚱鏁版帴鍙椾竴涓敱KeInitializeApc瀹屾垚鍒濆鍖栫殑APC瀵硅薄鎸囬拡錛屼袱涓郴緇熷弬鏁板拰涓涓紭鍏堢駭澧為噺銆傝窡浼犻掔粰KeInitializeApc鍑芥暟鐨勫弬鏁癱ontext 涓鏍鳳紝榪欎袱涓郴緇熷弬鏁板彧鏄湪APC鐨勪緥紼嬫墽琛屾椂錛岀畝鍗曠殑浼犻掔粰APC鐨勪緥紼嬨?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
NTKERNELAPI
BOOLEAN
KeInsertQueueApc (
IN PRKAPC Apc,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2,
IN KPRIORITY Increment
);
//-----------------
鍦↘eInsertQueueApc 灝咥PC瀵硅薄瀛樻斁鍒扮洰鏍囩嚎紼嬬浉搴旂殑APC闃熷垪涔嬪墠錛屽畠棣栧厛媯鏌ョ洰鏍囩嚎紼嬫槸鍚︽槸APC queueable銆傚鏋滀笉鏄紝鍑芥暟绔嬪嵆榪斿洖FALSE.濡傛灉鏄紝鍑芥暟鐩存帴鐢ㄥ弬鏁拌緗甋ystemArgument1鍩熷拰SystemArgument2 鍩燂紝闅忓悗錛屽嚱鏁拌皟鐢↘iInsertQueueApc鏉ュ皢APC瀵硅薄瀛樻斁鍒扮浉搴旂殑APC闃熷垪銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
KiInsertQueueApc 浠呬粎鎺ュ彈涓涓狝PC瀵硅薄鍜屼竴涓紭鍏堢駭澧為噺銆傝繖涓嚱鏁伴鍏堝緱鍒扮嚎紼婣PC闃熷垪鐨剆pinlock騫朵笖鎸佹湁瀹冿紝闃叉鍏朵粬綰跨▼淇敼褰撳墠綰跨▼鐨凙PC緇撴瀯銆傞殢鍚庯紝媯鏌PC瀵硅薄鐨処nserted 鍩熴傚鏋滄槸TRUE,琛ㄦ槑榪欎釜APC瀵硅薄宸茬粡瀛樻斁鍒癆PC闃熷垪涓簡錛屽嚱鏁扮珛鍗寵繑鍥濬ALSE.濡傛灉APC瀵硅薄鐨処nserted 鍩熸槸FALSE.鍑芥暟閫氳繃ApcStateIndex鍩熸潵紜畾鐩爣APC鐜錛岀劧鍚庢妸APC瀵硅薄瀛樻斁鍒扮浉搴旂殑APC闃熷垪涓紝鍗沖皢APC瀵硅薄涓殑ApcListEntry 鍩熼摼鍏ュ埌APC鐜鐨凙pcListHead鍩熶腑銆傞摼鍏ョ殑浣嶇疆鐢盇PC鐨勭被鍨嬪喅瀹氥傚父瑙勭殑鍐呮牳妯″紡APC,鐢ㄦ埛妯″紡APC閮芥槸瀛樻斁鍒扮浉搴旂殑APC闃熷垪鐨勬湯绔傜浉鍙嶇殑錛屽鏋滈槦鍒椾腑宸茬粡瀛樻斁浜嗕竴浜汚PC瀵硅薄錛岀壒孌婄殑鍐呮牳妯″紡APC瀛樻斁鍒伴槦鍒椾腑絎竴涓父瑙勫唴鏍告ā寮廇PC瀵硅薄鐨勫墠闈€傚鏋滄槸鍐呮牳瀹氫箟鐨勪竴涓綋綰跨▼閫鍑烘椂浣跨敤鐨勭敤鎴稟PC,瀹冧篃浼氳鏀懼湪鐩稿簲鐨勯槦鍒楃殑鍓嶉潰銆傜劧鍚庯紝綰跨▼鐨勪富APC鐜涓殑UserApcPending鍩熸澂璁劇疆涓篢RUE銆傝繖鏃禟iInsertQueueApc 璁劇疆APC瀵硅薄鐨処nserted 鍩熶負TRUE錛岃〃鏄庤繖涓狝PC瀵硅薄宸茬粡瀛樻斁鍒癆PC闃熷垪涓簡銆傛帴涓嬫潵錛屾鏌ヨ繖涓狝PC瀵硅薄鏄惁琚帓闃熷埌綰跨▼鐨勫綋鍓嶈繘紼嬩笂涓嬫枃APC鐜涓紝濡傛灉涓嶆槸錛屽嚱鏁扮珛鍗寵繑鍥濼RUE銆傚鏋滆繖鏄竴涓唴鏍告ā寮廇PC錛岀嚎紼嬩富APC鐜涓殑KernelApcPending鍩熻緗負TRUE銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
鍦╓IN32 SDK鏂囨。涓槸榪欐牱鎻忚堪APCs鐨勶細 褰撲竴涓狝PC琚垚鍔熺殑瀛樻斁鍒板畠鐨勯槦鍒楀悗錛屽彂鍑轟竴涓蔣涓柇錛孉PC灝嗕細鍦ㄧ嚎紼嬭璋冨害榪愯鐨勪笅涓涓椂闂寸墖鎵ц銆傜劧鑰岃繖涓嶆槸瀹屽叏姝g‘鐨勩傝繖鏍蜂竴涓蔣涓柇錛屼粎浠呮槸褰撲竴涓唴鏍告ā寮忕殑APC錛堟棤璁烘槸甯歌鐨勫唴鏍告ā寮廇PC榪樻槸鐗規畩鐨勫唴鏍告ā寮廇PC錛夐拡瀵逛簬璋冪敤綰跨▼鏃訛紝鎵嶄細鍙戝嚭銆傞殢鍚庡嚱鏁拌繑鍥濼RUE銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
1錛夊鏋淎PC涓嶆槸閽堝浜庤皟鐢ㄧ嚎紼嬶紝鐩爣綰跨▼鍦≒assive鏉冮檺絳夌駭澶勫湪絳夊緟鐘舵侊紱
2錛夎繖鏄竴涓父瑙勫唴鏍告ā寮廇PC
3錛夎繖涓嚎紼嬩笉鍐嶄復鐣屽尯
4錛夋病鏈夊叾浠栫殑甯歌鍐呮牳妯″紡APC浠嶇劧鍦ㄨ繘琛屼腑
閭d箞榪欎釜綰跨▼琚敜閱掞紝榪斿洖鐘舵佹槸STATUS_KERNEL_APC銆備絾鏄瓑寰呯姸鎬佹病鏈塧borted銆?濡傛灉榪欐槸涓涓敤鎴鋒ā寮廇PC錛孠iInsertQueueApc媯鏌ュ垽鏂洰鏍囩嚎紼嬫槸鍚︽槸alertable絳夊緟鐘舵侊紝騫朵笖WaitMode鍩熺瓑浜嶶serMode銆傚鏋滄槸錛屼富APC鐜鐨刄serApcPending 鍩熻緗負TRUE銆傜瓑寰呯姸鎬佽繑鍥濻TATUS_USER_APC錛屾渶鍚庯紝鍑芥暟閲婃斁spinlock錛岃繑鍥濼RUE錛岃〃紺篈PC瀵硅薄宸茬粡琚垚鍔熸斁鍏ラ槦鍒椼?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">鏃╂湡浣滀負APC綆$悊鍑芥暟鐨勮ˉ鍏咃紝璁懼椹卞姩寮鍙戣呭彲浠ヤ嬌鐢ㄦ湭鍏紑鐨勭郴緇熸湇鍔tQueueApcThread鏉ョ洿鎺ュ皢涓涓敤鎴鋒ā寮忕殑APC鎶曢掑埌鏌愪釜綰跨▼銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">榪欎釜鍑芥暟鍐呴儴瀹為檯涓婃槸璋冪敤浜咾eInitializeApc 鍜孠eInsertQueueApc 鏉ュ畬鎴愯繖涓換鍔°?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
NTSYSAPI
NTSTATUS
NTAPI
NtQueueApcThread (
IN HANDLE Thread,
IN PKNORMAL_ROUTINE NormalRoutine,
IN PVOID NormalContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
NT鐨凙PC媧懼彂鍣?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
NT媯鏌ユ槸鍚︾嚎紼嬫湁鏈喅鐨凙PCs. 鐒跺悗APC媧懼彂鍣ㄥ瓙紼嬪簭KiDeliverApc鍦ㄨ繖涓嚎紼嬩笂涓嬫枃鎵ц鏉ュ紑濮嬪皢鏈喅鐨凙PC鎵ц銆傛敞鎰忥紝榪欎釜琛屼負涓柇浜嗙嚎紼嬬殑姝e父鎵ц嫻佺▼錛岄鍏堝皢鎺у埗鏉冪粰APC媧懼彂鍣紝闅忓悗褰揔iDeliverApc瀹屾垚鍚庯紝緇х畫綰跨▼鐨勬墽琛屻?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">渚嬪錛氬綋涓涓嚎紼嬭璋冨害榪愯鏃訛紝鏈鍚庝竴姝ワ紝涓婁笅鏂囧垏鎹㈠嚱鏁?SwapContext 鐢ㄦ潵媯鏌ユ槸鍚︽柊鐨勭嚎紼嬫湁鏈喅鐨勫唴鏍窤PCs.濡傛灉鏄紝SwapContext瑕佷箞錛?錛夎姹備竴涓狝PC綰у埆鐨勮蔣涓柇鏉ュ紑濮婣PC鎵ц錛岀敱浜庢柊綰跨▼榪愯鍦ㄤ綆鐨処RQL錛圥assive綰у埆銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">鎴栬咃紙2錛夎繑鍥濼RUE錛岃〃紺烘柊鐨勭嚎紼嬫湁鏈喅鐨勫唴鏍窤PCs銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
絀剁珶鏄墽琛?1)榪樻槸(2)鍙栧喅浜庢柊綰跨▼鎵澶勭殑IRQL綰у埆. 濡傛灉瀹冪殑鏉冮檺綰у埆楂樹簬Passive綰?SwapContext 鎵ц(1),濡傛灉瀹冩槸鍦≒assive綰?鍒欓夋嫨鎵ц(2).
SwapContext鐨勮繑鍥炲間粎浠呮槸鐗瑰畾緋葷粺鍑芥暟鍙敤鐨?榪欎簺緋葷粺鍑芥暟璋冪敤SwapContext鏉ュ己鍒跺垏鎹㈢嚎紼嬩笂涓嬫枃鍒板彟涓涓嚎紼? 鐒跺悗,褰撹繖浜涚郴緇熷嚱鏁扮粡榪囦竴孌墊椂闂村啀緇х畫鏃?浠栦滑閫氬父媯鏌wapContext 鐨勮繑鍥炲?濡傛灉鏄疶RUE,浠栦滑灝變細璋冪敤APC媧懼彂鍣ㄦ潵鎶曢掑唴鏍窤PCs鍒板綋鍓嶇殑綰跨▼. 渚嬪:
緋葷粺鍑芥暟KiSwapThread琚瓑寰呮湇鍔$敤鏉ユ斁寮冨鐞嗗櫒錛岀洿鍒扮瓑寰呯粨鏉熴傝繖涓嚱鏁板唴閮ㄨ皟鐢⊿wapContext銆傚綋絳夊緟緇撴潫錛岀戶緇粠璋冪敤SwapContext澶勬墽琛屾椂錛屽氨浼氭鏌wapContext鐨勮繑鍥炲箋傚鏋滄槸TRUE錛孠iSwapThread浼氶檷浣嶪RQL綰у埆鍒癆PC綰э紝鐒跺悗璋冪敤KiDeliverApc鏉ュ湪褰撳墠綰跨▼鎵ц鍐呮牳APCs.
瀵逛簬鐢ㄦ埛APCs, 鍐呮牳璋冪敤APC媧懼彂鍣ㄤ粎浠呮槸褰撶嚎紼嬪洖鍒扮敤鎴鋒ā寮忥紝騫朵笖綰跨▼鐨勪富APC鐜鐨刄serApcPending鍩熶負TRUE鏃躲備緥濡傦細褰撶郴緇熸湇鍔℃淳鍙戝櫒KiSystemService瀹屾垚涓涓郴緇熸湇鍔¤姹傛鎵撶畻鍥炲埌鐢ㄦ埛妯″紡鏃訛紝瀹冧細媯鏌ユ槸鍚︽湁鏈喅鐨勭敤鎴稟PCs銆傚湪鎵ц涓婏紝KiDeliverApc璋冪敤鐢ㄦ埛APC鐨凨ernelRoutine. 闅忓悗錛孠iInitializeUserApc鍑芥暟琚皟鐢紝鐢ㄦ潵璁劇疆綰跨▼鐨勯櫡闃卞撫銆傛墍浠ヤ粠鍐呮牳妯″紡閫鍑烘椂錛岀嚎紼嬪紑濮嬪湪鐢ㄦ埛妯″紡涓嬫墽琛?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">銆侹iInitializeUserApc鐨勫嚱鏁扮殑浣滅敤鏄嫹璐濆綋鍓嶇嚎紼嬪厛鍓嶇殑鎵ц鐘舵侊紙褰撹繘鍏ュ唴鏍告ā寮忔椂錛岃繖涓姸鎬佷繚瀛樺湪綰跨▼鍐呮牳鏍堝垱寤虹殑闄烽槺甯ч噷錛夛紝浠庡唴鏍告爤鍒扮嚎紼嬬殑鐢ㄦ埛妯″紡鏍堬紝鍒濆鍖栫敤鎴鋒ā寮廇PC銆侫PC媧懼彂鍣ㄥ瓙紼嬪簭KiUserApcDispatcher鍦∟tdll.dll鍐呫傛渶鍚庯紝鍔犺澆闄烽槺甯х殑EIP瀵勫瓨鍣ㄥ拰Ntdll.dll涓璌iUserApcDispatcher鐨勫湴鍧銆傚綋闄烽槺甯ф渶鍚庨噴鏀炬椂錛屽唴鏍稿皢鎺у埗杞氦緇橩iUserApcDispatcher錛岃繖涓嚱鏁拌皟鐢ˋPC鐨凬ormalRoutine渚嬬▼錛孨ormalRoutine鍑芥暟鍦板潃浠ュ強鍙傛暟閮藉湪鏍堜腑錛屽綋渚嬬▼瀹屾垚鏃訛紝瀹冭皟鐢∟tContinue鏉ヨ綰跨▼鍒╃敤鍦ㄦ爤涓厛鍓嶇殑涓婁笅鏂囩戶緇墽琛岋紝浠夸經浠涔堜簨鎯呬篃娌℃湁鍙戠敓榪囥?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
褰撳唴鏍歌皟鐢↘iDeliverApc鏉ユ墽琛屼竴涓敤鎴鋒ā寮廇PC鏃訛紝綰跨▼涓殑PreviousMode鍩熻璁句負UserMode. TrapFrame鍩熸寚鍚戠嚎紼嬬殑闄烽槺甯с傚綋鍐呮牳璋冪敤KiDeliverApc鏉ユ墽琛屽唴鏍窤PCs鏃訛紝綰跨▼涓殑PreviousMode鍩熻璁句負KernelMode. TrapFrame鍩熸寚鍚慛ULL銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">娉ㄦ剰錛屾棤璁轟綍鏃跺彧瑕並ernelRoutine琚皟鐢紝浼犻掔粰瀹冪殑鎸囬拡鏄竴涓眬閮ㄧ殑APC灞炴х殑鍓湰錛岀敱浜嶢PC瀵硅薄宸茬粡鑴辯浜嗛槦鍒楋紝鎵浠ュ彲浠ュ畨鍏ㄧ殑鍦↘ernelRoutine涓噴鏀続PC鍐呭瓨銆傛澶栵紝榪欎釜渚嬬▼鍦ㄥ畠鐨勫弬鏁拌浼犻掔粰鍏朵粬渚嬬▼涔嬪墠錛屾湁涓涓渶鍚庣殑鏈轟細鏉ヤ慨鏀硅繖浜涘弬鏁般?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
緇撹錛?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">APC鎻愪緵浜嗕竴涓潪甯告湁鐢ㄧ殑鏈哄埗錛屽厑璁稿湪鐗瑰畾鐨勭嚎紼嬩笂涓嬫枃涓紓姝ョ殑鎵ц浠g爜銆備綔涓轟竴涓澶囬┍鍔ㄥ紑鍙戣咃紝浣犲彲浠ヤ緷璧朅PCs鍦ㄦ煇涓壒瀹氱殑綰跨▼涓婁笅鏂囦腑鎵ц涓涓緥紼嬶紝鑰屼笉闇瑕佺嚎紼嬬殑璁稿彲鍜屽共娑夈傚浜庣敤鎴峰簲鐢ㄧ▼搴忥紝鐢ㄦ埛妯″紡APCs鍙互鐢ㄦ潵鏈夋晥鍦板疄鐜頒竴浜涘洖璋冮氱煡鏈哄埗銆?/span>