CreateProcess逆向分析-3環使用者層逆向分析(一)

紅人發表於2022-03-11

0x00前言

windows11是如何建立程式並管理他們的呢?這篇分析CreateProcess在3環使用者層做了哪些事情。

作業系統:windows 11

工具:vs,IDA,windbg

0x01CreateProcess第一階段

CreateProcess用來建立一個新的程式和它的主執行緒,這個新程式執行指定的可執行檔案。下面看一個示例 建立一個程式 

#include <stdio.h>
#include <windows.h>


int main(int argc, char* argv[]) {
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    TCHAR szCommandLine[] = TEXT("powershell.exe");

    if (!CreateProcess(NULL,           // No module name (use command line)
        szCommandLine,  // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        0,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi)            // Pointer to PROCESS_INFORMATION structure
        )

    return 0;
}

現在我們就來分析CreateProcess 這個函式的內部實現

根據是你union 編碼還是ascii 呼叫CreateProcessW或者CreateProcessA  會呼叫kenrel32.dll 的createprocess

 

 引數複製 完了 接著會繼續呼叫KERNELBASE.dll  裡面的CreateProcessW  這裡面就是他的3環具體實現

0x02CreateProcess第二階段

CreateProcessW  可以看到複製完引數 呼叫了 CreateProcessInternalW 去實現建立程式程式碼

 

 真正的起點,應該是從CreateProcessInternal開始的

下面開始分析CreateProcessInternal函式

第一步就是 引數初始化和賦值

 

 首先是引數的是否為空判斷

lpCommandLine命令列字串 不能為空

lpStartupInfo傳遞給新程式的資訊 不能為空

lpProcessInformation新程式返回的資訊 不能為空

 

 獲取當前程式peb的地址

 

 

接著dwCreationFlags 控制優先順序等一系列標誌判斷

 

 

 其中有程式碼會判斷dwCreationFlags是否包含DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS標誌位,

有則呼叫DbgUiConnectToDbg建立除錯物件,並呼叫DbgUiGetThreadDebugObject獲取該除錯物件。

這也是一些偵錯程式開啟程式的原理

 

 

 

 接著建立新程式的環境塊RtlCreateEnvironmentEx

 

 

接著STARTUPINFO 資料處理

 

 檢測到STARTUPINFO  包含擴充套件資料 會呼叫函式BasepConvertWin32AttributeList

判斷lpCurrentDirectory是否為NULL,不為NULL則申請堆空間,呼叫GetFullPathNameW由字串獲取對應的全路徑

 

接著呼叫BaseFormatObjectAttributes通過引數ProcessAttributes格式化ProcessObjectAttributes物件,

通過引數ThreadAttributes格式化ThreadObjectAttributes物件,準備進入0環

 

 接著就是對傳入的lpCommandLine 引數做處理

 

 

最後到BasepCreateProcessParameters 根據FileName、bInheritHandles、Environment、StartupInfo這些資訊,

建立RTL_USER_PROCESS_PARAMETERS結構體作為0環引數。

 

 接著就是進入0環 NtCreateUserProcess  後面開始分析0環

 

相關文章