流浪汉17 2023-02-26 17:59 采纳率: 75%
浏览 97
已结题

如何修改下面的驱动读整数的代码,读取这种字符串并用printf打印

我会用这些代码读整数 单双浮点,这种字符串就把我整不明白了

img


NTSTATUS KReadProcessMemory(IN PEPROCESS Process, IN PVOID Address, IN UINT32 Length, IN OUT PVOID Buffer)
{
    NTSTATUS ret_status = 0;
    KAPC_STATE apc_state;
    RtlZeroMemory(&apc_state, sizeof(KAPC_STATE));
    
    PVOID tmpBuf_Kernel = ExAllocatePool(NonPagedPool, Length);


    KeStackAttachProcess((PVOID)Process, &apc_state);

    
    BOOLEAN dwRet = MmIsAddressValid(Address);

    if (dwRet)
    {
        
        KdPrint(("yjx[sys64] RtlCopyMemory(Address=%p, Buffer=%p, Length=%d);\r\n", Address, Buffer, Length));
        BOOLEAN isOk = IsOkWritePtr(Address);
        
        if (isOk)
        {
            __try
            {
                //可以访问
                RtlCopyMemory(tmpBuf_Kernel, Address, Length); // c/c++ memcpy 
                ret_status = STATUS_SUCCESS;//表示复制成功
            }
            __except (1)
            {
                ret_status = STATUS_UNSUCCESSFUL; //不可访问
                __debugbreak();
                KdPrint(("yjx:sys64:Error line=%d\n", __LINE__));
            }
        }
        else
        {
            ret_status = STATUS_UNSUCCESSFUL; //不可访问
        }

    }
    else
    {
        KdPrint(("yjx:sys64:Error line=%d\n", __LINE__));
        ret_status = STATUS_UNSUCCESSFUL;
    }
    
    KeUnstackDetachProcess(&apc_state);
    
    RtlCopyMemory(Buffer, tmpBuf_Kernel, Length);
    
    ExFreePool(tmpBuf_Kernel);
    return ret_status;
}
//dwPid为目标进程id
//lpBaseAddress 目标进程地址

//lpBuffer 当前进程地址 1
//内核内存地址 当前进程地址 2
NTSTATUS ReadProcessMemoryForPid(UINT32 dwPid, PVOID pBase, PVOID lpBuffer, UINT32 nSize)
{
    NTSTATUS retstatus = STATUS_SUCCESS;
    //根据pid获取PEPROCESS OpenProcess
    PEPROCESS Seleted_pEPROCESS = NULL;
    KdPrint(("yjx:sys64  pid=%d pBase=%p  %s 行号=%d\n", dwPid, pBase, __FUNCDNAME__, __LINE__));

    retstatus = PsLookupProcessByProcessId((PVOID)(UINT_PTR)(dwPid), &Seleted_pEPROCESS);
    if (retstatus == STATUS_SUCCESS)
    {

        retstatus = KReadProcessMemory(Seleted_pEPROCESS, (PVOID)pBase, nSize, lpBuffer);
        ObDereferenceObject(Seleted_pEPROCESS);
        //return retstatus;
    }
    else
    {
        KdPrint(("yjx sys64 PsLookupProcessByProcessId Fail...%s line=%d\n", __FUNCDNAME__, __LINE__));
        //return STATUS_UNSUCCESSFUL;
    }

    return retstatus;// STATUS_UNSUCCESSFUL;

}
void IRP_IO_通过PID读内存1(PIRP pirp)
{
    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(pirp); //获取应用层传来的参数
    UINT64* 缓冲区 = (UINT64*)(pirp->AssociatedIrp.SystemBuffer);
    KdPrint(("yjx:%s 行号%d\n", __FUNCDNAME__, __LINE__));
    if (缓冲区)
    {
        //
        //int*p = (int*)缓冲区;
        UINT32 PID = (UINT32)(UINT64)缓冲区[0]; //传入数据
        
        PVOID pBase = (PVOID)((UINT64)缓冲区[1] ); //传入数据
        //PVOID lpBuffer = (PVOID)(UINT64)缓冲区[2]; //传入数据
        UINT64 nSize = (UINT64)缓冲区[3]; //传入数据


        UINT32 ReadSize = ReadProcessMemoryForPid(PID, pBase, 缓冲区, nSize);

        ReadSize;
        pirp->IoStatus.Status = STATUS_SUCCESS;
        pirp->IoStatus.Information = nSize;//返回给DeviceIoControl中的 倒数第二个参数lpBytesReturned
        IoCompleteRequest(pirp, IO_NO_INCREMENT);//调用方已完成所有I/O请求处理操作 并且不增加优先级 
    }
    irpStack;
}

这是读64位整数的代码 怎么改成读unicode字符串
UINT64 PID读内存地址x64(INT pid, UINT_PTR 地址)
{


    DWORD dwRetSize = 0;//返回字节数


    ULONG64 tmp = 0;//存放读取的数据

    UINT64 输入缓冲区[4] = { pid,地址,0,8 };


    DeviceIoControl(
        DeviceHandle,//CreateFile打开驱动设备 返回的句柄
        通过PID读整数1,//控制码 CTL_CODE

        &输入缓冲区,//输入缓冲区指针
        8 * 4,//输入缓冲区大小

        &tmp,//返回缓冲区
        sizeof(tmp),//返回缓冲区大小

        &dwRetSize, //返回字节数
        NULL);

    return tmp;

}
  • 写回答

6条回答 默认 最新

  • 这我哪会啊 2023-02-26 18:11
    关注
    
    #include <string>
    #include <vector>
    
    UINT64 读取Unicode字符串(INT pid, UINT_PTR 地址, std::wstring& 结果) {
        DWORD dwRetSize = 0;
        UINT64 tmp = 0;
    
        // 输入缓冲区的第一个元素是PID,第二个元素是要读取的地址,
        // 第三个元素是要读取的字符串的长度(以字节为单位),第四个元素是0,
        // 这样驱动程序就知道要读取的是Unicode字符串。
        std::vector<UINT64> 输入缓冲区 = { pid, 地址, 0, 0 };
    
        // 返回缓冲区是一个用来存放字符串的缓冲区,大小为4096个字符。
        std::vector<wchar_t> 返回缓冲区(4096);
    
        // 调用DeviceIoControl函数来读取Unicode字符串。
        BOOL bResult = DeviceIoControl(
            DeviceHandle,
            控制码,
            输入缓冲区.data(),
            sizeof(UINT64) * 输入缓冲区.size(),
            返回缓冲区.data(),
            sizeof(wchar_t) * 返回缓冲区.size(),
            &dwRetSize,
            NULL
        );
    
        if (bResult && dwRetSize > 0) {
            // 如果读取成功,将结果保存到wstring对象中,并返回字符串的长度。
            结果.assign(返回缓冲区.data(), dwRetSize / sizeof(wchar_t));
            return 结果.size();
        } else {
            // 如果读取失败,返回0。
            return 0;
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 3月6日
  • 已采纳回答 2月26日
  • 赞助了问题酬金20元 2月26日
  • 修改了问题 2月26日
  • 展开全部

悬赏问题

  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)