色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C/C++之函數體hack(上)

jf_78858299 ? 來源:小余的自習室 ? 作者:小余的自習室 ? 2023-03-30 16:54 ? 次閱讀

前言

首先來說下 什么是hack ? hack字面意思“ 非法入侵 ”,那么在C/C++中其實就是 使用反匯編查看C/C++代碼對應的匯編代碼

那可能有人要問了,C/C++不是高級語言么,為什么還要看匯編代碼?理由嘛見仁見智,

個人理解有下面幾種:

  • 1.C/C/C++應用不像javapython那樣,報錯信息可以在日志中一目了然,C/C++應用的報錯可以讓你查的懷疑人生,為什么呢?因為 報錯日志提供的信息可能會誤導你 ,比如真實錯誤是在100行,但是報錯信息會在第一行或者全局都有報錯,就很讓人上頭。。有了這個hack過程,就可以定位到可能報錯的地方,使用hack反編譯得到匯編代碼,匯編代碼可以讓你看清你寫的C/C/C++代碼對于CPU來說實際執行的行為。
  • 2.當我們在調試C/C++應用的時候,經常會 有些疑惑 ,比如i++和++i為什么結果不同,又比如inline內聯函數有什么用處?原理是什么?等等,這些也可以使用hack來解釋,那有人要說了,這些我都知道啥意思啊,i++和++i前自增和后自增么,內聯函數原理就是編譯期將函數代碼拷貝到調用處嘛。可是這些都是別人告訴你的,那如果一個代碼段別人沒告訴你呢?百度是不是什么都可以找到的,特別是對于C/C++開發來說,信息更是少的可憐,此時你就會知道hack是多重要了。
  • 3.如果你的C/C++應用需要實現一些性 能上優化 ,也可以使用hack過程查看CPU和內存的行為,從而對應用性能做一些提升,是不是很cool。。

既然有這么多用處,那么下面小余就來講解下如何在我們的應用中hack。

不過在hack前我們需要了解一些匯編語言基礎。

匯編語言基礎

首先我們得了解匯編語言中的幾個模塊:1.寄存器 2.內存 3.CPU

1.寄存器

寄存器是我們計算機中的最小存儲單位,在計算機金字塔的頂端, 屬于CPU的內部存儲 ,主要用來存儲CPU需要使用到的臨時數據。

CPU訪問寄存器的速度比訪問內存的速度快了100倍左右。

CPU中寄存器種類包括:通用寄存器,指令地址寄存器,狀態寄存器等等等等。。 這里只介紹幾個比較關鍵的寄存器:

1.通用寄存器

寄存器 原文 解釋 說明
AX accumulator 累加寄存器 通常用來執行加法,函數調用的返回值一般也放在這里面
CX counter 計數寄存器 通常用來作為計數器,比如for循環
DX data 數據寄存器 數據存取
BX base 基址寄存器 讀寫I/O端口時,edx用來存放端口號
SP stack pointer 棧指針寄存器 棧頂指針,指向棧的頂部
BP base pointer 基址指針寄存器 棧底指針,指向棧的底部,通常用ebp+偏移量的形式來定位函數存放在棧中的局部變量
SI source index 源變址寄存器 字符串操作時,用于存放數據源的地址
DI destination index 目標變址寄存器 字符串操作時,用于存放目的地址的,和esi兩個經常搭配一起使用,執行字符串的復制等操作

這里說明幾點:

  • 1.在具體hack的過程中你可能看到的是eax,ecx,edx等而不是AX,CX,DX,他們區別: 帶e開頭的說明是32位寄存器,也就是4個字節存儲的寄存器,而AX是eax的低16位的“子寄存器”, 這是早期一些寄存器是16位的,而為了兼容早期這些寄存器就使用“子寄存器”來標識。
  • 2.匯編語言中,在函數體返回時,統一使用eax為返回值,這個為什么這樣?我也不清楚,可能是早期大家都這么用就約定下來了吧。
  • 3.當我們在使用函數的時候,會將ebp的內容壓入棧底,作為棧底指針,指向棧的底部,局部變量使用ebp+偏移地址來定位。對于棧頂則使用esp寄存器來定位,關于函數棧會在后面講解。

2.eip寄存器

eip寄存器可以說是CPU中最關鍵的一個寄存器了,它指向了下一條要執行的指令所存放的地址, CPU工作其實就是取出eip中的地址中的指令,然后去執行這條指令,并將下一條指令的地址賦值給eip ,這樣CPU就可以依次執行完成所有的匯編代碼.

如果你要問我它是怎么找到下一條指令的地址的,首先正常執行指令是+1位下一條指令地址,如果碰到一些比如if語句,函數調用等情況,就會在上一條指令中得到這個地址,并賦值給eip,這個賦值動作是CPU自動完成的,開發是不能隨便更改的,這也變相的防止你搞出bug不是?

3.狀態寄存器

狀態寄存器中記錄了CPU執行過程中的一系列狀態,對于32位就有32個標志位,這些標志大部分都是由CPU自行設置:

寄存器標志位 解釋
CF 進位標志
PF 奇偶標志
ZF 零標志
SF 符號標志
OF 補碼溢出標志
TF 跟蹤標志
IF 中斷標志
……

圖片

4.指令寄存器:

根據指令在存貯器中的地址(由指令地址計數器給出),把指令從存貯器中取出來之后,需要有一個專門用于存放指令的地方,以便對指令進行分析和執行。 這個專門存放現行指令的部件就叫做指令寄存器

后面會具體匯編代碼會涉及到。

關于寄存器就講這么幾個吧,hack過程夠用了。

2.內存

這里講解的內存一般是指高速緩存(Cache)或者主存。

計算機在運行程序時,首先將程序從磁盤讀取到主存,然后CPU按規則從主存中取出指令,數據并執行指令,但是直接從主存(一般是DRAM)中讀寫是很慢的,所以引入了高速緩存(Cache)(使用的是SRAM)。

圖片

在程序運行前首先會試圖將指令,數據從主存中讀取到Cache中,然后在程序執行時直接訪問Cache, 如果指令和數據可以從Cache中讀取到,那么就說是“命中(hit)”,反之就是“不命中(miss)”, miss情況下需要從主存中讀取指令或者數據,這樣會直接影響CPU的性能,所以命中率對CPU來說至關重要。

內存在計算中又會分為:堆區,棧區,全局(靜態)區,常量區,代碼區等等。

圖片

這里講解下hack中比較關鍵的棧區。

棧區

  • 棧中存放了局部變量,參數,函數的返回地址等
  • 棧區由編譯器自動分配釋放,由操作系統自動管理,無須手動管理
  • 棧區中的局部變量只在該函數作用域中有效,函數退出后就會被銷毀、

    棧區就像一個桶一樣,桶底就是棧底為高地址區,桶的頂部為低地址, 桶中放東西當然是先放桶底然后依次疊加咯,也就是平時所說的FILO先進后出的模式。

圖片

3.CPU

1.CPU的功能

指令控制(程序的順序控制)
操作控制(一條指令由若干操作信號實現)
時間控制(指令各個操作實施時間的定時)
數據加工(算術運算和邏輯運算)

2.CPU的基本組成

中央處理器 CPU= 運算器 + 控制器
運算器:
ALU
累加器
暫存器
控制器
程序計數器 (PC) 、指令寄存器 (IR) 、數據緩沖器 (DR) 、地址寄存器 (AR) 、通用寄存器、狀態寄存器 (PSW) 、時序發生器、指令譯碼器 (ID) 、總線

圖片

CPU的工作分為以下 5 個階段:取指令階段、指令譯碼階段、執行指令階段、訪存取數和結果寫回。

  • 取指令 (IF,instruction fetch),即將一條指令從主存儲器中取到指令寄存器的過程。程序計數器中的數值,用來指示當前指令在主存中的位置。當 一條指令被取出后,程序計數器(PC)中的數值將根據指令字長度自動遞增。
  • 指令譯碼階段 (ID,instruction decode),取出指令后,指令譯碼器按照預定的指令格式,對取回的指令進行拆分和解釋,識別區分出不同的指令類 別以及各種獲取操作數的方法。現代CISC處理器會將拆分已提高并行率和效率
  • 執行指令階段 (EX,execute),具體實現指令的功能。CPU的不同部分被連接起來,以執行所需的操作。
  • 訪存取數階段 (MEM,memory),根據指令需要訪問主存、讀取操作數,CPU得到操作數在主存中的地址,并從主存中讀取該操作數用于運算。部分指令不需要訪問主存,則可以跳過該階段。
  • 結果寫回階段 (WB,write back),作為最后一個階段,結果寫回階段把執行指令階段的運行結果數據“寫回”到某種存儲形式。結果數據一般會被寫到CPU的內部寄存器中,以便被后續的指令快速地存取;許多指令還會改變程序狀態字寄存器中標志位的狀態,這些標志位標識著不同的操作結果,可被用來影響程序的動作。 在指令執行完畢、結果數據寫回之后,若無意外事件(如結果溢出等)發生,計算機就從程序計數器中取得下一條指令地址,開始新一輪的循環,下一個指令周期將順序取出下一條指令。 [1] 許多復雜的CPU可以一次提取多個指令、解碼,并且同時執行。

一些基礎的匯編命令:

1.數據傳送指令

  • 1.mov :傳送指令,也可以單純理解為賦值語句,這個語句在匯編中是最常用的。 格式:mov det,src

    首先mov語句分以下幾種情況:

    • 1.CPU內部寄存器之間數據傳送:mov ebp,esp ,將esp寄存器中的數據傳遞給ebp寄存器。
    • 2.立即數傳遞到通用寄存器:mov ebp 3 ,將立即數3傳遞到ebp寄存器中。
    • 3.立即數傳遞到內存存儲單元:mov [bx] 123h,將立即數傳遞到bx指向的內存地址中。
    • 4.內存和CPU之間數據傳送:內存傳遞到CPU寄存器中:mov eax,dword ptr [a] ,CPU寄存器傳遞到內存中:mov dword ptr [a],eax。

2.加減運算指令

首先要了解,加減法運算是會改變狀態寄存器中的值的,如一個有符號數的運算高位溢出標志(OF),無符號的運算進位標志(CF)等。

加法指令:add、adc、inc

  • 1.add
    格式:add OPRD1,OPRD2
    功能:OPRD1 = OPRD1 + OPRD2
    舉例:
    add eax ecx;//得到的結果為eax = eax+ecx;
    
  • 2.adc
    格式:add OPRD1,OPRD2
    功能:OPRD1 = OPRD1 + OPRD2
    舉例:
    adc eax ecx;得到的結果為eax = eax+ecx+狀態寄存器中給的進位標志CF
  • 3.inc
    格式:add OPRD
    功能:OPRD = OPRD + 1
    舉例:
    inc eax;//得到的結果為eax = eax+1;
    

減法指令:sub,dec,cmp,當然還有和adc對應的sbb 這里講解下sub和dec

  • 1.sub
    格式:sub OPRD1,OPRD2
    功能:OPRD1 = OPRD1 - OPRD2
    舉例:
    sub eax ecx;//得到的結果為eax = eax - ecx;
    
  • 2.dec
    格式:dec OPRD
    功能:OPRD = OPRD - 1
    舉例:
    dec eax;//得到的結果為eax = eax - 1;
    
  • 3.cmp
    格式:cmp OPRD1,OPRD2
    功能:執行OPRD1 - OPRD2,但運算結果不運送到OPRD1
    注:該指令通過OPRD - OPRD2影響標志位CF、ZF、SF、OF、AF、PF來判斷OPRD1和OPRD2的大小關系。
    通過ZF判斷是否相等;如果是無符號數,通過CF可判斷大小;如果是有符號數,通過SF和OF判斷大小
    

3.邏輯運算和移位指令

1、邏輯運算指令:not、and、or、xor、test

  • (1) NOT:非運算
    格式:NOT OPRD
    功能:把操作數OPRD取反,然后送回OPRD。
    注:    OPRD可以是通用寄存器,也可以是存儲器操作數,此指令對標志沒有影響
    
  • (2) AND:與運算
    格式:AND OPRD1,OPRD2
    功能:對兩個操作數進行按位邏輯“與”運算,結果送到OPRD1中
    注: 該指令執行后,CF=0,OF=0,標志PF、ZF、SF反映運算結果,AF未定義。
    某個操作數與自身相與,值不變,但可以使CF置0。
    
  • (3) OR:或運算
    格式:OR OPRD1,OPRD2
    功能:對兩個操作數進行按位邏輯“或”運算,結果送到OPRD1中
    注: 該指令執行后,CF=0,OF=0,標志PF、ZF、SF反映運算結果,AF未定義。
    某個操作數與自身相或,值不變,但可以使CF置0。
    
  • (4) XOR:異或運算
    格式:XOR OPRD1,OPRD2
        功能:對兩個操作數進行按位邏輯“異或”運算,結果送到OPRD1中
    

2、一般移位指令:SAL/SHL,SAR/SHR

  • (1) SAL/SHL(Shift Arithmetic Left / Shift Logic Left);算術左移/邏輯左移
    格式:SAL OPRD,m
    SHL OPRD,m
    功能:把操作數OPRD左移m位,每移動一位,右邊用0補足1位,移出的最高位進入標志位CF
    注:    算術左移和邏輯左移進行相同的動作,為了方便提供了兩個助記符。
    
  • (2) SAR(Shift Arithmetic Right) ;算數右移指令
    格式:SAR OPRD,m
    功能:操作數右移m位,同時每移1位,左邊的符號位保持不變,移出的最低位進入標志位CF
    注:  對有符號數和無符號數,算數右移1位相當于除以2
    如:SAR BH,1 ;(BH)= 80H,指令執行后(BH)= C0H
    
  • (3) SHR(Shift Logic Right) ;邏輯右移指令
    格式:SHR OPRD,m
    功能:操作數右移m位,同時每移1位,左邊用0補足,移出的最低位進入標志位CF
    注:    對無符號數,邏輯右移1位相當于除以2
    如:SHR AH,1 ;(AH)= 80H,指令執行后(AH)= 40H
    

切記:算術移位和邏輯移位的區別:

對于左移不管是算術移位和邏輯移位,低位都補0; 對于右移的算術移位:對于有符號數,符號位不變,然后整體右移。

4.轉移指令

1、無條件轉移指令:JMP(Jump)

直接跳轉到Jump指定的地址, 跳轉指令也是改變當前eip的值來決定的 ,這樣下次取指令會去新的eip地址下取。

格式:JMP OPRD
功能:使控制指令無條件轉移到OPRD的內容給定的目標地址處。操作數OPRD可以是通用寄存器,也可以是字存儲單元
例如:
jmp cx                    ;CX寄存器的內容送IP
jmp word ptr [1234h]    ;字存儲單元[1234h]的內容送IP
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C++
    C++
    +關注

    關注

    22

    文章

    2108

    瀏覽量

    73632
  • 匯編代碼
    +關注

    關注

    0

    文章

    23

    瀏覽量

    7550
  • hacker
    +關注

    關注

    0

    文章

    4

    瀏覽量

    1362
收藏 人收藏

    評論

    相關推薦

    C++STL算法(二)

    C++STL算法(二)
    的頭像 發表于 07-18 14:49 ?1037次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>之</b>STL算法(二)

    c++STL算法(三)

    c++STL算法(三)
    的頭像 發表于 07-18 15:00 ?1280次閱讀
    <b class='flag-5'>c++</b><b class='flag-5'>之</b>STL算法(三)

    C++文件操作

    C++文件操作
    的頭像 發表于 07-21 10:52 ?1111次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>之</b>文件操作

    C++教程之函數的遞歸調用

    C++教程之函數的遞歸調用 在執行函數 f 的過程中,又要調用 f 函數本身,稱為函數的遞歸調用;形式
    發表于 05-15 18:00 ?35次下載

    C++課程資料詳細資料合集包括了:面向對象程序設計與C++,算法,函數

    本文檔的主要內容詳細介紹的是C++課程資料資料合集包括了:面向對象程序設計與C++,算法,函數,概述, C++語言基礎,構造數據類型,數據類型,C+
    發表于 07-09 08:00 ?18次下載
    <b class='flag-5'>C++</b>課程資料詳細資料合集包括了:面向對象程序設計與<b class='flag-5'>C++</b>,算法,<b class='flag-5'>函數</b>等

    如何在中斷C函數中調用C++

    之前,我們在單片機程序開發時都會面對中斷函數。眾所周知的,這個中斷函數肯定是要用C函數來定義的。我在用C++進行程序開發的時候就發現了一個需
    發表于 05-09 18:17 ?0次下載
    如何在中斷<b class='flag-5'>C</b><b class='flag-5'>函數</b>中調用<b class='flag-5'>C++</b>

    C++重載函數學習總結

    函數重載是c++c的一個重要升級;函數重載通過參數列表區分不同的同名函數;extern關鍵字能夠實現c
    的頭像 發表于 12-24 17:10 ?796次閱讀

    EE-128:C++中的DSP:從C++調用匯編類成員函數

    EE-128:C++中的DSP:從C++調用匯編類成員函數
    發表于 04-16 17:04 ?2次下載
    EE-128:<b class='flag-5'>C++</b>中的DSP:從<b class='flag-5'>C++</b>調用匯編類成員<b class='flag-5'>函數</b>

    C++基礎語法inline 內聯函數

    上節我們分析了C++基礎語法的const,static以及 this 指針,那么這節內容我們來看一下 inline 內聯函數吧! inline 內聯函數 特征 相當于把內聯函數里面的內
    的頭像 發表于 09-09 09:38 ?2148次閱讀

    C++ C語言函數查詢電子版下載

    C++ C語言函數查詢電子版下載
    發表于 01-18 10:15 ?0次下載

    深度解析C++中的虛函數

    函數作為C++的重要特性,讓人又愛又怕,愛它功能強大,但又怕駕馭不好,讓它反咬一口,今天我們用CPU的角度,撕掉語法的偽裝,重新認識一下虛函數。 虛函數
    的頭像 發表于 02-15 11:14 ?835次閱讀
    深度解析<b class='flag-5'>C++</b>中的虛<b class='flag-5'>函數</b>

    C++學習筆記c++的基本認識

    自這篇文章我們即將開始C++的奇幻之旅,其內容主要是讀C++ Primer的總結和筆記,有興趣可以找原版書看看,對于學習C++還是有很大幫助的。這篇文章將從一個經典的程序開始介紹C++
    的頭像 發表于 03-17 13:57 ?734次閱讀

    C/C++函數hack(下)

    首先來說下 什么是hackhack字面意思“ 非法入侵 ”,那么在C/C++中其實就是 使用反匯編查看C/
    的頭像 發表于 03-30 16:53 ?1209次閱讀
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b><b class='flag-5'>之</b><b class='flag-5'>函數</b><b class='flag-5'>體</b><b class='flag-5'>hack</b>(下)

    C++基礎知識函數1

    函數C++ 中的一個重要概念,它可以讓我們將一段代碼封裝起來,然后在需要的時候調用它。C++ 中的函數有以下幾個特點: * 函數
    的頭像 發表于 04-03 10:34 ?571次閱讀

    同樣是函數,在CC++中有什么區別

    同樣是函數,在 CC++ 中有什么區別? 第一個返回值。 C語言的函數可以不寫返回值類型,編譯器會默認為返回 int。 但是
    的頭像 發表于 11-29 10:25 ?285次閱讀
    主站蜘蛛池模板: 国语自产精品一区在线视频观看| 二级特黄绝大片免费视频大片| 69精品人妻一区二区三区蜜桃 | 18岁末年禁止观看免费1000个| 99re.05久久热最新地址| WRITEAS塞红酒瓶| 菲律宾毛片| 黄色三级网站在线观看| 啦啦啦视频在线观看WWW| 欧美性喷潮xxxx| 午夜不卡久久精品无码免费| 亚洲无AV在线中文字幕| 97人摸人人澡人人人超一碰| 成人免费在线观看视频| 国产人妻人伦精品1国产| 久在线观看福利视频| 人成午夜免费视频| 校花爽好大快深点h| 最近中文字幕高清中文| 调教玩弄奶头乳夹开乳震动器| 国内精品日本久久久久影院 | 97干97吻| 国产精品成人免费视频99| 久久精品一卡二卡三卡四卡视频版 | 51国产偷自视频在线视频播放 | 纯肉宠文高h一对一| 海角国精产品一区一区三区糖心| 蜜臀久久99精品久久久久久做爰| 三级中国免费的| 又黄又粗又爽免费观看| 粉嫩国产14xxxxx0000| 久久精品亚洲牛牛影视| 色综合a在线| 在线免费视频国产| 国产高清在线a视频大全| 美女全光末满18勿进| 无码人妻丰满熟妇啪啪网不卡| 365电影成人亚洲网在线观看| 国产成人综合95精品视频免费| 狼人射综合| 亚洲爆乳无码精品AAA片蜜桃|