home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 1999 October
/
PCWorld_1999-10_cd1.bin
/
Hardware
/
Drivers
/
APISpy
/
Procmem.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-07-16
|
4KB
|
141 lines
/*************************************************************
Module name: ProcMem.C
Notices: Copyright (c) 1995-1997 Jeffrey Richter
*************************************************************/
#include "CmnHdr.H" /* See Appendix C. */
#include <windows.h>
#include "ProcMem.H"
//////////////////////////////////////////////////////////////
#if defined(_X86_)
#define STACKPTR(Context) ((Context).Esp)
#endif
#if defined(_MIPS_)
#define STACKPTR(Context) ((Context).IntSp)
#endif
#if defined(_ALPHA_)
#define STACKPTR(Context) ((Context).IntSp)
#endif
#if defined(_PPC_)
#define STACKPTR(Context) ((Context).Gpr1)
#endif
#if !defined(STACKPTR)
#error Module contains CPU-specific code; modify and recompile.
#endif
//////////////////////////////////////////////////////////////
PVOID AllocProcessMemory (HANDLE hProcess, DWORD dwNumBytes) {
CONTEXT Context;
DWORD dwThreadId, dwNumBytesXferred, dwError;
HANDLE hThread;
HINSTANCE hinstKrnl = GetModuleHandle(__TEXT("Kernel32"));
PVOID pvMem = NULL;
MEMORY_BASIC_INFORMATION mbi;
BOOL fOk = FALSE; // Assume failure.
__try {
hThread = CreateRemoteThread(
hProcess,
NULL, // Default security
dwNumBytes + sizeof(HANDLE),
// Amount of memory to allocate in
// the remote process plus 4 bytes
// for a thread handle
(LPTHREAD_START_ROUTINE)
GetProcAddress(hinstKrnl, "ExitThread"),
// Address of function where thread
// should begin execution. We pass the
// address of ExitThread so that the
// stack will be destroyed.
0, // Parameter passed to thread function.
// This will be passed to ExitThread.
CREATE_SUSPENDED, // Flags. We must create the thread
// suspended so that the thread
// doesn't terminate before we use
// the allocated memory.
&dwThreadId); // ID of the new thread
if (hThread == NULL) {
dwError = GetLastError(); // For debugging
__leave;
}
Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
if (!GetThreadContext(hThread, &Context))
__leave;
// Determine the bottom address of the committed memory.
if (sizeof(mbi) != VirtualQueryEx(hProcess,
(PDWORD) STACKPTR(Context) - 1, &mbi, sizeof(mbi)))
__leave;
// Store the remote thread's handle in the bottommost
// bytes of the allocated memory.
pvMem = (PVOID) mbi.BaseAddress;
fOk = WriteProcessMemory(hProcess, pvMem, &hThread,
sizeof(hThread), &dwNumBytesXferred);
if (!fOk)
__leave;
// Point past the thread's handle.
pvMem = (PVOID) ((PHANDLE) pvMem + 1);
}
__finally {
if (!fOk) {
if (hThread) {
ResumeThread(hThread);
CloseHandle(hThread);
}
pvMem = NULL;
}
}
return(pvMem);
}
//////////////////////////////////////////////////////////////
BOOL FreeProcessMemory (HANDLE hProcess, PVOID pvMem) {
BOOL fOk;
HANDLE hThread;
DWORD dwNumBytesXferred;
// Get the handle of the remote thread from the block of
// memory.
pvMem = (PVOID) ((PHANDLE) pvMem - 1);
fOk = ReadProcessMemory(hProcess, pvMem, &hThread,
sizeof(hThread), &dwNumBytesXferred);
if (fOk) {
if (ResumeThread(hThread) == 0xffffffff) {
// Resume failed, probably because the application
// overwrote the memory containing the handle.
fOk = FALSE;
}
CloseHandle(hThread);
}
return(fOk);
}
//////////////////////// End Of File /////////////////////////