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位,二者通信时,象这种结构体参数传递时由于长度不一致,而导致的错位问题,有没有办法解决?
[课程]Linux pwn 探索篇!