Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   CreateRemoteThread постоянное возникновение ошибки (http://forum.oszone.net/showthread.php?t=141525)

dwar 31-05-2009 20:21 1131787

CreateRemoteThread постоянное возникновение ошибки
 
Появилась необходимость инжектировать свой код в другую программу. Базовый адрес и смещение, куда требуется занести свое значение, известно.
Вот код процедуры:

Код:

procedure TMainForm.Button1Click(Sender: TObject);
var
 
  aParamsSize: DWORD;
  dd,ProcessId,lpNumberOfBytes:cardinal;
  ThreadAddr, ParamAddr: Pointer;
    hThread, hProcess: THandle;
  Wnd :HWND;

procedure ChangePrivilege(szPrivilege: PChar; fEnable: Boolean);
var
  NewState: TTokenPrivileges;
  luid: TLargeInteger;
  hToken: THandle;
  ReturnLength: DWord;
begin
  OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken);
  LookupPrivilegeValue(nil, szPrivilege, luid);

  NewState.PrivilegeCount := 1;
  NewState.Privileges[0].Luid := luid;
  if (fEnable) then
    NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
  else
    NewState.Privileges[0].Attributes := 0;

  AdjustTokenPrivileges(hToken, False, NewState, SizeOf(NewState), nil, ReturnLength);
  CloseHandle(hToken);
end;

// процедура, которая выполняет необходимые изменения в памяти
procedure Injected(Param: PParams); stdcall;
begin
....
end;

begin
  try
  Wnd := FindWindow(nil, WinName); //находим окно
  GetWindowThreadProcessId(Wnd, @ProcessId);

  ChangePrivilege('SeDebugPrivilege', True);

  hProcess := OpenProcess( PROCESS_ALL_ACCESS, true, ProcessId); //хэндл окна

  dd := 1000; //значение, которое надо внести
  aParamsSize := SizeOf(dd);

//выделяем память, где будет храниться процедура Injected 
ThreadAddr := VirtualAllocEx(hProcess, 0, 4, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE);
    WriteProcessMemory(hProcess, ThreadAddr, @Injected, 4, lpNumberOfBytes);

    ParamAddr := VirtualAllocEx(hProcess, 0, 4, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
    WriteProcessMemory(hProcess, ParamAddr, Pointer(dd), 4, lpNumberOfBytes);

    hThread := CreateRemoteThread(hProcess, 0, 0, ThreadAddr, ParamAddr, 0, lpNumberOfBytes);

    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);

  finally
  CloseHandle(hProcess);
  end;

end;

при запуске процедуры, программа, в которую инжектируется год, выдает ошибку «инструкция по адресу 0х0000000 обратилась к памяти по адресу 0х0000000. память не может быть read».
Ошибка возникает при CreateRemoteThread. ThreadAddr и ParamAddr <> nil, т.е. память выделена.
Пожалуйста, помогите разобраться с данной проблемой. В инете встречалась пара сообщений о подобной ошибке, но решения и адекватного объяснения, я так и не встретил.

P.S. Среда delphi 2009

pva 01-06-2009 08:55 1132046

Если CREATE_SUSPENDED указать - та же ошибка получается?

dwar 01-06-2009 13:00 1132204

Сегодня решил эту проблему выделением большего объема памяти под модуль и под параметры, которые передаются ему (+исправил небольшие неточности в самом коде). Хотя все равно остается не понятным, какой же нужно выделить размер, если VirtualAllocEx(hProcess, 0, SizeOf(Injected), MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE); не дает результата. Я просто вписал 512, и все заработало, но это же не есть оптимальный вариант, учитывая, что хранимая функция может быть и большего размера и меньшего.

pva 01-06-2009 13:41 1132235

а под стек и под свободную память откуда оперативка выделяется? (неизвестно как реализуют себя борландовские функции, попавшие в чужой процесс, без инициализации своих библиотек)

DillerInc 01-06-2009 13:58 1132246

dwar, во-первых,вы пробовали отлаживать?Например,в SoftIce.
Во-вторых,внедряя код подобным образом,вы скорее всего получите ошибку доступа.Дело в том,что в вашей процедуре Injected могут быть относительные смещения,а VirtualAllocEx вернёт вам в данном случае адрес,заданный системой.Поэтому смещения будут указывать не туда,куда надо,что и вызовет ошибку.
И почему вы выделяете место для процедуры размером четыре байта?
Более грамотный способ - это внедрение своей библиотеки.Ищите статьи.


Время: 10:48.

Время: 10:48.
© OSzone.net 2001-