Делаю простую утилиту для дампа памяти: Код (Text): #include <windows.h> #include <tlhelp32.h> #include <tchar.h> #include <stdio.h> #define CHUNK_SIZE (4 * 1024 * 1024) #define OUTPUT_DIR "pdump_out" static VOID PrintError(TCHAR *msg); static BOOL GetProcByName(DWORD *pdwPid, const char *pcName); static BOOL DumpProcess(DWORD dwPid); static BOOL DumpModule(HANDLE hProcess, MODULEENTRY32 *me32, BYTE *pBuf); VOID PrintError(TCHAR *msg) { DWORD eNum; TCHAR sysMsg[512]; TCHAR *p; eNum = GetLastError(); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, eNum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), sysMsg, 256, NULL); p = sysMsg; while((*p > 31) || (*p == 9)) ++p; do { *p-- = 0; } while((p >= sysMsg) && ((*p == '.') || (*p < 33))); _tprintf(TEXT("\n WARNING: %s failed with error %d (%s)"), msg, eNum, sysMsg); } BOOL GetProcByName(DWORD *pdwPid, const char *pcName) { HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(hProcessSnap == INVALID_HANDLE_VALUE) { PrintError("CreateToolhelp32Snapshot"); return FALSE; } PROCESSENTRY32 pe32; memset(&pe32, 0, sizeof(pe32)); pe32.dwSize = sizeof(pe32); if(!Process32First(hProcessSnap, &pe32)) { PrintError("Process32First"); CloseHandle(hProcessSnap); return FALSE; } do { if(strcmp(pcName, pe32.szExeFile) == 0) { printf("====================================================="); _tprintf(TEXT("\nPROCESS NAME: %s"), pe32.szExeFile); printf("\n-----------------------------------------------------"); printf("\n Process ID = 0x%08X", pe32.th32ProcessID); printf("\n Thread count = %d", pe32.cntThreads); printf("\n Parent process ID = 0x%08X", pe32.th32ParentProcessID); printf("\n Priority base = %d", pe32.pcPriClassBase); *pdwPid = pe32.th32ProcessID; CloseHandle(hProcessSnap); return TRUE; } } while(Process32Next(hProcessSnap, &pe32)); CloseHandle(hProcessSnap); return FALSE; } BOOL DumpProcess(DWORD dwPid) { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); if(!hProcess) { PrintError("OpenProcess"); return FALSE; } HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPid); if(!hModuleSnap) { PrintError("CreateToolhelp32Snapshot"); return FALSE; } BYTE *pBuf = (BYTE *)HeapAlloc(GetProcessHeap(), 0, CHUNK_SIZE); if(!pBuf) { PrintError("HeapAlloc"); CloseHandle(hProcess); return FALSE; } MODULEENTRY32 me32; memset(&me32, 0, sizeof(me32)); me32.dwSize = sizeof(me32); if(!Module32First(hModuleSnap, &me32)) { PrintError("Module32First"); HeapFree(GetProcessHeap(), 0, pBuf); CloseHandle(hModuleSnap); CloseHandle(hProcess); return FALSE; } do { _tprintf(TEXT("\n\n MODULE NAME: %s"), me32.szModule); _tprintf(TEXT("\n Executable = %s"), me32.szExePath); printf("\n Process ID = 0x%08X", me32.th32ProcessID); printf("\n Ref count (g) = 0x%04X", me32.GlblcntUsage); printf("\n Ref count (p) = 0x%04X", me32.ProccntUsage); printf("\n Base address = 0x%08X", (DWORD)me32.modBaseAddr); printf("\n Base size = %d", me32.modBaseSize); DumpModule(hProcess, &me32, pBuf); } while(Module32Next(hModuleSnap, &me32)); HeapFree(GetProcessHeap(), 0, pBuf); CloseHandle(hModuleSnap); CloseHandle(hProcess); return TRUE; } BOOL DumpModule(HANDLE hProcess, MODULEENTRY32 *me32, BYTE *pBuf) { char szFileName[_MAX_PATH]; strcpy_s(szFileName, sizeof(szFileName), OUTPUT_DIR); strcat_s(szFileName, sizeof(szFileName), "\\"); strcat_s(szFileName, sizeof(szFileName), me32->szModule); strcat_s(szFileName, sizeof(szFileName), ".d"); HANDLE hFile = CreateFile( szFileName, FILE_ALL_ACCESS, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(!hFile) { PrintError("CreateFile"); return FALSE; } BYTE *pBaseAddr = me32->modBaseAddr; DWORD dwBaseSize = me32->modBaseSize; DWORD dwPos = 0; DWORD dwBytesToRead; DWORD dwRes; while(dwPos < dwBaseSize) { DWORD dwDelta = dwBaseSize - dwPos; if(dwDelta >= CHUNK_SIZE) dwBytesToRead = CHUNK_SIZE; else dwBytesToRead = dwDelta; if(!ReadProcessMemory(hProcess, pBaseAddr + dwPos, pBuf + dwPos, dwBytesToRead, &dwRes)) { PrintError("ReadProcessMemory"); CloseHandle(hFile); return FALSE; } if(!WriteFile(hFile, pBuf + dwPos, dwBytesToRead, &dwRes, NULL)) { PrintError("WriteFile"); CloseHandle(hFile); return FALSE; } dwPos += dwBytesToRead; } CloseHandle(hFile); return TRUE; } void main(int argc, char *argv[]) { if(argc < 2) { printf("Usage: pdump <ProcessName>\n"); return; } CreateDirectory(OUTPUT_DIR, NULL); DWORD dwPid; if(GetProcByName(&dwPid, argv[1])) { DumpProcess(dwPid); } } Проблема заключается в том, что иногда ReadProcessMemory возвращает error 998 (Invalid access to memory location). Например: Код (Text): ===================================================== PROCESS NAME: qip.exe ----------------------------------------------------- Process ID = 0x00000BB4 Thread count = 9 Parent process ID = 0x00000228 Priority base = 8 MODULE NAME: qip.exe Executable = C:\Program Files\QIP\qip.exe Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x00400000 Base size = 3297280 MODULE NAME: ntdll.dll Executable = C:\WINDOWS\system32\ntdll.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x7C900000 Base size = 720896 MODULE NAME: kernel32.dll Executable = C:\WINDOWS\system32\kernel32.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x7C800000 Base size = 999424 MODULE NAME: user32.dll Executable = C:\WINDOWS\system32\user32.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x77D40000 Base size = 589824 MODULE NAME: GDI32.dll Executable = C:\WINDOWS\system32\GDI32.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x77F10000 Base size = 286720 MODULE NAME: advapi32.dll Executable = C:\WINDOWS\system32\advapi32.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x77DD0000 Base size = 634880 MODULE NAME: RPCRT4.dll Executable = C:\WINDOWS\system32\RPCRT4.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x77E70000 Base size = 593920 MODULE NAME: oleaut32.dll Executable = C:\WINDOWS\system32\oleaut32.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x77120000 Base size = 573440 MODULE NAME: msvcrt.dll Executable = C:\WINDOWS\system32\msvcrt.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x77C10000 Base size = 360448 MODULE NAME: ole32.dll Executable = C:\WINDOWS\system32\ole32.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x774E0000 Base size = 1294336 MODULE NAME: version.dll Executable = C:\WINDOWS\system32\version.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x77C00000 Base size = 32768 MODULE NAME: comctl32.dll Executable = C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9\comctl32.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x773D0000 Base size = 1056768 MODULE NAME: SHLWAPI.dll Executable = C:\WINDOWS\system32\SHLWAPI.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x77F60000 Base size = 483328 MODULE NAME: imm32.dll Executable = C:\WINDOWS\system32\imm32.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x76390000 Base size = 118784 MODULE NAME: winspool.drv Executable = C:\WINDOWS\system32\winspool.drv Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x73000000 Base size = 155648 MODULE NAME: shell32.dll Executable = C:\WINDOWS\system32\shell32.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x7C9C0000 Base size = 8470528 WARNING: ReadProcessMemory failed with error 998 (Invalid access to memory location) MODULE NAME: comdlg32.dll Executable = C:\WINDOWS\system32\comdlg32.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x763B0000 Base size = 299008 MODULE NAME: winmm.dll Executable = C:\WINDOWS\system32\winmm.dll Process ID = 0x00000BB4 Ref count (g) = 0xFFFF Ref count (p) = 0xFFFF Base address = 0x76B40000 Base size = 184320 MODULE NAME: MSCTF.dll Executable = C:\WINDOWS\system32\MSCTF.dll Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x74720000 Base size = 307200 MODULE NAME: uxtheme.dll Executable = C:\WINDOWS\system32\uxtheme.dll Process ID = 0x00000BB4 Ref count (g) = 0x0003 Ref count (p) = 0x0003 Base address = 0x5AD70000 Base size = 229376 MODULE NAME: olepro32.dll Executable = C:\WINDOWS\system32\olepro32.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x5EDD0000 Base size = 94208 MODULE NAME: D3d8.dll Executable = C:\WINDOWS\system32\D3d8.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x6D9A0000 Base size = 1212416 MODULE NAME: d3d8thk.dll Executable = C:\WINDOWS\system32\d3d8thk.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x6D990000 Base size = 24576 MODULE NAME: DSound.dll Executable = C:\WINDOWS\system32\DSound.dll Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x73F10000 Base size = 376832 MODULE NAME: security.dll Executable = C:\WINDOWS\system32\security.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x71F80000 Base size = 16384 MODULE NAME: SECUR32.dll Executable = C:\WINDOWS\system32\SECUR32.dll Process ID = 0x00000BB4 Ref count (g) = 0x0003 Ref count (p) = 0x0003 Base address = 0x77FE0000 Base size = 69632 MODULE NAME: msv1_0.dll Executable = C:\WINDOWS\system32\msv1_0.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x77C70000 Base size = 143360 MODULE NAME: WS2_32.dll Executable = C:\WINDOWS\system32\WS2_32.dll Process ID = 0x00000BB4 Ref count (g) = 0x0025 Ref count (p) = 0x0025 Base address = 0x71AB0000 Base size = 94208 MODULE NAME: WS2HELP.dll Executable = C:\WINDOWS\system32\WS2HELP.dll Process ID = 0x00000BB4 Ref count (g) = 0x0028 Ref count (p) = 0x0028 Base address = 0x71AA0000 Base size = 32768 MODULE NAME: iphlpapi.dll Executable = C:\WINDOWS\system32\iphlpapi.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x76D60000 Base size = 102400 MODULE NAME: docking.dll Executable = C:\Program Files\QIP\Plugins\docking.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x10000000 Base size = 65536 MODULE NAME: CLBCATQ.DLL Executable = C:\WINDOWS\system32\CLBCATQ.DLL Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x76FD0000 Base size = 520192 MODULE NAME: COMRes.dll Executable = C:\WINDOWS\system32\COMRes.dll Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x77050000 Base size = 806912 MODULE NAME: Flash8.ocx Executable = C:\WINDOWS\system32\Macromed\Flash\Flash8.ocx Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x30000000 Base size = 2236416 MODULE NAME: WSOCK32.dll Executable = C:\WINDOWS\system32\WSOCK32.dll Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x71AD0000 Base size = 36864 MODULE NAME: WININET.dll Executable = C:\WINDOWS\system32\WININET.dll Process ID = 0x00000BB4 Ref count (g) = 0x0005 Ref count (p) = 0x0005 Base address = 0x771B0000 Base size = 679936 MODULE NAME: CRYPT32.dll Executable = C:\WINDOWS\system32\CRYPT32.dll Process ID = 0x00000BB4 Ref count (g) = 0x0012 Ref count (p) = 0x0012 Base address = 0x77A80000 Base size = 606208 MODULE NAME: MSASN1.dll Executable = C:\WINDOWS\system32\MSASN1.dll Process ID = 0x00000BB4 Ref count (g) = 0x0013 Ref count (p) = 0x0013 Base address = 0x77B20000 Base size = 73728 MODULE NAME: urlmon.dll Executable = C:\WINDOWS\system32\urlmon.dll Process ID = 0x00000BB4 Ref count (g) = 0x0007 Ref count (p) = 0x0007 Base address = 0x77260000 Base size = 638976 MODULE NAME: WINTRUST.dll Executable = C:\WINDOWS\system32\WINTRUST.dll Process ID = 0x00000BB4 Ref count (g) = 0x0008 Ref count (p) = 0x0008 Base address = 0x76C30000 Base size = 188416 MODULE NAME: IMAGEHLP.dll Executable = C:\WINDOWS\system32\IMAGEHLP.dll Process ID = 0x00000BB4 Ref count (g) = 0x0008 Ref count (p) = 0x0008 Base address = 0x76C90000 Base size = 163840 MODULE NAME: wdmaud.drv Executable = C:\WINDOWS\system32\wdmaud.drv Process ID = 0x00000BB4 Ref count (g) = 0x0009 Ref count (p) = 0x0009 Base address = 0x72D20000 Base size = 36864 MODULE NAME: msacm32.drv Executable = C:\WINDOWS\system32\msacm32.drv Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x72D10000 Base size = 32768 MODULE NAME: MSACM32.dll Executable = C:\WINDOWS\system32\MSACM32.dll Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x77BE0000 Base size = 86016 MODULE NAME: midimap.dll Executable = C:\WINDOWS\system32\midimap.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x77BD0000 Base size = 28672 MODULE NAME: SXS.DLL Executable = C:\WINDOWS\system32\SXS.DLL Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x75E90000 Base size = 720896 MODULE NAME: shdocvw.dll Executable = C:\WINDOWS\system32\shdocvw.dll Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x77760000 Base size = 1490944 MODULE NAME: CRYPTUI.dll Executable = C:\WINDOWS\system32\CRYPTUI.dll Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x754D0000 Base size = 524288 MODULE NAME: NETAPI32.dll Executable = C:\WINDOWS\system32\NETAPI32.dll Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x5B860000 Base size = 344064 MODULE NAME: WLDAP32.dll Executable = C:\WINDOWS\system32\WLDAP32.dll Process ID = 0x00000BB4 Ref count (g) = 0x0003 Ref count (p) = 0x0003 Base address = 0x76F60000 Base size = 180224 MODULE NAME: shdoclc.dll Executable = C:\WINDOWS\system32\shdoclc.dll Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x20000000 Base size = 557056 MODULE NAME: xpsp2res.dll Executable = C:\WINDOWS\system32\xpsp2res.dll Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x03260000 Base size = 2904064 MODULE NAME: mshtml.dll Executable = C:\WINDOWS\system32\mshtml.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x7D4A0000 Base size = 3022848 MODULE NAME: msls31.dll Executable = C:\WINDOWS\system32\msls31.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x746C0000 Base size = 159744 MODULE NAME: mlang.dll Executable = C:\WINDOWS\system32\mlang.dll Process ID = 0x00000BB4 Ref count (g) = 0x0003 Ref count (p) = 0x0003 Base address = 0x75CF0000 Base size = 593920 MODULE NAME: KsUser.dll Executable = C:\WINDOWS\system32\KsUser.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x73EE0000 Base size = 16384 MODULE NAME: mswsock.dll Executable = C:\WINDOWS\System32\mswsock.dll Process ID = 0x00000BB4 Ref count (g) = 0x0005 Ref count (p) = 0x0005 Base address = 0x71A50000 Base size = 258048 MODULE NAME: DNSAPI.dll Executable = C:\WINDOWS\system32\DNSAPI.dll Process ID = 0x00000BB4 Ref count (g) = 0x0002 Ref count (p) = 0x0002 Base address = 0x76F20000 Base size = 159744 MODULE NAME: winrnr.dll Executable = C:\WINDOWS\System32\winrnr.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x76FB0000 Base size = 32768 MODULE NAME: rasadhlp.dll Executable = C:\WINDOWS\system32\rasadhlp.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x76FC0000 Base size = 24576 MODULE NAME: hnetcfg.dll Executable = C:\WINDOWS\system32\hnetcfg.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x662B0000 Base size = 360448 MODULE NAME: wshtcpip.dll Executable = C:\WINDOWS\System32\wshtcpip.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x71A90000 Base size = 32768 MODULE NAME: msimtf.dll Executable = C:\WINDOWS\system32\msimtf.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x746F0000 Base size = 172032 MODULE NAME: jscript.dll Executable = C:\WINDOWS\system32\jscript.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x75C50000 Base size = 450560 MODULE NAME: SETUPAPI.dll Executable = C:\WINDOWS\system32\SETUPAPI.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x77920000 Base size = 995328 MODULE NAME: appHelp.dll Executable = C:\WINDOWS\system32\appHelp.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x77B40000 Base size = 139264 MODULE NAME: mshtmled.dll Executable = C:\WINDOWS\system32\mshtmled.dll Process ID = 0x00000BB4 Ref count (g) = 0x0001 Ref count (p) = 0x0001 Base address = 0x76200000 Base size = 462848
Как корабль назовешь, так он и поплывет... Код глянул мельком, но VirtualProtect перед вызовом ReadProcessMemory не нашел, в этом и ошибка.
Странно, почему без VirtualProtect не работает на некоторых либах. Код (Text): BOOL DumpModule(HANDLE hProcess, MODULEENTRY32 *me32, BYTE *pBuf) { char szFileName[_MAX_PATH]; strcpy_s(szFileName, sizeof(szFileName), OUTPUT_DIR); strcat_s(szFileName, sizeof(szFileName), "\\"); strcat_s(szFileName, sizeof(szFileName), me32->szModule); strcat_s(szFileName, sizeof(szFileName), ".d"); HANDLE hFile = CreateFile( szFileName, FILE_ALL_ACCESS, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(!hFile) { PrintError("CreateFile"); return FALSE; } MEMORY_BASIC_INFORMATION virtualInfo; BYTE *pBaseAddr = me32->modBaseAddr; BYTE *pAddr; DWORD dwBaseSize = me32->modBaseSize; DWORD dwPos = 0; DWORD dwDelta; DWORD dwBytesToRead; DWORD dwProtect; DWORD dwOldProtect; DWORD dwBytes; BOOL bRet = FALSE; while(dwPos < dwBaseSize) { pAddr = pBaseAddr + dwPos; dwDelta = dwBaseSize - dwPos; if(dwDelta >= CHUNK_SIZE) dwBytesToRead = CHUNK_SIZE; else dwBytesToRead = dwDelta; VirtualQuery(pAddr, &virtualInfo, sizeof(virtualInfo)); dwProtect = virtualInfo.AllocationProtect | PAGE_EXECUTE_READ; if(!VirtualProtect(pAddr, dwBytesToRead, dwProtect, &dwOldProtect)) { PrintError("VirtualProtect"); goto err; } if(!ReadProcessMemory(hProcess, pAddr, pBuf + dwPos, dwBytesToRead, &dwBytes)) { PrintError("ReadProcessMemory"); goto err; } if(!WriteFile(hFile, pBuf + dwPos, dwBytesToRead, &dwBytes, NULL)) { PrintError("WriteFile"); goto err; } if(!VirtualProtect(pAddr, dwBytesToRead, dwOldProtect, &dwProtect)) { PrintError("VirtualProtect"); goto err; } dwPos += dwBytesToRead; } pAddr = NULL; bRet = TRUE; err: if(pAddr) VirtualProtect(pAddr, dwBytesToRead, dwOldProtect, &dwProtect); CloseHandle(hFile); return bRet; } VirtualProtect failed with error 487 (Attempt to access invalid address) В msdn сказано что можно менять флаги доступа только для страниц целиком, может нужно dwBytesToRead получать из MEMORY_BASIC_INFORMATION?