Доброго времени суток. Нужно внедрить образ модуля(PE, DLL) из памяти в процесс. Обычно надо писать загрузчик. Я попытался сделать проще. В системе существуют секции из директории \KnownDlls носящие имена системных модулей(kernel32.dll, gdi32.dll и др.) из которых они созданы и имеют атрибут MEM_IMAGE. При созданиеи прцесса в нём спроецирован только ntdll, остальные модуля загрузчик из этого модуля загружает сам. При загрузке модуля загрузчик вначале ищет секцию с именем загружаемого модуля из директории \KnownDlls и если найдёт, то он проецирует эту секцию и работает только с ней без обращения к файлу. Иначе не найдя секцию загрузчик обращается к файлу на диске. Так и должно быть, иначе была бы возможность подменить модуль. Оказалось в загрузчике отсутствует проверка атрибутов секции! Чтобы загрузить модуль из памяти нужно открыть директорию \KnownDlls, создать секцию с атрибутом MEM_COMMIT и с именем модуля, спроецировать её в текущий процесс и скопировать туда внедряемый образ модуля. После чего в процессе, куда необходимо внедрить модуль следует вызвать LoadLibrary с именем этой секции и загрузчик сделает всю работу сам, настроит релоки, загрузит всё что в статическом импорте. Вот код который создаёт секцию: Код (Text): CreateKnownDllSection proc uses ebx SectionHandle:PHANDLE, SectionName:PSTR, SectionSize:ULONG, SourceAddress:PVOID, SourceSize:ULONG Local ObjAttr:OBJECT_ATTRIBUTES, LocalSectionHandle:HANDLE Local DirectoryNameUni:UNICODE_STRING, SectionNameUni:UNICODE_STRING Local LocalSectionSize:LARGE_INTEGER, ViewSize:ULONG Local BaseAddress:PVOID, SectionOffset:LARGE_INTEGER _setseh_ lea eax,DirectoryNameUni push offset DirectoryName push eax Call RtlCreateUnicodeStringFromAsciiz test eax,eax mov eax,STATUS_INTERNAL_ERROR jz exit_ mov ecx,SectionSize xor eax,eax lea edx,DirectoryNameUni mov ebx,SectionHandle mov ObjAttr.uLength,SizeOf OBJECT_ATTRIBUTES mov ObjAttr.hRootDirectory,eax mov ObjAttr.pObjectName,edx mov ObjAttr.uAttributes,eax mov ObjAttr.pSecurityDescriptor,eax mov ObjAttr.pSecurityQualityOfService,eax mov dword ptr [LocalSectionSize],ecx mov dword ptr [LocalSectionSize+4],eax mov dword ptr [ebx],eax cmp SourceSize,ecx mov eax,STATUS_INVALID_PARAMETER_5 ja err_open_ invoke ZwOpenDirectoryObject, addr ObjAttr.hRootDirectory, DIRECTORY_CREATE_OBJECT, addr ObjAttr test eax,eax jnz err_open_ invoke RtlCreateUnicodeStringFromAsciiz, addr SectionNameUni, SectionName test eax,eax mov eax,STATUS_INVALID_PARAMETER_2 lea edx,SectionNameUni jz err_name_ mov ObjAttr.pObjectName,edx invoke ZwCreateSection, addr LocalSectionHandle, SECTION_ALL_ACCESS, addr ObjAttr, addr LocalSectionSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL test eax,eax jnz err_create_ cmp SourceAddress,eax mov BaseAddress,eax mov ViewSize,eax jz return_ mov dword ptr [SectionOffset],eax mov dword ptr [SectionOffset+4],eax invoke ZwMapViewOfSection, LocalSectionHandle, NtCurrentProcess, addr BaseAddress, 0, 0, addr SectionOffset, addr ViewSize, ViewShare, NULL, PAGE_READWRITE test eax,eax jnz err_map_ invoke ZwWriteVirtualMemory, NtCurrentProcess, BaseAddress, SourceAddress, SourceSize, NULL push eax invoke ZwUnmapViewOfSection, NtCurrentProcess, BaseAddress pop eax test eax,eax jnz err_map_ return_: mov edx,LocalSectionHandle mov dword ptr [ebx],edx jmp err_create_ err_map_: push eax invoke ZwClose, LocalSectionHandle pop eax err_create_: push eax invoke RtlFreeUnicodeString, addr SectionNameUni pop eax err_name_: push eax invoke ZwClose, ObjAttr.hRootDirectory pop eax err_open_: push eax invoke RtlFreeUnicodeString, addr DirectoryNameUni pop eax exit_: _endseh_ ret DirectoryName CHAR "\KnownDlls",0 CreateKnownDllSection endp Единственный минус - формат образа должен быть таким, как и у проекции секции созданной из этого модуля, но я думаю что это не проблема.
Clerk Привет. Очень заинтересовала эта тема, поскольку я писал свой загрузчик и для меня это было немного проще, тк там нужно лишь знание РЕ формата, тогда как здесь, нужно знать тонкости работы виндового загрузчика. В связи с этим, у меня к тебе один вопрос и одна просьба. Что посоветуешь почитать по этой темке (желательно на русском)? В твоем коде, я конечно разберусь, но, не мог бы ты сдобрить код небольшими комментами. Спасибо.
Формат образа предельно прост, данные в образе аналогичны данным в файле, одна лишь разница в том, что разное выравнивание секций - если в файле секции выравнены на границу в 512 байт, то в проекции на границу страницы. Тоесть если реальный размер секции равен 100 байтам, секция в файле займёт 512 байт, а в образе 1000h байт. Aspire Что почитать я не знаю. Насчёт комментариев - тут всё очень просто, что именно комментировать ?
Clerk Сорри, я просто на работе и у меня нет времени подробно рассмотреть код, но судя по описанию все, действительно, не сложно. Вечером посмотрю повнимательней.
Извините не совсем понял в этом месте загрузить "из " или "в". Если все-таки из. То из какой памяти, из чьей? Из программы, которая и будет внедрять дллку в память интересующего процесса?