<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    Windows API調用詳解

    VSole2022-04-06 16:07:31

    綜述:

    Windows內核中的執行體層暴露了大量執行體中的對象給Windows用戶層的API來操作,那么用戶層的API是怎么調用這些功能的呢,比如說創建一個文件,文件是一個內核對象必須得有內核層來處理,所以肯定有一個從用戶層到內核層然后內核層解決再返回到用戶層的一個流程。

    API調用流程:

    這里以CreateFile舉例:(大致流程如下)

    采用OllyDbg跟蹤觀察:

    #include#includeusing namespace std;int main(){    cout << "Begin" << endl;    auto hFile =CreateFileW(        L"temp.txt",        GENERIC_READ,        FILE_SHARE_READ,        NULL,        OPEN_ALWAYS,        FILE_ATTRIBUTE_NORMAL,        NULL    );    return NULL;}
    

    可以看到在調用CreateFile時,是直接采用的Kernel32中的CreateFileW函數:

    然后跟進Kernel32.CreateFileW函數中:

    會跳轉到KernelBase中的CreateFileW函數中,繼續步入查看:

    一直往下翻才能看到NtCreateFile函數,前面的我猜是給創建新文件所需進行初始化的一些代碼。

    正所謂前人栽樹后人乘涼,書上的大牛寫的是調用ntdll中的NtCreateFile我們就不要懷疑了,然后步入Ntdll.NtCreateFile查看:

    這里的call esi就是調用NtCreateFile的地方,然后繼續步入查看:

    就成了這樣子,這個我也不知道什么意思,就繼續call dword ptr ds:[edx]查看:

    最后的最后是由三個匯編指令為結尾:

    mov edx,espsysenterretn
    

    retn是返回指令,表示已經執行完成。

    sysenter在od中無法看到,不管是步入還是步過只會直接執行完跳過。

    所以目前而言的API調用過程是這樣的:

    現在不理解的就是NtCreateFile函數內部的代碼邏輯:

    mov eax,xxmov edx,xxxcall dword ptr ds:[edx]retn xxx... mov edx,espsysenter
    

    這幾行匯編代碼是什么意思。

    詳解NtCreateFile:

    首先是NtCreateFile中的第一層匯編代碼:

    mov eax,xxmov edx,xxcall dword ptr ds:[edx]retn xxx
    

    這附近的匯編代碼都是這樣的樣式:

    mov eax,xx

    這里的eax叫做系統服務號,它代表進入0環后,調用那一個API,就類似于數組和下標的關系,根據下標一對一對應內核中的某一個API,然后內核調用內核的對應的API。

    也就是說由eax的值來決定內核API的調用。

    mov edx,xxx

    所有通過ntdll調用的函數,給edx所傳遞的值都是一樣的,這里都是0x7FFE0300。

    該值是_KUSER_SHARED_DATA結構體的一個成員,該結構體所在的內存空間是一個提供給User層和Kernel層共享的一個內存空間,該空間主要用來在User和Kernel之間快速傳遞信息。

    該結構體所在的內存空間是固定的:User層下:0x7FFE0000,Kernel層下:0xFFDF0000。

    //0x5f0 bytes (sizeof)struct _KUSER_SHARED_DATA{    ULONG TickCountLowDeprecated;                                           //0x0    ULONG TickCountMultiplier;                                              //0x4    volatile struct _KSYSTEM_TIME InterruptTime;                            //0x8    volatile struct _KSYSTEM_TIME SystemTime;                               //0x14    volatile struct _KSYSTEM_TIME TimeZoneBias;                             //0x20    USHORT ImageNumberLow;                                                  //0x2c    USHORT ImageNumberHigh;                                                 //0x2e    WCHAR NtSystemRoot[260];                                                //0x30    ULONG MaxStackTraceDepth;                                               //0x238    ULONG CryptoExponent;                                                   //0x23c    ULONG TimeZoneId;                                                       //0x240    ULONG LargePageMinimum;                                                 //0x244    ULONG Reserved2[7];                                                     //0x248    enum _NT_PRODUCT_TYPE NtProductType;                                    //0x264    UCHAR ProductTypeIsValid;                                               //0x268    ULONG NtMajorVersion;                                                   //0x26c    ULONG NtMinorVersion;                                                   //0x270    UCHAR ProcessorFeatures[64];                                            //0x274    ULONG Reserved1;                                                        //0x2b4    ULONG Reserved3;                                                        //0x2b8    volatile ULONG TimeSlip;                                                //0x2bc    enum _ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;            //0x2c0    ULONG AltArchitecturePad[1];                                            //0x2c4    union _LARGE_INTEGER SystemExpirationDate;                              //0x2c8    ULONG SuiteMask;                                                        //0x2d0    UCHAR KdDebuggerEnabled;                                                //0x2d4    UCHAR NXSupportPolicy;                                                  //0x2d5    volatile ULONG ActiveConsoleId;                                         //0x2d8    volatile ULONG DismountCount;                                           //0x2dc    ULONG ComPlusPackage;                                                   //0x2e0    ULONG LastSystemRITEventTickCount;                                      //0x2e4    ULONG NumberOfPhysicalPages;                                            //0x2e8    UCHAR SafeBootMode;                                                     //0x2ec    union    {        UCHAR TscQpcData;                                                   //0x2ed        struct        {            UCHAR TscQpcEnabled:1;                                          //0x2ed            UCHAR TscQpcSpareFlag:1;                                        //0x2ed            UCHAR TscQpcShift:6;                                            //0x2ed        };    };    UCHAR TscQpcPad[2];                                                     //0x2ee    union    {        ULONG SharedDataFlags;                                              //0x2f0        struct        {            ULONG DbgErrorPortPresent:1;                                    //0x2f0            ULONG DbgElevationEnabled:1;                                    //0x2f0            ULONG DbgVirtEnabled:1;                                         //0x2f0            ULONG DbgInstallerDetectEnabled:1;                              //0x2f0            ULONG DbgSystemDllRelocated:1;                                  //0x2f0            ULONG DbgDynProcessorEnabled:1;                                 //0x2f0            ULONG DbgSEHValidationEnabled:1;                                //0x2f0            ULONG SpareBits:25;                                             //0x2f0        };    };    ULONG DataFlagsPad[1];                                                  //0x2f4    ULONGLONG TestRetInstruction;                                           //0x2f8    ULONG SystemCall;                                                       //0x300    ULONG SystemCallReturn;                                                 //0x304    ULONGLONG SystemCallPad[3];                                             //0x308    union    {        volatile struct _KSYSTEM_TIME TickCount;                            //0x320        volatile ULONGLONG TickCountQuad;                                   //0x320        ULONG ReservedTickCountOverlay[3];                                  //0x320    };    ULONG TickCountPad[1];                                                  //0x32c    ULONG Cookie;                                                           //0x330    ULONG CookiePad[1];                                                     //0x334    LONGLONG ConsoleSessionForegroundProcessId;                             //0x338    ULONG Wow64SharedInformation[16];                                       //0x340    USHORT UserModeGlobalLogger[16];                                        //0x380    ULONG ImageFileExecutionOptions;                                        //0x3a0    ULONG LangGenerationCount;                                              //0x3a4    ULONGLONG Reserved5;                                                    //0x3a8    volatile ULONGLONG InterruptTimeBias;                                   //0x3b0    volatile ULONGLONG TscQpcBias;                                          //0x3b8    volatile ULONG ActiveProcessorCount;                                    //0x3c0    volatile USHORT ActiveGroupCount;                                       //0x3c4    USHORT Reserved4;                                                       //0x3c6    volatile ULONG AitSamplingValue;                                        //0x3c8    volatile ULONG AppCompatFlag;                                           //0x3cc    ULONGLONG SystemDllNativeRelocation;                                    //0x3d0    ULONG SystemDllWowRelocation;                                           //0x3d8    ULONG XStatePad[1];                                                     //0x3dc    struct _XSTATE_CONFIGURATION XState;                                    //0x3e0};
    

    edx是該結構體中的SystemCall成員,該結構體成員指定了從User層到Kernel層的調用方式,這里我們可以通過WinDbg來查看一下:

    kd> dt nt!_KUSER_SHARED_DATA 0xFFDF0000   +0x000 TickCountLowDeprecated : 0   +0x004 TickCountMultiplier : 0xf99a027   +0x008 InterruptTime    : _KSYSTEM_TIME   +0x014 SystemTime       : _KSYSTEM_TIME   +0x020 TimeZoneBias     : _KSYSTEM_TIME   +0x02c ImageNumberLow   : 0x14c   +0x02e ImageNumberHigh  : 0x14c   +0x030 NtSystemRoot     : [260]  "C:\Windows"   +0x238 MaxStackTraceDepth : 0   +0x23c CryptoExponent   : 0   +0x240 TimeZoneId       : 0   +0x244 LargePageMinimum : 0x200000   +0x248 Reserved2        : [7] 0   +0x264 NtProductType    : 1 ( NtProductWinNt )   +0x268 ProductTypeIsValid : 0x1 ''   +0x26c NtMajorVersion   : 6   +0x270 NtMinorVersion   : 1   +0x274 ProcessorFeatures : [64]  ""   +0x2b4 Reserved1        : 0x7ffeffff   +0x2b8 Reserved3        : 0x80000000   +0x2bc TimeSlip         : 0   +0x2c0 AlternativeArchitecture : 0 ( StandardDesign )   +0x2c4 AltArchitecturePad : [1] 0   +0x2c8 SystemExpirationDate : _LARGE_INTEGER 0x0   +0x2d0 SuiteMask        : 0x110   +0x2d4 KdDebuggerEnabled : 0x3 ''   +0x2d5 NXSupportPolicy  : 0x2 ''   +0x2d8 ActiveConsoleId  : 1   +0x2dc DismountCount    : 0   +0x2e0 ComPlusPackage   : 0xffffffff   +0x2e4 LastSystemRITEventTickCount : 0   +0x2e8 NumberOfPhysicalPages : 0x3ff7e   +0x2ec SafeBootMode     : 0 ''   +0x2ed TscQpcData       : 0 ''   +0x2ed TscQpcEnabled    : 0y0   +0x2ed TscQpcSpareFlag  : 0y0   +0x2ed TscQpcShift      : 0y000000 (0)   +0x2ee TscQpcPad        : [2]  ""   +0x2f0 SharedDataFlags  : 0xe   +0x2f0 DbgErrorPortPresent : 0y0   +0x2f0 DbgElevationEnabled : 0y1   +0x2f0 DbgVirtEnabled   : 0y1   +0x2f0 DbgInstallerDetectEnabled : 0y1   +0x2f0 DbgSystemDllRelocated : 0y0   +0x2f0 DbgDynProcessorEnabled : 0y0   +0x2f0 DbgSEHValidationEnabled : 0y0   +0x2f0 SpareBits        : 0y0000000000000000000000000 (0)   +0x2f4 DataFlagsPad     : [1] 0   +0x2f8 TestRetInstruction : 0xc3   +0x300 SystemCall       : 0x76f46c00   +0x304 SystemCallReturn : 0x76f46c04   +0x308 SystemCallPad    : [3] 0   +0x320 TickCount        : _KSYSTEM_TIME   +0x320 TickCountQuad    : 0x9806   +0x320 ReservedTickCountOverlay : [3] 0x9806   +0x32c TickCountPad     : [1] 0   +0x330 Cookie           : 0xccc8c182   +0x334 CookiePad        : [1] 0   +0x338 ConsoleSessionForegroundProcessId : 0n1504   +0x340 DEPRECATED_Wow64SharedInformation : [16] 0   +0x380 UserModeGlobalLogger : [16] 0   +0x3a0 ImageFileExecutionOptions : 0   +0x3a4 LangGenerationCount : 1   +0x3a8 Reserved5        : 0   +0x3b0 InterruptTimeBias : 0   +0x3b8 TscQpcBias       : 0   +0x3c0 ActiveProcessorCount : 1   +0x3c4 ActiveGroupCount : 1   +0x3c6 Reserved4        : 0   +0x3c8 AitSamplingValue : 0   +0x3cc AppCompatFlag    : 1   +0x3d0 DEPRECATED_SystemDllNativeRelocation : 0   +0x3d8 DEPRECATED_SystemDllWowRelocation : 0   +0x3dc XStatePad        : [1] 0   +0x3e0 XState           : _XSTATE_CONFIGURATION
    +0x300 SystemCall       : 0x76f46c00,該字段存放著函數的調用地址,結合前面的內容可以看到確實是該地址:
    

    //然后反匯編查看一下該函數的內容:kd> u 0x76f46c00ntdll!KiFastSystemCall:76f46c00 ??              ???               ^ Memory access error in 'u 0x76f46c00'  這個函數的名字叫做KiFastSystemCall 那么這一段匯編代碼:mov eax,xxmov edx,xxcall dword ptr ds:[edx]retn xxx 就可以抽象成一個函數:KiFastSystemCall()//當然里面肯定有參數
    

    那么圖就可以變成這樣子:

    然后重點就來到了剩下的兩個。

    mov edx,esp:

    這個其實就是函數傳參,參數在棧里面,然后把棧的首地址交給edx。

    sysenter

    sysenter才是整個調用的關鍵。

    整個調用方式最關鍵的就是通過sysenter從User層到達Kernel層,可以說前面的都是在給這一步做鋪墊。

    sysenter叫做快速系統調用,叫快速是因為之前的系統調用不快,在Pentium II(奔騰2代CPU)之后才有的sysenter,在其之前是采用的 KiIntSystemCall函數來處理的。

    在IDA下查看:該函數:

    ; Exported entry 109. KiIntSystemCall   ; _DWORD __stdcall KiIntSystemCall()public _KiIntSystemCall@0_KiIntSystemCall@0 proc near arg_4= byte ptr  8 lea     edx, [esp+arg_4]int     2Eh             ; DOS 2+ internal - EXECUTE COMMAND                        ; DS:SI -> counted CR-terminated command stringretn_KiIntSystemCall@0 endp
    

    這里的int 2Eh,采用的就是一種CPU機制,叫做中斷門:

    Windows內核中的CPU架構-6-中斷門(32-Bit Interrupt Gate) - Sna1lGo - 博客園 (cnblogs.com)(https://www.cnblogs.com/Sna1lGo/p/15515746.html

    這樣調用會用到內存,比較麻煩,所以就引入了快速系統調用:

    sysenter/sysexit 兩個函數和三個MSR寄存器。

    MSR寄存器比較類似內存,直接根據序號來命名,沒有像通用寄存器EAX,EBX一樣,單獨命名。

    和sysenter連用的是MSR174和,MSR175,MSR176三個寄存器。

    sysenter內部邏輯為:

    //1:設置寄存器CS = IA32_SYSENTER_CSSS = IA32_SYSENTER_CS+8eip = IA32_SYSENTER_EIPesp = IA32_SYSENTER_ESP  //2:切換特權級切換到0環特權級,(其實設置了寄存器就是切換了) //3:切換CPU模式清楚eflags寄存器中的虛擬8086模式(VM標志) //4:執行執行系統例程調用
    
    函數調用volatile
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    假如想在x86平臺運行arm程序,稱arm為source ISA, 而x86為target ISA, 在虛擬化的角度來說arm就是Guest, x86為Host。這種問題被稱為Code-Discovery Problem。每個體系結構對應的helper函數在target/xxx/helper.h頭文件中定義。
    逆向角度看C++部分特性
    CVE-2021-31956是由Windows Ntfs組件系統存在整形溢出所導致,該漏洞可導致本地權限提升。
    概述在windows系統上,涉及到內核對象的功能函數,都需要從應用層權限轉換到內核層權限,然后再執行想要的內核函數,最終將函數結果返回給應用層。本文就是用OpenProcess函數來觀察函數從應用層到內核層的整體調用流程。OpenProcess函數,根據指定的進程ID,返回進程句柄。NTSTATUS Status; //保存函數執行狀態。OBJECT_ATTRIBUTES Obja; //待打開對象的對象屬性。HANDLE Handle; //存儲打開的句柄。CLIENT_ID ClientId; //進程、線程ID. dwDesiredAccess, //預打開進程并獲取對應的權限。ObjectNamePresent = ARGUMENT_PRESENT ; //判斷對象名稱是否為空
    關于堆棧ShellCode操作:基礎理論002-利用fs寄存器尋找當前程序dll的入口:從動態運行的程序中定位所需dll003-尋找大兵LoadLibraryA:從定位到的dll中尋找所需函數地址004-被截斷的shellCode:加解密,解決shellCode的零字截斷問題
    反射式DLL注入實現
    2022-05-13 15:59:21
    反射式dll注入與常規dll注入類似,而不同的地方在于反射式dll注入技術自己實現了一個reflective loader()函數來代替LoadLibaryA()函數去加載dll,示意圖如下圖所示。藍色的線表示與用常規dll注入相同的步驟,紅框中的是reflective loader()函數行為,也是下面重點描述的地方。
    該漏洞發生的位置是在驅動文件Win32k.sys中的xxxHandleMenuMessage函數,產生的原因是沒有對該函數中調用的xxxMNFindWindowFromPoint函數的返回值進行合法性驗證,直接將其作為參數傳遞給后面的xxxSendMessage函數調用,從而造成了提權漏洞。
    Win32k組件最初的設計和編寫是完全建立的用戶層上的,但是微軟在 Windows NT 4.0 的改變中將 Win32k.sys 作為改變的一部分而引入,用以提升圖形繪制性能并減少 Windows 應用程序的內存需求。窗口管理器(User)和圖形設備接口(GDI)在極大程度上被移出客戶端/服務端運行時子系統(CSRSS)并被落實在它自身的一個內核模塊中。
    結構&拷貝與引用
    2023-05-10 11:27:04
    結構&拷貝與引用開始之前,我們約定數據塊也叫插槽,也就是storage。storage是永久存儲在區塊鏈上的地方。Stack 的最大深度為 1024 個元素,支持 256 位的字長。結構當定義局部變量時,它存儲在內存中,然后壓入堆棧以執行。1024棧深簡介EVM不是寄存器機而是堆棧機,所以所有的計算都在稱為堆棧的數據區域上進行。1024 是一個非常保守的值,以盡可能安全EVM 的設計方式往往會使更大的堆棧變得無用。EVM 只能訪問堆棧中前16個slot。
    可是當我們開啟了smap保護之后,內核態就沒有辦法訪問用戶態的數據,此時當我們再hijack tty_operation到我們的用戶態時,我們的kernel就會panic,更別說劫持執行流到用戶態上執行rop了。當我們調用msgsnd時,在linux內核中會調用do_msgsnd。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类