首页
社区
课程
招聘
[原创]用驱动实现自己的 ZwOpenProcess ZwReadVirtualMemory ZwWriteVirtualMemory[菜鸟学习笔记]
发表于: 2009-3-3 22:12 30336

[原创]用驱动实现自己的 ZwOpenProcess ZwReadVirtualMemory ZwWriteVirtualMemory[菜鸟学习笔记]

2009-3-3 22:12
30336

/*

  jhxxs.C

  Author: <your name>
  Last Updated: 2006-03-23

  This framework is generated by EasySYS 0.3.0
  This template file is copying from QuickSYS 0.3.0 written by Chunhua Liu

*/

#include "dbghelp.h"
#include "jhxxs.h"
#include <stdio.h>

#include <ntdef.h>
#include <ntstatus.h>
#include <ntddk.h>
//
// A structure representing the instance information associated with
// a particular device
//

typedef struct _DEVICE_EXTENSION
{
    ULONG  StateVariable;

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

typedef struct _KAPC_STATE{
        LIST_ENTRY        ApcListHead[2];
        PEPROCESS        Process;
        UCHAR                KernelApcInProgress;
        UCHAR                KernelApcPending;
        UCHAR                UserApcPending;
}KAPC_STATE,*PKAPC_STATE;

NTKERNELAPI void KeStackAttachProcess(IN PEPROCESS Process, OUT PKAPC_STATE ApcState);

NTKERNELAPI void KeUnstackDetachProcess(IN PKAPC_STATE ApcState);

NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(IN ULONG ulProcId,OUT PEPROCESS * pEProcess);

NTKERNELAPI NTSTATUS ObOpenObjectByPointer(
    IN PVOID Object,                                            
    IN ULONG HandleAttributes,                                 
    IN PACCESS_STATE PassedAccessState OPTIONAL,               
    IN ACCESS_MASK DesiredAccess OPTIONAL,                     
    IN POBJECT_TYPE ObjectType OPTIONAL,                        
    IN KPROCESSOR_MODE AccessMode,                              
    OUT PHANDLE Handle                                          
        );
//
// Device driver routine declarations.
//

NTSTATUS
DriverEntry(
        IN PDRIVER_OBJECT                DriverObject,
        IN PUNICODE_STRING                RegistryPath
        );

NTSTATUS
JhxxsDispatchCreate(
        IN PDEVICE_OBJECT                DeviceObject,
        IN PIRP                                        Irp
        );

NTSTATUS
JhxxsDispatchClose(
        IN PDEVICE_OBJECT                DeviceObject,
        IN PIRP                                        Irp
        );

NTSTATUS
JhxxsDispatchDeviceControl(
        IN PDEVICE_OBJECT                DeviceObject,
        IN PIRP                                        Irp
        );

VOID
JhxxsUnload(
        IN PDRIVER_OBJECT                DriverObject
        );

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, JhxxsDispatchCreate)
#pragma alloc_text(PAGE, JhxxsDispatchClose)
#pragma alloc_text(PAGE, JhxxsDispatchDeviceControl)
#pragma alloc_text(PAGE, JhxxsUnload)
#endif // ALLOC_PRAGMA

NTSTATUS
MyWriteMemory(IN HANDLE hProcess,OUT PVOID BaseAddress,IN PVOID Pbuff,IN ULONG BufferSize)
{
PEPROCESS EProcess;
KAPC_STATE ApcState;
PVOID writebuffer=NULL;
NTSTATUS status;

status = ObReferenceObjectByHandle(
                  hProcess,
                  PROCESS_VM_WRITE|PROCESS_VM_READ,
                  NULL,
                  KernelMode,
                  &EProcess,
                  NULL
                  );
                  
if(!NT_SUCCESS(status))
{
ObDereferenceObject(EProcess);
return STATUS_UNSUCCESSFUL;
}
writebuffer = ExAllocatePoolWithTag (NonPagedPool, BufferSize, 'Sys');

if(writebuffer==NULL)
{
ObDereferenceObject(EProcess);
ExFreePool (writebuffer);
return STATUS_UNSUCCESSFUL;
}
*(ULONG*)writebuffer=(ULONG)0x1;

if (MmIsAddressValid(Pbuff))
{
   __try
   {
   ProbeForRead ((CONST PVOID)Pbuff, BufferSize, sizeof(CHAR));
   RtlCopyMemory (writebuffer, Pbuff, BufferSize);
   }
   __except(EXCEPTION_EXECUTE_HANDLER)
   {
   status = STATUS_UNSUCCESSFUL;
   }
}
else
{
   status = STATUS_UNSUCCESSFUL;
}

if (NT_SUCCESS(status))
{
  KeStackAttachProcess (EProcess, &ApcState);
  if (MmIsAddressValid(BaseAddress))
  {
   __try
   {
   ProbeForWrite ((CONST PVOID)BaseAddress, BufferSize, sizeof(CHAR));
   RtlCopyMemory (BaseAddress,writebuffer, BufferSize);
   }
   __except(EXCEPTION_EXECUTE_HANDLER)
   {
   status = STATUS_UNSUCCESSFUL;
   }
  }
  else
  {
   status = STATUS_UNSUCCESSFUL;
  }
  KeUnstackDetachProcess (&ApcState);
}

ObDereferenceObject(EProcess);
ExFreePool (writebuffer);
return status;
}

NTSTATUS
MyReadMemory(IN HANDLE hProcess,IN PVOID BaseAddress,OUT PVOID Pbuff,IN ULONG BufferSize)
{
PEPROCESS EProcess;
KAPC_STATE ApcState;
PVOID readbuffer=NULL;
NTSTATUS status;

status = ObReferenceObjectByHandle(
                  hProcess,
                  PROCESS_VM_WRITE|PROCESS_VM_READ,
                  NULL,
                  KernelMode,
                  &EProcess,
                  NULL
                  );

if(!NT_SUCCESS(status))
{
ObDereferenceObject(EProcess);
return STATUS_UNSUCCESSFUL;
}

readbuffer = ExAllocatePoolWithTag (NonPagedPool, BufferSize, 'Sys');

if(readbuffer==NULL)
{
ObDereferenceObject(EProcess);
ExFreePool (readbuffer);
return STATUS_UNSUCCESSFUL;
}
*(ULONG*)readbuffer=(ULONG)0x1;

KeStackAttachProcess (EProcess, &ApcState);
if (MmIsAddressValid(BaseAddress))
{
   __try
   {
   ProbeForRead ((CONST PVOID)BaseAddress, BufferSize, sizeof(CHAR));
   RtlCopyMemory (readbuffer, BaseAddress, BufferSize);
   }
   __except(EXCEPTION_EXECUTE_HANDLER)
   {
   status = STATUS_UNSUCCESSFUL;
   }
}
else
{
  status = STATUS_UNSUCCESSFUL;
}
KeUnstackDetachProcess (&ApcState);

   if(NT_SUCCESS(status))
   {
        if (MmIsAddressValid(Pbuff))
        {
         __try
         {
         ProbeForWrite(Pbuff, BufferSize, sizeof(CHAR));
         RtlCopyMemory (Pbuff, readbuffer, BufferSize);
         }
         __except(EXCEPTION_EXECUTE_HANDLER)
         {
         status = STATUS_UNSUCCESSFUL;
         }
        }
        else
        {
        status = STATUS_UNSUCCESSFUL;
        }
   }

ObDereferenceObject(EProcess);
ExFreePool (readbuffer);
return status;
}

NTSTATUS MyOpenProcess(ULONG PID, PHANDLE pHandle)
{
  NTSTATUS  status;
  PEPROCESS  EProcess = NULL;
  HANDLE    handle = NULL;
  UNICODE_STRING y;
  PULONG    PsProcessType;

  status = PsLookupProcessByProcessId(PID, &EProcess);
  if (NT_SUCCESS(status))
  {
    handle = 0;
    RtlInitUnicodeString(&y, L"PsProcessType");
    PsProcessType = MmGetSystemRoutineAddress(&y);
    if (PsProcessType)
    {
      status = ObOpenObjectByPointer(EProcess, 0, 0, PROCESS_ALL_ACCESS, (PVOID)*PsProcessType, UserMode, &handle);
      if (NT_SUCCESS(status))
      {
                *pHandle = handle;
      }
    }
    ObfDereferenceObject(EProcess);
  }
  return status;
}

NTSTATUS
DriverEntry(
        IN PDRIVER_OBJECT                DriverObject,
        IN PUNICODE_STRING                RegistryPath
        )
{
        NTSTATUS                        status = STATUS_SUCCESS;   
    UNICODE_STRING                ntDeviceName;
        UNICODE_STRING                dosDeviceName;
    PDEVICE_EXTENSION        deviceExtension;
        PDEVICE_OBJECT                deviceObject = NULL;
        BOOLEAN                                fSymbolicLink = FALSE;

        KdBreakPoint();
        RtlInitUnicodeString(&ntDeviceName, JHXXS_DEVICE_NAME_W);
    status = IoCreateDevice(
                DriverObject,
                sizeof(DEVICE_EXTENSION),
                &ntDeviceName,
                FILE_DEVICE_JHXXS,
                0,
                TRUE,
                &deviceObject
                );

    if (!NT_SUCCESS(status))
        {
                goto __failed;
        }

        deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
        RtlInitUnicodeString(&dosDeviceName, JHXXS_DOS_DEVICE_NAME_W);
        status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);
    if (!NT_SUCCESS(status))
        {
                goto __failed;
    }

        fSymbolicLink = TRUE;

    DriverObject->MajorFunction[IRP_MJ_CREATE]         = JhxxsDispatchCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]          = JhxxsDispatchClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = JhxxsDispatchDeviceControl;
    DriverObject->DriverUnload                         = JhxxsUnload;

    if (NT_SUCCESS(status))
            return status;

__failed:
        if (fSymbolicLink)
                IoDeleteSymbolicLink(&dosDeviceName);
        if (deviceObject)
                IoDeleteDevice(deviceObject);
        return status;
}

NTSTATUS
JhxxsDispatchCreate(
        IN PDEVICE_OBJECT                DeviceObject,
        IN PIRP                                        Irp
        )
{
        NTSTATUS status = STATUS_SUCCESS;

        Irp->IoStatus.Information = 0;
    Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return status;
}

NTSTATUS
JhxxsDispatchClose(
        IN PDEVICE_OBJECT                DeviceObject,
        IN PIRP                                        Irp
        )
{
        NTSTATUS status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return status;
}

NTSTATUS
JhxxsDispatchDeviceControl(
        IN PDEVICE_OBJECT                DeviceObject,
        IN PIRP                                        Irp
        )
{
        NTSTATUS                        status = STATUS_SUCCESS;
    PIO_STACK_LOCATION        irpStack;
    PDEVICE_EXTENSION        deviceExtension;
        PVOID                                ioBuf;
    ULONG                                inBufLength, outBufLength;
        ULONG                                ioControlCode;

        UCHAR               *buff =0;
        ULONG               OutByteCount =0;

        HANDLE              Writehandel;
        PVOID               WriteDstAddr;
        PVOID               WriteSrcAddr;
        ULONG               WriteSize;
        NTSTATUS            WriteReturn;

        HANDLE              Readhandel;
        PVOID               ReadBaseAddr;
        PVOID               ReadBuffer;
        ULONG               ReadSize;
        NTSTATUS            ReadReturn;

        ULONG               OpenPid;
        PHANDLE             PProcessHandle;
        NTSTATUS            OpenReturn;

    irpStack = IoGetCurrentIrpStackLocation(Irp);
    deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
        Irp->IoStatus.Information = 0;
        ioBuf = Irp->AssociatedIrp.SystemBuffer;
        inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

    switch (ioControlCode)
        {
        case  0X0022E004:
                {
                 buff=(UCHAR *)Irp->AssociatedIrp.SystemBuffer ;
                 memmove(&Writehandel,&buff[0],4);
                 memmove(&WriteDstAddr,&buff[4],4);
                 memmove(&WriteSrcAddr,&buff[8],4);
                 memmove(&WriteSize,&buff[12],4);

                 WriteReturn=MyWriteMemory(Writehandel,WriteDstAddr,WriteSrcAddr,WriteSize);
                 memmove(Irp->AssociatedIrp.SystemBuffer,&WriteReturn,4);
                 OutByteCount=4;
                 break;
                }

        case  0X0022E008:
                {
                 buff=(UCHAR *)Irp->AssociatedIrp.SystemBuffer ;
                 memmove(&Readhandel,&buff[0],4);
                 memmove(&ReadBaseAddr,&buff[4],4);
                 memmove(&ReadBuffer,&buff[8],4);
                 memmove(&ReadSize,&buff[12],4);

                 ReadReturn=MyReadMemory(Readhandel,ReadBaseAddr,ReadBuffer,ReadSize);
                 memmove(&buff[0],&ReadReturn,4);
                 OutByteCount=4;
                 break;
                }

        case  0X0022E000:
                {
                 OpenReturn = MyOpenProcess(*(PULONG)ioBuf,ioBuf);
                 buff=(UCHAR *)Irp->AssociatedIrp.SystemBuffer ;
                 memmove(&buff[4],&OpenReturn,4);
                 OutByteCount=8;
                 break;
                }
               
        case IOCTL_JHXXS_HELLO:
                {
            break;
                }

    default:
        status = STATUS_INVALID_PARAMETER;
                break;
        }
        Irp->IoStatus.Status = status;
        Irp->IoStatus.Information = OutByteCount;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}

VOID
JhxxsUnload(
        IN PDRIVER_OBJECT                DriverObject
        )
{
    UNICODE_STRING dosDeviceName;
        RtlInitUnicodeString(&dosDeviceName, JHXXS_DOS_DEVICE_NAME_W);
    IoDeleteSymbolicLink(&dosDeviceName);
        IoDeleteDevice(DriverObject->DeviceObject);
}

完整可编译代码如下[驱动由 BC++编写 WINDDK编译]


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (35)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
学习......谢谢分享
2009-3-3 22:29
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
3
KeAttach不和谐啊不和谐,被NP日过你就切不过去了,自己切换cr3才比较有看头。不过还是向楼主学习~
2009-3-4 00:05
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
4
MyReadMemory
好挫的函数
2009-3-4 00:15
0
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
5
在MJ等牛的BS中成长
2009-3-4 02:33
0
雪    币: 214
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
FuckReadMemory
就不挫了
2009-3-4 05:01
0
雪    币: 231
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdk
7
很久才见到一次这个头像。
3年前注册的时候就见到这个头像了

人生当真如梦
2009-3-4 05:40
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
8
这些函数几年前就有源码了...
比如去年的金山比赛的答案....
2009-3-4 08:25
0
雪    币: 242
活跃值: (14)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
看我头像对号入座
2009-3-4 13:24
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
10
说一句不针对任何人的话"煞笔"
欢迎对号入座
2009-3-4 14:26
0
雪    币: 242
活跃值: (14)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
*******************
2009-3-4 14:40
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
12
好笑....
2009-3-4 14:45
0
雪    币: 193
活跃值: (26)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
13
继续吧!继续吧!
2009-3-4 15:19
0
雪    币: 231
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
很黄很暴力,借阅一天
2009-3-5 08:51
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX
15
我看到了 KeStackAttachProcess
2009-3-5 09:14
0
雪    币: 231
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
KdBreakPoint();
没有此函数
2009-3-9 10:28
0
雪    币: 231
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
知道了
2009-3-9 10:33
0
雪    币: 222
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
18
正需要,谢谢分享
2009-3-9 11:50
0
雪    币: 376
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
原来蓝屏是debug的缘故。。。
2009-4-5 11:04
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
20
看了代码  还是有几个地方不明白   

KeStackAttachProcess 目标
对其他进程低2G虚拟空间进行写入  是不是需要指定权限? 否则就会失败?

小弟测试过直接KeStackAttachProcess目标   可以读出目标低2G内存   
但不能进行写入 一写就蓝了 不知是何原因   

status = ObReferenceObjectByHandle(
                  hProcess,
                  PROCESS_VM_WRITE|PROCESS_VM_READ,
                  NULL,
                  KernelMode,
                  &EProcess,
                  NULL
                  );

这句有点不大懂   
如果不指定权限 直接KeStackAttachProcess目标EPROCESS 进行写操作  可以么?
2009-7-14 22:10
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
21
这句是用来获取相应进程句柄对应的进程对象的指针,也就是指向EPROCESS结构的指针,这样才能Attach。
2009-7-15 00:25
0
雪    币: 1505
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
22
没啥用呀 不过也支持下.
要写就尽量完全不调用系统调用 否则还不如直接copy过来一份内存,修复下hook自己用爽.嘎嘎
2009-7-15 01:42
0
雪    币: 129
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
因为你说的分页内存存在的内存属性,不可读不可写等。。

如果不可写你直接在R0写会导致蓝屏的,所以去一下内存保护再写就没问题了
2009-7-15 10:40
0
雪    币: 129
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
哈哈,bujin888好久没见了,原来在弄这玩意...

既然写到这了,应该顺便带上一个自己实现OpenThread嘛,反正和打开进程没多大区别了

顺便请教下   :

完整可编译代码如下[驱动由 BC++编写 WINDDK编译]

这个BC++是什么语言呀?没听过,还是打错,是VC++呢?

2009-7-15 10:50
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
顶礼膜拜六月大牛 BC++  就是 宝蓝C++

2009-7-17 09:31
0
游客
登录 | 注册 方可回帖
返回
//