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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

API函数的调用过程

發布時間:2023/12/14 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 API函数的调用过程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

API函數的調用過程(ring3)

Windows API

  • Application Programing Interface (應用程序接口) 簡稱API函數

  • Windows 有多少個API?
    主要是存放在C:\WINDOWS\system32下面所有的dll

  • 幾個重要的dll
    Kernel32.dll:最核心的功能模塊,比如管理內存,進程和線程相關的函數等.

  • User32.dll:是Windows用戶界面相關的應用程序接口,如創建窗口和發送消息等.

    GDI32.dll全稱是Graphical Device Interface(圖形設備接口),包含用于畫圖和顯示

    Ntdll.dll:大多數API都會通過這個dll進入內核(0環)

    絕大部分核心功能是在0環實現的,3環只是使用了0環提供給他的一個接口.

    Kernel32.dll ->ReadProcessMemory

    在C:\WINDOWS\system32\目錄下找到kernel32.dll模塊,放到IDA中 查看ReadProcessMemory的代碼

    我們看到在用戶層的核心功能模塊中的ReadProcessMemory函數再將參數壓棧后,又調用了另一個模塊的函數NtReadVirtualMemory

    ReadProcessMemory:
    ring3所做的事情:

    接下來看看NtReadVirtualMemory函數 (ring 0)所做的事情

    這時候再打開另一個ntdll.dll模塊 查看其中的NtReadVirtualMemory函數:

    這個函數傳進去一個調用號,以及一個地址,再去call這個地址中的值,這個值就是存在于內核的一個函數.

    //這個函數的功能: 提供編號 找到函數 通過函數進入ring 0也就是說ntdll也只是做了個引薦人的功能,引薦進ring 0

    真正對內存讀寫是在ring 0實現的
    那就再繼續跟跟看7FFE0300處的值是什么?

    7c92e4f0

    再繼續跟7c92e4f0:

    這就跟到了sysenter 匯編指令:
    該匯編指令的作用是?:

    通過寄存器,切換EIP,ESP

    1.將IA32_SYSENTER_CS 和IA32_SYSENTER_EIP分別裝到cs和eip寄存器中2.將IA32_SYSENTER_CS+8 和IA32_SYSENTER_ESP 分別裝載到ss和esp寄存器中,切換特權級0;

    之后程序在ring 0環境下跳轉到指定eip去執行,執行結束后使用sysexit 匯編指令返回,這條指令功能與sysenter相反:

    1.將IA32_SYSENTER_CS+16裝載到cs寄存器,將edx寄存器中的指令的指針裝載到eip;2.將IA32_SYSENTER_CS+24裝載到ss寄存器中;3.cx寄存器中的指針裝載到esp中,切換到特權3IA32_SYSENTER_CS之類的屬于MSR寄存器

    KiFastSystemCall,KiIntSystemCall

    操作系統會檢測CPU支不支持快速調用,如果支持,就會調用KiFastSystemCall 進ring 0,如果CPU比較老舊不支持快速調用 就會調用 KiIntSystemCall去進入ring 0

    在ntdll.dll模塊中找到該函數


    發現他的本質其實還是調用了int 2e 號中斷進入的ring 0

    我們現在嘗試在ntoskrnl.exe模塊中查看一下int 2e是怎么進ring 0的?


    SEP位

    那CPU到底是怎么驗證支不支持KiFastSystemCall的呢?

    CPUID 指令 //該指令需要傳入一個參數 //當eax = 1 來執行cpuid指令時,處理器的特征信息被放在ecx,和edx寄存器中,其中edx包含了一個SEP位(11位),該位指明了當前處理器是否支持

    當SEP位 == 1 時,說明是支持的

    1 1 1 1 1 0 0 0 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 15 11 0

    這兩種的區別

    KiIntSystemCall:

    這個主要是使用INT 2E 中斷門去做,中斷門中CS,EIP都已經在IDT表中存儲好了,SS與ESP需要TSS提供,所以使用一次int 2e 會讀取IDT中的CS,和查找TSS

    KiFastSystemCall:

    sysenter : 系統會提前將CS/SS/ESP/EIP的值存儲在MSR寄存器中,sysenter指令執行時,會將MSR寄存器值直接寫入相關寄存器,直接就是寄存器的讀,沒有讀內存的過程,這是快速調用的本質。

    _KUSER_SHARED_DATA

  • 這個結構體是在User層和Kernel層分別定義了一個_KUSER_SHARED_DATA結構體 用于User和Kernel層共享某些數據

  • 他們使用固定的地址值映射,_KUSER_SHARED_DATA結構區域在User和Kernel層地址分別為:
    User 層地址為:0x7ffe0000
    Kernel層地址為:0xffdf0000

  • 注意:雖然指向同一個物理頁,但在User層是只讀的,在Kernel層是可讀寫的

    回到上面的內容:

    也就是說,call這個地址里的內容,我們并不能武斷的就說這里面一定是什么,CPU新舊不同,可能會導致調用的函數是不同的.有可能是KiFastSystemCall,也有可能是KiIntSystemCall

    附件

    MSR地址
    IA32_SYSENTER_CS174H
    IA32_SYSENTER_ESP175H
    IA32_SYSENTER_EIP176H

    SS = CS + 8

    可以通過RDMSR/WRMST 來進行讀寫(操作系統使用WRMST寫該寄存器)

    內核模塊:

    ntoskrnl.exe(CPU以10-10-12分頁模式啟動) ntkrnlpa.exe(CPU以2-9-9-12分頁模式啟動)

    總結

    以上是生活随笔為你收集整理的API函数的调用过程的全部內容,希望文章能夠幫你解決所遇到的問題。

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