Прежде всего, я не хочу вводить DLL. Я хочу внедрить код с помощью WriteProcessMemory () (если это даже возможно). Я уже использовал ReadProcessMemory (), поэтому я думаю, что написание не имеет большого значения.
Ну, скажем, есть функция в TargetProgram.exe + D78C612
и скажем, это можно назвать так:
push eax
push [esp+08]
push edx
push 00
push TargetProgram.exe+AF76235
push 04
call TargetProgram.exe+D78C612
Как именно я могу сделать это с WriteProcessMemory ()?
Я имею в виду, где я могу найти раздел, в котором я могу вставить свой код, не перезаписывая важные вещи. И самое главное, как бы я назвал функцию?
Просто вставьте мой код в активную подпрограмму, отскок назад и затем удалите его? Но как мне найти рутину?
Так много вопросов, и я понятия не имею, как начать … Я надеюсь, что вы можете мне помочь. 🙂
И если у вас есть время, я бы очень хотел увидеть пример кода функции-вызова-инъекции.
Ты можешь использовать VirtualAllocEx
выделить память в удаленном процессе, а затем скопировать вашу процедуру в эту память.
Вот шаги, чтобы сделать инъекцию:
SuspendThread(hThread); // Suspend the remote thread
remote_address = VirtualAllocEx(hProcess, ...) // allocate memory for your code
WriteProcessMemory(hProcess, remote_address, local_address, length, NULL) // copy your code to remote process
WriteProcessMemory(hProcess, remote_fixup, ...) // insert a jump to your code
ResumeThread(hThread); // Resume the remote thread
Как сказано в ответе Макса, VirtualAllocEx это один из способов выделить страницы памяти в удаленном процессе, при условии, что у вас есть PROCESS_VM_OPERATION право доступа к рассматриваемому процессу. Вы также хотите убедиться, что новые страницы помечены PAGE_EXECUTE_READWRITE для их уровня защиты во время записи, а затем изменить его позже PAGE_EXECUTE_READ
с помощью VirtualProtectEx.
Обратите внимание, что ветвление и некоторые инструкции вызова в x86 являются IP-относительными. Это означает, что их кодировки зависят от того, где они находятся в памяти, так как они используют относительное смещение со знаком от конца инструкции. Поэтому, если вы планируете вызывать существующую функцию из своего нового кода, убедитесь, что вы учитываете это при использовании относительной инструкции вызова или вместо этого используете косвенную / немедленную форму.
Однако, не зная точно, что вы пытаетесь сделать здесь, трудно порекомендовать методику выполнения вашего нового целевого кода. С новым кодом вы можете просто внедрить удаленный поток, используя CreateRemoteThread выполнить его без необходимости прерывать существующие потоки. Это было бы самым простым решением для выполнения нового кода, но требует, чтобы код, который вы вызываете, был потокобезопасным. Выбрать уже запущенный поток, приостановить его, изменить EIP или ввести обходной путь и возобновить его без побочных эффектов (должным образом сохраняя контекст во введенном вызове) очень сложно, если не сказать больше.
Личное примечание: как автор инструмента покрытия кода в Visual Studio 2012, который использует кучу трюков для перезаписи стороннего кода x86 / x86-64 на лету для сбора данных покрытия, этот материал очень интересен взломать и подумать 🙂