Created
February 7, 2023 00:28
-
-
Save iscle/063375da64333ce5667313301a1c31be to your computer and use it in GitHub Desktop.
Extract ForFan Android HU update files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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