Skip to content

Instantly share code, notes, and snippets.

@v3l0c1r4pt0r
Last active September 2, 2019 19:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save v3l0c1r4pt0r/9acdbca0792cc1c8eece039b6246a537 to your computer and use it in GitHub Desktop.
Save v3l0c1r4pt0r/9acdbca0792cc1c8eece039b6246a537 to your computer and use it in GitHub Desktop.
SMAZ package decompressor (Work In Progress)
// compile with:
// $ gcc -o smaz smaz.c -Iucl-1.03/include -lucl -Lucl-1.03/build/src/.libs
// or if you have ucl in system:
// $ gcc -o smaz smaz.c -lucl
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <ucl/ucl.h>
#define SMAZ 0x534d415a
#define OUTLEN 0x50000 * 20
typedef struct {
uint32_t magic;
uint32_t unknown;
uint32_t unknown1;
uint32_t size;
} smaz_hdr_t;
int main() {
/* read header */
smaz_hdr_t header;
if (fread(&header, 1, sizeof(header), stdin) != sizeof(header)) {
perror("fread(header)");
return 1;
}
/* check magic */
if (header.magic != htonl(SMAZ)) {
fprintf(stderr, "error: wrong magic: '%.4s'\n", header.magic);
return 1;
}
uint32_t flags = header.unknown1;
size_t compressed_size = ntohl(header.size);
do {
/* read rest of file to buffer */
void *buffer = malloc(header.size);
//compressed_size -= sizeof(header);
size_t to_read = compressed_size;
size_t done = 0;
fprintf(stderr, "info: I am about to read %u bytes\n", to_read);
while (to_read > 0) {
done = fread(buffer, 1, to_read, stdin);
fprintf(stderr, "info: done %u bytes\n", done);
if (done == 0) {
perror("fread(buffer)");
fprintf(stderr, "info: %u yet to be read, but got nothing\n", to_read);
break;
//return 1;
}
to_read -= done;
fprintf(stderr, "info: %u yet to be read\n", to_read);
}
/* decompress */
void *cursor = buffer;
unsigned int outlen = compressed_size + (compressed_size / 8) + 256;
uint8_t *output = (uint8_t*) calloc(outlen, 1);
int status = ucl_nrv2e_decompress_safe_8(buffer, compressed_size, output, &outlen, NULL);
if (status != 0) {
fprintf(stderr, "error: decompression failed with %x\n", status);
/* intentionally do not return, something was done either way */
}
fprintf(stderr, "info: I am about to write %u bytes\n", outlen);
if (fwrite(output, 1, outlen, stdout) != outlen) {
perror("fwrite");
return 1;
}
if (fread(&flags, 1, sizeof(flags), stdin) != sizeof(flags)) {
perror("fread(flags)");
return 1;
}
flags = ntohl(flags);
fprintf(stderr, "info: flags are %u\n", flags);
if (flags == 0) {
break;
}
if (fread(&compressed_size, 1, sizeof(uint32_t), stdin) != sizeof(uint32_t)) {
perror("fread(compressed_size)");
return 1;
}
compressed_size = ntohl(compressed_size);
fprintf(stderr, "info: next chunk compressed size is %u\n", compressed_size);
free(buffer);
} while (flags != 0);
/* clean up */
return 0;
}
@v3l0c1r4pt0r
Copy link
Author

v3l0c1r4pt0r commented Sep 2, 2019

I'm not sure if you did it right. In my case (LKV373A-fw/TX\ firmware/LKV373A_TX_20151028_PKG.PKG) it is 0xb70.

I know this is not the best code I've wrote :) I would like to rewrite it from scratch, when I find some time to do that. For now I want to see where the rabbit hole leads me :)

Edit: Ah, one more note. Ignore the errors and other junk printed to stderr. The juice is on stdout, regardless of any errors happening in the meantime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment