home *** CD-ROM | disk | FTP | other *** search
/ PC World 1999 October / PCWorld_1999-10_cd1.bin / Hardware / Drivers / APISpy / Procmem.cpp < prev    next >
C/C++ Source or Header  |  1999-07-16  |  4KB  |  141 lines

  1. /*************************************************************
  2. Module name: ProcMem.C
  3. Notices: Copyright (c) 1995-1997 Jeffrey Richter
  4. *************************************************************/
  5.  
  6.  
  7. #include "CmnHdr.H"                  /* See Appendix C. */
  8. #include <windows.h>
  9. #include "ProcMem.H"
  10.  
  11.  
  12. //////////////////////////////////////////////////////////////
  13.  
  14.  
  15. #if defined(_X86_)
  16. #define STACKPTR(Context)  ((Context).Esp)
  17. #endif
  18.  
  19. #if defined(_MIPS_)
  20. #define STACKPTR(Context)  ((Context).IntSp)
  21. #endif
  22.  
  23. #if defined(_ALPHA_)
  24. #define STACKPTR(Context)  ((Context).IntSp)
  25. #endif
  26.  
  27. #if defined(_PPC_)
  28. #define STACKPTR(Context)  ((Context).Gpr1)
  29. #endif
  30.  
  31. #if !defined(STACKPTR)
  32. #error Module contains CPU-specific code; modify and recompile.
  33. #endif
  34.  
  35.  
  36. //////////////////////////////////////////////////////////////
  37.  
  38.  
  39. PVOID AllocProcessMemory (HANDLE hProcess, DWORD dwNumBytes) {
  40.    CONTEXT Context;
  41.    DWORD dwThreadId, dwNumBytesXferred, dwError;
  42.    HANDLE hThread;
  43.    HINSTANCE hinstKrnl = GetModuleHandle(__TEXT("Kernel32"));
  44.    PVOID pvMem = NULL;
  45.    MEMORY_BASIC_INFORMATION mbi;
  46.    BOOL fOk = FALSE;    // Assume failure.
  47.  
  48.    __try {
  49.       hThread = CreateRemoteThread(
  50.          hProcess, 
  51.          NULL,          // Default security
  52.          dwNumBytes + sizeof(HANDLE),
  53.                         // Amount of memory to allocate in
  54.                         // the remote process plus 4 bytes
  55.                         // for a thread handle
  56.          (LPTHREAD_START_ROUTINE)
  57.             GetProcAddress(hinstKrnl, "ExitThread"),
  58.                         // Address of function where thread
  59.                         // should begin execution. We pass the
  60.                         // address of ExitThread so that the
  61.                         // stack will be destroyed.
  62.          0,             // Parameter passed to thread function.
  63.                         // This will be passed to ExitThread.
  64.          CREATE_SUSPENDED, // Flags. We must create the thread
  65.                            // suspended so that the thread
  66.                            // doesn't terminate before we use
  67.                            // the allocated memory.
  68.          &dwThreadId);     // ID of the new thread
  69.  
  70.       if (hThread == NULL) {  
  71.          dwError = GetLastError();  // For debugging
  72.          __leave;
  73.       }
  74.  
  75.       Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
  76.       if (!GetThreadContext(hThread, &Context))
  77.          __leave;
  78.  
  79.       // Determine the bottom address of the committed memory.
  80.       if (sizeof(mbi) != VirtualQueryEx(hProcess,
  81.          (PDWORD) STACKPTR(Context) - 1, &mbi, sizeof(mbi)))
  82.          __leave;
  83.  
  84.       // Store the remote thread's handle in the bottommost
  85.       // bytes of the allocated memory.
  86.       pvMem = (PVOID) mbi.BaseAddress;
  87.  
  88.       fOk = WriteProcessMemory(hProcess, pvMem, &hThread, 
  89.          sizeof(hThread), &dwNumBytesXferred);
  90.  
  91.       if (!fOk) 
  92.          __leave;
  93.  
  94.       // Point past the thread's handle.
  95.       pvMem = (PVOID) ((PHANDLE) pvMem + 1);
  96.    }
  97.    __finally {
  98.       if (!fOk) {
  99.          if (hThread) {
  100.             ResumeThread(hThread);
  101.             CloseHandle(hThread);
  102.          }
  103.          pvMem = NULL;
  104.       }
  105.    }     
  106.     
  107.     return(pvMem);
  108. }
  109.  
  110.  
  111. //////////////////////////////////////////////////////////////
  112.  
  113.  
  114. BOOL FreeProcessMemory (HANDLE hProcess, PVOID pvMem) {
  115.    BOOL fOk;
  116.    HANDLE hThread;
  117.    DWORD dwNumBytesXferred;
  118.  
  119.  
  120.    // Get the handle of the remote thread from the block of 
  121.    // memory.
  122.    pvMem = (PVOID) ((PHANDLE) pvMem - 1);
  123.  
  124.    fOk = ReadProcessMemory(hProcess, pvMem, &hThread, 
  125.       sizeof(hThread), &dwNumBytesXferred);
  126.  
  127.    if (fOk) {
  128.       if (ResumeThread(hThread) == 0xffffffff) {
  129.          // Resume failed, probably because the application
  130.          // overwrote the memory containing the handle.
  131.          fOk = FALSE;
  132.       }
  133.       CloseHandle(hThread);
  134.    }
  135.  
  136.    return(fOk);
  137. }
  138.  
  139.  
  140. //////////////////////// End Of File /////////////////////////
  141.