LoadDriver SSDT Hook
#11
STRELiTZIA كتب :1 - اظنها النسخة الأولى لــ WinXP بدون SP صينية...

2- في المثال فوق لا يتم الاعتماد عليها في عملية المعالجة، فالأندكيس يرجعه DbgPrint

1- أظنها تابعة لـ هده المشاركة[صورة: icon10.gif] هنا
الخاص بمثال NtOpenProcess SSDT Hook ....
PHP كود :
DbgPrint('ZwOpenProcess Ord Address: 0x%.8X', SystemServiceOrd($7A)^);    //  XP Ord! 
الأندكس 7A = 122 هو للدالة NtOpenProcess كما هو موضح في المثال , خطأ بسيط ليست مشكلة ...

2- كيف لا يتم الإعتماد عليها في عملية المعالجة ؟ SystemServiceOrdترجع عنوان الدالة
المستهدفة إنطلاقا من الأندكس الممر ؟؟
بالتوفيق,,
I'M Fly Like A G6

الرد
#12
GamingMasteR كتب :الافضل تحميل Image نظيف للملف من الدسك والعمل عليه .

1- لو إعتمدنا على إستخراج قائمة الدوال الـ Ntxxx المصدرة من NTDLL , سيكون ترتيب بعض
الدوال خاطئ , هل يتم وضع قائمة إستثنائية تحتوي على ترتيب الدوال المضافة حديثا أو على حسب
إصدار النظام ؟؟


[صورة: 44655478.gif]

- قمت بإستخراج الـ Index من ملف NTDLL , فكان ترتيب الداول الموضحة في الصورة مغاير ...
إلا أن راجعه قائمة Windows System Call Table فكان الترتيب صحيح !

2- الـ Native APi يتم تصديرها من NtosKrnl.exe و مساره معروف أم أنه يتم الإعتماد على الـ
Int 2E في الباراماتر الأول EAX الذي يحدد أي SDT هو المستهدف ... (البيت #12-#13) .
00 :
NtosKrnl.exe SDT
Win32K.sys SDTS : 01
n : 10
n
: 11

بارك الله فيك ,,
I'M Fly Like A G6

الرد
#13
1- الترتيب صحيح ، الترتيب المعروض في الصورة بالنظام العشري ، في الـdisassembler ستجده بالنظام الست عشري .
2- لم افهم المقصود .
الرد
#14
كود :
PWCHAR *GetSsdtStrings(VOID) { LOADED_IMAGE LoadedImage; PVOID PtrImage; PWCHAR *Result; PUSHORT Ordinals; PULONG ExportRva; PCHAR FunctionString, *StringRva; ULONG ServiceId, FunctionId; MapAndLoad("ntdll.dll", NULL, &LoadedImage, FALSE, TRUE); PtrImage = calloc(LoadedImage.FileHeader->OptionalHeader.SizeOfImage, sizeof(UCHAR)); CopyMemory((PUCHAR)PtrImage, LoadedImage.MappedAddress, LoadedImage.FileHeader->OptionalHeader.SizeOfHeaders); for (WORD Index = 0; Index < LoadedImage.FileHeader->FileHeader.NumberOfSections; Index++) { CopyMemory((PUCHAR)PtrImage + LoadedImage.Sections[Index].VirtualAddress, LoadedImage.MappedAddress + LoadedImage.Sections[Index].PointerToRawData, LoadedImage.Sections[Index].SizeOfRawData ); } UnMapAndLoad(&LoadedImage); LoadedImage.FileHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)PtrImage + ((PIMAGE_DOS_HEADER)PtrImage)->e_lfanew); PIMAGE_EXPORT_DIRECTORY ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(LoadedImage.FileHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (ULONG_PTR)PtrImage); StringRva = (PCHAR *)(ExportDirectory->AddressOfNames + (ULONG_PTR)PtrImage); Ordinals = (PUSHORT)(ExportDirectory->AddressOfNameOrdinals + (ULONG_PTR)PtrImage); ExportRva = (PULONG)(ExportDirectory->AddressOfFunctions + (ULONG_PTR)PtrImage); Result = (PWCHAR *)calloc(KiSsdtLimit, sizeof(PWCHAR)); for (ULONG Index = 0; Index < KiSsdtLimit; Index++) { Result[Index] = L"Unknown Entry"; } for (ULONG Index = 0; Index < ExportDirectory->NumberOfNames; Index++) { FunctionId = ExportRva[Ordinals[Index]] + (ULONG_PTR)PtrImage; FunctionString = StringRva[Index] + (ULONG_PTR)PtrImage; if (*(PUCHAR)FunctionId == 0xb8 && *(PUCHAR)(FunctionId + 5) == 0xba && *(PUCHAR)(FunctionId + 10) == 0xff && (*(PUCHAR)(FunctionId + 12) & 0xc0) == 0xc0) { if (FunctionString[0] == 'N' && FunctionString[1] == 't') { ServiceId = *(PULONG)(FunctionId + 1); if (ServiceId < KiSsdtLimit) { Result[ServiceId] = (PWCHAR)calloc(256, sizeof(WCHAR)); _snwprintf_s(Result[ServiceId], 256, _TRUNCATE, L"%S", FunctionString); } } } } free(PtrImage); return Result; }
الرد
#15
GamingMasteR كتب :1- الترتيب صحيح ، الترتيب المعروض في الصورة بالنظام العشري ، في الـdisassembler ستجده بالنظام الست عشري .
2- لم افهم المقصود .
1- نعم هذا ما قصدته بالرغم من أن طريقة جلب الـ Ntxxx من الـ Ntdll تعطي ترتيب يختلف
عن الذي يعرضه KD إنطلاقا من NTyieldExecution ؟؟
كود دلفي :
كود :
type TDWordArray = array [0..$FFFFF] of DWORD; var imageinfo: LoadedImage; pExportDirectory: PImageExportDirectory; dirsize: Cardinal; pDummy: PImageSectionHeader; i: Cardinal; pNameRVAs: ^TDWordArray; Name: string; _index: Word; begin ListFdLL.Clear; _index:= 0; if MapAndLoad(PChar('ntdll.dll'), nil, @imageinfo, True, True) then begin try pExportDirectory := ImageDirectoryEntryToData(imageinfo.MappedAddress, False, IMAGE_DIRECTORY_ENTRY_EXPORT, dirsize); if (pExportDirectory <> nil) then begin pNameRVAs := ImageRvaToVa(imageinfo.FileHeader, imageinfo.MappedAddress, DWORD(pExportDirectory^.AddressOfNames), pDummy); for i := 0 to pExportDirectory^.NumberOfNames - 1 do begin Name := PChar(ImageRvaToVa(imageinfo.FileHeader, imageinfo.MappedAddress, pNameRVAs^[i], pDummy)); If Pos('Nt',Name)=1 Then Begin ListFdLL.Items.Add; ListFdLL.Items.Item[_index].Caption:= IntToStr(_index); ListFdLL.Items.Item[_index].SubItems.Add(Name); ListFdLL.Items.Item[_index].SubItems.Add(''); ListFdLL.Items.Item[_index].SubItems.Add(''); ListFdLL.Items.Item[_index].SubItems.Add('-'); ListFdLL.Items.Item[_index].SubItems.Add('%SystemDirectory%\ntkrnlpa.exe'); Inc(_index); End; end; end; finally UnMapAndLoad(@imageinfo); Label2.Caption:= IntToStr(ListFdLL.Items.Count -1 ); ListFdLL.Items.Add; end; end; End;
2- قصدي هل يتم التعرف على الـ Module المصدر برمجيا أم إفتراضا ؟؟ , قرأت في أحد المقالات :
PHP كود :
KiSystem
Service
() knows that it is handling a win32k.sys API call by examining bits #12
and 13 of the function index in register EAX. If both bits are zero, it is a Native API
call handled by ntoskrnl
.exe, so KiSystemService() uses the first SDT slot. If bit
#12 is set and bit #13 is zero, KiSystemService() uses the second slot. 
I'M Fly Like A G6

الرد
#16
هناك جدولين واحد خاص بالـnative threads اسمه KeServiceDescriptorTable ، واخر خاص بالـgui threads اسمه KeServiceDescriptorTableShadow .
كلاهما عبارة عن مصفوفة رباعية من التركيبة SERVICE_DESCRIPTOR_TABLE :
كود :
[align=left]typedef struct _SERVICE_DESCRIPTOR_TABLE { PVOID *ServiceTable; PULONG CounterTable; ULONG TableSize; PUCHAR ArgumentTable; } SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;[/align]
عندما يحدث system call فان عنوان الـServiceTable يكون موجود في KTHREAD.ServiceTable والذي اما ان يشير الى KeServiceDescriptorTable او KeServiceDescriptorTableShadow حسب كون الـthread ألحالي native/gui .

اذا كان الـService Index اقل من 0x1000 فيتم استعمال العنصر الاول من الـServiceTable (هي مصفوفة رباعية كما قلنا) .
اكبر من او يساوي 0x1000 يتم استعمال العنصر الثاني الذي يحتوي على دوال الـGUI ، اذا كان الthread الحالي native وتم استدعاء GUI syscall لأول مرة فانه يتم تحويله الى gui thread .
العنصر الثالث والرابع من SDT لا يستخدم حاليا .
الرد
#17
" (البيت #12-#13) .
00 :
NtosKrnl.exe SDT
Win32K.sys SDTS : 01
n : 10
n
: 11 "

- هذا ما أشرت إليه أخي GM , بارك الله فيك على مشاركتك & التوضيح .
I'M Fly Like A G6

الرد


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم