Pets move function

12/05/2020 13:09 Roxeez#1
Hi, i'm making a small bot for a friend and i need to implement pet movement.
Looks like ptctl packet does not display pet movement on client screen. (Like walk packet does not display character movement)

That's why i'm looking if somebody can share with me pet walk function because i'm a total noob about RE and i can't find it by myself :feelsbadman:

Thanks
12/05/2020 21:54 Hatz~#2
Code from cheat engine:

Small test dll to make sure it works:

To find it i've just put a break point on the instruction that writes the destiny position of the pet/partner, once the breakpoint hit execute till return and if you scroll up a little bit you'll see it.

Signature and mask for walk func (generated with CE plugin):
12/05/2020 22:17 FI0w#3
Quote:
Originally Posted by Hatz~ View Post
Code from cheat engine:

Small test dll to make sure it works:

To find it i've just put a break point on the instruction that writes the destiny position of the pet/partner, once the breakpoint hit execute till return and if you scroll up a little bit you'll see it.

Signature and mask for walk func (generated with CE plugin):
Dont need it but great work :)
12/06/2020 00:02 Roxeez#4
Quote:
Originally Posted by Hatz~ View Post
Code from cheat engine:

Small test dll to make sure it works:

To find it i've just put a break point on the instruction that writes the destiny position of the pet/partner, once the breakpoint hit execute till return and if you scroll up a little bit you'll see it.

Signature and mask for walk func (generated with CE plugin):
Big thanks :pogchamp:
12/17/2020 17:20 Roxeez#5
Got some issue with pet object.
The value of static address + 0x3C is equals to 0 until you first move your cursor and also this value change if you put your cursor on any entity

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

Object = value in ESI needed by pet walk function

1 - In character selection screen, object value is 0 (nothing strange i guess)
2 - In game but haven't move cursor yet, object value is 0, so if i call pet walk it will crash
3 - Normal behavior object value is correct, if i call pet walk function it will work
4 - Cursor on an entity on your screen object value is incorrect, if i call pet walk function it will crash


Here is the code i'm using to test it.
Code:
if (GetAsyncKeyState(VK_INSERT) & 1)
{
    std::cout << "--------------- PATTERN ---------------" << std::endl;

    DWORD function = Module::GetInstance()->FindPattern<DWORD>("\x55\x8b\xEC\x83\xC4\x00\x53\x56\x57\x8B\xF9\x89\x55\x00\x8B\xD8\xC6\x45", "xxxxx?xxxxxxx?xxxx", 0);
    DWORD address = **Module::GetInstance()->FindPattern<DWORD**>("\x50\xA1\x00\x00\x00\x00\x8B\x00\x8B\x40\x20\x66\x8B\x4D\xF6", "xx????x?xxxxxxx", 2);
    DWORD obj = *(DWORD*)(*((DWORD*)address) + 0x3C);

    std::cout << "Function: " << function << " (NostaleClientX.exe + " << function - Module::GetInstance()->GetBaseAddress() << ")" << std::endl;
    std::cout << "Object static address: " << address << " (NostaleClientX.exe + " << address - Module::GetInstance()->GetBaseAddress() << ")" << std::endl;
    std::cout << "Object: " << obj << std::endl;
} 
else if (GetAsyncKeyState(VK_DELETE) & 1)
{
    std::cout << "--------------- HARDCODED ---------------" << std::endl;

    DWORD function = 0x53e318;
    DWORD address = 0x8997d8;
    DWORD obj = *(DWORD*)(*((DWORD*)address) + 0x3C);

    std::cout << "Function: " << function << " (NostaleClientX.exe + " << (function - 0x400000) << ")" << std::endl;
    std::cout << "Object static address: " << address << " (NostaleClientX.exe + " << (address - 0x400000) << ")" << std::endl;
    std::cout << "Object: " << obj << std::endl;
}
else if (GetAsyncKeyState(VK_END) & 1)
{
    std::cout << "--------------- TESTING ---------------" << std::endl;

    DWORD function = Module::GetInstance()->FindPattern<DWORD>("\x55\x8b\xEC\x83\xC4\x00\x53\x56\x57\x8B\xF9\x89\x55\x00\x8B\xD8\xC6\x45", "xxxxx?xxxxxxx?xxxx", 0);
    DWORD address = **Module::GetInstance()->FindPattern<DWORD**>("\x50\xA1\x00\x00\x00\x00\x8B\x00\x8B\x40\x20\x66\x8B\x4D\xF6", "xx????x?xxxxxxx", 2);
    DWORD obj = *(DWORD*)(*((DWORD*)address) + 0x3C);

    DWORD position = (28 << 16) | 28;

    std::cout << "Function: " << function << " (NostaleClientX.exe + " << function - Module::GetInstance()->GetBaseAddress() << ")" << std::endl;
    std::cout << "Object static address: " << address << " (NostaleClientX.exe + " << address - Module::GetInstance()->GetBaseAddress() << ")" << std::endl;
    std::cout << "Object: " << obj << std::endl;

    _asm
    {
        push 1
        xor ecx, ecx
        mov edx, position
        mov eax, obj
        call function;
    }
}
Any help appreciated :feelsbadman:
12/18/2020 09:53 Hatz~#6
The function moves a ptr to TSvrCtlObjManager into eax, so i found a ptr to CtrlObjManagerList at 0x899924 adding + 0x4 to the adress of the CtrlObjManagerList leads you to the list of objects and at + 0x8 you have the number of objects in the list which is usually just your pets. It looks something like this:
12/18/2020 13:09 Roxeez#7
Thanks for your help, works fine :feelsgoodman:

Another problem :lul:
After calling 5-6 times pet walk function my app crash (when reaching ASM)

I checked and all addresses/pointers are ok, even when it crash :feelsbadman:

Code:
DWORD WINAPI Thread(HMODULE hModule)
{
    AllocConsole();
    FILE* file = new FILE;
    freopen_s(&file, "CONOUT$", "w", stdout);

    std::cout << std::hex;

    DWORD position = (28 << 16) | 28;
    DWORD function = Module::GetInstance()->FindPattern<DWORD>("\x55\x8b\xEC\x83\xC4\x00\x53\x56\x57\x8B\xF9\x89\x55\x00\x8B\xD8\xC6\x45", "xxxxx?xxxxxxx?xxxx", 0);
    DWORD base = **Module::GetInstance()->FindPattern<DWORD**>("\x8B\xF8\x8B\xD3\xA1\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x8B\xD0", "xxxxx????x????xx", 5);

    std::cout << "Function: " << function << std::endl;
    std::cout << "Base: " << base << std::endl;

    while (!(GetAsyncKeyState(VK_END) & 1))
    {
        Sleep(10);
        if (GetAsyncKeyState(VK_INSERT) & 1)
        {
            DWORD list = *(DWORD*)(base + 0x4);
            int size = *(DWORD*)(base + 0x8);

            std::cout << "Address: " << list << std::endl;
            std::cout << "Size: " << size << std::endl;

            if (size == 0)
            {
                continue;
            }

            DWORD address = size == 1 ? list + 0x0 : list + 0x4;
            DWORD object = *(DWORD*)address;

            std::cout << "Object: " << object << std::endl;

            __asm
            {
                push 1
                xor ecx, ecx
                mov edx, position
                mov eax, object
                call function
            }

            std::cout << "--------------------------" << std::endl;
        }
    }

    return 0x0;
}
12/19/2020 14:13 Roxeez#8
I checked assembly in cheat engine and i saw 2 "push 1" at the beginning instead of 1 so i tried to add it into asm and it works, no more crash :kappa:

From
Code:
__asm
{
    push 1
    xor ecx, ecx
    mov edx, position
    mov eax, object
    call function
}
to
Code:
__asm
{
    push 1
    push 1
    xor ecx, ecx
    mov edx, position
    mov eax, object
    call function
}
If somebody can explain me why i appreciate :lul:
12/19/2020 14:48 Apourtartt#9
[Only registered and activated users can see links. Click Here To Register...]
12/19/2020 14:58 romdrak#10
Quote:
Originally Posted by Roxeez View Post
If somebody can explain me why i appreciate :lul:
It's 4th and 5th argument, that are pushed onto stack. For more info check register calling convention=D