[C++] GetModuleBase incompability menu

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 15 of 22
  1. #1
    Amrok's Avatar Banned
    Reputation
    4
    Join Date
    Apr 2009
    Posts
    59
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [C++] GetModuleBase incompability

    Hi, i've made a little tool to read / write to wow memory but on some computers GetModuleBase fails! It gets wrong Module Base while others work fine. C++ Redistributable is static linked. This is my function:

    Code:
    UINT_PTR GetModuleBase(LPTSTR lpModuleName, DWORD dwProcessId)
    {
    	MODULEENTRY32 lpModuleEntry = {0};
    	HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
    	if(!hSnapShot)
    		return NULL;
    	lpModuleEntry.dwSize = sizeof(lpModuleEntry);
    	BOOL bModule = Module32First(hSnapShot, &lpModuleEntry);
    	while(bModule)
    	{
    		if(!_tcscmp(lpModuleEntry.szModule, lpModuleName))
    		{
    			CloseHandle(hSnapShot);
    			return (UINT_PTR)lpModuleEntry.modBaseAddr;
    		} 
    		bModule = Module32Next(hSnapShot, &lpModuleEntry);
    	}
    	CloseHandle(hSnapShot);
    	return NULL;
    }
    Can somebody explain why it doesn't work for some users.. it displays 0x400000 als mainmodule on some computers which is WRONG.

    [C++] GetModuleBase incompability
  2. #2
    LogicWin's Avatar Master Sergeant
    Reputation
    51
    Join Date
    Mar 2011
    Posts
    103
    Thanks G/R
    4/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could copy'n paste chyper's "Hades-lib"

  3. #3
    _Mike's Avatar Contributor
    Reputation
    310
    Join Date
    Apr 2008
    Posts
    531
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Try using the hModule member instead. That has always worked for me. In fact I had never even noticed there was a .modBaseAddr before you mentioned it just now

  4. #4
    Amrok's Avatar Banned
    Reputation
    4
    Join Date
    Apr 2009
    Posts
    59
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thx .. worked Didnt thought that .modBaseAddr has different effects on some computers. Dont know what was causing it.

    Now i only have 1 more problem to solve.. I need to read a string from memory. I've made a loop to read every single byte and check if its 0x00 terminator and keep reading until we found 0x00. Here is the code:

    Code:
    string ReadString(UINT_PTR Offset)
    {
    	int count;
    	char Value[50] = "\0";
    	BYTE strbyte = {0x20}; // hack.. anything else than 0x00 to initiate.
    	for(count=0;strbyte!=0x00;count++) // keep reading until we found end of string byte 0x00
    		if(ReadProcessMemory(hProcess, (LPCVOID)(Offset+count), &strbyte, 1, NULL)) // read single byte and write it to array
    			Value[count] = strbyte;
    	return (string)Value;
    }
    I'm sure this can be optimized .. But could you take a look at it and tell me what you think?
    Last edited by Amrok; 08-03-2011 at 07:28 PM.

  5. #5
    _Mike's Avatar Contributor
    Reputation
    310
    Join Date
    Apr 2008
    Posts
    531
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    My suggestion; Read more data at once than a single byte, say a full memory page or so, and process the string locally. If you haven't found a '\0' by then, read the next page as well..
    The increased time it takes to copy the extra amount of data is probably less than the overhead of repeatedly calling ReadProcessMemory unless the strings are only a few characters long.

    Edit:
    Also, why are you limiting your strings to 49 characters? Use a vector<char> or similar.
    And even worse, you aren't enforcing the 49 char limit so you are risking buffer overflows on long strings.
    Last edited by _Mike; 08-03-2011 at 07:40 PM.

  6. #6
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by _Mike View Post
    My suggestion; Read more data at once than a single byte, say a full memory page or so, and process the string locally. If you haven't found a '\0' by then, read the next page as well..
    The increased time it takes to copy the extra amount of data is probably less than the overhead of repeatedly calling ReadProcessMemory unless the strings are only a few characters long.

    Edit:
    Also, why are you limiting your strings to 49 characters? Use a vector<char> or similar.
    And even worse, you aren't enforcing the 49 char limit so you are risking buffer overflows on long strings.
    Obviously he's running ring-0 proxies to protect against buffer overflows.

  7. #7
    flo8464's Avatar Active Member
    Reputation
    30
    Join Date
    Apr 2009
    Posts
    434
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Also, why are you limiting your strings to 49 characters? Use a vector<char> or similar.
    He's using C, at least I hope that.
    Please tell me that the return value type 'string' is in no way related to std::string.
    Hey, it compiles! Ship it!

  8. #8
    _Mike's Avatar Contributor
    Reputation
    310
    Join Date
    Apr 2008
    Posts
    531
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by flo8464 View Post
    He's using C, at least I hope that.
    Read the topic title ;)

  9. #9
    suicidity's Avatar Contributor
    Reputation
    207
    Join Date
    Oct 2006
    Posts
    1,439
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm saddened.


  10. #10
    flo8464's Avatar Active Member
    Reputation
    30
    Join Date
    Apr 2009
    Posts
    434
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I was a bit bored, so I cleaned up your mess a bit.
    It's still inefficient (reading only a byte at a time), but at least it doesn't violate half of C++'s language rules within 10 lines of code.

    Code:
    std::string ReadString(std::uintptr_t address)
    {
      std::string temp;
    
      char current;
      do
      {
        SIZE_T bytesRead;
        BOOL ec = ReadProcessMemory(  hProcess,
                                      reinterpret_cast<LPCVOID>(address++),
                                      static_cast<LPVOID>(&current),
                                      sizeof(current),
                                      &bytesRead);
        if(!ec || bytesRead != sizeof(current))
          throw std::runtime_error("Error reading string");
    
        if(current)
          temp.push_back(current);
      }
      while(current);
    
      return temp;
    }
    Last edited by flo8464; 08-04-2011 at 01:14 PM.
    Hey, it compiles! Ship it!

  11. #11
    Amrok's Avatar Banned
    Reputation
    4
    Join Date
    Apr 2009
    Posts
    59
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by flo8464 View Post
    I was a bit bored, so I cleaned up your mess a bit.
    It's still inefficient (reading only a byte at a time), but at least it doesn't violate half of C++'s language rules within 10 lines of code.

    Code:
    std::string ReadString(std::uintptr_t address)
    {
      std::string temp;
    
      char current;
      do
      {
        SIZE_T bytesRead;
        BOOL ec = ReadProcessMemory(  hProcess,
                                      reinterpret_cast<LPCVOID>(address++),
                                      static_cast<LPVOID>(¤t),
                                      sizeof(current),
                                      &bytesRead);
        if(!ec || bytesRead != sizeof(current))
          throw std::runtime_error("Error reading string");
    
        if(current)
          temp.push_back(current);
      }
      while(current);
    
      return temp;
    }
    Thanks for your correction. I've written a function to read my whole memory page from beginning of string and then process it in my application. Didn't care too much about inefficiency b4.

    To Topic: not hModule Member was causing it! it was _tcscmp! it doesnt work correct on some computers for some reason. I'm now using wcscmp instead!

    Also modBaseAddress member is correct:

    modBaseAddr
    The base address of the module in the context of the owning process.
    Last edited by Amrok; 08-05-2011 at 07:28 AM.

  12. #12
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by flo8464 View Post
    I was a bit bored, so I cleaned up your mess a bit.
    It's still inefficient (reading only a byte at a time), but at least it doesn't violate half of C++'s language rules within 10 lines of code.

    Code:
    std::string ReadString(std::uintptr_t address)
    {
      std::string temp;
    
      char current;
      do
      {
        SIZE_T bytesRead;
        BOOL ec = ReadProcessMemory(  hProcess,
                                      reinterpret_cast<LPCVOID>(address++),
                                      static_cast<LPVOID>(&current),
                                      sizeof(current),
                                      &bytesRead);
        if(!ec || bytesRead != sizeof(current))
          throw std::runtime_error("Error reading string");
    
        if(current)
          temp.push_back(current);
      }
      while(current);
    
      return temp;
    }
    You should template it on character type (and probably traits and allocator too, but meh, nobody seems to do that anyway ).

  13. #13
    Amrok's Avatar Banned
    Reputation
    4
    Join Date
    Apr 2009
    Posts
    59
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Cypher View Post
    You should template it on character type (and probably traits and allocator too, but meh, nobody seems to do that anyway ).
    I have template functions for Read / Write Offset if you mean that. I handle strings as an extra function.

    EDIT:
    I'm stupid. Didnt read correct. Sorry.

  14. #14
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Amrok View Post
    I have template functions for Read / Write Offset if you mean that. I handle strings as an extra function.

    EDIT:
    I'm stupid. Didnt read correct. Sorry.
    template <typename CharT>
    std::basic_string<CharT> ReadString(PVOID Address);

  15. #15
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How would you use a template like that in c++? I know in C# you use Type.Typecode, what is the equal in c++?

Page 1 of 2 12 LastLast
All times are GMT -5. The time now is 03:57 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search