Click to See Complete Forum and Search --> : ReadProcessMemory()


mpapeo
March 7th, 2005, 09:04 AM
I need help guys and i have been going about this for weeks. I want to read a process's memory which i've created using the createdprocess function, but now i have some slight problems but i should think im close to the solution. Pliz help me, my code is below:


#include <windows.h>
#include <stdio.h>
#include <windef.h>
#include <winbase.h>
#include <imagehlp.h>
//Program that creates a process
//This program assumes that numbers.exe is in the PATH!

LPVOID lpMsgBuf;


typedef int BOOL;
int main(int argc, char **argv)
{

PROCESS_INFORMATION pi; /* filled in by CreateProcess */
STARTUPINFO si; /* startup info for the new process*/

HANDLE hProcess = NULL;
BYTE buf[2000];
DWORD bufsize = sizeof buf;
DWORD baseaddr = 1;
DWORD error = GetLastError();
LPCVOID lpAddress;
PMEMORY_BASIC_INFORMATION lpBuffer = 0;
DWORD dwLength;
DWORD flNewProtect;
PDWORD lpflOldProtect = 0;
DWORD dwSize =0;
LPCVOID lpBaseAddress;
DWORD nSize;
LPDWORD lpNumberOfBytesRead;


printf("Process %d reporting for creation\n",GetCurrentProcessId());//print out our process ID
GetStartupInfo(&si);

// Call CreateProcess, telling it to run an exe file
CreateProcess(NULL, /* lpApplicationName */
"numbers.exe", /* lpCommandLine assumes to use curent process directory*/
NULL, /* lpsaProcess */
NULL, /* lpsaThread */
FALSE, /* bInheritHandles */
CREATE_NEW_CONSOLE, /* dwCreationFlags */
NULL, /* lpEnvironment */
NULL, /* lpCurDir */
&si, /* lpStartupInfo */
&pi /* lpProcInfo */
);

// hProcess = pi.hProcess;

printf("New Process ID: %d ",pi.dwProcessId);
printf("has started \n");

BOOL EnableDebugPrivNT();
{
HANDLE hToken;
LUID DebugValue;
TOKEN_PRIVILEGES tkp;

//
// Retrieve a handle of the access token
//
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken))
{
return FALSE;
}

//
// Enable the SE_DEBUG_NAME privilege
//
if (!LookupPrivilegeValue((LPSTR) NULL,
SE_DEBUG_NAME,
&DebugValue))
{
return FALSE;
}

tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = DebugValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

AdjustTokenPrivileges(hToken,
FALSE,
&tkp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL);

if (GetLastError() != ERROR_SUCCESS)
{
return FALSE;
}

return TRUE;
}




//============================================
// OpenProcess(
// PROCESS_ALL_ACCESS, // access flag
// 0, // handle inheritance flag
// pi.dwProcessId, // process identifier
// );
//===============================================

GetModuleHandle(
"numbers.exe" // address of module name to return handle
// for
);

// GetModuleInformation(
// hProcess, // handle to the process
// hModule, // handle to the module //HMODULE
// DWORD lpmodinfo, // structure that receives information//LPMODULEINFO
// cb // size of the structure//DWORD
// );


//============================================================

VirtualQueryEx(
hProcess, // handle to process
lpAddress, // address of region
lpBuffer,// address of information buffer
dwLength// size of buffer
// GetLastError()
);

//*to avoid crashing

VirtualProtectEx(
hProcess, // handle to process
lpAddress, // address of region of committed pages
dwSize, // size of region
flNewProtect, // desired access protection
lpflOldProtect // address of variable to get old protection
);

ZeroMemory(buf, sizeof(buf));
if( ReadProcessMemory( hProcess, &baseaddr, &buf, bufsize, NULL ) == FALSE )
{
printf("\nProcess memory read failed", GetLastError());
_exit(1);
}
else
{
printf("\nProcess memory read \n");
printf("\nProcess memory read: \n",buf);
}


return(0);
}

Darka
March 7th, 2005, 09:28 AM
you should tell us what problems you are having if you want some help

mpapeo
March 7th, 2005, 12:32 PM
I get this bug on compiling: E:\createprocess.c(56) : error C2275: 'BOOL' : illegal use of this type as an expression. when using declaring this function BOOL EnableDebugPrivNT();
Otherwise if BOOL is removed it doesn't link when
createprocess.obj : error LNK2001: unresolved external symbol _EnableDebugPrivNT

NoHero
March 7th, 2005, 12:49 PM
Well ...


typedef int BOOL;


Remove this, BOOL is already defined in windows.h...


BOOL EnableDebugPrivNT();


And this is an invalid function implementation, because the semicolon at the end tells the compiler that this is only a declaration of the function. Not the implementation. So remove the semicolon:


BOOL EnableDebugPrivNT ( void )


And EnableDebugPrivNt will not be found by the main() function because, it is unknown at compile time, because it is defined after the call. So write:


BOOL EnableDebugPrivNT ( void );


Over your main function, to tell the compiler to expect the implementation of EnableDebugPrivNt() somewhere else (that means later in the source code in your case).

Darka
March 7th, 2005, 12:50 PM
Have you missed a closing } after this line ?

printf("has started \n");

mpapeo
March 7th, 2005, 12:58 PM
No curly brackets because it goes under the main. But there are still some problems after removing BOOL
Errors
Linking...
createprocess.obj : error LNK2001: unresolved external symbol _EnableDebugPrivNT
Debug/createprocess.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

NoHero
March 7th, 2005, 01:00 PM
No curly brackets because it goes under the main. But there are still some problems after removing BOOL

Defining a function in a function is not legal. So you have to put a } (closing paranthesis) there.

Darka
March 7th, 2005, 01:01 PM
In that case you are declaring a function within another function, you can't do that.

NoHero
March 7th, 2005, 01:05 PM
In that case you are declaring a function within another function, you can't do that.

Dito. Use the closing paranthesis and suggestions above, and come back if you have other errors. But please, if you post code again: Use the code tags.

mpapeo
March 7th, 2005, 01:09 PM
Well ...


typedef int BOOL;


Remove this, BOOL is already defined in windows.h...


BOOL EnableDebugPrivNT();


And this is an invalid function implementation, because the semicolon at the end tells the compiler that this is only a declaration of the function. Not the implementation. So remove the semicolon:


BOOL EnableDebugPrivNT ( void )


And EnableDebugPrivNt will not be found by the main() function because, it is unknown at compile time, because it is defined after the call. So write:


BOOL EnableDebugPrivNT ( void );


Over your main function, to tell the compiler to expect the implementation of EnableDebugPrivNt() somewhere else (that means later in the source code in your case).

But now why does it complain about missing function header when the function is on top of main

Darka
March 7th, 2005, 01:13 PM
Please repost the modified code so that we can see the changes you have made.

regards,

NoHero
March 7th, 2005, 01:13 PM
Post your current code again, with code tags! (http://www.codeguru.com/forum/misc.php?do=bbcode#code)

mpapeo
March 7th, 2005, 01:19 PM
Do you mean it can't be like this?


#include <windows.h>
#include <stdio.h>
#include <windef.h>
#include <winbase.h>
#include <imagehlp.h>
//Program that creates a process
//This program assumes that numbers.exe is in the PATH!

LPVOID lpMsgBuf;


//typedef int BOOL;


BOOL EnableDebugPrivNT(void);
{
HANDLE hToken;
LUID DebugValue;
TOKEN_PRIVILEGES tkp;

//
// Retrieve a handle of the access token
//
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken))
{
return FALSE;
}

//
// Enable the SE_DEBUG_NAME privilege
//
if (!LookupPrivilegeValue((LPSTR) NULL,
SE_DEBUG_NAME,
&DebugValue))
{
return FALSE;
}

tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = DebugValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

AdjustTokenPrivileges(hToken,
FALSE,
&tkp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL);

if (GetLastError() != ERROR_SUCCESS)
{
return FALSE;
}

return TRUE;
}


int main(int argc, char **argv)
{

PROCESS_INFORMATION pi; /* filled in by CreateProcess */
STARTUPINFO si; /* startup info for the new process*/

HANDLE hProcess = NULL;
BYTE buf[2000];
DWORD bufsize = sizeof buf;
DWORD baseaddr = 1;
DWORD error = GetLastError();
LPCVOID lpAddress;
PMEMORY_BASIC_INFORMATION lpBuffer = 0;
DWORD dwLength;
DWORD flNewProtect;
PDWORD lpflOldProtect = 0;
DWORD dwSize =0;
LPCVOID lpBaseAddress;
DWORD nSize;
LPDWORD lpNumberOfBytesRead;


printf("Process %d reporting for creation\n",GetCurrentProcessId());//print out our process ID
GetStartupInfo(&si);

// Call CreateProcess, telling it to run an exe file
CreateProcess(NULL, /* lpApplicationName */
"numbers.exe", /* lpCommandLine assumes to use curent process directory*/
NULL, /* lpsaProcess */
NULL, /* lpsaThread */
FALSE, /* bInheritHandles */
CREATE_NEW_CONSOLE, /* dwCreationFlags */
NULL, /* lpEnvironment */
NULL, /* lpCurDir */
&si, /* lpStartupInfo */
&pi /* lpProcInfo */
);

// hProcess = pi.hProcess;

printf("New Process ID: %d ",pi.dwProcessId);
printf("has started \n");







//============================================
// OpenProcess(
// PROCESS_ALL_ACCESS, // access flag
// 0, // handle inheritance flag
// pi.dwProcessId, // process identifier
// );
//===============================================

GetModuleHandle(
"numbers.exe" // address of module name to return handle
// for
);



VirtualQueryEx(
hProcess, // handle to process
lpAddress, // address of region
lpBuffer,// address of information buffer
dwLength// size of buffer
// GetLastError()
);

//*to avoid crashing

VirtualProtectEx(
hProcess, // handle to process
lpAddress, // address of region of committed pages
dwSize, // size of region
flNewProtect, // desired access protection
lpflOldProtect // address of variable to get old protection
);

ZeroMemory(buf, sizeof(buf));
if( ReadProcessMemory( hProcess, &baseaddr, &buf, bufsize, NULL ) == FALSE )
{
printf("\nProcess memory read failed", GetLastError());
_exit(1);
}
else
{
printf("\nProcess memory read \n");
printf("\nProcess memory read: \n",buf);
}


return(0);
}



From above code i removed semi colon infront of the first function and it compile but now it returns false not the buf size as i want. Remeber " number.exe "can be a any process like "Notepad.exe"

NoHero
March 7th, 2005, 01:24 PM
Nice try, but code tags not quote tags :)


#include <windows.h>
#include <stdio.h>
#include <windef.h>
#include <winbase.h>
#include <imagehlp.h>
//Program that creates a process
//This program assumes that numbers.exe is in the PATH!

LPVOID lpMsgBuf;


//typedef int BOOL;


BOOL EnableDebugPrivNT(void) // Remove ; here
{
HANDLE hToken;
LUID DebugValue;
TOKEN_PRIVILEGES tkp;

//
// Retrieve a handle of the access token
//
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken))
{
return FALSE;
}

//
// Enable the SE_DEBUG_NAME privilege
//
if (!LookupPrivilegeValue((LPSTR) NULL,
SE_DEBUG_NAME,
&DebugValue))
{
return FALSE;
}

tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = DebugValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

AdjustTokenPrivileges(hToken,
FALSE,
&tkp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL);

if (GetLastError() != ERROR_SUCCESS)
{
return FALSE;
}

return TRUE;
}


int main(int argc, char **argv)
{

PROCESS_INFORMATION pi; /* filled in by CreateProcess */
STARTUPINFO si; /* startup info for the new process*/

HANDLE hProcess = NULL;
BYTE buf[2000];
DWORD bufsize = sizeof buf;
DWORD baseaddr = 1;
DWORD error = GetLastError();
LPCVOID lpAddress;
PMEMORY_BASIC_INFORMATION lpBuffer = 0;
DWORD dwLength;
DWORD flNewProtect;
PDWORD lpflOldProtect = 0;
DWORD dwSize =0;
LPCVOID lpBaseAddress;
DWORD nSize;
LPDWORD lpNumberOfBytesRead;


printf("Process %d reporting for creation\n",GetCurrentProcessId());//print out our process ID
GetStartupInfo(&si);

// Call CreateProcess, telling it to run an exe file
CreateProcess(NULL, /* lpApplicationName */
"numbers.exe", /* lpCommandLine assumes to use curent process directory*/
NULL, /* lpsaProcess */
NULL, /* lpsaThread */
FALSE, /* bInheritHandles */
CREATE_NEW_CONSOLE, /* dwCreationFlags */
NULL, /* lpEnvironment */
NULL, /* lpCurDir */
&si, /* lpStartupInfo */
&pi /* lpProcInfo */
);

// hProcess = pi.hProcess;

printf("New Process ID: %d ",pi.dwProcessId);
printf("has started \n");







//============================================
// OpenProcess(
// PROCESS_ALL_ACCESS, // access flag
// 0, // handle inheritance flag
// pi.dwProcessId, // process identifier
// );
//===============================================

GetModuleHandle(
"numbers.exe" // address of module name to return handle
// for
);



VirtualQueryEx(
hProcess, // handle to process
lpAddress, // address of region
lpBuffer,// address of information buffer
dwLength// size of buffer
// GetLastError()
);

//*to avoid crashing

VirtualProtectEx(
hProcess, // handle to process
lpAddress, // address of region of committed pages
dwSize, // size of region
flNewProtect, // desired access protection
lpflOldProtect // address of variable to get old protection
);

ZeroMemory(buf, sizeof(buf));
if( ReadProcessMemory( hProcess, &baseaddr, &buf, bufsize, NULL ) == FALSE )
{
printf("\nProcess memory read failed", GetLastError());
_exit(1);
}
else
{
printf("\nProcess memory read \n");
printf("\nProcess memory read: \n",buf);
}


return(0);
}


The ';' says the compiler that the function declaration is only a declaration, not an implementation. The declarations only shows the compiler how a function looks like (name, parameters und return value) and not how it "works". The implementation is used to define how it "works". This shows how to use functoin pre declarations:


int foo ( void ); // Only a declaration not implementation

int main ( int, char** )
{
return foo(); // Call declarated function
}

int foo ( void ) // Do not use the ; here, cuz this is the implementation
{
printf("Hello World\n");
return 0;
}

Darka
March 7th, 2005, 01:24 PM
looks better, does it compile ?

also, you really should use code tags.

mpapeo
March 7th, 2005, 01:44 PM
Yes it compiles and its coming to where i want!
I want to capture size of memory of this process created, but now it doesn't return this buf size but the false part of readprocessmemory(). Pliz help

this function:

ZeroMemory(buf, sizeof(buf));
if( ReadProcessMemory( hProcess, &baseaddr, &buf, bufsize, NULL ) == FALSE )
{
printf("\nProcess memory read failed", GetLastError());
_exit(1);
}
else
{
printf("\nProcess memory read: \n",buf);
}


return(0);

NoHero
March 7th, 2005, 01:53 PM
Check this! (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/collecting_memory_usage_information_for_a_process.asp) :wave:

mpapeo
March 7th, 2005, 02:07 PM
Good site, it may help. I'm still studying readmemoinfo
but my compiler cannot find

#include "psapi.h"

NoHero
March 7th, 2005, 02:09 PM
Well then try ...


#include <psapi.h>


And I think you will also need the library file (so the linker can reference the external calls of psapi.dll):


#pragma comment(lib, "psapi.lib")


/You got the code tags :)

mpapeo
March 7th, 2005, 02:32 PM
But does the code compiles well in your compiler, i mean the example?? Because i get lot of errors i don't if its because of that header

NoHero
March 7th, 2005, 02:33 PM
But does the code compiles well in your compiler, i mean the example?? Because i get lot of errors i don't if its because of that header

Post the errors (and use code tags) and I will take a look at them ...

NoHero
March 7th, 2005, 02:37 PM
Well this code ...


#include <windows.h>
#include <stdio.h>
#include "psapi.h"

#pragma comment(lib, "psapi.lib")

void PrintMemoryInfo( DWORD processID )
{
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;

// Print the process identifier.

printf( "\nProcess ID: %u\n", processID );

// Print information about the memory usage of the process.

hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
if (NULL == hProcess)
return;

if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
{
printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
printf( "\tPeakWorkingSetSize: 0x%08X\n",
pmc.PeakWorkingSetSize );
printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n",
pmc.QuotaPeakPagedPoolUsage );
printf( "\tQuotaPagedPoolUsage: 0x%08X\n",
pmc.QuotaPagedPoolUsage );
printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n",
pmc.QuotaPeakNonPagedPoolUsage );
printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n",
pmc.QuotaNonPagedPoolUsage );
printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage );
printf( "\tPeakPagefileUsage: 0x%08X\n",
pmc.PeakPagefileUsage );
}

CloseHandle( hProcess );
}

void main( )
{
// Get the list of process identifiers.

DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;

if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
return;

// Calculate how many process identifiers were returned.

cProcesses = cbNeeded / sizeof(DWORD);

// Print the memory usage for each process

for ( i = 0; i < cProcesses; i++ )
PrintMemoryInfo( aProcesses[i] );
}


... compiles fine on my Visual Studio .NET 7.0. The only thing I need to modify is: Include the #pragma directive to add the lib file to the linker. (highlighted)

mpapeo
March 7th, 2005, 02:39 PM
I got these errors, i don't know if its because of the libraries or what?


Compiling...
memoinfo.c
E:\memoinfo.c(9) : error C2065: 'PROCESS_MEMORY_COUNTERS' : undeclared identifier
E:\memoinfo.c(9) : error C2146: syntax error : missing ';' before identifier 'pmc'
E:\memoinfo.c(9) : error C2065: 'pmc' : undeclared identifier
E:\memoinfo.c(23) : warning C4013: 'GetProcessMemoryInfo' undefined; assuming extern returning int
E:\memoinfo.c(25) : error C2224: left of '.PageFaultCount' must have struct/union type
E:\memoinfo.c(28) : error C2224: left of '.WorkingSetSize' must have struct/union type
E:\memoinfo.c(31) : error C2224: left of '.QuotaPagedPoolUsage' must have struct/union type
E:\memoinfo.c(36) : error C2224: left of '.PagefileUsage' must have struct/union type
E:\memoinfo.c(37) : error C2224: left of '.PeakPagefileUsage' must have struct/union type
E:\memoinfo.c(50) : warning C4013: 'EnumProcesses' undefined; assuming extern returning int
Error executing cl.exe.

memoinfo.obj - 8 error(s), 2 warning(s)


after trying yours
i get this


Compiling...
memoinfo.c
E:\memoinfo.c(3) : fatal error C1083: Cannot open include file: 'psapi.h': No such file or directory
Error executing cl.exe.

memoinfo.obj - 1 error(s), 0 warning(s)

NoHero
March 7th, 2005, 02:46 PM
Then you are missing the PSAPI include file. PSAPI is not supported by Windows 9X versions. If you are running NT or above, you should download the newest Software SDK by Microsoft to get this file. If you are sure you have it, search for it in the Microsoft Visual Studio subfolder, if you found it, add the directory where it is located to the "include directory" path list.

NoHero
March 7th, 2005, 02:48 PM
Sorry for missing something: Use these defines of macros before you include the windows header file:


#define _WIN32_WINNT 0x0400
#define WINVER 0x0400
// Includes
#include <windows.h>

mpapeo
March 7th, 2005, 02:55 PM
Sorry for missing something: Use these defines of macros before you include the windows header file:


#define _WIN32_WINNT 0x0400
#define WINVER 0x0400
// Includes
#include <windows.h>


im using windows 2000

C:\Program Files\Microsoft Visual Studio\VC98\Include

there is no psapi there as a header file but its there in other folders like system 32 e.t.c

NoHero
March 7th, 2005, 03:00 PM
Well if it doesn't work with the includes above, you should download the latest Platform SDK.

mpapeo
March 7th, 2005, 03:06 PM
Well thats another problem. If you have the site you can post it here for please, but i will search in google.

NoHero
March 7th, 2005, 03:10 PM
Here (http://www.microsoft.com/msdownload/platformsdk/sdkupdate/downlevel.htm) (found by typing Microsoft Platform SDK into google)

/Me go to sleep now ...

mpapeo
March 7th, 2005, 03:13 PM
Thanks very much, good night. I also have to go and sleep but its only that i have to be through about this by the end of the week.

Good Luck