
مكتبة x64 صغيرة لتحميل ملفات dll في الذاكرة.
مكتبة x64 صغيرة لتحميل ملفات dll في الذاكرة.
يمكن دمج الأعلام
LIBRARYEX_NONE: تعيين الوحدة من القرص إلى الذاكرة وتنفيذ نقطة الدخول.
LIBRARYEX_BYPASS_LOAD_CALLBACK: تعيين الوحدة من القرص إلى ذاكرة خاصة (غير مدعومة) مما يتجاوز استدعاءات تحميل الصور (PsSetLoadImageNotifyRoutine)
LIBRARYEX_NO_ENTRY: عدم تنفيذ نقطة الدخول للوحدة.
LIBRARYEX_BUFFER: تعيين الوحدة من الذاكرة بدلاً من القرص.
LdrLibraryدالة سهلة الاستخدام لتحميل مكتبة في الذاكرة. المعلمة الأولى، بناءً على الأعلام المحددة، يمكن أن تكون إما اسم وحدة كنص عريض (wide string) لتحميله أو عنوان ذاكرة حيث يوجد ملف PE.
/*!
* @brief
* load library into memory
*
* @param Buffer
* buffer context to load library
* either a wide string or a buffer pointer
* the to PE file to map (LIBRARYEX_BUFFER)
*
* @param Library
* loaded library pointer
*
* @param Flags
* flags
*
* @return
* status of function
*/
NTSTATUS LdrLibrary(
_In_ PVOID Buffer,
_Out_ PVOID* Library,
_In_ ULONG Flags
);
يوضح هذا المثال كيفية تحميل وحدة من القرص (من مسار System32):
PVOID Module = { 0 };
ULONG Flags = { 0 };
//
// mapping flags to be used by the library
//
Flags = LIBRARYEX_NONE;
//
// map file into memory
//
if ( ! NT_SUCCESS( Status = LdrLibrary( L"advapi32.dll", &Module, Flags ) ) ) {
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
return;
}
printf( "[*] Module @ %p\n", Module );
يوضح هذا المثال كيفية تحميل وحدة من مخزن مؤقت في الذاكرة:
PVOID Module = { 0 };
ULONG Flags = { 0 };
//
// mapping flags to be used by the library
//
Flags = LIBRARYEX_NONE |
LIBRARYEX_BUFFER;
//
// read file on disk into memory
//
if ( ! ( Image = ReadFileBuffer( L"C:\\Windows\\System32\\advapi32.dll", NULL ) ) ) {
puts( "[-] ReadFileBuffer Failed" );
return;
}
//
// map file into memory
//
if ( ! NT_SUCCESS( Status = LdrLibrary( Image, &Module, Flags ) ) ) {
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
return;
}
printf( "[*] Module @ %p\n", Module );
من الممكن أيضاً تحميل الوحدات بناءً على api set الخاصة بها (دعم ويندوز 10+ فقط):
//
// map file into memory
//
if ( ! NT_SUCCESS( Status = LdrLibrary( L"api-ms-win-base-util-l1-1-0.dll", &Module, Flags ) ) ) {
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
return;
}
printf( "[*] Module @ %p\n", );
LdrLibraryExتسمح LdrLibraryEx بربط (hook) دوال معينة لتعديل سلوك كيفية تعيين المكتبة في الذاكرة.
//
// mapping flags to be used by the library
// and insert the loaded module into Peb
//
Flags = LIBRARYEX_BYPASS_LOAD_CALLBACK |
LIBRARYEX_NO_ENTRY;
//
// init LibraryEx context
//
if ( ! NT_SUCCESS( Status = LdrLibraryCtx( &Ctx, Flags ) ) ) {
printf( "[-] LdrLibraryCtx Failed: %d\n", Status );
goto END;
}
//
// hook function
//
Ctx.LdrLoadDll = C_PTR( HookLdrLoadDll );
//
// map file into memory
//
if ( ! NT_SUCCESS( Status = LdrLibraryEx( &Ctx, L"cryptsp.dll", &Module, Flags ) ) ) {
printf( "[-] LdrLibraryEx Failed: %p\n", Status );
return;
}
كُتبت قاعدة التعليمات البرمجية هذه وحُسّنت لبيئة x86_64-mingw، ومن المرجح جداً ألا تعمل أو تُترجم (compile) تحت Visual Studio.
يعود الفضل الكبير إلى الموارد والمشاريع التالية:
لا ينبغي استخدام هذا المشروع في بيئة أو عملية حقيقية. لقد كتبته أساساً لفهم ومعرفة المزيد عن كيفية عمل محمل ويندوز. كتبته كمكتبة لأنني أردت استخدامه لأنواع أخرى من المشاريع العامة والخاصة. لقد حققت هدفي. أراك لاحقاً.