* Parse visual basic object table * @param structureOffset Offset in file where the structure starts * @return @c true if object table was successfuly parsed, @c false otherwise */
| 1258 | * @return @c true if object table was successfuly parsed, @c false otherwise |
| 1259 | */ |
| 1260 | bool PeFormat::parseVisualBasicObjectTable(std::size_t structureOffset) |
| 1261 | { |
| 1262 | const auto &allBytes = getBytes(); |
| 1263 | std::vector<std::uint8_t> bytes; |
| 1264 | std::size_t offset = 0; |
| 1265 | std::uint64_t projectNameOffset = 0; |
| 1266 | std::uint64_t objectDescriptorsOffset = 0; |
| 1267 | struct VBObjectTable vbot; |
| 1268 | std::string projName; |
| 1269 | |
| 1270 | if (!getBytes(bytes, structureOffset, vbot.structureSize()) || bytes.size() != vbot.structureSize()) |
| 1271 | { |
| 1272 | return false; |
| 1273 | } |
| 1274 | |
| 1275 | DynamicBuffer structContent(bytes, retdec::utils::Endianness::LITTLE); |
| 1276 | vbot.null1 = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.null1); |
| 1277 | vbot.execCOMAddr = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.execCOMAddr); |
| 1278 | vbot.projecInfo2Addr = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.projecInfo2Addr); |
| 1279 | vbot.reserved = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.reserved); |
| 1280 | vbot.null2 = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.null2); |
| 1281 | vbot.projectObjectAddr = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.projectObjectAddr); |
| 1282 | std::memcpy(&vbot.objectGUID, static_cast<void *>(&bytes.data()[offset]), sizeof(vbot.objectGUID)); offset += sizeof(vbot.objectGUID); |
| 1283 | vbot.flagsCompileState = structContent.read<std::uint16_t>(offset); offset += sizeof(vbot.flagsCompileState); |
| 1284 | vbot.nObjects = structContent.read<std::uint16_t>(offset); offset += sizeof(vbot.nObjects); |
| 1285 | vbot.nCompiledObjects = structContent.read<std::uint16_t>(offset); offset += sizeof(vbot.nCompiledObjects); |
| 1286 | vbot.nUsedObjects = structContent.read<std::uint16_t>(offset); offset += sizeof(vbot.nUsedObjects); |
| 1287 | vbot.objectDescriptorsAddr = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.objectDescriptorsAddr); |
| 1288 | vbot.IDE1 = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.IDE1); |
| 1289 | vbot.IDE2 = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.IDE2); |
| 1290 | vbot.IDE3 = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.IDE3); |
| 1291 | vbot.projectNameAddr = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.projectNameAddr); |
| 1292 | vbot.LCID1 = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.LCID1); |
| 1293 | vbot.LCID2 = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.LCID2); |
| 1294 | vbot.IDE4 = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.IDE4); |
| 1295 | vbot.templateVesion = structContent.read<std::uint32_t>(offset); offset += sizeof(vbot.templateVesion); |
| 1296 | |
| 1297 | visualBasicInfo.setProjectPrimaryLCID(vbot.LCID1); |
| 1298 | visualBasicInfo.setProjectSecondaryLCID(vbot.LCID2); |
| 1299 | visualBasicInfo.setObjectTableGUID(vbot.objectGUID); |
| 1300 | |
| 1301 | if (!visualBasicInfo.hasProjectName() && getOffsetFromAddress(projectNameOffset, vbot.projectNameAddr)) |
| 1302 | { |
| 1303 | projName = retdec::utils::readNullTerminatedAscii(allBytes.data(), allBytes.size(), projectNameOffset, |
| 1304 | VB_MAX_STRING_LEN, true); |
| 1305 | visualBasicInfo.setProjectName(projName); |
| 1306 | } |
| 1307 | |
| 1308 | if (getOffsetFromAddress(objectDescriptorsOffset, vbot.objectDescriptorsAddr)) |
| 1309 | { |
| 1310 | parseVisualBasicObjects(objectDescriptorsOffset, vbot.nObjects); |
| 1311 | } |
| 1312 | |
| 1313 | visualBasicInfo.computeObjectTableHashes(); |
| 1314 | return true; |
| 1315 | } |
| 1316 | |
| 1317 | /** |
nothing calls this directly
no test coverage detected