Deprecated: The behavior of unparenthesized expressions containing both '.' and '+'/'-' will change in PHP 8: '+'/'-' will take a higher precedence in /home/iano/public_html/tpforums-vb5/forum/includes/class_core.php on line 5842

PHP Warning: Use of undefined constant MYSQL_NUM - assumed 'MYSQL_NUM' (this will throw an Error in a future version of PHP) in ..../includes/init.php on line 165

PHP Warning: Use of undefined constant MYSQL_ASSOC - assumed 'MYSQL_ASSOC' (this will throw an Error in a future version of PHP) in ..../includes/init.php on line 165

PHP Warning: Use of undefined constant MYSQL_BOTH - assumed 'MYSQL_BOTH' (this will throw an Error in a future version of PHP) in ..../includes/init.php on line 165

PHP Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in ..../includes/functions_navigation.php on line 588

PHP Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in ..../includes/functions_navigation.php on line 612

PHP Warning: Use of undefined constant misc - assumed 'misc' (this will throw an Error in a future version of PHP) in ..../global.php(29) : eval()'d code(6) : eval()'d code on line 1

PHP Warning: Use of undefined constant index - assumed 'index' (this will throw an Error in a future version of PHP) in ..../global.php(29) : eval()'d code(6) : eval()'d code on line 1

PHP Warning: Use of undefined constant misc - assumed 'misc' (this will throw an Error in a future version of PHP) in ..../includes/class_bootstrap.php(1422) : eval()'d code(4) : eval()'d code on line 1

PHP Warning: Use of undefined constant index - assumed 'index' (this will throw an Error in a future version of PHP) in ..../includes/class_bootstrap.php(1422) : eval()'d code(4) : eval()'d code on line 1

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 85

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6

PHP Warning: Use of undefined constant onlinestatusphrase - assumed 'onlinestatusphrase' (this will throw an Error in a future version of PHP) in ..../includes/class_core.php(4684) : eval()'d code on line 6
Reading the Character List in 9.71
Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: Reading the Character List in 9.71

  1. #1
    Senior Member
    Join Date
    Apr 2008
    Posts
    689

    Reading the Character List in 9.71

    This update brought some changes to the character list. This "tutorial" will show you how to read it based on what I could find.

    Code:
    #define LOGININFO_ADDR 0x546CB0
    As long as structures don't change this is all you need! It is the address of the following structure:

    Code:
    #pragma pack(1)
    struct loginInfo
    {
    	uint32_t charListBegin;
    	uint32_t charListEnd;
    	char unknown[12];
    	textField accountName;
    	textField password;	
    };
    As you can see, this contains the pointer to the beginning of a list of characters on your account. The length of the list can be calculated as:
    Code:
    uint32_t length = (li->charListEnd - li->charListBegin)/sizeof(charListEntry);
    Now that you have charListBegin and length, all you gotta do is read an array of the following structure with that size:

    Code:
    #pragma pack(1)
    struct charListEntry
    {
    	uint32_t unknown1;
    	textField charName;
    	textField worldName;
    	union
    	{
    		uint8_t asByte;
    		uint32_t asUint;
    
    	} isPreview;
    	union
    	{
    		uint8_t asBytes[4];
    		uint32_t asUInt;
    	} worldIP;
    	union
    	{
    		uint16_t asUShort;
    		uint32_t asUInt;
    	} worldPort;
    };
    Code:
    ...
    	loginInfo* li = (loginInfo*) malloc( sizeof(loginInfo));	
    	if(ReadProcessMemory(clientHandle,(LPCVOID)(clientBase + LOGININFO_ADDR),(LPVOID)li,sizeof(loginInfo),NULL))
    	{
    		uint32_t length = (li->charListEnd - li->charListBegin)/sizeof(charListEntry);
    		charListEntry* charList = (charListEntry*) calloc(length,sizeof(charListEntry));
    		if(ReadProcessMemory(clientHandle,(LPCVOID)li->charListBegin,(LPVOID)charList,length*sizeof(charListEntry),NULL))
    		{	
    ...
    The attached code shows how to transverse the list and display the data. I have tested it with 2 accounts and seems to be working OK. Any improvement, question or bug report* is welcome.
    GL


    *only bugs regarding reading the character list itself please

    P.S.: For information on the textField structure, see http://tpforums.org/forum/thread-11358.html

  2. #2

    RE: Reading the Character List in 9.71

    delphi please... :<

  3. #3

    RE: Reading the Character List in 9.71

    Nice one, Farsa.
    I was gonna look into it but I got stuck re-doing my bots script threading model. Some changes to my Scripter revealed some pretty bad bugs with it

  4. #4
    Senior Member
    Join Date
    Aug 2010
    Posts
    532

    RE: Reading the Character List in 9.71

    Nice one, I used another address with similar structure that works too.

  5. #5

    RE: Reading the Character List in 9.71

    thank you very much awesome tutorial, helped me alot

    thats the function I'm using to change text_field into string (c#), might be useful to some1 :P

    Code:
     public static string text_field_to_string(byte[] array)
            {
                
                /*
                16 bytes - text or pointer for a text 
                1 bytes text length
                //3 bytes uknknown
                1 bytes field Type
                //7 bytes unknown
                 */
    	    int BytesReadSize = 0;
                int length = array[16];
                int type = array[20];
    
                if (type > 15)
                    {
                        if (global.reader != null)
                        {
                            IntPtr pointer = new IntPtr(BitConverter.ToUInt32(array, 0));
                            byte[] text = global.reader.ReadProcessMemory(pointer, (uint)length, out BytesReadSize);
                            return global.ByteArrayToStr(text);
                        }
                        else
                        {
                            return "";
                        }
                    }
                else
                    {
                        byte[] text = new byte[length];
                        for (int i = 0; i < length; i++)
                        {
                            text[i] = array[i];
                        }
                        return (global.ByteArrayToStr(text));
                    }
    
    
                if (array.Length < 28)               
                return "";
    
                return "";
            }

  6. #6

    RE: Reading the Character List in 9.71

    can someone write it in delphi ?:|

  7. #7
    Junior Member
    Join Date
    Dec 2011
    Posts
    25

    RE: Reading the Character List in 9.71

    I downloaded your code, C++ 2010 Express and compiled it.

    Worked exceptionally fine and I even got a smirk in my face lol, but unfortunately my program is developed in VB6.

    My needs are even smaller than what you put effort into. Since I don't need the “struct charListEntry” part, I removed it and its related code, therefore what I got was this (tested and working):

    [code=c++]#define LOGININFO_ADDR 0x546CB0[/code]
    [code=c++]
    #pragma pack(1)
    struct loginInfo
    {
    uint32_t charListBegin;
    uint32_t charListEnd;
    char unknown[12];
    textField accountName;
    textField password;
    };
    [/code]
    [code=c++]
    ...
    loginInfo* li = (loginInfo*) malloc( sizeof(loginInfo));
    if(ReadProcessMemory(clientHandle,(LPCVOID)(client Base + LOGININFO_ADDR),(LPVOID)li,sizeof(loginInfo),NULL) )
    {
    ...
    [/code]

    I so wish I could change the code above to VB6 language.

    In VB6 I have 3 types of ReadProcessMemory, they being Long, String and Byte. What type of reading is the ReadProcessMemory above doing?

    And is the * in loginInfo* a multiplier (I think so)? What does "li" stand for?

  8. #8
    Senior Member
    Join Date
    Jan 2012
    Posts
    417

    RE: Reading the Character List in 9.71

    I don't touch native languages in ages, but I bet it is a reference type (pointer to loginInfo). clientBase + LOGININFO_ADDR seems to be integer (the base pointer to structure) and since he is using "sizeof(loginInfo)", I think he is filling this loginInfo structure at this line.

    I didn't see the complete code, only the one you've posted and I'm not sure about all this, but seems reasonable.
    Farsa or any other c++ programmer can answer better than me.

  9. #9
    Junior Member
    Join Date
    Dec 2011
    Posts
    25

    RE: Reading the Character List in 9.71

    Farsa, I want to make your code the smallest possible, by removing both client.h and client.cpp. They are not necessary because I don't want your code supporting multiclienting, and they are also not necessary because I already have the PID number for reading the client in question.

    Only this data is needed:
    LOGININFO_ADDR = &H546CB0
    TibiaBaseAddr (static in WinXP) = &H400000
    Client Process ID (PID) = 12192

    So your code is much smaller and “compact”, and can no longer identify the clients or the base address or print “debugging” (?) MSGs.

    We are left with charlist.h (likely no changes needed)
    [code=c++]
    #ifndef _CHARLIST_H_
    #define _CHARLIST_H_

    #include <stdint.h>

    #define LOGININFO_ADDR 0x546CB0

    #pragma pack(1)
    struct textField
    {
    //0
    union nameField
    {
    void* ptr;
    char cstring[16];
    } text;
    //16
    uint8_t textLength;
    //17
    char unknown1[3];
    //20
    uint8_t fieldType;
    //21
    char unknown2[3];
    //24
    uint32_t unknown3;
    //28
    };

    #pragma pack(1)
    struct loginInfo
    {
    uint32_t charListBegin;
    uint32_t charListEnd;
    char unknown[12];
    textField accountName;
    textField password;
    };

    #endif
    [/code]

    And main.cpp (remove the excess code)

    [code=c++]#include <stdio.h>
    #include <stdint.h>
    #include <Windows.h>
    #include "charlist.h"

    DWORD clientPid=0;
    HANDLE clientHandle=0;
    HWND clientHwnd=0;
    DWORD clientBase=0;

    void printCharList();
    void getText(char* dst, textField field);

    void main()
    {
    if(getTibiaClient(&clientPid,&clientHwnd,&clientHa ndle,"TibiaClient",PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)==0)
    {
    if(getTibiaBaseAddress(&clientBase,clientPid))
    {
    while(1)
    {
    printCharList();
    system("pause");
    }
    }
    else
    puts("Error getting tibia base address...exiting...");
    }

    if(clientHandle!=0)
    CloseHandle(clientHandle);
    system("PAUSE");
    }

    void printCharList()
    {
    char text[256];
    int k;
    loginInfo* li = (loginInfo*) malloc( sizeof(loginInfo));
    if(ReadProcessMemory(clientHandle,(LPCVOID)(client Base + LOGININFO_ADDR),(LPVOID)li,sizeof(loginInfo),NULL) )
    {
    puts("======Account Info======");
    getText(text,li->accountName);
    printf("Account Name: %s\n",text);
    getText(text,li->password);
    printf("Password: %s\n",text);
    return;
    }
    puts("Error reading process memory...exiting...");
    system("pause");
    exit(0);
    }

    void getText(char* dst, textField field)
    {
    if(field.fieldType > 0xF)
    {
    ReadProcessMemory(clientHandle,(LPCVOID) field.text.ptr,(LPVOID)dst,field.textLength,NULL);
    }
    else
    {
    memcpy((void*) dst, (void*)field.text.cstring, field.textLength);
    }
    dst[field.textLength]=0;
    }
    [/code]

    This is all that I need! Can you or anyone else edit main.cpp to work straight with the data I provided in the beginning of this post? Your code doesn't need getTibiaClient and getTibiaBaseAddress because I already have provided you with the PID and Tibia base address for Windows XP (&H400000).

    Please

  10. #10
    Senior Member
    Join Date
    Apr 2008
    Posts
    689

    RE: Reading the Character List in 9.71

    this is the idea(did not check if compiles):
    Code:
    #define LOGININFO_ADDR 0x546CB0
    #define DESIRED_ACCESS (PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
    void main()
    {
            clientPid = 12192;
    	clientBase = 0x400000;
            clientHandle = OpenProcess(DESIRED_ACCESS , FALSE, clientPid );
    			while(clientHandle)
    			{
    				printCharList();
    				system("pause");
    			}
     
    	if(clientHandle!=0)
    		CloseHandle(clientHandle);
    	system("pause");
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •