#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 #include #include #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 & listTypesToDefine, _Inout_ std::list& 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 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 & listTypesToDefine, _Inout_ std::ostringstream& oss) { std::list 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 & listProcTypes, _Out_ std::ostringstream& oss ) { std::list listAllTypesSorted; std::ostringstream ossUseless; /*oss<<"/*"<uOffset<<" "; } oss<<""<& 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 "< 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<& 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; } //// //if(bResult == TRUE) //{ // RPC_PRINT_FN((UCHAR*)"getTypeMemorySize type : %x, size : %x \n", bFC_TYPE, *pszMemorySize); // //} //else //{ // RPC_PRINT_FN((UCHAR*)"getTypeMemorySize failed \n"); //} //// 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& 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); }