// ImHex Pattern for Radar .out Data Files (v14 - Automatic File-based Parser) #pragma require 1.30 #pragma endian little // ================================================================================== // --- ENUMS --- // ================================================================================== enum MasterMode : u32 { IDLE_MASTER_MODE = 0, INT_BIT_MASTER_MODE = 1, GM_MASTER_MODE = 2, DBS_MASTER_MODE = 3, RWS_MASTER_MODE = 4, VS_MASTER_MODE = 5, ACM_MASTER_MODE = 6, TWS_MASTER_MODE = 7, SEA_LOW_MASTER_MODE = 8, SEA_HIGH_MASTER_MODE = 9, GMTI_MASTER_MODE = 10, BCN_MASTER_MODE = 11, SAM_MASTER_MODE = 12, TA_MASTER_MODE = 13, WA_MASTER_MODE = 14, STT_MASTER_MODE = 15, DTT_MASTER_MODE = 16, SSTT_MASTER_MODE = 17, ACQ_MASTER_MODE = 18, FTT_MASTER_MODE = 19, AGR_MASTER_MODE = 20, SAR_MASTER_MODE = 21, INVALID_MASTER_MODE_ = 22, XTST_DUMMY_MODE = 23, XTST_HW_VALIDATION_MODE = 24, BOOT_MASTER_MODE = 25 }; // ================================================================================== // --- Basic Types and Constants --- // ================================================================================== using c_boolean = u32; using c_radians_t = float; const u32 LEGACY_MARKER_WORD = 0x5A5A5A5A; const u32 ID_DSPHDRIN = 1213223748; const u32 ID_DSPHDROUT_DISCRIMINATOR = 1431261764; const u32 ID_STT_LAA = 1599362131; const u32 ID_STT_LAA_DISCRIMINATOR = 4276556; // ================================================================================== // --- Data Structures --- // ================================================================================== // Definizioni delle struct come prima... struct PacketDescriptor { u32 npri; u32 nrbin; u32 num_of_channels; u32 block_dimension; u32 signal_ordering; }; struct SignalDescriptor { u32 batch_counter; u32 ttag; PacketDescriptor packet_descr; u32 packet_length; u32 number_of_packet_signal; }; struct ModeDescriptor { MasterMode master_mode; u32 operation_mode; c_boolean standby; c_boolean radiate; u32 waveform; u32 range_scale; u32 scan_rate; u32 dsp_mode_qualifier; u32 vuoto[8]; }; struct GeHeader { u8 header_info_padding[60]; SignalDescriptor signal_descr; ModeDescriptor mode; u8 remaining_padding[844]; }; struct TargetFilteringResults { float state_estimation[4]; float covariance_matrix[16]; float residual; float normalized_residual; float residual_variance; c_boolean validity_of_the_measure; c_boolean filter_is_working; }; struct MostImportantTargetData { s32 target_id; c_boolean target_is_valid; TargetFilteringResults range_filtering_results; TargetFilteringResults range_rate_filtering_results; TargetFilteringResults azimuth_filtering_results; TargetFilteringResults elevation_filtering_results; }; struct TrackManagementData { c_boolean track_is_on; c_boolean track_file_is_valid; c_boolean target_is_on_track; s32 type_of_tracking; float time_on_track; float track_file_age; s32 number_of_consecutive_misses; c_radians_t boresight_error_azimuth; c_radians_t boresight_error_elevation; }; struct LocalAATrackingData { MostImportantTargetData data_for_the_most_important_target; TrackManagementData track_management; }; // ================================================================================== // --- Main Block Definition --- // ================================================================================== struct RadarBlock { // L'header del blocco struct Header { u32 marker1; u32 marker2; u8 padding_to_size[0x14 - 8]; u32 declared_payload_size_bytes; u8 padding_to_name_id[0x44 - 0x18]; u32 name_id; u32 discriminator; } header; u8 block_header_padding[144 - sizeof(header)]; // Il payload letto come dati grezzi u8 payload_data[this.header.declared_payload_size_bytes]; // Viste condizionali sul payload GeHeader ge_header [[ addr(this.payload_data.addr()), if(this.header.name_id == ID_DSPHDRIN && this.header.discriminator != ID_DSPHDROUT_DISCRIMINATOR) ]]; LocalAATrackingData tracking_data [[ addr(this.payload_data.addr()), if((this.header.name_id == ID_DSPHDRIN && this.header.discriminator == ID_DSPHDROUT_DISCRIMINATOR) || (this.header.name_id == ID_STT_LAA && this.header.discriminator == ID_STT_LAA_DISCRIMINATOR)) ]]; } [[size(this.header.declared_payload_size_bytes + 144)]]; // Struttura principale del file che scansiona automaticamente struct FileFormat { while(!eof()) { u64 current_pos = tell(); // Leggiamo i primi 8 byte per verificare il marcatore struct { u32 m1; u32 m2; } peek_marker @ current_pos; if (peek_marker.m1 == LEGACY_MARKER_WORD && peek_marker.m2 == LEGACY_MARKER_WORD) { RadarBlock block; } else { // Se non รจ un marcatore, salta un byte e continua la ricerca [[hidden]] u8 junk_data; } } }; // Punto di ingresso del pattern: applica FileFormat all'inizio del file FileFormat file @ 0;