Skip to content

Instantly share code, notes, and snippets.

@iscle
Created February 7, 2023 00:28
Show Gist options
  • Save iscle/063375da64333ce5667313301a1c31be to your computer and use it in GitHub Desktop.
Save iscle/063375da64333ce5667313301a1c31be to your computer and use it in GitHub Desktop.
Extract ForFan Android HU update files
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
static void *mmap_file(const char *file_path) {
int fd = open(file_path, O_RDONLY);
if (fd == -1) {
printf("open failed: %s\n", strerror(errno));
return NULL;
}
struct stat st;
if (fstat(fd, &st) == -1) {
printf("fstat failed: %s\n", strerror(errno));
close(fd);
return NULL;
}
void *addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (addr == MAP_FAILED) {
printf("mmap failed: %s\n", strerror(errno));
close(fd);
return NULL;
}
close(fd);
return addr;
}
static void munmap_file(const char *file_path, void *addr) {
int fd = open(file_path, O_RDONLY);
if (fd == -1) {
printf("open failed: %s\n", strerror(errno));
return;
}
struct stat st;
if (fstat(fd, &st) == -1) {
printf("fstat failed: %s\n", strerror(errno));
close(fd);
return;
}
if (munmap(addr, st.st_size) == -1) {
printf("munmap failed: %s\n", strerror(errno));
close(fd);
return;
}
close(fd);
}
static void write_to_file(uint8_t *buf, size_t len, const char *file_path) {
int fd = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
printf("open failed: %s\n", strerror(errno));
return;
}
if (write(fd, buf, len) == -1) {
printf("write failed: %s\n", strerror(errno));
close(fd);
return;
}
close(fd);
}
int main() {
printf("ForFan .upd extractor v1.0 by Iscle\n");
char *file_path = "/mnt/d/Users/Iscle/Downloads/8667Q军灿UI02-国外-VHD720x1280_v11_20211207/8667.bin";
uint8_t *addr = mmap_file(file_path);
if (addr == NULL) {
return 1;
}
uint64_t total_size = (uint64_t) addr[7] << 56 |
(uint64_t) addr[6] << 48 |
(uint64_t) addr[5] << 40 |
(uint64_t) addr[4] << 32 |
(uint64_t) addr[3] << 24 |
(uint64_t) addr[2] << 16 |
(uint64_t) addr[1] << 8 |
(uint64_t) addr[0];
printf("Total size: %lu bytes\n", total_size);
printf("\nPartitions:\n");
uint64_t current_offset = 0x908;
for (size_t i = 0; i < 15; i++) {
uint8_t *base = addr + 0x08 + (i * 0x48);
char fileName[0x30];
memcpy(fileName, base, sizeof(fileName));
char name[0x10];
memcpy(name, base + 0x30, sizeof(name));
uint32_t size = (uint32_t) base[0x43] << 24 |
(uint32_t) base[0x42] << 16 |
(uint32_t) base[0x41] << 8 |
(uint32_t) base[0x40];
uint32_t flags = (uint32_t) base[0x47] << 24 |
(uint32_t) base[0x46] << 16 |
(uint32_t) base[0x45] << 8 |
(uint32_t) base[0x44];
printf("%s: %s (%u bytes), flags: 0x%08X, offset: 0x%lX\n", name, fileName, size, flags, current_offset);
if (size == 0) continue;
char out_file_path[0x100];
sprintf(out_file_path, "/mnt/d/Users/Iscle/Downloads/8667Q军灿UI02-国外-VHD720x1280_v11_20211207/out/%s", fileName);
write_to_file(addr + current_offset, size, out_file_path);
current_offset += size;
}
munmap_file(file_path, addr);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment