14.IDA-XREF(交叉引用)概述
XREF分類
CODE XREF:代碼交叉引用?
DATA XREF:數(shù)據(jù)交叉引用
XREF描述含義
4.每個交叉引用注釋都包含一個單字符后綴(箭頭后面),用以說明交叉引用的類型,這里是↓P
CODE XREF
代碼交叉引用用于表示一條指令將控制權(quán)轉(zhuǎn)交給另一條指令。在IDA中,指令轉(zhuǎn)交控制權(quán)的方式叫做流(flow)?
IDA中有3種基本流:
普通流?
調(diào)用流?
跳轉(zhuǎn)流
示例代碼:
int read_it; int write_it; int ref_it; void callflow() {} int main() {int *p = &ref_it;*p = read_it;write_it = *p;callflow();if (read_it == 3){write_it = 2;}else{write_it = 1;}callflow(); }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
示例匯編:
.text:00401010 ; int __cdecl main(int argc, const char **argv, const char **envp) .text:00401010 _main proc near ; CODE XREF: __tmainCRTStartup+10Ap .text:00401010 .text:00401010 p = dword ptr -4 .text:00401010 argc = dword ptr 8 .text:00401010 argv = dword ptr 0Ch .text:00401010 envp = dword ptr 10h .text:00401010 .text:00401010 push ebp .text:00401011 mov ebp, esp .text:00401013 push ecx .text:00401014 mov [ebp+p], offset int ref_it .text:0040101B mov eax, [ebp+p] .text:0040101E mov ecx, int read_it .text:00401024 mov [eax], ecx .text:00401026 mov edx, [ebp+p] .text:00401029 mov eax, [edx] .text:0040102B mov int write_it, eax .text:00401030 ③call callflow(void) .text:00401035 cmp int read_it, 3 .text:0040103C jnz short loc_40104A .text:0040103E mov int write_it, 2 .text:00401048 jmp short loc_401054 .text:0040104A ; --------------------------------------------------------------------------- .text:0040104A .text:0040104A loc_40104A: ; CODE XREF: _main+2C↑j .text:0040104A mov int write_it, 1 .text:00401054 .text:00401054 loc_401054: ; CODE XREF: _main+38↑j .text:00401054 ③call callflow(void) .text:00401059 xor eax, eax .text:0040105B mov esp, ebp .text:0040105D pop ebp .text:0040105E retn .text:0040105E _main endp .text:0040105E- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
普通流
普通流表示由一條指令到另一條指令的順序流。這是所有非分支指令(如ADD)的默認(rèn)執(zhí)行流。
調(diào)用流
如果IDA認(rèn)為某個函數(shù)并不返回(在分析階段確定,注意不是運(yùn)行階段),那么,在調(diào)用該函數(shù)時,它就不會為該函數(shù)分配普通流
.text:00401030 ③call callflow(void) .text:00401054 ③call callflow(void)- 1
- 2
- 1
- 2
指令用于調(diào)用函數(shù),如③處的 call指令,它分配到一個調(diào)用流(call flow),表示控制權(quán)被轉(zhuǎn)交給目標(biāo)函數(shù)?
callflow函數(shù)的反匯編:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
callflow所在的位置顯示了兩個交叉引用(①處),表示這個函數(shù)被調(diào)用了兩次
由函數(shù)調(diào)用導(dǎo)致的交叉引用使用后綴↓p(看做是Procedure)。
跳轉(zhuǎn)流
每個無條件分支指令和條件分支指令將分配到一個跳轉(zhuǎn)流(jump flow)
.text:00401048 jmp short loc_401054 .text:0040104A ; --------------------------------------------------------------------------- .text:0040104A- 1
- 2
- 3
- 1
- 2
- 3
無條件分支并沒有相關(guān)的普通流,因為它總會進(jìn)入分支。上處的虛線表示相鄰的兩條指令之間并不存在普通流(也就是00401048后沒有跟著順序執(zhí)行的指令)
跳轉(zhuǎn)交叉引用使用后綴↑j(看做是Jump)。
DATA XREF
數(shù)據(jù)交叉引用用于跟蹤二進(jìn)制文件訪問數(shù)據(jù)的方式。數(shù)據(jù)交叉引用與IDA數(shù)據(jù)庫中任何牽涉到虛擬地址的字節(jié)有關(guān)(換言之,數(shù)據(jù)交叉引用與棧變量毫無關(guān)系)?
最常用的3種數(shù)據(jù)交叉引用:
address何時被讀取(讀取交叉引用)?
address何時被寫入(寫入交叉引用)?
address何時被引用(偏移量交叉引用)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
讀取交叉引用
讀取交叉引用(read cross-reference)表示訪問的是某個內(nèi)存位置的內(nèi)容?
可以看到read_it在_main+E處、_main+25被讀取,如下
- 1
- 2
- 1
- 2
讀取交叉引用使用后綴↑r(看做是Read)。
寫入交叉引用
寫入交叉引用指出了修改變量內(nèi)容的程序位置?
可以看到write_it在_main+1B、_main+2E處被寫入,如下
- 1
- 2
- 1
- 2
寫入交叉引用使用后綴↑w(看做是Write)。
偏移量交叉引用
偏移量交叉引用表示引用的是某個位置的地址(而非內(nèi)容)?
可以看到ref_it在_main+4處被引用
- 1
- 1
偏移量交叉引用使用后綴↑o(看做是Offset)。
與僅源自于指令位置的讀取和寫入交叉引用不同,偏移量交叉引用可能源于指令位置或數(shù)據(jù)位置,例如虛表
回溯偏移量交叉引用是一種有用的技術(shù),可迅速在程序的數(shù)據(jù)部分定位C++虛表。
總結(jié)
以上是生活随笔為你收集整理的14.IDA-XREF(交叉引用)概述的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 13.IDA-显示正确的函数名称(去掉c
- 下一篇: 15.IDA-查看XREF列表