14.IDA-XREF(交叉引用)概述

XREF分类

CODE XREF:代码交叉引用
DATA XREF:数据交叉引用

XREF描述含义

这里写图片描述

  1. 这是个代码交叉引用
  2. sub401000是被引用者,main+2A是引用者(引用sub401000的位置)
  3. 下箭头表示引用者的地址比sub401000高,你需要向下滚动才能到达引用者地址(main+2A),上行反之~
    4.每个交叉引用注释都包含一个单字符后缀(箭头后面),用以说明交叉引用的类型,这里是↓P

CODE XREF

代码交叉引用用于表示一条指令将控制权转交给另一条指令。在IDA中,指令转交控制权的方式叫做流(flow)
IDA中有3种基本流:

普通流
调用流
跳转流

示例代码:

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();
}

示例汇编:

.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:00401030call    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:00401054call    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

普通流

普通流表示由一条指令到另一条指令的顺序流。这是所有非分支指令(如ADD)的默认执行流。

调用流

如果IDA认为某个函数并不返回(在分析阶段确定,注意不是运行阶段),那么,在调用该函数时,它就不会为该函数分配普通流

.text:00401030call    callflow(void)
.text:00401054call    callflow(void)

指令用于调用函数,如③处的 call指令,它分配到一个调用流(call flow),表示控制权被转交给目标函数
callflow函数的反汇编:

.text:00401000 void __cdecl callflow(void) proc near   ; ①CODE XREF: _main+20↓p
.text:00401000                                         ; ①_main:loc_401054↓p
.text:00401000                 push    ebp
.text:00401001                 mov     ebp, esp
.text:00401003                 pop     ebp
.text:00401004                 retn
.text:00401004 void __cdecl callflow(void) endp

callflow所在的位置显示了两个交叉引用(①处),表示这个函数被调用了两次

由函数调用导致的交叉引用使用后缀↓p(看做是Procedure)。

跳转流

每个无条件分支指令和条件分支指令将分配到一个跳转流(jump flow)

.text:00401048                 jmp     short loc_401054
.text:0040104A ; ---------------------------------------------------------------------------
.text:0040104A

无条件分支并没有相关的普通流,因为它总会进入分支。上处的虚线表示相邻的两条指令之间并不存在普通流(也就是00401048后没有跟着顺序执行的指令)

跳转交叉引用使用后缀↑j(看做是Jump)。

DATA XREF

数据交叉引用用于跟踪二进制文件访问数据的方式。数据交叉引用与IDA数据库中任何牵涉到虚拟地址的字节有关(换言之,数据交叉引用与栈变量毫无关系)
最常用的3种数据交叉引用:

address何时被读取(读取交叉引用)
address何时被写入(写入交叉引用)
address何时被引用(偏移量交叉引用)

.data:00403378 int ref_it      db    ? ;               ; DATA XREF: _main+4↑o
.data:00403379                 db    ? ;
.data:0040337A                 db    ? ;
.data:0040337B                 db    ? ;
.data:0040337C int write_it    dd ?                    ; DATA XREF: _main+1B↑w
.data:0040337C                                         ; _main+2E↑w ...
.data:00403380 int read_it     dd ?                    ; DATA XREF: _main+E↑r
.data:00403380                                         ; _main+25↑r

读取交叉引用

读取交叉引用(read cross-reference)表示访问的是某个内存位置的内容
可以看到read_it在_main+E处、_main+25被读取,如下

.text:0040101E                 mov     ecx, int read_it
.text:00401035                 cmp     int read_it, 3

读取交叉引用使用后缀↑r(看做是Read)。

写入交叉引用

写入交叉引用指出了修改变量内容的程序位置
可以看到write_it在_main+1B、_main+2E处被写入,如下

.text:0040102B                 mov     int write_it, eax
.text:0040103E                 mov     int write_it, 2

写入交叉引用使用后缀↑w(看做是Write)。

偏移量交叉引用

偏移量交叉引用表示引用的是某个位置的地址(而非内容)
可以看到ref_it在_main+4处被引用

.text:00401014                 mov     [ebp+p], offset int ref_it

偏移量交叉引用使用后缀↑o(看做是Offset)。

与仅源自于指令位置的读取和写入交叉引用不同,偏移量交叉引用可能源于指令位置或数据位置,例如虚表
回溯偏移量交叉引用是一种有用的技术,可迅速在程序的数据部分定位C++虚表。

  • 21
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
IDA是一款非常强大的反汇编工具,它不仅可以将二进制文件反汇编成汇编代码,还可以对汇编代码进行分析和调试。在IDA中,我们可以进行文本搜索、二进制搜索和替换16进制字节序列等操作。 1. 文本搜索 在IDA中,我们可以使用快捷键Ctrl+F或者点击菜单“Edit”->“Find”来进行文本搜索。在搜索框中输入要查找的文本,点击“Find”按钮即可。如果要查找下一个匹配项,可以使用快捷键F3或者点击菜单“Edit”->“Find Next”。 2. 二进制搜索 在IDA中,我们也可以进行二进制搜索。首先,我们需要打开“Hex View-A”窗口,该窗口可以显示二进制文件的16进制表示。在该窗口中,我们可以使用快捷键Ctrl+F或者点击菜单“Search”->“Find Bytes”来进行二进制搜索。在搜索框中输入要查找的16进制字节序列,点击“OK”按钮即可。如果要查找下一个匹配项,可以使用快捷键F3或者点击菜单“Search”->“Find Next”. 3. 替换16进制字节序列 在IDA中,我们也可以替换16进制字节序列。首先,我们需要打开“Hex View-A”窗口。在该窗口中,我们可以使用快捷键Ctrl+R或者点击菜单“Search”->“Replace Bytes”来进行替换操作。在弹出的对话框中,输入要查找的16进制字节序列和要替换的16进制字节序列,然后点击“OK”按钮即可。如果要替换所有匹配项,可以点击“Replace All”按钮。 以上就是IDA中文本搜索、二进制搜索和替换16进制字节序列的操作方法。在实际使用中,这些操作非常实用,可以帮助我们更快地定位和解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值