Reversing with IDA: Cross-references

Cross-references, or more commonly referred to as xrefs, are used to identify references (usage/call or declaration) of a particular function, string, variable, etc. Example — if you’ve identified a particular function (a VM check) being called inside another subroutine (installation of a backdoor), you might be interested in knowing other calls to the same function.

Categories of Cross-references

Cross-references can be categorized as follows:

  • Code cross-references
  • Data cross-references

Let’s explore the two in a short section next.

Code Cross-references

Code cross-references are used to identify relationships between function calls, declarations, or jumps. Let’s take a look at an example.

CODE XREF shows the reference to the actual jump

Here, we can see that loc_1000D325 has a code cross-reference to sub_1000D2F9+19. It suggests that this location is accessed by the function (sub_*) at the address 1000D2F9 and an offset of 0x19 into the function. Next, the arrow shows us that the code is at a lower address than the reference and the ‘j’ suggests it’s a jump.

Much like this jump, there are several other cross-reference types as I’ll discuss later on.

Data Cross-references

Much like code cross-references, data cross-references can help us keep track of data being accessed or written throughout the binary. For example, you might find an IP address being referenced in a few functions; using xrefs, you can identify all those functions easily.

DATA XREF shows several strings being referenced in functions

Here, we can see several data strings being referenced in functions. For example, the aThePidofProces_1 is being referenced in the function, sub_1000D5B0 and at on offset of 0x264. The direction is upwards again suggesting the function is at a lower address than string’s address.

For the DATA XREF to aCopySToSSucces you can see two cross-references being listed. IDA restricts listing multiple references by default. You can change this setting and show as many references as you want. It is under ‘Options’ — ‘General’ — ‘Cross-references’.

Listing Cross-references

If you’ve identified an offset or a function and would like to list all cross-references, you can simply do so by selecting the label and pressing ‘X’ to list all cross-references to that particular label (or identifier).

CTRL+X’ shows us cross-references to the address (cursor’s selection does not matter as it is worked with addresses not identifiers). ‘CTRL+J’ shows us cross-references from the address

Cross-references to the offset, ‘aCopySToSucces’

Here, we can find the following information:

  • Direction: Whether the target reference is at a higher (Down) or lower (Up) address
  • Type: Type of the cross-reference
  • Address/Text: Address of the target reference and the actual code/text at that particular address

Similarly, we can also view the information in a graphical view. Select ‘View’, Go into ‘Graphs’ and select either of the three xref charts available. You can:

  • View xrefs from the identifier (where the reference ‘goes to’)
  • View xrefs to the identifier (where the reference ‘comes from’)
  • Use a custom xref chart with several customization options (this is particularly helpful in larger binaries and to filter out unhelpful identifiers)
Custom XREF chart in IDA

Types of Cross-references

From the official Hex-Rays documentation [2], we can find 13 types of cross-references. A few of these cross-reference types are listed below:

  • O: Offset — Address is taken by the identifier selected by the cursor (there’s no read or write operation here)
  • R: Read access — Data is being read from the address
  • W: Write access — Data is being written at the address
  • J: Far (Inter-segment) jump — Code being jumped to is in a different code segment than the current segment
  • j: Near (Intra-segment) jump — Code being jumped to is in the same code segment as the identifier
  • P: Far (Inter-segment) call — Call is in a different code segment
  • p: Near (Intra-segment) call — Call is in the same code segment

Conclusion

Cross-references can be really helpful when reversing binaries. You can quickly identify the purpose of a function by identifying its calls or look for interesting code by the data it references. Hopefully, this guide was a quick hands-on to getting started with cross-references.

References

[1] Hex-Rays’ Tip of the Week by Igor

[2] Cross-reference Attributes

[3] Adding Cross-references

Hi, I’m Syed. Explore my articles as I embark on this journey of learning more about Forensics, Threat Hunting, and Cyber-threat Intelligence.