A simple example of how to dump the executable image of a process or module/DLL from memory.

Some "process dumpers" try to dump the entire image in one go, for example ...
ReadProcessMemory (BYVAL hProc, BYVAL me32.ModBaseAddr, BYVAL STRPTR(sBuf), BYVAL me32.ModBaseSize, lBytesRead)

That works most of the time, but sometimes it will fail, as MSDN's ReadProcessMemory documentation states: "The entire area to be read must be accessible, and if it is not accessible, the function fails."

The solution is to simply read the image one page at a time -- GetSystemInfo(SYSTEM_INFO) ... SYSTEM_INFO.dwPageSize

Code:
#COMPILE EXE
#INCLUDE "win32api.inc"
#INCLUDE "tlhelp32.inc"
 
FUNCTION DumpModule (BYVAL dwPID AS DWORD, szModule AS ASCIIZ, sBuf AS STRING) AS DWORD  '// Returns LEN(sBuf) if success, 0 if failed
LOCAL hModuleSnap AS DWORD, me32 AS MODULEENTRY32, lResult AS LONG, szLModule AS ASCIIZ * %MAX_PATH, lBytesRead AS DWORD
LOCAL dwBase AS DWORD, dwSize AS DWORD, lpSystemInfo AS SYSTEM_INFO, dwOffset AS DWORD, hProc AS DWORD, i AS DWORD
 GetSystemInfo lpSystemInfo
 szLModule = LCASE$(szModule)
 '// Now try to locate the base address and size of the target module
 hModuleSnap = CreateToolhelp32Snapshot(%TH32CS_SNAPMODULE, dwPID)
 IF hModuleSnap <> %INVALID_HANDLE_VALUE THEN
    me32.dwSize = SIZEOF(MODULEENTRY32)
    lResult = Module32First (hModuleSnap, me32)
    WHILE lResult
        IF LCASE$(me32.szExePath) = szLModule THEN
            dwBase = me32.ModBaseAddr
            dwSize = me32.ModBaseSize
            EXIT
        END IF
        lResult = Module32Next (hModuleSnap, me32)
    WEND
    CloseHandle hModuleSnap
 END IF
 IF dwBase = 0 THEN
    MSGBOX "Couldn't locate module in target process", %MB_ICONERROR + %MB_OK, "Error"
    EXIT FUNCTION
 END IF
 '// Now open the target process
 IF dwPID = GetCurrentProcessId THEN
     hProc = GetCurrentProcess
 ELSE
     hProc = OpenProcess(%PROCESS_VM_READ, %FALSE, dwPID)
     IF hProc = 0 THEN
         MSGBOX "OpenProcess failed", %MB_ICONERROR + %MB_OK, "Error"
         EXIT FUNCTION
     END IF
 END IF
 '// Read the memory one page at a time
 sBuf = STRING$(me32.ModBaseSize + lpSystemInfo.dwPageSize, 0)
 FOR i = 1 TO (me32.ModBaseSize \ lpSystemInfo.dwPageSize) + 1
    ReadProcessMemory (BYVAL hProc, BYVAL me32.ModBaseAddr + dwOffset, BYVAL STRPTR(sBuf) + dwOffset, BYVAL lpSystemInfo.dwPageSize, lBytesRead)
    dwOffset = dwOffset + lpSystemInfo.dwPageSize
 NEXT
 sBuf = LEFT$(sBuf, me32.ModBaseSize)
 FUNCTION = LEN(sBuf)
END FUNCTION


FUNCTION PBMAIN () AS LONG
 '// Dump a module (szModule) from a process (dwPID) into string buffer (sBuf)
 LOCAL dwPID AS DWORD, sBuf AS STRING, szModule AS ASCIIZ * %MAX_PATH
 dwPID = GetCurrentProcessID                                                     '// PID of target process
 GetModuleFilename(BYVAL GetModuleHandle(BYVAL 0), szModule, SIZEOF(szModule))   '// Module filename in target process
 IF DumpModule(BYVAL dwPID, szModule, sBuf) > 0 THEN
     MSGBOX "Success. First two bytes = " & LEFT$(sBuf,2) '// should be "MZ"
 ELSE
     MSGBOX "Failed"
 END IF
 
 '// Save the buffer to disk
 LOCAL hFile AS DWORD: hFile = FREEFILE
 OPEN szModule & "-dumped.dat" FOR BINARY ACCESS WRITE LOCK SHARED AS #hFile
  PUT #hFile, 1, sBuf
 CLOSE #hFile
END FUNCTION