1
0
mirror of git://f0xx.org/android_cast synced 2026-07-29 08:37:37 +03:00
Files
android_cast/ndk/obfuscate/obfuscate_file.c
Anton Afanasyeu b9f94fe005 docs, obfuscation
2026-06-19 22:41:27 +02:00

216 lines
4.4 KiB
C

#include "obfuscate_file.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static uint32_t dummy_u32(uint64_t seed, uint32_t salt)
{
uint64_t x = seed ^ ((uint64_t)salt * 0x9E3779B97F4A7C15ULL);
x ^= x >> 33;
x *= 0xFF51AFD7ED558CCDULL;
x ^= x >> 33;
return (uint32_t)(x ^ (x >> 32));
}
static void put_u32_le(uint8_t *dst, uint32_t v)
{
dst[0] = (uint8_t)(v);
dst[1] = (uint8_t)(v >> 8);
dst[2] = (uint8_t)(v >> 16);
dst[3] = (uint8_t)(v >> 24);
}
static void put_u64_le(uint8_t *dst, uint64_t v)
{
unsigned int i;
for (i = 0; i < 8u; i++)
dst[i] = (uint8_t)(v >> (8u * i));
}
static uint32_t get_u32_le(const uint8_t *src)
{
return (uint32_t)src[0] | ((uint32_t)src[1] << 8) | ((uint32_t)src[2] << 16) |
((uint32_t)src[3] << 24);
}
static uint64_t get_u64_le(const uint8_t *src)
{
uint64_t v = 0;
unsigned int i;
for (i = 0; i < 8u; i++)
v |= (uint64_t)src[i] << (8u * i);
return v;
}
int32_t obf_file_payload_count(long file_size, size_t *count_out)
{
long payload_bytes;
if (file_size < 0)
return OBF_ERR_IO;
if ((unsigned long)file_size < OBF_FILE_OVERHEAD + sizeof(uint64_t))
return OBF_ERR_FORMAT;
payload_bytes = file_size - (long)OBF_FILE_OVERHEAD;
if (payload_bytes % (long)sizeof(uint64_t) != 0)
return OBF_ERR_FORMAT;
*count_out = (size_t)payload_bytes / sizeof(uint64_t);
return OBF_OK;
}
static int32_t write_encoded_file(const char *path, const uint64_t *encoded, size_t count,
uint64_t seed)
{
FILE *fp;
uint8_t hdr[OBF_FILE_HDR_SIZE];
uint8_t tail[OBF_FILE_TAIL_SIZE];
uint8_t block[sizeof(uint64_t)];
size_t i;
if (path == NULL || encoded == NULL || count == 0)
return OBF_ERR_NULL;
fp = fopen(path, "wb");
if (fp == NULL)
return OBF_ERR_IO;
put_u32_le(hdr, dummy_u32(seed, 0xA11CEu));
if (fwrite(hdr, 1, sizeof(hdr), fp) != sizeof(hdr)) {
fclose(fp);
return OBF_ERR_IO;
}
for (i = 0; i < count; i++) {
put_u64_le(block, encoded[i]);
if (fwrite(block, 1, sizeof(block), fp) != sizeof(block)) {
fclose(fp);
return OBF_ERR_IO;
}
}
put_u32_le(tail, dummy_u32(seed, 0x7A1Lu));
if (fwrite(tail, 1, sizeof(tail), fp) != sizeof(tail)) {
fclose(fp);
return OBF_ERR_IO;
}
if (fclose(fp) != 0)
return OBF_ERR_IO;
return OBF_OK;
}
int32_t write_many_to(const char *path, const uint64_t *vals, size_t count, uint64_t seed)
{
uint64_t *encoded;
size_t i;
int32_t rv;
if (path == NULL || vals == NULL || count == 0)
return OBF_ERR_NULL;
encoded = (uint64_t *)malloc(count * sizeof(uint64_t));
if (encoded == NULL)
return OBF_ERR_IO;
for (i = 0; i < count; i++) {
rv = encode(vals[i], seed, &encoded[i]);
if (rv != OBF_OK) {
free(encoded);
return rv;
}
}
rv = write_encoded_file(path, encoded, count, seed);
free(encoded);
return rv;
}
int32_t write_to(const char *path, uint64_t val, uint64_t seed)
{
return write_many_to(path, &val, 1, seed);
}
int32_t read_many_from(const char *path, uint64_t seed, uint64_t *out_vals, size_t out_cap,
size_t *out_count)
{
FILE *fp;
long file_size;
size_t count;
size_t i;
uint8_t hdr[OBF_FILE_HDR_SIZE];
uint8_t tail[OBF_FILE_TAIL_SIZE];
uint8_t block[sizeof(uint64_t)];
uint64_t encoded;
uint64_t decoded;
int32_t rv;
if (path == NULL || out_vals == NULL || out_count == NULL)
return OBF_ERR_NULL;
fp = fopen(path, "rb");
if (fp == NULL)
return OBF_ERR_IO;
if (fseek(fp, 0, SEEK_END) != 0) {
fclose(fp);
return OBF_ERR_IO;
}
file_size = ftell(fp);
if (file_size < 0 || fseek(fp, 0, SEEK_SET) != 0) {
fclose(fp);
return OBF_ERR_IO;
}
rv = obf_file_payload_count(file_size, &count);
if (rv != OBF_OK) {
fclose(fp);
return rv;
}
if (count > out_cap) {
fclose(fp);
return OBF_ERR_OVERFLOW;
}
if (fread(hdr, 1, sizeof(hdr), fp) != sizeof(hdr)) {
fclose(fp);
return OBF_ERR_IO;
}
(void)get_u32_le(hdr);
for (i = 0; i < count; i++) {
if (fread(block, 1, sizeof(block), fp) != sizeof(block)) {
fclose(fp);
return OBF_ERR_IO;
}
encoded = get_u64_le(block);
rv = decode(encoded, seed, &decoded);
if (rv != OBF_OK) {
fclose(fp);
return rv;
}
out_vals[i] = decoded;
}
if (fread(tail, 1, sizeof(tail), fp) != sizeof(tail)) {
fclose(fp);
return OBF_ERR_IO;
}
(void)get_u32_le(tail);
fclose(fp);
*out_count = count;
return OBF_OK;
}
int32_t read_from(const char *path, uint64_t seed, uint64_t *out)
{
size_t count = 0;
return read_many_from(path, seed, out, 1, &count);
}