mirror of
https://github.com/silverf0x/RpcView
synced 2026-06-08 17:26:38 +00:00
1353 lines
38 KiB
C++
1353 lines
38 KiB
C++
#include "internalRpcDecompTypeDefs.h"
|
|
#include "internalRpcDecompiler.h"
|
|
#include "internalRpcUtils.h"
|
|
#include "internalComplexTypesStrings.h"
|
|
#include "internalComplexTypesArrays.h"
|
|
#include "internalComplexTypesPointers.h"
|
|
#include "InternalComplexTypesMisc.h"
|
|
#include "internalComplexTypesUnions.h"
|
|
#include "internalComplexTypesStructs.h"
|
|
#include <stdio.h>
|
|
#include <sstream>
|
|
#include <iostream>
|
|
|
|
#include "internalTypeTools.h"
|
|
|
|
|
|
|
|
|
|
///\warning Global variable is64B to set according to the real RPC binary information to decompile. The code design is to be adapted.
|
|
BOOL is64B;
|
|
|
|
//#ifdef _AMD64_
|
|
//boolean is64B = TRUE;
|
|
//#else
|
|
//boolean is64B = FALSE;
|
|
//#endif
|
|
|
|
///\warning Global variable robustFlagWasSet to set according to the real RPC binary information to decompile. The code design is to be adapted.
|
|
/// robustFlagWasSet to set according to the real environment (/robust used or not, see following line)
|
|
/// robustFlagWasSet could be set to the w2kHeaderToDecode.interpreter_opt_flag2.HasNewCorrDesc value read from a procedure descriptor.
|
|
boolean robustFlagWasSet;
|
|
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
BOOL __fastcall getAllTypesSortedInAList(
|
|
_In_ VOID* pContext,
|
|
_In_ std::list<TypeToDefine> & listTypesToDefine,
|
|
_Inout_ std::list<TypeToDefine>& listAllTypesSorted,
|
|
_Inout_ std::ostringstream& oss)
|
|
{
|
|
|
|
|
|
BOOL bResult;
|
|
|
|
listTypesToDefine.sort();
|
|
listTypesToDefine.unique();
|
|
|
|
while(!listTypesToDefine.empty())
|
|
{
|
|
// list used to store addition type that might be embeded in current type
|
|
std::list<TypeToDefine> listAdditionalType;
|
|
|
|
TypeToDefine TypeToDefineToDefine = listTypesToDefine.front();
|
|
|
|
// remove first element from list
|
|
listTypesToDefine.pop_front();
|
|
|
|
// print it
|
|
bResult = printType(
|
|
pContext,
|
|
TypeToDefineToDefine,
|
|
listAdditionalType,
|
|
oss);
|
|
|
|
// if we're unable to Print type we abort
|
|
if(bResult == FALSE)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
listAllTypesSorted.push_back(TypeToDefineToDefine);
|
|
|
|
// merge listTypesToDefine and ListAdditionalTypes
|
|
if(!listAdditionalType.empty())
|
|
{
|
|
//listTypesToDefine.merge(listAdditionalType);
|
|
listTypesToDefine.splice(listTypesToDefine.end(), listAdditionalType);
|
|
}
|
|
|
|
// remove from listTypesToDefine elements that already are in
|
|
for(auto iter = listAllTypesSorted.begin(); iter != listAllTypesSorted.end(); iter++)
|
|
{
|
|
listTypesToDefine.remove(*iter);
|
|
}
|
|
|
|
|
|
listTypesToDefine.sort();
|
|
listTypesToDefine.unique();
|
|
|
|
}
|
|
|
|
listAllTypesSorted.unique();
|
|
listAllTypesSorted.sort();
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------------------------
|
|
BOOL __fastcall dumpTypeList(
|
|
_In_ VOID* pContext,
|
|
_In_ std::list<TypeToDefine> & listTypesToDefine,
|
|
_Inout_ std::ostringstream& oss)
|
|
{
|
|
|
|
std::list<TypeToDefine> listAdditionalType;
|
|
BOOL bResult;
|
|
|
|
listTypesToDefine.sort();
|
|
listTypesToDefine.unique();
|
|
|
|
|
|
for(auto iter=listTypesToDefine.begin(); iter!=listTypesToDefine.end(); iter++)
|
|
{
|
|
bResult = printType(
|
|
pContext,
|
|
*iter,
|
|
listAdditionalType,
|
|
oss);
|
|
|
|
if(bResult == FALSE)
|
|
{
|
|
oss << std::endl << "[ERROR] dumpTypeList : unable to print type\n" << std::endl;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------------------------------
|
|
BOOL __fastcall RpcDecompilerPrintAllTypesInList
|
|
(
|
|
_In_ VOID* pContext,
|
|
_In_ std::list<TypeToDefine> & listProcTypes,
|
|
_Out_ std::ostringstream& oss
|
|
)
|
|
{
|
|
std::list<TypeToDefine> listAllTypesSorted;
|
|
std::ostringstream ossUseless;
|
|
|
|
|
|
/*oss<<"/*<DEBUG purpose>"<<std::endl;
|
|
for(auto iter = listProcTypes.begin(); iter != listProcTypes.end(); iter++)
|
|
{
|
|
oss<<"offset : "<<iter->uOffset<<" ";
|
|
}
|
|
oss<<"</DEBUG purpose>"<<std::endl;*/
|
|
|
|
|
|
|
|
|
|
|
|
// recursively explore all list in order to get a complete list of types
|
|
if (getAllTypesSortedInAList(pContext, listProcTypes, listAllTypesSorted, ossUseless) == FALSE)
|
|
{
|
|
oss<<"[ERROR] unable to get list of all types sorted" << std::endl;
|
|
return FALSE;
|
|
}
|
|
|
|
if( dumpTypeList(pContext, listAllTypesSorted, oss) == FALSE)
|
|
{
|
|
oss<<"[ERROR] unable to dump type list" << std::endl;
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
BOOL __fastcall RpcDecompilerDecodeAndPrintPrototypeReturnType(
|
|
_In_ VOID* pContext,
|
|
_In_ UINT formatStringOffset,
|
|
_Out_ UINT * paramOffset,
|
|
_Out_ UINT * sizeOfProcDescr,
|
|
_Inout_ IdlFunctionDesc& IdlFunctionDesc,
|
|
_Inout_ std::list<TypeToDefine>& listProcType,
|
|
_Inout_ std::ostringstream& oss)
|
|
{
|
|
BOOL bResult = FALSE;
|
|
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
|
|
|
Oi_Header_1stPart_t oiHeader1stPartToDecode;
|
|
Oi_Header_RpcFlags_t * oiHeaderRpcFlagsToDecode = NULL;
|
|
Oi_Header_3rdPart_t oiHeader3rdPartToDecode;
|
|
ExplicitHandle_t * oiHeaderExplicitHandleToDecode = NULL;
|
|
Oif_Header_t oifHeaderToDecode;
|
|
Win2kExt_Header_t w2kHeaderToDecode;
|
|
|
|
UINT currentOffset = formatStringOffset;
|
|
UINT numParam = 0;
|
|
BOOL isReturnParam = FALSE;
|
|
BOOL returnTypeHasBeenPrinted = FALSE;
|
|
|
|
UINT paramSizeInBytes = 0;
|
|
|
|
memset(&oiHeader1stPartToDecode, 0, sizeof(Oi_Header_1stPart_t));
|
|
memset(&oiHeader3rdPartToDecode, 0, sizeof(Oi_Header_3rdPart_t));
|
|
memset(&oifHeaderToDecode, 0, sizeof(Oif_Header_t));
|
|
memset(&w2kHeaderToDecode, 0, sizeof(Win2kExt_Header_t));
|
|
|
|
//following checks already done by the caller function
|
|
/* if (pRpcDecompilerCtxt == NULL) goto End;
|
|
if (pRpcDecompilerCtxt->pRpcViewHelper == NULL) goto End;
|
|
|
|
if (pRpcDecompilerCtxt->pRpcDecompilerInfo == NULL) goto End;
|
|
if (pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString == NULL) goto End;*/
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\n\n*************** RpcDecompilerDecodeAndPrintPrototypeReturnType ******************");
|
|
|
|
/**********************************************************************
|
|
* Decode the Oi Header
|
|
***********************************************************************/
|
|
//Decode the Oi header 1st part
|
|
RPC_GET_PROCESS_DATA(
|
|
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + currentOffset),
|
|
&oiHeader1stPartToDecode,
|
|
sizeof(Oi_Header_1stPart_t)
|
|
);
|
|
currentOffset += sizeof(Oi_Header_1stPart_t);
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\n\n");
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeader1stPartToDecode.handle_type = 0x%x", oiHeader1stPartToDecode.handle_type);
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeader1stPartToDecode.oi_flags = 0x%x", oiHeader1stPartToDecode.oi_flags);
|
|
|
|
//Decode the Oi header Rpc Flags
|
|
if(oiHeader1stPartToDecode.oi_flags & Oi_HAS_RPCFLAGS)
|
|
{
|
|
oiHeaderRpcFlagsToDecode = (Oi_Header_RpcFlags_t *) RPC_ALLOC_FN(sizeof(Oi_Header_RpcFlags_t));
|
|
if(oiHeaderRpcFlagsToDecode == NULL)
|
|
{
|
|
RPC_DEBUG_FN((UCHAR*)"\n!!! source = %s line = %d - RpcAlloc returned NULL pointer", __FILE__, __LINE__);
|
|
goto End;
|
|
}
|
|
|
|
RPC_GET_PROCESS_DATA(
|
|
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + currentOffset),
|
|
oiHeaderRpcFlagsToDecode,
|
|
sizeof(Oi_Header_RpcFlags_t)
|
|
);
|
|
|
|
currentOffset += sizeof(Oi_Header_RpcFlags_t);
|
|
//RPC_DEBUG_FN((UCHAR*)"\noiHeaderRpcFlagsToDecode->rpc_flags = 0x%x", oiHeaderRpcFlagsToDecode->rpc_flags);
|
|
}
|
|
|
|
|
|
|
|
//Decode the Oi header 3rd part
|
|
RPC_GET_PROCESS_DATA(
|
|
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + currentOffset),
|
|
&oiHeader3rdPartToDecode,
|
|
sizeof(Oi_Header_3rdPart_t)
|
|
);
|
|
currentOffset += sizeof(Oi_Header_3rdPart_t);
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeader3rdPartToDecode.procNum = 0x%x", oiHeader3rdPartToDecode.procNum);
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeader3rdPartToDecode.stack_size = 0x%x", oiHeader3rdPartToDecode.stack_size);
|
|
|
|
|
|
//Decode the Oi header explicit handle
|
|
//TODO : creer une fonction qui fait cela, cad GetExplicitHandleSize
|
|
if(oiHeader1stPartToDecode.handle_type == FC_EXPLICIT_HANDLE)
|
|
{
|
|
oiHeaderExplicitHandleToDecode = (ExplicitHandle_t *) RPC_ALLOC_FN(sizeof(ExplicitHandle_t));
|
|
if(oiHeaderExplicitHandleToDecode == NULL)
|
|
{
|
|
RPC_DEBUG_FN((UCHAR*)"!!! source = %s line = %d - RpcAlloc returned NULL pointer", __FILE__, __LINE__);
|
|
goto End;
|
|
}
|
|
|
|
RPC_GET_PROCESS_DATA(
|
|
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + currentOffset),
|
|
oiHeaderExplicitHandleToDecode,
|
|
EXPLICIT_HANDLE_MIN_SIZE
|
|
);
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeaderExplicitHandleToDecode->htype = 0x%x", oiHeaderExplicitHandleToDecode->htype);
|
|
|
|
switch(oiHeaderExplicitHandleToDecode->htype)
|
|
{
|
|
case FC_BIND_PRIMITIVE:
|
|
#if EXPLICIT_HANDLE_MIN_SIZE != EXPLICIT_HANDLE_PRIMITIVE_SIZE
|
|
#error check the value of EXPLICIT_HANDLE_MIN_SIZE, EXPLICIT_HANDLE_PRIMITIVE_SIZE and the code
|
|
#endif
|
|
currentOffset += EXPLICIT_HANDLE_PRIMITIVE_SIZE;
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeaderExplicitHandleToDecode->hContent.explicitHandlePrimitive.flag = 0x%x", oiHeaderExplicitHandleToDecode->hContent.explicitHandlePrimitive.flag);
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeaderExplicitHandleToDecode->hContent.explicitHandlePrimitive.offset = 0x%x", oiHeaderExplicitHandleToDecode->hContent.explicitHandlePrimitive.offset);
|
|
|
|
break;
|
|
|
|
case FC_BIND_GENERIC:
|
|
RPC_GET_PROCESS_DATA(
|
|
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + currentOffset),
|
|
oiHeaderExplicitHandleToDecode,
|
|
EXPLICIT_HANDLE_GENERIC_SIZE
|
|
);
|
|
currentOffset += EXPLICIT_HANDLE_GENERIC_SIZE;
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeaderExplicitHandleToDecode->hContent.explicitHandleGeneric.flagAndSize = 0x%x", oiHeaderExplicitHandleToDecode->hContent.explicitHandleGeneric.flagAndSize);
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeaderExplicitHandleToDecode->hContent.explicitHandleGeneric.offset = 0x%x", oiHeaderExplicitHandleToDecode->hContent.explicitHandleGeneric.offset);
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeaderExplicitHandleToDecode->hContent.explicitHandleGeneric.binding_routine_pair_index = 0x%x", oiHeaderExplicitHandleToDecode->hContent.explicitHandleGeneric.binding_routine_pair_index);
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeaderExplicitHandleToDecode->hContent.explicitHandleGeneric.pad = 0x%x", oiHeaderExplicitHandleToDecode->hContent.explicitHandleGeneric.pad);
|
|
|
|
break;
|
|
|
|
case FC_BIND_CONTEXT:
|
|
RPC_GET_PROCESS_DATA(
|
|
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + currentOffset),
|
|
oiHeaderExplicitHandleToDecode,
|
|
EXPLICIT_HANDLE_CONTEXT_SIZE
|
|
);
|
|
currentOffset += EXPLICIT_HANDLE_CONTEXT_SIZE;
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeaderExplicitHandleToDecode->hContent.explicitHandleContext.flags = 0x%x", oiHeaderExplicitHandleToDecode->hContent.explicitHandleContext.flags);
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeaderExplicitHandleToDecode->hContent.explicitHandleContext.offset = 0x%x", oiHeaderExplicitHandleToDecode->hContent.explicitHandleContext.offset);
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeaderExplicitHandleToDecode->hContent.explicitHandleContext.context_rundown_routine_index = 0x%x", oiHeaderExplicitHandleToDecode->hContent.explicitHandleContext.context_rundown_routine_index);
|
|
RPC_DEBUG_FN((UCHAR*)"\noiHeaderExplicitHandleToDecode->hContent.explicitHandleContext.param_num = 0x%x", oiHeaderExplicitHandleToDecode->hContent.explicitHandleContext.param_num);
|
|
|
|
break;
|
|
|
|
default:
|
|
RPC_DEBUG_FN((UCHAR*)"\n!!! source = %s line = %d - ERREUR : oiHeaderExplicitHandleToDecode->htype undefined value. value = 0x%x", __FILE__, __LINE__, oiHeaderExplicitHandleToDecode->htype);
|
|
bResult = FALSE;
|
|
goto End;
|
|
break;
|
|
|
|
} // switch(oiHeaderExplicitHandleToDecode->htype)
|
|
|
|
}// if(oiHeader1stPartToDecode.handle_type == FC_EXPLICIT_HANDLE)
|
|
|
|
|
|
/**********************************************************************
|
|
* Decode the Oif Header (necessary for 64bits)
|
|
***********************************************************************/
|
|
|
|
RPC_GET_PROCESS_DATA(
|
|
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + currentOffset),
|
|
&oifHeaderToDecode,
|
|
OIF_EXT_HEADER_SIZE
|
|
);
|
|
currentOffset += OIF_EXT_HEADER_SIZE;
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\noifHeaderToDecode.constant_client_buffer_size = 0x%x", oifHeaderToDecode.constant_client_buffer_size);
|
|
RPC_DEBUG_FN((UCHAR*)"\noifHeaderToDecode.constant_server_buffer_size = 0x%x", oifHeaderToDecode.constant_server_buffer_size);
|
|
RPC_DEBUG_FN((UCHAR*)"\noifHeaderToDecode.interpreter_opt_flag = 0x%x", oifHeaderToDecode.interpreter_opt_flag);
|
|
RPC_DEBUG_FN((UCHAR*)"\noifHeaderToDecode.number_of_param = 0x%x", oifHeaderToDecode.number_of_param);
|
|
|
|
|
|
#ifdef DBG_DECOMP
|
|
oss << "/* is Async bit set : ";
|
|
|
|
if(oifHeaderToDecode.interpreter_opt_flag.HasAsyncUuid)
|
|
{
|
|
oss << " TRUE */";
|
|
}
|
|
else
|
|
{
|
|
oss << " FALSE */";
|
|
}
|
|
#endif
|
|
|
|
/**********************************************************************
|
|
* Decode the Win2kExt Header
|
|
***********************************************************************/
|
|
// TODO : need to identify which precise condition trigger the apparition of a win2KExt header
|
|
if(pRpcDecompilerCtxt->pRpcDecompilerInfo->NDRVersion != 0x20000)
|
|
{
|
|
RPC_GET_PROCESS_DATA(
|
|
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + currentOffset),
|
|
&(w2kHeaderToDecode.extension_version),
|
|
sizeof(w2kHeaderToDecode.extension_version)
|
|
);
|
|
|
|
switch (w2kHeaderToDecode.extension_version)
|
|
{
|
|
case WIN2K_EXT_HEADER_32B_SIZE:
|
|
RPC_GET_PROCESS_DATA(
|
|
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + currentOffset),
|
|
&w2kHeaderToDecode,
|
|
WIN2K_EXT_HEADER_32B_SIZE
|
|
);
|
|
|
|
currentOffset += WIN2K_EXT_HEADER_32B_SIZE;
|
|
|
|
break;
|
|
case WIN2K_EXT_HEADER_64B_SIZE:
|
|
RPC_GET_PROCESS_DATA(
|
|
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + currentOffset),
|
|
&w2kHeaderToDecode,
|
|
WIN2K_EXT_HEADER_64B_SIZE
|
|
);
|
|
|
|
currentOffset += WIN2K_EXT_HEADER_64B_SIZE;
|
|
|
|
break;
|
|
default:
|
|
RPC_DEBUG_FN((UCHAR*)"\n!!! source = %s line = %d - ERREUR : w2kHeaderToDecode.extension_version undefined value. value = 0x%x", __FILE__, __LINE__, w2kHeaderToDecode.extension_version);
|
|
bResult = FALSE;
|
|
goto End;
|
|
}
|
|
// parse Win32Ext Header
|
|
IdlFunctionDesc.parseWin32ExtHeader(&w2kHeaderToDecode);
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\nw2kHeaderToDecode.extension_version = 0x%x", w2kHeaderToDecode.extension_version);
|
|
RPC_DEBUG_FN((UCHAR*)"\nw2kHeaderToDecode.interpreter_opt_flag2 = 0x%x", w2kHeaderToDecode.interpreter_opt_flag2);
|
|
RPC_DEBUG_FN((UCHAR*)"\nw2kHeaderToDecode.clientCorrHint = 0x%x", w2kHeaderToDecode.clientCorrHint);
|
|
RPC_DEBUG_FN((UCHAR*)"\nw2kHeaderToDecode.serverCorrHint = 0x%x", w2kHeaderToDecode.serverCorrHint);
|
|
RPC_DEBUG_FN((UCHAR*)"\nw2kHeaderToDecode.notifyIndex = 0x%x", w2kHeaderToDecode.notifyIndex);
|
|
|
|
if(w2kHeaderToDecode.extension_version == WIN2K_EXT_HEADER_64B_SIZE)
|
|
{
|
|
RPC_DEBUG_FN((UCHAR*)"\nw2kHeaderToDecode.floatDoubleMask = 0x%x", w2kHeaderToDecode.floatDoubleMask);
|
|
}
|
|
|
|
|
|
}//endif
|
|
|
|
|
|
|
|
|
|
//TODO
|
|
// Print the handle type information to take into account
|
|
switch(oiHeader1stPartToDecode.handle_type)
|
|
{
|
|
case FC_BIND_CONTEXT:
|
|
break;
|
|
case FC_BIND_PRIMITIVE:
|
|
|
|
oss << "\n/*********************************************************";
|
|
oss << "\n * Add the following line in header of the the ACF file:";
|
|
//oss << "\n *\timplicit_handle (handle_t "<<narrow(std::wstring(DEFAULT_IF_NAME))<<"_IfHandle)";
|
|
oss << "\n *\timplicit_handle (handle_t "<< DEFAULT_IF_NAME <<"_IfHandle)";
|
|
oss << "\n *********************************************************/\n";
|
|
break;
|
|
case FC_AUTO_HANDLE:
|
|
break;
|
|
case FC_CALLBACK_HANDLE:
|
|
oss << "[callback]\t";
|
|
break;
|
|
case FC_EXPLICIT_HANDLE:
|
|
break;
|
|
default:
|
|
RPC_DEBUG_FN((UCHAR*)"\n!!! source = %s line = %d - ERREUR : oiHeader1stPartToDecode.handle_type undefined value. value = 0x%x", __FILE__, __LINE__, oiHeader1stPartToDecode.handle_type);
|
|
bResult = FALSE;
|
|
goto End;
|
|
break;
|
|
}
|
|
|
|
// Compute the nbParamToPrint and the paramOffset
|
|
*paramOffset = currentOffset;
|
|
IdlFunctionDesc.setNbParam(oifHeaderToDecode.number_of_param); //TODO : cas du oi header ?
|
|
|
|
// Find and print the procedure return type
|
|
if( oifHeaderToDecode.interpreter_opt_flag.HasReturn )
|
|
{
|
|
if (oifHeaderToDecode.number_of_param <= 0)
|
|
{
|
|
//No parameter to be printed whereas the procedure is supposed to return something...
|
|
RPC_DEBUG_FN((UCHAR*)"\n!!! RpcDecompilerDecodeAndPrintPrototypeReturnType: file = %s, line = %d, *nbParamToPrint = %d whereas oifHeaderToDecode.interpreter_opt_flag.HasReturn",
|
|
__FILE__, __LINE__, oifHeaderToDecode.number_of_param);
|
|
goto End;
|
|
}
|
|
else //(oifHeaderToDecode.number_of_param > 0)
|
|
{
|
|
//Find and print the return parameter type. Note: as soon as a return type is printed, the loop ends
|
|
numParam = 1;
|
|
while( (! returnTypeHasBeenPrinted) && (numParam <= oifHeaderToDecode.number_of_param) )
|
|
{
|
|
RPC_DEBUG_FN((UCHAR*)"\nRpcDecompilerDecodeAndPrintPrototypeReturnType: numParam = 0x%x on total to analyse = 0x%x", numParam, oifHeaderToDecode.number_of_param);
|
|
bResult = RpcDecompilerGetReturnParamInfo(/* in */ pRpcDecompilerCtxt, /* in */ currentOffset, /* in */ paramDescrOif, /* out */ &isReturnParam);
|
|
if (bResult == FALSE) goto End;
|
|
|
|
if(isReturnParam)
|
|
{
|
|
//Return param is found, to be printed
|
|
//RPC_PRINT_FN((UCHAR*)"\t");
|
|
oss << "\t";
|
|
|
|
bResult = RpcDecompilerPrintParam(
|
|
pRpcDecompilerCtxt,
|
|
/* in */ currentOffset,
|
|
/* in */ paramDescrOif,
|
|
/* out */ ¶mSizeInBytes,
|
|
/* in */ IdlFunctionDesc,
|
|
/* in/out */ listProcType,
|
|
/* in, out */oss);
|
|
|
|
|
|
if (bResult == FALSE || paramSizeInBytes == RPC_DECOMPILER_INVALID_PARAM_SIZE) goto End;
|
|
returnTypeHasBeenPrinted = TRUE;
|
|
}
|
|
|
|
currentOffset += OIF_PARAM_SIZE;
|
|
numParam++;
|
|
}
|
|
|
|
if(! returnTypeHasBeenPrinted)
|
|
{
|
|
//No parameter to be printed whereas the procedure is supposed to return something...
|
|
RPC_DEBUG_FN((UCHAR*)"\n!!! RpcDecompilerDecodeAndPrintPrototypeReturnType: file = %s, line = %d, no return param found whereas oifHeaderToDecode.interpreter_opt_flag.HasReturn",
|
|
__FILE__, __LINE__);
|
|
goto End;
|
|
}
|
|
}// (*nbParamToPrint > 0)
|
|
}//( oifHeaderToDecode.interpreter_opt_flag.HasReturn )
|
|
else
|
|
{
|
|
//RPC_PRINT_FN((UCHAR*)"\tvoid");
|
|
oss <<"\tvoid ";
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\tvoid ");
|
|
}// !( oifHeaderToDecode.interpreter_opt_flag.HasReturn )
|
|
|
|
End:
|
|
*sizeOfProcDescr = currentOffset - formatStringOffset;
|
|
if(oiHeaderRpcFlagsToDecode != NULL) RPC_FREE_FN(oiHeaderRpcFlagsToDecode);
|
|
if(oiHeaderExplicitHandleToDecode != NULL) RPC_FREE_FN(oiHeaderExplicitHandleToDecode);
|
|
return (bResult);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
BOOL __fastcall RpcDecompilerPrintPrototypeName(
|
|
_In_ VOID* pContext,
|
|
_In_ UINT ProcIndex,
|
|
_Inout_ std::ostringstream& oss)
|
|
{
|
|
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
|
|
|
//following checks already done by the caller function
|
|
/* if (pRpcDecompilerCtxt == NULL) goto End;
|
|
if (pRpcDecompilerCtxt->pRpcViewHelper == NULL) goto End;
|
|
|
|
if (pRpcDecompilerCtxt->pRpcDecompilerInfo == NULL) goto End;*/
|
|
if(pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcNameTable == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\n\n************************** RpcDecompilerPrintPrototypeName ************************");
|
|
|
|
|
|
if(pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcNameTable[ProcIndex] == NULL)
|
|
{
|
|
|
|
//oss << "_Function_0x" << std::hex << (long)(pFunction - pModuleBase) << "(";
|
|
oss << " _Function_" << std::dec << ProcIndex << "(";
|
|
|
|
}
|
|
else
|
|
{
|
|
size_t sz = wcslen(pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcNameTable[ProcIndex]) + 1;
|
|
size_t szConverted = 0;
|
|
|
|
char* pTmp = (char*)pRpcDecompilerCtxt->pRpcViewHelper->RpcAlloc(sz);
|
|
|
|
if(pTmp != NULL)
|
|
{
|
|
ZeroMemory(pTmp, sz);
|
|
wcstombs_s(&szConverted, pTmp, sz, pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcNameTable[ProcIndex], sz);
|
|
|
|
oss << pTmp << "(";
|
|
|
|
pRpcDecompilerCtxt->pRpcViewHelper->RpcFree(pTmp);
|
|
}
|
|
|
|
//oss << narrow(std::wstring(pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcNameTable[ProcIndex])) << "(";
|
|
|
|
|
|
}// if(pRpcDecompilerCtxt->pRpcDecompilerInfo->ppProcNameTable[ProcIndex] == NULL)
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
BOOL __fastcall RpcDecompilerGetReturnParamInfo(
|
|
_In_ VOID* pContext,
|
|
_In_ UINT paramOffset,
|
|
_In_ ParamID_E paramDescrFormat,
|
|
_Out_ BOOL * isReturnParam)
|
|
{
|
|
BOOL bResult = FALSE;
|
|
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
|
|
|
//UINT formatStringOffset = 0;
|
|
ProcFormatStringParam_U paramToAnalyze;
|
|
|
|
|
|
//following checks already done by the caller function
|
|
/* if (pRpcDecompilerCtxt == NULL) goto End;
|
|
if (pRpcDecompilerCtxt->pRpcViewHelper == NULL) goto End;
|
|
|
|
if(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString == NULL) goto End; */
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\n\n******************* RpcDecompilerGetReturnParamInfo *****************");
|
|
|
|
switch(paramDescrFormat)
|
|
{
|
|
case paramDescrOi:
|
|
//TODO
|
|
//paramSizeInBytes = OI_PARAM_BASETYPE_SIZE;
|
|
//paramSizeInBytes = OI_PARAM_OTHERTYPE_SIZE;
|
|
RPC_DEBUG_FN((UCHAR*)"\n!!! source = %s ligne = %d - RpcDecompilerGetReturnParamInfo : paramDescrOi not handled", __FILE__, __LINE__);
|
|
goto End;
|
|
break;
|
|
|
|
case paramDescrOif:
|
|
RPC_GET_PROCESS_DATA(
|
|
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + paramOffset),
|
|
¶mToAnalyze,
|
|
sizeof(paramToAnalyze)
|
|
);
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\nRpcDecompilerGetReturnParamInfo: paramToPrint.oif_Format.paramAttributes = 0x%x", paramToAnalyze.oif_Format.paramAttributes);
|
|
|
|
*isReturnParam = paramToAnalyze.oif_Format.paramAttributes.IsReturn;
|
|
break;
|
|
default:
|
|
RPC_DEBUG_FN((UCHAR*)"\n!!! RpcDecompilerGetReturnParamInfo : ERROR, paramDescrFormat not recognized");
|
|
bResult = FALSE;
|
|
goto End;
|
|
break;
|
|
}
|
|
|
|
End:
|
|
return bResult;
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
DWORD __fastcall getSimpleTypeMemorySize(_In_ FC_TYPE fcType)
|
|
{
|
|
switch(fcType)
|
|
{
|
|
|
|
case FC_BYTE:
|
|
case FC_CHAR:
|
|
case FC_SMALL:
|
|
case FC_USMALL:
|
|
return 1;
|
|
|
|
case FC_WCHAR:
|
|
case FC_SHORT:
|
|
case FC_USHORT:
|
|
return 2;
|
|
|
|
case FC_LONG:
|
|
case FC_ULONG:
|
|
case FC_ENUM16:
|
|
case FC_ENUM32:
|
|
case FC_ERROR_STATUS_T:
|
|
return 4;
|
|
|
|
case FC_FLOAT:
|
|
case FC_HYPER:
|
|
case FC_DOUBLE:
|
|
case FC_INT3264:
|
|
case FC_UINT3264:
|
|
return 8;
|
|
|
|
case FC_ZERO:
|
|
return 0;
|
|
|
|
case FC_IGNORE:
|
|
return POINTER_SIZE;
|
|
|
|
default:
|
|
return (DWORD)-1;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
BOOL __fastcall processSimpleType(
|
|
_In_ VOID* pContext,
|
|
_In_ FC_TYPE fcType,
|
|
_Inout_ ParamDesc& paramDesc,
|
|
_Inout_ std::ostringstream& oss)
|
|
{
|
|
if (printSimpleType(pContext, fcType, oss) == FALSE)
|
|
{
|
|
RPC_DEBUG_FN((UCHAR*)"[ERROR] processSimpleType : unknow type\n");
|
|
return FALSE;
|
|
}
|
|
|
|
// get simple type size
|
|
//paramDesc.setMemorySize(getSimpleTypeMemorySize(fcType));
|
|
|
|
displayPtrLevel(paramDesc.getuPtrLevel(), oss);
|
|
|
|
oss<<paramDesc.getStrTypeName();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
BOOL __fastcall printSimpleType(
|
|
_In_ VOID* pContext,
|
|
_In_ FC_TYPE fcType,
|
|
_Inout_ std::ostringstream& oss)
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(pContext);
|
|
|
|
switch(fcType)
|
|
{
|
|
case FC_BYTE:
|
|
oss<<"byte ";
|
|
break;
|
|
case FC_CHAR:
|
|
oss<<"char ";
|
|
break;
|
|
|
|
case FC_SMALL:
|
|
oss<<"small ";
|
|
break;
|
|
|
|
case FC_USMALL:
|
|
oss<<"unsigned small ";
|
|
break;
|
|
|
|
case FC_WCHAR:
|
|
oss <<"wchar_t ";
|
|
break;
|
|
|
|
case FC_SHORT:
|
|
oss << "short ";
|
|
break;
|
|
case FC_USHORT:
|
|
oss << "unsigned short ";
|
|
break;
|
|
|
|
case FC_LONG:
|
|
oss << "long ";
|
|
break;
|
|
|
|
case FC_ULONG:
|
|
oss << "unsigned long ";
|
|
break;
|
|
|
|
case FC_FLOAT:
|
|
oss << "float ";
|
|
break;
|
|
|
|
case FC_HYPER:
|
|
oss << "hyper ";
|
|
break;
|
|
|
|
case FC_DOUBLE:
|
|
oss << "double ";
|
|
break;
|
|
|
|
case FC_ENUM16:
|
|
oss << "/* enum_16 */ short ";
|
|
break;
|
|
|
|
case FC_ENUM32:
|
|
oss << " /* enum_32 : typedef [v1_enum] enum */ long ";
|
|
break;
|
|
|
|
case FC_ERROR_STATUS_T:
|
|
oss << "error_status_t ";
|
|
break;
|
|
|
|
case FC_IGNORE:
|
|
oss << "void* /* FC_IGNORE */ ";
|
|
break;
|
|
|
|
case FC_INT3264:
|
|
oss <<"__int3264 ";
|
|
break;
|
|
|
|
case FC_UINT3264:
|
|
oss << "unsigned __int3264 ";
|
|
break;
|
|
|
|
|
|
default :
|
|
oss << "[ERROR] parseBaseType : unknown type ("<<fcType<<")";
|
|
return FALSE; // TODO : ret FALSE
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
BOOL __fastcall rpcDumpType(
|
|
_In_ VOID* pContext,
|
|
_In_ ParamDesc& paramDesc,
|
|
_Inout_ std::list<TypeToDefine>& listProcTypes,
|
|
_Inout_ std::ostringstream& oss)
|
|
{
|
|
BOOL bResult = TRUE;
|
|
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
|
BYTE bFC_TYPE;
|
|
|
|
|
|
RPC_GET_PROCESS_DATA(
|
|
paramDesc.getRva(),
|
|
&bFC_TYPE,
|
|
sizeof(bFC_TYPE));
|
|
|
|
if(bResult == FALSE)
|
|
{
|
|
RPC_ERROR_FN("RpcGetProcessData failed\n");
|
|
return FALSE;
|
|
}
|
|
|
|
paramDesc.setFcType((FC_TYPE)bFC_TYPE);
|
|
|
|
switch(paramDesc.getFcType())
|
|
{
|
|
//------------------------------------
|
|
// Simple type
|
|
//------------------------------------
|
|
case FC_BYTE:
|
|
case FC_CHAR:
|
|
case FC_SMALL:
|
|
case FC_WCHAR:
|
|
case FC_SHORT:
|
|
case FC_USHORT:
|
|
case FC_LONG:
|
|
case FC_ULONG:
|
|
case FC_FLOAT:
|
|
case FC_HYPER:
|
|
case FC_DOUBLE:
|
|
case FC_ENUM16:
|
|
case FC_ENUM32:
|
|
case FC_ERROR_STATUS_T:
|
|
case FC_IGNORE:
|
|
case FC_INT3264:
|
|
case FC_UINT3264:
|
|
//processSimpleType(pContext,
|
|
bResult = processSimpleType(pContext, (FC_TYPE)bFC_TYPE, paramDesc, oss);
|
|
if (bResult==FALSE) RPC_ERROR_FN("processSimpleType failed\n");
|
|
break;
|
|
|
|
|
|
|
|
//------------------------------------
|
|
// Arrays
|
|
//------------------------------------
|
|
case FC_CARRAY:
|
|
bResult = processConformantArray(pContext,paramDesc.getRva(), (FC_TYPE)bFC_TYPE, paramDesc, listProcTypes, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processConformantArray failed\n");
|
|
break;
|
|
case FC_CVARRAY:
|
|
bResult = processConformantVaryingArray(pContext,paramDesc.getRva(), (FC_TYPE)bFC_TYPE, paramDesc, listProcTypes, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processConformantVaryingArray failed\n");
|
|
break;
|
|
case FC_SMFARRAY:
|
|
case FC_LGFARRAY:
|
|
bResult = processFixedSizeArray(pContext,paramDesc.getRva(), (FC_TYPE)bFC_TYPE, paramDesc, listProcTypes, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processFixedSizeArray failed\n");
|
|
break;
|
|
case FC_SMVARRAY:
|
|
case FC_LGVARRAY:
|
|
bResult = processVaryingArray(pContext,paramDesc.getRva(), (FC_TYPE)bFC_TYPE, paramDesc, listProcTypes, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processVaryingArray failed\n");
|
|
break;
|
|
case FC_BOGUS_ARRAY:
|
|
bResult = processComplexArray(pContext,paramDesc.getRva(), (FC_TYPE)bFC_TYPE, paramDesc, listProcTypes, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processComplexArray failed\n");
|
|
break;
|
|
//------------------------------------
|
|
// Structures
|
|
//------------------------------------
|
|
case FC_STRUCT:
|
|
case FC_PSTRUCT:
|
|
case FC_CSTRUCT:
|
|
case FC_CPSTRUCT:
|
|
case FC_CVSTRUCT:
|
|
case FC_BOGUS_STRUCT:
|
|
case FC_HARD_STRUCT:
|
|
bResult = processStructure(pContext, paramDesc.getRva(), (FC_TYPE)bFC_TYPE, paramDesc, listProcTypes, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processStructure failed\n");
|
|
break;
|
|
//------------------------------------
|
|
// Unions
|
|
//------------------------------------
|
|
case FC_ENCAPSULATED_UNION:
|
|
|
|
bResult = processEncapsulatedUnion(
|
|
pContext,
|
|
paramDesc.getRva(),
|
|
(FC_TYPE)bFC_TYPE,
|
|
paramDesc,
|
|
listProcTypes,
|
|
oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processEncapsulatedUnion failed\n");
|
|
break;
|
|
|
|
case FC_NON_ENCAPSULATED_UNION:
|
|
|
|
bResult = processNonEncapsulatedUnion(
|
|
pContext,
|
|
paramDesc.getRva(),
|
|
(FC_TYPE)bFC_TYPE,
|
|
paramDesc,
|
|
listProcTypes,
|
|
oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processNonEncapsulatedUnion failed\n");
|
|
break;
|
|
|
|
|
|
|
|
|
|
//------------------------------------
|
|
// Pointers
|
|
//------------------------------------
|
|
case FC_RP:
|
|
case FC_UP:
|
|
case FC_FP:
|
|
case FC_OP:
|
|
bResult = processStandardPointer(
|
|
pContext,
|
|
paramDesc.getRva(),
|
|
(FC_TYPE)bFC_TYPE,
|
|
paramDesc,
|
|
listProcTypes,
|
|
oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processStandardPointer failed\n");
|
|
break;
|
|
|
|
case FC_IP:
|
|
bResult = processInterfacePointer(
|
|
pContext,
|
|
paramDesc.getRva(),
|
|
paramDesc,
|
|
oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processInterfacePointer failed\n");
|
|
break;
|
|
|
|
case FC_BYTE_COUNT_POINTER:
|
|
bResult = processByteCountPointer(
|
|
pContext,
|
|
paramDesc.getRva(),
|
|
paramDesc,
|
|
listProcTypes,
|
|
oss
|
|
);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processByteCountPointer failed\n");
|
|
break;
|
|
|
|
//------------------------------------
|
|
// Strings
|
|
//------------------------------------
|
|
case FC_C_CSTRING:
|
|
case FC_C_WSTRING:
|
|
bResult = processConformantString(pContext, paramDesc.getRva(), (FC_TYPE)bFC_TYPE, paramDesc, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processConformantString failed\n");
|
|
break;
|
|
|
|
case FC_WSTRING:
|
|
case FC_CSTRING:
|
|
bResult = processNonConformantString(pContext, paramDesc.getRva(), (FC_TYPE)bFC_TYPE, paramDesc, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processNonConformantString failed\n");
|
|
break;
|
|
|
|
case FC_SSTRING:
|
|
case FC_C_SSTRING:
|
|
bResult = processStructureString(pContext, paramDesc.getRva(), (FC_TYPE)bFC_TYPE, paramDesc, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processStructureString failed\n");
|
|
break;
|
|
|
|
//------------------------------------
|
|
// Misc ...
|
|
//------------------------------------
|
|
case FC_BIND_CONTEXT:
|
|
bResult = processBindContext(pContext,paramDesc.getRva(), paramDesc, listProcTypes, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processBindContext failed\n");
|
|
break;
|
|
|
|
case FC_BLKHOLE:
|
|
bResult = process_FC_BLKHOLE(pContext, paramDesc.getRva(), paramDesc, listProcTypes, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("process_FC_BLKHOLE failed\n");
|
|
break;
|
|
|
|
case FC_RANGE:
|
|
bResult = processRange(pContext, paramDesc.getRva(), paramDesc, listProcTypes, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processRange failed\n");
|
|
break;
|
|
|
|
case FC_USER_MARSHAL:
|
|
bResult = processUserMarshal(pContext, paramDesc.getRva(), paramDesc, listProcTypes, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processUserMarshal failed\n");
|
|
break;
|
|
|
|
case FC_TRANSMIT_AS:
|
|
case FC_REPRESENT_AS:
|
|
bResult = processTransmitRepresentAs(pContext, paramDesc.getRva(), paramDesc, listProcTypes, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processTransmitRepresentAs failed\n");
|
|
break;
|
|
|
|
case FC_PIPE:
|
|
bResult = processPipe(pContext, paramDesc.getRva(), paramDesc, listProcTypes, oss);
|
|
if (bResult == FALSE) RPC_ERROR_FN("processPipe failed\n");
|
|
break;
|
|
|
|
case FC_ZERO:
|
|
|
|
oss << "/* FC_ZERO */";
|
|
bResult = TRUE;
|
|
break;
|
|
default:
|
|
RPC_ERROR_FN("Invalid type\n");
|
|
oss << "[ERROR] dump type : unknown type (0x" << std::hex << (int)bFC_TYPE << ")" << std::endl;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
BOOL __fastcall getTypeMemorySize(
|
|
_In_ VOID* pContext,
|
|
_In_ RVA_T pType,
|
|
_Out_ size_t* pszMemorySize,
|
|
_In_ BOOL bHasRangeOnConformance)
|
|
{
|
|
BOOL bResult = FALSE;
|
|
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
|
BYTE bFC_TYPE;
|
|
|
|
*pszMemorySize = 0;
|
|
|
|
RPC_GET_PROCESS_DATA(
|
|
pType,
|
|
&bFC_TYPE,
|
|
sizeof(bFC_TYPE));
|
|
|
|
if(bResult == FALSE)
|
|
{
|
|
RPC_DEBUG_FN((UCHAR*)"[ERROR] getTypeMemorySize : Unable to get process data\n");
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
switch(bFC_TYPE)
|
|
{
|
|
//------------------------------------
|
|
// Simple type
|
|
//------------------------------------
|
|
case FC_BYTE:
|
|
case FC_CHAR:
|
|
case FC_SMALL:
|
|
case FC_WCHAR:
|
|
case FC_SHORT:
|
|
case FC_USHORT:
|
|
case FC_LONG:
|
|
case FC_ULONG:
|
|
case FC_FLOAT:
|
|
case FC_HYPER:
|
|
case FC_DOUBLE:
|
|
case FC_ENUM16:
|
|
case FC_ENUM32:
|
|
case FC_ERROR_STATUS_T:
|
|
case FC_IGNORE:
|
|
case FC_INT3264:
|
|
case FC_UINT3264:
|
|
//processSimpleType(pContext,
|
|
(*pszMemorySize) = getSimpleTypeMemorySize((FC_TYPE)bFC_TYPE);
|
|
bResult = TRUE;
|
|
break;
|
|
|
|
|
|
|
|
//------------------------------------
|
|
// Arrays
|
|
//------------------------------------
|
|
case FC_CARRAY:
|
|
case FC_CVARRAY:
|
|
case FC_SMFARRAY:
|
|
case FC_LGFARRAY:
|
|
case FC_SMVARRAY:
|
|
case FC_LGVARRAY:
|
|
case FC_BOGUS_ARRAY:
|
|
*pszMemorySize = getArrayMemorySize(pContext, pType);
|
|
break;
|
|
|
|
|
|
//------------------------------------
|
|
// Structures
|
|
//------------------------------------
|
|
case FC_STRUCT:
|
|
case FC_PSTRUCT:
|
|
case FC_CSTRUCT:
|
|
case FC_CPSTRUCT:
|
|
case FC_CVSTRUCT:
|
|
case FC_BOGUS_STRUCT:
|
|
case FC_HARD_STRUCT:
|
|
bResult = getStructureMemorySize(pContext, pType, pszMemorySize);
|
|
|
|
break;
|
|
|
|
//------------------------------------
|
|
// Unions
|
|
//------------------------------------
|
|
case FC_ENCAPSULATED_UNION:
|
|
bResult = getEncapsulatedUnionMemorySize(pContext, pType, pszMemorySize);
|
|
break;
|
|
|
|
case FC_NON_ENCAPSULATED_UNION:
|
|
bResult = getNonEncapsulatedUnionMemorySize(pContext, pType, pszMemorySize, bHasRangeOnConformance);
|
|
break;
|
|
|
|
|
|
|
|
|
|
//------------------------------------
|
|
// Pointers / Strings / BIND_CONTEXT
|
|
//------------------------------------
|
|
case FC_RP:
|
|
case FC_UP:
|
|
case FC_FP:
|
|
case FC_OP:
|
|
case FC_IP:
|
|
case FC_BYTE_COUNT_POINTER:
|
|
case FC_C_CSTRING:
|
|
case FC_C_WSTRING:
|
|
case FC_WSTRING:
|
|
case FC_CSTRING:
|
|
case FC_BIND_CONTEXT:
|
|
*pszMemorySize = POINTER_SIZE;
|
|
bResult = TRUE;
|
|
break;
|
|
|
|
|
|
|
|
//------------------------------------
|
|
// Misc ...
|
|
//------------------------------------
|
|
case FC_BLKHOLE:
|
|
bResult = getFC_BLKHOLEMemorySize(pContext, pType, pszMemorySize, bHasRangeOnConformance);
|
|
break;
|
|
|
|
case FC_RANGE:
|
|
bResult = getRangeMemorySize(pContext, pType, pszMemorySize);
|
|
break;
|
|
|
|
case FC_USER_MARSHAL:
|
|
bResult = getUserMarshallMemorySize(pContext, pType, pszMemorySize);
|
|
break;
|
|
|
|
case FC_TRANSMIT_AS:
|
|
case FC_REPRESENT_AS:
|
|
bResult = getTransmitAsRepresentAsMemorySize(pContext, pType, pszMemorySize);
|
|
break;
|
|
|
|
case FC_PIPE:
|
|
bResult = getPipeMemorySize(pContext, pType, pszMemorySize, bHasRangeOnConformance);
|
|
break;
|
|
|
|
case FC_ZERO:
|
|
*pszMemorySize = 0;
|
|
bResult = TRUE;
|
|
break;
|
|
|
|
default:
|
|
bResult = FALSE;
|
|
RPC_DEBUG_FN("[ERROR] getTypeMemorySize : unable to get memory size for type : 0x%x \n", bFC_TYPE);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//// <DBG>
|
|
//if(bResult == TRUE)
|
|
//{
|
|
// RPC_PRINT_FN((UCHAR*)"getTypeMemorySize type : %x, size : %x \n", bFC_TYPE, *pszMemorySize);
|
|
//
|
|
//}
|
|
//else
|
|
//{
|
|
// RPC_PRINT_FN((UCHAR*)"getTypeMemorySize failed \n");
|
|
//}
|
|
//// </DBG>
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
BOOL __fastcall RpcDecompilerPrintParam(
|
|
_In_ VOID* pContext,
|
|
_In_ UINT paramOffset,
|
|
_In_ ParamID_E paramDescrFormat,
|
|
_Out_ UINT * paramSizeInBytes,
|
|
_In_ const IdlFunctionDesc& IdlFunctionDesc,
|
|
_Inout_ std::list<TypeToDefine>& listProcType,
|
|
_Inout_ std::ostringstream& oss)
|
|
{
|
|
BOOL bResult = FALSE;
|
|
RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext;
|
|
|
|
//UINT formatStringOffset = 0;
|
|
ProcFormatStringParam_U paramToPrint;
|
|
|
|
UINT32 argNbr = 0;
|
|
|
|
ParamDesc ParamDesc;
|
|
|
|
//following checks already done by the caller function
|
|
/* if (pRpcDecompilerCtxt == NULL) goto End;
|
|
if (pRpcDecompilerCtxt->pRpcViewHelper == NULL) goto End;
|
|
|
|
if(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString == NULL) goto End; */
|
|
|
|
|
|
switch(paramDescrFormat)
|
|
{
|
|
case paramDescrOi:
|
|
//TODO
|
|
//paramSizeInBytes = OI_PARAM_BASETYPE_SIZE;
|
|
//paramSizeInBytes = OI_PARAM_OTHERTYPE_SIZE;
|
|
goto End;
|
|
break;
|
|
|
|
|
|
case paramDescrOif:
|
|
*paramSizeInBytes = OIF_PARAM_SIZE;
|
|
|
|
RPC_GET_PROCESS_DATA(
|
|
(pRpcDecompilerCtxt->pRpcDecompilerInfo->pProcFormatString + paramOffset),
|
|
¶mToPrint,
|
|
sizeof(paramToPrint)
|
|
);
|
|
|
|
RPC_DEBUG_FN((UCHAR*)"\nparamToPrint.oif_Format.paramAttributes = 0x%x", paramToPrint.oif_Format.paramAttributes);
|
|
RPC_DEBUG_FN((UCHAR*)"\nparamToPrint.oif_Format.stack_offset = 0x%x", paramToPrint.oif_Format.stack_offset);
|
|
|
|
//*isReturnParam = paramToPrint.oif_Format.paramAttributes.IsReturn;
|
|
|
|
|
|
if(is64B) argNbr = paramToPrint.oif_Format.stack_offset / VIRTUAL_STACK_OFFSET_GRANULARITY_64B;
|
|
else argNbr = paramToPrint.oif_Format.stack_offset / VIRTUAL_STACK_OFFSET_GRANULARITY_32B;
|
|
|
|
|
|
// add param IdlFunctionDesc properties
|
|
if(IdlFunctionDesc.hasRangeOnConformance())
|
|
{
|
|
ParamDesc.setHasRangeOnConformance();
|
|
}
|
|
|
|
// fill param desc with ParamAttr
|
|
ParamDesc.fillWithParamAttr(paramToPrint.oif_Format.paramAttributes);
|
|
|
|
if( (!paramToPrint.oif_Format.paramAttributes.IsReturn) /*&&
|
|
(typeFieldType != ptrCommonSimpleDescr) &&
|
|
(typeFieldType != ptrCommonComplexDescr) &&
|
|
(typeFieldType != ptrInterfaceConstantIID) &&
|
|
(typeFieldType != ptrInterfaceNonConstantIIDDescr) &&
|
|
(typeFieldType != ptrByteCountSimpleDescr) &&
|
|
(typeFieldType != ptrByteCountComplexDescr)*/
|
|
// ) { RPC_PRINT_FN((UCHAR*)"_%d", paramOffset); RPC_DEBUG_FN((UCHAR*)"_%d", paramOffset);}
|
|
)
|
|
{
|
|
std::ostringstream ossTmp;
|
|
ossTmp << "arg_" << argNbr;
|
|
|
|
ParamDesc.setParamName(ossTmp.str());
|
|
|
|
RPC_DEBUG_FN((UCHAR*)" arg_%d", argNbr);
|
|
|
|
oss << std::endl << "\t\t";
|
|
|
|
if(paramToPrint.oif_Format.paramAttributes.IsIn && paramToPrint.oif_Format.paramAttributes.IsOut)
|
|
{
|
|
oss << "[in, out]";
|
|
RPC_DEBUG_FN((UCHAR*)"[in, out]");
|
|
}
|
|
else if (paramToPrint.oif_Format.paramAttributes.IsIn)
|
|
{
|
|
oss<<"[in]";
|
|
RPC_DEBUG_FN((UCHAR*)"[in]");
|
|
}
|
|
else // paramAttributes.IsOut
|
|
{
|
|
oss<<"[out]";
|
|
RPC_DEBUG_FN((UCHAR*)"[out]");
|
|
}
|
|
}
|
|
|
|
if(paramToPrint.oif_Format.paramAttributes.IsBasetype)
|
|
{
|
|
bResult = processSimpleType(
|
|
pContext,
|
|
(FC_TYPE)paramToPrint.oif_Format.paramType.base_type_format_char.type_format_char,
|
|
ParamDesc,
|
|
oss);
|
|
|
|
if(FALSE == bResult)
|
|
{
|
|
displayErrorMessage(oss, " unable to processSimpleType ");
|
|
goto End;
|
|
}
|
|
|
|
|
|
} //if(paramToPrint.oif_Format.paramAttributes.IsBasetype)
|
|
else
|
|
{
|
|
//ParamDesc.setuOffset(paramToPrint.oif_Format.paramType.other_type_offset); // param offset in type format string
|
|
ParamDesc.setRva(pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString + paramToPrint.oif_Format.paramType.other_type_offset);
|
|
|
|
bResult = rpcDumpType(
|
|
pContext,
|
|
ParamDesc,
|
|
listProcType,
|
|
oss);
|
|
|
|
if(bResult == FALSE)
|
|
{
|
|
displayErrorMessage(oss, " unable to dump type");
|
|
//RPC_DEBUG_FN((UCHAR*)"\n!!! source = %s ligne = %d - PrintParamOfFieldType returned bResult = %d", __FILE__, __LINE__, bResult);
|
|
goto End;
|
|
}
|
|
}// !(paramToPrint.oif_Format.paramAttributes.IsBasetype)
|
|
|
|
|
|
|
|
bResult = TRUE;
|
|
break;
|
|
|
|
|
|
default:
|
|
RPC_DEBUG_FN((UCHAR*)"\n!!! RpcDecompilerPrintParam : ERROR, paramDescrFormat not recognized");
|
|
bResult = FALSE;
|
|
goto End;
|
|
break;
|
|
}
|
|
|
|
End:
|
|
return (bResult);
|
|
}
|
|
|