首页
社区
课程
招聘
[旧帖] [求助]多核cpu为什么读写内存老是蓝屏,该怎么处理啊, 0.00雪花
发表于: 2014-6-19 16:43 3359

[旧帖] [求助]多核cpu为什么读写内存老是蓝屏,该怎么处理啊, 0.00雪花

2014-6-19 16:43
3359
在论坛看到别的代码,写了下,但是内存保护的时候为什么老是蓝屏,我用单核虚拟机通过(单机的是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;
}

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
服了 没DUMP怎么看?
2014-6-19 19:50
0
雪    币: 287
活跃值: (343)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
用内核快照吗,呵呵,我自己解决啦,有个硬编码地址错误不能读导致的蓝屏,
2014-6-19 20:05
0
雪    币: 44
活跃值: (186)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
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
    }
}

我想说LZ你是不是从哪里抄来的源码呀,能不蓝吗不蓝就不正常了
2014-6-19 20:05
0
雪    币: 287
活跃值: (343)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
是啊,论坛里面抄的,为什么我把这两句代码直接注释掉就不蓝了一切正常,加上反而蓝呢,内存保护机制到底是啥样的,我们写在dipatich函数里面的代码是DISPATCH中断级吗,还有那我们平时写的DPC定时器和系统回调的代码在哪个中断级,哪个中断级才可以操作cr3寄存器不蓝屏呢,非常感谢
2014-6-19 21:43
0
雪    币: 287
活跃值: (343)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
8dcc637 fa              cli
f8dcc638 8b45f4          mov     eax,dword ptr [ebp-0Ch]
f8dcc63b c60001          mov     byte ptr [eax],1
f8dcc63e 8b4dfc          mov     ecx,dword ptr [ebp-4]
f8dcc641 c60100          mov     byte ptr [ecx],0
f8dcc644 8b55f0          mov     edx,dword ptr [ebp-10h]
f8dcc647 8b45ec          mov     eax,dword ptr [ebp-14h]
f8dcc64a 8902            mov     dword ptr [edx],eax
f8dcc64c fb              sti
f8dcc64d 6834c5dcf8      push    offset ResumeDebug!SetSystemDebug+0xffffffff`ffffffe4 (f8dcc534)
f8dcc652 e8b3030000      call    ResumeDebug!DbgPrint (f8dcca0a)
搞了半天什么还是蓝呢,关中断的情况下读写内核内存,弄不好就蓝了,怎么解决啊,
上传的附件:
2014-6-20 16:03
0
雪    币: 287
活跃值: (343)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
有时候蓝,有时候又不蓝,蓝的位置是读取数据的那一个指令应该跟中断级或者内存保护有关,我真是个大菜鸟
2014-6-20 16:05
0
雪    币: 287
活跃值: (343)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
单步调试的情况下改这个KiDebugRoutine的值的时候就蓝啦,不单步的时候就不蓝,原来是这样啊,单步的情况下单步异常发出了没有相应的处理程序(KdTrap)函数啦,原来是这样,我如果把KdStub转向KdTrap执行就没事啦吗
2014-6-20 17:05
0
游客
登录 | 注册 方可回帖
返回
//