cake
/
libg1m
Archived
1
0
Fork 0

Added G3L support, made headers dependency in Makefile

This commit is contained in:
Thomas Touhey 2016-11-25 13:47:03 +01:00
parent ebb674e304
commit f98798db11
5 changed files with 152 additions and 9 deletions

View File

@ -83,7 +83,7 @@ all-lib: $(CHECKCFG) lib$(NAME).so.$(MAJOR)
# Make a module object out of a module source file.
define make-moduleobj-rule
$(OBJDIR)/$1/%.o: $(SRCDIR)/$1/%.c | $(OBJDIR)/$1
$(OBJDIR)/$1/%.o: $(SRCDIR)/$1/%.c $(INC:%=$(INCDIR)/%.h) | $(OBJDIR)/$1
$(call bcmd,cc,$$@,$(CC) -c -o $$@ $$< $(CFLAGS))
endef
$(foreach mod,$(MODULES), \

View File

@ -95,10 +95,17 @@ $(foreach mod,$(MODULES), \
$(eval $(call get-module-source,$(mod))))
#******************************************************************************#
# Look for public headers (not internals.h or internals/**/*.h #
# Look for headers #
#******************************************************************************#
INCPUB := $(basename $(shell find $(INCDIR) \
-name "*.h" -and -not -path "*internals*" -printf "%P\n" | sort))
# All headers
INC := \
$(basename $(shell find $(INCDIR) -name "*.h" -printf "%P\n"))
# Public headers only (not internals.h or internals/**/*.h)
INCPUB := \
$(basename $(shell find $(INCDIR) \
\( -name "*.h" -and -not -path "*internals*" \) \
-printf "%P\n" | sort))
#******************************************************************************#
# Look for manpages #

View File

@ -12,8 +12,91 @@
# include <libg1m.h>
# pragma pack(1)
/* The format of this file is yet to discover. (may be discovered by someone
* out there, I don't know yet) */
/* Thanks to amazonka for his (minimalist) description of the G3L format
* at Cemetech. So the G3L format starts off with a header: */
struct g3l_subheader {
/* a checksum */
uint32_t checksum;
/* magic: always "0401" */
uint8_t magic[4];
/* lol */
uint8_t undocumented[14];
/* size of the message zone size */
uint32_t message_zone_size;
/* undocumented, again */
uint8_t undocumented5[6];
/* name of the language */
uint8_t language_name2[28];
/* size of the entire file */
uint32_t filesize;
/* size of the entire file - starts with an '@' */
uint8_t internal_name[8];
/* undocumented */
uint8_t undocumented2[200];
/* version number string: "XX.XX.XXXX" */
uint8_t version[10];
/* unused */
uint8_t unused2[2];
/* creation time: "YYYY.MMDD.HHMM" */
uint8_t datetime[14];
/* big undocumented thing */
uint8_t undocumented3[3410];
/* language name (zero terminated) */
uint8_t language_name[16];
/* language salutation (zero terminated) */
uint8_t language_salutation[16];
/* filename (extension included) */
uint8_t g3l_filename[16];
/* undocumented */
uint8_t undocumented4[308];
};
/* Then there is something amazonka names the "executable code section".
* This is in fact the message zone.
*/
struct g3l_lang_header {
/* sequence: '4C 59 37 35 35 00 00 00 02' (LY755 ) */
uint8_t sequence[9];
/* unused byte. */
uint8_t unused;
/* number of messages ("possibly 0 base indexed") */
uint32_t num;
/* unused bytes */
uint8_t unused2[2];
};
/* Then we have offsets of all messages (4 bytes each),
* then messages themselves, zero-terminated.
*
* The four last bytes of the files are a little footer, which is: */
struct g3l_footer {
/* copy of the first checksum in the subheader */
uint32_t checksum;
};
/* This footer is not counted as part of the file. */
# pragma pack()
#endif /* LIBG1M_FORMAT_LANG_H */

View File

@ -38,7 +38,60 @@ int g1m_parse_lang(g1m_t *handle, FILE *stream)
int g1m_parse_lang_cg(g1m_t *handle, FILE *stream)
{
(void)handle;
(void)stream;
log_info("Language type isn't managed yet.");
/* read the subheader */
DREAD(hd, g3l_subheader)
/* correct the endianness */
hd.message_zone_size = be32toh(hd.message_zone_size);
/* log */
log_info("internal name is '%.8s'", hd.internal_name);
log_info("language name is '%.16s'", hd.language_name);
log_info("language salutation is '%.16s'", hd.language_salutation);
log_info("version is '%.10s'", hd.version);
log_info("datetime is '%.14s'", hd.datetime);
log_info("g3l filename is '%.16s'", hd.g3l_filename);
/* read the languages header */
DREAD(lhd, g3l_lang_header)
logm_info(&lhd, sizeof(struct g3l_lang_header));
/* correct endianness */
lhd.num = be32toh(lhd.num);
/* log */
log_info("there are %d messages", lhd.num);
/* read the entire message zone */
size_t message_zone_size = hd.message_zone_size
- sizeof(struct g3l_lang_header);
uint8_t message_zone[message_zone_size];
READ(message_zone, message_zone_size)
/* get parts */
const uint_fast32_t num = lhd.num + 1;
uint32_t *offsets = (uint32_t*)message_zone;
uint8_t *messages = (uint8_t*)message_zone + num * sizeof(uint32_t);
/* read messages */
for (uint_fast32_t i = 0; i < num; i++) {
/* check if offset is valid */
if (offsets[i] == (uint32_t)-1) {
log_info("[#%ld] -", i);
continue ;
}
/* correct offset */
offsets[i] = be32toh(offsets[i]);
/* log */
log_info("[#%ld] message: '%s'", i, &messages[offsets[i]]);
}
/* parse footer */
DREAD(footer, g3l_footer)
/* TODO: check the checksum */
/* no error */
return (0);
}

View File

@ -60,7 +60,7 @@ int g1m_parse_g3p(g1m_t *handle, FILE *stream,
/* check some little things */
int is_obfuscated =
(std->obfuscated + 8) & 0xff != ((std->filesize & 0xff00) >> 8);
((std->obfuscated + 8) & 0xff) != ((std->filesize & 0xff00) >> 8);
int has_footer = 1; /* might change? */
size_t deflated_image_size = ihd.data_size - has_footer * 0x4;