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

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

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

3天內不再提示

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

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

2、條件轉移指令

指令的匯編格式及功能根據條件碼的值轉移:

ja 大于時跳轉
jae 大于等于
jb 小于
jbe 小于等于
je 相等
jna 不大于
jnae 不大于或者等于
jnb 不小于
jnbe 不小于或等于
jne 不等于
jg 大于(有符號)
jge 大于等于(有符號)
jl 小于(有符號)
jle 小于等于(有符號)
jng 不大于(有符號)
jnge 不大于等于(有符號)
jnl 不小于
jnle 不小于等于
jns 無符號
jnz 非零
js 如果帶符號
jz 如果為零

例子:

mov eax, 1
    cmp eax, 100
    jle xiao_deng_yu_100
    sub eax, 20

xiao_deng_yu_100:
    add eax, 1
    ret

這個例子中就是讓eax中存儲的值和100比較,如果小于等于則跳轉到xiao_deng_yu_100處。 從這個例子也可以看出:

    1. 條件轉移一般會和cmp比較指令配合使用,因為比較指令會改變狀態寄存器中的標志位,而jle等跳轉指令回去狀態寄存器中讀取這些標志位
  • 2.跳轉指令不會返回到原來的指令地址處,后面講解函數跳轉的時候可以看到會返回到原來的指令地址處,根據返回地址。

條件跳轉指令這么多,怎么記住呢?這里面是有套路的: 首先,跳轉指令的前面都是字母j,關鍵是j后面的的字母,比如j后面是ne,對應的是jne跳轉指令,n和e分別對應not和equal,也就是“不相等”,也就是說在比較指令的結果為“不想等”的時候,就會跳轉。

a: above
e: equal
b: below
n: not
g: greater
l: lower
s: signed
z: zero

好了,這里列出來了j后面的字母所對應的含義。根據這些字母的組合,和上述大概的規則,你就能清楚怎么寫出這些跳轉指令了。當然,這里有“有符號”和“無符號”之分,后面有機會再扯,讀者也可以自行了解。

5.堆棧操作指令

我們知道,在一個函數作用域中會使用到一些寄存器,如果在這個函數中又調用了另外一個函數,那這些寄存器信息可能會被覆蓋掉,怎么辦呢? 首先CPU會在內存中開辟一塊空間,叫棧空間,CPU將這些寄存器壓入到棧中,叫入棧,待另外一個函數返回時,再將當前棧中的信息恢復回來,叫出棧。

1.入棧指令push

格式:push src
功能: 把數據src壓入到棧中
注意:src可以是寄存器或者內存中的數據。

2.出棧指令pop

格式:pop dst
功能: 把數據彈出到到棧中
注意:dst可以是通用寄存器和段寄存器,但不能是CS,可以是字存儲單元。

6.函數調用跳轉指令

格式:call   標號
功能:跳轉到另外一個函數去執行。

舉例:

eax_plus_1s:
    add eax, 1
    ret
main:
    mov eax, 0
    call eax_plus_1s
    ret

這里的eax_plus_1s就是一個函數,使用call跳轉

call方法執行之前CPU還會做一個動作,就是將當前eip保存起來,然后再去跳轉,這是為了函數執行完成后可以找到回來執行的地址。

好了。有了以上基礎后,我們再來看C/C++中的hack環節。

hack

那我們就拿前面的舉得例子來講解下hack過程

1.前增++i和后增i++

我們打開vs中輸入下面一段代碼:

int  main()
{
    int a = 0;
    int b = ++a;
    return 0;
}

如何反匯編呢, 在main的兩個括號{}處打兩個斷點,然后執行程序,右擊選擇反匯編 。 得到的反匯編代碼如下:

int  main()
//段1:初始化
{
001947C0  push        ebp  
001947C1  mov         ebp,esp  
001947C3  sub         esp,0D8h  
001947C9  push        ebx  
001947CA  push        esi  
001947CB  push        edi  
001947CC  lea         edi,[ebp-18h]  
001947CF  mov         ecx,6  
001947D4  mov         eax,0CCCCCCCCh  
001947D9  rep stos    dword ptr es:[edi]  
001947DB  mov         ecx,offset _BCEF6C65_20221229-demo-cAndCpp@cpp (01A8052h)  
001947E0  call        @__CheckForDebuggerJustMyCode@4 (0173F1Eh)  
//段2:
    int a = 0;
001947E5  mov         dword ptr [a],0  
    int b = ++a;
001947EC  mov         eax,dword ptr [a]  
001947EF  add         eax,1  
001947F2  mov         dword ptr [a],eax  
001947F5  mov         ecx,dword ptr [a]  
001947F8  mov         dword ptr [b],ecx  
    return 0;
001947FB  xor         eax,eax  
//段3:反初始化
}
001947FD  pop         edi  
001947FE  pop         esi  
001947FF  pop         ebx  
00194800  add         esp,0D8h  
00194806  cmp         ebp,esp  
00194808  call        __RTC_CheckEsp (0173AC8h)  
0019480D  mov         esp,ebp  
0019480F  pop         ebp  
00194810  ret

這段匯編代碼怎么讀呢?由于main方法中沒有其他函數調用,所以CPU會按順序執行這段代碼。 我們將代碼分為3段: 段1:首先來看前面這段代碼:

001947C0  push        ebp  
001947C1  mov         ebp,esp  
001947C3  sub         esp,0D8h  
001947C9  push        ebx  
001947CA  push        esi  
001947CB  push        edi  
001947CC  lea         edi,[ebp-18h]  
001947CF  mov         ecx,6  
001947D4  mov         eax,0CCCCCCCCh  
001947D9  rep stos    dword ptr es:[edi]  
001947DB  mov         ecx,offset _BCEF6C65_20221229-demo-cAndCpp@cpp (01A8052h)  
001947E0  call        @__CheckForDebuggerJustMyCode@4 (0173F1Eh)

這段代碼不用管太多,只是對函數棧的一個初始化的操作,ebp指向棧底,esp指向棧底,還有一些就是當前棧的基地址,返回地址等等信息。因為函數中可能還會調用函數,所以每個函數調用都會有自己的棧,也叫函數的棧幀,函數的深度就代表棧深,但是CPU中的寄存器又是共享的,函數a在使用這些寄存器的時候,函數b又要使用了,那怎么辦?方法就是 將寄存器中的數值壓入棧幀中保存起來,等函數b結束后,再從棧幀中恢復起來就好了

下面看重點代碼:

段2:
    int a = 0;
001947E5  mov         dword ptr [a],0  //1
    int b = ++a;
001947EC  mov         eax,dword ptr [a]  //2
001947EF  add         eax,1  //3
001947F2  mov         dword ptr [a],eax  //4
001947F5  mov         ecx,dword ptr [a]  //5
001947F8  mov         dword ptr [b],ecx  //6
    return 0;
001947FB  xor         eax,eax  //7

分析:

  • 1.mov指令將0賦值到內存中的一個a變量地址中。
  • 2.mov指令將變量a地址中的值賦值給eax,此時eax變為0.
  • 3.add指令給eax+1,此時eax變為了1.
  • 4.mov指令將eax的值傳遞到變量a中,此時a變為了1.
  • 5.mov指令將a中的值傳遞給寄存器ecx,此時ecx值變為1.
  • 6.mov指令將ecx的值傳遞給變量b地址,這樣b就變為了1。

以上過程需要注意點:

a的值變化是在b的值變化之前,所以++a是先a+1,然后再將a+1賦值給b。

下面我們再來看下這段代碼:

int  main()
{
    int a = 0;
    int b = a++;
    return 0;
}

反匯編后:同樣找到關鍵代碼:

int a = 0;
00AB47E5  mov         dword ptr [a],0  //1
    int b = a++;
00AB47EC  mov         eax,dword ptr [a]  //2
00AB47EF  mov         dword ptr [b],eax  //3
00AB47F2  mov         ecx,dword ptr [a]  //4
00AB47F5  add         ecx,1  //5
00AB47F8  mov         dword ptr [a],ecx  //6
    return 0;
00AB47FB  xor         eax,eax  
}

分析:

  • 1.給a賦值為0
  • 2.將a傳遞給eax,此時eax變為了0
  • 3.將eax傳遞給b,此時b變為了0
  • 4.將a值傳遞給ecx,此時ecx變為了0
  • 5.給ecx+1,此時ecx變為了1
  • 6.將ecx值傳遞給a,此時a變為了1

這個過程可以看到CPU是先賦值給b,然后再讓a進行+1的操作。

通過對a++和++a的分析,也可以看到hack可以讓我們了解底層是如何執行我們寫的代碼的。

下面我們再來看一個函數調用過程:

2.函數體hack過程

int maxab(int a,int b) {
    return a > b ? a : b;
}
int  main()
{
    maxab(3, 4);
    return 0;
}

反匯編后:

maxab(3, 4);
00A347E5  push        4  //1
00A347E7  push        3  //2
00A347E9  call        maxab (0A13794h)  //3

00A347EE  add         esp,8  //4


int maxab(int a,int b) { 
    return a > b ? a : b;
00A32685  mov         eax,dword ptr [a]  //5
00A32688  cmp         eax,dword ptr [b]  //6
00A3268B  jle         __$EncStackInitStart+2Ch (0A32698h)  //7
00A3268D  mov         ecx,dword ptr [a]  //8
00A32690  mov         dword ptr [ebp-0C4h],ecx  //9
00A32696  jmp         __$EncStackInitStart+35h (0A326A1h)  //10
00A32698  mov         edx,dword ptr [b]  //11
00A3269B  mov         dword ptr [ebp-0C4h],edx  //12
00A326A1  mov         eax,dword ptr [ebp-0C4h]  //13
}

分析:

  • 1和2處將立即數4和3壓入到棧內。注意他是先push的右邊參數4,再push的左邊參數3。
  • 3處調用call跳轉到maxab函數處,注意5處以后這個時候是處于另外一個函數棧內了。
  • 5處將變量a的值3傳遞給eax,a的值是怎么得到的呢?看前面壓棧操作是先壓入右邊再壓入左邊,根據FILO規則,此時先找到的參數就是先出左邊3,再出右邊4.
  • 6處讓eax也就是前面的a的值和b的值進行比較,比較結果會寫入到狀態寄存器中。
  • 7處的jle是小余等于就跳轉,這個比較結果是在狀態寄存器中獲取到的,a是3,b是4,所以結果就是小余咯。條件成功跳轉到指定的0A32698h位置。0A32698h指向11處:00A32698 mov edx,dword ptr [b] //11
  • 11處使用mov指令將b中的值傳遞給edx。
  • 然后在12處將edx存入到ebp-0C4h位置,ebp是棧底,根據棧的特點,ebp-C4H其實是一個往棧頂走的一個操作,如果你觀察仔細,可以看到其實就是棧頂。
  • 最終在13處將ebp-0C4h處的值傳遞給eax,最終返回eax。 前面也說過所有函數都使用eax進行返回。

上面講解了一個max函數的hack過程,如果你對hack過程還比較模糊,還可以使用vs提供的 內存監視器查看具體內存變化

圖片

好了,關于函數的hack分析過程就這里了,大部分操作其實還是要理解匯編一些基本指令以及CPU和內存,棧的模型等。

總結

本篇文章主要講解了hack的定義以及hack過程中需要了解的幾個基本知識: 如 寄存器,內存,CPU以及一些基本匯編指令 。并使用兩個例子來講解如何在C/C++中進行hack的過程。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 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++文件操作

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

    C++筆記004:C++類通俗點說—— C結構復習

    ` 本帖最后由 tyyhmtyyhm 于 2018-5-12 09:37 編輯 C++類通俗點說—— C結構復習核心:C++的類就是對C
    發表于 03-05 12:53

    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:54 ?901次閱讀
    <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次閱讀

    C++生成Dll與回調函數測試

    描述了VS環境,通過C++生成dll的方法,測試回調函數
    的頭像 發表于 08-29 16:05 ?1614次閱讀
    <b class='flag-5'>C++</b>生成Dll與回調<b class='flag-5'>函數</b>測試

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

    同樣是函數,在 CC++ 中有什么區別? 第一個返回值。 C語言的函數可以不寫返回值類型,編譯器會默認為返回 int。 但是
    的頭像 發表于 11-29 10:25 ?285次閱讀
    主站蜘蛛池模板: 老司机亚洲精品影院| 成人片在线播放| 亚洲在线视频自拍精品| 向日葵视频app下载18岁以下勿看| 情欲.美女高潮| 人人爽久久久噜噜噜丁香AV| 欧美18在线| 女人高潮了拔出来了她什么感觉| 蜜臀AV久久国产午夜福利软件| 久久中文字幕人妻AV熟女| 久草精品在线| 久久久免费观成人影院| 久久黄色小视频| 老女老肥熟国产在线视频| 两个洞一起插哦!好刺激| 免费亚洲视频| 欧美精品高潮呻吟AV久久 | 亚洲午夜精品A片久久软件| 亚洲AV怡红院影院怡春院| 亚洲精品中文字幕制| 亚洲在线中文无码首页| 一级做a爰片久久毛片苍井优| 伊人青青草| 97在线视频免费观看97| chinese耄耋70老太性| 大胸美女裸身色诱网站| 国产精品高清在线观看地址| 国产乱人精品视频AV麻豆| 狠狠色狠狠色88综合日日91| 久久久久久久国产精品视频| 免费看国产曰批40分钟| 全黄h全肉细节全文| 天天国产在线精品亚洲| 亚洲免费在线视频观看| 在线亚洲97se| 把内衣脱了把奶露出来| 国产高清亚洲日韩字幕一区| 精品一区二区三区AV天堂| 免费毛片在线播放| 神马电影院午 夜理论| 亚洲精品高清在线|