Skip to content
MPGHThe Dark Arts
/
RegisterLog in
Forum
Community
What's NewLatest posts across the boardTrendingHottest threads right nowSubscribedThreads you follow
Discussion
GeneralIntroductionsEntertainmentDebate FortFlaming & Rage
Board
News & AnnouncementsMPGH TimesSuggestions & HelpGiveaways
More Sections
Art & Graphic DesignProgrammingHackingCryptocurrency
Hacks & Cheats
Games
ValorantCS2 / CS:GOCall of Duty / WarzoneFortniteApex LegendsEscape From Tarkov
+14 moreLeague of LegendsGTA VMinecraftRustROTMGBattlefieldTroveBattleOnCombat ArmsCrossFireBlackshotRuneScapeDayZDead by Daylight
Resources
Game Hacking TutorialsReverse EngineeringGeneral Game HackingAnti-CheatConsole Game Hacking
Tools
Game Hacking ToolsTrainers & CheatsHack/Release NewsNew
Submit a release →Share your cheat, tool, or config with the community.
AINEW
AI Tools
General & DiscussionPrompt EngineeringLLM JailbreaksHotAI Agents & AutomationLocal / Open Models
AI × Gaming
AI Aimbots & VisionML Anti-CheatGame Bots & Automation
Create
AI Coding / Vibe CodingAI Art & MediaAI Voice & TTS
The AI frontier →Where game hacking meets modern machine learning. Jump in.
Marketplace
Buy & Sell
SellingBuyingTradingUser Services
Trust & Safety
Middleman LoungeMarketplace TalkVouch Copy Profiles
Money
Cryptocurrency TalkCurrency ExchangeWork & Job Offers
Start selling →List accounts, services, and goods. Use the middleman to trade safe.
MPGH The Dark Arts

A community for offensive security research, reverse engineering, and AI.

Community

ForumMarketplaceSearch

Account

RegisterLog in

Legal

Privacy PolicyForum RulesHelp & FAQ
© 2026 MPGH · All rights reserved.Built by the community, for the community. For educational purposes onlyContent is shared for security research and education — we don't condone illegal use. You're responsible for complying with applicable laws. Use at your own risk.
Home › Forum › Programming › C++/C Programming › Memory reading, structures, and pointers

Memory reading, structures, and pointers

Posts 1–9 of 9 · Page 1 of 1
AB
abduct
Memory reading, structures, and pointers
Hi all. I am having a bit of a problem with my code ive been working on lately. What I am trying to do is (from the base address that doesnt change) grab all the data from memory and include it in a structure. Essentially what i want to do is recreate the structure like how it is in the game and simply point my structure to the address and use it.

What I am having troubles with is getting to the correct address in C. I have found my base address though CE and it looks like this. BaseAddress->AnotherAddress+0x34->My Data to fill my structure.

I have reversed enough of my structure to know what is in it and everything is aligned properly I just cant get the correct address. Here is my code.

Code:
typedef unsigned char BYTE;

typedef struct
{
    BYTE Unknown01[0x468]; //Unknown stuff
    DWORD Id;
    DWORD Level;
    DWORD Cultivation;
    DWORD Current_HP;
    DWORD Current_MP;
    DWORD Exp;
    DWORD Spirit;
    DWORD Attribute_Points;
    DWORD Current_Chi;
    DWORD Attack_Level;
    DWORD Defence_Level;
    float Critical_Rate;
    float Rage_Damage;
    DWORD Stealth_Level;
    DWORD Stealth_Detection_Level;
    DWORD Slaying_Level;
    DWORD Warding_level;
    DWORD Vitality_Points;
    DWORD Magic_Points;
    DWORD Strength_Points;
    DWORD Dextarity_Points;
    DWORD Max_HP;
    DWORD Max_MP;
    DWORD HP_Regen;
    DWORD MP_Regen;
    float Walk_Speed;
    float Run_Speed;
    float Swim_Speed;
    float Fly_Speed;
    DWORD Accuracy;
    DWORD Min_Attack_Damage;
    DWORD Max_Attack_Damage;
    float Attack_Rate;
    float Range;
    DWORD Min_Metal_Damage;
    DWORD Max_Metal_Damage;
    DWORD Min_Wood_Damage;
    DWORD Max_Wood_Damage;
    DWORD Min_Water_Damage;
    DWORD Max_Water_Damage;
    DWORD Min_Fire_Damage;
    DWORD Max_Fire_Damage;
    DWORD Min_Earth_Damage;
    DWORD Max_Earth_Damage;
    DWORD Min_Magic_Damage;
    DWORD Max_Magic_Damage;
    DWORD Metal_Defence;
    DWORD Wood_Defence;
    DWORD Water_Defence;
    DWORD Fire_Defence;
    DWORD Earth_Defence;
    DWORD Physical_Defence;
    DWORD Evasion;
    DWORD Max_Chi;
    DWORD Coins;
    DWORD Max_Coins;
}PLAYER;

typedef struct
{
    BYTE Unknown[0x34];
    PLAYER *p_player;
}VARBASE;

DWORD WINAPI function()
{
    VARBASE *Stats = (VARBASE*)0x00BBC9CC;
    char lol[1000];

    sprintf(lol, "stats pointer: %p  |  player pointer: %p  |  player pointer + 34: %ld", (void*)Stats, (void*)Stats->p_player, Stats->p_player->Level);
    SomeFunction(lol);

    return NULL;
}
What should be happening is when I create my VARBASE structure it will add 0x34 bytes to the address 0x00BBC9CC is pointing to and then set that new address as a pointer to my player struct where I can use all my variables.

It should look like 0x00BBC9CC->0x0A15CDC0+34->14DEE5F0(the beginning of the games structure i want to point to)
but instead it looks like 0x00BBC9CC->0x00000301->0x00001501 which causes a segment fault when i try to read it.

maybe someone here can help point me in the right direction for trying to find the correct memory address.

thanks for any help!
#1 · 13y ago
FO
Fovea
Are you in your target process's memory space? If not, then you're just reading your own process's memory. Also, sometimes the compiler will align structures to some boundary for optimization reasons. In MSVS, you can surround your structures with #pragma pack directives in order to specify alignment (in this case you want a one byte boundary). Look for an equivalent directive/option if you are not using MSVS.
#2 · edited 13y ago · 13y ago
AB
abduct
Quote Originally Posted by Fovea View Post
Are you in your target process's memory space? If not, then you're just reading your own process's memory. Also, sometimes the compiler will align structures to some boundary for optimization reasons. In MSVS, you can surround your structures with #pragma pack directives in order to specify alignment (in this case you want a one byte boundary). Look for an equivalent directive/option if you are not using MSVS.
How can i make sure I am indeed in the target process's memory? ive done some tests and if i remove the `BYTE Unknown[0x34]` line and print the pointers for `Stats` and `Stats->p_player` they both point to the proper addresses (more so p_player being what Stats is currently pointing at so I am almost sure I am in the targets process memory. after all i am injecting the dll into it.)

Just to make sure is it possible to create a double pointer to grab the data of one variable. The HP variable is loacated at `BASE->ADDR+34->ADDR+494`

Also I am using Code::Blocks with mingw gcc so I will have to look into this structure padding. Thank you for the reply

edit:: I just used `#pragma pack(push,1)` and outputted the size of VARBASE and it was 56, although when i removed it the struct was still 56 (52 bytes + 4 bytes for the pointer) going to read into this more

heres an image of my addresses for `Stats` and `Stats->p_player`



Stats is pointing to the right address but when I have that `BYTE Unknown[0x34]` line in the structure it points to the wrong address where as if i remove it it points to what Stats is pointing to (0x0A**CDC0). if that makes any sense.
#3 · edited 13y ago · 13y ago
FO
Fovea
Just read your edit, it seems like 0x00BBC9CC is actually a pointer to a pointer to a VARBASE structure and not the VARBASE structure (the latter is what your code is assuming). Dereference 0x00BBC9CC and then store that as the pointer to VARBASE.
#4 · edited 13y ago · 13y ago
AB
abduct
Quote Originally Posted by Fovea View Post
Just read your edit, it seems like 0x00BBC9CC is actually a pointer to a pointer to a VARBASE structure and not the VARBASE structure (the latter is what your code is assuming). Dereference 0x00BBC9CC and then store that as the pointer to VARBASE.
ah yes im sorry if i explained that wrong. it is a pointer to a pointer to a structure holding my information.

fake edit:: thank you so much for that hint. ive managed to fix it by first creating a DWORD pointer to my base address and then using that derefenced pointer to my VARBASE structure like you said.

here is the new code if anyone else has this problem in the future.

Code:
DWORD WINAPI function()
{
    FILE *fp;
    fp = fopen("testaddr.txt", "a+");
    DWORD *ptr = (DWORD*)0x00BBC9CC;
    VARBASE *Stats = (VARBASE*)*ptr;
    fprintf(fp, "size of varbase:%d\n", sizeof(*Stats));
    fprintf(fp, "stats pointer: %p  |  player pointer: %p\n", (void*)Stats, Stats->p_player);
    fprintf(fp, "stats pointer: %p  |  player pointer: %p\n\n", (void*)Stats, Stats->p_player);
    fprintf(fp, "current hp %ld/%ld\n", Stats->p_player->Current_HP, Stats->p_player->Max_HP);
    fclose(fp);
    return NULL;
}
output:

size of varbase:56
stats pointer: 0A12CDC0 | player pointer: 225DE678
stats pointer: 0A12CDC0 | player pointer: 225DE678

current hp 2745/2745
#5 · 13y ago
AB
abduct
because this is fixed for a 2 level pointer (i also have to work with up to 5 level pointers) is there a ReadProcessMemory() but for local memory? Wouldnt that just be the same thing as memcpy? I am trying to write up a function that will allow me to pass the BASE ADDRESS, array of offsets, and how many levels the pointer is and i want to be able to follow all the pointers (adding the offsets each level) to come to my final destination address which i will return from the function.

tl;dr: ReadProcessMemory() same thing as memcpy() except memcpy can be use locally during dll injection?
#6 · 13y ago
FO
Fovea
This could have bugs but you should get the picture. Also it's not safe, read this. Wrote it in C as this seems to be what you're using (although I would use the builder pattern / initializer_list if you plan to use C++, as well as implementing it as a function template).

Code:
unsigned long ReadPointer(void* base, unsigned int level, ...) {
  unsigned long* output;
  va_list        offsets;

  output = *(unsigned long*)output;
  
  va_start(offsets, level);

  for (unsigned int i = 0; i < level; i++)
    output = *(output + va_arg(offsets, unsigned int));

  va_end(offsets);

  return (unsigned long)output;
}
For a pointer, you just set the level to zero, for a pointer to a pointer you set the level to one and provide an offset, etc. Keep in mind that this will give you the value you want, not a pointer to a structure/variable you want. If this isn't what you want, just tweak the code.
#7 · edited 13y ago · 13y ago
AB
abduct
Quote Originally Posted by Fovea View Post
This could have bugs but you should get the picture. Also it's not safe, read this. Wrote it in C as this seems to be what you're using (although I would use the builder pattern / initializer_list if you plan to use C++, as well as implementing it as a function template).

Code:
unsigned long ReadPointer(void* base, unsigned int level, ...) {
  unsigned long* output;
  va_list        offsets;

  output = *(unsigned long*)output;
  
  va_start(offsets, level);

  for (unsigned int i = 0; i < level; i++)
    output = *(output + va_arg(offsets, unsigned int));

  va_end(offsets);

  return (unsigned long)output;
}
For a pointer, you just set the level to zero, for a pointer to a pointer you set the level to one and provide an offset, etc. Keep in mind that this will give you the value you want, not a pointer to a structure/variable you want. If this isn't what you want, just tweak the code.
thanks that looks exactly like what i need. i will test it out and post back with my findings here if it doesnt work (with a working code snippet hopefully).

---------- Post added at 09:58 PM ---------- Previous post was at 08:26 PM ----------

Quote Originally Posted by abduct View Post
thanks that looks exactly like what i need. i will test it out and post back with my findings here if it doesnt work (with a working code snippet hopefully).
after playing with the function a bit and fixing some compile errors (variable was unsigned long but was using unsigned long* kind of stuff) i managed to get it to sort of work

Code:
unsigned long ReadPointer(void* base, unsigned int level, ...)
{
  unsigned long *output = (unsigned long*)base; //correctly points to the next address the BASE is pointing to
  va_list        offsets;

  va_start(offsets, level);

  for (unsigned int i = 0; i < level; i++)
  {
    output = (unsigned long*)*(output + va_arg(offsets, unsigned int)); //This is the problem code. I cant figure out how to properly dereference
                                                              //the pointers and add the offsets
  }

  va_end(offsets);

  return (unsigned long)output;
}
other then that I cant figure out how to add the offsets this should work. (only other minor detail that im going to change is that it returns DWORD addresses rather than unsigned long integers.

---------- Post added at 10:12 PM ---------- Previous post was at 09:58 PM ----------

Quote Originally Posted by abduct View Post
thanks that looks exactly like what i need. i will test it out and post back with my findings here if it doesnt work (with a working code snippet hopefully).

---------- Post added at 09:58 PM ---------- Previous post was at 08:26 PM ----------



after playing with the function a bit and fixing some compile errors (variable was unsigned long but was using unsigned long* kind of stuff) i managed to get it to sort of work

Code:
unsigned long ReadPointer(void* base, unsigned int level, ...)
{
  unsigned long *output = (unsigned long*)base; //correctly points to the next address the BASE is pointing to
  va_list        offsets;

  va_start(offsets, level);

  for (unsigned int i = 0; i < level; i++)
  {
    output = (unsigned long*)*(output + va_arg(offsets, unsigned int)); //This is the problem code. I cant figure out how to properly dereference
                                                              //the pointers and add the offsets
  }

  va_end(offsets);

  return (unsigned long)output;
}
other then that I cant figure out how to add the offsets this should work. (only other minor detail that im going to change is that it returns DWORD addresses rather than unsigned long integers.
fixed it:

usage: ReadPointer((void*)0x00BBC9CC, 1, 0x34)

this will follow the base address (0x00BBC9CC) to the address it points to. add a 0x34 byte offset to that address, and then return what that address points to.

Code:
DWORD *ReadPointer(void* base, unsigned int level, ...)
{
  unsigned long *output = (unsigned long*)base;
  va_list        offsets;

  va_start(offsets, level);

  for (unsigned int i = 0; i <= level; i++)
  {
    output = ((unsigned long*)(*output + va_arg(offsets, unsigned int)));
  }

  va_end(offsets);

  return (DWORD*)output;
}
#8 · edited 13y ago · 13y ago
WhiteHat PH
WhiteHat PH
what game is this???
#9 · 13y ago
Posts 1–9 of 9 · Page 1 of 1

Post a Reply

Similar Threads

  • Memory addresses and pointers -.- FMLBy PsychicSounds in General Game Hacking
    0Last post 15y ago
  • ALL HACKING REQUESTS ARE ANSWERED HERE read this and your questions will be answeredBy iverson954360 in General
    0Last post 19y ago
  • [Read] Leeching and posting other peoples hacksBy DoubleDutch in WarRock - International Hacks
    7Last post 17y ago
  • no fall damage addresse and pointer or valueBy 123456789987654321 in WarRock - International Hacks
    2Last post 19y ago
  • read this and PLZ ANSWERBy mpghhackersrock123 in General
    12Last post 18y ago

Tags for this Thread

None