PWI - Guide for finding chat message offsets - C# code included

11/20/2012 12:10 dumbfck#151
I don't know which client version you have, but try 0x5D0 instead of 0x800 and see if there's anything there.
Otherwise, we'll probably have to dig a bit deeper.
11/26/2012 13:22 AHTOLLlKA#152
thx you dumbfck!
all work, but i cant get some description, i mean i do:
Quote:
var
Buff : Array[0..800] Of widechar;
buf,wr:dword;

begin
readprocessmemory(process, ptr(BASE_ADDRESS+OFFSET), @buf, sizeof(buf), wr);
[0..800] - it is enough to describe, but some of the descriptions fail to get, but if I change the Buff: Array [0 .. 400] Of widechar;I get no errors, but long descriptions are cut off.what am I doing wrong? (((
11/26/2012 13:52 dumbfck#153
Hrm, I'm not sure about the specifics of whatever language that is you're using (Delphi?) but it sounds like perhaps when you're reading 800 bytes, sometimes your program wanders into unallocated or protected address space.
I used to use a function which manually read a string in small chunks until it found a unicode termination (0x00, 0x00).
It's a bit slower, but I found it was a lot more reliable for some of the things I was reading in.
Here's a snippet - It actually had an option for double terminator (e.g., two bytes of 0x00) or triple (three bytes of 0x00) because it was actually possible to have two 0x00 bytes in the chat box text which wasn't actually a terminator!
You should be able to disregard that part though and just look for double termination.
This isn't a particularly elegant piece of code. There may well be a single line solution in your programming language. Maybe someone else here can help?

Code:
    // This one will be a bit slower, but will hopefully eliminate returning empty strings where 
    // the address + size is not in accessible memory, resulting in a failure from ReadProcessMemory.
    // Bytes are read in chunks of [chunkSize] size and chunks are scanned for 0x00, 0x00 (i.e., 
    // end of string). If this is not found, we read another chunk, repeating until the string 
    // terminator is found.
    // This might also help with reading enormous strings (e.g., complete chat listing) until I find 
    // a better solution for working around the maximum memory size that can be read
    public static string MemReadUnicodeToEnd(IntPtr processHandle, uint address, uint maxSize, uint chunkSize, ref uint _bytesRead, bool doubleTerminator = false)
    {
        bool success;
        byte[] buffer = new byte[chunkSize];
        byte[] bigString = new byte[maxSize];
        UInt32 nBytesRead = 0;
        bool exit = false;
        uint i, j, currLength = 0;
        do
        {
            success = ReadProcessMemory(processHandle, (IntPtr)(address + currLength), buffer, chunkSize, ref nBytesRead);
            _bytesRead = nBytesRead;

            System.Buffer.BlockCopy(buffer, 0, bigString, (int)currLength, (int)chunkSize);
            currLength += chunkSize;
            if (!doubleTerminator)
            {
                for (i = 0, j = chunkSize - 2; i < j; i++)
                {
                    if (buffer[i] == 0 && buffer[i + 1] == 0)
                    {
                        // We found the string terminator
                        exit = true;
                        break;
                    }
                }
            }
            else    // Full chat listing can contain more than two consecutive 0x00 bytes because of item links.
            {
                for (i = 0, j = chunkSize - 3; i < j; i++)
                {
                    if (buffer[i] == 0 && buffer[i + 1] == 0 && buffer[i + 2] == 0)
                    {
                        // We found the string terminator
                        exit = true;
                        break;
                    }
                }
            }
        } while (!exit && currLength < maxSize);
        _bytesRead = currLength - chunkSize + i;
        return ByteArrayToString(bigString, EncodingType.Unicode);
    }
11/26/2012 14:13 Shareen#154
I'd look for size indicator. If message is allowed to contain terminator char that isn't used as a terminator, then other way for code to know how big the string is, is to write down length of it somewhere.

Some strings in PW I operated on, used to have length stored in textOffset - 8 bytes, check there if you haven't already.

Quote:
0..800] - it is enough to describe, but some of the descriptions fail to get, but if I change the Buff: Array [0 .. 400] Of widechar;I get no errors, but long descriptions are cut off.what am I doing wrong? (((
You say you get no errors by using buf size of 400. Are you getting errors with 800 buf size? If so, what are they? Did you check the below links?

Read docs on ReadProcessMemory, things like this, for example:
Quote:
Originally Posted by msdocs
If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError.

The function fails if the requested read operation crosses into an area of the process that is inaccessible
[Only registered and activated users can see links. Click Here To Register...]

[Only registered and activated users can see links. Click Here To Register...]
11/26/2012 21:48 Interest07#155
Quote:
Originally Posted by Shareen View Post
I'd look for size indicator. If message is allowed to contain terminator char that isn't used as a terminator, then other way for code to know how big the string is, is to write down length of it somewhere.

Some strings in PW I operated on, used to have length stored in textOffset - 8 bytes, check there if you haven't already.



You say you get no errors by using buf size of 400. Are you getting errors with 800 buf size? If so, what are they? Did you check the below links?

Read docs on ReadProcessMemory, things like this, for example:


[Only registered and activated users can see links. Click Here To Register...]

[Only registered and activated users can see links. Click Here To Register...]


Yeah this was my issue when I sometimes randomly didn't manage to read item descriptions :p Here I was thinking I hadn't found the correct function to update descriptions, when it was something so simple ;) Goes to show how important error checking is anyway.
11/27/2012 19:07 AHTOLLlKA#156
thx! now can get full wide-string :))

now i try get chat info... can get message but when someone send item to sell and i grab this itemID i get ID at $C but this ID wrong (if search at pwdatabase.com)
i try brute force this offset but dont have right value =(
mb this ID something else not itemID ?
or mb something else?? anybody know ?

UPD.... got it... just pointer.. ^^
and another quest \=
how 2 find desription for item in chat??
11/28/2012 10:09 dumbfck#157
Chat item descriptions are very very tricky to find lol.
It's been a long time since I really worked on this stuff, and I don't really do much of this stuff anymore... But if for some reason I decide to revisit any of it, I'll see what info I have about this ;)
One of the problems with the item objects for the chat system is that sometimes, when a new message appears, all the item pointers get moved around. This can potentially happen when you're halfway through reading it (which I have observed before!).
On the system I was working on, I used an injected DLL which hooked parts of the chat system, so every time a new message appeared, the message and any linked item info was all read in real time.
Worked very nicely indeed, but it was a real bitch to get it all working in the first place.
11/28/2012 11:38 AHTOLLlKA#158
if i click some item in chat then i can get description... now i try 2 find way to simulate this "click", but dunno how (
11/28/2012 11:45 dumbfck#159
Yeah, there's a function you have to inject. That's what I can't remember at the moment as it's all on my computer at home (and probably out of date!).
I'm fairly sure the function is located in the vTable for either the item object or the chat window itself.
11/28/2012 12:30 AHTOLLlKA#160
Quote:
Originally Posted by dumbfck View Post
Yeah, there's a function you have to inject. That's what I can't remember at the moment as it's all on my computer at home (and probably out of date!).
I'm fairly sure the function is located in the vTable for either the item object or the chat window itself.
damn, dont like injecting \=
u mean i can find chat message and etc use window offsets like BASE_CALL+1C+18]+8+xxx ?? and can find some vTable here ?
11/28/2012 12:47 dumbfck#161
Yep, most objects have vTables.
They're always at [[objectBase]+0]
You'll know when you've found one as it will be an unbroken list of values that are all within the elementclient address space (e.g., 0x00451840 (I made that one up)).
How big that list is depends on the complexity of the object, although even the simplest objects generally seem to have at least 10 member functions.
Sometimes, when I find a vTable, I just put breakpoints on a bunch of them in OllyDbg and see what happens when I do stuff with that object in-game :D
Normally the first bunch of entries are low level functions for drawing / rendering, etc, so I normally start putting breakpoints on at about 0x20.
If when you put the breakpoint on, it breaks instantly, that's normally because it's something very low level, and can thus usually be ignored.
I've found some really cool stuff by doing this lol. You'll need a lot of patience though as this is kind of coming from the opposite direction of the sort of stuff you'd do with CE.
With CE, you know what you're looking for and you trace backwards to see where it happens.
When just 'playing' with vTables, you're generally observing what sort of behaviour triggers a function call but you don't know what you're looking for! Then you try to figure out if it's useful, what it does and what memory it modifies.
Except of course in this case; You have a hunch that there's a function you're interested in in a vTable, then you're kind of taking a shortcut to finding it.
Either way, vTables are a lot of fun lol.
11/28/2012 13:15 AHTOLLlKA#162
can u tell offset for some1 vTable, i just want to look at this... coz if so hard i give up ((
11/28/2012 13:30 dumbfck#163
Well an example of a function that can be found in a vTable is the function used for updating an item's description in your inventory:
[[[itemBase]+0]+0x40]
Where [[itemBase]+0] is the vTable base, then you'll find the address of the function that is called 0x40 higher than that base.
When I get home, I'll take a look for some more examples.
11/29/2012 12:47 AHTOLLlKA#164
Quote:
Originally Posted by dumbfck View Post
When I get home, I'll take a look for some more examples.
ahhh dont leave me dude ^^
F5 this page all day :D
11/29/2012 12:58 dumbfck#165
Sorry, I was really busy doing other stuff at home last night.
I don't finish work for another 6 hours yet, so don't waste too much time refreshing this page lol.
I'll try my best to find some time this evening to take a look.