السلام عليكم
ملحوظة :
مستوى الكاتب متواضع جداً فاتمنى ممن لهم الخبرة التعديل في اي مكان جانبني الصواب فيه , كما أني انصح ذوي المستويات المتقدمة عدم تضييع وقتهم في النظر لمواضيع من المستوى المبتدئ ...
تعقيباً على الموضوع الذي وضعه الأخ عروة بعنوان"أفكار سريعة , ... " و تحديداً النقطة التي ذكر فيها كيفية الحصول (التغيير) على (في) خصائص الملفات باستخدام API Function GetFileAttributesA , وددت أن أضع شرح للكيفية التي تعمل بها تلك الدالة ..
عندما نستدعي الدالة GetFileAttributesA واعطاء الاسم الكامل لمسار الملف ما الذي يحدث ؟
GetFileAttributesA موجود في الملف kernel32.dll ( كلام فاضي , الكل يعلم هذا )..لنلقي نظرة على الدالة بعد عمل Disassemble للمكتبه kernel32.dll باستخدام IDA pro ( ما هذا ؟ .. ممم .. لا تسألني google it وستعلم ما هو ) ..
.text:77E5951F; DWORD __stdcall GetFileAttributesA(LPCSTR lpFileName)
.text:77E5951F public GetFileAttributesA
.text:77E5951F GetFileAttributesA proc near ; CODE XREF: .text:77E49036p
.text:77E5951F
.text:77E5951F lpFileName = dword ptr 4
.text:77E5951F
.text:77E5951F push [esp+lpFileName]
.text:77E59523 call sub_0_77E5B392; kcahcn : here RtlInitAnsiString is called to pass Filename as ANSI_STRING to GetFileAttributesW
.text:77E59528 test eax, eax
.text:77E5952A jz loc_0_77E754A1
.text:77E59530 push dword ptr [eax+4]; kcahcn : buffer in ANSI_STRING that poit to FileName. why eax+4? 2 bytes for Length, 2 bytes for Maxlength..
.text:77E59533 call GetFileAttributesW
.text:77E59538
.text:77E59538 locret_0_77E59538: ; CODE XREF: .text:77E754A4j
.text:77E59538 retn 4
.text:77E59538 GetFileAttributesA endp
يوجد شرح مبسط امام الاجزاء المهمة , اي استفسار او تعديل سأكون في غاية السرور لتلقيه ..
نلاحظ أن هناك استدعاء للدالة GetFileAttributesW و التي سنوضح التحليل الخاص بها فيما يلي :
.text:77E5E6BD; Exported entry 339. GetFileAttributesW
.text:77E5E6BD; Attributes: bp-based frame
.text:77E5E6BD
.text:77E5E6BD; DWORD __stdcall GetFileAttributesW(LPCWSTR lpFileName)
.text:77E5E6BD public GetFileAttributesW
.text:77E5E6BD GetFileAttributesW proc near ; CODE XREF: .text:77E41D3Cp
.text:77E5E6BD ; sub_0_77E4561D+544p ...
.text:77E5E6BD
.text:77E5E6BD var_54 = byte ptr -54h
.text:77E5E6BD var_34 = dword ptr -34h
.text:77E5E6BD var_2C = dword ptr -2Ch
.text:77E5E6BD var_28 = dword ptr -28h
.text:77E5E6BD var_24 = dword ptr -24h
.text:77E5E6BD var_20 = dword ptr -20h
.text:77E5E6BD var_1C = dword ptr -1Ch
.text:77E5E6BD var_18 = dword ptr -18h
.text:77E5E6BD var_14 = dword ptr -14h
.text:77E5E6BD var_C = dword ptr -0Ch
.text:77E5E6BD var_8 = byte ptr -8
.text:77E5E6BD var_4 = dword ptr -4
.text:77E5E6BD lpFileName = dword ptr 8
.text:77E5E6BD; kcahcn : Creating stack frame. We need that for routines that had parameters and local variable to avoid problems of changing esp value
.text:77E5E6BD push ebp; kcahcn : save old value of epb (base pointer)
.text:77E5E6BE mov ebp, esp; kcahcn : ebp=esp, provide "base" address which used to allocate space for local variable
.text:77E5E6C0 sub esp, 54h; kcahcn : allocate space of 0x54 byte for local variable by subtracting esp
.text:77E5E6C3 push esi; save old value of esi
.text:77E5E6C4 lea eax, [ebp+var_14]; kcahcn : NtFilePath (OPTIONAL) (out)
.text:77E5E6C7 push eax
.text:77E5E6C8 xor esi, esi; esi=0
.text:77E5E6CA push esi; kcahcn : NtFilePath=NULL (OPTIONAL) (out)
.text:77E5E6CB lea eax, [ebp+var_8]; out kcahcn : NtName (out)
.text:77E5E6CE push eax
.text:77E5E6CF push [ebp+lpFileName]; kcahcn : DosName (in)
.text:77E5E6D2 call ds:RtlDosPathNameToNtPathName_U; kcahcn : call the native api routine to get NtPathName of the file
.text:77E5E6D8 test al, al
.text:77E5E6DA jz loc_0_77E4DA35; kcahcn : if result =0 means error
.text:77E5E6E0 mov eax, [ebp+var_14]
.text:77E5E6E3 cmp ax, si
.text:77E5E6E6 push ebx
.text:77E5E6E7 mov ebx, [ebp+var_4]; kcahcn : contain the ntpathname why? cause var_8 points to PUNICODE_STRING ,
;and as we know UNICODE_STRING struct contain : length(word 2byte, epb+var_8),maxlength(word 2byte),Buffer(PWSTR pointer 4byte,ebp+var_4)
.text:77E5E6EA push edi
.text:77E5E6EB jnz loc_0_77E5848C
.text:77E5E6F1 mov [ebp+var_C], esi
.text:77E5E6F4
.text:77E5E6F4 loc_0_77E5E6F4: ; CODE XREF: .text:77E58495j
.text:77E5E6F4 mov eax, [ebp+var_C]
.text:77E5E6F7 mov [ebp+var_28], eax; kcahcn : var_28 = 0 (RootDirectory)
.text:77E5E6FA lea eax, [ebp+var_8]; kcahcn : NtPathName
.text:77E5E6FD mov [ebp+var_24], eax; kcahcn : var_24 contain the NtPathName of file
.text:77E5E700 lea eax, [ebp+var_54]; kcahcn : FileAttributes
.text:77E5E703 push eax
.text:77E5E704 lea eax, [ebp+var_2C]; kcahcn : ObjectAttributes
.text:77E5E707 push eax
.text:77E5E708 mov [ebp+var_2C], 18h; kcahcn : Length = 0x18 ( SizeOf(OBJECT_ATTRIBUTES) , always 24 byte)
.text:77E5E70F mov [ebp+var_20], 40h; kcahcn : var_20 = 0x40 = OBJ_CASE_INSENSITIVE (Attribute)
.text:77E5E716 mov [ebp+var_1C], esi; kcahcn : var_1C =NULL (SecurityDescriptor)
.text:77E5E719 mov [ebp+var_18], esi; kcahcn : var_18=NULL (SecurityQualityOfService)
.text:77E5E71C call ds:NtQueryAttributesFile
.text:77E5E722 mov edi, eax
.text:77E5E724 mov eax, large fs:18h; kcahcn : large file system, no idea until now :(
.text:77E5E72A mov eax, [eax+30h]; kcahcn : have no idea :(
.text:77E5E72D push ebx; kcahcn : pointer to memory block to be freed (var_4)
.text:77E5E72E push esi; Flag=0
.text:77E5E72F push dword ptr [eax+18h]; kcahcn : hHeap handle, don't know why like this :(
.text:77E5E732 call ds:RtlFreeHeap; kcahcn : free the memory block started at var_4
.text:77E5E738 cmp edi, esi; kcahcn : edi > 0 error ,check path name using RtlIsDosDeviceName_U
.text:77E5E73A jl loc_0_77E5691F
.text:77E5E740 mov eax, [ebp+var_34]; kcahcn : why? :(
.text:77E5E743
.text:77E5E743 loc_0_77E5E743: ; CODE XREF: .text:77E56939j
.text:77E5E743 ; .text:77E7AC71j
.text:77E5E743 pop edi
.text:77E5E744 pop ebx
.text:77E5E745
.text:77E5E745 loc_0_77E5E745: ; CODE XREF: .text:77E4DA3Fj
.text:77E5E745 pop esi
.text:77E5E746 leave
.text:77E5E747 retn 4
.text:77E5E747 GetFileAttributesW endp
.text:77E5E747
نلاحظ في البداية ان اول شئ في الدالة هو عمل stack frame للمتغيرات المحلية وهذا شئ طبيعي .
بعد ذلك استدعاء لــ Native API Routine وهو RtlDosPathNameToNtPathName_U والذي يقوم بتحويل DosPath الى NtPath باضافة "\؟\\" في بداية المسار ...
بعد ذلك يأتي الجزء الهام وهو استدعاء NtQueryAttributesFile التي عن طريقها نحصل على خصائص الملف . لتفاصيل اكثر يرجى الاطلاع على الشرح المتواضع المذكور أعلاه ...
بالنسبة لعمل مثال يستخدم NtQueryAttributesFile فهذا اتركه لمن له اهتمام بالموضوع ...
معذرة لعدم التعمق في الشرح واترك ذلك لمن يود التعمق في الموضوع ...
تحياتي
CIONO1
ارفق صورة
-
Resized to 64% (was 1024 x 768) - Click image to enlarge