Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Dereferencing multilevel pointer
Goto page Previous  1, 2
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
SteveAndrew
Master Cheater
Reputation: 30

Joined: 02 Sep 2012
Posts: 323

PostPosted: Sat Nov 23, 2013 12:35 am    Post subject: Reply with quote

Well yes I have thought about it and known about it. I've found though that most of the time you can just check for zero and be fine. It's true however that you are basically trusting the pointer then!

So for completeness I've modified it to be safer based on your feedback!

Gniarf's recommendation: (I went with a __try __except block rather than IsBadReadPtr)
Code:

void *GetPointerSafer(DWORD PointerBase, ...)
{
   DWORD CurrentPointer = (PointerBase + (DWORD)GetModuleHandle(0));
   DWORD LastOffset = 0;
   va_list Params;
   va_start(Params, PointerBase);
   for(;;)
   {
      unsigned int CurrentOffset = va_arg(Params, unsigned int);
      if(CurrentOffset != 0xffffffff)
      {
         __try
         {
            CurrentPointer = *(DWORD*)(CurrentPointer + LastOffset);
         }
         __except(1)
         {
            CurrentPointer = 0; //read failed, full pointer not accessible at this time!
            break;
         }
         LastOffset = CurrentOffset;
      }
      else
      {
         CurrentPointer += LastOffset;
         break;
      }
   }
   va_end(Params);

   return (void*)CurrentPointer;
}



Dark Byte's recommendation: (ReadProcessMemory on local process)
(HANLDE)-1 == GetCurrentProcess()

Code:

void *GetPointerSafest(DWORD PointerBase, ...)
{
   DWORD CurrentPointer = (PointerBase + (DWORD)GetModuleHandle(0));
   DWORD LastOffset = 0, BytesRead;
   va_list Params;
   va_start(Params, PointerBase);
   for(;;)
   {
      unsigned int CurrentOffset = va_arg(Params, unsigned int);
      if(CurrentOffset != 0xffffffff)
      {
         CurrentPointer += LastOffset;
         ReadProcessMemory((HANDLE)-1, (void*)CurrentPointer, (void*)&CurrentPointer, 4, &BytesRead);
         if(BytesRead != 4 || CurrentPointer == 0) //failed reading or we ran into null pointer!
         {
            CurrentPointer = 0;
            break;
         }
         LastOffset = CurrentOffset;
      }
      else
      {
         CurrentPointer += LastOffset;
         break;
      }
   }
   va_end(Params);

   return (void*)CurrentPointer;
}


For completeness sake that should be good! Very Happy

_________________
Back to top
View user's profile Send private message
zm0d
Master Cheater
Reputation: 7

Joined: 06 Nov 2013
Posts: 423

PostPosted: Sat Nov 23, 2013 3:45 am    Post subject: Reply with quote

Gniarf wrote:
@zm0d: What's the problem with ASLR? Normally the GetModuleHandle(0) in SteveAndrew's code will give you the address at which the exe is loaded.

Yeah.... my first impressions with ASLR yesterday let me thought that I cant use codeinjection that easy. But I created a new thread... and already knew how to go on with it Smile

SteveAndrew wrote:
For completeness sake that should be good! Very Happy

You are a darling!!! Very Happy Very Happy Very big thanks Smile
Back to top
View user's profile Send private message
SteveAndrew
Master Cheater
Reputation: 30

Joined: 02 Sep 2012
Posts: 323

PostPosted: Sat Nov 23, 2013 5:18 am    Post subject: Reply with quote

zm0d wrote:

You are a darling!!! Very Happy Very Happy Very big thanks Smile


You are very welcome! Anytime! Smile

Just for fun I implemented an alternative version, that you can specify a pointer with a similar format to CE's pointer strings:

For example it gets a pointer by using a string like: [[[[[[[[["Game.exe"+2496338]+3c]+e8]+1c]+4c]+40]+8]+0]+5c]

However slightly different since this is an internal function only, I omitted the exe name in the string you specify, so its like this in my version:
[[[[[[[[[+2496338]+3c]+e8]+1c]+4c]+40]+8]+0]+5c]

It just takes for granted that the first one specified '+2496338' is what your adding to "Game.exe" which the name of doesn't matter since we are inside it and just do 'GetModuleHandle(0)' anyway! Smile

Also has the advantage of being coded to also accept negative offsets, (the other function has to be adjusted for negative offsets too work Wink)

Examples:

Code:

WORD *Ptr = (WORD*)GetPointerFromString("[[[[[[[[[+2496338]+3c]+e8]+1c]+4c]+40]+8]+0]+5c]");

DWORD *Ptr2 = (DWORD*)GetPointerFromString("[[[[[+77b130]+58]-24]+10]-4]");


Etc..

Because it became it a little more complicated now having to parse a string it needs the helper function 'ExtractNumberFromPointerString' but all in all its a simple enough string format that it wasn't too much trouble! Very Happy
Code:

DWORD ExtractNumberFromPointerString(char *pCurrentOffset, DWORD *StringLength)
{
   
   char *pEndOfNumber = pCurrentOffset;
   while (*pEndOfNumber != ']') pEndOfNumber++;
   DWORD DigitsLength = ((pEndOfNumber - pCurrentOffset) + 1);

   char *NumberString = new char[DigitsLength];
   memcpy(NumberString, pCurrentOffset, DigitsLength);
   *StringLength = DigitsLength;

   DWORD NumberValue = strtol(NumberString, 0, 16);

   delete[] NumberString;
   return NumberValue;
}

void *GetPointerFromString(char *PointerString)
{
   DWORD CurrentPointer = (DWORD)GetModuleHandle(0);
   DWORD i = 0, CurrentOffset, BytesRead, DigitsLength;
   
   if (PointerString[0] != '[') return 0; //invalid pointer string case 1
   while (PointerString[i] == '[') i++;
   for(;;)
   {
      if(PointerString[i] != '+' && PointerString[i] != '-') return 0; //invalid pointer string case 2

      CurrentOffset = ExtractNumberFromPointerString(&PointerString[i+1], &DigitsLength);
      if (PointerString[i] == '+')
         CurrentPointer += CurrentOffset;
      else if (PointerString[i] == '-')
         CurrentPointer -= CurrentOffset;

      i += (DigitsLength + 1);

      if (PointerString[i] == 0)
         return (void*)CurrentPointer;
      else
      {
         ReadProcessMemory((HANDLE)-1, (void*)CurrentPointer, (void*)&CurrentPointer, 4, &BytesRead);
         if (BytesRead != 4 || CurrentPointer == 0) //failed reading or we ran into null pointer!
         {
            return 0;
         }
      }
   }
}

_________________
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites