RpcView/RpcDecompiler/InternalComplexTypesMisc.cpp

973 lines
21 KiB
C++

#include "InternalComplexTypesMisc.h"
#include "internalRpcDecompiler.h"
#include "internalRpcUtils.h"
#include <string>
BOOL __fastcall processBindContext(
_In_ VOID* pContext,
_In_ RVA_T pType,
_Inout_ ParamDesc& ParamDesc,
_Inout_ std::list<TypeToDefine>& listProcTypes,
_Inout_ std::ostringstream& oss)
{
UNREFERENCED_PARAMETER(listProcTypes);
UNREFERENCED_PARAMETER(pType);
UNREFERENCED_PARAMETER(pContext);
oss << "[context_handle] void*";
displayPtrLevel(ParamDesc.getuPtrLevel(), oss);
oss <<" "<<ParamDesc.getStrTypeName();
return TRUE;
}
BOOL __fastcall process_FC_BLKHOLE(
_In_ VOID* pContext,
_In_ RVA_T pType,
_Inout_ ParamDesc& ParamDesc,
_Inout_ std::list<TypeToDefine>& listProcTypes,
_Inout_ std::ostringstream& oss)
{
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
BOOL bResult = TRUE;
short wOffsetRange = 0;
DWORD dwRangeBegin = 0;
DWORD dwRangeEnd = 0;
RVA_T pNewType = NULL;
BYTE bRead = 0;
pType += sizeof(BYTE) + sizeof(BYTE); // skip FC_TYPE and first BYTE
//read offset to complex type
RPC_GET_PROCESS_DATA(pType,&wOffsetRange,sizeof(wOffsetRange));
if(!bResult)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] process_FC_BLKHOLE : unable to read process data\n");
return FALSE;
}
pNewType = pType + wOffsetRange;
pType += sizeof(wOffsetRange);
// read FC_TYPE at given offset
RPC_GET_PROCESS_DATA(pNewType,&bRead,sizeof(bRead));
if(bResult == FALSE)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] process_FC_BLKHOLE : unable to read process data\n");
return FALSE;
}
// if type is a FC_BIND_CONTEXT range doesn't make sense
// todo : check why this happen
if((FC_TYPE) bRead != FC_BIND_CONTEXT)
{
//read range begin
RPC_GET_PROCESS_DATA(pType,&dwRangeBegin,sizeof(dwRangeBegin));
if(bResult == FALSE)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] process_FC_BLKHOLE : unable to read process data\n");
return FALSE;
}
pType += sizeof(dwRangeBegin);
//read range end
RPC_GET_PROCESS_DATA(pType,&dwRangeEnd,sizeof(dwRangeEnd));
if(bResult == FALSE)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] process_FC_BLKHOLE : unable to read process data\n");
return FALSE;
}
oss<<"[range("<<dwRangeBegin<<","<<(UINT)dwRangeEnd<<")] ";
}
ParamDesc.setRva(pNewType);
bResult = rpcDumpType(
pContext,
ParamDesc,
listProcTypes,
oss);
return bResult;
}
BOOL __fastcall getFC_BLKHOLEMemorySize(
_In_ VOID* pContext,
_In_ RVA_T pType,
_Out_ size_t* pszMemorySize,
_In_ BOOL bHasRangeOnConformance)
{
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
BOOL bResult = TRUE;
short offsetRange = 0;
RVA_T pNewType = NULL;
pType += sizeof(BYTE) + sizeof(BYTE); // skip FC_TYPE and first BYTE
//read offset to complex type
RPC_GET_PROCESS_DATA(pType,&offsetRange,sizeof(offsetRange));
if(!bResult)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] getFC_BLKHOLEMemorySize : unable to read process data\n");
return FALSE;
}
pNewType = pType + offsetRange;
bResult = getTypeMemorySize(pContext, pNewType, pszMemorySize, bHasRangeOnConformance);
return bResult;
}
BOOL __fastcall processRange(
_In_ VOID* pContext,
_In_ RVA_T pType,
_Inout_ ParamDesc& ParamDesc,
_Inout_ std::list<TypeToDefine>& listProcTypes,
_Inout_ std::ostringstream& oss)
{
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
BOOL bResult = TRUE;
std::ostringstream ossTmp;
Range_t range;
UNREFERENCED_PARAMETER(listProcTypes);
RPC_GET_PROCESS_DATA(pType, &range, sizeof(range));
if(!bResult)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] processRange : unable to read process data\n");
return FALSE;
}
processSimpleType(
pContext,
(FC_TYPE)(range.flags_type & 0xF), //type is on lower byte
ParamDesc,
ossTmp);
if(ParamDesc.getuPtrLevel() != 0)
{
oss << "/*";
}
oss << "[range(" << std::dec << range.lowValue << "," << range.highValue<< ")] ";
if(ParamDesc.getuPtrLevel() != 0)
{
oss << "*/";
}
oss<<ossTmp.str();
return TRUE;
}
BOOL __fastcall getRangeMemorySize(
_In_ VOID* pContext,
_In_ RVA_T pType,
_Out_ size_t* pszMemorySize)
{
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
BOOL bResult = TRUE;
Range_t range;
RPC_GET_PROCESS_DATA(pType, &range, sizeof(range));
if(!bResult)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] getRangeMemorySize : unable to read process data\n");
return FALSE;
}
(*pszMemorySize) = getSimpleTypeMemorySize((FC_TYPE) (range.flags_type & 0xF));
return TRUE;
}
BOOL __fastcall ProcessArrayRange(
_In_ VOID* pContext,
_In_ RVA_T pType,
_Inout_ ParamDesc& ParamDesc,
_Inout_ std::ostringstream& temp)
{
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
BOOL bResult = TRUE;
Range_t range;
UNREFERENCED_PARAMETER(ParamDesc);
RPC_GET_PROCESS_DATA(pType, &range, sizeof(range));
if(!bResult)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] ProcessArrayRange : unable to read process data\n");
return FALSE;
}
temp << "/*[range(" << std::dec << range.lowValue << "," << range.highValue<< ")]*/ ";
return bResult;
}
UINT getElementByOffset(std::vector <UINT> v, UINT offset)
{
for(UINT i=0; i<v.size(); i++)
{
if(v[i] == offset)
{
return i;
}
}
return (UINT)-1;
}
BOOL __fastcall processUserMarshal(
_In_ VOID* pContext,
_In_ RVA_T pType,
_Inout_ ParamDesc& ParamDesc,
_Inout_ std::list<TypeToDefine>& listProcTypes,
_Inout_ std::ostringstream& oss)
{
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
BOOL bResult = TRUE;
UserMarshal_t userMarshal;
RVA_T pUserMarshalTarget = NULL;
std::string strParamNameTmp;
RPC_GET_PROCESS_DATA(pType, &userMarshal, sizeof(userMarshal));
if(FALSE == bResult)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] processUserMarshal : unable to read process data\n");
return FALSE;
}
oss << "/* WARNING : user_marshall should be defined in ACF file */ [user_marshall(";
// compute user marshal target offset
pUserMarshalTarget = pType + FIELD_OFFSET(UserMarshal_t, offset_to_the_transmitted_type) + userMarshal.offset_to_the_transmitted_type;
ParamDesc.setRva(pUserMarshalTarget);
strParamNameTmp = ParamDesc.getStrTypeName();
ParamDesc.setParamName("");
if (rpcDumpType(pContext, ParamDesc, listProcTypes, oss) == FALSE)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] processUserMarshal : unable to dump type\n");
return FALSE;
}
oss << ")] " << strParamNameTmp;
// set user_marshal size ??
return TRUE;
}
BOOL __fastcall getUserMarshallMemorySize(
_In_ VOID* pContext,
_In_ RVA_T pType,
_Out_ size_t* pszMemorySize)
{
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
BOOL bResult = TRUE;
UserMarshal_t userMarshal;
RPC_GET_PROCESS_DATA(pType, &userMarshal, sizeof(userMarshal));
if(FALSE == bResult)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] processUserMarshal : unable to read process data\n");
return FALSE;
}
*pszMemorySize = userMarshal.user_type_memory_size;
return TRUE;
}
BOOL __fastcall processPipe(
_In_ VOID* pContext,
_In_ RVA_T pType,
_Inout_ ParamDesc& ParamDesc,
_Inout_ std::list<TypeToDefine>& listProcTypes,
_Inout_ std::ostringstream& oss)
{
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
BOOL bResult = TRUE;
Pipe_t pipe;
RVA_T pPipeTarget = NULL;
std::string strParamNameTmp;
RPC_GET_PROCESS_DATA(pType, &pipe, sizeof(pipe));
if(FALSE == bResult)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] processPipe : unable to read process data\n");
return FALSE;
}
// compute pipe target offset
pPipeTarget = pType + FIELD_OFFSET(Pipe_t, offsetToType ) + pipe.offsetToType;
ParamDesc.setRva(pPipeTarget);
oss << "pipe ";
if (rpcDumpType(pContext, ParamDesc, listProcTypes, oss) == FALSE)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] processPipe : unable to read process data\n");
return FALSE;
}
// set pipe size ??
return TRUE;
}
BOOL __fastcall getPipeMemorySize(
_In_ VOID* pContext,
_In_ RVA_T pType,
_Out_ size_t* pszMemorySize,
_In_ BOOL bHasRangeOnConformance)
{
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
BOOL bResult = TRUE;
Pipe_t pipe;
RVA_T pPipeTarget = NULL;
RPC_GET_PROCESS_DATA(pType, &pipe, sizeof(pipe));
if(FALSE == bResult)
{
RPC_DEBUG_FN((UCHAR*)"[ERROR] getPipeMemorySize : unable to read process data\n");
return FALSE;
}
// compute pipe target offset
pPipeTarget = pType + FIELD_OFFSET(Pipe_t, offsetToType ) + pipe.offsetToType;
bResult = getTypeMemorySize(pContext, pPipeTarget, pszMemorySize, bHasRangeOnConformance);
return bResult;
}
BOOL __fastcall processCorrelationDescriptor(
_In_ VOID* pContext,
_In_ ConformanceDescr_T confDesc,
_Inout_ std::ostringstream& oss,
_Inout_ ParamDesc& paramDesc)
{
BOOL bResult = FALSE;
oss<<"[";
// display conformance type
switch(confDesc.confType)
{
case size_is:
oss<<"size_is(";
break;
case switch_is:
oss<<"switch_is(";
break;
case length_is:
oss<<"length_is(";
break;
case byte_count:
oss<<"byte_count(";
break;
default:
oss<<"unknow_corr_type(";
}
// Check on which pointer level conformance should be applied
{
UINT uPtrLevel = paramDesc.getuPtrLevel();
if(uPtrLevel > 1)
{
while(--uPtrLevel > 1)
{
oss << ",";
}
}
}
bResult = processCorrelationDescriptorNaked(pContext, confDesc, oss, paramDesc);
oss<<")]";
return bResult;
}
BOOL __fastcall processCorrelationDescriptorNaked(
_In_ VOID* pContext,
_In_ ConformanceDescr_T confDesc,
_Inout_ std::ostringstream& oss,
_Inout_ ParamDesc& paramDesc)
{
BOOL bResult;
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
std::string strCorrelationItem; // string describing X in size_is(X)
// special cases : OperationType == FC_EXPR || OperationType === FC_CALLBACK
if(confDesc.corrDesc.correlation_operator == FC_EXPR )
{
USHORT offset = 0;
// read offset
RPC_GET_PROCESS_DATA(
((RVA_T)pRpcDecompilerCtxt->pRpcDecompilerInfo->pExprOffset + confDesc.corrDesc.offset*sizeof(USHORT)),
&offset,
sizeof(USHORT));
if(bResult == FALSE)
{
oss << "/* ERROR unable to read ExprOffset table */";
return FALSE;
}
oss << "/* FC_EXPR */";
bResult = processFcExpr(
pContext,
pRpcDecompilerCtxt->pRpcDecompilerInfo->pExprFormatString + offset,
paramDesc,
confDesc,
oss);
return bResult;
}
if(confDesc.corrDesc.correlation_operator == FC_CALLBACK )
{
oss << "/*FC_CALLBACK not implemented */";
return TRUE;
}
// FIRST STEP : according to correlation type correlation item
// case of a FC_CONSTANT_CONFORMANCE
if(confDesc.corrDesc.correlation_type & FC_CONSTANT_CONFORMANCE)
{
INT32 iSize = ((confDesc.corrDesc.correlation_operator << 16) | confDesc.corrDesc.offset) & 0xFFFFFF;
oss<<std::dec<<iSize;
return TRUE;
}
// case of a FC_TOP_LEVEL_CONFORMANCE
// only used in function definition ?
if(confDesc.corrDesc.correlation_type & FC_TOP_LEVEL_CONFORMANCE)
{
UINT uArgNbr = 0;
std::stringstream ss;
#ifdef DBG_DECOMP
oss <<"/*FC_TOP_LEVEL_CONFORMANCE*/";
#endif
uArgNbr = confDesc.corrDesc.offset / (VIRTUAL_STACK_OFFSET_GRANULARITY);
ss<<"arg_"<<std::dec<<uArgNbr;
strCorrelationItem = ss.str();
}
else if(confDesc.corrDesc.correlation_type & FC_POINTER_CONFORMANCE) // case of FC_POINTER_CONFORMANCE
{
std::stringstream ss;
UINT uCorrDescMember;
#ifdef DBG_DECOMP
oss<<"/*FC_POINTER_CONFORMANCE(" << std::dec << confDesc.corrDesc.offset << ") */" ;
#endif
// check if vectMemberOffset is correctly filled
if(paramDesc.getVectMembersOffset().size() == 0)
{
oss << " /* ERROR : FC_POINTER_CONFORMANCE but an empty vectMemberOffset has been provided (offset = " <<confDesc.corrDesc.offset<< ") */";
return FALSE;
}
// get corr desc member number according to its offset
uCorrDescMember = getElementByOffset(paramDesc.getVectMembersOffset(), confDesc.corrDesc.offset);
if(uCorrDescMember == -1)
{
oss << "/* ERROR invalid corrDescMember */";
return FALSE;
}
ss << "StructMember"<<std::dec<<uCorrDescMember;
strCorrelationItem = ss.str();
}
else if(confDesc.corrDesc.correlation_type & FC_TOP_LEVEL_MULTID_CONFORMANCE) // case of FC_TOP_LEVEL_MULTID_CONFORMANCE
{
// currently not implemented
oss<<"/*FC_TOP_LEVEL_MULTID_CONFORMANCE not implemented */)]";
return FALSE;
}
else
{
// last remaining case is FC_NORMAL_CONFORMANCE
// Onlys used in structure definition ?
UINT uCorrDescMemberOffset;
UINT uCorrDescMember;
std::stringstream ss;
#ifdef DBG_DECOMP
oss<<"/*FC_NORMAL_CONFORMANCE ("<< std::dec << confDesc.corrDesc.offset<<")*/ ";
#endif
// check if vectMemberOffset is correctly filled
if(paramDesc.getVectMembersOffset().size() == 0)
{
oss << " /* ERROR : FC_NORMAL_CONFORMANCE but an empty vectMemberOffset has been provided */";
return FALSE;
}
// compute correlation member offset
if(paramDesc.getVectMembersOffset().size() <= paramDesc.getuStructMemberNum())
{
oss << "/* ERROR invalid structMemberNum */";
return FALSE;
}
// get member number according to its offset
uCorrDescMemberOffset = paramDesc.getVectMembersOffset()[paramDesc.getuStructMemberNum()] + confDesc.corrDesc.offset;
uCorrDescMember = getElementByOffset(paramDesc.getVectMembersOffset(), uCorrDescMemberOffset);
if(uCorrDescMember == -1)
{
oss << "/* ERROR invalid corrDescMember || corr desc offset = */" << std::dec << confDesc.corrDesc.offset;
return TRUE;
//return FALSE
}
ss << "StructMember"<<std::dec<<uCorrDescMember;
strCorrelationItem = ss.str();
}
// SECOND STEP : display correlation item according to correlation operator
switch(confDesc.corrDesc.correlation_operator)
{
case FC_DEREFERENCE:
// the correlation item describing the size of the current item
// can derive from an out parameter. In that case, we can only set it
// has a max range and not the exact size since it's not known before the call.
// Ex :
// HRESULT Proc0 (
// [in] int arg1,
// [out] int *arg2,
// [out][size_is( , *arg2)] int **arg2
// );
if (paramDesc.isOut())
{
oss << ", *" << strCorrelationItem;
}
else
{
oss << "*" << strCorrelationItem;
}
break;
case FC_ADD_1:
oss << strCorrelationItem << "+1";
break;
case FC_SUB_1:
oss << strCorrelationItem << "-1";
break;
case FC_DIV_2:
oss << strCorrelationItem << "/2";
break;
case FC_MULT_2:
oss << strCorrelationItem << "*2";
break;
case FC_EXPR:
oss << "/* FC_EXPR not implemented */";
break;
case FC_CALLBACK:
oss << "/* FC_CALLBACK not implemented */";
default:
oss << strCorrelationItem;
}
return TRUE;
}
UINT __fastcall processFcExpr(
_In_ VOID* pContext,
_Out_ RVA_T pExpr,
_In_ ParamDesc& paramDesc,
_In_ ConformanceDescr_T confDesc,
_Inout_ std::ostringstream& oss)
{
EXPR_OPERATOR operation;
EXPR_CONST32 constante32;
//EXPR_CONST64 constante64; Not used as of yet. Maybe with NDR64?
EXPR_VAR var;
UINT32 varNb;
BOOL bResult;
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
UINT sizeToAdvance = 0;
UINT sizeOfExpr = 0;
RPC_GET_PROCESS_DATA(
pExpr,
&operation,
sizeof(EXPR_OPERATOR)
);
switch(operation.ExprType)
{
case FC_EXPR_OPER:
if(operation.Operator >= OP_UNARY_PLUS && operation.Operator <= OP_UNARY_AND) // Unary operator
{
oss << getOperatorType(operation);
pExpr += sizeof(EXPR_OPERATOR);
sizeToAdvance += sizeof(EXPR_OPERATOR);
sizeOfExpr = processFcExpr(pContext, pExpr, paramDesc, confDesc, oss);
sizeToAdvance += sizeOfExpr;
}else if(operation.Operator >= OP_PLUS && operation.Operator <= OP_LOGICAL_OR) // binary operator
{
std::string tmpOper = getOperatorType(operation);
oss << "(";
pExpr += sizeof(EXPR_OPERATOR);
sizeToAdvance += sizeof(EXPR_OPERATOR);
sizeOfExpr = processFcExpr(pContext, pExpr, paramDesc, confDesc, oss);
pExpr += sizeOfExpr;
sizeToAdvance += sizeOfExpr;
oss <<" "<< tmpOper.c_str()<<" ";
sizeOfExpr = processFcExpr(pContext, pExpr, paramDesc, confDesc, oss);
sizeToAdvance += sizeOfExpr;
oss << ")";
}else{ // Ternary operator => (expr ? expr1 : expr2)
std::ostringstream tmpIfYes;
std::ostringstream tmpIfNo;
pExpr += sizeof(EXPR_OPERATOR);
sizeToAdvance += sizeof(EXPR_OPERATOR);
sizeOfExpr = processFcExpr(pContext, pExpr, paramDesc, confDesc, tmpIfYes);
sizeToAdvance += sizeOfExpr;
pExpr += sizeOfExpr;
sizeOfExpr = processFcExpr(pContext, pExpr, paramDesc,confDesc, tmpIfNo);
sizeToAdvance += sizeOfExpr;
pExpr += sizeOfExpr;
oss << "(";
sizeOfExpr = processFcExpr(pContext, pExpr, paramDesc, confDesc, oss);
sizeToAdvance += sizeOfExpr;
oss << "?";
oss << tmpIfYes.str();
oss << ":";
oss << tmpIfNo.str();
oss << ")";
}
break;
case FC_EXPR_VAR:
RPC_GET_PROCESS_DATA(pExpr, &var, sizeof(EXPR_VAR));
if(confDesc.corrDesc.correlation_type & FC_TOP_LEVEL_CONFORMANCE)
{
varNb = var.Offset / VIRTUAL_STACK_OFFSET_GRANULARITY;
oss << "arg_" << std::dec << varNb;
}else{
INT uCorrDescMemberOffset;
INT uCorrDescMember;
std::stringstream ss;
// get member number according to its offset
if(paramDesc.getArrayIsAttributedPointer())
{
uCorrDescMemberOffset = var.Offset;
}else{
uCorrDescMemberOffset = paramDesc.getVectMembersOffset()[paramDesc.getuStructMemberNum()] + var.Offset;
}
uCorrDescMember = getElementByOffset(paramDesc.getVectMembersOffset(), uCorrDescMemberOffset);
if(uCorrDescMember == -1)
{
oss << "/* [ERROR] invalid corrDescMember || var offset = " << std::dec << var.Offset << "*/";
return FALSE;
}
oss << "StructMember"<<std::dec<<uCorrDescMember;
}
sizeToAdvance += sizeof(EXPR_VAR);
break;
case FC_EXPR_CONST32:
RPC_GET_PROCESS_DATA(pExpr, &constante32, sizeof(EXPR_CONST32));
oss << std::dec << constante32.ConstValue;
sizeToAdvance += sizeof(EXPR_CONST32);
break;
case FC_EXPR_CONST64:
// TODO
break;
default:
oss << "/*[ERROR] unknown expression type */";
break;
}
return sizeToAdvance;
}
std::string __fastcall getOperatorType(
_In_ EXPR_OPERATOR oper)
{
std::string result;
switch(oper.Operator)
{
case OP_UNARY_PLUS:
result = "+";
break;
case OP_UNARY_MINUS:
result = "-";
break;
case OP_UNARY_NOT:
result = "!";
break;
case OP_UNARY_COMPLEMENT:
result = "~";
break;
case OP_UNARY_CAST:
switch(oper.CastType)
{
case FC_SMALL:
result = "(byte)" ;
break;
case FC_USMALL:
result = "(char)";
break;
case FC_USHORT:
result = "(unsigned short)";
break;
case FC_LONG:
result = "(long)";
break;
case FC_ULONG:
result = "(unsigned long)";
break;
default:
result = "/* unknown cast type */";
break;
}
break;
case OP_UNARY_INDIRECTION:
result = "*";
break;
case OP_UNARY_AND:
result = "&";
break;
case OP_PLUS:
result = "+";
break;
case OP_MINUS:
result = "-";
break;
case OP_STAR:
result = "*";
break;
case OP_SLASH:
result = "/";
break;
case OP_MOD:
result = "%";
break;
case OP_LEFT_SHIFT:
result = "<<";
break;
case OP_RIGHT_SHIFT:
result = ">>";
break;
case OP_LESS:
result = "<";
break;
case OP_LESS_EQUAL:
result = "<=";
break;
case OP_GREATER_EQUAL:
result = ">=";
break;
case OP_GREATER:
result = ">";
break;
case OP_EQUAL:
result = "==";
break;
case OP_NOT_EQUAL:
result = "!=";
break;
case OP_AND:
result = "&";
break;
case OP_OR:
result = "|";
break;
case OP_XOR:
result = "^";
break;
case OP_LOGICAL_AND:
result = "&&";
break;
case OP_LOGICAL_OR:
result = "||";
break;
case OP_EXPRESSION:
break;
default:
result = "/*[ERROR] unknown operation */" ;
break;
}
return result;
}
BOOL __fastcall processTransmitRepresentAs(
_In_ VOID* pContext,
_In_ RVA_T pType,
_Inout_ ParamDesc& ParamDesc,
_Inout_ std::list<TypeToDefine>& listAdditionalTypes,
_Inout_ std::ostringstream& oss)
{
BOOL bResult;
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
TransmitRepresentAs_t transmit;
RPC_GET_PROCESS_DATA(pType, &transmit, sizeof(TransmitRepresentAs_t));
RVA_T pTransmittedType = pType + sizeof(TransmitRepresentAs_t) + transmit.transmitted_type_offset - sizeof(transmit.transmitted_type_offset);
oss << "/* data transmitted as */";
ParamDesc.setRva(pTransmittedType);
if( rpcDumpType(pContext, ParamDesc, listAdditionalTypes, oss) == FALSE)
{
RPC_DEBUG_FN("[ERROR] processTransmitRepresentAs : dump type failed \n");
return FALSE;
}
return TRUE;
}
BOOL __fastcall getTransmitAsRepresentAsMemorySize(
_In_ VOID* pContext,
_In_ RVA_T pType,
_Out_ size_t* pszMemorySize)
{
BOOL bResult;
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
TransmitRepresentAs_t transmit;
RPC_GET_PROCESS_DATA(pType, &transmit, sizeof(TransmitRepresentAs_t));
if(bResult == FALSE)
{
RPC_DEBUG_FN("[ERROR] getTransmitAsRepresentAsMemorySize : unable to get process data\n");
return FALSE;
}
// TODO : check if this is this size and not target size that is used for conformance
*pszMemorySize = transmit.presented_type_memory_size;
return TRUE;
}
UINT getCorrelationDescriptorSize(
_In_ BOOL bRobustFlagWasSet,
_In_ BOOL bHasRangeOnConformance)
{
UINT uSize = 0;
UNREFERENCED_PARAMETER(bRobustFlagWasSet);
if(robustFlagWasSet)
{
uSize = sizeof(CorrelationDescriptorRobust_t);
}
else
{
uSize = sizeof(CorrelationDescriptorNonRobust_t);
}
if(bHasRangeOnConformance)
{
uSize += sizeof(Range_t);
}
return uSize;
}