Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

Example of how to find stash data from bottom up (using cheat engine):

Start with an empty stash and toss some items into it to give it numbers.

Scan for that number (5),

Remove an item, scan for 4, rinse and repeat until you get down to a few results.

Add the value to your cheat table and hit find what accesses on it. I picked all 3 and started with
the first and worked my way down.

Right click on the address and pick “find what accesses this address”:

You’ll get a blank window.


Pick up and drop an item and it’ll populate with a hit.
Go ahead and hit stop.
Pick the first one and hit show disassembler, then add a breakpoint. Move your item around
again and you should only get 1 hit. In my case, I had like 5 hits. A “hit” is when the breakpoint
is triggered and pauses the game.

I didn’t like having 5 hits so I went ahead and went to the next address.
Same process. I took the screenshot after doing it a few clicks but here:
I put a breakpoint on the first op, cmp[rsi+10],rax as above, and it hit instantly. I resumed the
process and it hit again, ok, removed the breakpoint because this is hit too often to filter and I
don’t want to put a codecave on it.
Go down to the next op, mov r8,[rsi+10]

This time it hit only when I moved the item and we have some valid data. Now, how is this
useful? Well! In the bottom right, pathofexile.exe+offset, the first one is the call’s return, which
we can click and scroll up to see the parameters of the call.

Keeping in mind that this is an object with inheritance and this is a class function (how can you
tell? Well it’s generally good programming practice for this sort of application, but also the RCX
register is populated with the “this” class pointer. We want that.

So clicking that return address takes us here:


I want a breakpoint above the call, and keeping in mind that I also want to read RCX and the
assembly says rcx is set on that third line, we want to break after that point (or just read it from
r15, which is what I plan to do as that is a base class + an offset) and afterwards, move your
item again. Keep in mind to resume the thread afterwards so you don’t get disconnected and
have to login repeatedly.

So this gives access to R15, which we can see is blahblahblah270. Wrapping it in brackets as
[blahblah270+3c0] means to read value of that address plus offset. So whatever our item’s
count is, it is stored inside a class (RCX) and that class is at some class + 3c0.

Something to note, because it says “lea rcx” and not “mov rcx”, it is a class object and not a
class pointer. This can be a little confusing but the thing to take away is that mov [] means it’s a
ptr and lea [] means its not. So in CE we can add this as Address: blahblah+3c0 and it will give
us what is currently residing in rcx. Blahblah630, (that’s also just the math behind it)

Now we can skim through the code and be sure that rsi isn’t changing inside the function before
previously found opcode is hit (it isn’t) and see that blahblah270+3c0+10 is actually equal to our
address in cheat engine. +5.
You’ve found the base class to that stash! Blahblah270+3c0 is the instance of the stash tab
object that includes the count, +10 is the count of items in it, and blahblah270 is the parent
class.

Now how do we get the items and not just the count? So this is where a bit of experience comes
in to play. We know that POE uses UI elements that have a parent and children. We know we
are in the stash UI element. We know the item we are looking at is a child. We know that
blahblah270 is the parent. Therefore, we can know that blahblah270+childoffset(0x30) is the
first child.

We also know that blahblah270 is that stash tab.

Therefore, we can view that offset as a pointer,

Then right click in the hex view at the bottom and change display type -> 8 byte hex.

These are the pointers to your list of items in the stash.


The first 6 are valid pointers, so after that is garbage. If I add an item it should append to that list
though. (EASY confirmation here)
It is important to note that removing an item does not guarantee the memory will go away, as
that is part of garbage collection and probably not needed. There’s a second offset we can use
for that, +0x38. Again, this is inherited knowledge from it being a UI Element and +0x30 is the
first child and +0x38 is the terminator.

You can push and pull items into the list to see it populate and the +0x38 ender change to match
the list as you see fit.

You might also like