在论坛看到别的代码,写了下,但是内存保护的时候为什么老是蓝屏,我用单核虚拟机通过(单机的是xpsp3-ntoskrnl.exe),双机联到我的本子上就蓝的不行(本子是xpsp3-ntkrpamp.exe),该怎么弄啊,非常感谢
#include <ntddk.h>
#include <windef.h>
#include <string.h>
#define IOCTL_CODE_SETSYSTEMDEBUG (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN,0x901,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_CODE_UNSETSYSTEMDEBUG (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN,0x902,METHOD_BUFFERED,FILE_ANY_ACCESS)
//#define ntoskrnl
//#define ntkrnlpama
#pragma pack(1)
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union {
LIST_ENTRY HashLinks;
struct {
PVOID SectionPointer;
ULONG CheckSum;
};
};
ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
#pragma pack()
PDRIVER_OBJECT pdoGlobalDrvObj = 0;
UNICODE_STRING usSymlinkName={0};
UNICODE_STRING usDeviceName={0};
void PageProtectOn()
{
__asm //恢复内存保护
{
// mov eax, cr0
// or eax, 10000h
// mov cr0, eax
sti
}
}
void PageProtectOff()
{
__asm //去掉内存保护
{
cli
//mov eax, cr0
// and eax, not 10000h
// mov cr0, eax
}
}
ULONG strEnd(PWCHAR dest,PWCHAR sub)
{
int ulDest ;
int ulSub ;
if (dest == NULL && sub == NULL)
return 0;
ulDest = wcslen(dest);
ulSub = wcslen(sub);
if (ulSub == 0 || ulSub > ulDest)
return 0;
return !wcscmp(&dest[ulDest - ulSub],sub);
}
PLDR_DATA_TABLE_ENTRY FindModule(IN PDRIVER_OBJECT DriverObject, PUNICODE_STRING pDestDriverName)
{
PLDR_DATA_TABLE_ENTRY pModuleCurrent = NULL;
PLDR_DATA_TABLE_ENTRY PStop = NULL;
if (DriverObject == NULL)
return 0;
pModuleCurrent = (PLDR_DATA_TABLE_ENTRY)(DriverObject->DriverSection);
if (pModuleCurrent == NULL)
return 0;
PStop = pModuleCurrent;
do
{
if ( NULL == pDestDriverName)
{
// ntoskrnl.exe,\SystemRoot\system32\ntkrnlpa.exe, 基地址 - 大小0x410000
KdPrint(("%wZ [0x%04X - 0x%04X] %wZ\n", &pModuleCurrent->BaseDllName, pModuleCurrent->DllBase, pModuleCurrent->SizeOfImage, &pModuleCurrent->FullDllName)) ;
}
else
{
if ( RtlEqualUnicodeString( &pModuleCurrent->BaseDllName, pDestDriverName, FALSE ))
return pModuleCurrent ;
}
pModuleCurrent = (PLDR_DATA_TABLE_ENTRY)pModuleCurrent->InLoadOrderLinks.Flink;
}
while ( pModuleCurrent != PStop );
return NULL;
}
void SetSystemDebug(PVOID lpBase , BOOL bSetDebug)
{
#ifdef ntoskrnl
BYTE *lpKdPitchDebugger = (BYTE*)lpBase+0x000761fc;
BYTE *lpKdDebuggerEnabled = (BYTE *)lpBase + 0x0007c741; //$+0x163cec
DWORD *lpKiDebugRoutine = (DWORD *)((BYTE *)lpBase + 0x00083184); //$+0x1689bc
DWORD lpKdpTrap = (DWORD)lpBase + 0x001a8bbf;
DWORD lpKdpStub = (DWORD)lpBase + 0x0002bdbf;
#else
BYTE *lpKdPitchDebugger = (BYTE*)lpBase+0x000766fc;
BYTE *lpKdDebuggerEnabled = (BYTE *)lpBase + 0x0007ea41; //$+0x163cec
DWORD *lpKiDebugRoutine = (DWORD *)((BYTE *)lpBase + 0x00085664); //$+0x1689bc
DWORD lpKdpTrap = (DWORD)lpBase + 0x001961f8;
DWORD lpKdpStub = (DWORD)lpBase + 0x00020d7c;
#endif
/*
$debugpointKdDebuggerEnabled @$t0+0x0007c741
$debugpointKdDebuggerNotPresent @$t0+0x0007c740;
$debugpointKdEnteredDebugger r @$t0+0x0007c744;
$debugpointKdPitchDebugger @$t0+0x000761fc
$debugpointKdpStub @$t0+0x0002bdbf
$debugpointKdpTrap @$t0+0x001a8bbf
$debugpointKiDebugRoutine @$t0+0x00083184
*/
KdPrint(("BASE:0x%08X", lpBase));
//$+0x127ce7
KdPrint(("lpKdPitchDebugger[0x%08X]:%d\n", lpKdPitchDebugger, *lpKdPitchDebugger));
KdPrint(("lpKdDebuggerEnabled[0x%08X]:%d\n", lpKdDebuggerEnabled, *lpKdDebuggerEnabled));
KdPrint(("lpKiDebugRoutine[0x%08X],0x%08X\n", lpKiDebugRoutine, *lpKiDebugRoutine));
KdPrint(("lpKdpTrap[0x%08X]\n", lpKdpTrap));
KdPrint(("lpKdpStub[0x%08X]\n", lpKdpStub));
if ( bSetDebug )
{
PageProtectOff();
*lpKdPitchDebugger = 0 ;
*lpKdDebuggerEnabled = 1 ;
*lpKiDebugRoutine = lpKdpTrap ;
PageProtectOn();
}
else
{
PageProtectOff();
*lpKdPitchDebugger =1 ;
*lpKdDebuggerEnabled = 0;
*lpKiDebugRoutine = lpKdpStub;
PageProtectOn();
}
}
VOID NotifyRoutine(IN PUNICODE_STRING FullImageName,
IN HANDLE ProcessId, // where image is mapped
IN PIMAGE_INFO ImageInfo)
{
if (strEnd(FullImageName->Buffer,L"EagleXNt.sys"))
{
KdPrint(("驱动加载:EagleXNt.sys:ImageBase:%08x \t size: %06x\n",ImageInfo->ImageBase,ImageInfo->ImageSize));
SetSystemDebug((PVOID)0x804d8000 , TRUE);
//PassAntiDebug((ULONG)ImageInfo->ImageBase); //写入各种nop
}
}
NTSTATUS DispatchDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status =STATUS_SUCCESS;
PIO_STACK_LOCATION irpSp;
//PLDR_DATA_TABLE_ENTRY lpNtoskrnl;
UNICODE_STRING destName = {0} ;
BOOL bDebug=FALSE;
KdPrint(("DispatchDeviceControl Entry\n"));
irpSp = IoGetCurrentIrpStackLocation(Irp);
switch(irpSp->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_CODE_SETSYSTEMDEBUG:
case IOCTL_CODE_UNSETSYSTEMDEBUG:
{
#ifdef ntoskrnl
RtlInitUnicodeString(&destName, L"ntoskrnl.exe");
#else
RtlInitUnicodeString(&destName, L"ntkrpamp.exe");
#endif
//lpNtoskrnl = FindModule(pdoGlobalDrvObj, &destName) ;
#define lpNtoskrnl 0x804d8000
KdPrint(("%wZ\n",lpNtoskrnl));
if ( lpNtoskrnl )
{
if ( IOCTL_CODE_SETSYSTEMDEBUG == irpSp->Parameters.DeviceIoControl.IoControlCode )
bDebug = TRUE ;
SetSystemDebug((PVOID)lpNtoskrnl , bDebug ) ;
Irp->IoStatus.Status =STATUS_SUCCESS;
KdPrint(("lpNtoskrnl in :%wZ\n", lpNtoskrnl)) ;
}
else
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}
break;
default:
KdPrint(("==== No ====\n")) ;
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
break;
}
status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
KdPrint(("DispatchDeviceControl Exit\n")) ;
return status;
}
NTSTATUS DispatchCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status = STATUS_SUCCESS;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
VOID DriverUnload(
IN PDRIVER_OBJECT DriverObject
)
{
PDEVICE_OBJECT pdoNextDeviceObj = pdoGlobalDrvObj->DeviceObject;
PsRemoveLoadImageNotifyRoutine(NotifyRoutine);
IoDeleteSymbolicLink(&usSymlinkName);
// Delete all the device objects
while(pdoNextDeviceObj)
{
PDEVICE_OBJECT pdoThisDeviceObj = pdoNextDeviceObj;
pdoNextDeviceObj = pdoThisDeviceObj->NextDevice;
IoDeleteDevice(pdoThisDeviceObj);
}
}
NTSTATUS DriverEntry(
IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
PDEVICE_OBJECT pdoDeviceObj = 0;
NTSTATUS status=STATUS_UNSUCCESSFUL;
//这个不是定义,如果把变量放在这个后面定义就出现语法错位,原来C89要求很严格的啊
pdoGlobalDrvObj = DriverObject;
KdPrint(("==== DriverEntry ====\n"));
KdPrint(("IOCTL_CODE_SETSYSTEMDEBUG:%X\n",IOCTL_CODE_SETSYSTEMDEBUG));
KdPrint(("IOCTL_CODE_UNSETSYSTEMDEBUG:%X\n",IOCTL_CODE_UNSETSYSTEMDEBUG));
RtlInitUnicodeString(&usDeviceName, L"\\Device\\ResumeDebug");
RtlInitUnicodeString(&usSymlinkName, L"\\DosDevices\\ResumeDebug");
// Create the device object.
if(!NT_SUCCESS(status = IoCreateDevice(
DriverObject,
0,
&usDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&pdoDeviceObj
)))
{
// Bail out (implicitly forces the driver to unload).
return status;
};
// Now create the respective symbolic link object
if(!NT_SUCCESS(status = IoCreateSymbolicLink(
&usSymlinkName,
&usDeviceName
)))
{
IoDeleteDevice(pdoDeviceObj);
return status;
}
// NOTE: You need not provide your own implementation for any major function that
// you do not want to handle. I have seen code using DDKWizard that left the
// *empty* dispatch routines intact. This is not necessary at all!
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
DriverObject->DriverUnload = DriverUnload;
PsSetLoadImageNotifyRoutine(NotifyRoutine);
return STATUS_SUCCESS;
}
[课程]Linux pwn 探索篇!