Внедрение модуля в процесс

Тема в разделе "WASM.WIN32", создана пользователем Clerk, 9 май 2008.

  1. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Доброго времени суток. Нужно внедрить образ модуля(PE, DLL) из памяти в процесс.
    Обычно надо писать загрузчик. Я попытался сделать проще.
    В системе существуют секции из директории \KnownDlls носящие имена системных модулей(kernel32.dll, gdi32.dll и др.) из которых они созданы и имеют атрибут MEM_IMAGE. При созданиеи прцесса в нём спроецирован только ntdll, остальные модуля загрузчик из этого модуля загружает сам. При загрузке модуля загрузчик вначале ищет секцию с именем загружаемого модуля из директории \KnownDlls и если найдёт, то он проецирует эту секцию и работает только с ней без обращения к файлу. Иначе не найдя секцию загрузчик обращается к файлу на диске. Так и должно быть, иначе была бы возможность подменить модуль.
    Оказалось в загрузчике отсутствует проверка атрибутов секции!
    Чтобы загрузить модуль из памяти нужно открыть директорию \KnownDlls, создать секцию с атрибутом MEM_COMMIT и с именем модуля, спроецировать её в текущий процесс и скопировать туда внедряемый образ модуля. После чего в процессе, куда необходимо внедрить модуль следует вызвать LoadLibrary с именем этой секции и загрузчик сделает всю работу сам, настроит релоки, загрузит всё что в статическом импорте. Вот код который создаёт секцию:
    Код (Text):
    1. CreateKnownDllSection proc uses ebx SectionHandle:PHANDLE, SectionName:PSTR, SectionSize:ULONG, SourceAddress:PVOID, SourceSize:ULONG
    2. Local ObjAttr:OBJECT_ATTRIBUTES, LocalSectionHandle:HANDLE
    3. Local DirectoryNameUni:UNICODE_STRING, SectionNameUni:UNICODE_STRING
    4. Local LocalSectionSize:LARGE_INTEGER, ViewSize:ULONG
    5. Local BaseAddress:PVOID, SectionOffset:LARGE_INTEGER
    6.     _setseh_
    7.     lea eax,DirectoryNameUni
    8.     push offset DirectoryName
    9.     push eax
    10.     Call RtlCreateUnicodeStringFromAsciiz
    11.     test eax,eax
    12.     mov eax,STATUS_INTERNAL_ERROR
    13.     jz exit_
    14.     mov ecx,SectionSize
    15.     xor eax,eax
    16.     lea edx,DirectoryNameUni
    17.     mov ebx,SectionHandle
    18.     mov ObjAttr.uLength,SizeOf OBJECT_ATTRIBUTES
    19.     mov ObjAttr.hRootDirectory,eax
    20.     mov ObjAttr.pObjectName,edx
    21.     mov ObjAttr.uAttributes,eax
    22.     mov ObjAttr.pSecurityDescriptor,eax
    23.     mov ObjAttr.pSecurityQualityOfService,eax
    24.     mov dword ptr [LocalSectionSize],ecx
    25.     mov dword ptr [LocalSectionSize+4],eax
    26.     mov dword ptr [ebx],eax
    27.     cmp SourceSize,ecx
    28.     mov eax,STATUS_INVALID_PARAMETER_5
    29.     ja err_open_
    30.     invoke ZwOpenDirectoryObject, addr ObjAttr.hRootDirectory, DIRECTORY_CREATE_OBJECT, addr ObjAttr
    31.     test eax,eax
    32.     jnz err_open_
    33.     invoke RtlCreateUnicodeStringFromAsciiz, addr SectionNameUni, SectionName
    34.     test eax,eax
    35.     mov eax,STATUS_INVALID_PARAMETER_2
    36.     lea edx,SectionNameUni
    37.     jz err_name_
    38.     mov ObjAttr.pObjectName,edx
    39.     invoke ZwCreateSection, addr LocalSectionHandle, SECTION_ALL_ACCESS, addr ObjAttr, addr LocalSectionSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL
    40.     test eax,eax
    41.     jnz err_create_
    42.     cmp SourceAddress,eax
    43.     mov BaseAddress,eax
    44.     mov ViewSize,eax
    45.     jz return_
    46.     mov dword ptr [SectionOffset],eax
    47.     mov dword ptr [SectionOffset+4],eax
    48.     invoke ZwMapViewOfSection, LocalSectionHandle, NtCurrentProcess, addr BaseAddress, 0, 0, addr SectionOffset, addr ViewSize, ViewShare, NULL, PAGE_READWRITE
    49.     test eax,eax
    50.     jnz err_map_
    51.     invoke ZwWriteVirtualMemory, NtCurrentProcess, BaseAddress, SourceAddress, SourceSize, NULL
    52.     push eax
    53.     invoke ZwUnmapViewOfSection, NtCurrentProcess, BaseAddress
    54.     pop eax
    55.     test eax,eax
    56.     jnz err_map_
    57. return_:
    58.     mov edx,LocalSectionHandle
    59.     mov dword ptr [ebx],edx
    60.     jmp err_create_
    61. err_map_:
    62.     push eax
    63.     invoke ZwClose, LocalSectionHandle
    64.     pop eax
    65. err_create_:
    66.     push eax
    67.     invoke RtlFreeUnicodeString, addr SectionNameUni
    68.     pop eax
    69. err_name_:
    70.     push eax
    71.     invoke ZwClose, ObjAttr.hRootDirectory
    72.     pop eax
    73. err_open_:
    74.     push eax
    75.     invoke RtlFreeUnicodeString, addr DirectoryNameUni
    76.     pop eax
    77. exit_:
    78.     _endseh_
    79.     ret
    80. DirectoryName       CHAR "\KnownDlls",0
    81. CreateKnownDllSection endp
    Единственный минус - формат образа должен быть таким, как и у проекции секции созданной из этого модуля, но я думаю что это не проблема.
     
  2. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    Clerk
    Привет. Очень заинтересовала эта тема, поскольку я писал свой загрузчик и для меня это было немного проще, тк там нужно лишь знание РЕ формата, тогда как здесь, нужно знать тонкости работы виндового загрузчика.
    В связи с этим, у меня к тебе один вопрос и одна просьба.
    Что посоветуешь почитать по этой темке (желательно на русском)?
    В твоем коде, я конечно разберусь, но, не мог бы ты сдобрить код небольшими комментами.
    Спасибо.
     
  3. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Формат образа предельно прост, данные в образе аналогичны данным в файле, одна лишь разница в том, что разное выравнивание секций - если в файле секции выравнены на границу в 512 байт, то в проекции на границу страницы.
    Тоесть если реальный размер секции равен 100 байтам, секция в файле займёт 512 байт, а в образе 1000h байт.
    Aspire
    Что почитать я не знаю. Насчёт комментариев - тут всё очень просто, что именно комментировать ?
     
  4. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    Clerk
    Сорри, я просто на работе и у меня нет времени подробно рассмотреть код, но судя по описанию все, действительно, не сложно. Вечером посмотрю повнимательней.
     
  5. wvlg

    wvlg New Member

    Публикаций:
    0
    Регистрация:
    25 сен 2007
    Сообщения:
    44
    Извините не совсем понял в этом месте загрузить "из " или "в". Если все-таки из. То из какой памяти, из чьей? Из программы, которая и будет внедрять дллку в память интересующего процесса?
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Из памяти текущего процесса в чужой.