Инжектирование кода
Модераторы: Duncon, Hawk, Romeo, Eugie
Ни как не могу заставить работать инжектируемый код (ну это тот, который я запихиваю в адресное пространство процесса). Можешь дать исходник такого кода и процедуры инжекта (или всей проги сразу), желательно на асме. (статью на http://www.xakep.ru не предлагать!).
Блин, вообще бред какой-то: записал я код в память процесса, запустил я его, и на этом хорошие новости заканчиваются.
пишу push 0, винда мне "Инструкция по адресу 0х00000000 обратилась к памяти по адресу 0х00000000. Память не может быть read". Написал push 5, она мне "Инструкция по адресу 0х00000005 обратилась к памяти по адресу 0х00000005. Память не может быть read". Написал pop eax - "Инструкция по адресу 0х00400003 обратилась к памяти по адресу 0х00400000. Память не может быть written". - Чё за чёрт?!
пишу push 0, винда мне "Инструкция по адресу 0х00000000 обратилась к памяти по адресу 0х00000000. Память не может быть read". Написал push 5, она мне "Инструкция по адресу 0х00000005 обратилась к памяти по адресу 0х00000005. Память не может быть read". Написал pop eax - "Инструкция по адресу 0х00400003 обратилась к памяти по адресу 0х00400000. Память не может быть written". - Чё за чёрт?!
И пусть удача повернется к тебе нужным местом 

Код: Выделить всё
.386
.model flat,stdcall
option casemap:none
find_PID PROTO
myInject PROTO
include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
.const
.data?
hSnapshot dd ? ; Хэндл снимка процессов
hProcess HANDLE ? ; Хэндл нужного мне процесса
lpMemory HANDLE ? ; Хэндл блока памяти
dwTid HANDLE ?
need_memory dd ? ; Размер блока памяти, который я хочу захапать
.data
pid HANDLE 0 ; PID нужного мне процесса
szProcessName db "test.exe",0 ; Имя процесса, который я ищу
p_entry PROCESSENTRY32 <> ; Структура для инфы о процессе
.code
start:
invoke find_PID
.if pid==0
;
.else
invoke myInject
.endif
invoke ExitProcess,0
find_PID proc
invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,0 ; Делаем снимок системы
inc eax
test eax,eax
jz exit ; Если ошибка - выходим
dec eax
mov hSnapshot,eax ; Сохраняем хэндл снимка
mov p_entry.dwSize,sizeof PROCESSENTRY32
invoke Process32First,hSnapshot,addr p_entry ; Получаем инфу о первом процессе
test eax,eax
jz exit ; Если ошибка - выходим
jmp cmp__ ; Отправляем PID на проверку
p_next__:
mov p_entry.dwSize,sizeof PROCESSENTRY32
invoke Process32Next,hSnapshot,addr p_entry ; Получаем инфу о следующем процессе
test eax,eax
jz exit ; Если ошибка - выходим
cmp__:
invoke lstrcmp,addr szProcessName,addr p_entry.szExeFile ; Если это наш процесс - заебись :)
test eax,eax
jz find_it__ ; Ага, наш)
jmp p_next__ ; Неа, нифига не наш(
find_it__:
mov eax,p_entry.th32ProcessID
mov pid,eax ; Сохраняем PID нужной нам проги
invoke CloseHandle,hSnapshot
exit:
ret ; Возврат из подпрограммы
find_PID endp
myInject proc
jmp backdoor_code_end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
backdoor_code:
push 9
ret
backdoor_code_end:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lea eax,backdoor_code_end
lea ecx,backdoor_code
sub eax,ecx
mov need_memory,eax
; Открываю процесс:
invoke OpenProcess,PROCESS_ALL_ACCESS or PROCESS_VM_WRITE or PROCESS_CREATE_THREAD or PROCESS_CREATE_PROCESS,FALSE,pid
test eax,eax
jz exit__ ; Если не открыл - на выход
mov hProcess,eax ; Сохраняю хэндл процесса
invoke VirtualAllocEx,hProcess,0,need_memory,MEM_COMMIT,PAGE_EXECUTE ; Выделяю 1000 байт
test eax,eax
jz exit__ ; Если не выделил - выхожу
mov lpMemory,eax ; Сохраняю хэндл памяти
; Пишу свой код в память процесса:
invoke WriteProcessMemory,hProcess,lpMemory,addr backdoor_code,need_memory,0
dec eax
test eax,eax
jnz exit__ ; Если записать не удалось - выхожу
inc eax
; Создаю удалённый поток, указывая на свой код:
invoke CreateRemoteThread,hProcess,0,0,lpMemory,lpMemory,0,0
exit__:
invoke CloseHandle,hProcess
ret
myInject endp
End start
И пусть удача повернется к тебе нужным местом 

Давно уже написана куча статей по этому вопросу, вот например - http://www.codeproject.com/threads/winspy.asp
А можно перевести код инжектирования с С++ на дельфи
Перепиши)))
И пусть удача повернется к тебе нужным местом 

Извиняюсь, что задаю вопрос в чужой теме, но у меня близкая проблема. Суть в следующем. Я осуществляю перехват WinAPI следующим образом (как и было описано в свое время в "Хакере"):
инжектирую свои функции в адресное пространство процесса и меняю таблицу импорта. Однако столкнулся с такой неприятностью: мне по моей задумке нужно сперва создавать замороженный процесс (CreateProcess с флагом SUSPENDED), затем инжектироваться и уже потом "размораживать" созданный процесс, то есть в нем с самого начала его работы должны быть перехвачены функции (это важно). Однако если я создаю его SUSPENDED, я не могу отследить окончания его инициализации (WaitForInputIdle помогает только для процессов, которые создаются активными), и из-за этого программа в половине случаев не работает: есть подозрение, что инжект происходит до окончания инициализации процесса, и из-за этого всё нарушается
Если у кого-то есть соображения, большая просьба ими со мной поделиться
инжектирую свои функции в адресное пространство процесса и меняю таблицу импорта. Однако столкнулся с такой неприятностью: мне по моей задумке нужно сперва создавать замороженный процесс (CreateProcess с флагом SUSPENDED), затем инжектироваться и уже потом "размораживать" созданный процесс, то есть в нем с самого начала его работы должны быть перехвачены функции (это важно). Однако если я создаю его SUSPENDED, я не могу отследить окончания его инициализации (WaitForInputIdle помогает только для процессов, которые создаются активными), и из-за этого программа в половине случаев не работает: есть подозрение, что инжект происходит до окончания инициализации процесса, и из-за этого всё нарушается

Если у кого-то есть соображения, большая просьба ими со мной поделиться
Как вы внедряетесь в процесс? С помощью глоб.хуков, CreateRemoteThread(), или как-то еще?
Сперва я прописываю свои функции в адресное пространство созданного процесса, затем запускаю CreateRemoteThread(), и в удаленном потоке выполняю функцию, которая подменяет в таблице импорта адреса WinAPI на адреса моих функций, ранее туда прописанных с помощью WriteProcessMemory().
Понятно. Чтобы гарантировать завершение внедрения до запуска процесса, для синхронизации используйте WaitForSingleObject(hRemoteThread, INFINITE) вместо WaitForInputIdle(hProcess). И только потом ResumeThread(hMainThread).
Зам.: WaitForInputIdle() вообще работает только с GUI-процессами, т.к. ждет пока очередь сообщений не станет пуста. Если у процесса нет message queue (например, console application), эта функция бесполезна.
Зам.: WaitForInputIdle() вообще работает только с GUI-процессами, т.к. ждет пока очередь сообщений не станет пуста. Если у процесса нет message queue (например, console application), эта функция бесполезна.