Registration Code (Part 1): w%kQ6
Registration Code (Part 2): b<#$1[*(cw~
In order to register on this forum, you must use the codes above. Combine them into one code (copy paste).

Useful Address Information

Topics regarding the new upcoming ARPG Grim Dawn.
User avatar
atom0s
Site Admin
Posts: 401
Joined: Sun Jan 04, 2015 11:23 pm
Location: 127.0.0.1
Contact:

Useful Address Information

Post by atom0s » Fri Apr 17, 2015 10:58 pm

Grim Dawn b28 (and prior)

Base Address
8B 16 8B 42 10 8B CE ?? ?? A1 ?? ?? ?? ?? 8B 48 54 85 C9
+0x0A is the pointer

Navigation Manager
33 F6 C7 45 FC FF FF FF FF 89 35 ?? ?? ?? ?? A1 ?? ?? ?? ?? 85 C0 ?? ?? 8B 46 04 50 FF ?? ?? ?? ?? ?? 83 3D ?? ?? ?? ?? 00 ?? ?? 6A 48
+0x10 is the pointer

Writable Player Coords
[[[[[navman+8]+0]+0x10]+(playerindex)]+0x004] = player x coord (readable)
[[[[[navman+8]+0]+0x10]+(playerindex)]+0x008] = player y coord (readable)
[[[[[navman+8]+0]+0x10]+(playerindex)]+0x00C] = player z coord (readable)
[[[[[navman+8]+0]+0x10]+(playerindex)]+0x198] = player x coord (readable/writable)
[[[[[navman+8]+0]+0x10]+(playerindex)]+0x19C] = player y coord (readable/writable)
[[[[[navman+8]+0]+0x10]+(playerindex)]+0x1A0] = player z coord (readable/writable)
Derp~
Need a great web host? Check out: AnHonestHost.com


Donations can be made via Paypal:
https://www.paypal.me/atom0s
User avatar
atom0s
Site Admin
Posts: 401
Joined: Sun Jan 04, 2015 11:23 pm
Location: 127.0.0.1
Contact:

Re: Useful Address Information

Post by atom0s » Mon Dec 28, 2015 10:49 am

Grim Dawn b29

Base Address

Code: Select all

Pattern: 8B 16 8B CE ?? ?? ?? 8B 35 ?? ?? ?? ?? 8B 4E
Offset : +0x09
NavManager

Code: Select all

Pattern: 89 46 ?? C7 46 ?? 00 00 00 00 50 ?? ?? ?? ?? ?? ?? C7 45 FC FF FF FF FF 89 35 ?? ?? ?? ?? A1 ?? ?? ?? ?? 85 C0 75 ?? FF 76 04 ?? ?? ?? ?? ?? ?? 83 3D ?? ?? ?? ?? 00 75 ?? 6A 48
Offset : +1F
Writable Player Coords
[[[[[navman+8]+0]+0xC]+(playerindex)]+0x004] = player x coord (readable)
[[[[[navman+8]+0]+0xC]+(playerindex)]+0x008] = player y coord (readable)
[[[[[navman+8]+0]+0xC]+(playerindex)]+0x00C] = player z coord (readable)
[[[[[navman+8]+0]+0xC]+(playerindex)]+0x198] = player x coord (readable/writable)
[[[[[navman+8]+0]+0xC]+(playerindex)]+0x19C] = player y coord (readable/writable)
[[[[[navman+8]+0]+0xC]+(playerindex)]+0x1A0] = player z coord (readable/writable)

How to retrieve the playerindex:
[[[[[navman+8]+0]+0]+(playerarray)]+0x1EC] = A float value

Developer Console

Code: Select all

Pattern: 53 8B 09 32 DB 56 8B 35 ?? ?? ?? ?? 57 8B 3D ?? ?? ?? ?? FF ?? 8B C8
Offset : +0x0F

[[ptr+0x00]+0x38]+0x08 = enable console boolean (0 / 1)
Derp~
Need a great web host? Check out: AnHonestHost.com


Donations can be made via Paypal:
https://www.paypal.me/atom0s
User avatar
immorrr
Posts: 110
Joined: Fri Mar 27, 2015 2:21 pm
Location: Germany

Re: Useful Address Information

Post by immorrr » Tue Dec 29, 2015 8:11 am

Thanks alot, i was still missing the NavManager for b29!
atom0s wrote:[[[[[navman+8]+0]+0x10]+(playerindex)]+0x198] = player x coord (readable/writable)
[[[[[navman+8]+0]+0x10]+(playerindex)]+0x19C] = player y coord (readable/writable)
[[[[[navman+8]+0]+0x10]+(playerindex)]+0x1A0] = player z coord (readable/writable)
It is true that those addresses are writeable but it should be mentioned that those cant be used for 'true' teleport because the game still checks for obstackles or any other stuff blocking the way between point A and point B.
User avatar
immorrr
Posts: 110
Joined: Fri Mar 27, 2015 2:21 pm
Location: Germany

Re: Useful Address Information

Post by immorrr » Wed Jan 06, 2016 3:45 pm

Ptr to coordinates has changed, the new ones are:

Writable Player Coords
[[[[[navman+8]+0]+0xC]+(playerindex)]+0x004] = player x coord (readable)
[[[[[navman+8]+0]+0xC]+(playerindex)]+0x008] = player y coord (readable)
[[[[[navman+8]+0]+0xC]+(playerindex)]+0x00C] = player z coord (readable)
[[[[[navman+8]+0]+0xC]+(playerindex)]+0x198] = player x coord (readable/writable)
[[[[[navman+8]+0]+0xC]+(playerindex)]+0x19C] = player y coord (readable/writable)
[[[[[navman+8]+0]+0xC]+(playerindex)]+0x1A0] = player z coord (readable/writable)

How to retrieve the playerindex:
[[[[[navman+8]+0]+0]+(playerarray)]+0x1EC] = A float value

The playerarray goes from 0x0 to 0x3C. Loop through this array (inc. by 0x4) and check the result (float)
If the result is '2' the current index from your loop through the playerarray is the playerindex.
User avatar
atom0s
Site Admin
Posts: 401
Joined: Sun Jan 04, 2015 11:23 pm
Location: 127.0.0.1
Contact:

Re: Useful Address Information

Post by atom0s » Tue Feb 23, 2016 1:00 pm

Grim Dawn (b31)

Base Pointer

Code: Select all

8B 17 8B CF ?? ?? ?? 8B 3D ?? ?? ?? ?? 8B 4F
+ 0x09
Easy way to find this if it breaks:
  • Unpack the Grim Dawn.exe with my Steamless project.
  • Open Grim Dawn.exe in IDA (or another disassembler of your choice).
  • Locate the following string reference: tagReportUsageStats
  • Follow the reference into the function it is referenced at.
  • Scroll up a bit and you should see the following block of code:

Code: Select all

.text:00489532                 call    ds:?GetNetworkConnectionManager@Engine@GAME@@QAEPAVConnectionManager@2@XZ ; GAME::Engine::GetNetworkConnectionManager(void)
.text:00489538                 mov     edi, eax
.text:0048953A                 test    edi, edi
.text:0048953C                 jz      short loc_489551
.text:0048953E                 mov     ecx, edi
.text:00489540                 call    ds:?IsInitialized@ConnectionManager@GAME@@QAE_NXZ ; GAME::ConnectionManager::IsInitialized(void)
.text:00489546                 test    al, al
.text:00489548                 jz      short loc_489551
.text:0048954A                 mov     edx, [edi]
.text:0048954C                 mov     ecx, edi
.text:0048954E                 call    dword ptr [edx+10h]
.text:00489551
.text:00489551 loc_489551:                             ; CODE XREF: sub_488650+EECj
.text:00489551                                         ; sub_488650+EF8j
.text:00489551                 mov     edi, dword_634830
.text:00489557                 mov     ecx, [edi+48h]
.text:0048955A                 test    ecx, ecx
.text:0048955C                 jz      short loc_489569
.text:0048955E                 mov     eax, [ecx]
.text:00489560                 call    dword ptr [eax+34h]
.text:00489563                 mov     edi, dword_634830
.text:00489569
.text:00489569 loc_489569:                             ; CODE XREF: sub_488650+F0Cj
.text:00489569                 mov     eax, [edi+54h]
.text:0048956C                 mov     [edi+48h], eax
.text:0048956F                 mov     ecx, ds:?gEngine@GAME@@3PAVEngine@1@A ; GAME::Engine * GAME::gEngine
.text:00489575                 mov     ecx, [ecx]
.text:00489577                 call    ds:?SetAsNetworkStub@Engine@GAME@@QAEXXZ ; GAME::Engine::SetAsNetworkStub(void)
.text:0048957D                 mov     ecx, ds:?gEngine@GAME@@3PAVEngine@1@A ; GAME::Engine * GAME::gEngine
.text:00489583                 push    dword ptr [edi+48h]
.text:00489586                 mov     ecx, [ecx]
.text:00489588                 call    ds:?SetNetworkController@Engine@GAME@@QAEXPAVNetworkControllerBase@2@@Z ; GAME::Engine::SetNetworkController(GAME::NetworkControllerBase *)
.text:0048958E                 mov     ecx, ds:?gGameEngine@GAME@@3PAVGameEngine@1@A ; GAME::GameEngine * GAME::gGameEngine
.text:00489594                 mov     ecx, [ecx]
.text:00489596                 call    ds:?SetAsNetworkStub@GameEngine@GAME@@QAEXXZ ; GAME::GameEngine::SetAsNetworkStub(void)
.text:0048959C                 mov     eax, [esi+25Ch]
.text:004895A2                 test    eax, eax
.text:004895A4                 jz      short loc_4895AE
.text:004895A6                 push    eax
.text:004895A7                 mov     ecx, esi
.text:004895A9                 call    sub_4672E0
.text:00489551 holds the pointer, so adjust the pattern as needed per-update based on the minor changes.

Developer Console

Code: Select all

Pattern: 53 8B 09 32 DB 56 8B 35 ?? ?? ?? ?? 57 8B 3D ?? ?? ?? ?? FF ?? 8B C8
Offset : +0x0F

[[ptr+0x00]+0x38]+0x08 = enable console boolean (0 / 1)
Nav Manager

Code: Select all

Pattern: 89 46 ?? C7 46 ?? 00 00 00 00 50 ?? ?? ?? ?? ?? ?? C7 45 FC FF FF FF FF 89 35 ?? ?? ?? ?? A1 ?? ?? ?? ?? 85 C0 75 ?? FF 76 04 ?? ?? ?? ?? ?? ?? 83 3D ?? ?? ?? ?? 00 75 ?? 6A 48
Offset : +1F
Derp~
Need a great web host? Check out: AnHonestHost.com


Donations can be made via Paypal:
https://www.paypal.me/atom0s
User avatar
atom0s
Site Admin
Posts: 401
Joined: Sun Jan 04, 2015 11:23 pm
Location: 127.0.0.1
Contact:

Re: Useful Address Information

Post by atom0s » Wed Mar 02, 2016 5:16 pm

Grim Dawn v1.0.0.1

Base Pointer

Code: Select all

Pattern: 8B 17 8B CF ?? ?? ?? 8B 3D ?? ?? ?? ?? 8B 4F
Offset: + 0x09
Object Manager

Code: Select all

Pattern: 08 89 46 04 C7 46 08 00 00 00 00 50 FF 15 ?? ?? ?? ?? C7 45 FC FF FF FF FF 89 35 ?? ?? ?? ?? A1 ?? ?? ?? ?? 85 C0 75 ?? FF 76 04 ?? ?? ?? ?? ?? ?? 83 3D ?? ?? ?? ?? 00 75 ?? 68
Offset: +0x20
Nav Manager

Code: Select all

Pattern: 89 46 ?? C7 46 ?? 00 00 00 00 50 ?? ?? ?? ?? ?? ?? C7 45 FC FF FF FF FF 89 35 ?? ?? ?? ?? A1 ?? ?? ?? ?? 85 C0 75 ?? FF 76 04 ?? ?? ?? ?? ?? ?? 83 3D ?? ?? ?? ?? 00 75 ?? 6A 48
Offset : +1F
Developer Console

Code: Select all

Pattern: 53 8B 09 32 DB 56 8B 35 ?? ?? ?? ?? 57 8B 3D ?? ?? ?? ?? FF ?? 8B C8
Offset : +0x0F

[[ptr+0x00]+0x38]+0x08 = enable console boolean (0 / 1)

Main Player Object Index (see GAME::GameEngine::GetMainPlayer)

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>191137</ID>
      <Description>"Player Character Index"</Description>
      <LastState Value="00003150" RealAddress="0D8455A0"/>
      <ShowAsHex>1</ShowAsHex>
      <VariableType>4 Bytes</VariableType>
      <Address>GAME::gGameEngine</Address>
      <Offsets>
        <Offset>8</Offset>
        <Offset>10</Offset>
        <Offset>16B0</Offset>
      </Offsets>
    </CheatEntry>
  </CheatEntries>
</CheatTable>

Getting The Main Player Character Pointer
For whatever reason Grim Dawn devs decided to make this a convoluted process now instead of the easier lookup in the past.
To do this you are going to need a few pointers:
- Pointer to the GAME::gGameEngine
- Pointer to the GAME::ObjectManager

Here is my example code in C++ using my personal memory class to obtain the character pointer and print out its coords:
  1. int __cdecl main(int, char*[])
  2. {
  3.     auto memory = new Memory;
  4.     if (memory->Attach("Grim Dawn.exe"))
  5.     {
  6.         memory->AddPattern("Game.dll", "gameengine", "A1????????568BB080000000FF15????????508BCEE8????????5EC3", 1, 0);
  7.         memory->AddPattern("Engine.dll", "objectmanager", "08894604C746080000000050FF15????????C745FCFFFFFFFF8935????????A1????????85C075??FF7604????????????833D????????0075??68", 0x20, 0);
  8.         memory->CollectPatterns();
  9.  
  10.         auto getPlayerPointer = [&memory]() -> unsigned
  11.         {
  12.             // Obtain the needed game objects..
  13.             auto gameEngine = memory->Read<int>(memory->GetPattern("gameengine"));
  14.             auto objectManager = memory->Read<int>(memory->GetPattern("objectmanager"));
  15.             if (gameEngine == 0 || objectManager == 0)
  16.                 return 0;
  17.  
  18.             // Obtain the player index..
  19.             auto index_ptr1 = memory->Read<int>(gameEngine);
  20.             auto index_ptr2 = memory->Read<int>(index_ptr1 + 0x16B0);
  21.             auto index_ptr3 = memory->Read<int>(index_ptr2 + 0x10);
  22.             auto playerIndex = memory->Read<int>(index_ptr3 + 0x08);
  23.  
  24.             // Obtain the object manager mask..
  25.             auto mask_ptr1 = memory->Read<int>(objectManager);
  26.             auto objectMask = memory->Read<int>((mask_ptr1 + 0x20) + 0x18);
  27.  
  28.             // Calculate the player object index..
  29.             auto part1 = (unsigned int)memory->Read<unsigned char>(index_ptr3 + 0x08);
  30.             part1 = part1 ^ 0x811C9DC5;
  31.             part1 = part1 * 0x01000193;
  32.  
  33.             auto part2 = (unsigned int)memory->Read<unsigned char>(index_ptr3 + 0x09);
  34.             part2 = part2 ^ part1;
  35.             part2 = part2 * 0x01000193;
  36.  
  37.             auto part3 = (unsigned int)memory->Read<unsigned char>(index_ptr3 + 0x0A);
  38.             part3 = part3 ^ part2;
  39.             part3 = part3 * 0x01000193;
  40.  
  41.             auto part4 = (unsigned int)memory->Read<unsigned char>(index_ptr3 + 0x0B);
  42.             part4 = part4 ^ part3;
  43.             part4 = part4 * 0x01000193;
  44.             part4 = part4 & objectMask;
  45.  
  46.             auto object_ptr1 = memory->Read<int>((mask_ptr1 + 0x20) + 0x0C);
  47.             auto object_ptr2 = memory->Read<int>(object_ptr1 + part4 * 8);
  48.             auto first_object = object_ptr2;
  49.  
  50.             while (true)
  51.             {
  52.                 auto current_index = memory->Read<int>(object_ptr2 + 0x08);
  53.                 if (current_index == playerIndex)
  54.                 {
  55.                     return memory->Read<int>(object_ptr2 + 0x0C);
  56.                 }
  57.                 else
  58.                 {
  59.                     object_ptr2 = memory->Read<int>(object_ptr2);
  60.                     if (object_ptr2 == 0 || object_ptr2 == first_object)
  61.                         return 0;
  62.                 }
  63.             }
  64.  
  65.             return 0;
  66.         };
  67.  
  68.         auto player = getPlayerPointer();
  69.         printf_s("Current Pointer: %08X\r\n", player);
  70.         if (player)
  71.         {
  72.             printf_s("Current position: %f - %f - %f\r\n",
  73.                 memory->Read<float>(player + 0xA0),
  74.                 memory->Read<float>(player + 0xA4),
  75.                 memory->Read<float>(player + 0xA8)
  76.                 );
  77.         }
  78.     }
  79.  
  80.     delete memory;
  81.     return 0;
  82. }
Derp~
Need a great web host? Check out: AnHonestHost.com


Donations can be made via Paypal:
https://www.paypal.me/atom0s
User avatar
immorrr
Posts: 110
Joined: Fri Mar 27, 2015 2:21 pm
Location: Germany

Re: Useful Address Information

Post by immorrr » Thu Mar 17, 2016 1:00 am

v1.0.0.2 broke the AoB for the Object Manager and for the Nav Manager.
User avatar
atom0s
Site Admin
Posts: 401
Joined: Sun Jan 04, 2015 11:23 pm
Location: 127.0.0.1
Contact:

Re: Useful Address Information

Post by atom0s » Fri Mar 18, 2016 10:53 am

Grim Dawn v1.0.0.2

Base Pointer

Code: Select all

Pattern: 8B 17 8B CF ?? ?? ?? 8B 3D ?? ?? ?? ?? 8B 4F
Offset: + 0x09
Object Manager

Code: Select all

Pattern: 08 89 46 ?? C7 46 ?? 00 00 00 00 50 FF 15 ?? ?? ?? ?? C7 45 FC FF FF FF FF 89 35 ?? ?? ?? ?? A1 ?? ?? ?? ?? 85 C0 75 ?? FF 76 ?? ?? ?? ?? ?? ?? ?? 83 3D ?? ?? ?? ?? 00 75 ?? 68
Offset : + 0x20
Nav Manager

Code: Select all

Pattern: 89 46 ?? C7 46 ?? 00 00 00 00 50 ?? ?? ?? ?? ?? ?? C7 45 FC FF FF FF FF 89 35 ?? ?? ?? ?? A1 ?? ?? ?? ?? 85 C0 75 ?? FF 76 ?? ?? ?? ?? ?? ?? ?? 83 3D ?? ?? ?? ?? 00 75 ?? 6A 48
Offset : + 0x1F
Developer Console

Code: Select all

Pattern: 53 8B 09 32 DB 56 8B 35 ?? ?? ?? ?? 57 8B 3D ?? ?? ?? ?? FF ?? 8B C8
Offset : +0x0F

[[ptr+0x00]+0x38]+0x08 = enable console boolean (0 / 1)
Derp~
Need a great web host? Check out: AnHonestHost.com


Donations can be made via Paypal:
https://www.paypal.me/atom0s
three0s
Posts: 1
Joined: Sat Sep 12, 2015 7:23 pm

Re: Useful Address Information

Post by three0s » Fri Mar 18, 2016 7:42 pm

Mind sharing your "personal memory class"?
I wasn't able to figure out the base address using cheat engine like I usually do...
User avatar
immorrr
Posts: 110
Joined: Fri Mar 27, 2015 2:21 pm
Location: Germany

Re: Useful Address Information

Post by immorrr » Thu Mar 24, 2016 3:41 pm

Add the following to your Cheattable's Luascript:
  1. -- BasePointer (ByteArray + Offset + ScanFlag)
  2. basePtrAoBArray = "8B 17 8B CF ?? ?? ?? 8B 3D ?? ?? ?? ?? 8B 4F"
  3. basePtrAobOffset = 0x09
  4. basePtrAoBFlags = "-W"
  5.  
  6. -- Function: 'onOpenProcess(processid)'
  7. -- Scans for specific BasePointers by using a specified 'Array of Bytes' on attaching a process to cheatengine.
  8. function onOpenProcess(processid)
  9.     reinitializeSymbolhandler()
  10.  
  11.     -- Modul Base
  12.     modulebase=getAddress("Grim Dawn.exe")
  13.     if (modulebase == nil) then
  14.         showMessage("Grim Dawn not yet running! You'll have to manually attach the CE table to your Grim Dawn's process!")
  15.         return
  16.     end
  17.  
  18.     -- Base Pointer (AoB)
  19.     basePtrAoB = AOBScan(basePtrAoBArray, basePtrAoBFlags);
  20.     if (basePtrAoB == nil or strings_getCount(basePtrAoB) ~= 1) then
  21.         showMessage('Failed to find the BasePointer with the specified array of bytes!');
  22.     else
  23.         bAoB = tonumber('0x' .. strings_getString(basePtrAoB, 0)) + basePtrAobOffset;
  24.         bAoBAdr = readInteger(bAoB);
  25.         registerSymbol('BasePointer', bAoBAdr);
  26.         showMessage([[AoB Scan Results: BasePointer]].."\n"..[[  > [BasePointer] > Grim Dawn.exe+0x]]..StringLayoutHex(bAoB-modulebase)..[[  ( = 0x]]..StringLayoutHex(bAoB)..[[ )]])
  27.     end
  28. end
  29.  
  30. -- Function: 'StringLayoutHex(decaddress)'
  31. -- Change the format from any decimal value to a hex, uppercase address.
  32. function StringLayoutHex(decaddress)
  33.     return string.upper(string.format("%x",decaddress))
  34. end
Now after attaching the Grim Dawn process to cheatengine the script results:
Image

Now 'BasePointer' is a registered symbol and can easyli be used within your Grim Dawn Cheattable.
Image -> Image

You can also download a basic CE file (with the mentioned script above already integratred) here quickly.
GD_BasePointer.rar
(1.37 KiB) Downloaded 75 times
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest