IDA Pro: using PV or whatever else to locate XREF to data

643 Views Asked by At

Are there any built-in tools for the feature I need, or should I write my own script? If so, what IDC functions might be useful?

I am aware that I may use PV for finding connection between two arbitrary procedures

However what I need is a bit different. More exactly, I need to see if particular function eventually references specified memory address (or even better memory region)

Consider analyzing an embedded software which is known to toggle a few GPIOs. Memory region to which the GPIOs are mapped is known and defined. I want to see if specific top level entity ever reaches GPIOs.

Right now the only way I can think of is to right click on each address, run "Xrefs to.." dialog, produce wingraph32 chart and see top level functions that eventually refer to specific address

Another example: I know which RAM address holds some variable, and I want to know all sub procedures of a given procedure, where the variable is referenced. I can run ctrl-x (xrefs to) command which would list all xrefs in whole code, while I need to limit the list down to only procedures called from given top level entity.

1

There are 1 best solutions below

4
On

Xrefs are created between instructions and variables present in the binary. GPIO addresses are outside, no Xrefs are created for these. You can analyze all memory read\write instructions of all functions of the binary to find out if they reference a specific memory range. Then build a call graph and propagate GPIO access info from called functions to it's callers.

This algorithm has two problems:

  • when a GPIO address is accessed not through an immediate value, you have no guaranteed method to statically calculate the accessed address.
  • indirect function calls do not create Xrefs, thus a callgraph created from Xrefs would not be precise. Again no guaranteed method to statically get all possible functions called at a given indirect call site.

For "Another example": when the RAM address is outside your binary, no Xrefs are created. The solution is same - find all fixed RAM address references and propagate them up through the call graph. Use the "given procedure" as the call graph root.

Both solutions can be implemented in idc.

When the referenced addresses are present and IDA created Xrefs for these, instead of traversing all function instructions, you can traverse all addresses in the given region and save all functions that reference them. This idc code snippet does this for memory range 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%X\n", 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 region\n", fnName );
}
DeleteArray( arr );