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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

new 一个结构体数组_每天一个IDA小技巧(四):结构体识别

發(fā)布時(shí)間:2025/3/12 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 new 一个结构体数组_每天一个IDA小技巧(四):结构体识别 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

之前提到IDA可以將一長串的數(shù)組數(shù)據(jù)聲明變成一行數(shù)組聲明,簡化反匯編代碼,對(duì)于結(jié)構(gòu)體,IDA也同樣支持通過各種設(shè)置工具來改善結(jié)構(gòu)體代碼的可讀性。

這篇文章的目標(biāo)是將[edx+10h]之類的結(jié)構(gòu)體元素訪問 變成 [edx+struct_filed5]之類。

只要發(fā)現(xiàn)一個(gè)程序正操縱某種數(shù)據(jù)結(jié)構(gòu),你就需要確定:你是否希望將結(jié)構(gòu)體的字段名稱合并到反匯編代碼清單中,或者你是否理解分散在代碼清單中的所有數(shù)字偏移量。

如果是C標(biāo)準(zhǔn)庫或者IDA能夠確定的已知結(jié)構(gòu)體,IDA會(huì)自動(dòng)將數(shù)字偏移量轉(zhuǎn)換成更加符號(hào)化的字段名稱,但如果是自定義的結(jié)構(gòu)體,就需要我們手動(dòng)幫助IDA進(jìn)行識(shí)別。

IDA之所以在分析階段無法識(shí)別結(jié)構(gòu)體,可能源于兩個(gè)原因。首先,雖然IDA了解某個(gè)結(jié)構(gòu)體的布局,但它并沒有足夠的信息,能夠判斷程序確實(shí)使用了結(jié)構(gòu)體。其次,程序中的結(jié)構(gòu)體可能是一種IDA對(duì)其一無所知的非標(biāo)準(zhǔn)結(jié)構(gòu)體。在這兩種情況下,問題都可以得到解決,且首先從Structures窗口下手。

創(chuàng)建一個(gè)新的結(jié)構(gòu)體(或Union)

在IDA Structures窗口(默認(rèn)展示,如果沒有可以在View -> Open SubViews里打開)中,列舉了當(dāng)前反匯編文件的所有已知結(jié)構(gòu)體,并且在注釋中也提示了我們?nèi)绾卧谠摯翱谥刑砑?刪除/編輯一個(gè)結(jié)構(gòu)體:

00000000 ; Ins/Del : create/delete structure 或者 Edit -> Add struct type

00000000 ; D/A/* : create structure member (data/ascii/array)

00000000 ; N : rename structure or structure member

00000000 ; U : delete structure member

注意:只有當(dāng)一個(gè)字段是結(jié)構(gòu)體中的最后一個(gè)字段時(shí),使用U鍵才能刪除該字段。對(duì)于所有其他字段,按下U鍵將取消該字段的定義,這樣做僅僅刪除了該字段的名稱,并沒有刪除分配給該字段的字節(jié)。

為了創(chuàng)建一個(gè)新的結(jié)構(gòu)體,你必須首先在Structure name(結(jié)構(gòu)體名稱)字段中指定結(jié)構(gòu)體的名稱。前兩個(gè)復(fù)選框用于決定新結(jié)構(gòu)體在Structures窗口中的顯示位置,或者是否在窗口中顯示新結(jié)構(gòu)體。第三個(gè)復(fù)選框Creat union(創(chuàng)建聯(lián)合),指定你定義的是否為C風(fēng)格聯(lián)合結(jié)構(gòu)體(Union和結(jié)構(gòu)體的區(qū)別在于union中字段相互重疊,因此總大小等于其中最大字段的大小)。

此外還有一個(gè)按鈕「add standard structure」,用于添加標(biāo)準(zhǔn)結(jié)構(gòu)體。IDA內(nèi)置了大量的各種庫和API函數(shù)有關(guān)的數(shù)據(jù)結(jié)構(gòu),IDA會(huì)嘗試確定與二進(jìn)制文件有關(guān)的編譯器和平臺(tái),并加載適當(dāng)?shù)慕Y(jié)構(gòu)體模板。單擊這個(gè)按鈕,IDA將顯示與當(dāng)前編譯器(在分析階段檢測出來)和文件格式有關(guān)的結(jié)構(gòu)體主列表。這個(gè)結(jié)構(gòu)體主列表中還包含通過解析C頭文件添加到數(shù)據(jù)庫中的結(jié)構(gòu)體。

編輯結(jié)構(gòu)體成員

為了給新結(jié)構(gòu)體添加字段,你必須利用字段創(chuàng)建命令D、A和數(shù)字鍵盤上的星號(hào)鍵(*),需要注意的是D快捷鍵還可用于為當(dāng)前光標(biāo)所所在的字段調(diào)整數(shù)據(jù)大小。所以推薦的創(chuàng)建結(jié)構(gòu)體的步驟為:

  • 在結(jié)構(gòu)體定義的最后一行(包含ends的那一行)按下D鍵,這時(shí)候,IDA會(huì)在結(jié)構(gòu)體末尾添加一個(gè)新字段,默認(rèn)的字段名稱為filed_N,N為結(jié)構(gòu)體開頭到字段開頭的數(shù)字偏移量。

  • 如果需要修改字段大小,可以重復(fù)按D,循環(huán)數(shù)據(jù)轉(zhuǎn)盤上的數(shù)據(jù)類型,或者通過Options->Setup Data Types來指定一個(gè)在數(shù)據(jù)轉(zhuǎn)盤上不存在的大小,如果是數(shù)組,右鍵名稱然后選擇Array。

  • 如果要更改字段名稱,使用N或者右鍵然后Rename

  • 如果知道結(jié)構(gòu)體的大小,而不了解它的布局,你需要?jiǎng)?chuàng)建兩個(gè)字段。第一個(gè)字段為一個(gè)數(shù)組,它的大小為結(jié)構(gòu)體的大小減去1個(gè)字節(jié)(size-1);第二個(gè)字段應(yīng)為1個(gè)字節(jié)。創(chuàng)建第二個(gè)字段后,取消第一個(gè)(數(shù)組)字段的定義。這樣,結(jié)構(gòu)體的大小被保留下來,隨后,當(dāng)你進(jìn)一步了解該結(jié)構(gòu)體的布局后,你可以回過頭來定義它的字段及其大小。

    此外,在你定義和編輯結(jié)構(gòu)體時(shí),IDA會(huì)有一些提示:

    • 一個(gè)字段的字節(jié)偏移量以一個(gè)8位十六進(jìn)制值在Structures窗口的左側(cè)顯示。

    • 每次你添加或刪除一個(gè)結(jié)構(gòu)體字段,或更改一個(gè)現(xiàn)有字段的大小時(shí),結(jié)構(gòu)體的新大小都會(huì)在結(jié)構(gòu)體定義的第一行反映出來。

    • 你必須對(duì)一個(gè)結(jié)構(gòu)體定義中的所有字段進(jìn)行適當(dāng)?shù)膶?duì)齊。如果你需要填補(bǔ)字節(jié),那么你必須負(fù)責(zé)添加這些字節(jié)。填補(bǔ)字節(jié)最好作為適當(dāng)大小的啞字段添加。

    • 分配到結(jié)構(gòu)體中間的字節(jié)只有在取消關(guān)聯(lián)字段的定義后才能刪除,使用Edit?Shrink Struct Type(縮小結(jié)構(gòu)體類型)即可刪除被取消定義的字節(jié)。

    • 你也可以在結(jié)構(gòu)體的中間添加新的字節(jié):選擇新字節(jié)后面的一個(gè)字段,然后使用Edit?Expand Struct Type(擴(kuò)大結(jié)構(gòu)體類型)在選中的字段前插入一定數(shù)量的字節(jié)。

    通過重復(fù)應(yīng)用這些步驟(添加字段,設(shè)置字段大小,添加填補(bǔ)字節(jié)等),就可以完成IDA結(jié)構(gòu)體定義的創(chuàng)建。接下來就可以利用這些定義好的結(jié)構(gòu)體改善反匯編代碼。

    使用結(jié)構(gòu)體模版

    前面提到這篇文章的目標(biāo)是將[edx+10h]之類的結(jié)構(gòu)體元素訪問 變成 [edx+struct_filed5]之類。

    此時(shí)有了結(jié)構(gòu)體定義之后,就可以右鍵10h,選擇Structure Offset(結(jié)構(gòu)體偏移量)選項(xiàng),然后就可以進(jìn)行格式化了,如果有多個(gè)結(jié)構(gòu)體中字段匹配上了偏移量,則會(huì)有多個(gè)選擇。

    如果是棧變量或者全局變量,則可以直接將棧和全局變量格式化為整個(gè)結(jié)構(gòu)體,首先打開棧幀的詳細(xì)視圖(雙擊函數(shù)棧幀中的變量),然后使用ALT+Q(Edit->Struct Var)命令顯示一組已知的結(jié)構(gòu)體并選擇對(duì)應(yīng)想要格式化的結(jié)構(gòu)體即可。如果是全局變量,則選擇要格式化的全局變量或者表示結(jié)構(gòu)體開頭部分的地址,再使用ALT+Q(Edit->Struct Var)即可。

    重新格式化之后,IDA認(rèn)識(shí)到,任何對(duì)分配給var_18的24個(gè)字節(jié)塊的內(nèi)存引用,都必須引用該結(jié)構(gòu)體中的一個(gè)字段。如果IDA發(fā)現(xiàn)這樣一個(gè)引用,它會(huì)盡一切努力,將這個(gè)內(nèi)存引用與結(jié)構(gòu)體變量中的一個(gè)已定義的字段關(guān)聯(lián)起來。

    導(dǎo)入結(jié)構(gòu)體

    IDA能夠解析C(而非C++)數(shù)據(jù)聲明,以及整個(gè)C頭文件,并自動(dòng)為在這些聲明或頭文件中定義的結(jié)構(gòu)體創(chuàng)建對(duì)應(yīng)的IDA結(jié)構(gòu)體。如果你碰巧擁有你正進(jìn)行逆向工程的二進(jìn)制文件的源代碼,或者至少是頭文件,那么,你就可以讓IDA直接從源代碼中提取出相關(guān)結(jié)構(gòu)體,從而節(jié)省大量時(shí)間。

    解析C結(jié)構(gòu)體聲明

    如果我們已經(jīng)有某個(gè)結(jié)構(gòu)體的聲明代碼,那可以直接在View?Open Subviews?Local Types(查看?打開子窗口?本地類型)窗口中,輸入我們的結(jié)構(gòu)體聲明代碼,例如:

    注意,IDA解析器使用4字節(jié)的默認(rèn)結(jié)構(gòu)體成員對(duì)齊方式。如果你的結(jié)構(gòu)體需要其他對(duì)齊方式,你可以包括該對(duì)齊方式,IDA認(rèn)可使用pragma pack指令來指定所需的結(jié)構(gòu)體成員對(duì)齊方式。

    添加到Local Types(本地類型)窗口中的數(shù)據(jù)類型不會(huì)立即在Structures(結(jié)構(gòu)體)窗口中出現(xiàn)。有兩種方法可以將本地類型聲明添加到Structures窗口中。最簡單的方法是在相關(guān)本地類型上單擊鼠標(biāo)右鍵,并選擇Synchronize to idb。或者,由于每個(gè)新類型均被添加到標(biāo)準(zhǔn)結(jié)構(gòu)體列表中,因而也可將新類型導(dǎo)入到Structures窗口中即add standard structure。

    解析C頭文件

    要解析頭文件,可以使用File?Load File?Parse C Header File(文件?加載文件?解析C頭文件)選擇你想要解析的頭文件。如果一切正常,IDA會(huì)通知你Compilation successful(編譯完成)。如果解析器遇到任何問題,IDA將會(huì)在輸出窗口中顯示錯(cuò)誤消息。

    IDA會(huì)將所有被成功解析的結(jié)構(gòu)體添加到當(dāng)前數(shù)據(jù)庫的標(biāo)準(zhǔn)結(jié)構(gòu)體列表末尾,此時(shí)同樣需要手動(dòng)從標(biāo)準(zhǔn)結(jié)構(gòu)體列表中添加到Structures窗口中。如果新結(jié)構(gòu)體的名稱與現(xiàn)有結(jié)構(gòu)體的名稱相同,IDA會(huì)用新結(jié)構(gòu)體布局覆蓋原有結(jié)構(gòu)體定義。

    一般而言,要最大限度地提高成功解析一個(gè)頭文件的幾率,你需要使用標(biāo)準(zhǔn)C數(shù)據(jù)類型,并盡可能地減少使用include文件,從而最大程度地簡化結(jié)構(gòu)體定義。記住,在IDA中創(chuàng)建結(jié)構(gòu)體時(shí),正確布局最為重要。正確的布局更多地取決于每個(gè)字段的正確大小和結(jié)構(gòu)體的正確對(duì)齊,而不只是對(duì)每個(gè)字段都使用正確的類型。

    IDA TIL文件(Type Library)

    IDA中的所有數(shù)據(jù)類型和函數(shù)原型信息都存儲(chǔ)在TIL文件中。IDA擁有存儲(chǔ)在/til目錄中的許多主要編譯器和API的類型庫信息。Types窗口(View?Open subview?Type Libraries)列出了當(dāng)前加載的.til文件,并可用于加載你想要使用的其他.til文件。IDA將根據(jù)在分析階段發(fā)現(xiàn)的二進(jìn)制文件屬性,自動(dòng)加載類型庫。正常情況下,一般不需要直接處理.til文件。

    IDA還利用.til文件存儲(chǔ)你在Structures窗口中手動(dòng)創(chuàng)建的或者通過解析C頭文件獲得的任何自定義結(jié)構(gòu)體定義。這些結(jié)構(gòu)體存儲(chǔ)在一個(gè)與創(chuàng)建它們的數(shù)據(jù)庫有關(guān)的專用.til文件中。該文件的名稱與其相關(guān)數(shù)據(jù)庫的名稱相同,擴(kuò)展名為.til。

    例如,如果數(shù)據(jù)庫名為some_file.idb,則相應(yīng)的類型庫文件則為some_file.til。

    .idb文件實(shí)際上是一個(gè)歸檔文件(類似于.tar文件),用于保存不使用的數(shù)據(jù)庫組件。打開一個(gè)數(shù)據(jù)庫時(shí),其組件文件(.til文件為其中之一)將被提取出來,成為IDA中的運(yùn)行文件。

    在其他數(shù)據(jù)庫中共享til文件

    有兩種共享方法。第一種方法有些不太正規(guī),即將.til文件由打開的數(shù)據(jù)庫復(fù)制到另一個(gè)目錄中,然后再通過Types窗口,在任何其他數(shù)據(jù)庫中打開這個(gè).til文件。第二種是一種正式的方法,即從一個(gè)數(shù)據(jù)庫中提取出自定義類型信息,生成一段IDC腳本,用于在任何其他數(shù)據(jù)庫中重建自定義結(jié)構(gòu)體。使用File?Produce File?Dump Type. into to IDC File(文件?生成文件?轉(zhuǎn)儲(chǔ)類型信息到IDC文件)命令可生成該腳本。但是,與第一種方法不同的是,這種方法只能轉(zhuǎn)儲(chǔ)Structures窗口中列出的結(jié)構(gòu)體,但并不轉(zhuǎn)儲(chǔ)通過解析C頭文件得到的結(jié)構(gòu)體(而復(fù)制.til文件卻可以轉(zhuǎn)儲(chǔ)這類結(jié)構(gòu)體)。

    總結(jié)

    以上是生活随笔為你收集整理的new 一个结构体数组_每天一个IDA小技巧(四):结构体识别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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