#include #include #include #include "..\RpcCommon\RpcView.h" #include "internalRpcDecompTypeDefs.h" #include "internalComplexTypesStructs.h" #include "internalTypeTools.h" #include "internalRpcDecompiler.h" #include "internalRpcUtils.h" #include "internalComplexTypesPointers.h" BOOL __fastcall getStructureMemorySize( _In_ VOID* pContext, _In_ RVA_T pType, _Out_ size_t* pszStructureMemorySize) { RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext; BOOL bResult = FALSE; SimpleStructHeader_t structHeader; // header common to all kind of structures // read structure header in order to store it's memory size RPC_GET_PROCESS_DATA( pType, &structHeader, sizeof(SimpleStructHeader_t) ); if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] processStructure : unable to get process data"); return FALSE; } *pszStructureMemorySize = structHeader.memory_size; return TRUE; } BOOL __fastcall processStructure( _In_ VOID* pContext, _In_ RVA_T pType, _In_ const FC_TYPE fcType, _Inout_ ParamDesc& ParamDesc, _Inout_ std::list& listProcTypes, _Inout_ std::ostringstream& oss) { BOOL bResult = FALSE; RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext; SimpleStructHeader_t structHeader; // header common to all kind of structures UNREFERENCED_PARAMETER(fcType); // read structure header in order to store it's memory size RPC_GET_PROCESS_DATA( pType, &structHeader, sizeof(SimpleStructHeader_t) ); if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] processStructure : unable to get process data"); return FALSE; } //ParamDesc.setMemorySize(structHeader.memory_size); // declare structure param oss<<"struct Struct_"<< std::dec <pRpcDecompilerInfo->pTypeFormatString)<<"_t"; displayPtrLevel(ParamDesc.getuPtrLevel(), oss); oss<<" "<& vectMembersOffset) { BOOL bResult = FALSE; RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext; BYTE bRead; UINT uOffsetInMemberList = 0; while(1) { RPC_GET_PROCESS_DATA( pMemberLayout, &bRead, sizeof(bRead)); if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] defineType_FC_BOGUS_STRUCT : unable to get process data"); return FALSE; } if(isSimpleType((FC_TYPE)bRead)) // is this a simple type { // save member offset vectMembersOffset.push_back(uOffsetInMemberList); // increment offset counter uOffsetInMemberList += getSimpleTypeMemorySize((FC_TYPE)bRead); pMemberLayout += sizeof(bRead); } else if((FC_TYPE)bRead == FC_EMBEDDED_COMPLEX) // is this an embedded complex { StructNonBaseTypeMemberLayout_t structMemberLayout; //ParamDesc paramDesc; RVA_T pComplexType; size_t szComplexSize = 0; //std::list listUseless; //std::ostringstream ossUseless; RPC_GET_PROCESS_DATA(pMemberLayout, &structMemberLayout, sizeof(StructNonBaseTypeMemberLayout_t)); if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*)"[ERROR] buildStructureOffsetMemberVector : unable to get process data"); return FALSE; } //// dump type in order to get its size pComplexType = pMemberLayout + FIELD_OFFSET(StructNonBaseTypeMemberLayout_t, offsetToDescription) + structMemberLayout.offsetToDescription; ////paramDesc.setuOffset((UINT)(pComplexType - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString)); //paramDesc.setpType(pComplexType); //paramDesc.inheritProperties(structureDesc); //if (rpcDumpType(pContext, paramDesc, listUseless, ossUseless) == FALSE) //{ // RPC_DEBUG_FN((UCHAR*)"[ERROR] defineType_FC_BOGUS_STRUCT : unable to dump type"); // return FALSE; //} if(getTypeMemorySize(pContext, pComplexType, &szComplexSize, structureDesc.getHasRangeOnConformance()) == FALSE) { RPC_DEBUG_FN((UCHAR*)"[ERROR] buildStructureOffsetMemberVector : unable to get memory type size"); return FALSE; } // save member offset vectMembersOffset.push_back(uOffsetInMemberList); // increment offset counter uOffsetInMemberList += (UINT)szComplexSize; pMemberLayout += sizeof(StructNonBaseTypeMemberLayout_t); } else if((FC_TYPE)bRead == FC_POINTER) // is this a pointer { // save member offset vectMembersOffset.push_back(uOffsetInMemberList); // increment offset counter uOffsetInMemberList += POINTER_SIZE; pMemberLayout += sizeof(bRead); } else if((FC_TYPE)bRead >= FC_STRUCTPAD1 && (FC_TYPE)bRead <= FC_STRUCTPAD7) // is this PAD { // increment offset counter uOffsetInMemberList += bRead - (FC_STRUCTPAD1 - 1); pMemberLayout += sizeof(bRead); } else if((FC_TYPE)bRead == FC_PAD || (FC_TYPE)bRead == FC_END) // is this the end ? { // store last offset off the structure (useful when we have a conformant array) vectMembersOffset.push_back(uOffsetInMemberList); // and exit break; } else { RPC_DEBUG_FN((UCHAR*)"/* [ERROR] unknow member layout : 0x%x", bRead ); return FALSE; } } return TRUE; } BOOL __fastcall dumpEveryStructMember( _In_ VOID* pContext, _In_ RVA_T pMemberLayout, _In_opt_ RVA_T pPointerLayout, _In_ const TypeToDefine& structureDesc, _In_ const std::vector& vectMembersOffset, _Inout_ std::list& listAdditionalTypes, _Inout_ std::ostringstream& oss, _In_opt_ const std::map* pMapPointerLayout = NULL) { BOOL bResult = FALSE; RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext; BYTE bRead; UINT uStructMemberCounter = 0; UINT uPointerCounter = 0; while(TRUE) { RPC_GET_PROCESS_DATA( pMemberLayout, &bRead, sizeof(bRead)); if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] dumpEveryStructMember : unable to get process data"); return FALSE; } if((FC_TYPE)bRead == FC_END) // is this the end { break; } else if( ((FC_TYPE)bRead >= FC_STRUCTPAD1 && (FC_TYPE)bRead <= FC_STRUCTPAD7) || (FC_TYPE)bRead == FC_PAD) // is this PAD { // increment offset counter pMemberLayout += sizeof(bRead); } else if(bRead != FC_EMBEDDED_COMPLEX && pMapPointerLayout != NULL && pMapPointerLayout->find(vectMembersOffset[uStructMemberCounter]) != pMapPointerLayout->end()) // check if there's an entry in mapPointerLayout for current structure member { auto it = pMapPointerLayout->find(vectMembersOffset[uStructMemberCounter]); std::ostringstream ossTmp; oss<<"\t\t"; //set struct member name ossTmp << "\tStructMember"<second); if (rpcDumpType(pContext, paramDesc, listAdditionalTypes, oss) == FALSE) { RPC_DEBUG_FN((UCHAR*)"[ERROR] dumpEveryStructMember : unable to dump mapPointerLayout associated type"); oss << "/* [ERROR] dumpEveryStructMember : unable to dump mapPointerLayout associated type */" << std::endl; return FALSE; } // End of member printing oss<<";\n"; uStructMemberCounter++; pMemberLayout += sizeof(bRead); // type read should be a simple type (FC_LONG) } else if(isSimpleType((FC_TYPE)bRead)) // is this a simple type { std::stringstream ossTmp; ParamDesc paramDesc; oss<<"\t\t"; //set struct member name ossTmp << "\tStructMember" << uStructMemberCounter; paramDesc.setParamName(ossTmp.str()); paramDesc.setuStructMemberNum(uStructMemberCounter); // inherit its properties from structure paramDesc.inheritProperties(structureDesc); //simple type to print processSimpleType(pContext, (FC_TYPE)bRead, paramDesc, oss); // End of member printing oss<<";\n"; uStructMemberCounter ++; pMemberLayout += sizeof(bRead); } else if((FC_TYPE)bRead == FC_EMBEDDED_COMPLEX) // is this an embedded complex { std::ostringstream ossTmp; StructNonBaseTypeMemberLayout_t structMemberLayout; RVA_T pComplexType; oss<<"\t\t"; //set struct member name ossTmp << "\tStructMember"<pRpcDecompilerInfo->pTypeFormatString)); paramDesc.setRva(pComplexType); if (rpcDumpType(pContext, paramDesc, listAdditionalTypes, oss) == FALSE) { RPC_DEBUG_FN((UCHAR*)"[ERROR] dumpEveryStructMember : unable to dump type"); oss << "/* [ERROR] dumpEveryStructMember : unable to dump FC_EMBEDDED_COMPLEX type */" << std::endl; return FALSE; } // End of member printing oss<<";\n"; uStructMemberCounter++; pMemberLayout += sizeof(StructNonBaseTypeMemberLayout_t); } else if((FC_TYPE)bRead == FC_POINTER) // is this a pointer { std::ostringstream ossTmp; RVA_T pPointer; // check if pPointerLayout has been provide if(pPointerLayout == NULL) { RPC_DEBUG_FN((UCHAR*)"[ERROR] dumpEveryStructMember, a pointer need to be decoded but an empty pPointerLayout has been provided\n"); oss << "[ERROR] dumpEveryStructMember, a pointer need to be decoded but an empty pPointerLayout has been provided\n"; return FALSE; } oss<<"\t\t"; //set struct member name ossTmp << "\tStructMember"<pRpcDecompilerInfo->pTypeFormatString)); paramDesc.setRva(pPointer); bResult = rpcDumpType(pContext, paramDesc, listAdditionalTypes, oss); if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*)"[ERROR] dumpEveryStructMember : unable to dump FC_POINTER type"); oss << "/* [ERROR] dumpEveryStructMember : unable to dump FC_POINTER type */" << std::endl; return FALSE; } // End of member printing oss<<";\n"; // increment pointer counter uPointerCounter++; uStructMemberCounter++; pMemberLayout += sizeof(bRead); } else { RPC_DEBUG_FN((UCHAR*)"/* [ERROR] unknow member layout : 0x%x", bRead ); oss << "/* [ERROR] unknow member layout : 0x" << std::hex <<(int) bRead << std::dec << "*/" << std::endl; return FALSE; } } return TRUE; } BOOL __fastcall parseNoRepeat( _In_ VOID* pContext, _In_ RVA_T pPointerInstanceLayout, _Out_ std::map& mapPointerLayout, _Out_ size_t* pSzPointerInstanceLayout) { BOOL bResult = FALSE; RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext; SingleInstancePtrToSimpleType_t singleInstancePtr; RVA_T pPtrDesc; RPC_GET_PROCESS_DATA(pPointerInstanceLayout, &singleInstancePtr, sizeof(singleInstancePtr)); if(FALSE == bResult) { RPC_DEBUG_FN((UCHAR*) "[ERROR] parseNoRepeat : unable to get process data"); return FALSE; } pPtrDesc = pPointerInstanceLayout + OFFSET_SINGLE_INSTANCE_TO_PTR_DESC; mapPointerLayout.insert( std::pair(singleInstancePtr.pointerInstance.offsetToPtrInBuffer, pPtrDesc)); // set szPointerInstanceLayout size *pSzPointerInstanceLayout = sizeof(singleInstancePtr); return TRUE; } BOOL __fastcall parseVariableRepeat( _In_ VOID* pContext, _In_ RVA_T pPointerInstanceLayout, _Inout_ std::map& mapPointerLayout, _Out_ size_t* pSzPointerInstanceLayout) { BOOL bResult = FALSE; RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext; VariableRepeatPtr_t variableRepeatPtr; PointerInstance_t pointerInstanceRead; RVA_T pPointerInstance = NULL; RPC_GET_PROCESS_DATA(pPointerInstanceLayout, &variableRepeatPtr, sizeof(variableRepeatPtr)); if(FALSE == bResult) { RPC_DEBUG_FN((UCHAR*) "[ERROR] parseNoRepeat : unable to get process data"); return FALSE; } pPointerInstance = pPointerInstanceLayout + sizeof(VariableRepeatPtr_t); for(int i=0; i( pointerInstanceRead.offsetToPtrInBuffer, pPointerInstance + FIELD_OFFSET(PointerInstance_t, pointerDescription))); pPointerInstance += sizeof(pointerInstanceRead); } // set szPointerInstanceLayout size *pSzPointerInstanceLayout = (pPointerInstance - pPointerInstanceLayout); return TRUE; } BOOL __fastcall parseFixedRepeat() { return FALSE; } BOOL __fastcall parsePointerLayout( _In_ VOID* pContext, _In_ const RVA_T pPointerLayout, _Inout_ std::map& mapPointerLayout, _Out_ size_t* pSzPointerLayout, _Inout_ std::ostringstream& oss) { BOOL bResult = FALSE; RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext; PointerLayoutHeader_t pointerLayoutHeader; RVA_T pStream = pPointerLayout; BYTE bFcType; *pSzPointerLayout = 0; //oss << std::endl << "\t/*DBG DUMP : "; //int i = 0; //while(true) //{ // BYTE bRead; // RPC_GET_PROCESS_DATA((pStream+i), &bRead, sizeof(bRead)); // oss << std::hex << " 0x"<<(int)bRead; // if(i++ == 128) // { // break; // } //} //oss << " */"; // read header RPC_GET_PROCESS_DATA(pStream, &pointerLayoutHeader, sizeof(pointerLayoutHeader)); if(FALSE == bResult) { RPC_DEBUG_FN((UCHAR*) "[ERROR] parsePointerLayout : unable to get process data"); return FALSE; } if(pointerLayoutHeader.pointerType != FC_PP) { RPC_DEBUG_FN((UCHAR*) "[ERROR] parsePointerLayout : not a pointer layout"); oss << " // [ERROR] parsePointerLayout : not a pointer layout" << std::endl; return FALSE; } pStream += sizeof(pointerLayoutHeader); // read pointer description RPC_GET_PROCESS_DATA(pStream, &bFcType, sizeof(bFcType)); if(FALSE == bResult) { RPC_DEBUG_FN((UCHAR*) "[ERROR] parsePointerLayout : unable to get process data"); return FALSE; } // FC_END means it's the end of pointers description while((FC_TYPE)bFcType != FC_END) { size_t szPointerInstanceLayout = 0; if(bFcType == FC_NO_REPEAT) { if( parseNoRepeat(pContext, pStream, mapPointerLayout, &szPointerInstanceLayout) == FALSE) { oss << " // [ERROR] parsePointerLayout : error in parseNoRepeat "; return FALSE; } pStream += (RVA_T)szPointerInstanceLayout; } else if(bFcType == FC_VARIABLE_REPEAT) { if( parseVariableRepeat(pContext, pStream, mapPointerLayout, &szPointerInstanceLayout) == FALSE) { oss << " // [ERROR] parsePointerLayout : error in parseVariableRepeat "; return FALSE; } pStream += (RVA_T)szPointerInstanceLayout; } else if(bFcType == FC_FIXED_OFFSET) { oss << " // [ERROR] parsePointerLayout : error, parseFixedOffset not implemented"; return FALSE; } else { oss << " // [ERROR] parsePointerLayout : unknown pointer layout type : (0x" << std::hex << bFcType << ")"; return FALSE; } RPC_GET_PROCESS_DATA(pStream, &bFcType, sizeof(bFcType)); if(FALSE == bResult) { RPC_DEBUG_FN((UCHAR*) "[ERROR] parsePointerLayout : unable to get process data"); return FALSE; } }//while((FC_TYPE)bFcType != FC_END) // compute pointerLayout size *pSzPointerLayout = (size_t) ((pStream + 1) - pPointerLayout); return TRUE; } BOOL __fastcall defineTypeSimpleStruct( _In_ VOID* pContext, _In_ RVA_T pType, _In_ const TypeToDefine& structureDesc, _Inout_ std::list& listAdditionalType, _Inout_ std::ostringstream& oss) { BOOL bResult = FALSE; RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext; SimpleStructHeader_t SimpleStructHeader; RVA_T pMemberLayout = NULL; std::map mapPointerLayout; UINT uStructId = (UINT32)(pType - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString); #ifdef DBG_DECOMP oss << std::endl << "\t/*FC_STRUCT || FC_PSTRUCT */" ; #endif oss < //oss << " /* DBG : mapPointerLayout " << std::endl; //for(auto iter=mapPointerLayout.begin(); iter != mapPointerLayout.end(); iter++) //{ // oss << "offset : 0x" << std::hex <<(int)iter->first << ", "; // oss << " pointer desc : " << std::hex << (LONGLONG) iter->second; // oss << std::endl; //} //oss << " */" << std::endl; // pMemberLayout = pPointerLayout + (RVA_T)szPointerLayout; } else // structure is a simple structure without pointer { pMemberLayout = pType + sizeof(SimpleStructHeader); } // building of a vector associating every member // to its offset std::vector vectMembersOffset; if(buildStructureOffsetMemberVector(pContext, pMemberLayout, structureDesc, vectMembersOffset) == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] defineTypeSimpleStruct : unable to build structure member offset"); return FALSE; } // then let's dump every struct member bResult = dumpEveryStructMember( pContext, pMemberLayout, NULL, // no pointer layout structureDesc, vectMembersOffset, listAdditionalType, oss, &mapPointerLayout); if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] defineTypeSimpleStruct : unable to dumpEveryStructMember"); return FALSE; } //close the structure declaration oss<<"\t}Struct_"<& listAdditionalType, _Inout_ std::ostringstream& oss) { BOOL bResult = FALSE; RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext; ConfStructHeader_t confStructHeader; std::map mapPointerLayout; RVA_T pMemberLayout; RVA_T pArrayDescription; UINT uStructId = (UINT32)(pType - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString); UINT uStructMemberCount; #ifdef DBG_DECOMP oss << std::endl << "\t/*FC_CSTRUCT*/" ; #endif oss<<"\n\ttypedef struct Struct_"<< std::dec << uStructId<<"_t\n\t{\n"; RPC_GET_PROCESS_DATA( pType, &confStructHeader, sizeof(confStructHeader) ); if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] defineType_FC_CSTRUCT : unable to get process data"); return FALSE; } // compute pArrayDescription pArrayDescription = pType + FIELD_OFFSET(ConfStructHeader_t, offsetToArrayDescription) + confStructHeader.offsetToArrayDescription; //+ sizeof(confStructHeader.structType) //+ sizeof(confStructHeader.alignment) //+ sizeof(confStructHeader.memory_size) //+ confStructHeader.offsetToArrayDescription; // check if it's a structure with pointers if(confStructHeader.structType == FC_CPSTRUCT) { RVA_T pPointerLayout = pType + sizeof(confStructHeader); size_t szPointerLayout = 0; bResult = parsePointerLayout(pContext, pPointerLayout, mapPointerLayout, &szPointerLayout,oss); if(bResult == FALSE) { oss << "[ERROR] an error has occured in parsePointerLayout\n"; return FALSE; } pMemberLayout = pPointerLayout + (RVA_T)szPointerLayout; } else // structure is a simple structure without pointer { pMemberLayout = pType + sizeof(confStructHeader); } // first let's build a vect list associating every member // to its offset std::vector vectMembersOffset; if(buildStructureOffsetMemberVector(pContext, pMemberLayout, structureDesc, vectMembersOffset) == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] defineType_FC_CSTRUCT : unable to build structure member offset"); return FALSE; } // then let's dump every struct member bResult = dumpEveryStructMember( pContext, pMemberLayout, NULL, structureDesc, vectMembersOffset, listAdditionalType, oss); if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] defineType_FC_CSTRUCT : unable to dumpEveryStructMember"); return FALSE; } // dump last struct member (conformant string or array) { uStructMemberCount = (UINT) vectMembersOffset.size() - 1; // last struct member count is equal to the size of vectMemberOffset std::stringstream ss; ss << "StructMember" << uStructMemberCount ; ParamDesc lastStructMember(ss.str(), uStructMemberCount, vectMembersOffset); // TODO rassembler le inherit dans le constructeur lastStructMember.inheritProperties(structureDesc); lastStructMember.setRva(pArrayDescription); oss<<"\t"; bResult = rpcDumpType( pContext, lastStructMember, listAdditionalType, oss); oss<<";" << std::endl << "\t" ; if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] defineType_FC_CSTRUCT : unable to Dump last member"); return FALSE; } } //close the structure declaration oss<<"\t}Struct_"<& listAdditionalType, _Inout_ std::ostringstream& oss) { BOOL bResult = FALSE; RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext; ComplexStructHeader_t complexStructHeader; RVA_T pMemberLayout; RVA_T pPointerLayout; RVA_T pConformantArrayDescription = NULL; UINT uStructId = (UINT32)(pType - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString); UINT uStructMemberCount; #ifdef DBG_DECOMP oss << std::endl << "\t/*FC_BOGUS_STRUCT*/" ; #endif oss<<"\n\ttypedef struct Struct_"<< std::dec << uStructId<<"_t\n\t{\n"; RPC_GET_PROCESS_DATA( pType, &complexStructHeader, sizeof(ComplexStructHeader_t) ); if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] defineType_FC_BOGUS_STRUCT : unable to get process data"); return FALSE; } // compute PointerLayout pPointerLayout = pType + sizeof(complexStructHeader.structType) + sizeof(complexStructHeader.alignment) + sizeof(complexStructHeader.memory_size) + sizeof(complexStructHeader.offsetToArrayDescription) + complexStructHeader.offsetToPointerLayout; // compute pArrayDescription if needed if(complexStructHeader.offsetToArrayDescription != 0) { pConformantArrayDescription = pType + sizeof(complexStructHeader.structType) + sizeof(complexStructHeader.alignment) + sizeof(complexStructHeader.memory_size) + complexStructHeader.offsetToArrayDescription; } pMemberLayout = pType + sizeof(ComplexStructHeader_t); // first let's build a vect list associating every member // to its offset std::vector vectMembersOffset; if(buildStructureOffsetMemberVector(pContext, pMemberLayout, structureDesc, vectMembersOffset) == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] defineType_FC_BOGUS_STRUCT : unable to build structure member offset"); return FALSE; } // then let's dump every struct member bResult = dumpEveryStructMember( pContext, pMemberLayout, pPointerLayout, structureDesc, vectMembersOffset, listAdditionalType, oss); if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] defineType_FC_BOGUS_STRUCT : unable to dumpEveryStructMember"); return FALSE; } // if needed let's dump conformant_array_description if(pConformantArrayDescription != NULL) { uStructMemberCount = (UINT) vectMembersOffset.size() - 1; // last struct member count is equal to the size of vectMemberOffset std::stringstream ss; ss << "StructMember" << uStructMemberCount ; ParamDesc lastStructMember(ss.str(), uStructMemberCount, vectMembersOffset); lastStructMember.inheritProperties(structureDesc); lastStructMember.setRva(pConformantArrayDescription); lastStructMember.setArrayIsAttributedPointer(); oss<<"\t"; bResult = rpcDumpType( pContext, lastStructMember, listAdditionalType, oss); oss<<";" << std::endl << "\t" ; if(bResult == FALSE) { RPC_DEBUG_FN((UCHAR*) "[ERROR] defineType_FC_BOGUS_STRUCT : unable to Dump last member"); return FALSE; } } //close the structure declaration oss<<"\t}Struct_"< memory_size<2> reserved<4> enum_offset<2> copy_size<2> mem_copy_incr<2> union_description_offset<2> member_layout<> FC_END */ //BOOL __fastcall defineTypeHardStruct( // _In_ VOID* pContext, // _In_ PBYTE pType, // _Out_ std::list& listProcTypes, // _Out_ std::ostringstream& oss) //{ // BOOL bResult = FALSE; // RpcDecompilerCtxt_T * pRpcDecompilerCtxt = (RpcDecompilerCtxt_T *) pContext; // // HardStructHeader_t hardStructHeader; // // // PBYTE pMemberLayout; // PBYTE pEnum; // PBYTE pUnion; // // UINT uStructId = (UINT32)(pType - pRpcDecompilerCtxt->pRpcDecompilerInfo->pTypeFormatString); // // oss< vectMembersOffset; // if(buildStructureOffsetMemberVector(pContext, pMemberLayout, vectMembersOffset) == FALSE) // { // RPC_DEBUG_FN((UCHAR*) "[ERROR] defineType_FC_HARD_STRUCT : unable to build structure member offset"); // return FALSE; // } // // // // then let's dump every struct member // bResult = dumpEveryStructMember( // pContext, // pMemberLayout, // NULL, // vectMembersOffset, // listProcTypes, // oss); // // if(bResult == FALSE) // { // RPC_DEBUG_FN((UCHAR*) "[ERROR] defineType_FC_HARD_STRUCT : unable to dumpEveryStructMember"); // return FALSE; // // } // // // // and finaly dump last member : enum or union // // //close the structure declaration // oss<<"\t}Struct_"<