欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python逆向入門(mén)教程

 更新時(shí)間:2018年01月15日 10:22:28   作者:aidear_evo  
這篇文章主要介紹了python逆向入門(mén)教程,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

1、開(kāi)發(fā)環(huán)境

我們?cè)赪indows 10上開(kāi)始python逆向之旅,首先開(kāi)始搭建開(kāi)發(fā)環(huán)境,python解釋器使用最新的3.6.1,IDE使用PyCharm社區(qū)版2017.1.3,下載地址如下所示,下載完成后直接雙擊安裝包安裝即可,隨后設(shè)置PyCharm的Project Interpreter為剛才安裝的Python解釋器就可以了。

【Python】https://www.python.org/downloads/
【PyCharm】http://www.jetbrains.com/pycharm/download/#section=windows

2、ctypes

首先介紹一下ctypes,它是一個(gè)用于Python的外部函數(shù)庫(kù),提供了與C語(yǔ)言兼容的數(shù)據(jù)類型,允許調(diào)用動(dòng)態(tài)鏈接庫(kù)或共享庫(kù)中的函數(shù),還可以包裝這些庫(kù)。下面是ctypes中的數(shù)據(jù)類型與C語(yǔ)言、Python中的數(shù)據(jù)類型的對(duì)應(yīng)關(guān)系。

ctypes中的數(shù)據(jù)類型全部通過(guò)class來(lái)實(shí)現(xiàn),在Python中加載C庫(kù)涉及如下幾個(gè)類。

  1. class ctypes.CDLL 加載共享庫(kù),使用標(biāo)準(zhǔn)C函數(shù)調(diào)用慣例即cdecl,返回類型為int。
  2. class ctypes.OleDLL 加載共享庫(kù),只用于Windows平臺(tái),使用stdcall函數(shù)調(diào)用慣例,返回類型為HRESULT。
  3. class ctypes.WinDLL 加載共享庫(kù),只用于Windows平臺(tái),使用stdcall函數(shù)調(diào)用慣例,返回類型為int。
  4. class ctypes.PyDLL 類似于CDLL,與前面三個(gè)不同的是,在函數(shù)調(diào)用期間不會(huì)釋放GIL,Global Interpreter Lock。
  5. class ctypes.LibraryLoader(dlltype) dlltype為CDLL、OleDLL、WinDLL、PyDLL,這個(gè)類有一個(gè)加載共享庫(kù)的函數(shù)LoadLibrary。

加載C庫(kù)更簡(jiǎn)單的方法是使用如下幾個(gè)預(yù)先創(chuàng)建的類實(shí)例。

ctypes.cdll
ctypes.oledll
ctypes.windll
ctypes.pydll
ctypes.pythonapi

上面提到了函數(shù)調(diào)用慣例cdecl和stdcall,cdecl的意思是函數(shù)的參數(shù)從右往左依次壓入棧內(nèi),函數(shù)的調(diào)用者在函數(shù)執(zhí)行完成之后負(fù)責(zé)函數(shù)的平衡,常用于X86架構(gòu)的C語(yǔ)言里,返回值存儲(chǔ)在EAX寄存器中,從匯編代碼的角度來(lái)看,函數(shù)參數(shù)從右往左依次壓棧,然后調(diào)用函數(shù),最后修改棧指針ESP為原來(lái)的位置。stdcall,參數(shù)傳遞的順序也是從右到左,不過(guò)棧的平衡處理由函數(shù)自己完成,而不是調(diào)用者,返回值同樣存儲(chǔ)在EAX中,也就是說(shuō),函數(shù)參數(shù)壓棧、函數(shù)調(diào)用之后沒(méi)有像cdecl一樣的棧指針ESP移動(dòng)。

下面的例子在Python中調(diào)用C的printf函數(shù),printf屬于“C:\Windows\System32\msvcrt.dll”,也就是Linux上的“l(fā)ibc.so”。

from ctypes import *

msvcrt = cdll.msvcrt
message = b"Hello World\n"
msvcrt.printf(b"Message is %s", message)

上面的代碼輸出“Message is Hello World”。另外,ctypes還允許在Python中定義結(jié)構(gòu)和聯(lián)合等其它高級(jí)功能,詳細(xì)介紹請(qǐng)參考https://docs.python.org/3.6/library/ctypes.html?highlight=ctypes#。

3、調(diào)試原理

使用調(diào)試器,能夠?qū)Τ绦蜻M(jìn)行動(dòng)態(tài)跟蹤和分析,特別是涉及到exploit、fuzzer和病毒分析的時(shí)候,動(dòng)態(tài)分析程序的能力就顯得非常重要了。調(diào)試程序時(shí),如果可以獲得源代碼,調(diào)試起來(lái)就容易一些,也就是透明的白盒測(cè)試,如果沒(méi)有源代碼,也就是黑盒測(cè)試,想要得到理想的結(jié)果,那就必須擁有高超的逆向技術(shù)和逆向工具的幫助。黑盒測(cè)試包括用戶模式與內(nèi)核模式兩種情況,兩者有不同的權(quán)限。

CPU的寄存器能夠?qū)ι倭康臄?shù)據(jù)進(jìn)行快速的存取訪問(wèn),在X86指令集里,一個(gè)CPU有八個(gè)通用寄存器:EAX、EDX、ECX、ESI、EDI、EBP、ESP和EBX,以及其它的寄存器,下面逐個(gè)介紹。
EAX:累加寄存器,除了用于存儲(chǔ)函數(shù)的返回值外也用于執(zhí)行計(jì)算的操作,許多優(yōu)化的X86指令集都專門(mén)設(shè)計(jì)了針對(duì)EAX寄存器的讀寫(xiě)和計(jì)算指令。

EDX:數(shù)據(jù)寄存器,本質(zhì)上是EAX寄存器的延伸,輔助EAX寄存器完成更多復(fù)雜的計(jì)算操作。
ECX:計(jì)數(shù)寄存器,用于循環(huán)操作,計(jì)算是向下而不是向上的,由大減到小。
ESI:Source Index,源操作數(shù)指針,存儲(chǔ)著輸入的數(shù)據(jù)流的位置,用于讀,高效地處理循環(huán)操作的數(shù)據(jù)。
EDI:Destination Index,目的操作數(shù)指針,存儲(chǔ)了計(jì)算結(jié)果存儲(chǔ)的位置,用于寫(xiě),高效地處理循環(huán)操作的數(shù)據(jù)。
ESP:Stack Pointer,棧指針,負(fù)責(zé)函數(shù)的調(diào)用和棧的操作,函數(shù)調(diào)用時(shí)壓棧參數(shù)和返回地址,指向棧頂即返回地址。
EBP:Base Pointer,基指針,負(fù)責(zé)函數(shù)的調(diào)用和棧的操作,函數(shù)調(diào)用時(shí)壓棧參數(shù)和返回地址,指向棧底。
EBX:唯一一個(gè)沒(méi)有特殊用途的寄存器,作為額外的數(shù)據(jù)存儲(chǔ)器。
EIP:Instruction Pointer,指令指針,總是指向馬上要執(zhí)行的指令。

熟悉調(diào)試器的朋友們都知道斷點(diǎn),斷點(diǎn)其實(shí)就是一個(gè)調(diào)試事件,其它事件如經(jīng)典的段錯(cuò)誤(Segment Fault)等。斷點(diǎn)包括軟件斷點(diǎn)、硬件斷點(diǎn)和內(nèi)存斷點(diǎn),用于暫停被執(zhí)行程序。

軟件斷點(diǎn):一個(gè)單字節(jié)的指令,將控制權(quán)轉(zhuǎn)移給調(diào)試器的斷點(diǎn)處理函數(shù)。匯編指令是CPU執(zhí)行的指令的高級(jí)表示方法,如下面的匯編指令MOV EAX, EBX,告訴CPU把存儲(chǔ)在EBX寄存器里的東西放到EAX寄存器,然而CPU并不明白這個(gè)匯編指令,必須轉(zhuǎn)化為能夠讓CPU識(shí)別的操作碼8BC3,假設(shè)這一操作發(fā)生在地址0x44332211,為了在這個(gè)地址設(shè)置斷點(diǎn),暫停CPU,需要從2個(gè)字節(jié)的操作碼8BC3中換出一個(gè)單字節(jié)的操作碼,這個(gè)單字節(jié)的操作碼也就是3號(hào)中斷指令,INT3,一條能讓CPU暫停的指令,對(duì)應(yīng)的操作碼為0xCC,具體如下面的代碼片段所示。當(dāng)調(diào)試器被告知在目標(biāo)地址設(shè)置一個(gè)斷點(diǎn)時(shí),它首先讀取目標(biāo)地址的第一個(gè)字節(jié)的操作碼然后保存起來(lái),同時(shí)把地址存儲(chǔ)在內(nèi)部的中斷列表中,接著,調(diào)試器把3號(hào)中斷指令對(duì)應(yīng)的操作碼0xCC寫(xiě)到剛才的地址,當(dāng)CPU執(zhí)行到替換后的操作碼的時(shí)候,CPU暫停,并觸發(fā)一個(gè)INT3事件,此時(shí)調(diào)試器就能捕捉到這個(gè)事件,然后調(diào)試器通過(guò)EIP判斷這個(gè)中斷地址是否是我們?cè)O(shè)置的斷點(diǎn),如果是,就把對(duì)應(yīng)的操作碼寫(xiě)回以恢復(fù)程序的正常運(yùn)行。軟件斷點(diǎn)包括一次性斷點(diǎn)和持續(xù)性斷點(diǎn),前者生效一次,后者一直生效,不生效后將其從中斷列表移除。需要注意的是,當(dāng)我們改變了被調(diào)試程序的內(nèi)存數(shù)據(jù)時(shí),同時(shí)改變了運(yùn)行時(shí)軟件的CRC即循環(huán)冗余代碼校驗(yàn)和,CRC是一種校驗(yàn)數(shù)據(jù)是否被改變的機(jī)制,廣泛應(yīng)用于文件、內(nèi)存、文本、網(wǎng)絡(luò)數(shù)據(jù)包等任何想監(jiān)視數(shù)據(jù)的地方,它將一定范圍內(nèi)的數(shù)據(jù)進(jìn)行hash計(jì)算,然后將hash值同此前的hash值進(jìn)行比較,判斷數(shù)據(jù)是否改變,為了在這種特殊的情況下也能調(diào)試程序,就要使用下面介紹的硬件斷點(diǎn)了。

地址: 操作碼 匯編指令
0x44332211: 8BC3 MOV EAX, EBX
0x44332211: CCC3 MOV EAX, EBX

硬件斷點(diǎn):在小塊區(qū)域內(nèi)設(shè)置斷點(diǎn),屬于CPU級(jí)別,使用了DR0到DR7共八個(gè)特殊的調(diào)試寄存器,這些寄存器專門(mén)用于管理硬件斷點(diǎn)。DR0到DR3存儲(chǔ)硬件斷點(diǎn)地址,意味著同一時(shí)間內(nèi)最多只能有4個(gè)硬件斷點(diǎn),DR4和DR5保留,DR6是狀態(tài)寄存器,說(shuō)明被斷點(diǎn)觸發(fā)的調(diào)試事件的類型,DR7是開(kāi)關(guān)寄存器,同時(shí)也存儲(chǔ)了斷點(diǎn)的不同類型,包括指令執(zhí)行時(shí)中斷、數(shù)據(jù)可以寫(xiě)入時(shí)中斷、有數(shù)據(jù)讀或者寫(xiě)但不執(zhí)行時(shí)中斷。硬件斷點(diǎn)使用1號(hào)中斷指令I(lǐng)NT1,負(fù)責(zé)硬件中斷和步進(jìn)事件。硬件斷點(diǎn)的特點(diǎn)是同一時(shí)間只能設(shè)置四個(gè)斷點(diǎn),而且斷點(diǎn)起作用的區(qū)域只有四個(gè)字節(jié),如果想要跟蹤一大塊內(nèi)存數(shù)據(jù),請(qǐng)使用下面介紹的內(nèi)存斷點(diǎn)。

內(nèi)存斷點(diǎn):用于大塊區(qū)域,不是真正的斷點(diǎn),而是改變了內(nèi)存中某個(gè)塊或者頁(yè)的權(quán)限。一個(gè)內(nèi)存頁(yè)是操作系統(tǒng)處理的最小的內(nèi)存單位,一個(gè)內(nèi)存頁(yè)被申請(qǐng)成功后,就擁有了一個(gè)權(quán)限集,如可執(zhí)行頁(yè)、可讀頁(yè)、可寫(xiě)頁(yè),這些決定了內(nèi)存該如何被訪問(wèn),任何對(duì)保護(hù)頁(yè)的訪問(wèn)都會(huì)引發(fā)異常,之后頁(yè)面恢復(fù)訪問(wèn)前的狀態(tài)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論