dwar
31-05-2009, 20:21
Появилась необходимость инжектировать свой код в другую программу. Базовый адрес и смещение, куда требуется занести свое значение, известно.
Вот код процедуры:
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
Вот код процедуры:
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