IDA Pro:使用PV或其他任何东西来定位XREF到数据



是否有任何内置工具用于我需要的功能,或者我应该编写自己的脚本?如果有,IDC的哪些功能可能有用?

我知道我可以使用PV来查找两个任意过程之间的连接

然而,我需要的有点不同。更确切地说,我需要查看特定函数最终是否引用了指定的内存地址(或者更好的是内存区域))

考虑分析一个已知会切换几个gpio的嵌入式软件。gpio被映射到的内存区域是已知和定义的。我想看看特定的顶级实体是否达到了gpio。

现在我能想到的唯一方法就是右键单击每个地址,运行" xref to. "对话框,生成wingraph32图表,并查看最终指向特定地址的顶级函数

另一个例子:我知道哪个RAM地址保存一些变量,并且我想知道给定过程的所有子过程,其中引用了变量。我可以运行ctrl-x (xrefs to)命令,该命令将列出整个代码中的所有xrefs,而我需要限制列表,仅从给定的顶级实体调用过程。

xref是在指令和二进制文件中的变量之间创建的。GPIO地址在外部,没有为它们创建xref。您可以分析二进制文件中所有函数的所有内存读/写指令,以确定它们是否引用了特定的内存范围。然后构建一个调用图,并将GPIO访问信息从被调用的函数传播到它的调用者。

这个算法有两个问题:

  • 当一个GPIO地址不是通过一个立即值被访问时,你没有保证的方法来静态计算被访问的地址。
  • 间接函数调用不创建xref,因此从xref创建的callgraph将不精确。同样,没有保证的方法可以静态地在给定的间接调用站点上调用所有可能的函数。

对于"另一个例子":当RAM地址在二进制文件之外时,不会创建xref。解决方案是相同的——找到所有固定的RAM地址引用,并通过调用图向上传播它们。使用"给定的程序"。作为调用图根

两种方案都可以在idc中实现。

当引用的地址存在并且IDA为这些地址创建了xref时,您可以遍历给定区域中的所有地址并保存引用它们的所有函数,而不是遍历所有函数指令。这个idc代码片段为内存范围0x65607000 - 0x656070C0:

auto arr, VA, xref, fnName, mem_rgn_begin, mem_rgn_end;
mem_rgn_begin = 0x65607000;
mem_rgn_end = 0x656070C0;
arr = GetArrayId( "RegionReferences123" );
if( -1 != arr )
DeleteArray( arr );
arr = CreateArray( "RegionReferences123"  );
if( -1 == arr )
Message( "Can't create Array!n" );
VA = mem_rgn_begin;
while( VA <= mem_rgn_end )
{
if( isData( GetFlags( VA ) ) )
{
//get all data references to this VA
for( xref = DfirstB( VA ); xref != BADADDR; xref = DnextB( VA, xref ) )
{
//VA is referenced by xref. Find xrefs function.
fnName = GetFunctionName(xref);
//Function fnName references VA
//Message( "Func %s references addr 0x%Xn", fnName, VA );
SetHashString( arr, fnName, "1" );
}
}
VA = NextHead( VA, BADADDR );
} 
Message( "Func references:n" );
fnName = "";
for( ; ; )
{
fnName = GetNextHashKey( arr, fnName );
if( fnName == "" )
break;
Message( "Func %s references regionn", fnName );
}
DeleteArray( arr );

最新更新