diff --git a/include/libg1m/format/std.h b/include/libg1m/format/std.h index a60886f..004bbc7 100644 --- a/include/libg1m/format/std.h +++ b/include/libg1m/format/std.h @@ -60,10 +60,11 @@ struct standard_header { uint8_t control2; /* alignment */ - uint8_t align[8]; + uint8_t align[7]; /* is obfuscated - useful for G3P */ - uint8_t obfuscated; + uint8_t obfuscated0; + uint8_t obfuscated1; /* number of objects contained (useful for MCS filetype) */ uint16_t number; diff --git a/include/libg1m/format/std/picture.h b/include/libg1m/format/std/picture.h index 7276a0d..e21b8f0 100644 --- a/include/libg1m/format/std/picture.h +++ b/include/libg1m/format/std/picture.h @@ -83,12 +83,21 @@ struct g3p_subheader { * Before inflating, you should check if the image is obfuscated (Simon Lothar * says 'encrypted', I suppose that's more polite). It is if: * - * (std.obfuscated + 8) & 0xFF != (std.filesize & 0xff00) >> 8 + * std.obfuscated0 != std.subtype[0] + * + ((std.filesize & 0xFF00) >> 8) + (std.filesize & 0xFF) * + * Which is checked in `g1m_decode_std`. * If it is, then in order to de-obfuscate, you should do the following - * operation: + * operations: * - * byte = ~((byte << 5) | (byte >> 3)) & 0xFF; + * byte = ~byte; + * byte = (byte << 5) | (byte >> 3); + * + * For completeness' sake, here are the operations you'll need to do to + * obfuscate while making a Prizm picture: + * + * byte = (byte >> 5) | (byte << 3); + * byte = ~byte; * * Then you can inflate. * Once this is done, you can get the next four bytes, also considered as diff --git a/src/decode/std.c b/src/decode/std.c index c073df6..504d69f 100644 --- a/src/decode/std.c +++ b/src/decode/std.c @@ -211,6 +211,17 @@ int g1m_decode_std(g1m_t **handle, const char *path, g1m_buffer_t *buffer, if (find_decode_function(platform, type, &rd)) return (g1m_error_magic); + /* check the obfuscation bytes; imitates syscall 0x0C12 + * http://bible.planet-casio.com/simlo/chm/v20/fxCG20_Bfile.htm */ + if (std->obfuscated0 == std->subtype[0] + + ((std->filesize & 0xFF00) >> 8) + (std->filesize & 0xFF)) { + std->obfuscated0 = 0; + std->obfuscated1 = 0; + } else { + std->obfuscated0 = 1; + std->obfuscated1 = 1; + } + /* call it */ err = (*rd)(handle, buffer, std, &hd); if (err) return (err); diff --git a/src/decode/std/picture.c b/src/decode/std/picture.c index c746600..3d5cc2d 100644 --- a/src/decode/std/picture.c +++ b/src/decode/std/picture.c @@ -33,8 +33,8 @@ static void g3p_deobfuscate(uint8_t *buf, size_t n) { while (n--) { - int byte = *buf; - *buf++ = ~((byte << 5) | (byte >> 3)) & 0xFF; + uint8_t byte = ~*buf; + *buf++ = (byte << 5) | (byte >> 3); } } @@ -86,9 +86,7 @@ int g1m_decode_std_g3p(g1m_t **h, g1m_buffer_t *buffer, READ(defbuf, deflated_image_size) /* unobfuscate if required */ - int is_obfuscated = - ((std->obfuscated + 8) & 0xff) != ((std->filesize & 0xff00) >> 8); - if (is_obfuscated) { + if (std->obfuscated0) { log_info("Is obfuscated, let's deobfuscate!"); g3p_deobfuscate(defbuf, deflated_image_size); }