日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

3.APC的挂入过程

發(fā)布時間:2025/3/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 3.APC的挂入过程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

無論是正常狀態(tài)還是掛靠狀態(tài),都有兩個APC隊列,一個內(nèi)核隊列,一個用戶隊列。

每當(dāng)要掛入一個APC函數(shù)時,不管是內(nèi)核APC還是用戶APC,內(nèi)核都要準(zhǔn)備一個KAPC的數(shù)據(jù)結(jié)構(gòu),并且將這個KAPC結(jié)構(gòu)掛到相應(yīng)的APC隊列中。

kd> dt _kapc nt!_KAPC+0x000 Type //類型APC類型為0x12+0x002 Size //本結(jié)構(gòu)體的大小0x30+0x004 Spare0 //未使用+0x008 Thread //目標(biāo)線程+0x00c ApcListEntry //APC隊列掛的位置+0x014 KernelRoutine //指向一個函數(shù)(調(diào)用ExFreePoolWithTag釋放APC)+0x018 RundownRoutine //未使用+0x01c NormalRoutine //用戶APC總?cè)肟诨蛘哒嬲膬?nèi)核apc函數(shù)+0x020 NormalContext //內(nèi)核APC: NULL用戶APC:真正的APC函數(shù) +0x024 SystemArgument1 //APC函數(shù)的參數(shù)+0x028 SystemArgument2 //APC函數(shù)的參數(shù)+0x02c ApcStateIndex //掛哪個隊列,有四個值: 0 1 2 3+0x02d ApcMode //內(nèi)核APC用戶APC+0x02e Inserted //表示本apc是否已掛入隊列掛入前: 0掛入后1

+0x000 Type
APC的類型為0x12,windows下任何一種內(nèi)核對象都有一個類型編號。

+0x014 KernelRoutine
APC執(zhí)行完畢后,釋放本結(jié)構(gòu)內(nèi)存

+0x01c NormalRoutine
如果你當(dāng)前的APC是內(nèi)核APC,通過它就能找到內(nèi)核APC函數(shù)。
如果你當(dāng)前的APC是用戶APC,通過它找到的只是用戶APC的總?cè)肟诓⒉皇怯脩鬉PC函數(shù)。

+0x020 NormalContext
如果是內(nèi)核APC這個值為空,如果是用戶APC這個值執(zhí)行的就是用戶APC函數(shù)

+0x02c ApcStateIndex

  • =0原始環(huán)境
  • =1掛靠環(huán)境
  • =2當(dāng)前環(huán)境
  • =3插入APC時的當(dāng)前環(huán)境

正常情況下:

KTHREAD.ApcStatePointer[0] 指向 KTHREAD.ApcState KTHREAD.ApcStatePointer[1] 指向 KTHREAD.SavedApcState

掛靠情況下:

KTHREAD.ApcStatePointer[0] 指向 KTHREAD.SavedApcState KTHREAD.ApcStatePointer[1] 指向 KTHREAD.ApcState

·

0時無論是在正常還是掛靠的情況下都能正常寫到原來的那個列表中[0]

1時正常情況下寫的就是SavedApcState,掛靠就是ApcState [1]

2 初始化的時候,當(dāng)前進(jìn)程的ApcState

3 插入的時候,當(dāng)前進(jìn)程的ApcState

在你初始化APC時可能時正常情況也可能是掛靠情況時用3,在你真正插入是它會再做一次判斷。



APC掛入流程

我在3環(huán)插入APC調(diào)用QueueUserAPC,但是在0環(huán)有很多內(nèi)核函數(shù)有很多函數(shù)也是可以插入APC的,它可能直接調(diào)用KelnitializeApc或者KilsertQueueApc來分配APC并且掛入APC。

KeInitializeApc函數(shù)說明

void KeInitializeApc (IN PKAPC Apc,//KAPC指針 (分配好內(nèi)存的還沒初始化)IN PKTHREAD Thread,//目標(biāo)線程IN KAPC_ENVIRONMENT TargetEnvironment,//0 1 2 3四種狀態(tài)IN PKKERNEL_ROUTINE KernelRoutine//銷毀KAPC的函數(shù)地址IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL//未使用IN PKNORMAL_ROUTINE NormalRoutine,//用戶APC總?cè)肟诨蛘邇?nèi)核apc函數(shù)IN KPROCESSOR_MODE Mode,//要插入用戶apc隊列還是內(nèi)核apc隊列IN PVOID Context//內(nèi)核APC: NULL 用戶APC:真正的APC函數(shù) ) 1. 2.Thread傳進(jìn)來會掛到 _KAPC.0x8 Thread 3.TargetEnvironment 傳進(jìn)來會掛到_KAPC.0x2c ApcStateIndex 4.KernelRoutine 傳進(jìn)來會掛到_KAPC.0x14 KernelPoutine 5. 6.NormalRoutine 傳進(jìn)來會掛到_KAPC.0x1c NormalRoutine 7.Mode 傳進(jìn)來會掛到_KAPC.0x2d ApcMode 8.Context 傳進(jìn)來會掛到_KAPC.0x20 NormalRoutine

KeInsertQueueApc函數(shù)說明

BOOLEAN NTAPI KeInsertQueueApc(IN PKAPC Apc,IN PVOID SystemArgument1,IN PVOID SystemArgument2,IN KPRIORITY PriorityBoost);
  • 根據(jù)KAPC結(jié)構(gòu)中的ApcStateIndex找到對應(yīng)的APC隊列
  • 再根據(jù)KAPC結(jié)構(gòu)中的ApcMode確定是用戶隊列還是內(nèi)核隊列
  • 將KAPC掛到對應(yīng)的隊列中(掛到KAPC的ApcListEntry處)
  • 再根據(jù)KAPC結(jié)構(gòu)中的Inserted置1,標(biāo)識當(dāng)前的KAPC為已插入狀態(tài)
  • 修改KAPC_STATE結(jié)構(gòu)中的KernelApcPending/UserApcPending
  • typedef struct _KAPC_STATE {LIST_ENTRY ApcListHead[MaximumMode];//0:內(nèi)核apc鏈表。1:用戶apc鏈表struct _KPROCESS *Process;//APC所關(guān)聯(lián)的進(jìn)程BOOLEAN KernelApcInProgress;//該線程正在處理一個普通的內(nèi)核apc對象BOOLEAN KernelApcPending;//有內(nèi)核apc對象正在等待交付BOOLEAN UserApcPending;//有用戶apc對象正在等待交付 } KAPC_STATE, *PKAPC_STATE, *PRKAPC_STATE;

    UserApcPending = 1時,用戶apc才能被執(zhí)行。

    Alertable屬性說明(是否運行被APC吵醒):

    kd> dt KTHREAD ntdil! KTHREAD ... +0x164 Alertable: UChar ...DWORD SleepEx (DWORD dwMilliseconds, //time-out interval BOOL bAlertable // early completion option );DWORD WaitForSingleObjectEx (HANDLE hHandle,//handle to objectDWORD dwMilliseconds, // time-out interval BOOL bAlertable //alertable option );上面的兩個api的最后一個還是就可以修改KTHREAD->Alertable 的值。 = 1 當(dāng)前的線程是可以被APC喚醒的 = 0 不可被APC喚醒

    如果為用戶模式

    3個跳轉(zhuǎn)都沒有實現(xiàn)的話

    Alertable總結(jié)

  • Alertable = 0當(dāng)前插入的APC函數(shù)未必有機會執(zhí)行: UserApcPending = 0
  • Alertable-1UserApcPending =1將目標(biāo)線程喚醒(從等待鏈表中摘出來,并掛到調(diào)度鏈表)
  • 總結(jié)

    以上是生活随笔為你收集整理的3.APC的挂入过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。