主頁 >  其他 > 檔案映射之地址隨機化原理(Win10 x64)-“快取”

檔案映射之地址隨機化原理(Win10 x64)-“快取”

2021-09-03 18:28:31 其他

正文

由于是檔案映射,所以必然少不了這幾位主角:FILE_OBJECT、SEGMENT、SECTION、CONTROL_AREA,外加用戶層訪問記憶體的入口VAD(BITMAP就不提了它只是VAD的一種“快取”方式),由于上述文章中沒有過多的提及關于檔案映射的這塊內容,所以我必須自己在nt!NtCreateUserProcess函式流程的海洋中尋找與這些物件相關的函式影子,

尋找相關流程思路:

研究系統:由于頭鐵,所以直接拿了一個Win10 x64 1909或20HX的版本研究(搭建虛擬機太麻煩),所以我就以此版本為研究物件,

尋找相關函式的思路有兩種

第一種,對特定物件中的特定欄位進行下斷點(這種需要知道相關物件的創建時機),然后進行堆疊回溯查看周圍的堆疊情況,

第二種,直接從頭開始從下找,人肉篩選其重點函式(參考之前一些前輩的文章),

我選擇的是第二種,但是也參考了一些技巧,首先我對nt!NtCreateUserProcess函式進行下斷點,斷下后,使用 uf /c /D 地址,查看此函式的的下一層的函式呼叫關系,然后進行人肉篩選一些不重要的函式,

uf /c /D 地址

結果如下圖:

篩選規則很簡單,就是對一些解參考、記憶體操作、引數檢查的函式一律PASS掉,因為我們的核心是檔案映射相關(這里參考《64位Windows創建64位行程逆向分析》系列),

經過篩選最終如下圖(此時還沒有動態除錯哦~):

開始除錯驗證流程和探究其細節:

提出問題和猜想

由于在《XX之NTDLL隨機化“逆向”(XP系統)》文章中我提到了,在Win7乃至Win10中,有3種情況:

將一個exe程式重復啟動,查看其基址

第一次啟動:

在桌面移動一下坐標再次啟動:

將一個exe移動一下再回到原來位置啟動,查看其基址,

第一次啟動:

此時,我將這個exe移動(剪切的方式)到某個盤符下,再移動回來,

很明顯,此時,對于同一個軟體這個基址就發生了變化,

通過修改exe一些位元組,進行重新運行

沒改之前運行:

修改一些位元組:

很明顯,此時,exe在一個位置,但是其內容發生了變化,也會導致其基址改變,

通過這三個實驗我想提出的觀點是:對于檔案加載是存在“快取”機制的,而問題是如何進行快取呢?這是下文開始探討的問題,

除錯相關流程分析

首先我給出各個物件的框架關系圖:

接下來按照所過濾的函式流程開始逐層分析,驗證上面圖片中物件的關系和尋找如何進行“快取”?

第一個分析的便是:IoCreateFileEx函式,該函式會生成一個FILE_OBJECT物件,通過分析可以得出IopCreateFile的第一個引數是file_object的Handle,所以只需跟蹤即可,

經過分析會得出以下結果:

此時已經產生FILE_OBEJCT、SEGMENT、CONTROL_AREA物件,此時圖形更新為:

由于此時還沒有創建EPROCESS和SECTION物件,所以用戶層是無法看到映射的內容的,所以重點就在于nt!MmCreateSpecialImageSection函式的身上,

我先簡單的劃分一下,可以看的更清楚一些,最終圖如下:

由于我是直接運行了一個exe程式,所以必然流程走的是MiCreateImageOrDataSection函式,

struct CREATE_SECTION_PACKET
{
    ULONG Flags;
    DWORD Unknown04;
    POBJECT_ATTRIBUTES InputObjectAttributes;
    ULONG AllocateAttributes;
    ULONG InputAllocationAttributes;
    UCHAR InputSectionSignatureLevel;
    BYTE Unknown19;
    WORD Unknown1A;
    ULONG InputSectionPageProtection;
    ULONG PageProtectionMask;
    DWORD Unknown24;
    HANDLE InputFileHandle;
    PFILE_OBJECT InputFileObject;
    PFILE_OBJECT FileObject;
    CONTROL_AREA* SectionControlArea;
    KPROCESSOR_MODE InputPreviousMode;
    BYTE Unknown49[67];
    DWORD Unknown8C;
    SECTION* SectionObject;
    PLARGE_INTEGER MaximumSize;
    PACCESS_TOKEN InputToken;
    DWORD InputSessionId;
    DWORD UnknownAC;
    MI_PARTITION* Partition;
    PIRP TopLevelIrp;
    BYTE UnknownC0;
    BYTE UnknownC1[3];
    DWORD UnknownC4;
};
 
NTSTATUS __fastcall MiReferenceControlArea(
    CREATE_SECTION_PACKET* CreateSectionPacket,
    CONTROL_AREA* ControlArea,
    CONTROL_AREA** ControlAreaOut)
{
    CONTROL_AREA* controlArea;
//...
    fileObject = CreateSectionPacket->FileObject;
    /*
        檢索Section Object指標, 如果 SEC_IMAGE 使用 ImageSectionObject 否則使用 DataSectionObject
    */
    controlArea = fileObject->SectionObjectPointer->DataSectionObject;
    if ((CreateSectionPacket->AllocateAttributes & SEC_IMAGE) != 0)
    {
        controlArea = fileObject->SectionObjectPointer->ImageSectionObject;
    }
//...
//
// 一些非常丑陋的鎖回圈和驗證,
//
//...
            *ControlAreaOut = controlArea;
            return STATUS_SUCCESS;
//...
}
 
 
NTSTATUS __fastcall MiCreateImageOrDataSection(
    CREATE_SECTION_PACKET* CreateSectionPacket)
{
    NTSTATUS status;
    PFILE_OBJECT fileObject;
    CONTROL_AREA controlArea;
    CONTROL_AREA* newControlArea;
//...
    fileObject = CreateSectionPacket->InputFileObject;
    if (fileObject)
    {
        //
        // 已經提供了檔案物件,請使用它,
        //
        goto HaveFileObject;
    }
    if ((allocationAttributes & SEC_LARGE_PAGES) == 0)
    {
        //
        // 從輸入檔案句柄獲取檔案物件,  
        //
        status = ObReferenceObjectByHandle(
                     CreateSectionPacket->InputFileHandle,
                     MmMakeFileAccess[CreateSectionPacket->PageProtectionMask & 7],
                     IoFileObjectType,
                     CreateSectionPacket->InputPreviousMode,
                     &fileObject,
                     NULL);
        if (!NT_SUCCESS(status))
        {
            goto Exit;
        }
        if (!fileObject->SectionObjectPointer)
        {
            //
            // 如果使用了檔案句柄并且沒有為它創建的節,這是一個失敗條件,
            //
            status = STATUS_INVALID_FILE_FOR_SECTION;
            goto Exit;
        }
 
:HaveFileObject
//...
        //
        // 在資料包和本地 CONTROL_AREA 中存盤一些資訊以維護狀態以供進一步呼叫,
        //
        ObfReferenceObject(fileObject);
        CreateSectionPacket->FileObject = fileObject;
        controlArea.u.LongFlags = 2;
        controlArea.FilePointer.Value = fileObject;
        newControlArea = NULL;
//...
        while (1)
        {
//...
            //
            // Go reference the correct control area.
            // 去參考正確的控制區域,
            //
            status = MiReferenceControlArea(CreateSectionPacket, 
                                            &controlArea, 
                                            &sectionControlArea);
            if (NT_SUCCESS(status))
            {
                break;
            }
            if ((status == 0xC000060B) || (status == 0xC0000476))
            {
                //
                // The control area is not charged or is invalid.
                // 這個控制區域已經無效
                //
                goto Exit;
            }
        }
        CreateSectionPacket->SectionControlArea = sectionControlArea;
        if ((sectionControlArea->u.LongFlags & 2) != 0)
        {
            //
            // 我們有section控制區域,其中將包含參考部分, 現在,去創建一個新的,
            //
            status = MiCreateNewSection(CreateSectionPacket,
                                        &newControlArea);
            if (NT_SUCCESS(status)))
            {
//...
                CreateSectionPacket->SectionControlArea = newControlArea;
                goto Exit;
//...
Exit:
//...
    return status;
}

偽代碼參考:https[:]//github.com/jxy-s/herpaderping/blob/main/res/DivingDeeper.md

首先會判斷是否存在FILE_OBEJCT物件,如果有的話直接跳轉,不需要再通過輸入的句柄獲取其FILE_OBJECT物件(沒有的話,需要走這一步),

其次默認設定一些標志已經欄位,但是最重要的是BeingCreated標志位,

后續會根據此標志位(BeingCreated = 1)來判斷是否創建新的CONTROL_AREA,此時也會修改掉_SEGMENT.BaseAddress欄位,所以這里就不使用快取,

此時圖更新為:

實驗驗證:

先運行一個exe一次,然后記錄其基址:

然后在nt!NtCreateUserProcess中下斷,再次啟動該程式,跟蹤上述流程,并尋找_Segment.BaseAddress

不難發現,第二次啟動程式使用了第一次啟動后快取的_SEGMENT,所以基址保持不變,并且查看BeingCreated標志,也會發現此時該標志為0,

接下來再次啟動該程式,并將其BeingCreated標志置為0,查看其基址又是如何的情景呢?(此時我是將提出的問題1,2合并來進行測驗),將exe剪切移動到一個位置后,再移動回來,查看其BeingCreated標志,

為了更加了解_SEGMENT.BaseAddress如何來的,所以繼續順著流程往下跟蹤,(注解:ImageBase來源于_SEGMENT.BaseAddress,所以我一般會混合稱呼,

對于新創建的SEGMENT流程來說:

nt!MiCreateNewSection->nt!MiRelocateImage->nt!MiSelectImageBase最終生成_SEGMENT.BaseAddress

其中生成的演算法為:

充滿好奇心的同學,就如我一樣,肯定會心中產生一個疑問,那么便是為什么,這里會有兩種產生隨機地址的流程呢?那么讓我們繼續順藤摸瓜,向上查找

接著,就會尋找到如下圖的關系:

在nt! MiSelectImageBase會判斷_CONTROL_AREA.u2.e2.ImageBaseOkToReuse欄位是否為1,說明當這個欄位為1的時候,那么也會進行重定位,這個情況是發生在_CONTROL_AREA“快取的情況”下(為什么是這個情況呢?因為另一種情況會重新創建Segment),即發生下:

這就得出了一個結論,如果ImageBaseOkToReuse標志在置位的情況下,即時存在CONTROL_AREA的“快取”,那么也會進行重新計算BaseAddress,所以可以看到在這個分支中會出現一個獨特的函式,即:nt!MiSwitchBaseAddress

當nt!MiSelectImageBase回傳后,會回傳到nt!MiRelocateImageAgain函式中,

nt!MiRelocateImageAgain函式會判斷回傳的BaseAddress值與原來的_SEGMENT.BaseAddress中的值是否一致,如果不一致的話,那么就會呼叫nt!MiSwitchBaseAddress 函式更新_SEGMENT,

但是這里還有一個小細節,就是它會判斷ImageActive標志位,這個位顧名思義(我猜的),代表的是當前行程是否存活,為了突出重點,所以我標出了流程中關鍵的部分,具體圖如下:

細分析如下:

在nt!MiRelocateImageAgain函式中,首先判斷 _control_area .u2.e2.ImageActive,是否為1(即)當前行程是否存活,如果不是退出狀態,則會呼叫nt!MiSelectImageBase函式來獲取基址,

如果獲取到新的BaseAddress后,則將其和老的進行比較,不相同,則呼叫 nt!MiSwitchBaseAddress來更新_SEGMENT

對于其他的流程,后續總結的時候簡要說明一下,nt!PspAllocateProcess函式流程可以參考《64位Windows創建64位行程逆向分析》,

總結:

對于復用CONTROL_AREA“快取”的情況圖:

對于重新創建SEGMENT的圖:

簡單說一句,如果想讓記憶體在用戶層可見,都需要呼叫nt!MiMapViewOfImageSection函式,這個函式主要作用就是創建_SECTION物件,并將_SEGMENT.BaseAddress函式映射到用戶層可見部分,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/297088.html

標籤:其他

上一篇:每日分享-sql注入簡單檢測小工具(僅供參考學習)

下一篇:程式員干個五六年能存100萬,焦慮啥?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more