首页
社区
课程
招聘
[求助]通过 DeviceIoControl 调用NtReadVirtualMemory 不成功
发表于: 2011-8-2 06:19 8285

[求助]通过 DeviceIoControl 调用NtReadVirtualMemory 不成功

2011-8-2 06:19
8285
为了实现ReadProcessMemory,写了个驱动来实现NtReadVirtualMemory功能,

ReadProcessMemory有ReadBuf(存放读取的数据)参数,该参数在R3下分配的,地址空间是R3,

通过DeviceIoControl传递给自己写的驱动的时候,用我自己写的MyNtReadVirtualMemory可以

正常工作,但是因为自己写的MyNtReadVirtualMemory比较简单,功能不完善,所以想用系统的

NtReadVirtualProcess,这个函数的地址我是通过SSDT Table获取的,地址应该没有错,但是我把

同样的参数传递给这个函数的时候,怎么读不了数据,也没有报什么错误!

下面是准备直接调用系统的NtReadVirtualMemory代码:
NTSTATUS MyNtReadVirtualMemory(
                           IN HANDLE ProcessHandle,
               IN PVOID BaseAddress,
               OUT PVOID Buffer,
               IN ULONG NumberOfBytesToRead,
                           OUT PULONG NumberOfBytesReaded)
{

        NTSTATUS   status=STATUS_SUCCESS;

        NTREADVIRTUALMEMORY fnNtReadVirtualMemory=(NTREADVIRTUALMEMORY)g_NtReadVirtualMemory;
        status=fnNtReadVirtualMemory(ProcessHandle,
                                                             BaseAddress,
                                                             Buffer,
                                                             NumberOfBytesToRead,
                                                                 NumberOfBytesReaded);               

        return status;
  
}

g_NtReadVirtualMemory 是我预先保存起来的函数地址.MyNtReadVirtualMemory用在

SSDT Hook时也是正确的,就是 通过DeviceIoControl 的CODE_ITL代码来执行时,读不到数据,有的时候要蓝屏:

        ReturnStatus=MyReadVirtualMemory(ReadHandle,ReadBaseAddr,ReadBuffer,ReadSize,&ReadedSize);       

这里的ReadBuffer是传入的R3下分配的Buff,用我自己写实现的MyReadVirtualMemory2又是正确的,有高人帮我分析下吗?

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
2
NTSYSAPI
NTSTATUS
NTAPI
NtReadVirtualMemory(
        IN HANDLE ProcessHandle,
        IN PVOID BaseAddress,
        OUT PVOID Buffer,
        IN ULONG BufferLength,
        OUT PULONG ReturnLength OPTIONAL
        );
Buffer 这个r3与r0通信 非常容易出错,传入地址与传入数据与大小是否正确?读不出数据,你是否打开句柄,获取的NtReadVirtualMemory函数地址是否正确?。
你为什么这样写函数,是否有HOOK,没有HOOK的话,直接调用就行了,论坛上有模拟ReadVirtualMemory
2011-8-2 07:47
0
雪    币: 235
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
NtReadVirtualMemory 这个函数的地址是对的
MyReadVirtualMemory 用在SSDT Hook里都是正确的,说明这个函数本身应该没什么问题
用在DeviceIoControl 通讯模式里就不行
但是我自己实现的MyReadVirtualMemory2 用在DeviceIoControl 里是可以的,参数和NtReadVirtualMemory一样,说明我传递的参数没问题
不知道两种调用模式的参数是不是转换过的

我们通常调用NtReadVirtualMemory 的路径:ReadProcessMemory->ZwReadVirtualMemory->NtReadVirtualMemory-> KiFastSystemCall(SSDT)->NtReadVirtualMemory

我现在想实现
ReadProcessMemory->DeviceIoControl->NtReadVirtualMemory

该怎么做呢?
2011-8-2 07:57
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
4
你要绕过 NtReadVirtualMemory 的inline hook ?
如果你要自己实现ReadVirtualMemory,网上有ReadVirtualMemory模拟代码
NTSTATUS IoReadMemory(
        IN HANDLE hProcess,
        IN PVOID BaseAddress,
        OUT PVOID Pbuff,
        IN ULONG BufferSize,
        OUT LPDWORD byReadSize
        )
{
        PEPROCESS EProcess;

        KAPC_STATE ApcState;

        PVOID readbuffer=NULL;

        NTSTATUS status;

        __asm
        {
                push NULL
                lea eax, EProcess
                push eax
                push KernelMode
                push NULL
                push PROCESS_VM_WRITE|PROCESS_VM_READ
                push hProcess
                call ObReferenceObjectByHandle
                mov status,eax
        }

        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;
}
2011-8-2 08:03
0
雪    币: 235
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我自己实现的,和你这个发出来的差不多,我用DeviceIoControl调用的,就是这个
但是为什么调用系统的不行呢,读不出东西来
因为还有很多函数,如果每个都自己实现,要累死人的, 如果能用系统的,那不是方便很多?
主要是想达到这个目的,这个函数用来测试的,居然不行,找不出问题,我已经测试了3,4天了
2011-8-2 08:15
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
6
这个倒是没试验过,读不到数据,有的时候要蓝屏,我自己认为还是数据传输问题,我当时用易语言与驱动通信在数据传输上费过很多时间,无数的蓝屏。
2011-8-2 08:27
0
游客
登录 | 注册 方可回帖
返回
//