日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

软件调试基础

發(fā)布時(shí)間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 软件调试基础 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • PE文件格式
    • 文件格式
    • 加殼
  • 虛擬內(nèi)存
    • Windows安全模式
    • 虛擬內(nèi)存
    • 進(jìn)程空間
    • PE文件和虛擬內(nèi)存的映射
      • 基本概念
      • 映射關(guān)系
    • LordPE
      • 查看導(dǎo)入表信息
      • IAT表信息
    • PEView
  • 調(diào)試分析工具
    • OllyDbg
      • 基本調(diào)試方法
      • 快捷鍵
      • 跟蹤
    • IDA PRO
      • 反匯編窗口
      • 其它窗口
  • PE文件代碼注入示例
    • 演示內(nèi)容及實(shí)驗(yàn)環(huán)境
      • 用OllyDBG打開掃雷程序
      • 在空白代碼區(qū)編寫要注入的代碼
    • 編輯和注入代碼
      • Message函數(shù)
      • 構(gòu)造相關(guān)字符串
      • 構(gòu)造函數(shù)調(diào)用的代碼
    • 掛接代碼及完成跳轉(zhuǎn)
      • 掛接代碼
      • 保存修改
      • 修改程序入口點(diǎn)完成跳轉(zhuǎn)
  • 軟件破解示例
    • 使用OllyDBG破解
      • 破解方式一:修改分支語句
      • 破解方式二:修改函數(shù)返回值
  • 總結(jié)


PE文件格式

文件格式

可執(zhí)行文件之所以可以被操作系統(tǒng)加載且運(yùn)行,是因?yàn)樗鼈冏裱嗤囊?guī)范。PE(Portable Executable)是Win32平臺(tái)下可執(zhí)行文件遵守的數(shù)據(jù)格式。常見的可執(zhí)行文件(.exe文件和.dll文件)都是典型的PE文件。

一個(gè)可執(zhí)行文件不光包含了二進(jìn)制機(jī)器碼,還會(huì)自帶許多其他信息,如字符串、菜單、圖標(biāo)、位圖、字體等。PE文件格式規(guī)定了所有的這些信息在可執(zhí)行文件中如何組織。在程序被執(zhí)行時(shí),操作系統(tǒng)會(huì)按照PE文件格式的約定去相應(yīng)的地方準(zhǔn)確地定位各種類型的資源,并分別裝入內(nèi)存的不同區(qū)域。

PE文件格式把可執(zhí)行文件分成若干個(gè)數(shù)據(jù)節(jié)(section),不同的資源被存放在不同的節(jié)中。一個(gè)典型的PE文件中包含的節(jié)如下:

  • rsrc

    存放程序的資源,如圖標(biāo)、菜單等。

  • text

    由編譯器產(chǎn)生,存放著二進(jìn)制的機(jī)器代碼,也是我們反匯編和調(diào)試的對(duì)象。

  • idata

    可執(zhí)行文件所使用的動(dòng)態(tài)鏈接庫等外來函數(shù)與文件的信息, 即輸入表

  • data

    初始化的數(shù)據(jù)塊,如宏定義、全局變量、靜態(tài)變量等。

如果是正常編譯出的標(biāo)準(zhǔn)PE文件,其節(jié)信息往往是大致相同的。但這些section的名字只是為了方便人的記憶與使用,使用Microsoft Visual C++中的編譯指示符:
#pragma data_seg()
可以把代碼中的任意部分編譯到PE的任意節(jié)中,節(jié)名也可以自己定義,如果可執(zhí)行文件經(jīng)過了“加殼”處理,PE的節(jié)信息就會(huì)變得非常“古怪”。在Crack和反病毒分析中需要經(jīng)常處理這類古怪的PE文件。

加殼

全稱應(yīng)該是可執(zhí)行程序資源壓縮,是保護(hù)文件的常用手段。 加殼過的程序可以直接運(yùn)行,但是不能查看源代碼。要經(jīng)過脫殼才可以查看源代碼。

加殼其實(shí)是利用特殊的算法,對(duì)EXE、DLL文件里的代碼、資源進(jìn)行壓縮、加密。類似WINZIP 的效果,只不過這個(gè)壓縮之后的文件,可以獨(dú)立運(yùn)行。附加在原程序上的解壓程序通過Windows加載器載入內(nèi)存后,先于原始程序執(zhí)行,得到控制權(quán),執(zhí)行過程中對(duì)原始程序進(jìn)行解密、還原,還原完成后再把控制權(quán)交還給原始程序,執(zhí)行原來的代碼部分。

加上外殼后,原始程序代碼在磁盤文件中一般是以加密后的形式存在只在執(zhí)行時(shí)在內(nèi)存中還原,這樣就可以比較有效地防止對(duì)程序文件的非法修改和靜態(tài)反編譯

加殼工具通常分為壓縮殼和加密殼兩類。

  • 壓縮殼的特點(diǎn)是減小軟件體積大小,加密保護(hù)不是重點(diǎn)。
  • 加密殼種類比較多,不同的殼側(cè)重點(diǎn)不同,一些殼單純保護(hù)程序,另一些殼提供額外的功能,如提供注冊(cè)機(jī)制、使用次數(shù)、時(shí)間限制等。

虛擬內(nèi)存

Windows安全模式

為了防止用戶程序訪問并篡改操作系統(tǒng)的關(guān)鍵部分,Windows使用了2種處理器存取模式:用戶模式和內(nèi)核模式。用戶程序運(yùn)行在用戶模式,而操作系統(tǒng)代碼(如系統(tǒng)服務(wù)和設(shè)備驅(qū)動(dòng)程序)則運(yùn)行在內(nèi)核模式。在內(nèi)核模式下程序可以訪問所有的內(nèi)存和硬件,并使用所有的處理器指令。操作系統(tǒng)程序比用戶程序有更高的權(quán)限,使得系統(tǒng)設(shè)計(jì)者可以確保用戶程序不會(huì)意外的破壞系統(tǒng)的穩(wěn)定性。

虛擬內(nèi)存

Windows的內(nèi)存可以被分為兩個(gè)層面:物理內(nèi)存和虛擬內(nèi)存。其中,物理內(nèi)存非常復(fù)雜,需要進(jìn)入Windows內(nèi)核級(jí)別ring0才能看到。通常,在用戶模式下,用調(diào)試器看到的內(nèi)存地址都是虛擬內(nèi)存。

用戶編制程序時(shí)使用的地址稱為虛擬地址或邏輯地址,其對(duì)應(yīng)的存儲(chǔ)空間稱為虛擬內(nèi)存或邏輯地址空間;而計(jì)算機(jī)物理內(nèi)存的訪問地址則稱為實(shí)地址或物理地址,其對(duì)應(yīng)的存儲(chǔ)空間稱為物理存儲(chǔ)空間或主存空間。程序進(jìn)行虛地址到實(shí)地址轉(zhuǎn)換的過程稱為程序的再定位。

進(jìn)程空間

在Windows系統(tǒng)中,在運(yùn)行PE文件時(shí),操作系統(tǒng)會(huì)自動(dòng)加載該文件到內(nèi)存,并為其映射出4GB的虛擬存儲(chǔ)空間,然后繼續(xù)運(yùn)行,這就形成了所謂的進(jìn)程空間。用戶的PE文件被操作系統(tǒng)加載進(jìn)內(nèi)存后,PE對(duì)應(yīng)的進(jìn)程支配了自己獨(dú)立的4GB虛擬空間。在這個(gè)空間中定位的地址稱為虛擬內(nèi)存地址(Virtual Address,VA)。
到了現(xiàn)在,系統(tǒng)運(yùn)行在X64架構(gòu)的硬件上,可訪問的內(nèi)存也突破了以前4GB的限制,但是獨(dú)立的進(jìn)程擁有獨(dú)立的虛擬地址空間的內(nèi)存管理機(jī)制還在沿用。

PE文件和虛擬內(nèi)存的映射

在調(diào)試漏洞時(shí),可能經(jīng)常需要做這樣兩種操作:

  • 靜態(tài)反匯編工具看到的PE文件中某條指令的位置是相對(duì)于磁盤文件而言的,即所謂的文件偏移,我們可能還需要知道這條指令在內(nèi)存中所處的位置,即虛擬內(nèi)存地址。
  • 反之,在調(diào)試時(shí)看到的某條指令的地址是虛擬內(nèi)存地址,我們也經(jīng)常需要回到PE文件中找到這條指令對(duì)應(yīng)的機(jī)器碼。

基本概念

相對(duì)虛擬地址(RVA)

相對(duì)虛擬地址是內(nèi)存地址相對(duì)于映射基址的偏移量。

虛擬內(nèi)存地址(VA)

PE文件中的指令被裝入內(nèi)存后的地址。

文件偏移地址(File Offset)

數(shù)據(jù)在PE文件中的地址叫文件偏移地址,這是文件在磁盤上存放時(shí)相對(duì)于文件開頭的偏移。

裝載基址(Image Base)

PE裝入內(nèi)存時(shí)的基地址。默認(rèn)情況下,EXE文件在內(nèi)存中的基地址是0x00400000,DLL文件是0x10000000。
這些位置可以通過修改編譯選項(xiàng)更改。

映射關(guān)系

VA=Image Base+RVA

由于文件數(shù)據(jù)的存放單位與內(nèi)存數(shù)據(jù)存放單位不同而造成一些差異:

  • PE文件中的數(shù)據(jù)按照磁盤數(shù)據(jù)標(biāo)準(zhǔn)存放,以0x200字節(jié)為基本單位進(jìn)行組織。當(dāng)一個(gè)數(shù)據(jù)節(jié)(section)不足0x200字節(jié)時(shí),不足的地方將被0x00填充:當(dāng)一個(gè)數(shù)據(jù)節(jié)超過0x200字節(jié)時(shí),下一個(gè)0x200塊將分配給這個(gè)節(jié)使用。因此PE數(shù)據(jù)節(jié)的大小永遠(yuǎn)是0x200的整數(shù)倍。
  • 當(dāng)代碼裝入內(nèi)存后,將按照內(nèi)存數(shù)據(jù)標(biāo)準(zhǔn)存放,并以0x1000字節(jié)為基本單位進(jìn)行組織。類似的,不足將被補(bǔ)全,若超出將分配下一個(gè)0x1000為其所用。因此,內(nèi)存中的節(jié)總是0x1000的整數(shù)倍。

LordPE

LordPE是一款功能強(qiáng)大的PE文件分析、修改、脫殼軟件。LordPE是查看PE格式文件信息的首選工具,并且可以修改相關(guān)信息。

VOffset是RVA(相對(duì)虛擬地址),ROffset是文件偏移。也就是,在系統(tǒng)進(jìn)程中,代碼(.text節(jié))將被加載到0x400000+0x11000=0x411000的虛擬地址中(裝載基址+RVA)。而在文件中,可以使用二進(jìn)制文件打開,看到對(duì)應(yīng)的代碼在0x1000位置處。

查看導(dǎo)入表信息

導(dǎo)入表在文件里的偏移地址ROffset為0x24000,RVA是0x25000。打開目錄表可以看到,可以看到輸入表的RVA確實(shí)是0x25000。點(diǎn)左側(cè)按鈕L可以查看具體輸入表里的內(nèi)容。

IAT表信息

IAT(Import Address Table:輸入函數(shù)地址表)

每個(gè)API函數(shù)在對(duì)應(yīng)的進(jìn)程空間中都有其相應(yīng)的入口地址。眾所周知,操作系統(tǒng)動(dòng)態(tài)庫版本的更新,其包含的API函數(shù)入口地址通常也會(huì)改變。由于入口地址的不確定性,程序在不同的電腦上很有可能會(huì)出錯(cuò),為了解決程序的兼容問題,操作系統(tǒng)就必須提供一些措施來確保程序可以在其他版本的Windows操作系統(tǒng),以及DLL版本下也能正常運(yùn)行。這時(shí)IAT表就應(yīng)運(yùn)而生了。

基于導(dǎo)入表可以定位IAT的具體信息,相關(guān)工具可以幫助直接查看IAT表的相關(guān)內(nèi)容。

PEView

直觀顯示PE文件內(nèi)容


調(diào)試分析工具

OllyDbg

是一種具有可視化界面的 32 位匯編—分析調(diào)試器,適合動(dòng)態(tài)調(diào)試。 OllyDBG版的發(fā)布版本是個(gè)ZIP 壓縮包,解壓就可以使用了。

基本調(diào)試方法

OllyDBG 有兩種方式來載入程序進(jìn)行調(diào)試

  • 一種是點(diǎn)擊菜單文件,打開(快捷鍵是F3)來打開可執(zhí)行文件進(jìn)行調(diào)試
  • 另一種是點(diǎn)擊菜單文件,附加到一個(gè)己運(yùn)行的進(jìn)程上進(jìn)行調(diào)試,要附加的程序必須己運(yùn)行。

快捷鍵

  • F2設(shè)置斷點(diǎn)。
  • F7單步步入。功能同單步步過(F8)類似,區(qū)別是遇到 CALL 等子程序時(shí)會(huì)進(jìn)入其中,進(jìn)入后首先會(huì)停留在子程序的第一條指令上。
  • F8單步步過。執(zhí)行一條指令,遇到 CALL 等子程序不進(jìn)入其代碼。
  • F4運(yùn)行到選定位置。
  • F9運(yùn)行
  • CTR+F9執(zhí)行到返回。此命令在執(zhí)行到一個(gè)ret(返回指令)指令時(shí)暫停,常用于從系統(tǒng)領(lǐng)空返回到我們調(diào)試的程序領(lǐng)空。
  • ALT+F9執(zhí)行到用戶代碼。可用于從系統(tǒng)領(lǐng)空快速返回到我們調(diào)試的程序領(lǐng)空。

跟蹤

使用調(diào)試功能時(shí)通常會(huì)碰到在斷點(diǎn)處無法定位入口的情況,即無法確定前序執(zhí)行指令,通過Trace(跟蹤)功能可以記錄調(diào)試過程中執(zhí)行的指令,用于分析前序執(zhí)行指令。Trace記錄可選擇是否記錄寄存器的值。

IDA PRO

簡(jiǎn)稱IDA(Interactive Disassembler),是一個(gè)世界頂級(jí)的交互式反匯編工具,是逆向分析的主流工具。

IDA使用File菜單中的Open選項(xiàng),可以打開一個(gè)計(jì)劃逆向分析的可執(zhí)行文件,打開的過程是需要耗費(fèi)一些時(shí)間的。IDA會(huì)對(duì)可執(zhí)行文件進(jìn)行分析。一旦打開成功,會(huì)提示你是否進(jìn)入Proximity view。通常都會(huì)點(diǎn)Yes,按默認(rèn)選項(xiàng)進(jìn)入。

反匯編窗口

也叫IDA-View窗口,是操作和分析二進(jìn)制文件的主要工具。
反匯編窗口有三種顯示格式:

  • 面向文本的列表視圖(Text view)
  • 基于圖形的視圖(Graphic View)
  • 優(yōu)化視圖(Proximity view)將顯示函數(shù)及其調(diào)用關(guān)系

視圖間可以切換:在上圖的Proximity view視圖中,點(diǎn)選一個(gè)塊,比如_main函數(shù)塊,在其上點(diǎn)右鍵,可以看到Text view和Graph view等選項(xiàng)。通過右鍵可以實(shí)現(xiàn)不同視圖的切換。

圖形視圖:將一個(gè)函數(shù)分解為許多基本塊,類似程序流程圖類似,生動(dòng)的顯示該函數(shù)由一個(gè)塊到另一個(gè)塊的控制流程。
如下圖所示的_main函數(shù)的圖形視圖:

文本視圖:文本視圖則呈現(xiàn)一個(gè)程序的完整反匯編代碼清單(而在圖形模式下一次只能顯示一個(gè)函數(shù)),用戶只有通過這個(gè)窗口才能查看一個(gè)二進(jìn)制文件的數(shù)據(jù)部分。如下圖所示的文本視圖:

通常虛擬地址以[區(qū)域名稱]:[虛擬地址]這種格式顯示,如.txt:0040110C0。

實(shí)線箭頭表示非條件跳轉(zhuǎn),虛線箭頭則表示條件跳轉(zhuǎn)。如果一個(gè)跳轉(zhuǎn)將控制權(quán)交給程序中的某個(gè)地址,這時(shí)會(huì)使用粗線,出現(xiàn)這類逆向流程,通常表示程序中存在循環(huán)。

其它窗口

通過菜單Views,Open subviews可以打開更多的窗口。

Names窗口:列舉二進(jìn)制文件的所有全局名稱。名稱是指對(duì)一個(gè)程序虛擬地址的符號(hào)描述。 Names窗口顯示的名稱采用了顏色和字母編碼,其編碼方案如下:

  • F常規(guī)函數(shù)
  • A字符串?dāng)?shù)據(jù)
  • L庫函數(shù)
  • I導(dǎo)入的名稱,通常為共享庫導(dǎo)入的函數(shù)名稱
  • D數(shù)據(jù),已命名數(shù)據(jù)的位置通常表示全局變量

Strings窗口:顯示從二進(jìn)制文件中提取出的字符串,以及每個(gè)字符串所在的地址。與雙擊Names窗口中的名稱得到的結(jié)果類似,雙擊Strings窗口中的任何字符串,反匯編窗口將跳轉(zhuǎn)到該字符串所在的地址。將Strings窗口與交叉引用結(jié)合,可以迅速定義感興趣的字符串,并追蹤到程序中任何引用該字符串的位置。

Function name窗口:該窗口顯示所有的函數(shù)。點(diǎn)擊函數(shù)名稱,可以快速導(dǎo)航到反匯編視圖中的該函數(shù)區(qū)域。該窗口中的條目如下:

這一行信息指出:用戶可以在二進(jìn)制文件中虛擬地址為00401040的.text部分中找到_main函數(shù),該函數(shù)長(zhǎng)度為0x50字節(jié)。

Function call窗口:函數(shù)調(diào)用(Function call)窗口將顯示所有函數(shù)的調(diào)用關(guān)系。如下圖:

反編譯:新版本的IDA增加了反編譯功能,加強(qiáng)了分析能力。
在IDA View窗口下制定匯編代碼,按快捷鍵F5,IDA會(huì)將當(dāng)前所在位置的匯編代碼編譯成C/C++形式的代碼,并在Pseudocode窗口中顯示,如下圖所示。


PE文件代碼注入示例

演示內(nèi)容及實(shí)驗(yàn)環(huán)境

利用PE文件輸入表API實(shí)現(xiàn)代碼注入:讓目標(biāo)程序運(yùn)行之前,先運(yùn)行我們注入的代碼,注入的代碼將運(yùn)行PE文件輸入表里包含的API。

目標(biāo)PE文件為Windows XP下的掃雷程序,使用的工具包括OllyDBG和LordPE。

掃雷游戲程序位置:在Windows下找到附件里的掃雷游戲,右鍵屬性可以看到具體文件的位置,即C:\WINDOWS\system32\winmine.exe。

用OllyDBG打開掃雷程序

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-vVPKOYNS-1655188292069)(attachment:48ea5e2f8ed501e9e4e16c59bdde8403)]

程序會(huì)停下來,自動(dòng)停下來的這一行代碼位置就是程序入口點(diǎn)。可以通過LordPE文件來查看,得知程序入口點(diǎn)的RVA是0x00003E21,同時(shí)也可以看到裝載基址是0x01000000(掃雷程序是C++語言編寫);也可以通過右側(cè)寄存器EIP的值0x01003E21(VA)可以觀察到注釋信息里,提示是ModuleEntryPoint。
反匯編區(qū)域繼續(xù)往下翻頁,可以看到相關(guān)的導(dǎo)入表動(dòng)態(tài)鏈接庫及其相關(guān)函數(shù)的信息。

在空白代碼區(qū)編寫要注入的代碼

在代碼區(qū)可以找到大量的空白代碼區(qū)域,如果我們往這里頭植入代碼,直接修改PE文件相關(guān)跳轉(zhuǎn)地址(入口點(diǎn)或特定函數(shù)的IAT的跳轉(zhuǎn)地址),就可以實(shí)現(xiàn)相關(guān)的植入代碼的執(zhí)行。

本實(shí)驗(yàn):演示讓掃雷程序運(yùn)行之前,先運(yùn)行我們注入的代碼,注入的代碼將調(diào)用PE文件輸入表里包含的MessageBox函數(shù),彈出對(duì)話框,顯示相關(guān)信息。

編輯和注入代碼

Message函數(shù)

int MessageBox(HWND hWnd, // handle to owner windowLPCTSTR lpText, // text in message boxLPCTSTR lpCaption, // message box titleUINT uType // message box style );
  • hWnd:消息框所屬窗口的句柄,如果為NULL,消息框則不屬于任何窗口。
  • lpText:字符串指針,所指字符串會(huì)在消息框中顯示
  • lpCaption:字符串指針,所指字符串將成為消息框的標(biāo)題
  • uType:消息框的風(fēng)格(單按鈕、多按鈕等),NULL代表默認(rèn)風(fēng)格。

系統(tǒng)中并不存在真正的MessageBox函數(shù),調(diào)用最終都將由系統(tǒng)按照參數(shù)中的字符串的類型選擇“A”類函數(shù)(ASCII)或者“W”類函數(shù)(UNICODE)調(diào)用,我們使用MessageBoxA.

構(gòu)造相關(guān)字符串

計(jì)劃注入的代碼功能為:彈出對(duì)話框,顯示“You are Injected!”。

在代碼空白區(qū)域每一行位置,點(diǎn)鼠標(biāo)右鍵,選擇 編輯->二進(jìn)制編輯。

在彈出的編輯界面里,輸入ASCII碼“PE Inject”,將“保持代碼空間大小”去掉選中狀態(tài),狀態(tài)如下:

按快捷鍵CTRL+A(分析),顯示為ASCII碼。再加入另一條語句“You are Injected!” 。

上面的每個(gè)語句后面都留了一行00。因?yàn)?#xff0c;字符串后面是需要結(jié)束符0x00的。

構(gòu)造函數(shù)調(diào)用的代碼

push 0(默認(rèn)風(fēng)格); push 0x01004AA7(標(biāo)題字符串地址); push 0x01004A9C(內(nèi)容字符串地址); push 0(窗口歸屬); call MessageBoxA //參數(shù)壓入棧中的順序是從右向左

注意,直接雙擊要修改的當(dāng)前行,就進(jìn)入修改匯編代碼的狀態(tài),如下:

我們輸入的匯編指令call MessageBoxA之所以后面能成功運(yùn)行,也是因?yàn)?strong>PE文件的輸入表里已經(jīng)有這個(gè)函數(shù)的入口地址了。以上代碼完成輸入后,結(jié)果如下:

掛接代碼及完成跳轉(zhuǎn)

掛接代碼

我們首先繼續(xù)輸入一條指令jmp 0x01003E21。這句話意思是我們運(yùn)行完我們注入的彈出對(duì)話框之后,會(huì)跳轉(zhuǎn)到我們?cè)瓉淼倪@個(gè)PE文件的入口點(diǎn),繼續(xù)運(yùn)行。結(jié)果如下圖:

保存修改

上述修改是在原始文件副本里修改的,如果要保存修改,需要:

  • 點(diǎn)鼠標(biāo)右鍵,選擇“編輯->復(fù)制所有修改到可執(zhí)行文件”,會(huì)彈出一個(gè)對(duì)話框,包含所有修改后的代碼;
  • 在這個(gè)對(duì)話框空白處繼續(xù)點(diǎn)右鍵“編輯->保存文件”,彈出保存文件的界面,在這個(gè)里面選擇保存類型為“可執(zhí)行文件或DLL”,輸入新的文件名,比如winmine1.exe,點(diǎn)保存即可。
  • 到此,文件修改完畢,但是如果直接運(yùn)行這個(gè)掃雷程序,并沒有發(fā)生任何變化。** 因?yàn)?#xff0c;我們只是編輯了一段代碼,只有這些代碼被運(yùn)行了才算真正被注入。**

    修改程序入口點(diǎn)完成跳轉(zhuǎn)

    利用LordPE文件,我們更改一下程序入口點(diǎn),為我們的程序的起始位置,即我們編輯的代碼段的第一個(gè)push 0的位置,地址為0x01004ABA,因?yàn)橹恍枰腞VA,就修改為0x00004ABA即可,如下圖:

    保存后運(yùn)行,可以看到彈出右側(cè)對(duì)話框,之后出現(xiàn)掃雷程序。


    軟件破解示例

    本節(jié)將對(duì)一個(gè)簡(jiǎn)單的密碼驗(yàn)證程序,使用OllyDBG進(jìn)行破解。具體程序如下:·

    #include <iostream> using namespace std; #define password "12345678" bool verifyPwd(char * pwd) {int flag;flag=strcmp(password, pwd);return flag==0; } void main() {bool bFlag;char pwd[1024];printf("please input your password:\n");while (1){scanf("%s",pwd);bFlag=verifyPwd(pwd);if (bFlag){printf("passed\n");break;}else{printf("wrong password, please input again:\n");}} }

    破解對(duì)象是該程序生成的Debug模式的exe程序
    對(duì)得到的exe程序(假定不知道上面的源代碼),有多種方式實(shí)現(xiàn)破解:

    • 使用OllyDBG

      通過運(yùn)行程序,觀察關(guān)鍵信息,通過對(duì)關(guān)鍵信息定位,來得到關(guān)鍵分支語句,通過對(duì)該分支語句進(jìn)行修改,達(dá)到破解的目的;

    • 另一種方式

      可以通過IDA Pro來觀察代碼結(jié)構(gòu),確定函數(shù)入口地址,對(duì)函數(shù)體返回值進(jìn)行更改。(給出的程序?qū)嵗惺褂玫拿菜七€是OllyDBG)

    運(yùn)行程序,輸入一個(gè)密碼,發(fā)現(xiàn)運(yùn)行結(jié)果如下:

    使用OllyDBG破解

    在OllyDBG中,為了盡快定位到分支語句處,在反匯編窗口,點(diǎn)右鍵,選擇“查找→所有引用的字符串”功能:

    然后,使用快捷鍵,Ctrl+F打開搜索窗口,輸入wrong,點(diǎn)確定后,將定位出錯(cuò)信息的哪一行代碼:

    雙擊這一行代碼,就會(huì)定位反匯編中的相應(yīng)代碼處:

    破解方式一:修改分支語句

    觀察反匯編語言,可知核心分支判斷在于:

    Test eax,eax Jz short 0041364b

    如果jz條件成立,則跳轉(zhuǎn)到0041364b處,即顯示錯(cuò)誤密碼分支語句中。如果將jz該指令改為jnz,則程序截然相反。輸入了錯(cuò)誤密碼,將進(jìn)入驗(yàn)證成功的分支中。
    雙擊jz密碼一行,對(duì)其進(jìn)行修改:

    注意:
    此時(shí)并沒有真正修改二進(jìn)制文件中的有關(guān)代碼,如果想要修改二進(jìn)制文件中的代碼,需要在反匯編窗口,點(diǎn)右鍵,選擇“編輯->復(fù)制當(dāng)前修改到可執(zhí)行文件”。保存后的可執(zhí)行文件,將是破解后的文件。

    破解方式二:修改函數(shù)返回值

    更改函數(shù)。通過分析匯編語句,可知,驗(yàn)證命令使用的是verifyPwd函數(shù),點(diǎn)右鍵選擇跟隨,逐步進(jìn)入該函數(shù)

    函數(shù)的返回值通過eax寄存器來完成的,核心語句即sete al。
    對(duì)于函數(shù)中的代碼:

    flag=strcmp(password, pwd); return flag==0;

    被解釋成匯編語言:

    Mov dword ptr [ebp-8], eax //將strcmp函數(shù)調(diào)用后的返回值(存在eax中)賦值給變量flag Xor eax, eax //將eax的值清空 Cmp dword ptr [ebp-8], 0 //將flag的值與0進(jìn)行比較,即flag==0; //注意cmp運(yùn)算的結(jié)果只會(huì)影響一些狀態(tài)寄存器的值 Sete al //sete是根據(jù)狀態(tài)寄存器的值,如果相等,則設(shè)置,如果不等,則不設(shè)置

    要想更改該語句,在cmp dword ptr [ebp-8], 0處開始更改,將其更改為:mov al,01。取消保持代碼空間大小,如果新代碼超長(zhǎng),將無法完成更改。

    并將sete al改為NOP。
    得到結(jié)果如下:

    運(yùn)行結(jié)果校驗(yàn)破解正確性。

    總結(jié)

    本章介紹了軟件安全調(diào)試的基礎(chǔ)知識(shí),包括PE文件格式、虛擬內(nèi)存,以及介紹了LordPE、OllyDBG、IDA Pro等用于逆向分析的工具。還給出了PE文件代碼注入和軟件破解兩個(gè)示例,后續(xù)如果有時(shí)間會(huì)分享這兩個(gè)實(shí)驗(yàn)的錄制視頻,演示每一步實(shí)驗(yàn)細(xì)節(jié)。

    軟件安全系列預(yù)期會(huì)有8輯:

    • 軟件安全預(yù)備知識(shí)
    • 軟件調(diào)試基礎(chǔ)
    • 軟件漏洞篇
    • 漏洞利用篇
    • 漏洞挖掘篇
    • 滲透測(cè)試篇
    • WEB安全基礎(chǔ)
    • WEB滲透實(shí)戰(zhàn)

    內(nèi)容參考自《軟件安全:漏洞利用及滲透測(cè)試》,書中對(duì)于PE文件結(jié)構(gòu)講述并不到位,后續(xù)會(huì)發(fā)一篇博文,講述PE文件結(jié)構(gòu)有關(guān)內(nèi)容。

    總結(jié)

    以上是生活随笔為你收集整理的软件调试基础的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。