diff options
author | David Timber <mieabby@gmail.com> | 2021-12-06 15:21:52 +0800 |
---|---|---|
committer | David Timber <mieabby@gmail.com> | 2021-12-06 15:21:52 +0800 |
commit | 15ba357fa1b309171b4a6def367b7f82724f2e55 (patch) | |
tree | ab2856478a9e5c8764c002bac46194e4e38de4f3 /src/pack.h | |
parent | f5d9956c3e2343455a3025b9d38c539b680da8f5 (diff) |
Documentation progress, bug fix, interface change
* Update vscode settings for Doxygen
* Fix mem leak in prne_index_bin_archive()
* Fix bug where errno is not set in prne_htbt_parse_args()
* Change names of parameter to prne_htbt_cp_hover()
* Add template for Doxygen comment blocks
Diffstat (limited to 'src/pack.h')
-rw-r--r-- | src/pack.h | 196 |
1 files changed, 180 insertions, 16 deletions
@@ -1,3 +1,6 @@ +/** \file + * \brief Executable packing facility. + */ /* * Copyright (c) 2019-2021 David Timber <mieabby@gmail.com> * @@ -28,46 +31,62 @@ #include <zlib.h> +/* Alias declarations */ typedef struct prne_bin_host prne_bin_host_t; typedef struct prne_bin_tuple prne_bin_tuple_t; typedef struct prne_bin_archive prne_bin_archive_t; typedef struct prne_bin_rcb_ctx prne_bin_rcb_ctx_t; typedef struct prne_rcb_param prne_rcb_param_t; +// The pack function result codes typedef enum { - PRNE_PACK_RC_OK, - PRNE_PACK_RC_EOF, - PRNE_PACK_RC_INVAL, - PRNE_PACK_RC_FMT_ERR, - PRNE_PACK_RC_ERRNO, - PRNE_PACK_RC_Z_ERR, - PRNE_PACK_RC_NO_ARCH, - PRNE_PACK_RC_UNIMPL_REV, - - NB_PRNE_PACK_RC + PRNE_PACK_RC_OK, // Successful + PRNE_PACK_RC_EOF, // End of file reached + PRNE_PACK_RC_INVAL, // Invalid data + PRNE_PACK_RC_FMT_ERR, // Format error + PRNE_PACK_RC_ERRNO, // Syscall error, errno set + PRNE_PACK_RC_Z_ERR, // zlib function error + PRNE_PACK_RC_NO_ARCH, // Arch not found + PRNE_PACK_RC_UNIMPL_REV, // Unimplemented revision number + + NB_PRNE_PACK_RC // Meta: the number of result codes } prne_pack_rc_t; +// The executable host info record struct prne_bin_host { prne_os_t os; prne_arch_t arch; }; +// The executable host info record - executable size pair struct prne_bin_tuple { size_t size; prne_bin_host_t host; }; +// The indexed binary archive object struct prne_bin_archive { - const uint8_t *data; - size_t data_size; - size_t nb_bin; - prne_bin_tuple_t *bin; + const uint8_t *data; // The pointer to the start of the binary archive + size_t data_size; // The byte length of the binary archive + size_t nb_bin; // The number of the tuples + prne_bin_tuple_t *bin; // The array of the tuples }; -// Recombination Context +// The recombination context object struct prne_bin_rcb_ctx { - void *o_ctx; + void *o_ctx; // The opaque context + /** + * \brief The function used to free the opaque context. Not to be used + * directly. + * \note Use \c prne_free_bin_rcb_ctx() to free the object! + * \see \c prne_free_bin_rcb_ctx() + */ void (*ctx_free_f)(void*); + /** + * \brief The adaptive read callback function. Not to be used directly. + * \note Use \c prne_bin_rcb_read() + * \see \c prne_bin_rcb_read() + */ ssize_t(*read_f)( prne_bin_rcb_ctx_t *ctx, uint8_t *buf, @@ -76,6 +95,13 @@ struct prne_bin_rcb_ctx { int *err); }; +/** + * \brief The recombination parameter object for initiating binary + * recombination. The members are the parameters to \c prne_start_bin_rcb() + * call excluding the target info. An instance of this object is set up on + * program initialisation and shared globally. + * \see \c prne_start_bin_rcb() + */ struct prne_rcb_param { const uint8_t *m_self; size_t self_len; @@ -86,20 +112,96 @@ struct prne_rcb_param { const prne_bin_host_t *self; }; +/** + * \brief The binary archive identity magic "pr-ba" + * \see /doc/fmts.md + */ static const char PRNE_PACK_BA_IDEN_DATA[] = { 'p', 'r', '-', 'b', 'a' }; +/** + * \brief The nybin file format identity magic "nybin" + * \see /doc/fmts.md + */ static const char PRNE_PACK_NYBIN_IDEN_DATA[] = { 'n', 'y', 'b', 'i', 'n' }; +/** + * \brief The equality operator of the executable host info record + * \retval true if the contents of the records are equal. + * \retval false otherwise. + */ bool prne_eq_bin_host (const prne_bin_host_t *a, const prne_bin_host_t *b); +/** + * \brief The in-range operator of the executable host info record. Check both + * enums are in range(ie, recognised by the current implementation). + * \retval true if the enums are in range. + * \retval false otherwise. + */ bool prne_bin_host_inrange (const prne_bin_host_t *x); +/** + * \brief Initialise the indexed binary archive object. + * \note \p a can be freed using \c prne_free_bin_archive() once initialised. + * \see \c prne_free_bin_archive() + */ void prne_init_bin_archive (prne_bin_archive_t *a); +/** + * \brief Free resources allocated for the indexed binary archive object. + * \see \c prne_init_bin_archive() + */ void prne_free_bin_archive (prne_bin_archive_t *a); +/** + * \brief Index the binary archive from the binary. + * \param data The binary data, usually the address obtained using \c mmap() on + * the executable. + * \param len The byte length of the binary data. + * \param[out] out The pointer to the binary archive object for index info. + * \retval PRNE_PACK_RC_OK The binary archive has been successfully index and + * \p out is ready to use. + * \retval PRNE_PACK_RC_FMT_ERR The binary could not be parsed due to a format + * error. + * \retval PRNE_PACK_RC_UNIMPL_REV An unimplemented revision number encountered. + * \retval PRNE_PACK_RC_ERRNO A memory allocation error has occurred. \c errno + * is set to \c ENOMEM + * \note Any resource allocated previously for \p out is freed using + * \c prne_free_bin_archive() if the operation is successful. + */ prne_pack_rc_t prne_index_bin_archive ( const uint8_t *data, size_t len, prne_bin_archive_t *out); +/** + * \brief Initialise the recombination context object. + * \see \c prne_free_bin_rcb_ctx() + */ void prne_init_bin_rcb_ctx (prne_bin_rcb_ctx_t *ctx); +/** + * \brief Free resources allocated for the recombination context object. + * \see \c prne_init_bin_rcb_ctx() + */ void prne_free_bin_rcb_ctx (prne_bin_rcb_ctx_t *ctx); +/** + * \brief Initiate binary recombination. Get the recombination context object + * ready for \c prne_bin_rcb_read() + * \param ctx The recombination context object. + * \param target The recombination target host info. + * \param self The executable host info record of the running executable. + * \param m_self The pointer to the start of the running executable (the image + * of the current process). Usually the address obtained using \c mmap() + * \param self_len The total byte length of the running executable(the size of + * the file). + * \param exec_len The byte length of the ELF part of the running executable. + * \param m_dvault The pointer to the start of the data vault binary. + * \param dvault_len The byte length of the data vault binary. + * \param ba The indexed binary archive object. + * \retval PRNE_PACK_RC_OK if the initiation was successful. + * \retval PRNE_PACK_RC_INVAL if \p ba is NULL, or \p target or \p self is not + * in range. + * \retval PRNE_PACK_RC_ERRNO if a memory allocation error has occurred and + * \c errno is set to \c ENOMEM + * \retval PRNE_PACK_RC_NO_ARCH if \p ba does not contain the executable for + * \p target + * \retval PRNE_PACK_RC_Z_ERR if a zlib function returned an error. Probably + * allocation error or an incompatible zlib variant. + */ prne_pack_rc_t prne_start_bin_rcb ( prne_bin_rcb_ctx_t *ctx, const prne_bin_host_t target, @@ -110,6 +212,14 @@ prne_pack_rc_t prne_start_bin_rcb ( const uint8_t *m_dvault, const size_t dvault_len, const prne_bin_archive_t *ba); +/** + * \brief A variant of \c prne_start_bin_rcb() that try to initiate for a + * compatible arch target on \c PRNE_PACK_RC_NO_ARCH + * \param[out] actual The pointer to the executable host info record for + * returning the actual target initiated (optional) + * \see \c prne_start_bin_rcb() + * \see \c prne_compat_arch() + */ prne_pack_rc_t prne_start_bin_rcb_compat ( prne_bin_rcb_ctx_t *ctx, const prne_bin_host_t target, @@ -121,6 +231,26 @@ prne_pack_rc_t prne_start_bin_rcb_compat ( const size_t dvault_len, const prne_bin_archive_t *ba, prne_bin_host_t *actual); +/** + * \brief Read the recombined binary. + * \param ctx The initiated recombination context object. + * \param buf The output buffer. + * \param len The number of bytes available in \p buf + * \param[out] prc The pointer to a pack function result code variable(optional) + * \param[out] err The pointer to an int for library function return values + * (optional) + * \return The number of bytes written to \p buf + * \retval 0 with \p prc PRNE_PACK_RC_OK means no data could be produced in a + * reasonable amount of CPU time and the function had to return for other + * threads. This is not an error and the function may be called again with the + * same arguments after yielding to other threads. + * \retval 0 with \p prc PRNE_PACK_RC_EOF means all the data for the target + * has been produced and the output file can be closed. The subsequent calls + * will result in the same return values. + * \retval -1 on error. \p ctx cannot be used for read and must be freed or + * reinitialised. \p prc is set to either \c PRNE_PACK_RC_ERRNO or + * \c PRNE_PACK_RC_Z_ERR + */ ssize_t prne_bin_rcb_read ( prne_bin_rcb_ctx_t *ctx, uint8_t *buf, @@ -128,6 +258,20 @@ ssize_t prne_bin_rcb_read ( prne_pack_rc_t *prc, int *err); +/** + * \brief Index the NYBIN file. The file must be mmaped first. + * \param[in] m_nybin The pointer to the start of the contents of the NYBIN file. + * \param[in] nybin_len The byte length of the contents of the NYBIN file. + * \param[out] m_dv The start of the data vault. + * \param[out] dv_len The byte length of the data vault. + * \param[out] m_ba The start of the binary archive. + * \param[out] ba_len The byte length of the binary archive. + * \retval true if the parsing was successful and the output parameters are all + * set. + * \retval false with \c errno set to \c EPROTO on invalid format. + * \retval false with \c errno set to \c ENOSYS if the revision of the file is + * unrecognised. + */ bool prne_index_nybin ( const uint8_t *m_nybin, const size_t nybin_len, @@ -136,9 +280,29 @@ bool prne_index_nybin ( const uint8_t **m_ba, size_t *ba_len); +/** + * \brief Initialise the recombination parameter object. Reserved for any + * dynamically allocated members in the future. + */ void prne_init_rcb_param (prne_rcb_param_t *rp); +/** + * \brief Free resources allocated for the recombination parameter object. + * Reserved for any dynamically allocated members in the future. + */ void prne_free_rcb_param (prne_rcb_param_t *rp); +/** + * \brief Get the array of the compatible arches for \p arch + * \retval NULL if there's no known compatible arch for \p arch + * \return The pointer to an internal array, terminated by \c PRNE_ARCH_NONE + * \see \c prne_start_bin_rcb_compat() + * \note This function can be used to examine the "compat tree" of the arches. + */ const prne_arch_t *prne_compat_arch (const prne_arch_t arch); +/** + * \brief Get the descriptive string for the enum value. + * \retval NULL if \p prc is not in range. + * \return The pointer to the internal string describing the enum value. + */ const char *prne_pack_rc_tostr (const prne_pack_rc_t prc); |