procmem.c

来自「一本已经绝版的好书」· C语言 代码 · 共 141 行

C
141
字号
/*************************************************************
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 /////////////////////////

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?