![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
|
Всем Здравствуйте! Есть такой вопрос. Есть моя длл-ка которая инжектируется в другой процесс. Так вот как мне передать параметры в процедуру (например reset(par1,par2:word), в длл-ке она есть), из своей программы?
|
|
#2
|
||||
|
||||
|
Как вариант - при инжекте зарезервировать до/после инжект-кода место под переменные, и писать туда. После чего выставить там же какой-нибудь флаг. Этот флаг проверять в цикле в ДЛЛ, и как только он выставился - сбросить и вызвать нужную функцию с нужными параметрами. Инжект-код может сказать ДЛЛ-ке свой адрес вызовом какой-нибудь специально для этого сделанной функции в самой DLL.
Только вот нескромный вопрос - ради чего такие сложности? |
|
#3
|
||||
|
||||
|
А ещё наверное так можно, библиотека ведь загружена, в смысле её копия в памяти уже есть
сначало объявить Код:
... MyProc = procedure reset(par1, par2: word); stdcall; ... Код:
...
var
proc: MyProc;
begin
@proc := GetProcAddress(HandleDll{нужно подставить}, 'reset');
proc(par1, par2);
...
end; |
|
#4
|
||||
|
||||
|
Цитата:
|
|
#5
|
||||
|
||||
|
Bargest, а че я до длл-ки не могу добратся через CreateToolhelp32Snapshot? Alegun тут как-то мне не понятно
Цитата:
|
|
#6
|
||||
|
||||
|
Цитата:
|
|
#7
|
||||
|
||||
|
Цитата:
Код:
mov eax, param1 mov edx, param2 call reset Цитата:
Klyaksa, поясни, зачем тебе вообще это надо. Может есть решение проще. И код инжекта приведи. Последний раз редактировалось Bargest, 06.04.2014 в 00:36. |
|
#8
|
||||
|
||||
|
Цитата:
|
|
#9
|
||||
|
||||
|
Цитата:
Цитата:
Цитата:
Код:
function InjectModule(ModulePath: PAnsiChar; ProcessID: DWORD): Boolean;
type
TNtCreateThreadEx = function(
ThreadHandle: PHANDLE;
DesiredAccess: ACCESS_MASK;
ObjectAttributes: Pointer;
ProcessHandle: THANDLE;
lpStartAddress: Pointer;
lpParameter: Pointer;
CreateSuspended: BOOL;
dwStackSize: DWORD;
Unknown1: Pointer;
Unknown2: Pointer;
Unknown3: Pointer): HRESULT; stdcall;
var
lpStartAddress, lpParameter: Pointer;
dwSize: Integer;
hProcess, hThread, lpThreadId, lpExitCode, lpBytesWritten: Cardinal;
NtCreateThreadEx: TNtCreateThreadEx;
begin
Result := False;
if IsModuleLoaded(ModulePath, ProcessID) = True then
Exit;
hProcess := 0;
hProcess := OpenProcess(MAXIMUM_ALLOWED, False, ProcessID);
if hProcess = 0 then
Exit;
dwSize := StrLen(ModulePath) + 1;
lpParameter := VirtualAllocEx(hProcess, nil, dwSize, MEM_COMMIT, PAGE_READWRITE);
if (lpParameter = nil) then
begin
if hProcess <> 0 then
CloseHandle(hProcess);
Exit;
end;
if GetOSVersion >= 60 then
NtCreateThreadEx := GetProcAddress(GetModuleHandleW('ntdll'), 'NtCreateThreadEx');
lpStartAddress := GetProcAddress(GetModuleHandleW('kernel32'), 'LoadLibraryA');
if (lpStartAddress = nil) then
Exit;
if GetOSVersion >= 60 then
if (@NtCreateThreadEx = nil) then
Exit;
lpBytesWritten := 0;
if (WriteProcessMemory(hProcess, lpParameter, ModulePath, dwSize, lpBytesWritten) = False) then
begin
VirtualFreeEx(hProcess, lpParameter, 0, MEM_RELEASE);
if hProcess <> 0 then
CloseHandle(hProcess);
Exit;
end;
hThread := 0;
lpThreadId := 0;
if GetOSVersion >= 60 then
NtCreateThreadEx(@hThread, MAXIMUM_ALLOWED, nil, hProcess, lpStartAddress, lpParameter, false, 0, 0, 0, 0)
else
hThread := CreateRemoteThread(hProcess, nil, 0, lpStartAddress, lpParameter, 0, lpThreadId);
if (hThread = 0) then
begin
VirtualFreeEx(hProcess, lpParameter, 0, MEM_RELEASE);
CloseHandle(hProcess);
Exit;
end;
GetExitCodeThread(hThread, lpExitCode);
if hProcess <> 0 then
CloseHandle(hProcess);
if hThread <> 0 then
CloseHandle(hThread);
Result := True;
end;Последний раз редактировалось Klyaksa, 06.04.2014 в 00:48. |
|
#10
|
||||
|
||||
|
Цитата:
![]() |
|
#11
|
||||
|
||||
|
Цитата:
1) Скомпилировал бы в DLL проект с формой для редактирования данных; 2) Сделал бы в этой DLL функцию, заменяющую QueryPerformanceCounter, берущую значение из введенных данных; 3) Сделал бы, чотбы DLL заменила в импорте QueryPerformanceCounter на адрес подменной функции; 4) Пропатчил бы точку входа игры, чтобы она загрузила DLL. Ну или на крайняк написал бы мелкий сторонний инжектор. Если же обязательно надо, чтобы программа ввода была отдельно - то проще всего, на мой взгляд, как я сказал в начале. Стандартная технология инжекта - VirtualAlloc в чужом процессе, создание там побайтово кода загрузки ДЛЛ и запуск этого кода через CreateRemoteThread. Можно запросто выделить побольше места и передать в ДЛЛ после загрузки через какой-нибудь самописный Initialize адрес. Затем брать параметры всегда по какому-то смещению от этого адреса. То есть инжектируемый код будет примерно таким (FASM-синтаксис! не пытайся это скомпилировать во встроенном асм в делфи): Код:
push libName call LoadLibrary push aStart push eax call GetProcAddress call $+5 ; push eip - текущий адрес call eax ; call Start; _stdcall функция с одним параметром; никогда не возвращается ret ; не обязательно, чисто ради приличия param1: .dw 0 param2: .dw 0 libName: .db 'HelloWorld.dll',0 aStart: .db 'Start',0 Остается только менять эти параметры через WriteProcessMemory - в сторонней проге адрес тоже известен, она ведь его и выделила через VirtualAlloc. ЗЫЖ разумеется, при таком подходе DllMain должен сразу завершиться, и вернуть не ноль. Иначе либа автоматом выгрузиться и будешь долго кусать локти и искать ошибку. [EDIT] Код, который ты привел, не очень хорош тем, что вся работа обязательно должна происходить в DLLMain, и никогда нельзя из него выходить. А в DllMain сторонние параметры передать трудновато. Цитата:
![]() Последний раз редактировалось Bargest, 06.04.2014 в 01:29. |
|
#12
|
||||
|
||||
|
Цитата:
|
|
#13
|
||||
|
||||
|
Цитата:
![]() Также есть PostThreadMessage, хотя им я ни разу не пользовался. Но думаю, если есть - должен работать. Можно попробовать в дебаге инициировать запуск функции, вручную передав параметры и вручную же отловив выход. Но это все такие извраты, что лучше о них даже не думать. ![]() |
|
#14
|
||||
|
||||
|
Пришлось делать по пункту
Цитата:
|