Is it possible to also type out who the item belonged to? This would make for an exceptional loot log for map runs.
Is it possible to also type out who the item belonged to? This would make for an exceptional loot log for map runs.
Double check you're trading with me in case of impostors
whoa very nice! anyway to turn this into an simple auto looter?
Thanks for the update man
I wonder one thing though, how did you come up with the adjustment part?
Static BP addresses then add it with a changing baseaddress subtracted with a static value.
I find it very impressing.
Code:BP0 = 0x005B3E99 BP1 = 0x005B3EDD BP2 = 0x005B3EDF self.baseAddress = self.getBaseAddress() adjustment = self.baseAddress - 0x00400000 ItemAlert.BP0 += adjustment ItemAlert.BP1 += adjustment ItemAlert.BP2 += adjustment
It's actually the "less simple" way of doing it.
Typical base of an EXE is at 0x00400000. Code section is typically starts at 0x00401000.
When you find an address in the code section, say 0x005B3E99, you'd store the offset relative to the start of the base or the code section (I prefer the code section myself, but I see why people use base, less work).
That results in: 0x5B3E99 - 0x00400000 = 0x1B3E99. You would typically store that as your 'offset'.
When you go to apply the patch in an EXE that has a different base address, mostly due to ASLR / being in a DLL, you just add the offset to the new base address.
That'd be: finalAddress = self.getBaseAddress() + offset [0x1B3E99]. That's the address you have to patch, and are done. When it's time for updates, you just update the offset, as expected.
What he's doing though, is storing the original address to patch, and re-calculating the offset each time.
That is, if you keep in mind basic math operations: finalAddress = staticAddress [0x5B3E99] + self.baseAddress - 0x00400000.
Re-arranging the equation into something that makes more sense: finalAddress = self.baseAddress + (staticAddress [0x5B3E99] - 0x00400000).
That "staticAddress - 0x00400000" is simply the 'offset' that you'd normally otherwise calculate in the first place.
So in the end, it works the same, but it's just not the typical way you see it done, because most people just fold the static address and the base address into a single offset.
thank you for the program. I was wondering since you can intercept server messages if you can also intercept the chat messages? This would be very useful if it can parse through all the link items in chat and filter it
Hmhm, 'who' being an enemy NPC or another player? Not sure to be honest, might look into it when I'm really bored but I have some other stuff to do at the moment.
Pretty sure (although I haven't actually tried forging loot packets) looting requires movement - I guess that would make an auto looter pretty weak?
Great explanation. It might be the "less simple" way for Python as it has to do another arithmetic operation, but it's simpler for me as I just have to copy the address out of IDA (I'm lazy!).
Intercepting chat messages is no problem, but the item parsing is a pain. Maybe sometime in the future..
I've been doing the research on a pickit for my current (private) project. There are 3 main aspects to it:
1. Everything related to the item itself (id, type, position, etc...)
2. The "action index" bytes in movement/interact packets (This makes packet forging non-trivial)
3. Sending the packet in the client, as such you don't desync it with the server (in respect to both encryption and action index bytes).
The interact/movement packets are similar, but not the exact same. You can only send 1 interact packet to loot something without having to worry about moving there first. The main issue of course, is if your character can move there safely and unobstructed.
Then of course, there's always the issues of pickit logic and being able to repickup an item if it's not yours and other nice features, but those come later.
The pickit distance is going to cause the most problems I think (if it's too large). When you are playing the game, your movement packets will cancel out the pickit packets. This means if you are not doing it for a bot, you have to solve the issue of when a player wants to move after a pickit packet has been sent and keeping track of the fact the pickit didn't go through yet. This will create some issues if your pickit wants to loot something in a dangerous area that you'd rater not stick around in.
Those things are not unsolvable, but I just think the pickit is going to be at best a "press this key to auto-loot" button rather than something fluid that requires no user interactions. Who knows though, maybe someone will come up with something creative.
Great explanation. It might be the "less simple" way for Python as it has to do another arithmetic operation, but it's simpler for me as I just have to copy the address out of IDA (I'm lazy!).![]()
I would suggest in either case, coming up with an offset based signature search system to do all the work for you. Do it sooner, rather than later, because once you have it done, you'll never use static addresses again. In my current project (C++/ASM), I use such a system so each client update, I just rerun my offset generator, and if anything breaks, check out the signature and fix it. For a game like PoE that will patch quite often, it's invaluable!
I just realized the other day as I was randomly thinking about this stuff that I've had a solution to the packet parsing problem all along. I never came to the realization in PoE, but I've done the exact same in other games, just forgot about it since it's been a while.Intercepting chat messages is no problem, but the item parsing is a pain. Maybe sometime in the future..
I write packet analyzers based on client hooks that dump the data as it's parsed/built. This means I can get the exact packet structure from the client for all packets. This pattern works fine in most games, except for the ones where they build the packets by hand by using (stupid) pointer magic with casts.
Anyways, the analyzer's output looks like this. ASLR friendly call offsets along with the data of the parse/build. All along I've been trying to figure out how to achieve the same in the client, without having to keep track of client state, incomplete parses, etc...
Then I realized all the work is already done. All I have to do is process the already parsed packets (rather than just send them out to the analyzer). Essentially,, I've created a packet framework for "read-only" access to the packets the client "knows" about, which I think is what you want for most packet/memory hybrid based tools.
I'll give you a practical example. Let's say an item drops:
We would know that:Code:[S->C][F0][0x1E914E] [0030186A] 54 92 8A 3A T..:............ [001F1523] 00 00 14 C3 ................ [001F1546] 00 ................ [001F3F7F] 00 00 00 FC ................ [001F3F98] 00 00 00 EE ................ [001F3FAD] 40 83 8A 07 @............... [001F3FC4] 02 00 00 00 ................ [001F3FD0] 3F 80 00 00 ?............... [001F3067] 00 ................ [00235D71] 00 00 00 00 ................ [00235DAF] 01 ................ [0018EA51] D5 68 64 2E .hd............. [0018EBFF] 00 ................ [0018973C] 67 4E gN.............. [0018975C] 00 00 ................ [00189776] 00 ................ [0018B70F] 00 00 00 00 ................ [0018B725] 00 ................ [0018AD6C] 00 00 00 00 ................
0030186A - parent item type offset
001F1523 - id offset
001F3F7F - x offset
001F3F98 - y offset
00235D71 - owner id offset
0018EA51 - item name offset
This means, we can easily take the item's owner, and check all other stored 0xF0 packets until we found the id (keeping in mind 0xF2 packets). Once we found the already parsed 0xF0 packet, we'd just go directly to the [offset] where the name was parsed and have our owner's name.
This approach would then save us from having a billion client patches and injected code to steal the data as we need it from memory. We could just keep track of all parsed packets and process them each time we need something that we would otherwise have to access the client's memory for.
So, I think if you want to do tools and stuff of that nature, you really want to setup a packet framework like I have so you let the client do all the work for you, and then you can easily just process parsed packets to get the information you need. You will still need various in memory client patches and codecaves (such as for the pickit, for example), but you are no longer at the mercy of the packet protocol and fully dependent on finding how to access the parsed packets in memory.
Yeah, I just looked at the C->S 0x0D looting packets. They seem simple enough (just using 0x0000 for the counter didn't seem to cause a desync, but I guess that's a bad idea), but unfortunately they cause the server to move the character if he's out of range, so as you stated, the solution wouldn't be all that pretty.
Yeah, for my real projects (read: private) I favor C++ with HadesMem and some private libraries that bring all this. This project will not evolve any further, I merely wanted to get some discussion started here (I guess I've succeeded!). I'm also not sure if I'll continue working on PoE.
That sounds like a very sound approach. But I guess there's still quite some manual work involved as you have to check out the conditional execution paths as well, otherwise you won't know why the x/y offsets for example shifted by 4+ bytes in the packets.
Ultimatively though, if I ever make a large PoE project, it will probably be a headless bot, which means I'd have to reverse the packet structure anyway..
I really appreciate your answers!
I finished my simple pickit tonight and I see what they are doing now. I guess I over-estimated the importance of those bytes. Typically, most mmos that use a similar system will disconnect you as soon as you get out of order.
However, with PoE, they are simply using it as client prediction sequence bytes. That is, you send the server a bunch of movement/interaction packets, the client buffers those based on the sequence id, then based on the sequence id in the server response packet(s), the client handles the prediction of where you should be relative to where you were, as the server replies to only some of those packets.
I see now why this game has such bad desyncs. This system really needs to be rewritten.
I'd recommend not ignoring the bytes altogether, as that could be detected (I'd assume they'd have to change up some stuff to make that happen first), but it's more or less pointless for them to try that until it's actually a problem (imo, until they fix desyncs, never).
In my current method, I keep the bytes in order, but the client won't "know" that I've moved until I /oos (which forces a state update). I'd assume this is because I'm not queuing the interaction packet's sequence number internally, so when the client gets the entity update packet for my character, it doesn't process it. I guess this could be fixed, but I don't see the point in doing it right now really.
Since loot is not FFA, trying to ninja grab something is no easier with a pickit. If anything, I think it'd be worse due to the desync that you can incur if you are not right on top of the item. As it stands, the amount of desync in the game makes it so regular looting can be hard enough. Anyone that's played for a while knows how sometimes they try and pickup an item, but cannot. That's essentially due to desync.
At best, I think a pickit can give an advantage if you open a chest or kill a boss and are right on top of the loot drops, and everyone else is close enough to where the timer runs out fast, but there's too much loot on the screen to pickup items without toggling item names to get rid of the name spacing. That's pretty sad, actually.
Oh well, I'll work on trying to make mine better over time if i stick around the game, but as I initially thought, unless you are making a bot, I didn't see a pickit being that useful in this game given the current state of it. I think the item alerter gives the biggest advantage as you can make it notify you when something drops so you can react to it yourself. Due to things dying off-screen, I think an item alerter has a lot more practical uses too.
Very interesting.. and odd. I guess they'll be doing quite some changes still, before they release it officially.
Haha yeah, I was just testing what I could get away with.
Quite possible. Unless you're botting, auto looting seems rather clunky.
May I suggest adding this bit of code into NotifyItems.py? It's what I'm using at least.
keywords = ["Map","Gems","Currency"]
for key in ItemList._items:if any(x in ItemList._items[key][2] for x in keywords): _notifyItems.append(ItemList._items[key][1])
That will filter for any currency, skill gem, or map. The only thing worth filtering for besides those are 6 gem and 5 link items. I think if you're going to add anything, you should add 5 link and 6 gem items before anything else.
Because you don't know I'll point out that the only thing people care about when deciding to pick up an item are:
-Is it a gem, map, or currency?
-Does it have 6 sockets?
-Does it have 5 links?
-Is it rare or unique?
That's pretty much it. If you cover those your notifier is perfect. I can do the Python myself but I've never dabbled with processing packets. I assume you need to figure out what the code is for number of sockets and number of links? Or is it more complex than that?
Last edited by Rhynocerous; 02-07-2013 at 10:58 AM.
Done, thanks for the hint!
Thanks for the information, I had no idea what's useful and what isn't. I'm guessing rare and unique items are the ones that are 'unidentified' when dropped? Does that mean that even the gray items may be of value in this game?
You'll notice from my code that I've never actually 'learned' Python - it's pretty much 100% trial & error, and browsing the Python documentations on 'How do I do X?'. That explains the messy / ugly code. Nevertheless, I love the language for its deployment speed and the abundancy of available libraries.
You're right, I'd need to find out where this information is stored in the packet. There are a couple of ways on how to find this information, but I'm afraid that all can be quite time consuming (at least for me, I'm by no means an expert).
One way would be to gather lots and lots of WorldItem drop packets (and remember the item stats), and then basically "look at the data" and find out what it could stand for / how it correlates with the remembered item stats. That's obviously prone to errors (guess work invovled) and tedious. It would also require a high level character to get a huge variety of item drops (what are links?).
Another way (what I've been doing) is to analyse the client and go through the deserialization code of the packet, which reveals certain information step by step. It will show me which bytes of the packet are interpreted as floating point values (presumably coordinates and rotation), which ones are treated as groups-of-4-bytes (integers), how they are used, etc. The thing here is once again that it would require a lot of time and possibly also a high level character to get special drops.
pushedx explained the second approach (more automated, based on hooking the parsing routines) in much greater detail.
Basically, it all comes down to investing time (leveling up a character & learning the game, or what's valuable in the game, and then the actual reversing). I may eventually try to reverse the whole packet structure for WorldItem drops, but I can not give any guarantees - I'd probably be more motivated if I actually cared about the game.
There are 4 "rarities" of items, magic, rare, and unique are unidentified. Magic items in general aren't valuable.
Items can also have gem sockets that are linked together. Any item with 5 linked sockets or 6 linked sockets are automatically more important to pick up than a random rare. They also do not get assigned to anyone, so anyone can pick them up right away which would make an notifier very valuable.
"Links" are literally links between gem sockets that connect them allowing you to use support gems. They are very critical, you essentially need well linked equipment. If a chest armor piece for example has 6 sockets, they could have 5 links that connect them all in a chain, or maybe only one link that connects two sockets, with the rest all un-linked.
Thanks for the explanation, if you end up stopping I will continue with what you have. I would also just use a trial and error approach to get the packet information I'm looking for, which would be sockets and rarity. This is certainly a tool that would be used.Basically, it all comes down to investing time (leveling up a character & learning the game, or what's valuable in the game, and then the actual reversing). I may eventually try to reverse the whole packet structure for WorldItem drops, but I can not give any guarantees - I'd probably be more motivated if I actually cared about the game.
Last edited by Rhynocerous; 02-07-2013 at 03:36 PM.
Yeah umh, right. I know some of these words, yeap.
But anyways, how would range check work? Is it even possible? Like be within looting radius and the looter kicks in?
And about items.. Even magic items like rings with 12 % all resistance(prismatic ring) + 10% attack speed would be valuable since you can just add an currency orb for it to make it rare and put some extra stats on it. And in general if your item has higher Item level it can roll different stats / stats go higher if comparing 30 ilvl ring vs 68 ilvl ring.
Thanks for the explanation, makes sense.
The problem with this approach is their packet serializing/deserializing. In many games, packets have a consistent format regardless of the actual contents. For example, you could imagine a game sending the client object updates (i.e.: object with id 5 has moved to coordinates {x,y,z}). Let's say these packets have the id 1 (always).
Internally, it might be represented in the following manner:
struct ObjectUpdatePacket
{
byte pac****pcode;
int objectId;
float x, y, z;
};
When they want to send this over the network, it might look like this (ignoring host / network endiannes for now): [01] [05 00 00 00] [x ........ ] [y ........] [z .........].
Any time you receive a packet with id = 1, you'll know that the x, y and z coordinates are at offsets 5, 9, and 13, respectively.
In PoE, this is not the case. Their packet (de)serialization is very conditional, meaning that depending on the data in the packet, some things might have moved or might not even be present in the first place. Basically, there are 1-byte fields that say if some other field is present and in some cases how many will follow. This makes the whole thing a bit more annoying, and if you're trying to parse packets manually, you'll actually need to know the deserialization logic for said packet.
I'm actually doing just this partially in my code already, but a lot is still missing. In parseWorldItemPacket, you can see the following:
If unk3 >> 2 is not zero, the deserializer has to read another 2 integer values in the packet before proceeding. This means that everything that follows will have moved 8 bytes inside the packet.Code:... if unk3 >> 2 != 0: print >>self.logFile, 'The following packet has an odd unk3 field:' print >>self.logFile, self.dbg.hex_dump(map(lambda x: chr(x), packetData)) buffer.nextDword() buffer.nextDword() ... if unk5 != 0: buffer.nextDword()
If unk5 is not zero, the deserializer has to read yet another integer (apparently, this is group related). This again means that the rest (for example, the itemTypeId we're interested in) will have moved yet another 4 bytes inside the packet.
@Jonsbe: Thanks for the information. About the loot radius: Any time an item drops, you get its location from the server. You can also either read out your current position from memory or parse object update packets which contain your coordinates as well. Then it's a simple matter of sending out 0x0D packets (looting packets) if you're close enough to the item / any item.