Просмотр полной версии : Ошибка Error_partial_copy при чтении памяти процесса
Проблема такая. При чтении памяти процесса функцией ReadProcessMemory возникает ошибка ERROR_PARTIAL_COPY. Пробовал менять атрибуты защиты (VirtualProtectEx)- не помогло. На каком я зыку будет пример - особого значения не имеет. Мне бы концепцию понять.
Сорс в студию. У меня проблем не было
В общем хочу процесс изнутри сдампить
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib kernel32.lib
.data
szModulePath db 257 dup(?)
hHandle dword ?
hf_ dword ?
m7 dword ?
size_ dword ?
hdumped dword ?
address_ dword ?
error_ db "Cannot create file!",0
si_ dword ?
lpflOldProtect dword ?
hcom dword ?
REGION_ dword ?
CREATED_ db "Rewrite file?",0
open_error db "Cannot open file!",0
name_ db 300 dup (?)
concat_ db "\dumped_.exe",0
read_error db "Read file error!",0
size_headers dword ?
filter_ db "All EXEs",0
size_obraz dword ?
lpNumberOfBytesWritten dword ?
lpNumberOfBytesRead dword ?
title_ db "File To dump",0
.code
DllEntry proc hInstance:HINSTANCE, reason:DWORD, reserved1:DWORD
mov eax,TRUE
.if m7!=7
mov m7,7
invoke GetModuleFileNameA,0,addr szModulePath,255
invoke MessageBoxA,0,addr szModulePath,0,0
.if eax!=0
invoke GetModuleHandle,0
.if eax!=0
mov hHandle,eax
invoke CreateFile,addr szModulePath,GENERIC_READ,FILE_SHARE_READ,0,OPEN_E XISTING,0,0
.if eax==-1
invoke MessageBoxA,0,offset open_error,0,16
jmp ret_
.endif
mov hf_,eax
invoke GetFileSize,hf_,0
.if eax!=0
mov size_,eax
invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE
mov address_,eax
invoke ReadFile,hf_,address_, size_,addr lpNumberOfBytesRead,0
mov edi,lpNumberOfBytesRead
.if edi!=size_
invoke MessageBoxA,0,offset read_error,0,16
jmp free_
.endif
mov eax,address_
cmp word ptr[eax],IMAGE_DOS_SIGNATURE ; ïðîâåðÿåì èñïîëíÿåìûé ëè ýòî ôàéë
jnz free_
add eax, 03ch
mov esi, dword ptr [eax]
sub esi, 03ch
add eax, esi
cmp dword ptr [eax],IMAGE_NT_SIGNATURE ; åñëè íå PE, òî âûõîäèì
jnz free_
assume eax:ptr IMAGE_NT_HEADERS
mov esi,[eax].OptionalHeader.SizeOfHeaders
mov size_headers,esi
mov esi,[eax].OptionalHeader.SizeOfImage
sub esi, size_headers
mov size_obraz,esi
invoke GetCurrentDirectory,255,offset name_
invoke lstrcat,offset name_,offset concat_
invoke CreateFile,addr name_,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0
.if eax!=-1
pushad
invoke MessageBox,0, addr CREATED_,0,MB_YESNO
.if eax!=7
invoke CreateFile,addr name_,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,0,OPEN_ALWAYS,0,0
.if eax==-1
invoke MessageBox,0, addr error_,0,16
jmp free_
.endif
.endif
mov hdumped,eax
popad
.endif
.if eax==-1
invoke CreateFile,addr name_,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,0,OPEN_ALWAYS,0,0
.if eax==-1
invoke MessageBox,0, addr error_,0,16
jmp free_
.endif
mov hdumped,eax
.endif
invoke WriteFile,hdumped,address_,size_headers,addr lpNumberOfBytesWritten,0
free_:
invoke VirtualFree,address_,size_,MEM_DECOMMIT
mov esi,hHandle
add esi,size_headers
pushad
invoke VirtualAlloc,0,size_obraz,MEM_COMMIT,PAGE_READWRIT E
mov REGION_,eax
popad
invoke VirtualProtectEx,-1,esi,size_obraz,PAGE_EXECUTE_READWRITE, addr lpflOldProtect
invoke ReadProcessMemory,-1,esi,REGION_,size_obraz,addr lpNumberOfBytesRead ; вот тут вылетает ошибка
mov edi,lpNumberOfBytesRead
.if edi==size_obraz
invoke WriteFile,hdumped,REGION_,size_obraz,addr lpNumberOfBytesWritten,0
.endif
.endif
invoke VirtualFree,REGION_,size_obraz,MEM_DECOMMIT
invoke CloseHandle,hf_
invoke CloseHandle,hdumped
.endif
.endif
.endif
ret_:
ret
DllEntry Endp
End DllEntry
Причем если отхватить кусочек памяти килобайта на три - прокатывает. А больше - нет.
А смысл вызывать ReadProcessMemory для ТЕКУЩЕГО процесса? оО
Могу непосредственно внедритель продемонстрировать. Так лучше дампить... Изнутри самого процесса, предварительно заслав в него длл. Весь день сегодня просидел за этим
а rep mosvb не рулит? я никак не могу понять, в чем прикол читать таким раком память текущего процесса если можно напрямую =\
Процедура внедрения этой длл......
dump__ proc par__:dword
local procEntry:PROCESSENTRY32
local buffertool:dword
local bufferfirst:dword
local hProcess:dword
LOCAL pNumberOfBytesRead:dword
local written_:dword
local szModulePath[256]:byte
local lpflOldProtect:dword
invoke CreateToolhelp32Snapshot,2,0
mov buffertool, eax
mov procEntry.dwSize,500
invoke Process32First,buffertool, addr procEntry
mov bufferfirst, eax
.if eax!=INVALID_HANDLE_VALUE
xor edi,edi
.while eax!=0
invoke Process32Next,buffertool,addr procEntry
lea esi,procEntry
pushad
invoke lstrcmpiA,addr procEntry.szExeFile,par__
.if eax==0
mov esi,procEntry.th32ProcessID
invoke OpenProcess,PROCESS_ALL_ACCESS,0,esi
.if eax!=0
mov hProcess,eax
jmp alloc_
nachalo_shell:
jmp metka1
metka2:
call metka3
library_razbor:
mov edi,dword ptr[esp+4]
mov esi,dword ptr [esp+8]
mov eax,dword ptr [edi+3Ch]
mov ebx,dword ptr[esp+4]
mov ebp,edi
mov edx,dword ptr [ebp+eax+78h]
add edx,ebp
mov ecx,dword ptr [edx+18h]
mov ebx,dword ptr [edx+20h]
add ebx,ebp
push esi
poka:
jecxz exit_from_proc
dec ecx
xor esi,esi
mov esi,dword ptr [ebx+ecx*4h]
add esi,ebp
xor edi,edi
cld
cycl_:
xor eax,eax
lodsb
cmp al,ah ; конец строки?
je null_symbol
rol edi,0Ah ; хешируем
add edi,eax
jmp cycl_
null_symbol:
cmp edi,dword ptr[esp] ; сравниваем хеши
jnz poka
mov ebx,dword ptr [edx+24h]
ADD EBX,EBP
mov cx,word ptr [ebx+ecx*2h]
mov ebx,dword ptr [edx+1Ch]
add ebx,ebp
mov eax,dword ptr [ebx+ecx*4h]
add eax,ebp
exit_from_proc:
pop esi
db 0c3h ; ret
metka1:
call metka2
metka3:
pop edi
push edi
db 64h,0a1h,30h,00h,00h,00h ; у меня компилятор не скомпилил mov eax,fs:[30]
mov eax,dword ptr [eax+0ch]
mov esi,dword ptr[eax+1ch]
lodsd
mov edx,dword ptr [eax+8h]
push 5d217051h ; LoadLibraryA
push edx
call edi
jmp name_of_module
llibrary_:
pop edi
push edi
call eax
dead_loo:
jmp dead_loo ; в мертвый цикл...............
name_of_module:
call llibrary_
path:
db 258 dup(0)
alloc_:
invoke VirtualProtect,offset path,258,PAGE_EXECUTE_READWRITE,addr lpflOldProtect
.if eax==0
invoke MessageBoxA,0,offset error_protect,0,0
jmp ret_
.endif
invoke GetCurrentDirectory,255,offset path
.if eax==0
invoke MessageBoxA,0,offset error_dir,0,0
jmp ret_
.endif
invoke lstrcat,offset path,offset sym_
invoke lstrcat,offset path,offset dll_ ; составляем путь к библиотеке
mov edi,offset alloc_
sub edi,offset nachalo_shell ; вычисляем размер внедряемого кода
mov si_,edi
pushad
invoke VirtualAllocEx,hProcess,0,si_, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
.if eax==0 ; выделилась ли память в процессе
invoke MessageBoxA,0,offset error_alloc,0,0
jmp ret_
.endif
.if eax!=0
mov addr_in_process_,eax
invoke WriteProcessMemory,hProcess,addr_in_process_,offse t nachalo_shell,si_,addr written_
.if eax==0
invoke MessageBoxA,0,offset error_write,0,0
jmp ret_
.endif
invoke CreateRemoteThread,hProcess,0, 0,addr_in_process_,0, 0,0
.endif
.endif
jmp ret_
.endif
popad
.endw
.endif
ret_:
ret
dump__ endp
хотя не думаю что это суть важно. Уж не знаю что делать
Дык это ж длл для боевых условий. Как я прочитаю, если память недоступна? Причем у народа такая ошибка возникала и при чтении из другого процесса. И при записи. Как вариант был VirtualProtect, но не помогло.
Как я прочитаю, если память недоступна?
VirtualProtect ? потом чтение через rep movsb. В упор не пойму зачем использовать readprocessmemory для текущего процесса
есть принципиальная разница? А вот еще. VirtualProtect тоже падает с ошибкой invalid address
Я веду к тому, что попробуй прочитать блок вручную - может быть, узнаешь почему у ReadProcessMemory не получается.
VirtualProtect тоже падает с ошибкой invalid address
а такой адрес точно правильный?
Сейчас попробую. Все-таки не могу понять отчего и VirtualProtect не работает. Вроде значение размера образа беру с диска..... из поля SizeOfImage. Да я за отладчиком сижу. Адрес правильный. Заголовок беру с диска. Потом вычитаю размер заголовка. Все правильно. Но память недоступна.
0x0c0de
Такая ошибка возникает если,
Читать неоткуда или писать некуда, нет таких участков памяти.
Твою прогу откампелил в EXE , ERROR_PARTIAL_COPY не было, все сработало.
используй Setlasterror 0; ReadProcessMemory; getlasterror;
В отладчике глянь. И на размер выходного дампа посмотри.
Это ж dll! В exe? это ж дампер!
Виснет на entry point модуля. VirtualProtect не пашет. *попробовал вручную
Может это потому, что поток неактивен в это время (все эксперименты на loaddll.exe)? Xserg, да есть эта память! 100% но не читается
mov eax,hHandle; address_ кого дампим?
mov esi,[eax].OptionalHeader.SizeOfImage
Все секции сразу не получится.
Xserg, то есть проводить разбор по секциям? Сейчас попробую....
Через ReadProcessMemory да (по секциям), но и длл не нужна (можно из своего процесса)
Да нет, мне dll нужна.... Смотрел внедритель? Я думаю сделать что-то вроде экстремального дампинга.
OpenProcess PROCESS_ALL_ACCESS ; не каждый процесс можно открыть с таким доступом.
Это понятно. Так мне нужно хотя бы с несистемными процессами разобраться.
vBulletin® v3.8.14, Copyright ©2000-2026, vBulletin Solutions, Inc. Перевод: zCarot