كيف يمكنني معرفة ما إذا كان مقبض وحدة Windows لا يزال صالحا؟

StackOverflow https://stackoverflow.com/questions/1111820

  •  12-09-2019
  •  | 
  •  

سؤال

يمكن تفريغ الوحدة، فكيف يمكنني أن أخبرك بالتأكيد إذا كانت لا تزال في الذاكرة؟ لدي مقبض لذلك، تم الحصول عليها من GetModulehandle. عندما حاولت استدعاء gethandleinformation عليه، أرى خطأ 0xc0000008 - "تم تحديد مقبض غير صالح." حدث هذا قبل أن يكون قد تم تفريغه.

هل كانت مفيدة؟

المحلول

يمثل مصطلح "مقبض" مثالي بعض الشيء هنا - الكثير من فئات الكائنات المختلفة في واجهة برمجة تطبيقات Win32 تسمى "المقابض".

يتم استخدام GethandleInformation في مقابض كائنات Kernel - الملفات ومفاتيح التسجيل والمواد Mutexes وما إلى ذلك.

يتم استخدام HModule الذي تم إرجاعه بواسطة GetModulehandle من قبل المحمل وليس كائن Kernel الفعلي، وبالتالي فشل GentRandleInformation. لا أحد من الأعلام التي تحصل عليها في GethandleInformation منطقية على HModule على الرغم من ذلك.

إذا كنت ترغب في التحقق مما لا يزال يتم تحميل HMODULE في الذاكرة، فيمكنك فقط استدعاء GetModulehandle - يجب أن يكون API هذا سريعا بما يكفي للاتصال عدة مرات. ومع ذلك، يمكن أن تكون نتيجة GetModulehandle غير صالحة لحظة تعرضها - قد يسمى مؤشر ترابط آخر Frelibrary. من الأفضل التأكد من أن DLL لا يبقى محملا. يمكنك القيام بذلك عن طريق الاتصال LoadLibrary بنفسك، أو عن طريق استدعاء GetModulehandleex الذي سيزيد العدد المرجعي ل DLL.

نصائح أخرى

حلولان:

1

اتصل GetModuleFilename () على HModule. إذا تم تحميل الوحدة النمطية، فستحصل على اسم ملف صالح. إذا لم يتم تحميله، فلن تحصل على اسم ملف صالح. تأكد من ضبط البايت الأول من صفيف اسم الملف المرتجع إلى " 0" قبل استدعاء GetModuleFilename () أو للتحقق من قيمة الإرجاع. إذا قمت بتعيين البايت الأول قبل الاتصال، فيمكنك تجاهل قيمة الإرجاع بشكل فعال وعلاج سلسلة طول الصفر كإشارة "غير محملة".

TCHAR szModName[MAX_PATH + 1];

szModName[0] = _T('\0');
GetModuleFileName(hMod, szModName, MAX_PATH);

// zero length string if not loaded, valid DLL name if still loaded

2

استدعاء الظاهري () تمرير HModule كعنوان للاستعلام. كجرب يقوم بذلك على مكتبة محملة وعلى مكتبة تعرف أنه يتم تحريرها. ستجد أن لديهم نتائج مختلفة جدا عن memory_basic_information المرتجعة. أترك الأمر لك للعمل خوارزمية مناسبة لتحديد الفرق بين الاثنين.

مذكرة قانونية

بالطبع، تحذير أن مؤشر ترابط آخر قد تفريغ المكتبة أثناء تشغيل Eiher من هذه الاختبارات تنطبق. في تجربتي، من غير المرجح أن يحدث هذا، ولكن هذا يعتمد كثيرا على ما تفعله، لماذا تفعل ذلك، وعندما تقوم بذلك مسار تنفيذ البرنامج. استخدام بعناية.

انها بسيطة جدا API.

PIMAGE_NT_HEADERS (NTAPI* _RtlImageNtHeader)

نموذج البرنامج:

(PVOID)typedef PIMAGE_NT_HEADERS (NTAPI *RTLIMAGENTHEADER)(PVOID);
RTLIMAGENTHEADER RtlImageNtHeader;
HMODULE hDll = GetModuleHandle("ntdll.dll");
HMODULE hDllTmp = LoadLibrary("ws2_32.dll");
RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hDll,"RtlImageNtHeader");

struct _IMAGE_NT_HEADERS *r,*r2;
r= RtlImageNtHeader(hDllTmp); 
FreeLibrary(hDllTmp);
r2= RtlImageNtHeader(hDllTmp);

//r = NULL
//r2 = return ws2_32 PE Header address
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top