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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【安全报告】揭秘创建进程时ebx为什么指向peb的答案

發布時間:2025/3/21 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【安全报告】揭秘创建进程时ebx为什么指向peb的答案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、背景

為了確保被替換后的進程能順利執行不崩潰,需要獲取原進程各種上下文,并修改被替換后的新進程上下文,其中在原進程被掛起還沒開始執行的時候,需要將eax指向新oep,而ebx指向新peb,而為什么這樣設置的原因卻很少有人提及。為此,在經過查閱了一定的資料與簡單的分析后,我們可以找到答案。

二、具體分析

先拋出結論,這里的eax與ebx屬于線程上下文信息,在一個PE文件開始被運行的過程中,主線程上下文初始化過程是在進程已經創建完成,而主線程還沒創建的階段發生的,下面是具體更詳細的分析:

首先我們需要對進程的創建有一個大概的認識,在ring3下創建進程API無非是CreateProcessA/W,但是無論調用哪一個,最終都會將相關參數轉化為Unicode字符串,并最終調用CreateProcessInternalW,因此以下將主要分析CreateProcessInternalW,而在xp和win7下,它具體實現又有一些不一樣的地方。

2.1 XP下執行流程
在xp下,它大概分為四個部分,分別是ring3下創建進程,ring0下創建進程,ring3下創建線程,ring0下創建線程,以NtCreateProcessEx為分界線,NtCreateProcessEx之前為ring3下創建進程主要流程。

2.1.1 Ring3下創建進程

  • 判斷處理dwCreationFlag各種標志位,包括是否包含不合法標記組合,判斷優先級。
  • 判斷lpEnvironment是否為空,不為空則調用RtlAnsiStringToUnicodeString將其轉為UniCode字符串。
  • 判斷lpApplicationName、lpCommandLine是否為空。

    如果lpApplicationName不為空直接調用RtlDosPathNameToNtPathName_U函數將DOS路徑(C:\WINDOWS\XXX)轉換為NT路徑(\Device\HarddiskVolume1\WINDOWS\XXX),為空則會解析lpCommandLine,主要按照’”’引號,’ ’空格,’\t’制表符作為分隔符進行解析并獲取相應的PE文件,然后將DOS路徑轉換為NT路徑。



  • 4. 調用NtOpenFile得到文件句柄,調用了NtCreateSectiond函數得到內存區對象句柄。

  • 調用BasepIsProcessAllowed函數, 該函數用來判斷應用程序名是否在授權文件列表中。

  • 之后會經過一大段的函數進行各種校驗,再得到內存區對象句柄后調用NtQuerySection函數,返回后得到節的基本信息(節基地址,大小,屬性),并判斷創建標志中是否包含DEBUG_PROCESS或者DEBUG_ONLY_THIS_PROCESS,如果不包含該標志,則判斷PEB->ReadImageFileExecOptions域是否為0,如果包含DEBUG_PROCESS或者DEBUG_ONLY_THIS_PROCESS,或者不包含該標志但ReadImageFileExecOptions域不為0, 調用LdrQueryImageFileExecutionOptions函數查詢該信息。

  • 之后會經過一大段的函數進行各種校驗,再得到內存區對象句柄后調用NtQuerySection函數,返回后得到節的基本信息(節基地址,大小,屬性),并判斷創建標志中是否包含DEBUG_PROCESS或者DEBUG_ONLY_THIS_PROCESS,如果不包含該標志,則判斷PEB->ReadImageFileExecOptions域是否為0,如果包含DEBUG_PROCESS或者DEBUG_ONLY_THIS_PROCESS,或者不包含該標志但ReadImageFileExecOptions域不為0, 調用LdrQueryImageFileExecutionOptions函數查詢該信息。

  • 檢查鏡像文件的部分信息的有效性,并調用函數BasepIsImageVersionOk判斷鏡像文件版本是否合法。

  • 加載advapi32.dll并獲得CreateProcessAsUserSecure函數的地址。

  • 調用BaseFormatObjectAttributes將安全屬性結構格式為NT對象屬性結構(得到了對象屬性),接著調用了_DbgUiConnectToDbg在實現通過調用NtCreateDebugObject函數來創建調試對象,調用DbgUiGetThreadDebugObject來獲得調試對象(作為參數傳遞到0環)。

  • 最后調用NtCreateProcessEx函數。

    2.1.2 Ring0下創建進程
    NtCreateProcessEx內為ring0下創建進程主要流程。

  • 判斷父進程是否存在,若不存在則退出,否則,調用PspCreateProcess。

  • 在PspCreateProcess中,保存當前線程運行的前一個模式,通過KTHREAD->PreviousMode可以得到前一個模式,并判斷創建標志是否包含除DEBUG_PROCESS, DEBUG_ONLY_THIS_PROCESS,CREATE_SUSPENDED的標志之外其它標志, 如果包含其他的標志,則報錯退出。

  • 通過參數ParentProcess調用ObReferenceObjectByHandle函數得到父進程對象的指針。

  • 判斷參數 JobMemberLevel是否為0, 如果不為0,接著判斷父進程的EPROCESS->Job是否為0,如果JobMemberLevel不為為0且EPROCESS->Job為0,則返回無效參數錯誤后退出該函數;否則的話,將父進程對象中的屬性保存到局部變量中。

  • 調用ObCreateObject函數創建新進程對象并將對象內容初始化為0,然后從父進程繼承配額信息(PspInheritQuot)和設備位圖信息(ObInheritDeviceMap),將父進程對象中的部分域給新進程。

  • 判斷參數SectionHandle是否為0,若不為0,調用ObReferenceObjectByHandle函數得到區對象指針,然后將區對象指針賦值給新進程EPROCESS的相應域。

  • 接著就判斷參數DebugPort是否為0,若不為0,調用ObReferenceObjectByHandle函數通過調試對象句柄得到調試對象指針,否則調用DbgkCopyProcessDebugPort函數從父進程拷貝DebugPort給新進程。

  • 判斷參數ExceptionPort是否為0,若不為0,調用ObReferenceObjectByHandle函數通過異常端口對象句柄得到異常端口對象指針。

  • 接著調用PspInitializeProcessSecurity函數來設置新進程的安全屬性, 主要是設置新進程的安全令牌對象。該函數會調用SeSubProcessToken函數來設置新進程對象的令牌對象。

  • 接著調用MmCreateProcessAddressSpace為新進程創建地址空間,并構建頁目錄表、頁表及物理頁的關系。

  • 調用KeInitializeProcess函數初始化新進程對象中內核對象、優先級、親和性、頁目錄表物理地址幀號。

  • 調用ObInitProcess函數來初始化新進程對象的表。

  • 調用MmInitializeProcessAddressSpace函數初始化進程地址空間,該函數的實現中調用了KiAttachProcess函數來實現進程的切換(將當前線程掛靠到新進程中),以及初始化EPROCESS中的部分域和PFN、工作集列表等。

  • 調用PspMapSystemDll函數映射新進程對象的系統DLL(即NTDLL,映射第一個DLL),該函數會調用MmMapViewOfSection映射節區,而MmMapViewOfSection會調用MiMapViewOfImageSection函數將DLL作為鏡像映射。

  • 接著調用MmGetSessionId函數獲得指定進程的會話ID,然后調用SeSetSessionIdToken函數設置令牌的會話ID,之后再調用ExCreateHandle函數在PspCidTable中添加一項(PID)。

  • 調用MmCreatePeb為新進程創建PEB,該函數首先通過調用KeAttachProcess函數將當前線程切換到新進程對象,然后通過MmMapViewOfSection函數將NLS節區映射到新進程的地址空間中,隨后調用MiCreatePebOrTeb創建PEB/TEB。

    在MiCreatePebOrTeb函數中,該函數首先會通過ExAllocatePoolWithTag來申請0x34大小的空間,接著通過MiFindEmptyAddressRangeDownTree函數在VAD樹中查找一塊未被使用的地址空間范圍,并返回該范圍的起始地址,最后通過MiInsertVad函數將申請的地址空間插入到VAD樹中。



  • 在創建PEB結構后,初始化PEB中部分域的值(鏡像基地址,操作系統編譯號等域),最后調用KeDetachProcess函數使線程回到原來的線程中。截止此步驟,PEB創建完成。


    同時觀察也可以發現,這里也解析了包括Nt頭、擴展頭、擴展頭魔術字效驗等關鍵PE結構信息,聯想到之前分析流程也處理了一部分PE結構,可以猜測早期的PE文件結構逆向可能也是通過逆向進程創建過程,即逆向CreateProcess API來實現的。

  • 最后將新進程對象EPROCESS.ActiveProcessLinks更新為全局的活動進程鏈表(PsActiveProcessHead), 判斷父進程是否為系統進程,調用SeCreateAccessStateEx設置訪問狀態,調用ObInsertObject函數將進程對象加入到進程對象的句柄表中,并通過KeQuerySystemTime(獲取當前系統時間)結束PspCreateProcess的調用,完成ring0下進程的創建。

    接下來我們回到CreateProcessInternalW,以NtCreateThread為分界線,NtCreateProcessEx之后到NtCreateThread之前為ring3下創建線程流程,而NtCreateThread內則是ring0下創建線程流程,經過分析發現,我們所需要尋找的線程上下文設置其實就在ring3下創建線程流程內。
  • 總結

    以上是生活随笔為你收集整理的【安全报告】揭秘创建进程时ebx为什么指向peb的答案的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。