Народ помогите разобраться с этой функцией Есть простая dll Код (Text): BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if(fdwReason==DLL_PROCESS_ATTACH) MessageBox(0,"DLL","DLL",1); return TRUE; } При обыкновенном вызове Код (Text): UNICODE_STRING string1; HANDLE mod; RtlInitUnicodeString(&string1,L"D:\\dell\\Erunda\\ffffffff\\dll\\Project1.dll"); LdrLoadDll(NULL,0,&string1,&mod); MessageBox появляется я пытаюсь написать свой аналог Код (Text): RtlInitUnicodeString( &DllName,L"\\??\\D:\\dell\\Erunda\\ffffffff\\dll\\Project1.dll"); InitializeObjectAttributes(&ob, &DllName, OBJ_CASE_INSENSITIVE, 0, 0); ZwOpenFile(&hFile, FILE_EXECUTE | SYNCHRONIZE, &ob, &iosb, FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); ob.pObjectName = 0; PVOID ViewBase; SIZE_T ViewSize; st=NtCreateSection(&hSection,SECTION_ALL_ACCESS,&ob,NULL,PAGE_EXECUTE,SEC_IMAGE,hFile); ZwMapViewOfSection(hSection,GetCurrentProcess(),(PVOID *)&ViewBase,0L,0L,NULL,&ViewSize,ViewShare,0L,PAGE_EXECUTE_READWRITE); Entry=LdrpAllocateDataTableEntry (ViewBase); Entry->EntryPoint = LdrpFetchAddressOfEntryPoint(Entry->DllBase); st = (NTSTATUS)LdrRelocateImage(ViewBase, "LDR", (ULONG)STATUS_SUCCESS, (ULONG)STATUS_CONFLICTING_ADDRESSES, (ULONG)STATUS_INVALID_IMAGE_FORMAT ) Теперь как я понимаю мы находим таблицу импорта в моей библиотеке (Bound-импортом и тому подобное отбросим для простаты) Код (Text): ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData( Entry->DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportSize ); теперь получается надо бежать по импорту и проецировать библиотеки Код (Text): while (ImportDescriptor->Characteristics!=0) { ImportName = (PSZ)((ULONG_PTR)Entry->DllBase + ImportDescriptor->Name); FirstThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)Entry->DllBase + ImportDescriptor->FirstThunk); ImportDescriptor++; } И одновременно проверить не проецирована ли уже данная библиотека на процесс в моей dll это kernel32 и user32 т.е. они уже есть и вот что дальше я как то растерялся смотрю виртуальное адресное пространство процесса библиотека спроецирована За ранее благодарен
ахахах... поцталом)))) по теме: в интернете есть куча примеров как грузить dll, как настраивать релоки, как настраивать таблицу импорта, как настраивать таблицу экспорта и тд... гугли)
х64 на рсдене выкладывал рабочий код по загрузке длл вручную. Еще на забугорном сайте видел тоже рабочий код. Их валом.
_mikityak_ Спасибо за ссылку но что такое dll я как то в курсе Но вот видишь и тебе настроение поднял но LdrRelocateImage как раз и отвечает за настройку релоков особенно слышать это от тебя когда ты сам спрашивал о релоках http://wasm.ru/forum/viewtopic.php?id=38491 за ссылку х64 спасибо посмотрел практически такая же реализация какую и я хочу реализовать единственное надо покумекать над настройкой таблицы импорта а вот при чем тут таблица экспорта (хотя не уверен может и надо) реализовать свою GetProcAddress легко а разобрать экспорт легко легче чем импорт За желание помочь спасибо. Хоти вот к примеру такая ерунда а вот если вместо имени Project1.dll подать какой-нибудь Project да еще и подправить так чтобы он выглядел как просто мусор интересно антивирус сможет эмулировать его работы (пищу выпимщий могу ошибаться )
ziral2088 Выкиньте тот код. Загрузка должна быть выполнена средствами системного загрузчика. yurza Это довольно обширная тема, смотрите сурцы.
блин... так в чем твоя проблема-то тогда? импорт вообще по-моему самое простое в загрузке dll... пробегаешь по таблице импорта, для каждой dll от которой зависит твоя dll, находишь их базовые адреса, если dll нет, то загружаешь... пробегаешь по всем функциям для каждой из dll, находишь их адреса, подставляешь... в интернете куча примеров, я же говорил... и еще была функция что-то типа LdrpWalkImportDescriptor))) ЗЫ исходники той функции мне нужны были, чтобы уметь настроить один редкий тип релоков, если ты не понял... ЗЗЫ таблицу экспорта нужно настраивать, если она у тебя есть... ЗЗЗЫ кстати а как вы все находите адреса функций из ntdll.dll, которые не находятся в таблице экспорта? (LdrRelocateImage например) ЗЗЗЗЫ а ты добавляешь свою dll в "базу данных загрузщика"?)
Честно и откровенно роюсь в инете + обрывки исподников а дальше сам пытаюсь восстановить логику Дальше посмотрел так и в правда что LoadLibrary действительно загружает экспорт (получается функция по проецированию динамических библиотек использует будущие функции ведь при нармальной загрузке сначало LoadLibrary получила адрес потом GetProcAddress а в загрузчике идет LdrGetprocessAdresss) только вот вопрос смотрю через IDA на свою dll том в Export есть типа функция start как я понял это и есть DllEntry от сюда вопрос IDA думает что это экспорт что ли
то есть по сути ты переписываешь загрузщик))) а я вот хотел отойти от этого, но к сожалению не знаю как адекватно найти адреса этих самых функций, а встраивать какой-либо дисасм не хотелось бы в принципе... чет я не понял... виндовый загрузщик настраивает таблицу экспорта, так как предполагается, что dll - в первую очередь библиотека с каким то функционалом для программиста, который будет ее использовать... если таблицы экспорта нет, то и настраивать нечего... точка входа (EntryPoint) не имеет отношения к экспорту, насколько я знаю... более того dll может не иметь точки входа, если ей не нужно производить какие-либо действия по инициализации перед использованием dll программой... вообще по прочтенному в этой теме я сделал вывод, что ты делаешь малварю... не в обиду, но мне кажется, что тебе следует сначала прочитать про формат PE-файлов и про работу загрузщика, прежде чем его переписывать... ну хотя бы, чтобы знать про таблицы импорта, экспорта, ресурсы и тд... на васме есть статьи об этом, поищи например статьи "об упаковщиках в последний раз" или как-то так...
допустим в линкере студии это делается флагом /NOENTRY... msdn призывает ставить этот флаг для dll содержащих только ресурсы, без кода... я не в курсе, что в итоге ставится в поле EntryPoint pe-формата, и как это обрабатывается загрузщиком, может там ставится смещение какой-нить заглушки или ноль... но можно погуглить об этом)))
Rel Весьма просто. Для большинства функций имена определены для отладочного вывода. Например стандартный сех-пролог имеет ссылку массив хэндлеров, выполняющих отладочный вывод. Это например LdrpGenericExceptionFilter(). Ищите в модуле строку, например "LdrpLoadDll", затем фиксап для неё, один из них будет находится в хэндлере. Ищем его начало, а затем фиксап для него - он будет принадлежать прологу LdrpLoadDll(). Так можно найти функции(в XP): Код (Text): LdrpLoadDll LdrpSnapIAT LdrpCallTlsInitializers LdrpGetProcedureAddress LdrpSendDllLoadedNotifications LdrpSendDllUnloadedNotifications LdrLockLoaderLock LdrUnlockLoaderLock LdrEnumerateLoadedModules LdrUnloadDll LdrpLoadDll LdrQueryApplicationCompatibilityGoo LdrpCheckForLoadedDll LdrpMapDll LdrReadMemory LdrpTouchThreadStack Используя поиск по переменным ShowSnaps можно найти вобще всё. Но тут уже нужно граф создавать.
хех... я обычно слабо понимаю ваше "весьма просто")))) спасибо, попробую... пока еще не представляю, как определить, что фиксап строки находится в хендлере и как определить начала хендлера, там должен лежать стандартный пролог видимо)))
> как определить, что фиксап строки находится в хендлере хендлеры построены одинаково. стандартного пролога чаще всего нет, кстати.
n0name Стандартный пролог есть в болшинстве "тяжёлых" процедур, кстати. Он формирует seh/sfc/cookie фрейм и сохраняет ргп. Код (Text): push размер фрейма. push линк на список хэндлеров сех. Call _SEH_prolog
> Стандартный пролог есть в болшинстве "тяжёлых" процедур, кстати ну да, но не в хедлерах Код (Text): .text:77EC661E mov eax, [ebp-14h] .text:77EC6621 mov ecx, [eax] .text:77EC6623 mov ecx, [ecx] .text:77EC6625 mov [ebp-30h], ecx .text:77EC6628 push offset aLdrpsnapiat ; "LdrpSnapIAT" .text:77EC662D push eax .text:77EC662E call _LdrpGenericExceptionFilter@8 ; LdrpGenericExceptionFilter(x,x) .text:77EC6633 retn > как определить начала хендлера ищем ближайший фиксап.
Семпл, ищет LdrpResolveDllName(глубоко в загрузчике находится) - создаёт граф для LdrLoadDll(), ищет в нём линк на имя, затем ищет начало функции. Код не оптимизирован по размеру буфера(следует использовать расширяемые буфера) и скорости исполнения(следует использовать усечение графа посредством задания уровня вложенности(NestingLevel)), но в данном случае это не важно. Фиксапы не используем. http://files.virustech.org/indy/Code/GCBE/NL/