Skip to content
d3dev edited this page Apr 4, 2015 · 5 revisions

d3_tooltips opens the 'Diablo III.exe' process and scans its 32 bits virtual memory from 0x06000000 to 0x30000000. It uses the VirtualQueryEx Microsoft API function to retrieve information about a range of pages.

d3_tooltips reads the memory and tries to locate data structures I call tooltips:

ToolTip

Legend of the picture:

  • Light blue : ToolTip hash
  • Green : HexSpeak magic number (GOODFOOD)
  • Red : A flag defining the state of the tooltip's string (visible / hidden)
  • Purple : The string pointer
  • Yellow : A 24 bytes constant pattern

Tooltip structure begins with an 8 bytes hash, followed by the path of the tooltip. (Actually the structure beginning is before, but I don't care). 0x210 bytes after, another 8 bytes hash corresponding to the parent's tooltip hash is expected. Those two patterns help to identify the tooltip when searching for an item name or it's durability. Then, to ensure that the structure is a tooltip, a particular value (0x600DF00D : HexSpeak "GOODFOOD") will be checked at given offsets (0x458, 0xA68, 0xAB0, 0xB00, 0xB60, 0xBE8). Because it is not enough, a 24 bytes value is expected at offset 0xC14. When all expectations are fulfilled, the value at offsets 0xA28 or 0xC2C should be the string pointer we are desperately looking for. So it saves that pointer and go further.

At the end of the memory scan, d3_tooltips checks that all required tooltips have been found, and register a global shortcut so the user can trigger the capture in game.

For each shortcut events received, the target of the previously saved string pointer is captured, but that is not enough.

Let's take an example. Mouse hovers over a sword with 35 durability. The durability tooltip creates a new string 'durability : 35/35'. Then mouse hovers over a potion which has no durability, but the durability tooltip keeps pointing at 'durability : 35/35'. For efficiency reasons, the string will not be cleared, only a flag would say if the tooltip is active/visible/rendered or not. That flag is 0x784 bytes before the string pointer.

Clone this wiki locally