WriteProcessMemory не выполняется...

Тема в разделе "WASM.WIN32", создана пользователем SnugForce, 25 сен 2005.

  1. SnugForce

    SnugForce New Member

    Публикаций:
    0
    Регистрация:
    2 май 2005
    Сообщения:
    373
    Адрес:
    Из домУ
    Написал для перезаписи кода функции:

    Все нормально кроме WriteProcessMemory, после его вызова вылазит ошибка: "Privileged instruction" и есно память код не переписан :dntknw:.
    Код (Text):
    1.  
    2. var
    3.   msFile: TMemoryStream;
    4.   p, p1, p2: pointer;
    5.   dp: integer;
    6.   h: THandle;
    7.   p_buf: pointer;
    8.   t: Cardinal;
    9. begin
    10.   p1 := @MainF; // адрес начала функции
    11.   p2 := @EndF;  // Конец
    12.  
    13.   dp := integer(p2) - integer(p1) - 1;
    14.   h := OpenProcess(PROCESS_VM_WRITE, false, GetCurrentProcessId);
    15.   if h = NULL then
    16.   begin
    17.     Memo1.lines.Add('Не могу открыть свой процесс.');
    18.     exit;
    19.   end;
    20.  
    21.   p_buf := nil;
    22.   p_buf := VirtualAlloc(nil,dp,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    23.   if p_buf = nil then
    24.     Memo1.lines.Add('Не могу выделить память.');
    25.  
    26.   // Загрузка данных в выдленную память
    27.   // Можно не обращать внимания
    28.   msFile := TMemoryStream.Create;
    29.   msFile.LoadFromFile('code.dat');
    30.   msFile.Position := 0;
    31.   msFile.Read(p_buf, dp);
    32.   msFile.Free;
    33.  
    34.   if ( not WriteProcessMemory(h, p1, p_buf, dp, t)) then
    35.     Memo1.lines.Add('Не могу записать в память процесса.')
    36.   else
    37.     Memo1.lines.Add('Память записана.');
    38.    
    39.   VirtualFree(p_buf, dp, 0);
    40. end;
    41.  
     
  2. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Это все Ms Rem виноват, с его подачи теперь

    считается нормальным тоном постить на wasm листинги

    на дельфи :derisive:
     
  3. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Asterix

    В чем же я виноват? Случайно не в том, что заставил некоторых оставить старинные предрассудки? Или может быть кто-то здесь суеверен?



    SnugForce

    Код довольно хренов.

    Во-первых: зачем открывать свой процесс? Хэедл своего процесса ВСЕГДА равен INVALID_HANDLE_VALUE.

    Во-вторых: VirtualAlloc для маленьких участков памяти лучше не использовать. В Delphi RTL есть функция GetMem, которая работает в разы быстрее, если же пишеться код без RTL, то лучше использовать HeapAlloc.

    В-третьих: зачем записывать с помощью WriteProcessMemory в свой процесс? Лучше с помощью VirtualProtect изменить атрибуты нужной области памяти и использовать CopyMemory

    В-Четвертых (хотя это уже придирка): ООП не рулит, долой TMemoryStream и TMemo.

    В-пятых: зачем перед VirtualAlloc делать p_buf := nil?



    Короче, перепиши код по нормальному и тогда он заработает.
     
  4. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    SnugForce

    С подобным кодом тебе дорога в "Королевство Делфи", в лучшем случае на рсдн в соответствующий форум.



    Asterix

    Не надо делать кого-то виноватым в ламерстве третьих лиц.



    Ms Rem

    Значит,
    — это постить на форум Win32 сайта, посвящённого низкоуровневому программированию, откровенно ламерские листинги Делфи с использованием VCL?
     
  5. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"




    Вообще то Asterix высказался не против кода в этом листинге, а против языка на котором он написан. А про хреновость этого кода я и сам сказал. А оставить предрассудки означает лишь принятие любого языка пригодного для решения низкоуровневых задач. Если бы был приведен листинг даже на Visual Basic (а на нем тоже ухитряются системные вещи писать), то я был бы не против этого. К VCL конечно отношение особое, этому действительно место в "Королевстве Delphi", но сам вопрос вроде не был связан с VCL.
     
  6. SnugForce

    SnugForce New Member

    Публикаций:
    0
    Регистрация:
    2 май 2005
    Сообщения:
    373
    Адрес:
    Из домУ
    Сорри за все...

    Впредь больше не буду постить с VCL. Просто для меня еще туго все на API писать...
     
  7. Saint German

    Saint German New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2003
    Сообщения:
    222
    Asterix

    :)

    SnugForce

    Я вот, этот код даже не стал рассматривать.
     
  8. DESTROY_ru

    DESTROY_ru New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    17
    Только не понимаю, почему все взъелись на SnugForce. Какая разница на чём написан код, у человека проблема, кто может помочь решить помогите.Не можете помочь проигнорируйте. Если модераторы сочтут нужным, объяснят человеку всё "по понятиям про WASM и DELPHI".
     
  9. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    SnugForce

    > "Просто для меня еще туго все на API писать..."

    1) Пиши на чем хочешь, но вопросы формулируй по сути и без излишеств. И IceStudent прав - откровенно ламерские листинги Делфи с использованием VCL тут ни к месту, и Ms Rem прав - дело не в языке, а в сути вопроса. А посему совет: не приводи длинные листинги с ненужными подробностями (особенно на "чуждом" языке :) - заменяй несущественные детали многоточиями типа if not WriteProcessMemory then ... else ..., можно с пояснениями типа "читаем из файла" и т.п.



    2) По сути вопроса по Win32: в любом случае для записи в секцию кода (хоть своего процесса, хоть чужого) нужно получить разрешение на запись в соответствующую область памяти. Для своего процесса это делается с помощью VirtualProtect(p1,dp,PAGE_EXECUTE_READWRITE,OldProtect) и соответсвенно никаких OpenProcess и WriteProcessMemory делать не нужно. Затем код просто копируется из p_buf в p1 (апишнной CopyMemory или дельфийской Move).



    PS: А TMemoryStream ты тут юзаешь по ламерски, т.к. при LoadFromFile он сам выделяет нужное количесво памяти и грузит туда данные из файла. Если уж он тебе так нравится, то не нужно выделять никакой доп памяти под p_buf, а просто использовать p_buf:=msFile.Memory. Но это уже вопрос из сферы Королевства кривых зеркал ;)
     
  10. SnugForce

    SnugForce New Member

    Публикаций:
    0
    Регистрация:
    2 май 2005
    Сообщения:
    373
    Адрес:
    Из домУ
    Вот переписал код :). Но он не правильно код сохраняет... только первые байты, остальные нулями заполняются...
    Код (Text):
    1.  
    2. var
    3.   OldProtect: DWORD;
    4.   iFile: Cardinal;
    5.   wb: Cardinal;
    6. begin
    7.   p_begin := @ForCopy;
    8.   p_end := @End_ForCopy;
    9.   dp := integer(p_end) - integer(p_begin);
    10.   VirtualProtect(p_begin, dp, PAGE_EXECUTE_READWRITE, OldProtect);
    11.   iFile := CreateFile('code.dat',GENERIC_WRITE, 0,
    12.                       nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,0);
    13.   WriteFile(iFile, p_begin, dp, wb, 0);
    14.   CloseHandle(iFile);
    15. end;
    16.  
     
  11. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    SnugForce

    Возможно ошибусь, но вроде должно быть

    WriteFile(iFile,p_begin,dp,@wb,nil)?
     
  12. SnugForce

    SnugForce New Member

    Публикаций:
    0
    Регистрация:
    2 май 2005
    Сообщения:
    373
    Адрес:
    Из домУ
    Строчка-то правильная. По кол-ву байт все нормально, но вот содержимое файла и буфера отличаются. Я уж и стандартные функции перепробовал и API. Записывает только первые байты, остальные не хочет. Может надо по блочно записывать? Например, по байту...
     
  13. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    SnugForce

    Это скорее всего дельфийские прибамбасы с импортом - они часто в апишных функциях заменяют аргументы lpvoid на нетипированные var. Поэтому скорее всего у тебя пишется сам адрес p_begin, а не то что лежит по этому адресу. Проверь по подсказке или залезь в windows.pas - скорее всего нужно передавать p_begin^
     
  14. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Вот рабочий код:


    Код (Text):
    1. program Project2;
    2.  
    3. uses
    4.   windows;
    5.  
    6. procedure ForCopy();
    7. asm
    8.  nop
    9.  add eax, 1
    10.  add eax, 2
    11.  xchg edx, esp
    12.  pop eax
    13.  nop
    14.  nop
    15. end;
    16. procedure End_ForCopy();
    17. asm
    18. end;
    19.  
    20. var
    21.   iFile: Cardinal;
    22.   p_begin, p_end: pointer;
    23.   dp, wb: dword;
    24. begin
    25.   p_begin := @ForCopy;
    26.   p_end := @End_ForCopy;
    27.   dp := integer(p_end) - integer(p_begin);
    28.   iFile := CreateFile('c:\code.dat',GENERIC_WRITE, 0,
    29.                       nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,0);
    30.   WriteFile(iFile, p_begin^, dp, wb, nil);
    31.   CloseHandle(iFile);
    32. end.




    VirtualProtect я выкинул, потому что он там нафиг не нужен.
     
  15. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Чем гадать, не проще ли заглянуть в отладчик?

    Остатки Делфи я снёс пару месяцев назад, а то бы и сам проверил, чего она там накуролесила.



    --

    пока писал, Ms-Rem привёл код..
     
  16. SnugForce

    SnugForce New Member

    Публикаций:
    0
    Регистрация:
    2 май 2005
    Сообщения:
    373
    Адрес:
    Из домУ
    Всё... разобрался :)) Теперь все работает. И копирует и записывает код. СПАСИБО всем!
     
  17. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ms Rem, SnugForce

    И не лень вам приведение типов в integer(p_begin)-integer(p_end) делать ;) Не проще ли в подобных случаях объявлять указатели как pChar

    Ах, извините, это уже из сферы Королевства ;)))
     
  18. SnugForce

    SnugForce New Member

    Публикаций:
    0
    Регистрация:
    2 май 2005
    Сообщения:
    373
    Адрес:
    Из домУ
    понял... исправлюсь