Thread: Help with ReadProcessMemory function

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    9

    Help with ReadProcessMemory function

    I am trying to get the ReadProcessMemory function to work, but it doesnt seem to return anything useful. In the code below, I initiated output to 0 and the value of output does not change from my ReadProcessMemory function like expected. Am I missing anything? I am thinking that I need to include Kernel32.lib. somehow, but I have no idea really. Can someone point me in the right direction?

    Code:
    #include "stdafx.h"
    #include <iostream>
    #include <windows.h>
    using namespace std;
    
    
    
    int main()
    {
    	DWORD bytes, wid;
    	HWND w3wnd = FindWindow(NULL, L"Warcraft III"); ;
    	GetWindowThreadProcessId(w3wnd, &wid);
    	HANDLE w3hnd = OpenProcess(PROCESS_ALL_ACCESS, false, wid);
    	if (w3wnd==NULL)
    	{
    		printf("Warcraft III not found...\n");
    		system("PAUSE");
    		return 0;
    	}
    	int output=0;
    	void* pointer=&output;
    	ReadProcessMemory(w3hnd, 0x00000000, pointer, 1, &bytes);
    	if (ReadProcessMemory==0)
    		printf("ReadProcessMemory FAILED!\n");
    	printf("&#37;i", output);
    	system("PAUSE");
    	return 0;
    }
    Last edited by MattZimmerer; 10-28-2008 at 02:36 PM.

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by MattZimmerer View Post
    I am trying to get the ReadProcessMemory function to work, but it doesnt seem to return anything useful. In the code below, I initiated output to 0 and the value of output does not change from my ReadProcessMemory function like expected. Am I missing anything? I am thinking that I need to include Kernel32.lib. somehow, but I have no idea really. Can someone point me in the right direction?
    You never check for failure, so how can you know if it failed? It's probably working fine. This code is wrong:

    Code:
    	if (ReadProcessMemory==0)
    		printf("ReadProcessMemory FAILED!\n");
    You are checking if the address of the ReadProcessMemory() function is equal to zero. Obviously that isn't going to be true. You need to check the RETURN VALUE to test for failure. I'm not sure why you've assumed that this is failing in the first place, since you never examine the values of bytes[]. I bet it's all working fine.

    EDIT: Well, you're trying to examine address 0, which isn't going to be mapped in the other process since it contains the NULL address. Try checking some legitimate address instead of 0x00000000

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    9
    So the fifth parameter of ReadProcessMemory is stored in an array? How could I view this, I've been checking it with


    Code:
    .....
    	ReadProcessMemory(w3hnd, 0x08000000, pointer, 1, &bytes);
    	printf("&#37;i\n", bytes);
    .....
    ohh, and Ive looked at memory regions that contain non static values... im just trying to get ANYTHING out of the function so i don't care what the base is right now
    Last edited by MattZimmerer; 10-28-2008 at 02:51 PM.

  4. #4
    Registered User
    Join Date
    Oct 2008
    Posts
    9
    Here is what I have now:
    I'm not sure if i'm testing the return right though.
    Code:
    #include "stdafx.h"
    #include <iostream>
    #include <windows.h>
    using namespace std;
    
    
    
    int main()
    {
    	DWORD bytes, wid;
    	HWND w3wnd = FindWindow(NULL, L"Warcraft III"); ;
    	GetWindowThreadProcessId(w3wnd, &wid);
    	HANDLE w3hnd = OpenProcess(PROCESS_ALL_ACCESS, false, wid);
    	if (w3wnd==NULL)
    	{
    		printf("Warcraft III not found...\n");
    		system("PAUSE");
    		return 0;
    	}
    	int output=0;
    	void* pointer=&output;
    
    	if (ReadProcessMemory(w3hnd, (void*)0x08000000, pointer, 1, &bytes))
    		{
    			printf("%i", output);
    		}
    		else
    		{
    			printf("ReadProcessMemory Failed\n");
    		}
    
    	system("PAUSE");
    	return 0;
    }
    Here is the output:
    ReadProcessMemory Failed
    Press any key to continue . . .

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You should call GetLastError in that case to see what the error is.

  6. #6
    Registered User
    Join Date
    Oct 2008
    Posts
    9
    Ok then, I added the line
    Code:
    .....
    	printf("Get last error: %d\n",GetLastError());
    .....
    and got an output of:

    ReadProcessMemory Failed
    Get last error: 6
    Press any key to continue . . .


    From MSDN Library it follows:
    ERROR_INVALID_HANDLE
    6
    0x6
    I think that's the right error... i read it off a table
    http://msdn.microsoft.com/en-us/libr...82(VS.85).aspx

    I don't see anything wrong with the handle I pass to the function... any ideas?

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You check w3wnd but not w3hnd, so if OpenProcess fails, you wouldn't know. Does that process fail?

  8. #8
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Which is possibly due to your terrible variable names

  9. #9
    Registered User
    Join Date
    Oct 2008
    Posts
    9
    Quote Originally Posted by tabstop View Post
    You check w3wnd but not w3hnd, so if OpenProcess fails, you wouldn't know. Does that process fail?
    I added the following and found that it is indeed not working.
    Code:
    	if (w3hnd==NULL)
    	{
    		printf("HANDLE = NULL\n");
    		system("PAUSE");
    		return 0;
    	}
    //OUTPUT:
    //HANDLE = NULL
    //Press any key to continue . . .
    Thanks! I'll see where this gets me.

  10. #10
    Registered User
    Join Date
    Oct 2008
    Posts
    9
    Lol.... access is denied at

    Code:
    	HANDLE w3hnd = OpenProcess(PROCESS_ALL_ACCESS, false, wid);
    the error code returned is 5,
    ERROR_ACCESS_DENIED
    5
    0x5

    does this mean the process cannot be accessed with PROCESS_ALL_ACCESS flag?

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by MattZimmerer View Post
    Lol.... access is denied at

    Code:
    	HANDLE w3hnd = OpenProcess(PROCESS_ALL_ACCESS, false, wid);
    the error code returned is 5,
    ERROR_ACCESS_DENIED
    5
    0x5

    does this mean the process cannot be accessed with PROCESS_ALL_ACCESS flag?
    That seems likely. Technically you only need read access, for what you've got here anyway.

  12. #12
    Registered User
    Join Date
    Oct 2008
    Posts
    9
    yes, I'm able to read from Calculator, well, the ReadProcessMemory returns error 299
    ERROR_PARTIAL_COPY
    299
    0x12B


    Only part of a ReadProcessMemory or WriteProcessMemory request was completed.
    Anyways, I'm going to try a few more things. Thank you!
    Im so glad I know about GetLastError()!

  13. #13
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I am trying to get the ReadProcessMemory function to work, but it doesnt seem to return anything useful. In the code below, I initiated output to 0 and the value of output does not change from my ReadProcessMemory function like expected. Am I missing anything? I am thinking that I need to include Kernel32.lib. somehow, but I have no idea really. Can someone point me in the right direction?
    Well, first of all you have to thoroughly understand your target game. You have to spend a lot of time using such tools as Cheat Engine, OllyDbg etc. to investigate the game. These tools will help you find specific memory locations of interest such as memory locations to increase health, wealth etc. When you finally have a thorough understanding of the internal workings of the game, you can start writing code. With that said, here a basic example using pinball.

    The first thing I did before writing the code was to fire up Cheat Engine and attach it to a running instance of pinball. I then played one ball to generate a score. Let's assume my score for one ball was 17450. I entered this score, 17450 in the "value" box and clicked on the first scan button. I found two memory addresses of interest listed in the listbox. These are the two memory addresses that I used in the code below. You'll have to run CE and attach to pinball to get your memory addresses since they may not necessarily be the same addresses I used.

    Code:
    #include <windows.h>
    #include <stdio.h>
    
    HANDLE  hProcess   = (HANDLE) INVALID_HANDLE_VALUE;
    
    VOID DisplayError(CHAR* pMessage)
    {
        DWORD dwNum;
        CHAR szSysMsg[256] = {0};
        CHAR* p;
    
        dwNum = GetLastError( );
        FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, dwNum,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            szSysMsg, 256, NULL );
        // Trim the end of the line and terminate it with a null
        p = szSysMsg;
        while( ( *p > 31 ) || ( *p == 9 ) )
            ++p;
        do { *p-- = 0; } while( ( p >= szSysMsg ) &&
            ( ( *p == '.' ) || ( *p < 33 ) ) );
        printf( "\n%s error %d (%s)", pMessage, dwNum, szSysMsg );
    }
    
    BOOL EnableTokenPrivilege (LPTSTR pPrivilege)
    {
        HANDLE hToken;                        
        TOKEN_PRIVILEGES token_privileges;                  
        DWORD dwSize;                        
        ZeroMemory (&token_privileges, sizeof (token_privileges));
        token_privileges.PrivilegeCount = 1;
        if ( !OpenProcessToken (GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
        {
            DisplayError("OpenProcessToken failed");
            return FALSE;
        }
        if (!LookupPrivilegeValue ( NULL, pPrivilege, &token_privileges.Privileges[0].Luid))
        { 
            DisplayError("LookupPrivilegeValue failed");
            CloseHandle (hToken);
            return FALSE;
        }
        token_privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        if (!AdjustTokenPrivileges ( hToken, FALSE, &token_privileges, 0, NULL, &dwSize))
        { 
            DisplayError("AdjustTokenPrivileges failed");
            CloseHandle (hToken);
            return FALSE;
        }
        CloseHandle (hToken);
        return TRUE;
    }
    
    BOOL CloseProcess(VOID)
    {
        if (CloseHandle(hProcess))
            return TRUE;
        else
        {
            DisplayError("Close handle failed");
            return FALSE;
        }
    }
    
    BOOL OpenProcess(LPTSTR pProcessWindowTitle)
    {
    
        HWND    hTargetWindow = (HWND) -1;
        DWORD   dwProcessID = 0;
        hTargetWindow = FindWindow(NULL, pProcessWindowTitle);  // see if it exist
        if (hTargetWindow)
        {
            GetWindowThreadProcessId(hTargetWindow, &dwProcessID); //get a PROCESS number
            if (dwProcessID)
            {
                hProcess = OpenProcess(PROCESS_ALL_ACCESS  ,TRUE, dwProcessID);
                if (hProcess == NULL)
                {
                    DisplayError("Invalid Process handle");
                    return FALSE;
                }
                else return TRUE;
            }
            else
            {
                DisplayError("Invalid ProcessId");
                return FALSE;
            }
        }
        DisplayError("Cannot find target window");
        return FALSE;
    }
    
    BOOL ReadProcess(LPCVOID lpBaseAddress, DWORD dwSize)
    {
        BOOL bSuccess = FALSE, bProcessSuspended = FALSE;
        DWORD dwTemp = 0, dwBytesRead = 0; 
    
        if (hProcess)
        {
            if (SuspendThread(hProcess) != (DWORD) -1)
                bProcessSuspended = TRUE;
            if (ReadProcessMemory(hProcess, lpBaseAddress, &dwTemp, dwSize,
                &dwBytesRead) && dwBytesRead == dwSize)
            {
                bSuccess = TRUE;
                printf("Value read  = %d\n",dwTemp);
            }
            else
            {
                bSuccess = FALSE;
                DisplayError("ReadProcess failed");
            }
    
            if (bProcessSuspended)
                ResumeThread(hProcess);
        }
        else DisplayError("hProcess invalid");
        return bSuccess;
    }
    
    INT main(VOID)
    {
        // The following two addresses were identified by
        // attaching Cheat Engine (CE) to Pinball.exe   
        DWORD dwAddress1 = 0x00AB4414;
        DWORD dwAddress2 = 0x00BAFCF2;
    
        if ( !EnableTokenPrivilege (SE_DEBUG_NAME) )
            DisplayError("EnableTokenPrivilege failed");
        else if(OpenProcess("3d Pinball for Windows - Space Cadet"))
        {
            ReadProcess((LPCVOID)dwAddress1, sizeof(DWORD));
            ReadProcess((LPCVOID)dwAddress2, sizeof(DWORD));
            CloseProcess();
        }
        else DisplayError("OpenProcess failed");
        return 0;
    }

  14. #14
    Registered User
    Join Date
    Oct 2008
    Posts
    9
    yes, very helpful indeed. I already understand how to use cheat engine very well, and I pretty much found the area region I am interested in. Right now I am just trying to understand how exactly I need to use the ReadProcessMemory() function.

    I dont think I am able to access warcraft 3's memory, because I get an "Access Denied Error" when using the OpenProcess() function.

    I will look at how your code is written, but can your code be applied to games like warcraft 3?

    Btw, if you found the pointer offsets, your code would be much more practical =P...
    Last edited by MattZimmerer; 10-30-2008 at 07:05 PM.

  15. #15
    Registered User
    Join Date
    Oct 2008
    Posts
    9
    Code:
    BOOL OpenProcess(LPTSTR pProcessWindowTitle)
    {
    
        HWND    hTargetWindow = (HWND) -1;
        DWORD   dwProcessID = 0;
        hTargetWindow = FindWindow(NULL, pProcessWindowTitle);  // see if it exist
        if (hTargetWindow)
        {
            GetWindowThreadProcessId(hTargetWindow, &dwProcessID); //get a PROCESS number
            if (dwProcessID)
            {
                hProcess = OpenProcess(PROCESS_ALL_ACCESS  ,TRUE, dwProcessID);
                if (hProcess == NULL)
                {
                    DisplayError("Invalid Process handle");
                    return FALSE;
                }
                else return TRUE;
            }
            else
            {
                DisplayError("Invalid ProcessId");
                return FALSE;
            }
        }
        DisplayError("Cannot find target window");
        return FALSE;
    }
    yea, as I suspected, you also use
    hProcess = OpenProcess(PROCESS_ALL_ACCESS ,TRUE, dwProcessID);
    in the same fashion I do, except you pass TRUE into parameter two... which should have no effect.

    Is ReadProcessMemory useless on many multiplayer games?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  2. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  3. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  4. Change this program so it uses function??
    By stormfront in forum C Programming
    Replies: 8
    Last Post: 11-01-2005, 08:55 AM
  5. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM