srounet / Pymem

A python library for windows, providing the needed functions to start working on your own with memory editing.
MIT License
305 stars 46 forks source link

How can I combine a list of several offsets? #4

Closed ghost closed 7 years ago

ghost commented 7 years ago

I can't seem to find out the method of combining offsets with an address to get the desired value.

If these are my offsets scanshopinventorynameoffset = [0x0, 0x30, 0x0]

shopinventory[i][0] = pm.read_int(0x0536258+ scanshopinventoryidoffset)

I'm guessing I'm doing this completely wrong.

Could you please just clear this up for me? It is taking longer than I expected to get this right.

ghost commented 7 years ago

I've also tried stuff like this

    shopinventory[i][1] = pm.read_string(0x0536258 + scanshopinventorynameoffset[0] + scanshopinventorynameoffset[1] + scanshopinventorynameoffset[2])
srounet commented 7 years ago

How did you get the offsets: 0x0, 0x3, 0x0 ?

You could try:

static_pointer_value = pm.read_int(0x0536258)
shopinventory_value = pm.read_string(
  pm.read_int(static_pointer_value + 0x30)
)

This may not work, but it depends on how you collected those offsets at first.

ghost commented 7 years ago

These are offsets for items in a shop inventory http://imgur.com/a/5lZiq

I'll give it a shot. 1 moment.

ghost commented 7 years ago

That gives me b'\x92\x01'

The first offset (0x0) is for each item in the shop's inventory. So += 4 bytes in the offset is the next item, and I loop through them.

ghost commented 7 years ago

Ok, I finally figured it out but it feels a bit long winded, is this intentional?

This gives me the desired value from those offsets. I didn't include the last 0 offset.

    static_pointer_value = pm.read_int(0x0536258)
    shopinventory_value = pm.read_int(static_pointer_value + 0x0)
    shopinventory_value = pm.read_string(pm.read_int(shopinventory_value + 0x30))

b'Small Heal Potion'

Is this how I'm supposed to deal with multiple offsets?

srounet commented 7 years ago

You can write your own wrapper function around pymem that deals with multiple reads for you:

def read_ints(pm, base, offsets):
    value =  pm.read_int(base)
    for offset in offsets:
        value = pm.read_int(value + offset)
    return value

shopinventory_value = pm.read_string(
  read_ints(pm, 0x0536258, [0x0, 0x30])
)
ghost commented 7 years ago

Thanks for your help, I've been coding bots for many years now using tons of different tools but this is the first time I've used Python. It is incredibly fast and cool to use. Your library is great too. Thanks.

Perhaps in the readme you should add an example on how to use multiple offsets for people like me who are self taught and can get confused easily.

PS

ID 225 | Name b'Small Heal Potion' | Weight 1 | Dura 0 ID 226 | Name b'Small Mana Potion' | Weight 1 | Dura 0 ID 48 | Name b'Healing Potion' | Weight 2 | Dura 0 ID 49 | Name b'Mana Potion' | Weight 2 | Dura 0 ID 342 | Name b'Large Heal Potion' | Weight 3 | Dura 0 ID 343 | Name b'Large Mana Potion' | Weight 3 | Dura 0 ID 342 | Name b'Large Heal Potion' | Weight 4 | Dura 0 ID 343 | Name b'Large Mana Potion' | Weight 4 | Dura 0 ID 50 | Name b'Antidote' | Weight 5 | Dura 0 ID 51 | Name b'Energizer Tonic' | Weight 3 | Dura 0 ID 331 | Name b'Demon Water' | Weight 4 | Dura 10 ID 332 | Name b'Heaven Water' | Weight 4 | Dura 10 ID 333 | Name b'Forest Water' | Weight 4 | Dura 10 ID 232 | Name b'G-Bird Feather' | Weight 4 | Dura 0 ID 604 | Name b'Small Heal Potion (PVP Event)' | Weight 1 | Dura 0 ID 605 | Name b'Small Mana Potion (PVP Event)' | Weight 1 | Dura 0 ID 606 | Name b'Healing Potion (PVP Event)' | Weight 2 | Dura 0 ID 607 | Name b'Mana Potion (PVP Event)' | Weight 2 | Dura 0 ID 608 | Name b'Large Heal Potion (PVP Event)' | Weight 3 | Dura 0 ID 609 | Name b'Large Mana Potion (PVP Event)' | Weight 3 | Dura 0 ID 608 | Name b'Large Heal Potion (PVP Event)' | Weight 4 | Dura 0 ID 609 | Name b'Large Mana Potion (PVP Event)' | Weight 4 | Dura 0 ID 141 | Name b'Candle' | Weight 1 | Dura 0 ID 181 | Name b'Torch' | Weight 1 | Dura 0 ID 346 | Name b'Resurrection scroll' | Weight 1 | Dura 1 ID 180 | Name b'Town Portal Scroll' | Weight 1 | Dura 0 ID 180 | Name b'Thousand Year town portal scroll' | Weight 1 | Dura 0 ID 180 | Name b'Guild Town portal scroll ' | Weight 1 | Dura 0 ID 439 | Name b'Single shout scroll' | Weight 5 | Dura 0 ID 158 | Name b'Shout Scroll' | Weight 5 | Dura 0 ID 441 | Name b'Yellow shout scroll' | Weight 5 | Dura 0

Yay!

srounet commented 7 years ago

You can also have a look to the RemotePointer class in the x64 branch which implements __add__ and let you do things like:

pointer = RemotePointer(process_handle, 0x0536258)
value = pointer + 0x0

I'm not at home so I can't give you an interesting snippet right now but in the x64 branch I'm using it a lot in my tests.