Windows平臺相關基礎知識

0x00
一、Windows API編程相關知識

  • Windows的工作模式、Windows的內存管理、異常處理
  • Windows應用程序的編程環境
  • Win32彙編程序結構
  • Windows API
    二、Win32彙編語言程序設計
  • 80x86處理器寄存器
  • IA-32指令系統,標號、變量和數據結構
  • 使用子程序(參數傳遞、堆棧平衡等)

0x01

Windows工作模式及內存管理

1、Windows系統的特點

  • 圖形用戶界面。告別命令行,所見即所得;
  • 多任務系統。多個程序同時運行,提高效率;
  • 大量的函數調用。程序員可把精力放在程序邏輯結構和用戶界面上;
  • 和設備的無關性。應用程序不用關心具體的硬件型號;
  • 內存管理。內存分頁和虛擬內存,4GB地址空間。
    2、 Windows工作模式
  • 實模式 :提供不受保護的段,用於實現早期處理器的16位執行環境;使用20位地址線。
  • 保護模式:32位地址線,尋址空間達到4GB。支持多任務和程序優先級。保護模式出現的原因是:保護進程地址空間。
  • 虛擬86模式:是以任務形式在保護模式上執行。支持任務切換和內存分頁。虛擬86模式採用和實模式一樣的尋址方式,尋址空間爲1MB=1024KB。

注意:實模式可以切換到保護模式,保護模式可以和虛擬86模式相互切換,從實模式切換到保護模式是通過控制寄存器CR0的控制位PE。不支持從實模式直接切換到虛擬86模式。

Windows工作模式比較
https://img-blog.csdnimg.cn/20191005221347797.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxODE0Nzc3,size_16,color_FFFFFF,t_70注意:虛擬86模式以保護模式爲基礎,是以任務形式在保護模式上執行。利用分頁機制,將不同虛擬86任務的地址空間映射到不同物理地址上。每個虛擬86任務都認爲自己在使用獨享的1MB地址空間。

0x02

Windows的內存管理

實模式下的內存尋址方式 實模式支持內存分段模型。邏輯地址由16位段選擇器和16位段內偏移地址組成。16位段選擇器用於確定一個20位的段基址;再與16位段內偏移地址相加,得到邏輯地址對應的線性地址。由於段內偏移地址是16位的,因此,線性地址空間由一系列64KB大的段組成(一個地址上存放一個字節)。實模式不支持內存分頁,因此,線性地址即爲物理地址。
https://img-blog.csdnimg.cn/20191005222053236.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxODE0Nzc3,size_16,color_FFFFFF,t_70注:xxxx:yyyy格式的虛擬地址在內存中的實際位置是:xxxx*10h+yyyy
20位地址線,尋址空間1M

保護模式下內存尋址:

  • 保護模式支持內存分段模型。保護模式與實模式的主要區別在於:段寄存器中存放的不再是段基址,而是描述符表的索引。保護模式下對內存的分段是強制的,分頁是可選的。
  • 保護模式下內存尋址時,16位的段寄存器存放的不是段基地址,而是描述符表的索引地址,段內偏移地址長度32位;段描述符是64位,因爲需要包含地址空間定義的一些安全屬性;
  • GDT/GDTR, LDT/LDTR;
  • 段選擇器高13位表示索引,第0,1位表示段選擇器的請求特權級,第2位TI表示段描述符的位置:TI=0表示在GDT中,TI=1表示在LDT中。
  • 段描述符中的32位線性基地址與32位段內偏移地址相加,得到線性地址,如果不分頁則線性地址與物理地址直接對應。
  • 保護模式下,線性地址空間大小爲4G,32位地址線。
    我愛你
    注意:保護模式下,16位的段寄存器存放的不是段地址,而是段選擇器;
    段選擇器高13位表示索引,第0,1位表示城區的當前優先級,第2位TI表示段描述符的位置

在這裏插入圖片描述全局描述符表GDT:
在這裏插入圖片描述在 32 位保護模式下,段地址是 32 位的線性地址,如果未開啓分頁功能,該線性地址就是物理地址。

保護模式下,16位的段寄存器存放的不是段地址,而是段選擇器;
段選擇器高13位表示索引,第2位TI表示段描述符的位置在這裏插入圖片描述內存分頁機制:

CR0寄存器中第31位(PG位)決定是否分頁:

  • PG=0不啓用分頁,線性地址即爲物理地址;
  • PG=1啓用分頁,線性地址經過頁表映射得到物理地址;
    在這裏插入圖片描述
  • 一級頁表的映射:
    32位虛擬內存地址=20位頁表索引+12位頁內偏移
  • 二級頁表的映射方式:
    32位虛擬內存地址=10位頁目錄索引+10位頁表索引+12位頁內偏移

從Windows的內存安排看Win32編程中的幾個重要概念:

  • 每個應用程序都有自己的4GB尋址空間,用於存放操作系統、系統DLL、用戶的DLL代碼,應用程序代碼、數據等。
  • 不同應用程序的線性地址空間是隔離的。在某個程序所屬的時間片中,其他程序的代碼和數據沒有被映射到可尋址的線性地址中,所以是不可訪問的。
  • DLL程序沒有自己的私有空間,它們總被映射到其他應用程序的地址空間中,當做其他應用程序的一部分運行。
    在這裏插入圖片描述
    0x03

Windows的特權保護

80386實模式下的中斷和異常處理:

  • 發生n號中斷或異常,或者執行到int n 指令時,CPU到n*4的地址取出中斷服務程序地址;
  • 將標誌寄存器、CS,IP寄存器值壓入堆棧;
  • 執行中斷服務程序;
  • 服務程序執行到iret時,CPU從堆棧中彈出標誌寄存器、取出CS、IP並返回。
    woaini注:每個中斷向量4字節

80386保護模式下的中斷和異常處理

  • 異常處理往往是從用戶程序切換到系統程序,低優先級切換到高優先級;

  • 那麼,怎樣確保高優先級代碼能夠安全的被低優先級代碼調用?

  • 中斷門,自陷門,任務門

  • 中斷描述符:門的種類&入口地址,8字節,放在中斷描述符表中
    在這裏插入圖片描述
    80386的保護機制

  • 段的類型檢查:
    段的類型由段描述符指定,主要屬性有是否可執行,是否可讀寫。
    CS/DS/SS等段選擇器是否能裝入某種類型的段描述符是有限制的。
    例如,不可執行的段不能裝入CS;不可寫的段不能裝入SS。

  • 訪問數據時的級別檢查:
    低優先級的代碼不能訪問高優先級的數據段。
    80386 GDT中的DPL域(描述符優先級)指定了這個段可以被訪問的最低優先級;
    段選擇器中的RPL域(請求優先級)指定了當前執行代碼的優先級;
    DPL≥RPL,該段才能訪問,否則產生保護異常;

0x04

Windows應用程序的編程環境

在這裏插入圖片描述MASM編譯器和鏈接器:
在這裏插入圖片描述

0x05

Win32彙編程序結構

  • 使用的指令集
    內存模式:win32 程序代碼和數據使用同一個4GB段;CS/DS/SS/ES全部使用平坦模式
    子程序/API調用方式:參數傳遞、堆棧平衡

  • .data/.data?/.const/.code.data
    可讀可寫的已定義變量, .data段存放在可執行文件的_data節區
    .data?可讀可寫的未初始化數據段, .data?段存放在可執行文件的_BSS節區
    .const不能寫的常量段

  • 代碼段一般放在PE文件的_TEXT節區;
    程序在運行時,代碼段可寫嗎?
    For example,UPX…….

在這裏插入圖片描述

0x06

Windows API

  • API(應用程序接口)是windows操作系統提供的一套編程函數庫,提供應用程序運行所需的窗口管理,圖形設備接口、內存管理等各項服務功能。這些函數採用DLL實現。
  • Win32 API的核心由三個DLL提供:
    KERNEL 32.DLL——系統服務功能。任務管理,動態鏈接、內存管理等
    GDI32.DLL——圖形設備接口。利用顯卡驅動程序顯示文本、圖像等
    USER32.DLL——用戶服務接口。建立窗口、傳送消息等
  • 調用API的過程:利用堆棧傳遞參數,調用者把參數壓入堆棧,DLL中的函數再從堆棧中取出參數處理。
    在這裏插入圖片描述注意:在源程序編譯鏈接程可執行文件後,call MessageBox語句中的MessageBox會被換成一個指向可執行文件導入表的地址。而導入表中指向MessageBox函數的實際地址由系統根據User32.dll在內存中的位置動態填入。

API函數的返回值:

  1. 返回值存放在eax寄存器中;如果返回的內容超過了一個eax所能容納的長度,怎麼辦?
  2. Answer:Win32 API採用的方法一般是eax中返回一個指向返回數據的指針。
    Win32 環境下,和字符串相關的API函數有兩類,分別對應不同字符集:
    ANSI字符集:每個字符一個字節寬,API函數名尾部帶“A”
    Unicode字符集:每個字符兩個字節寬, API函數名尾部帶“W”
  3. User32.dll中只有MessageBoxA和MessageBoxW,why源程序中仍可以用MessageBox?
    在這裏插入圖片描述
  4. include語句:將程序調用到的API函數所在的DLL文件包含進來
    include <DLL名.inc> 例如: include <user32.inc>
    Includelib語句:告訴鏈接器在鏈接的時候到指定的庫文件中去找API函數的位置
    includelib 庫文件名 例如: includelib user32.lib

0x07

80x86處理器的寄存器

通用寄存器、指令寄存器、段寄存器、標誌寄存器、系統地址寄存器(GDTR/LDTR)、控制寄存器(CR0,CR2,CR3)

CR0:保護模式允許位、任務切換位
CR1:頁故障地址寄存器
CR2:頁表目錄寄存器,存放頁表目錄的物理基地址

在這裏插入圖片描述

  • 指令指針寄存器
    32位指令指針寄存器EIP存放指令指針,即當前代碼段中將被執行的下一條指令的線性地址偏移。程序運行時,CPU根據CS段寄存器和EIP寄存器的地址偏移讀取下一條指令,然後將EIP寄存器的值自增,增大的大小爲被讀取指令的字節數。
    EIP寄存器更改的途徑:一是通過跳轉和函數調用返回指令JMP,CALL,RET等,二是通過中斷或異常進行修改。

  • 段寄存器
    6個16位的段寄存器: CS,SS,DS,ES,FS,GS分別用於存儲保護模式下邏輯地址中的段選擇器。
    代碼段寄存器CS:存放應用程序代碼所在的段的段描述符索引(代碼段線性基址),CS+EIP得到下一條指令的線性地址。
    棧段寄存器SS:存放棧段的段描述符索引(棧段的線性基址)
    數據段寄存器(DS,ES,FS,GS):DS數據段含有程序使用的大部分數據;ES數據段可以爲某些串指令存放目的數據;FS段寄存器可用於計算結構化異常處理SEH, 線程環境塊TEB,進程環境塊PEB。

0x08

IA-32指令系統

在這裏插入圖片描述以funadd(arg1,arg2)爲例,在Win32環境下,採用stdcall調用方式,堆棧的變化過程:
在這裏插入圖片描述要求:能夠根據彙編指令分析出堆棧內容、堆棧指針的整個變化過程
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章