Выделяй кусок памяти, ставь туда прыжок и сохраняй значение.
То есть, вместо mov edi,[edx+ebx*4] подставь jmp на выделенную память. А в памяти:
Код:
mov [адрес куда сохранить значение ebx], ebx
mov edi,[edx+ebx*4]
jmp назад
В выделенном куске памяти ты сохраняешь себе значение регистра ebx (в свою переменную или куда там тебе надо), чуть ниже выполняешь инструкцию, которую ты подменил инструкцией прыжка, а потом прыгаешь назад на следующую инструкцию
Добавлено через 21 минуту
Ты внедряешь в адресное пространство DLL или работаешь через Read\WriteProcessMemory?
Последний раз редактировалось Paladin; 25.02.2015 в 21:19.
Причина: Добавлено сообщение
Новичок, даже пытался Olly рассмотреть какая команда заносит значение в стек. Но... еще туп, но и забрасывать я это не собираюсь ибо мне это очень интересно.
Добавлено через 15 минут
кстати ты имеешь ввиду сделать inject? насильно вставить в edi любое значение???
Последний раз редактировалось Foreworld; 25.02.2015 в 23:40.
Причина: Добавлено сообщение
кстати ты имеешь ввиду сделать inject? насильно вставить в edi любое значение???
Я имею ввиду модифицировать оригинальный код, воткнуть между asm инструкциями сохранение значения регистра.
1) Выделяешь кусочек памяти через VirtualAllocEx в чужом процессе;
2) Пишешь в выделенную память инструкцию:
Код:
mov [адрес куда сохранить значение], ebx
3) Чуть ниже вписываешь инструкции:
Код:
mov edi,[edx+ebx*4]
4) Под конец ставишь прыжок на sub esp,1C
В итоге в выделенной тобой памяти получается следующее:
Код:
mov [адрес куда сохранить значение], ebx
mov edi,[edx+ebx*4]
jmp $004A02EB // sub esp,1C
5) Инструкцию mov edi,[edx+ebx*4] (по адресу 004A02E8) заменяешь на прыжок (jmp) на кусочек выделенной тобой ранее памяти:
Код:
jmp = $E9
Адрес прыжка = [Адрес выделенной памяти] - [Адрес оригинальной инструкции] - 5;
Всё, код будет выполняться, а у тебя по адресу, который ты указал для сохранения регистра - будет его значение, которое можно считывать через ReadProcessMemory. Но проще конечно с памятью процесса работать из заинжекченной DLL
Кстати, вредная привычка - не проверять возврат у функций
Последний раз редактировалось Paladin; 26.02.2015 в 00:27.
procedure InjectFunc(ProcessID: Cardinal; Func, aParams: Pointer;
aParamsSize: DWord);
var
hThread: THandle;
lpNumberOfBytes: DWord;
ThreadAddr, ParamAddr: Pointer;
begin
if ProcessID<>0 then
begin
// ---- Выделяем место в памяти процесса, и записываем туда нашу функцию
ThreadAddr := VirtualAllocEx(ProcessID, nil, 256, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(ProcessID, ThreadAddr, Func, 256, lpNumberOfBytes);
// ---- Также запишем параметры к ней
ParamAddr := VirtualAllocEx(ProcessID, nil, aParamsSize, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(ProcessID, ParamAddr, aParams, aParamsSize, lpNumberOfBytes);
// ---- Создаем поток, в котором все это будет выполняться.
hThread := CreateRemoteThread(ProcessID, nil, 0, ThreadAddr, ParamAddr, 0, lpNumberOfBytes);
// ---- Ожидаем завершения функции
WaitForSingleObject(hThread, INFINITE);
// ---- подчищаем за собой
CloseHandle(hThread);
VirtualFreeEx(ProcessID, ParamAddr, 0, MEM_RELEASE);
VirtualFreeEx(ProcessID, ThreadAddr, 0, MEM_RELEASE);
end
end;
А что за адресс?
"mov [адрес куда сохранить значение], ebx"
Адрес твоей переменной или кусочка памяти (который нужно выделить дополнительно) куда ты будешь копировать значение регистра.
Цитата:
Сообщение от Foreworld
Чтобы внести свой код в чужой процессор
Такого рода вещи должны использоваться с осторожностью и полным пониманием того, что они делают.
У тебя дельфийская функция может дёргать какие-то другие методы\функции\процедуры, юзать переменные - которых в другом адресном пространстве не окажется и получишь в лучшем случае access violation.
Ну а вообще ответ на заданный вопрос я дал во 2 и 4 постах
Твой метод это модефецировать клиент и сохранить его. Я правильно понял тебя?
"Адрес твоей переменной или кусочка памяти (который нужно выделить дополнительно) куда ты будешь копировать значение регистра." - а где я его возьму, я не совсем понял.
Твой метод это модефецировать клиент и сохранить его. Я правильно понял тебя?
Нет, я предполагал, что ты работаешь с уже запущенным процессом через стороннюю программу. Ну а если нужно, чтобы "само" всё делалось - вариант закинуть свою дллку в импорт к экзешнику
Пойду почитаю что за зверь VirtualAllocEx. Сложно найти пример на pascal'e Он может создать адрес???
Да зачем там пример на паскале, если по msdn всё понятно?
[Ссылки могут видеть только зарегистрированные пользователи. ]
Пример:
Код:
var
Memory: Pointer;
begin
Memory := VirtualAllocEx( дескриптор процесса, Nil, требуемый размер в байтах, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
end;
Функция вернёт указатель (Pointer) на выделенный кусок памяти (или Nil в случае неудачи). В случае неудачи вызываешь GetLastError и смотришь в чём проблема.
Но лучше всего начинать с изучения основ прежде, чем лезть в такие дебри
Да зачем там пример на паскале, если по msdn всё понятно?
[Ссылки могут видеть только зарегистрированные пользователи. ]
Пример:
Код:
var
Memory: Pointer;
begin
Memory := VirtualAllocEx( дескриптор процесса, Nil, требуемый размер в байтах, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
end;
Функция вернёт указатель (Pointer) на выделенный кусок памяти (или Nil в случае неудачи). В случае неудачи вызываешь GetLastError и смотришь в чём проблема.
Но лучше всего начинать с изучения основ прежде, чем лезть в такие дебри
Если желаемый адрес равен nil, то система сама определит место, где будет выделен регион памяти. - Это и будет адрес?
Добавлено через 5 минут
я делаю бота не только для себя но и для других А что делать через dll лучше?
Добавлено через 7 минут
Я знания набиваю через опыт. Вот такой вот я
Последний раз редактировалось Foreworld; 26.02.2015 в 01:38.
Причина: Добавлено сообщение
Вообще-то лучше уж использовать не безусловные переходы, а вызов функции.
Кроме того, Paladin, мог бы рассказать ему как сделать собственно сплайсинг кода.
В третьих - свою переменную так или иначе он подгрузить в процесс (с условием получения из нее данных) не сможет ровно до тех пор, пока весь его код не будет загружен в виде библиотеки (а этого не требуется).
Ну и напоследок инструкция типа mov edi,[edx+ebx*4] используется при цикличном переборе указателей на структуры данных, а значит конкретное значение может быть и не столь нужным.
Первым делом следовало бы задать вопрос что именно хочет написать автор.
Итак. Foreworld что именно ты пишешь?
________________
Ни одно доброе дело не остается безнаказанным.
Пишу бота для себя, если смогу осилить, выложу его и поделюсь своим опыт с другими. Я благодарен людям которые открыли этот сайт и особо благодарен тем кто поделился своим опытом написав статьи. Если бы не эти статьи я не стал бы изучать pascal и не давно стал читать книги по asam и вообще тупа забил бы на это. Но, я увлекся и даже забив на целый год, я вновь вернулся чтобы решить эту проблему.