LoadDriver SSDT Hook
#1
السلام عليكم و رحمة الله

LoadDriver SSDT Hook.
Compile it with Meerlat 1.1 (http://www.delphi4arab.net/forum/showthread.php?p=22034)
Use DbgView to catch informations.
Only for Windows XP.

Delphi project link: hxxp://www.mediafire.com/?klfd7ozqliawq6f

الملفات المصدرية:

PHP كود :
unit ZwLoadDriverHook;
interface

uses
  nt_status
,
  
ntoskrnl,
  
fcall,
  
KernelUtils,
  
NtoskrnlCustom;

function 
_DriverEntry(
  
DriverObject: PDriverObject;
  
RegistryPath: PUnicodeString
  
): NTSTATUS; stdcall;

implementation
type
  TZwLoadDriver 
= function(DriverServiceName: PUnicodeString): NTSTATUS; stdcall;
var
  
HookActive: Boolean;
  
ZwLoadDriverNextHook: TZwLoadDriver;

function 
ZwLoadDriverHookProc(DriverServiceName: PUnicodeString): NTSTATUS; stdcall;
begin
  DbgPrint
('Driver service name :%wZ', DriverServiceName);
  
Result := ZwLoadDriverNextHook(DriverServiceName);
end;

procedure DriverUnload(DriverObject: PDriverObject); stdcall;
begin
  
if HookActive then
  begin
    ZwLoadDriverNextHook 
:=  TZwLoadDriver(InterlockedExchange(SystemServiceName(GetImportFunAddr(@ZwLoadDriver)),  LONG(@ZwLoadDriverNextHook)));
    
DbgPrint('ZwLoadDriver New Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwLoadDriver))^);
    
DbgPrint('ZwLoadDriver Old Address: 0x%.8X', DWORD(@ZwLoadDriverNextHook));

    
HookActive := False;
  
end;
  
DbgPrint('DriverUnload(-)');
end;

function 
_DriverEntry(DriverObject: PDriverObject; RegistryPath: PUnicodeString): NTSTATUS; stdcall;
begin
  DriverObject
^.DriverUnload := @DriverUnload;
  
Result := STATUS_SUCCESS;
  
DbgPrint('DriverEntry(-):0x%.8X', Result);
  
HookActive := False;

  
DbgPrint('ZwLoadDriver Import Address: 0x%.8X', GetImportFunAddr(@ZwLoadDriver));
  
DbgPrint('KeServiceDescriptorTable() Address 1: 0x%.8X', @KeServiceDescriptorTable);
  
DbgPrint('KeServiceDescriptorTable() Address 2: 0x%.8X', PPointer(@KeServiceDescriptorTable)^);

  
DbgPrint('ZwLoadDriver Ord Address: 0x%.8X', SystemServiceOrd($7A)^); //  XP Ord!
  
DbgPrint('ZwLoadDriver Name Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwLoadDriver))^);

  
DbgPrint('ZwLoadDriver HookProc Address: 0x%.8X', @ZwLoadDriverHookProc);

  if 
not HookActive then
  begin
    ZwLoadDriverNextHook 
:=  TZwLoadDriver(InterlockedExchange(SystemServiceName(GetImportFunAddr(@ZwLoadDriver)),  LONG(@ZwLoadDriverHookProc)));

    
DbgPrint('ZwLoadDriver New Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwLoadDriver))^);
    
DbgPrint('ZwLoadDriver Old Address: 0x%.8X', DWORD(@ZwLoadDriverNextHook));

    
HookActive := True;
  
end else
  
begin
    DbgPrint
('ZwLoadDriver Hooked');
  
end;
end;
end. 
PHP كود :
unit KernelUtils;
interface

uses
  nt_status
,
  
ntoskrnl;

function 
SystemServiceName(AFunc: Pointer): PLONG; stdcall;
function 
GetImportFunAddr(lpImportAddr: Pointer): Pointer; stdcall;
function 
SystemServiceOrd(iOrd: ULONG): PLONG; stdcall;

implementation

function GetImportFunAddr(lpImportAddr: Pointer): Pointer; stdcall;
begin
  Result 
:= PPointer(PPointer(Cardinal(lpImportAddr) + 2)^)^;
end;

function 
SystemServiceName(AFunc: Pointer): PLONG; stdcall;
var 
lpKeServiceDescriptorTable: PServiceDescriptorEntry;
begin
  lpKeServiceDescriptorTable 
:= GetImportFunAddr(@KeServiceDescriptorTable);
  
Result := PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * PULONG(ULONG(AFunc) + 1)^));
end;

function 
SystemServiceOrd(iOrd: ULONG): PLONG; stdcall;
var 
lpKeServiceDescriptorTable: PServiceDescriptorEntry;
begin
  lpKeServiceDescriptorTable 
:= GetImportFunAddr(@KeServiceDescriptorTable);
  
Result := PLONG(PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * iOrd)));
end;
end. 
بالتوفيق ان شاء الله
الرد
#2
السلام عليكم
شكرا لك أخي STRELiZIA .. ولكن عندما جربته على WinXP SP3 قام بعملية رستارت لا أعلم ما المشكل؟
الرد
#3
نعم ربما يحدث في NT 5.1 وما فوق لأن الـServiceTable يكون موجود في Read-only memory page .
لابد من ايقاف الـwrite protection عن طريق التعديل على الـcontrol register 0 ، او عن طريق عمل Mapping لنفس الـPhysical Page الى MDL تسمح بالـWrite .

كود :
cli; mov eax, cr0; and eax, ~0x10000; mov cr0, eax; // ssdt patch code mov eax, cr0; or eax, 0x10000; mov cr0, eax; sti;

او :

كود :
PMDL mdlServiceTable = MmCreateMdl(NULL, KeServiceDescriptorTable->ServiceTable, KeServiceDescriptorTable->TableSize * sizeof(PVOID)); if (mdlServiceTable) { PVOID lpServiceTable = NULL; MmBuildMdlForNonPagedPool(mdlServiceTable); mdlServiceTable->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA; lpServiceTable = MmMapLockedPages(mdlServiceTable, KernelMode); // ssdt patch code (use lpServiceTable instead of KeServiceDescriptorTable->ServiceTable) MmUnmapLockedPages(lpServiceTable, mdlServiceTable); IoFreeMdl(mdlServiceTable); }
الرد
#4
السلام عليكم و رحمة الله
بارك الله فيك اخي GM

تم التحديث بمعالجة الــ write protection لدعم النسخ Vista و Seven
التحميل نفس الرابط في المشاركة الأولى او في مدونة Slug Analysis Lab
رابط المدونة:

كود :
http://sluganalysislab.blogspot.com


Source updated 16 november 2010


بالتوفيق ان شاء الله
الرد
#5
مبروك افتتاح المدونة Smile




off topic:
(لماذا ليست Wordpress)
الرد
#6
السلام عليكم و رحمة الله
الله يبارك فيك اخي GM
و ان شاء الله نرى واحدة تخص KDetective في المستقبل القريب...

إقتباس :(لماذا ليست Wordpress)
للأسف WordPress مليئة بالثغرات... ثبتها على server افتراضي و نجحت عليها تجربة كل ما تم نشره من ثغرات...
على عكس Blogspot التي هي تحت دعم حقيقي من مهندسي Google في الوقت الحالي...

Off topic:
النسخة الجديدة التجريبية من KDetective رائعة جدا... (اشهـــــار Smile )

تحياتي
الرد
#7
و عليكم السلام و رحمة الله و بركاته
- بارك الله فيك أستاذ StrLxxx , لي ملاحظة بسيطة في ما يخص : Function Ord
كود :
[COLOR=#000000][COLOR=#0000bb]DbgPrint[/COLOR][COLOR=#007700]([/COLOR][COLOR=#dd0000]'ZwLoadDriver Ord Address: 0x%.8X'[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000bb]SystemServiceOrd[/COLOR][COLOR=#007700]($[/COLOR][COLOR=#0000bb]7A[/COLOR][COLOR=#007700])^); [/COLOR][COLOR=#ff8000]// XP Ord![/COLOR][/COLOR]
أنا لدي XP P3 G2600 , ترتيب الدالة 61$ ...

يكفي جلب قيمة الـ EAX للتحصل على عنوان الدالة المستهدفة ZwLoadDriver
يمكن تعويض كل من SystemServiceName & SystemServiceOrd بي :
كود :
Asm PushAd Mov Tmp,eax PopAd End; DbgPrint('SystemServiceOrd ($xx) : 0x%.8X', Tmp);
سيتم تخزين عنوان Source في الـ EAX&EDX بعد تنفيذ InterlockedExchange ....
- جلب الـ Ord الصحيح , دالة بدائية ممكن ؟ , لكن تفي بالغرض :
كود :
Type SSDT = Array[0..$FF]Of Dword ;//ServiceLimit = $F8 (Windows NT 4.0). Procedure GetOrigFuncOrdTable (_FuncAddress: Pointer); Var i: Byte; _Addr: SSDT; Begin For i:= 0 to $FF Do Begin _Addr[i]:= SystemServiceOrd(i)^; If _Addr[i] = Dword(_FuncAddress) Then DbgPrint('TrgFunction Ord : 0x%.8X',i); End; End;
بالتوفيق,,
I'M Fly Like A G6

الرد
#8
صحيح لم انتبه لهذا أخي STR ، أي كرنل توجد به NtLoadDriver في الـIndex 0x7A ؟ لا يبدو لي ان هناك واحد به هذا الترتيب ...

بالنسبة لطريقة الأخ TF6M فهي جيدة لكن الأفضل تطبيقها على Image لـntdll.dll غير المحمّل في الذاكرة لأنه لو هناك user-mode hook او patch لهذه الدالة سيتم جلب opcode آخر وبالتالي Index غير حقيقي .

الافضل تحميل Image نظيف للملف من الدسك والعمل عليه .
الرد
#9
السلام عليكم و رحمة الله اخي GM نورت الموضوع Smile

إقتباس :صحيح لم انتبه لهذا أخي STR ، أي كرنل توجد به NtLoadDriver في الـIndex 0x7A ؟
اظنها النسخة الأولى لــ WinXP بدون SP صينية...

إقتباس : DbgPrint('ZwLoadDriver Ord Address: 0x%.8X', SystemServiceOrd($7A)^); // XP Ord!
في المثال فوق لا يتم الاعتماد عليها في عملية المعالجة، فالأندكيس يرجعه DbgPrint

إقتباس :الافضل تحميل Image نظيف للملف من الدسك والعمل عليه .
فكرة جيدة

بارك الله فيك
الرد
#10
لدي نسخة أصلية بدون اي اضافات ، وايضا 0x61 ...
هل يمكن ان ترسل ي ملف الكرنل الخاص بها ؟
الرد


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


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