السلام عليكم
كما يتضح من العنوان سيكون الموضوع متعلقا بالدوال المسماه Native API . ربما لا يخفى على الجميع ما هي الــ Native API لكن لا بأس من ذكر فكرة مختصره عن ماهية الــ Native API .
هي مجموعة من الدوال - الروتينات - او لنقل خدمات (services ) يقدمها النظام لكلا نمطي النظام User & Kernel Mode . هذه الدوال مساويه او مكافئه لـ" استدعاءات النظام Unix او خدمات النظام VMS ".
هذه الدوال هامة جدا و باستخدامها احيانا يمكن لنا الاستغناء عن كم كبير من الكود للحصول على معلومات معينه ...
اغلب هذه الدوال غير مصرح بها - undocumented function - و من النادر الحصول على معلومات عنها وعن كيفية التعامل معها ( DDK يحتوي شرح لـ 10% تقريبا من هذه الدوال ) , لذا فاني اطرح فكرة عمل مرجع لهذه الدوال وكيفية استعمالها في هذا المنتدى , فمن له خبرة و اهتمام بهكذا موضوع اتمنى المشاركة .
من المراجع المتوفرة عن هذه الدوال Windows NT/2000 Native API Reference By Gary Nebbett
لنبدأ :
1) ZwQuerySystemInformation :
كما يتضح من الاسم هذه الدالة تعطي معلومات تتعلق بالنظام .
* تعريف الدالة :
- التعريف كما جاء في المرجع السابق :
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation ( IN UINT SystemInformationClass, // information type OUT PVOID SystemInformation, // pointer to buffer IN ULONG SystemInformationLength, // buffer size in bytes OUT PULONG ReturnLength OPTIONAL // number of bytes written to the buffer );
- التعريف المقابل في Delphi :
Type TPDword=^DWORD; function NtQuerySystemInformation: ( SystemInformationClass : DWORD; SystemInformation : Pointer; SystemInformationLength : DWORD; ReturnLength : TPDword ): DWORD; stdcall;
وليكون تعريف الدلفي قريبا الى تعريف المرجع يمكن استخدام ULONG بدلا عن DWORD فهما سيان , ولا ضير في استخدام PULONG بدلا عن TPWORD
Type PULONG = ^ULONG;
* متغيرات الدالة :
- SystemInformationClass :
نوع المعلومات المراد الحصول عليها . وهي احدى قيم SYSTEM_INFORMATION_CLASS وهناك 54 نوعا (0-53) . سيتم ذكرها لاحقا .
- SystemInformation :
مؤشر الى مساحة من الذاكرة (buffer) يخصص لمستدعي الدالة او الى متغير يستقبل معلومات النظام المطلوبه .
- SystemInformationLength :
حجم الـ SystemInformation هنا تستعمل الـ byte كوحدة .على مستخدم الدالة ( المستدعي ) عمل الاعدادات اللازمه لـ SystemInformation .
- ReturnLength :
بالامكان جعله يشير الى متغير , هذا المتغير يستقبل عدد الـ bytes الحقيقي لـ SystemInformation .
اذا كان SystemInformationLength صغير جدا فلن يحتوي هذا المتغير على معلومة يمكن الاستفاده منها ,عادة ما يعد هذا المتغير بقيمه مساويه لصفر .
اذا كنا لا نريد مثل هذه المعلومة ( حجم الـ SystemInformation ), نجعل المتغير على شكل NULL Pointer .
- القيمة التي ترجعها الدالة :
ترجع الدالة STATUS_SUCCESS او حالة خطأ مثل : STATUS_INVALID_INFO_CLASS ,STATUS_NOT_IMPLEMENTED او STATUS_INFO_LENGTH_MISMATCH .
* SYSTEM_INFOMATION_CLASS :
كما ذكرت مسبقا هناك 54 Class سأقوم بسردهم هنا و سيتم لاحقا عمل شرح لكل واحد منهم .
استخدم الـ enum لتعريف هذه الانواع في لغة c , حيث تعطى قيم طبيعية لكل نوع ابتداء من 0 حتى 53 , بالنسبة لدلفي فسوف استخدم const لتعريفها .
const //------------------------------------------------- Query Set SystemBasicInformation = 0 ; // Y N SystemProcessorInformation = 1 ; // Y N SystemPerformanceInformation = 2 ; // Y N SystemTimeInformation = 3 ; // Y N SystemNotImplemented1 = 4 ; // Y N SystemProcessesAndThreadsInformation = 5 ; // Y N SystemCallCounts = 6 ; // Y N SystemConfigurationInformation = 7 ; // Y N SystemProcessorTimes = 8 ; // Y N SystemGlobalFlag = 9 ; // Y Y SystemNotImplemented2 = 10 ; // Y N SystemModuleInformation = 11 ; // Y N SystemLockInformation = 12 ; // Y N SystemNotImplemented3 = 13 ; // Y N SystemNotImplemented4 = 14 ; // Y N SystemNotImplemented5 = 15 ; // Y N SystemHandleInformation = 16 ; // Y N SystemObjectInformation = 17 ; // Y N SystemPageFileInformation = 18 ; // Y N SystemInstructionEmulationCounts = 19 ; // Y N SystemInvalidInfoClass1 = 20 ; SystemCacheInformation = 21 ; // Y Y SystemPoolTagInforamtion = 22 ; // Y N SystemProcessorStatistics = 23 ; // Y N SystemDpcInformation = 24 ; // Y Y SystemNotImplemented6 = 25 ; // Y N SystemLoadImage = 26 ; // Y N SystemUnloadImage = 27 ; // Y N SystemTimeAdjustment = 28 ; // Y Y SystemNotImplemented7 = 29 ; // Y N SystemNotImplemented8 = 30 ; // Y N SystemNotImplemented9 = 31 ; // Y N SystemCrashDumpInformation = 32 ; // Y N SystemExceptionInformation = 33 ; // Y N SystemCrashDumpStateInformation = 34 ; // Y Y/N SystemKernelDebuggerInformation = 35 ; // Y N SystemContextSwitchInformation = 36 ; // Y N SystemRegistryQuoaInformation = 37 ; // Y Y SystemLoadAndCallImage = 38 ; // Y N SystemPrioritySeparation = 39 ; // N Y SystemNotImplemented10 = 40 ; // Y N SystemNotImplemented11 = 41 ; // Y N SystemInvalidInfoClass2 = 42 ; SystemInvalidInfoClass3 = 43 ; SystemTimeZoneInformation = 44 ; // Y N SystemLookasideInformation = 45 ; // Y N SystemSetTimeSlipEvent = 46 ; // N Y SystemCreateSession = 47 ; // N Y SystemDeleteSession = 48 ; // N Y SystemInvalidInfoClass4 = 49 ; SystemRangeStartInformation = 50 ; // Y N SystemVerifierInformation = 51 ; // Y Y SystemAddVerifier = 52 ; // N Y SystemSessionProcessInformation = 53 ; // Y N
سياتي شرح هذه الانواع واحدا واحدا ان شاء الله .
قد نلاحظ وجود Y,N اسفل الكلمتين Query,Set وهي تدل اذا ما كان هذا النوع من المعلومات يمكن استعمال الدالة NtQuerySystemInformation لعمل Query والحصول على معلومات
, او استعمال الدالة NtSetSystemInformation للقيام بتغيير معلومات النظام .
هذه المرة سنتعرف على اول نوع من معلومات النظام :
SystemBasicInformation :
* التعريف :
type TSystem_Basic_Information = packed record dwUnknown1 : DWORD; MaximumIncrement : ULONG; PhysicalPageSize : ULONG; NumberOfPhysicalPages : ULONG; LowestPhysicalPage : ULONG; HighestPhysicalPage : ULONG; AllocationGranularity : ULONG; LowestUserAddress : ULONG; HighestUserAddress : ULONG; ActiveProcessors : ULONG; NumberProcessors : byte; bUnknown2 : byte; wUnknown3 : word; end;
* عناصر الـ record :
- dwUnknown1 :
دائما يحوي القيمة 0 (صفر) غير معروف تفسير لهذه القيمة .
- MaximumIncrement :
( المعذرة لم تعجبني ترجمتي سواء من الانجليزيه او الصينيه الى العربيه ,لذا فضلت ذكر النص الانجليزي )
The maximum number of 100-nanosecond units between clock ticks. Also the number of
100-nanosecond units per clock tick for kernel intervals measured in clock ticks.
- PhysicalPageSize :
حجم صفحة فيزيائيه . ( الوحده Byte ).
- NumberOfPhysicalPages :
عدد الصفحات الفيزيائيه التي يديرها نظام التشغيل .
- LowestPhysicalPage :
اقل عدد من الصفحات الفيزيائيه يديرها نظام التشغيل . ( ترقيمها يبدأ من 0 ) .
- HighestPhysicalPage :
اكبر عدد من الصفحات الفيزيائيه يديرها نظام التشغيل . ( ترقيمها يبدأ من 0 ) .
- AllocationGranularity :
العنوان الاساسي -base address- للــ Virtual Memory , وهو reserved address .
- LowestUserAddress :
Low virtual address الموجودة فيه برامج الـ user mode .
- HighestUserAddress :
High virtual address الموجودة فيه برامج الـ user mode .
- ActiveProcessors :
تمثل رقم الـ Processor النشط . 0 تعني Processor 0 و بالمثل الى 31 التي تعني Processor 31.
- NumberProcessors :
عدد الـ Processors الموجودة في النظام .
- bUnknown2 :
غير معروف .
- wUnknown3 :
غير معروف .
جاء الان الوقت لكتابة مثال يظهر كيفيه الحصول على System Basic Informaion .
Example 1 :
علينا اضافة TMemo و TButton .
// System Basic Informaion
// يكتب بعد تعريف الـ TForm class
type
PSystem_Basic_Information=^TSystem_Basic_Information;
TSystem_Basic_Information = packed record
dwUnknown1 : DWORD;
MaximumIncrement : ULONG;
PhysicalPageSize : ULONG;
NumberOfPhysicalPages : ULONG;
LowestPhysicalPage : ULONG;
HighestPhysicalPage : ULONG;
AllocationGranularity : ULONG;
LowestUserAddress : ULONG;
HighestUserAddress : ULONG;
ActiveProcessors : ULONG;
NumberProcessors : byte;
bUnknown2 : byte;
wUnknown3 : word;
end;
TPDword=^DWORD;
var
NtQuerySystemInformation: function(infoClass: DWORD;
buffer: Pointer;
bufSize: DWORD;
returnSize: TPDword):
DWORD; stdcall =nil;
...
function MyNativeApi:bool;
var
hLib : DWORD;
begin
result:=True;
hLib := LoadLibrary('NTDLL.DLL');
if hLib>0 then
NtQuerySystemInformation := GetProcAddress(hLib,
'NtQuerySystemInformation')
else
result:=false;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
SysInfo:TSystem_Basic_Information;
status: Longint;
begin
if MyNativeApi then
begin
status:= NtQuerySystemInformation(0, @SysInfo, SizeOf(SysInfo), nil);
if(status<>0) then
exit;
Memo1.Lines.Clear;
Memo1.Lines.Add(inttostr(sizeof(SysInfo)));
Memo1.Lines.Add(inttostr(SysInfo.dwUnknown1));
Memo1.Lines.Add(inttostr(SysInfo.MaximumIncrement));
Memo1.Lines.Add(inttostr(SysInfo.PhysicalPageSize));
Memo1.Lines.Add(inttostr(SysInfo.NumberOfPhysicalPages));
Memo1.Lines.Add(inttostr(SysInfo.LowestPhysicalPage));
Memo1.Lines.Add(inttostr(SysInfo.HighestPhysicalPage));
Memo1.Lines.Add(inttostr(SysInfo.AllocationGranularity));
Memo1.Lines.Add(inttostr(SysInfo.LowestUserAddress));
Memo1.Lines.Add(inttostr(SysInfo.HighestUserAddress));
Memo1.Lines.Add(inttostr(SysInfo.ActiveProcessors));
Memo1.Lines.Add(inttostr(SysInfo.NumberProcessors));
Memo1.Lines.Add(inttostr(SysInfo.bUnknown2));
Memo1.Lines.Add(inttostr(SysInfo.wUnknown3));
end;
end;ان كان هناك اهتمام بالموضوع :-
----------
في المرة القادمة ان شاء الله سيتم وضع كل مايتعلق بالـ Native API من دوال او records .. في unit واحدة تضمها جميعا , حتى يسهل استخدامها .
اتمنى ممن له خبرة في الموضوع المشاركة في تجميع اكبر قدر من المعلومات , فمثل هذه الدوال يندر وجود معلومات عنها .
----------
(f)
CIONO1