首页
社区
课程
招聘
[旧帖] 32位应用层与64位驱动传递参数时数据错位 0.00雪花
发表于: 2015-4-22 10:14 4220

[旧帖] 32位应用层与64位驱动传递参数时数据错位 0.00雪花

2015-4-22 10:14
4220
32位应用层与64位驱动传递参数时数据错位

问题:
在64位win7系统下,运行32位应用程序,该应用程序需要调用64位驱动进行操作,64位驱动为minifilter型驱动,
当32位应用层传递如下结构体给64位驱动时,发生数据错位。
#pragma pack(1)
typedef enum _DATA_TYPE
{
        //app send to kernel
        DT_CREATE_SANDBOX = 1,
        DT_QUERY_PID,
}DATA_TYPE, *PDATA_TYPE;

typedef struct _COMMUNICATION_DATA
{
        DATA_TYPE DataType;
        union
        {
                struct
                {
                        ULONG_PTR ulSandboxId;
                }CreateSandbox;
                struct
                {
                        ULONG_PTR ulSandboxId;
                        HANDLE          ulPid;
                }AddSandboxPid;
        }DATA;
}COMMUNICATION_DATA, *PCOMMUNICATION_DATA;
#pragma pack()

应用层代码:
DWORD GetSandIdByPid(DWORD dwPid)
{
        char szPrint[200];
        if (this->m_CommunicationPort != INVALID_HANDLE_VALUE)
        {
                COMMUNICATION_DATA Data;
                DWORD dwReturn = 0;

                ZeroMemory(&Data, sizeof(Data));
                Data.DataType = DT_QUERY_PID;

                Data.DATA.QueryPid.ulSandboxId = 0;
                Data.DATA.QueryPid.ulPid = (HANDLE)(DWORD_PTR)dwPid;

sprintf_s(szPrint, sizeof(szPrint), "Data addr=[%x] DataType addr=[%x] sizeof(DataType)=[%d] ulSandboxId addr=[%x] sizeof(ulSandboxId)=[%d] ulPid addr=[%x] sizeof(ulPid)=[%d] dwPid=[%d]\n", &Data, &(Data.DataType), sizeof(Data.DataType), &(Data.DATA.QueryPid.ulSandboxId), sizeof(Data.DATA.QueryPid.ulSandboxId), &(Data.DATA.QueryPid.ulPid), sizeof(Data.DATA.QueryPid.ulPid), dwPid);
OutputDebugStringA(szPrint);
PUCHAR p1 = (PUCHAR)&Data;
for(int i=0; i<sizeof(COMMUNICATION_DATA); i++)
{
        sprintf_s(szPrint, sizeof(szPrint), "Data addr=[%x] p1 addr=[%x][%x]\r\n", &Data, p1, *p1);
        OutputDebugStringA(szPrint);
        p1++;
}

                if (::FilterSendMessage(m_CommunicationPort, &Data, sizeof(Data), &Data, sizeof(Data), &dwReturn) == S_OK && Data.DATA.QueryPid.ulSandboxId != 0)
                {
                        return Data.DATA.QueryPid.ulSandboxId;
                }
        }

        return 0;
}
应用层输出结果:
Data addr=[ecadcba0] DataType addr=[ecadcba0] sizeof(DataType)=[4] ulSandboxId addr=[ecadcba4] sizeof(ulSandboxId)=[4] ulPid addr=[ecadcba8] sizeof(ulPid)=[4] dwPid=[2108]
Data addr=[ecadcba0] p1 addr=[ecadcba0][2]
Data addr=[ecadcba0] p1 addr=[ecadcba1][0]
Data addr=[ecadcba0] p1 addr=[ecadcba2][0]
Data addr=[ecadcba0] p1 addr=[ecadcba3][0]
Data addr=[ecadcba0] p1 addr=[ecadcba4][0]
Data addr=[ecadcba0] p1 addr=[ecadcba5][0]
Data addr=[ecadcba0] p1 addr=[ecadcba6][0]
Data addr=[ecadcba0] p1 addr=[ecadcba7][0]
Data addr=[ecadcba0] p1 addr=[ecadcba8][3c]
Data addr=[ecadcba0] p1 addr=[ecadcba9][8]
Data addr=[ecadcba0] p1 addr=[ecadcbaa][0]
Data addr=[ecadcba0] p1 addr=[ecadcbab][0]

驱动层代码:
NTSTATUS MessageNotify(IN PVOID PortCookie, IN PVOID InputBuffer, IN ULONG InputBufferLength,
                                           OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, OUT PULONG ReturnOutputBufferLength)
{
        PPROCESS_INFO                pProcessInfo                = NULL;
        PCOMMUNICATION_DATA pCommunicationData        = (PCOMMUNICATION_DATA)InputBuffer;
        PCOMMUNICATION_DATA pOutBuf        = (PCOMMUNICATION_DATA)OutputBuffer;
        PUCHAR p1 = NULL;
        int i;

        if (InputBufferLength == 0 || pCommunicationData == NULL)
        {
                return STATUS_UNSUCCESSFUL;
        }

        if (pCommunicationData == NULL)
        {
                return STATUS_UNSUCCESSFUL;
        }

        switch (pCommunicationData->DataType)
        {
        case DT_CREATE_SANDBOX:
                {
                        break;
                }
        case DT_QUERY_PID:
                {
                        KdPrint(("Pid=[%d]\r\n", pCommunicationData->DATA.QueryPid.ulPid));
                        p1 = (PUCHAR)pCommunicationData;
                        for(i=0; i<sizeof(COMMUNICATION_DATA); i++)
                        {
                                KdPrint(("pCommunicationData addr=[%x] p1 addr=[%x][%x]\r\n", pCommunicationData, p1, *p1));
                                p1++;
                        }
                        if(pCommunicationData->DATA.QueryPid.ulPid != 0)
                        {
                                pCommunicationData->DATA.QueryPid.ulSandboxId = 5;
                        }
                }
        default:
                break;
        }

        return STATUS_SUCCESS;
}
驱动层输出结果:
Pid=[0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcba0][2]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcba1][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcba2][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcba3][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcba4][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcba5][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcba6][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcba7][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcba8][3c]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcba9][8]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcbaa][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcbab][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcbac][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcbad][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcbae][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcbaf][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcbb0][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcbb1][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcbb2][0]
pCommunicationData addr=[ecadcba0] p1 addr=[ecadcbb3][0]

分析:
由于应用层位32位,所以sid,pid所占内存大小均为4字节,结构体总长度为12个字节。而到了驱动层,因为是64位,
所以结构体总长度为20个字节,sid,pid所占内存大小都变为了8字节。这样应用层传过来的pid,在驱动层中就收不到了。

问题:
在应用层为32位,驱动层为64位,二者通信时,象这种结构体参数传递时由于长度不一致,而导致的错位问题,有没有办法解决?

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 1905
活跃值: (1537)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
好多钱。。。

话说。你都知道是长度不一致了,理应来说,也知道怎么解决了吧。
2015-4-22 10:31
0
雪    币: 581
活跃值: (215)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
驱动接收后按照64位地址的结构去解析你传入的结构体,确实不大好做。不过你可以在应用层根据系统做两中结构体往下传吧。
2015-4-22 13:11
0
雪    币: 1370
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
由于该问题所属项目较大,比如将应用层编译为64位,或者修改应用层与驱动层通信部分的结构体,都将产生较大工作量,能否有更有效的方法?
2015-4-22 13:36
0
雪    币: 65
活跃值: (112)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
内核和应用层里,统一用__int64代理指针和句柄类型不就够了
2015-4-22 14:13
0
雪    币: 69
活跃值: (270)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
msf
6
注意下基本的数据类型,用64位的试试
2015-4-22 14:29
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
这问题是从32位到64位必然经历的一个问题,越是项目大越应该早做准备,就算现在能有办法解决,以后还会遇到更多这样的问题,如果不是临时性的项目,还是早点改吧
2015-4-22 14:45
0
雪    币: 1370
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
谢谢你们的回复。
请问是把结构体中的:
ULONG_PTR 改为 __int64;
而HANDLE类型不变
对吗?
如果HANDLE不变的话,还是有同样的问题产生:HANDLE在32位下长度为4,64位下长度为8呢?
2015-4-22 15:45
0
雪    币: 1370
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
是不是在结构体中,所有涉及到
ULONG_PTR、DWORD_PTR、HANDLE这样的类型,全部改成__int64啊?
2015-4-22 16:01
0
游客
登录 | 注册 方可回帖
返回
//