18#include <radio_tool/fw/tyt_fw.hpp>
19#include <radio_tool/util.hpp>
25 const auto HeaderSize = 0x100;
27 auto i = std::ifstream(file, std::ios_base::binary);
30 auto header = ReadHeader(i);
33 firmware_model = std::string(header.radio, header.radio + strlen((
const char*)header.radio));
34 counterMagic = std::vector<uint8_t>(header.counter_magic, header.counter_magic + 1 + header.counter_magic[0]);
35 radio_model = GetRadioFromMagic(counterMagic);
38 for (uint32_t nMem = 0; nMem < header.n_regions; nMem++)
40 uint32_t rStart = 0, rLength = 0;
41 i.read((
char*)&rStart, 4);
42 i.read((
char*)&rLength, 4);
43 memory_ranges.push_back(std::make_pair(rStart, rLength));
44 binarySize += rLength;
50 data.resize(binarySize);
51 i.read((
char*)data.data(), data.size());
60 std::ofstream fout(file, std::ios_base::binary);
67 std::copy(tyt::magic::begin.begin(), tyt::magic::begin.end(), h.magic);
68 std::copy(firmware_model.begin(), firmware_model.end(), h.radio);
69 for (
auto cx = 0; cx < 76; cx++)
73 h.counter_magic[cx] = 0xff;
77 h.counter_magic[cx] = cx;
80 std::copy(counterMagic.begin(), counterMagic.end(), h.counter_magic);
81 h.n_regions = memory_ranges.size();
87 for (
const auto& rx : memory_ranges)
89 fout.write((
char*)&rx.first,
sizeof(uint32_t));
90 fout.write((
char*)&rx.second,
sizeof(uint32_t));
94 for (uint32_t pad_x = 0; pad_x < 0x80 - (
sizeof(uint32_t) * memory_ranges.size() * 2); pad_x++)
100 fout.write((
char*)data.data(), data.size());
103 for (
auto pad_end = 0; pad_end < 0x100 - 16; pad_end++)
109 fout.write((
char*)tyt::magic::end.data(), tyt::magic::end.size());
117 std::stringstream out;
118 out <<
"== TYT Firmware == " << std::endl
119 <<
"Radio: " << firmware_model <<
" (" << radio_model <<
")" << std::endl
120 <<
"Size: " << FormatBytes(
data.size()) << std::endl
121 <<
"Data Segments: " << std::endl;
125 out <<
" " << n++ <<
": Start=0x" << std::setfill(
'0') << std::setw(8) << std::hex << m.first
126 <<
", Length=0x" << std::setfill(
'0') << std::setw(8) << std::hex << m.second
138 if (ret.n_regions == std::numeric_limits<uint32_t>::max())
148 if (!std::equal(tyt::magic::begin.begin(), tyt::magic::begin.end(), header.magic))
150 throw std::runtime_error(
"Invalid start magic");
153 if (header.counter_magic[0] > 3)
155 throw std::runtime_error(
"Invalid counter magic length");
158 auto magic_match =
false;
159 for (
const auto& r : tyt::config::All)
162 if (std::equal(r.counter_magic.begin(), r.counter_magic.end(), header.counter_magic))
170 throw std::runtime_error(
"Counter magic is invalid, or not supported");
173 if ((header.n_regions * 8) > 0x80)
175 throw std::runtime_error(
"Memory region count out of bounds");
182 i.open(file, i.binary);
185 auto header = ReadHeader(i);
192 catch (std::exception&)
201 throw std::runtime_error(
"Can't open firmware file");
207 for (
const auto& mx : tyt::config::All)
209 if (mx.radio_model == model)
225 for (
const auto& rg : tyt::config::All)
227 if (rg.radio_model == model)
229 counterMagic = rg.counter_magic;
230 radio_model = rg.radio_model;
231 firmware_model = rg.firmware_model;
247auto TYTFW::ApplyXOR() ->
void
249 const uint8_t* xor_model =
nullptr;
250 uint32_t xor_len = 1024;
252 for (
const auto& r : tyt::config::All)
254 if (std::equal(r.counter_magic.begin(), r.counter_magic.end(), counterMagic.begin(), counterMagic.end()))
256 xor_model = r.cipher;
257 xor_len = r.cipher_len;
262 if (xor_model ==
nullptr)
264 throw std::runtime_error(
"No cipher found");
267 radio_tool::ApplyXOR(data, xor_model, xor_len);
272 if (
typeid(Other) !=
typeid(
this)) {
276 auto afw =
dynamic_cast<const TYTFW*
>(Other);
277 return afw->radio_model == radio_model
278 && afw->firmware_model == firmware_model;