Skip to content

Accessing temple.dll Data and Functions

shartte edited this page Apr 8, 2015 · 2 revisions

This is a short guide on how to properly access global data items and functions from temple.dll using the infrastructure provided by TemplePlus.

Imagine for example the following structure that has been identified in temple.dll as a global variable:

struct TigMouseState {
	int flags;
	int mouseCenterX;
	int mouseCenterY;
	int cursorTexWidth;
	int cursorTexHeight;
	int cursorHotspotX;
	int cursorHotspotY;
	int x;
	int y;
	int field24;
};

The data in temple.dll resides at virtual address 0x10D25184. To access this data, one could simply declare a pointer like this: auto *mouseState = (TigMouseState*)0x10D25184 and use it to access the mouse state.

This generally works, but has one very big problem: The operating system sometimes relocates a DLLs virtual memory space and this is unpredictable. Sometimes when you start, temple.dll may not be at 0x10000000, but at some other offset, making the above code mostly crash.

To account for this, TemplePlus provides several different helpers that will automatically rebase your pointers to the actual address of temple.dll in memory.

To do this without much hassle for lots of pointers, the AddressTable base struct has been introduced.

This can be used like this:

struct TigMouseAddresses : AddressTable {
  TigMouseState *state;

  TigMouseAddresses() {
    rebase(state, 0x10D25184);
  }
};
TigMouseAddresses tigMouseAddresses; // Global variable in TemplePlus

The rebase method used in the constructor will queue the pointer to be rebased once temple.dll's actual offset in memory is known to TemplePlus. You an then access the mouse state using tigMouseAddresses.state->x for example.

The same technique can be used to access global functions in temple.dll. Once the function signature and calling convention of the function one wants to access are known, a function pointer can be declared and rebased using the same mechanism as shown above.

Using another function from tig_mouse, SetPos as an example:

void (__cdecl *SetPos)(int x, int y, int wheelDelta);

Almost all functions in temple.dll are using the __cdecl calling conventions (caller cleans the stack, all arguments passed on the stack). This function sets the position of the mouse to the given x, y coordinates and applies the given mousewheel delta. It can be found at address 0x101DD070 in temple.dll

After adding the function, our address table looks like this:

struct TigMouseAddresses : AddressTable {
  void (__cdecl *SetPos)(int x, int y, int wheelDelta);
  TigMouseState *state;

  TigMouseAddresses() {
    rebase(state, 0x10D25184);
    rebase(SetPos, 0x10D25184);
  }
};
TigMouseAddresses tigMouseAddresses; // Global variable in TemplePlus

To call the function in temple.dll, one can now simply use this syntax:

tigMouseAddresses.SetPos(1, 2, -1);
Clone this wiki locally