This page hosts a formal specification of Android nanoapp header using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
All parsing code for C++11/STL generated by Kaitai Struct depends on the C++/STL runtime library. You have to install it before you can parse data.
For C++, the easiest way is to clone the runtime library sources and build them along with your project.
Using Kaitai Struct in C++/STL usually consists of 3 steps.
std::istream
). One can open local file for that, or use existing std::string
or char*
buffer.
#include <fstream>
std::ifstream is("path/to/local/file.napp_header", std::ifstream::binary);
#include <sstream>
std::istringstream is(str);
#include <sstream>
const char buf[] = { ... };
std::string str(buf, sizeof buf);
std::istringstream is(str);
#include "kaitai/kaitaistream.h"
kaitai::kstream ks(&is);
android_nanoapp_header_t data(&ks);
After that, one can get various attributes from the structure by invoking getter methods like:
data.header_version() // => get header version
#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>
#if KAITAI_STRUCT_VERSION < 9000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required"
#endif
/**
* \sa https://android.googlesource.com/platform/system/chre/+/a7ff61b9/build/build_template.mk#130 Source
*/
class android_nanoapp_header_t : public kaitai::kstruct {
public:
android_nanoapp_header_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, android_nanoapp_header_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~android_nanoapp_header_t();
private:
bool f_is_signed;
bool m_is_signed;
public:
bool is_signed();
private:
bool f_is_encrypted;
bool m_is_encrypted;
public:
bool is_encrypted();
private:
bool f_is_tcm_capable;
bool m_is_tcm_capable;
public:
bool is_tcm_capable();
private:
uint32_t m_header_version;
std::string m_magic;
uint64_t m_app_id;
uint32_t m_app_version;
uint32_t m_flags;
uint64_t m_hub_type;
uint8_t m_chre_api_major_version;
uint8_t m_chre_api_minor_version;
std::string m_reserved;
android_nanoapp_header_t* m__root;
kaitai::kstruct* m__parent;
public:
uint32_t header_version() const { return m_header_version; }
std::string magic() const { return m_magic; }
uint64_t app_id() const { return m_app_id; }
uint32_t app_version() const { return m_app_version; }
uint32_t flags() const { return m_flags; }
uint64_t hub_type() const { return m_hub_type; }
uint8_t chre_api_major_version() const { return m_chre_api_major_version; }
uint8_t chre_api_minor_version() const { return m_chre_api_minor_version; }
std::string reserved() const { return m_reserved; }
android_nanoapp_header_t* _root() const { return m__root; }
kaitai::kstruct* _parent() const { return m__parent; }
};
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "android_nanoapp_header.h"
#include "kaitai/exceptions.h"
android_nanoapp_header_t::android_nanoapp_header_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, android_nanoapp_header_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = this;
f_is_signed = false;
f_is_encrypted = false;
f_is_tcm_capable = false;
_read();
}
void android_nanoapp_header_t::_read() {
m_header_version = m__io->read_u4le();
if (!(header_version() == 1)) {
throw kaitai::validation_not_equal_error<uint32_t>(1, header_version(), _io(), std::string("/seq/0"));
}
m_magic = m__io->read_bytes(4);
if (!(magic() == std::string("\x4E\x41\x4E\x4F", 4))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x4E\x41\x4E\x4F", 4), magic(), _io(), std::string("/seq/1"));
}
m_app_id = m__io->read_u8le();
m_app_version = m__io->read_u4le();
m_flags = m__io->read_u4le();
m_hub_type = m__io->read_u8le();
m_chre_api_major_version = m__io->read_u1();
m_chre_api_minor_version = m__io->read_u1();
m_reserved = m__io->read_bytes(6);
if (!(reserved() == std::string("\x00\x00\x00\x00\x00\x00", 6))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x00\x00\x00\x00\x00\x00", 6), reserved(), _io(), std::string("/seq/8"));
}
}
android_nanoapp_header_t::~android_nanoapp_header_t() {
_clean_up();
}
void android_nanoapp_header_t::_clean_up() {
}
bool android_nanoapp_header_t::is_signed() {
if (f_is_signed)
return m_is_signed;
m_is_signed = (flags() & 1) != 0;
f_is_signed = true;
return m_is_signed;
}
bool android_nanoapp_header_t::is_encrypted() {
if (f_is_encrypted)
return m_is_encrypted;
m_is_encrypted = (flags() & 2) != 0;
f_is_encrypted = true;
return m_is_encrypted;
}
bool android_nanoapp_header_t::is_tcm_capable() {
if (f_is_tcm_capable)
return m_is_tcm_capable;
m_is_tcm_capable = (flags() & 4) != 0;
f_is_tcm_capable = true;
return m_is_tcm_capable;
}