Add Phoenix EVSA parser

This commit is contained in:
Nikolaj Schlej 2025-02-28 17:05:24 +07:00
parent f989fdfea1
commit b98edf6944
4 changed files with 556 additions and 3 deletions

View file

@ -0,0 +1,212 @@
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "phoenix_evsa.h"
#include "../kaitai/exceptions.h"
phoenix_evsa_t::phoenix_evsa_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = this; (void)p__root;
m_body = nullptr;
m__io__raw_body = nullptr;
_read();
}
void phoenix_evsa_t::_read() {
m_type = m__io->read_u1();
if (!(type() == 236)) {
throw kaitai::validation_not_equal_error<uint8_t>(236, type(), _io(), std::string("/seq/0"));
}
m_checksum = m__io->read_u1();
m_size = m__io->read_u2le();
if (!(size() == 20)) {
throw kaitai::validation_not_equal_error<uint16_t>(20, size(), _io(), std::string("/seq/2"));
}
m_signature = m__io->read_u4le();
if (!(signature() == 1095980613)) {
throw kaitai::validation_not_equal_error<uint32_t>(1095980613, signature(), _io(), std::string("/seq/3"));
}
m_attributes = m__io->read_u4le();
m_store_size = m__io->read_u4le();
m_reserved = m__io->read_u4le();
m__raw_body = m__io->read_bytes((store_size() - 20));
m__io__raw_body = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_body));
m_body = std::unique_ptr<evsa_body_t>(new evsa_body_t(m__io__raw_body.get(), this, m__root));
}
phoenix_evsa_t::~phoenix_evsa_t() {
_clean_up();
}
void phoenix_evsa_t::_clean_up() {
}
phoenix_evsa_t::evsa_entry_t::evsa_entry_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_body_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void phoenix_evsa_t::evsa_entry_t::_read() {
m_type = m__io->read_u1();
m_checksum = m__io->read_u1();
m_size = m__io->read_u2le();
switch (type()) {
case 239: {
m_body = std::unique_ptr<evsa_data_t>(new evsa_data_t(m__io, this, m__root));
break;
}
case 131: {
m_body = std::unique_ptr<evsa_data_t>(new evsa_data_t(m__io, this, m__root));
break;
}
case 227: {
m_body = std::unique_ptr<evsa_data_t>(new evsa_data_t(m__io, this, m__root));
break;
}
case 237: {
m_body = std::unique_ptr<evsa_guid_t>(new evsa_guid_t(m__io, this, m__root));
break;
}
case 226: {
m_body = std::unique_ptr<evsa_name_t>(new evsa_name_t(m__io, this, m__root));
break;
}
case 225: {
m_body = std::unique_ptr<evsa_guid_t>(new evsa_guid_t(m__io, this, m__root));
break;
}
case 238: {
m_body = std::unique_ptr<evsa_name_t>(new evsa_name_t(m__io, this, m__root));
break;
}
default: {
m_body = std::unique_ptr<evsa_unknown_t>(new evsa_unknown_t(m__io, this, m__root));
break;
}
}
}
phoenix_evsa_t::evsa_entry_t::~evsa_entry_t() {
_clean_up();
}
void phoenix_evsa_t::evsa_entry_t::_clean_up() {
}
phoenix_evsa_t::evsa_unknown_t::evsa_unknown_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void phoenix_evsa_t::evsa_unknown_t::_read() {
m_unknown = m__io->read_bytes(0);
}
phoenix_evsa_t::evsa_unknown_t::~evsa_unknown_t() {
_clean_up();
}
void phoenix_evsa_t::evsa_unknown_t::_clean_up() {
}
phoenix_evsa_t::evsa_body_t::evsa_body_t(kaitai::kstream* p__io, phoenix_evsa_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_entries = nullptr;
_read();
}
void phoenix_evsa_t::evsa_body_t::_read() {
m_entries = std::unique_ptr<std::vector<std::unique_ptr<evsa_entry_t>>>(new std::vector<std::unique_ptr<evsa_entry_t>>());
{
int i = 0;
while (!m__io->is_eof()) {
m_entries->push_back(std::move(std::unique_ptr<evsa_entry_t>(new evsa_entry_t(m__io, this, m__root))));
i++;
}
}
}
phoenix_evsa_t::evsa_body_t::~evsa_body_t() {
_clean_up();
}
void phoenix_evsa_t::evsa_body_t::_clean_up() {
}
phoenix_evsa_t::evsa_name_t::evsa_name_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void phoenix_evsa_t::evsa_name_t::_read() {
m_var_id = m__io->read_u2le();
m_name = m__io->read_bytes((_parent()->size() - 6));
}
phoenix_evsa_t::evsa_name_t::~evsa_name_t() {
_clean_up();
}
void phoenix_evsa_t::evsa_name_t::_clean_up() {
}
phoenix_evsa_t::evsa_guid_t::evsa_guid_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void phoenix_evsa_t::evsa_guid_t::_read() {
m_guid_id = m__io->read_u2le();
m_guid = m__io->read_bytes(16);
}
phoenix_evsa_t::evsa_guid_t::~evsa_guid_t() {
_clean_up();
}
void phoenix_evsa_t::evsa_guid_t::_clean_up() {
}
phoenix_evsa_t::evsa_data_t::evsa_data_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void phoenix_evsa_t::evsa_data_t::_read() {
m_guid_id = m__io->read_u2le();
m_var_id = m__io->read_u2le();
m_attributes = m__io->read_u4le();
n_data_size = true;
if ((attributes() & 268435456) != 268435456) {
n_data_size = false;
m_data_size = m__io->read_u4le();
}
n_data = true;
if ((attributes() & 268435456) == 268435456) {
n_data = false;
m_data = m__io->read_bytes((_parent()->size() - 12));
}
n_data_ext = true;
if ((attributes() & 268435456) != 268435456) {
n_data_ext = false;
m_data_ext = m__io->read_bytes(data_size());
}
}
phoenix_evsa_t::evsa_data_t::~evsa_data_t() {
_clean_up();
}
void phoenix_evsa_t::evsa_data_t::_clean_up() {
if (!n_data_size) {
}
if (!n_data) {
}
if (!n_data_ext) {
}
}

View file

@ -0,0 +1,242 @@
#pragma once
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "../kaitai/kaitaistruct.h"
#include <stdint.h>
#include <memory>
#include <vector>
#if KAITAI_STRUCT_VERSION < 9000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required"
#endif
class phoenix_evsa_t : public kaitai::kstruct {
public:
class evsa_entry_t;
class evsa_unknown_t;
class evsa_body_t;
class evsa_name_t;
class evsa_guid_t;
class evsa_data_t;
phoenix_evsa_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~phoenix_evsa_t();
class evsa_entry_t : public kaitai::kstruct {
public:
evsa_entry_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_body_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~evsa_entry_t();
private:
uint8_t m_type;
uint8_t m_checksum;
uint16_t m_size;
std::unique_ptr<kaitai::kstruct> m_body;
phoenix_evsa_t* m__root;
phoenix_evsa_t::evsa_body_t* m__parent;
public:
uint8_t type() const { return m_type; }
uint8_t checksum() const { return m_checksum; }
uint16_t size() const { return m_size; }
kaitai::kstruct* body() const { return m_body.get(); }
phoenix_evsa_t* _root() const { return m__root; }
phoenix_evsa_t::evsa_body_t* _parent() const { return m__parent; }
};
class evsa_unknown_t : public kaitai::kstruct {
public:
evsa_unknown_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~evsa_unknown_t();
private:
std::string m_unknown;
phoenix_evsa_t* m__root;
phoenix_evsa_t::evsa_entry_t* m__parent;
public:
std::string unknown() const { return m_unknown; }
phoenix_evsa_t* _root() const { return m__root; }
phoenix_evsa_t::evsa_entry_t* _parent() const { return m__parent; }
};
class evsa_body_t : public kaitai::kstruct {
public:
evsa_body_t(kaitai::kstream* p__io, phoenix_evsa_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~evsa_body_t();
private:
std::unique_ptr<std::vector<std::unique_ptr<evsa_entry_t>>> m_entries;
phoenix_evsa_t* m__root;
phoenix_evsa_t* m__parent;
public:
std::vector<std::unique_ptr<evsa_entry_t>>* entries() const { return m_entries.get(); }
phoenix_evsa_t* _root() const { return m__root; }
phoenix_evsa_t* _parent() const { return m__parent; }
};
class evsa_name_t : public kaitai::kstruct {
public:
evsa_name_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~evsa_name_t();
private:
uint16_t m_var_id;
std::string m_name;
phoenix_evsa_t* m__root;
phoenix_evsa_t::evsa_entry_t* m__parent;
public:
uint16_t var_id() const { return m_var_id; }
std::string name() const { return m_name; }
phoenix_evsa_t* _root() const { return m__root; }
phoenix_evsa_t::evsa_entry_t* _parent() const { return m__parent; }
};
class evsa_guid_t : public kaitai::kstruct {
public:
evsa_guid_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~evsa_guid_t();
private:
uint16_t m_guid_id;
std::string m_guid;
phoenix_evsa_t* m__root;
phoenix_evsa_t::evsa_entry_t* m__parent;
public:
uint16_t guid_id() const { return m_guid_id; }
std::string guid() const { return m_guid; }
phoenix_evsa_t* _root() const { return m__root; }
phoenix_evsa_t::evsa_entry_t* _parent() const { return m__parent; }
};
class evsa_data_t : public kaitai::kstruct {
public:
evsa_data_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~evsa_data_t();
private:
uint16_t m_guid_id;
uint16_t m_var_id;
uint32_t m_attributes;
uint32_t m_data_size;
bool n_data_size;
public:
bool _is_null_data_size() { data_size(); return n_data_size; };
private:
std::string m_data;
bool n_data;
public:
bool _is_null_data() { data(); return n_data; };
private:
std::string m_data_ext;
bool n_data_ext;
public:
bool _is_null_data_ext() { data_ext(); return n_data_ext; };
private:
phoenix_evsa_t* m__root;
phoenix_evsa_t::evsa_entry_t* m__parent;
public:
uint16_t guid_id() const { return m_guid_id; }
uint16_t var_id() const { return m_var_id; }
uint32_t attributes() const { return m_attributes; }
uint32_t data_size() const { return m_data_size; }
std::string data() const { return m_data; }
std::string data_ext() const { return m_data_ext; }
phoenix_evsa_t* _root() const { return m__root; }
phoenix_evsa_t::evsa_entry_t* _parent() const { return m__parent; }
};
private:
uint8_t m_type;
uint8_t m_checksum;
uint16_t m_size;
uint32_t m_signature;
uint32_t m_attributes;
uint32_t m_store_size;
uint32_t m_reserved;
std::unique_ptr<evsa_body_t> m_body;
phoenix_evsa_t* m__root;
kaitai::kstruct* m__parent;
std::string m__raw_body;
std::unique_ptr<kaitai::kstream> m__io__raw_body;
public:
uint8_t type() const { return m_type; }
uint8_t checksum() const { return m_checksum; }
uint16_t size() const { return m_size; }
uint32_t signature() const { return m_signature; }
uint32_t attributes() const { return m_attributes; }
uint32_t store_size() const { return m_store_size; }
uint32_t reserved() const { return m_reserved; }
evsa_body_t* body() const { return m_body.get(); }
phoenix_evsa_t* _root() const { return m__root; }
kaitai::kstruct* _parent() const { return m__parent; }
std::string _raw_body() const { return m__raw_body; }
kaitai::kstream* _io__raw_body() const { return m__io__raw_body.get(); }
};

View file

@ -0,0 +1,99 @@
meta:
id: phoenix_evsa
title: Phoenix EVSA NVRAM store
application: Phoenix-based UEFI firmware
file-extension: evsa
tags:
- firmware
license: CC0-1.0
ks-version: 0.9
endian: le
seq:
- id: type
type: u1
valid: 0xEC
- id: checksum
type: u1
- id: size
type: u2
valid: 20
- id: signature
type: u4
valid: 0x41535645
- id: attributes
type: u4
- id: store_size
type: u4
- id: reserved
type: u4
- id: body
type: evsa_body
size: store_size - 20
types:
evsa_guid:
seq:
- id: guid_id
type: u2
- id: guid
size: 16
evsa_name:
seq:
- id: var_id
type: u2
- id: name
size: _parent.size - 6
evsa_data:
seq:
- id: guid_id
type: u2
- id: var_id
type: u2
- id: attributes
type: u4
- id: data_size
type: u4
if: (attributes & 0x10000000) != 0x10000000
- id: data
size: _parent.size - 12
if: (attributes & 0x10000000) == 0x10000000
- id: data_ext
size: data_size
if: (attributes & 0x10000000) != 0x10000000
evsa_unknown:
seq:
- id: unknown
size: 0
evsa_entry:
seq:
- id: type
type: u1
- id: checksum
type: u1
- id: size
type: u2
- id: body
type:
switch-on: type
cases:
0xED: evsa_guid
0xE1: evsa_guid
0xEE: evsa_name
0xE2: evsa_name
0xEF: evsa_data
0xE3: evsa_data
0x83: evsa_data
_: evsa_unknown
evsa_body:
seq:
- id: entries
type: evsa_entry
repeat: eos

View file

@ -396,7 +396,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
// Add free space or padding after all variables, if needed
UINT32 freeSpaceOffset = vssVariableOffset - storeOffset;
if (freeSpaceOffset < storeSize) {
UByteArray freeSpace = vss.mid(freeSpaceOffset, storeSize - freeSpaceOffset);
UByteArray freeSpace = volumeBody.mid(freeSpaceOffset, storeSize - freeSpaceOffset);
// Add info
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());
@ -582,7 +582,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
// Add free space or padding after all variables, if needed
UINT32 freeSpaceOffset = vss2VariableOffset - storeOffset;
if (freeSpaceOffset < storeSize) {
UByteArray freeSpace = vss2.mid(freeSpaceOffset, storeSize - freeSpaceOffset);
UByteArray freeSpace = volumeBody.mid(freeSpaceOffset, storeSize - freeSpaceOffset);
// Add info
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());
@ -872,7 +872,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
// Add free space or padding after all variables, if needed
UINT32 freeSpaceOffset = sysfVariableOffset - storeOffset;
if (freeSpaceOffset < storeSize) {
UByteArray freeSpace = sysf.mid(freeSpaceOffset, storeSize - freeSpaceOffset);
UByteArray freeSpace = volumeBody.mid(freeSpaceOffset, storeSize - freeSpaceOffset);
// Add info
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());