204 lines
4.0 KiB
C
204 lines
4.0 KiB
C
|
/**
|
||
|
* WinPR: Windows Portable Runtime
|
||
|
* Microsoft Remote Procedure Call (MSRPC)
|
||
|
*
|
||
|
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
#ifdef HAVE_CONFIG_H
|
||
|
#include "config.h"
|
||
|
#endif
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#include <winpr/rpc.h>
|
||
|
|
||
|
#ifndef _WIN32
|
||
|
|
||
|
#include "ndr_correlation.h"
|
||
|
#include "ndr_private.h"
|
||
|
|
||
|
/*
|
||
|
* Correlation Descriptors: http://msdn.microsoft.com/en-us/library/windows/desktop/aa373607/
|
||
|
*
|
||
|
* correlation_type<1>
|
||
|
* correlation_operator<1>
|
||
|
* offset<2>
|
||
|
* [robust_flags<2>]
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
|
||
|
PFORMAT_STRING pFormat, ULONG_PTR* pCount)
|
||
|
{
|
||
|
LPVOID ptr = NULL;
|
||
|
ULONG_PTR data = 0;
|
||
|
unsigned char type;
|
||
|
unsigned short offset;
|
||
|
unsigned char conformance;
|
||
|
unsigned char correlation_type;
|
||
|
unsigned char correlation_operator;
|
||
|
correlation_type = pFormat[0];
|
||
|
type = correlation_type & 0x0F;
|
||
|
conformance = correlation_type & 0xF0;
|
||
|
correlation_operator = pFormat[1];
|
||
|
offset = *(unsigned short*)&pFormat[2];
|
||
|
|
||
|
if (conformance == FC_NORMAL_CONFORMANCE)
|
||
|
{
|
||
|
ptr = pMemory;
|
||
|
}
|
||
|
else if (conformance == FC_POINTER_CONFORMANCE)
|
||
|
{
|
||
|
ptr = pStubMsg->Memory;
|
||
|
}
|
||
|
else if (conformance == FC_TOP_LEVEL_CONFORMANCE)
|
||
|
{
|
||
|
ptr = pStubMsg->StackTop;
|
||
|
}
|
||
|
else if (conformance == FC_CONSTANT_CONFORMANCE)
|
||
|
{
|
||
|
data = offset | ((DWORD)pFormat[1] << 16);
|
||
|
*pCount = data;
|
||
|
}
|
||
|
else if (conformance == FC_TOP_LEVEL_MULTID_CONFORMANCE)
|
||
|
{
|
||
|
if (pStubMsg->StackTop)
|
||
|
ptr = pStubMsg->StackTop;
|
||
|
}
|
||
|
else
|
||
|
return pFormat;
|
||
|
|
||
|
switch (correlation_operator)
|
||
|
{
|
||
|
case FC_DEREFERENCE:
|
||
|
if (!ptr)
|
||
|
return pFormat;
|
||
|
|
||
|
ptr = *(LPVOID*)((char*)ptr + offset);
|
||
|
break;
|
||
|
|
||
|
case FC_DIV_2:
|
||
|
ptr = (char*)ptr + offset;
|
||
|
break;
|
||
|
|
||
|
case FC_MULT_2:
|
||
|
ptr = (char*)ptr + offset;
|
||
|
break;
|
||
|
|
||
|
case FC_SUB_1:
|
||
|
ptr = (char*)ptr + offset;
|
||
|
break;
|
||
|
|
||
|
case FC_ADD_1:
|
||
|
ptr = (char*)ptr + offset;
|
||
|
break;
|
||
|
|
||
|
case FC_CALLBACK:
|
||
|
{
|
||
|
WLog_ERR(TAG, "warning: NdrpComputeConformance FC_CALLBACK unimplemented");
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (!ptr)
|
||
|
return pFormat;
|
||
|
|
||
|
switch (type)
|
||
|
{
|
||
|
case FC_LONG:
|
||
|
data = *(LONG*)ptr;
|
||
|
break;
|
||
|
|
||
|
case FC_ULONG:
|
||
|
data = *(ULONG*)ptr;
|
||
|
break;
|
||
|
|
||
|
case FC_SHORT:
|
||
|
data = *(SHORT*)ptr;
|
||
|
break;
|
||
|
|
||
|
case FC_USHORT:
|
||
|
data = *(USHORT*)ptr;
|
||
|
break;
|
||
|
|
||
|
case FC_CHAR:
|
||
|
case FC_SMALL:
|
||
|
data = *(CHAR*)ptr;
|
||
|
break;
|
||
|
|
||
|
case FC_BYTE:
|
||
|
case FC_USMALL:
|
||
|
data = *(BYTE*)ptr;
|
||
|
break;
|
||
|
|
||
|
case FC_HYPER:
|
||
|
data = (ULONG_PTR) * (ULONGLONG*)ptr;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
switch (correlation_operator)
|
||
|
{
|
||
|
case FC_ZERO:
|
||
|
case FC_DEREFERENCE:
|
||
|
*pCount = data;
|
||
|
break;
|
||
|
|
||
|
case FC_DIV_2:
|
||
|
*pCount = data / 1;
|
||
|
break;
|
||
|
|
||
|
case FC_MULT_2:
|
||
|
*pCount = data * 1;
|
||
|
break;
|
||
|
|
||
|
case FC_SUB_1:
|
||
|
*pCount = data - 1;
|
||
|
break;
|
||
|
|
||
|
case FC_ADD_1:
|
||
|
*pCount = data + 1;
|
||
|
break;
|
||
|
|
||
|
case FC_CALLBACK:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (pStubMsg->fHasNewCorrDesc)
|
||
|
pFormat += 6;
|
||
|
else
|
||
|
pFormat += 4;
|
||
|
|
||
|
return pFormat;
|
||
|
}
|
||
|
|
||
|
PFORMAT_STRING NdrpComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
|
||
|
PFORMAT_STRING pFormat)
|
||
|
{
|
||
|
return NdrpComputeCount(pStubMsg, pMemory, pFormat, &pStubMsg->MaxCount);
|
||
|
}
|
||
|
|
||
|
PFORMAT_STRING NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
|
||
|
PFORMAT_STRING pFormat)
|
||
|
{
|
||
|
ULONG_PTR ActualCount = pStubMsg->ActualCount;
|
||
|
pFormat = NdrpComputeCount(pStubMsg, pMemory, pFormat, &ActualCount);
|
||
|
pStubMsg->ActualCount = (ULONG)ActualCount;
|
||
|
return pFormat;
|
||
|
}
|
||
|
|
||
|
#endif
|