win32彙編基礎概念
一、關於暫存器
暫存器有EAX,EBX,ECX,EDX,EDI,ESI,ESP,EBP等,似乎IP也是暫存器,但只有在CALL/RET在中會預設使用它,其它情況很少使用到,暫時可以不用理會。
EAX是WIN32 API 預設的返回值存放處。
ECX是LOOP指令自動減一的暫存器。
ESP是堆疊指標。
EBP經常用來在堆疊中定址。
ESI好像常常用在指標定址中,EDI不大清楚。
二、關於記憶體定址
WIN32中記憶體是平坦的,對於每個程式來說都可以使用2G範圍的地址,但各個程式之間並不會干擾,這是因為各個程式所使用到的實體記憶體被Windows自行安排,不會互相覆蓋,而且一個程式不會隨意地訪問到另一個程式的地址空間。
三、關於堆疊
Windows為每個程式安排了堆疊段,它是從高地址向低地址延伸的,之所以採用這種方式,是因為這樣可以使堆疊指標始終指向最近入棧的元素的起始地址,這樣的話,為訪問這個元素提供了非常便利的方式。
ESP作為堆疊指標始終指向棧頂,如果看一下PUSH和POP的操作就可以明白這句話:
PUSH: ESP <-- ESP-4 (ESP+3,ESP) <-- 入棧元素
POP: 出棧元素 <-- (ESP+3,ESP) ESP <-- ESP+4
因為PUSH和POP自動修改了ESP的值,使它始終指向棧頂了。當然也可以自己來修改ESP的值,例如我們可以:
sub esp,4 ;這樣就把棧頂指標向下移動了。
這種操作常常用在區域性變數的分配中,在子程式中使用到區域性變數時,就在堆疊中為它們提供空間,這樣可以使子程式退出時收回區域性變數佔用的空間,有利於子程式的模組化。
我們可以用ESP來定址堆疊中的元素,比如ESP指向當前棧頂元素的起始地址,ESP-4指向前一個元素的起始地址,不過因為ESP常常在變化,這樣用ESP在堆疊中定址的話不方便,所以我們就用EBP來代替ESP定址,首先把EBP入棧儲存,然後把ESP賦值給EBP,這樣就可以用EBP來定址堆疊中的資料了。我用一個例子來說明堆疊的變化。
push 0x00000001 ;1
push ebp ;2
mov ebp,esp ;3
push 0x12345678 ;4
mov eax,dword ptr[ebp+4] ;5
mov ebx,dword ptr[ebp-4] ;6
mov ax,word ptr[ebp-2] ;7
mov al,byte ptr[ebp-1] ;8
mov al,byte ptr[ebp-3] ;9
mov ax,word ptr[ebp-3] ;10
5 eax=0x00000001
6 ebx=0x12345678
7 ax=0x1234
8 al=0x12
9 al=0x56
10 ax=0x3456
堆疊使用在子程式的實現中,當呼叫子程式時,首先把引數入棧,然後把返回IP入棧,然後轉移到子程式處,如果有區域性變數,則下移ESP,然後初始化該區域性變數,這樣用到EBP來定址區域性變數,引數的定址同樣要用到EBP。
四、簡單的幾個關鍵字
ptr 顯式指定後面的資料的型別
offset 全域性變數的地址
addr 區域性變數的地址,也可以用在全域性變數上
local 定義區域性變數
proc 定義子程式
proto 宣告子程式
五、例子
Hello.asm檔案的內容如下: ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 第一部分:模式和源程式格式的定義語句 .386 ; 指令集 .model flat,stdcall ; 工作模式 option casemap:none ; 格式 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; Include 檔案定義 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 資料段 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .data szCaption db 'A MessageBox !',0 szText db 'Hello, World !',0 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; 程式碼段 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .code start: invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK invoke ExitProcess,NULL ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end start ; 指定程式的入口 1. 第一部分模式和源程式格式的定義語句 第一行 指定使用的指令集(編譯器使用) Win32環境工作在80386及以上的處理器中,所以必須定義.386。如果程式(VxD等驅動程式)中要用到特權指令,那麼必須定義.386p。 第二行 定義程式工作的模式(包括記憶體模式、語言模式、其它模式) 對Win32程式來說,只有一種記憶體模式,即flat(平坦)模式。 Win32 API呼叫使用的是stdcall格式,所以Win32彙編中必須在.model中加上stdcall引數。 第三行 option語句 由於Win32 API中的API名稱區分大小寫,所以必須定義option casemap:none,來表明程式中的變數和子程式名對大小寫敏感。 2. 包含全部段的源程式結構: .386 .model flat,stdcall option casemap:none <一些include語句> .stack [堆疊段的大小] .data <一些初始化過的變數定義> .data? <一些沒有初始化過的變數定義> .const <一些常量定義> .code <程式碼> <開始標記> <其他語句> end 開始標記 3. 段的定義 資料段 .data 已初始化資料段,可讀可寫的已定義變數; 當程式裝入完成時,這些值就已經在記憶體中; 資料定義在.data段中會增加可執行檔案的大小; .data段一般存放在可執行檔案的_DATA節區(Section)內; .data? 未初始化資料段,可讀可寫的未定義變數,在可執行檔案中不佔空間; 這些變數一般作為緩衝區或者在程式執行後才開始使用。 資料定義在.data?資料段中不會增加可執行檔案的大小; .data?段一般存放在可執行檔案的_BSS節區內; .const 常量,可讀不可寫的變數; 程式碼段 .code 所有的指令都必須寫在程式碼段中; Win32中,資料段是不可執行的,只有程式碼段有可執行的屬性; 對於執行在特權級3的應用程式,.code段不可寫。除非把可執行檔案PE頭部中的屬性位改成可寫; 對於執行在特權級0的程式,所有的段都有讀寫許可權,包括程式碼段; .code程式碼段一般存放在可執行檔案的_TEXT節區內; 堆疊段 .stack 與DOS彙編不同,Win32彙編不必考慮堆疊。系統會自動分配堆疊空間; 堆疊段的記憶體屬性是可讀寫並且可執行; 靠動態修改程式碼的反跟蹤模組可以拷貝到堆疊中去邊修改邊執行; 緩衝區溢位技術也會用到這個特性; 4. 呼叫作業系統功能的方法: DOS下 作業系統的功能通過各種軟中斷來實現。 應用程式呼叫作業系統功能將經歷如下三個過程: 把相應的引數放在各個暫存器中再呼叫相應的中斷; 程式控制權轉到中斷中去執行; 完成以後通過iret中斷返回指令回到應用程式中; DOS下呼叫系統功能方法的缺點: 所有的功能號定義是難以記憶的數字; 80x86系列處理器能處理的中斷最多隻能有256個; 通過暫存器來傳遞引數,對於引數較多的函式很不方便; Win32下 系統功能模組放在Windows的動態連結庫(DLL)中 作為Win32 API核心的3個DLL: KERNEL32.DLL 系統服務功能。 GDI32.DLL 圖形裝置介面。 USER32.DLL 使用者介面服務。 常用API的引數和函式宣告,檢視文件《Microsoft Win32 Programmer's Reference》 5. Win32 API的函式原型宣告 函式原型宣告的彙編格式如下: 函式名 proto [距離] [語言] [引數1]:資料型別, [引數2]:資料型別,...... proto是函式宣告的偽指令 距離可以設定為NEAR、FAR、NEAR16、NEAR32、FAR16或FAR32,由於Win32中只有一個平坦的段,無所謂距離,所以在定義時可以忽略距離。 語言型別可是使用.model所定義的預設值。 以訊息對話方塊函式MessageBox為例 C格式如下: int MessageBox( HWND hWnd, // Handle to owner window LPCTSTR lpText, // text in message box LPCTSTR lpCaption, // message box title UINT uType // message box style ); 彙編格式如下: MessageBox Proto hWnd:dword,lpText:dword,lpCaption:dword,uType:dword 或者寫為 MessageBox Proto :dword,:dword,:dword,:dword 編譯器只對引數的數量和型別感興趣,引數的名稱只是增加可讀性,所以可以省略。 對於組合語言來說,Win32環境中的引數實際上只有一種型別,就是一個32位的整數(dword,double word),雙字,四位元組。 6. 呼叫Win32 API 呼叫API有如下兩種方法: 1) invoke invoke是MASM提供的偽指令; invoke偽指令的好處就是能夠提高程式碼的可讀性,減少錯誤; invoke做了下面三件事: 在編譯的時候,由編譯器把invoke偽指令展開成相應的push指令和call指令; 進行引數數量的檢查工作; 如果帶的引數數量和宣告時的數量不符,編譯器會報錯; 2) push和call的組合 80386處理器的指令 invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK 也可寫為 push NULL push offset szText push offset szCaption push MB_OK call MessageBox 7. Win32 API函式返回值的處理方法 對於組合語言來說,Win32 API函式返回值的型別只有dword一種型別,它永遠放在eax中。 如果要返回的內容在一個eax中放不下,Win32 API採用如下方法來解決: a) 一般是eax中返回一個指向返回資料的指標; b) 在呼叫引數中提供一個緩衝區地址,資料直接返回到這個緩衝區中去。類似變參的概念; 8. 與字串相關Win32 API的分類 在Win32環境中,根據兩個不同的字符集(ANSI字符集和Unicode字符集),可以把和字串相關的API分成兩類: a) 處理ANSI字符集的Win32 API函式 函式名稱的尾部帶一個“A”字元; ANSI字串是以NULL結尾的一串字元陣列,每一個ANSI字元佔一個位元組的寬度; 例如:MessageBoxA Proto hWnd:dword,lpText:dword,lpCaption:dword,uType:dword b) 處理Unicode字符集的Win32 API函式 函式名稱的尾部帶一個“W”字元; 每一個Unicode字元佔兩個位元組的寬度,所以可以同時定義65536個不同的字元; 例如:MessageBoxW Proto hWnd:dword,lpText:dword,lpCaption:dword,uType:dword Windows 9x系列不支援Unicode版本的API,絕大多數的API只有ANSI版本。 只有Windows NT系列才完全支援Unicode版本的API。 為了編寫在幾個平臺中都能通用的程式,一般應用程式都使用ANSI版本的API函式集。 提高程式可移植性的一個方法:相關推薦
win32 彙編基礎概念整理
一、關於暫存器 暫存器有EAX,EBX,ECX,EDX,EDI,ESI,ESP,EBP等,似乎IP也是暫存器,但只有在CALL/RET在中會預設使用它,其它情況很少使用到,暫時可以不用理會。 EAX是WIN32 API 預設的返回值存放處。 ECX是LOOP指令自動減一的暫存器。 ESP是堆
win32彙編基礎概念
一、關於暫存器 暫存器有EAX,EBX,ECX,EDX,EDI,ESI,ESP,EBP等,似乎IP也是暫存器,但只有在CALL/RET在中會預設使用它,其它情況很少使用到,暫時可以不用理會。 EAX是WIN32 API 預設的返回值存放處。 ECX是LOOP指令自動減一的暫存器。 ESP是堆
程式語言的底層描述(1)——彙編基礎概念的開始之入門
該主題預設在類unix作業系統中進行討論 gcc編譯器可通過不同的引數,生成不同階段的編譯檔案,比如,我們想生成可執行檔案,就用gcc -o;要生成目的碼.o,就用gcc -c;要生成彙編程式碼.s,就用gcc -S, 程式編譯的順序是,編譯器先根據.c原始檔產生.s彙編
RabbitMQ基礎概念詳細介紹
可用性 將不 tar connect 相互 abi 封裝 編寫 綁定 原文地址:http://www.diggerplus.org/archives/3110 引言 你是否遇到過兩個(多個)系統間需要通過定時任務來同步某些數據?你是否在為異構系統的不同進程間相互調用、通
JS基礎概念
文件 數字 true while語句 第一個 加載 截取 pre js基礎 JS基礎概念 1. 算法及流程圖 算法類型:1.算數算法;2.事務性算法(解決某個問題的方法和先後順序)。 JS語法概述 1. 引入JS的方法 1.用<script src=""><
kafka-通俗易懂基礎概念篇
kafka python topic 一些大的網站如果想統計用戶的訪問情況,如果每個用戶的訪問,都在後端經過一系列的用戶行為分析,然後再給客戶返回結果這顯然不現實,直接寫入數據庫,數據庫也扛不住,這時候就需要一個消息系統,在用戶一個請求過來後,服務器只需要把這次操作扔到後端,不用管後
【extjs6學習筆記】0.1 準備:基礎概念(02)
json over cal 類的屬性 tab 常用事件 data 微軟 基於 Ext 類 Ext 是一個全局單例的對象,在 Sencha library 中它封裝了所有的類和許多實用的方法。許多常用的函數都定義在 Ext 對象裏。它還提供了像其他類中一些頻繁使用的方法
nodejs零基礎詳細教程1:安裝+基礎概念
img res 安裝過程 pkg 實時 linkedin 圖標 過程 好的 第一章 建議學習時間2小時 課程共10章 學習方式:詳細閱讀,並手動實現相關代碼 學習目標:此教程將教會大家 安裝Node、搭建服務器、express、mysql、mongodb、編寫後臺業務邏輯
java 基礎概念 -- 數組與內存控制
nbsp 堆內存 數組元素 art pan popu ace article pac 問題1: Java在聲明數組的過程中,是怎樣分配內存的? 在棧內存中 建一個數組變量,再在堆內存中 建一個 數組對象。至於詳細的內存分配細節,還得看 該初始化是 數組動態初始化 還是
Linux同步與相互排斥應用(零):基礎概念
使用 line 關系 並發執行 來看 文章 必須 生產者 而且 【版權聲明:尊重原創,轉載請保留出處:blog.csdn.net/shallnet 或 .../gentleliu,文章僅供學習交流,請勿用於商業用途】 當操作系統進入多道批處理
python3 基礎概念
small obj 如果 公司 不可變類 col targe 形象 height 一、3.x新特性 1、print (),打印,3.x必須加括號 2、raw_input,3.x改為input 二、簡介 Python是著名的“龜叔”Guido van Ros
2017.06.29數據挖掘基礎概念第六,八,九章
之前 屬性。 prior 選擇 處理 挖掘 允許 什麽是 單元 第六章51、關聯規則的挖掘的兩個過程1、找出所有的頻繁項集2、由頻繁項集產生強關聯規則52、頻繁項集挖掘方法 1、Apriori算法 2、挖掘頻繁項集的模式增長方法 3、使用垂直數據格式挖掘頻繁項
2017.06.29數據挖掘基礎概念第四章
構建 企業 操作 允許 包含 元數據 體系結構 當前 然而 第四章39、為什麽在進行聯機分析處理(OLAP)時,我們需要一個獨立的數據倉庫,而不是直接在日常操作的數據庫上進行 1、提高兩個系統的性能 2、操作數據庫支持多事務的並發處理,需要並發控制和恢復機制,確保一
基礎概念
們的 例如 區別 行為 事物 創建 自己 避免 要求 1、面向對象3大特點 封裝:封裝,也就是把客觀事物封裝成抽象的類,並且類可以把自己的數據和方法只讓可信的類或者對象操作,對不可信的進行信息隱藏。 繼承:繼承是指這樣一種能力:它可以使用現有類的
K8S基礎概念
使用 外部 清理 lac six 基本上 新的 容器 所有 一、核心概念 1、Node Node作為集群中的工作節點,運行真正的應用程序,在Node上Kubernetes管理的最小運行單元是Pod。Node上運行著Kubernetes的Kubelet、kube-proxy
軟件測試基礎概念總結
開發 提高 運行程序 手機軟件 標準化 理論 report 計算 管理 一、軟件測試概述 (一)什麽是測試,與測試相關常見活動有哪些? 測試:與科學方法中的實驗類似,是對事物狀態、功能的測量和觀察。通過將測量結果與已知狀態或理論假設相比較,測試者得以對事物狀態、功能做出
粵嵌java培訓第一天筆記-java基礎概念
ont 類型 運算符 按位或 次循環 規則 是否 支持 har 一、二進制數 1、最高位為0,表示正數;最高位為1,表示負數。 2、相應的負數與正數之間進行轉換方式:通過補碼方式進行轉換,即:取反再加1。 例如:0000 0001 表示 +1;通過對 000
站點分析基礎概念之訪問停留時間
基礎概念 sso ack nts visit gin san faq iss 類型:計數度量 定義:訪問停留時間(Visit Duration)是指一次訪問的持續時間。典型的計算方法是在一次訪問中,用戶最後一次操作發生的時間減去第一次操作發生的時間。
機器學習基礎概念筆記
最大 什麽 mar 機器學習 決策 常見 idg 框架 評估 監督學習:分類和回歸屬於監督學習。這類算法必須知道預測什麽,即目標變量的分類信息。 常見算法:k-近鄰算法、線性回歸、樸素貝葉斯算法、支持向量機、決策樹、Lasso最小回歸系數估計、Ridge回歸、局部加權線
oracle DDL,DML,DCL, 基礎概念詳解
aud ase class con ani 概念 ddl 數據庫狀態 修改 一、SQL語言,有兩個組成部分: DML(data manipulation language):它們是SELECT、UPDATE、INSERT、DELETE,命令是用來對數據庫裏的數據進行操作