View previous topic :: View next topic |
Author |
Message |
Plaigon How do I cheat? Reputation: 0
Joined: 04 Sep 2019 Posts: 2
|
Posted: Wed Sep 04, 2019 10:52 am Post subject: Find the size of the player structure |
|
|
Hello guys,
I'm trying to dissect data of the player structure, but how to be sure to give the exact size to cheat engine? I mean where is the end of the structure, how many bytes is the structure about? I don't wanna go over the structure, and read other unrelated data. Thanks in advance!
|
|
Back to top |
|
|
FreeER Grandmaster Cheater Supreme Reputation: 53
Joined: 09 Aug 2013 Posts: 1091
|
Posted: Wed Sep 04, 2019 11:08 am Post subject: |
|
|
/shrug reverse engineer the game and figure it out.
_________________
|
|
Back to top |
|
|
Plaigon How do I cheat? Reputation: 0
Joined: 04 Sep 2019 Posts: 2
|
Posted: Wed Sep 04, 2019 11:17 am Post subject: |
|
|
Do you think that finding out the entity list would help me in figuring out the struct size?
|
|
Back to top |
|
|
FreeER Grandmaster Cheater Supreme Reputation: 53
Joined: 09 Aug 2013 Posts: 1091
|
Posted: Wed Sep 04, 2019 1:18 pm Post subject: |
|
|
potentially, if you can find two or more entities allocated right next to each other or the code that actually allocates them. Me I just let CE use the default of 4096 or whatever and find all the values I care about, then I can delete whatever values are after that (and any inbetween too) if I want. But then I don't make trainers in C++ etc. so the actual size simply doesn't matter to me
_________________
|
|
Back to top |
|
|
atom0s Moderator Reputation: 198
Joined: 25 Jan 2006 Posts: 8517 Location: 127.0.0.1
|
Posted: Wed Sep 04, 2019 11:40 pm Post subject: |
|
|
Use a tool like IDA to disassemble the application/game and look for the pointer that you are working with. You can trace back to where it's initially allocated and see how large of a block was allocated for the given pointer.
It can look something like this:
Code: |
// Allocates memory for an entity object..
v5 = sub_1002BA70(680);
// ASM:
.text:10099C67 xor ecx, ecx
.text:10099C69 mov cx, [esi+8] ; obtain desired entity index
.text:10099C6D mov eax, PTR_NpcMap[ecx*4] ; obtain entity pointer from entity array
.text:10099C74 test eax, eax ; test if pointer is valid
.text:10099C76 jnz short loc_10099CA1 ; jump if valid
.text:10099C78 push 2A8h ; push size of new entity object
.text:10099C7D call sub_1002BA70 ; call memory allocator function
|
This is just an example of what things may look like depending on how the game is setup and how they handle allocations. You can also find the initialization function in some cases to see what all is being written to, for example in this case that I showed above that looks like this:
Code: |
int __thiscall sub_10088BF0(int this, int a2)
{
int v2; // esi
unsigned int v3; // edi
int v4; // edx
int v5; // ecx
int v6; // edi
unsigned int v7; // eax
unsigned int v8; // edx
int v9; // ecx
int v10; // edx
int v11; // edi
int v12; // ecx
int v13; // eax
int result; // eax
v2 = this;
*(_DWORD *)(this + 0xDC) = 100;
*(_DWORD *)(this + 0xE0) = 100;
*(_DWORD *)(this + 0x30) = 0x3F800000;
*(_DWORD *)(this + 0x10) = 0x3F800000;
*(_DWORD *)(this + 0x20) = 0x3F800000;
*(_DWORD *)(this + 0x120) &= 0xFFFFE07F;
*(_WORD *)(this + 0x11C) = 0;
*(_DWORD *)(this + 0x2C) = 0;
*(_DWORD *)(this + 0x28) = 0;
*(_DWORD *)(this + 0x24) = 0;
*(_DWORD *)(this + 0xC) = 0;
*(_DWORD *)(this + 8) = 0;
*(_DWORD *)(this + 4) = 0;
*(_DWORD *)(this + 0x1C) = 0;
*(_DWORD *)(this + 0x18) = 0;
*(_DWORD *)(this + 0x14) = 0;
*(_DWORD *)(this + 0x74) = 0;
*(_DWORD *)(this + 0x78) = 0;
*(_BYTE *)(this + 0x7C) = 0;
*(_DWORD *)(this + 0xA0) = 0;
memset((void *)(this + 0xA4), 0, 0x30u);
v3 = *(_DWORD *)(this + 0x120) & 0xFFFFFFCF;
*(_DWORD *)(this + 0xE8) = 0;
*(_DWORD *)(this + 0x120) = v3;
*(_BYTE *)(this + 0xEE) = 0;
*(_BYTE *)(this + 0xEF) = 0;
*(_WORD *)(this + 0x162) = 0;
*(_DWORD *)(this + 0x164) = '4uom';
memset((void *)(this + 0xFC), 0, 0x20u);
v4 = *(_DWORD *)(this + 0x120) & 0x1FB0;
*(_WORD *)(this + 244) = 0;
*(_BYTE *)(this + 246) = 0;
*(_DWORD *)(this + 216) = 0;
*(_DWORD *)(this + 364) = 0;
*(_DWORD *)(this + 360) = 0;
*(_DWORD *)(this + 372) = 0;
*(_DWORD *)(this + 376) = 0;
*(_DWORD *)(this + 344) = 1084227584;
*(_DWORD *)(this + 152) = 1084227584;
*(_DWORD *)(this + 156) = 1084227584;
*(_WORD *)(this + 242) = 0;
*(_WORD *)(this + 240) = 0;
*(_WORD *)(this + 436) = 0;
*(_DWORD *)(this + 388) = 0;
*(_DWORD *)(this + 384) = 0;
*(_DWORD *)(this + 380) = 0;
*(_WORD *)(this + 352) = 0;
*(_WORD *)(this + 350) = 0;
*(_WORD *)(this + 348) = 0;
*(_DWORD *)(this + 228) = 0;
*(_BYTE *)(this + 440) = 0;
*(_BYTE *)(this + 441) = 0;
*(_DWORD *)(this + 464) = 0;
*(_WORD *)(this + 468) = 23;
*(_DWORD *)(this + 460) = 0;
*(_WORD *)(this + 324) = 0;
*(_WORD *)(this + 330) = 0;
*(_WORD *)(this + 332) = 0;
*(_DWORD *)(this + 288) = v4;
*(_BYTE *)(this + 320) = 0;
*(_DWORD *)(this + 292) = 2176;
*(_WORD *)(this + 322) = 0;
*(_WORD *)(this + 326) = 0;
*(_WORD *)(this + 328) = 0;
v5 = *(_DWORD *)(this + 300);
v6 = *(_DWORD *)(v2 + 312);
*(_DWORD *)(v2 + 304) &= 0xFFFF7F00;
v7 = *(_DWORD *)(v2 + 316) & 0xFEC00800;
BYTE1(v7) |= 8u;
*(_DWORD *)(v2 + 300) = v5 & 0x300002;
*(_DWORD *)(v2 + 312) = v6 & 0x87FFFFFF;
*(_DWORD *)(v2 + 316) = v7;
*(_DWORD *)(v2 + 492) = 0;
*(_BYTE *)(v2 + 507) = 0;
*(_BYTE *)(v2 + 508) = 0;
*(_BYTE *)(v2 + 509) = 0;
*(_BYTE *)(v2 + 470) = 0;
*(_BYTE *)(v2 + 471) = 0;
*(_DWORD *)(v2 + 296) = 131073;
*(_BYTE *)(v2 + 321) = 0;
*(_WORD *)(v2 + 500) = 0;
*(_WORD *)(v2 + 674) = 0;
*(_WORD *)(v2 + 502) = 0;
*(_WORD *)(v2 + 672) = 0;
*(_BYTE *)(v2 + 506) = 0;
*(_WORD *)(v2 + 504) = 0;
*(_DWORD *)(v2 + 512) = -1082130432;
*(_DWORD *)(v2 + 516) = 0;
*(_DWORD *)(v2 + 520) = 0;
*(_WORD *)(v2 + 524) = 0;
*(_BYTE *)(v2 + 526) = 0;
*(_BYTE *)(v2 + 527) = 0;
memset((void *)(v2 + 588), 0, 0x2Cu);
v8 = *(_DWORD *)(v2 + 304) & 0xFFFC80FF;
*(_DWORD *)(v2 + 316) &= 0xFF3FFFFF;
*(_DWORD *)(v2 + 392) = 0;
*(_DWORD *)(v2 + 304) = v8;
memset((void *)(v2 + 632), 0, 0x24u);
v9 = *(_DWORD *)(v2 + 304);
v10 = *(_DWORD *)(v2 + 312);
*(_DWORD *)(v2 + 308) &= 0xFF0FFC02;
*(_BYTE *)(v2 + 311) = 0;
v11 = *(_DWORD *)(v2 + 308);
*(_DWORD *)(v2 + 304) = v9 & 0x103FFFF;
*(_WORD *)(v2 + 668) = 0;
*(_WORD *)(v2 + 0x29E) = 0;
*(_DWORD *)(v2 + 308) = v11 & 0xFFF003FD;
*(_WORD *)(v2 + 510) = 0;
*(_DWORD *)(v2 + 312) = v10 & 0xF8000000;
sub_10088A00((_DWORD *)v2);
if ( a2 == 0x1000000 )
{
v12 = *(_DWORD *)(v2 + 460);
*(_DWORD *)(v2 + 120) = 0x1000000;
v13 = *(_DWORD *)(v2 + 288);
BYTE1(v13) |= 2u;
*(_DWORD *)(v2 + 116) = 2304;
*(_DWORD *)(v2 + 460) = v12 | 2;
*(_DWORD *)(v2 + 288) = v13;
}
else
{
sub_10088A40(v2);
sub_1008C220(v2);
}
*(_DWORD *)(v2 + 212) = 0;
*(_DWORD *)(v2 + 248) = 0;
*(_WORD *)(v2 + 444) = -1;
*(_DWORD *)(v2 + 448) = 0;
*(_DWORD *)(v2 + 452) = 0;
*(_DWORD *)(v2 + 456) = 0;
*(_DWORD *)(v2 + 488) = 0;
*(_DWORD *)(v2 + 496) = 0;
*(_DWORD *)(v2 + 472) = 0;
*(_WORD *)(v2 + 476) = 0;
*(_WORD *)(v2 + 478) = 0;
*(_DWORD *)(v2 + 480) = 0;
*(_WORD *)(v2 + 484) = 0;
*(_WORD *)(v2 + 486) = 0;
*(_DWORD *)(v2 + 676) = 0;
memset((void *)(v2 + 528), 0, 0x20u);
*(_BYTE *)(v2 + 560) = 0;
result = 0;
memset((void *)(v2 + 561), 0, 0x18u);
*(_BYTE *)(v2 + 585) = 0;
return result;
}
|
Doing this also helps you find most of the entries in the structure as well as their proper types/sizes etc. It can also help you figure out what things are in general depending on how its used/written to.
_________________
- Retired. |
|
Back to top |
|
|
|