Инжектирование кода

Общие вопросы, не зависящие от языка реализации.

Модераторы: Duncon, Eugie, Romeo, Hawk

(GiG)*fh
Сообщения: 48
Зарегистрирован: 05 ноя 2004, 14:08
Откуда: Russia
Контактная информация:

19 апр 2005, 23:45

Ни как не могу заставить работать инжектируемый код (ну это тот, который я запихиваю в адресное пространство процесса). Можешь дать исходник такого кода и процедуры инжекта (или всей проги сразу), желательно на асме. (статью на http://www.xakep.ru не предлагать!).
(GiG)*fh
Сообщения: 48
Зарегистрирован: 05 ноя 2004, 14:08
Откуда: Russia
Контактная информация:

21 апр 2005, 17:13

Блин, вообще бред какой-то: записал я код в память процесса, запустил я его, и на этом хорошие новости заканчиваются.
пишу push 0, винда мне "Инструкция по адресу 0х00000000 обратилась к памяти по адресу 0х00000000. Память не может быть read". Написал push 5, она мне "Инструкция по адресу 0х00000005 обратилась к памяти по адресу 0х00000005. Память не может быть read". Написал pop eax - "Инструкция по адресу 0х00400003 обратилась к памяти по адресу 0х00400000. Память не может быть written". - Чё за чёрт?!
И пусть удача повернется к тебе нужным местом :)
(GiG)*fh
Сообщения: 48
Зарегистрирован: 05 ноя 2004, 14:08
Откуда: Russia
Контактная информация:

22 апр 2005, 21:49

Код: Выделить всё

.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
И пусть удача повернется к тебе нужным местом :)
Hawk
Сообщения: 215
Зарегистрирован: 17 фев 2004, 14:52
Откуда: СПб
Контактная информация:

03 май 2005, 11:45

Давно уже написана куча статей по этому вопросу, вот например - http://www.codeproject.com/threads/winspy.asp
ildar
Сообщения: 1
Зарегистрирован: 07 июл 2005, 13:22

07 июл 2005, 13:41

А можно перевести код инжектирования с С++ на дельфи
(GiG)*fh
Сообщения: 48
Зарегистрирован: 05 ноя 2004, 14:08
Откуда: Russia
Контактная информация:

19 сен 2005, 22:19

Перепиши)))
И пусть удача повернется к тебе нужным местом :)
TamerLAN
Сообщения: 7
Зарегистрирован: 31 янв 2006, 13:59
Откуда: из Орды

31 янв 2006, 14:27

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

01 фев 2006, 14:11

Как вы внедряетесь в процесс? С помощью глоб.хуков, CreateRemoteThread(), или как-то еще?
TamerLAN
Сообщения: 7
Зарегистрирован: 31 янв 2006, 13:59
Откуда: из Орды

01 фев 2006, 21:19

Сперва я прописываю свои функции в адресное пространство созданного процесса, затем запускаю CreateRemoteThread(), и в удаленном потоке выполняю функцию, которая подменяет в таблице импорта адреса WinAPI на адреса моих функций, ранее туда прописанных с помощью WriteProcessMemory().
Eugie
Сообщения: 707
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

02 фев 2006, 12:41

Понятно. Чтобы гарантировать завершение внедрения до запуска процесса, для синхронизации используйте WaitForSingleObject(hRemoteThread, INFINITE) вместо WaitForInputIdle(hProcess). И только потом ResumeThread(hMainThread).

Зам.: WaitForInputIdle() вообще работает только с GUI-процессами, т.к. ждет пока очередь сообщений не станет пуста. Если у процесса нет message queue (например, console application), эта функция бесполезна.
Ответить