mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-02 16:59:03 +00:00
374 lines
7.9 KiB
C
374 lines
7.9 KiB
C
#include "lib.h"
|
|
|
|
//MISC
|
|
void char_to_u8_array(unsigned char destination[], char source[], int size, int endianness, int base)
|
|
{
|
|
char tmp[size][2];
|
|
unsigned char *byte_array = malloc(size*sizeof(unsigned char));
|
|
memset(byte_array, 0, size);
|
|
memset(destination, 0, size);
|
|
memset(tmp, 0, size*2);
|
|
|
|
for (int i = 0; i < size; i ++){
|
|
tmp[i][0] = source[(i*2)];
|
|
tmp[i][1] = source[((i*2)+1)];
|
|
tmp[i][2] = '\0';
|
|
byte_array[i] = (unsigned char)strtol(tmp[i], NULL, base);
|
|
}
|
|
endian_memcpy(destination,byte_array,size,endianness);
|
|
free(byte_array);
|
|
}
|
|
|
|
void endian_memcpy(u8 *destination, u8 *source, u32 size, int endianness)
|
|
{
|
|
for (u32 i = 0; i < size; i++){
|
|
switch (endianness){
|
|
case(BE):
|
|
destination[i] = source[i];
|
|
break;
|
|
case(LE):
|
|
destination[i] = source[((size-1)-i)];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void u8_hex_print_be(u8 *array, int len)
|
|
{
|
|
for(int i = 0; i < len; i++)
|
|
printf("%02x",array[i]);
|
|
}
|
|
|
|
void u8_hex_print_le(u8 *array, int len)
|
|
{
|
|
for(int i = 0; i < len; i++)
|
|
printf("%02x",array[len - i - 1]);
|
|
}
|
|
|
|
u64 align_value(u64 value, u64 alignment)
|
|
{
|
|
u64 tmp = value;
|
|
while(tmp > alignment)
|
|
tmp -= alignment;
|
|
return (value + (alignment - tmp));
|
|
}
|
|
|
|
void resolve_flag(unsigned char flag, unsigned char *flag_bool)
|
|
{
|
|
unsigned char bit_mask[8] = {0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1};
|
|
for(int i = 0; i < 8; i++){
|
|
if (flag >= bit_mask[i]){
|
|
flag_bool[7-i] = true;
|
|
flag -= bit_mask[i];
|
|
}
|
|
else
|
|
flag_bool[7-i] = false;
|
|
}
|
|
}
|
|
|
|
void resolve_flag_u16(u16 flag, unsigned char *flag_bool)
|
|
{
|
|
u16 bit_mask[16] = {0x8000,0x4000,0x2000,0x1000,0x800,0x400,0x200,0x100,0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1};
|
|
for(int i = 0; i < 16; i++){
|
|
if (flag >= bit_mask[i]){
|
|
flag_bool[15-i] = true;
|
|
flag -= bit_mask[i];
|
|
}
|
|
else
|
|
flag_bool[15-i] = false;
|
|
}
|
|
}
|
|
|
|
int append_filextention(char *output, u16 max_outlen, char *input, char extention[])
|
|
{
|
|
if(output == NULL || input == NULL){
|
|
printf("[!] Memory Error\n");
|
|
return Fail;
|
|
}
|
|
memset(output,0,max_outlen);
|
|
u16 extention_point = strlen(input)+1;
|
|
for(int i = strlen(input)-1; i > 0; i--){
|
|
if(input[i] == '.'){
|
|
extention_point = i;
|
|
break;
|
|
}
|
|
}
|
|
if(extention_point+strlen(extention) >= max_outlen){
|
|
printf("[!] Input File Name Too Large for Output buffer\n");
|
|
return Fail;
|
|
}
|
|
memcpy(output,input,extention_point);
|
|
sprintf(output,"%s%s",output,extention);
|
|
return 0;
|
|
}
|
|
|
|
int CopyData(u8 **dest, u8 *source, u64 size)
|
|
{
|
|
if(!*dest){
|
|
*dest = malloc(size);
|
|
if(!*dest) return -1;
|
|
}
|
|
memcpy(*dest,source,size);
|
|
return 0;
|
|
}
|
|
|
|
u64 min_u64(u64 a, u64 b)
|
|
{
|
|
if(a < b) return a;
|
|
return b;
|
|
}
|
|
|
|
u64 max_u64(u64 a, u64 b)
|
|
{
|
|
if(a > b) return a;
|
|
return b;
|
|
}
|
|
|
|
//IO Related
|
|
void WriteBuffer(void *buffer, u64 size, u64 offset, FILE *output)
|
|
{
|
|
fseek_64(output,offset,SEEK_SET);
|
|
fwrite(buffer,size,1,output);
|
|
}
|
|
|
|
void ReadFile_64(void *outbuff, u64 size, u64 offset, FILE *file)
|
|
{
|
|
fseek_64(file,offset,SEEK_SET);
|
|
fread(outbuff,size,1,file);
|
|
}
|
|
|
|
u64 GetFileSize_u64(char *filename)
|
|
{
|
|
u64 size;
|
|
#ifdef _WIN32
|
|
/* Making sure file exists */
|
|
FILE *tmp = fopen(filename,"rb");
|
|
if(!tmp) return 0;
|
|
fclose(tmp);
|
|
|
|
int fh;
|
|
u64 n;
|
|
fh = _open( filename, 0 );
|
|
n = _lseeki64(fh, 0, SEEK_END);
|
|
_close(fh);
|
|
size = (n / sizeof(short))*2;
|
|
#else
|
|
FILE *file = fopen(filename,"rb");
|
|
fseeko(file, 0L, SEEK_END);
|
|
size = ftello(file);
|
|
fclose(file);
|
|
#endif
|
|
return size;
|
|
}
|
|
|
|
u32 GetFileSize_u32(FILE *file)
|
|
{
|
|
u32 size = 0;
|
|
fseek(file, 0L, SEEK_END);
|
|
size = ftell(file);
|
|
fseek(file, 0L, SEEK_SET);
|
|
return size;
|
|
}
|
|
|
|
int TruncateFile_u64(char *filename, u64 filelen)
|
|
{
|
|
#ifdef _WIN32
|
|
HANDLE fh;
|
|
|
|
LARGE_INTEGER fp;
|
|
fp.QuadPart = filelen;
|
|
|
|
fh = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
if (fh == INVALID_HANDLE_VALUE) {
|
|
printf("[!] Invalid File handle\n");
|
|
return 1;
|
|
}
|
|
|
|
if (SetFilePointerEx(fh, fp, NULL, FILE_BEGIN) == 0 ||
|
|
SetEndOfFile(fh) == 0) {
|
|
printf("[!] truncate failed\n");
|
|
CloseHandle(fh);
|
|
return 1;
|
|
}
|
|
|
|
CloseHandle(fh);
|
|
return 0;
|
|
#else
|
|
return truncate(filename,filelen);
|
|
#endif
|
|
}
|
|
|
|
int fseek_64(FILE *fp, u64 file_pos, int whence)
|
|
{
|
|
#ifdef _WIN32
|
|
if(whence != SEEK_SET)
|
|
printf("[!] fseek_64, whence has been overided to SEEK_SET\n");
|
|
fpos_t pos = file_pos;
|
|
return fsetpos(fp,&pos); //I can't believe the 2gb problem with Windows & MINGW, maybe I have a bad installation :/
|
|
#else
|
|
return fseeko(fp,file_pos,whence);
|
|
#endif
|
|
}
|
|
|
|
int makedir(const char* dir)
|
|
{
|
|
#ifdef _WIN32
|
|
return _mkdir(dir);
|
|
#else
|
|
return mkdir(dir, 0777);
|
|
#endif
|
|
}
|
|
|
|
char *getcwdir(char *buffer,int maxlen)
|
|
{
|
|
#ifdef _WIN32
|
|
return _getcwd(buffer,maxlen);
|
|
#else
|
|
return getcwd(buffer,maxlen);
|
|
#endif
|
|
}
|
|
|
|
//Data Size conversion
|
|
u16 u8_to_u16(u8 *value, u8 endianness)
|
|
{
|
|
u16 new_value;
|
|
switch(endianness){
|
|
case(BE): new_value = (value[1]<<0) | (value[0]<<8); break;
|
|
case(LE): new_value = (value[0]<<0) | (value[1]<<8); break;
|
|
}
|
|
return new_value;
|
|
}
|
|
|
|
u32 u8_to_u32(u8 *value, u8 endianness)
|
|
{
|
|
u32 new_value;
|
|
switch(endianness){
|
|
case(BE): new_value = (value[3]<<0) | (value[2]<<8) | (value[1]<<16) | (value[0]<<24); break;
|
|
case(LE): new_value = (value[0]<<0) | (value[1]<<8) | (value[2]<<16) | (value[3]<<24); break;
|
|
}
|
|
return new_value;
|
|
}
|
|
|
|
|
|
u64 u8_to_u64(u8 *value, u8 endianness)
|
|
{
|
|
u64 u64_return = 0;
|
|
switch(endianness){
|
|
case(BE):
|
|
u64_return |= (u64)value[7]<<0;
|
|
u64_return |= (u64)value[6]<<8;
|
|
u64_return |= (u64)value[5]<<16;
|
|
u64_return |= (u64)value[4]<<24;
|
|
u64_return |= (u64)value[3]<<32;
|
|
u64_return |= (u64)value[2]<<40;
|
|
u64_return |= (u64)value[1]<<48;
|
|
u64_return |= (u64)value[0]<<56;
|
|
break;
|
|
//return (value[7]<<0) | (value[6]<<8) | (value[5]<<16) | (value[4]<<24) | (value[3]<<32) | (value[2]<<40) | (value[1]<<48) | (value[0]<<56);
|
|
case(LE):
|
|
u64_return |= (u64)value[0]<<0;
|
|
u64_return |= (u64)value[1]<<8;
|
|
u64_return |= (u64)value[2]<<16;
|
|
u64_return |= (u64)value[3]<<24;
|
|
u64_return |= (u64)value[4]<<32;
|
|
u64_return |= (u64)value[5]<<40;
|
|
u64_return |= (u64)value[6]<<48;
|
|
u64_return |= (u64)value[7]<<56;
|
|
break;
|
|
//return (value[0]<<0) | (value[1]<<8) | (value[2]<<16) | (value[3]<<24) | (value[4]<<32) | (value[5]<<40) | (value[6]<<48) | (value[7]<<56);
|
|
}
|
|
return u64_return;
|
|
}
|
|
|
|
int u16_to_u8(u8 *out_value, u16 in_value, u8 endianness)
|
|
{
|
|
switch(endianness){
|
|
case(BE):
|
|
out_value[0]=(in_value >> 8);
|
|
out_value[1]=(in_value >> 0);
|
|
break;
|
|
case(LE):
|
|
out_value[0]=(in_value >> 0);
|
|
out_value[1]=(in_value >> 8);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int u32_to_u8(u8 *out_value, u32 in_value, u8 endianness)
|
|
{
|
|
switch(endianness){
|
|
case(BE):
|
|
out_value[0]=(in_value >> 24);
|
|
out_value[1]=(in_value >> 16);
|
|
out_value[2]=(in_value >> 8);
|
|
out_value[3]=(in_value >> 0);
|
|
break;
|
|
case(LE):
|
|
out_value[0]=(in_value >> 0);
|
|
out_value[1]=(in_value >> 8);
|
|
out_value[2]=(in_value >> 16);
|
|
out_value[3]=(in_value >> 24);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int u64_to_u8(u8 *out_value, u64 in_value, u8 endianness)
|
|
{
|
|
switch(endianness){
|
|
case(BE):
|
|
out_value[0]=(in_value >> 56);
|
|
out_value[1]=(in_value >> 48);
|
|
out_value[2]=(in_value >> 40);
|
|
out_value[3]=(in_value >> 32);
|
|
out_value[4]=(in_value >> 24);
|
|
out_value[5]=(in_value >> 16);
|
|
out_value[6]=(in_value >> 8);
|
|
out_value[7]=(in_value >> 0);
|
|
break;
|
|
case(LE):
|
|
out_value[0]=(in_value >> 0);
|
|
out_value[1]=(in_value >> 8);
|
|
out_value[2]=(in_value >> 16);
|
|
out_value[3]=(in_value >> 24);
|
|
out_value[4]=(in_value >> 32);
|
|
out_value[5]=(in_value >> 40);
|
|
out_value[6]=(in_value >> 48);
|
|
out_value[7]=(in_value >> 56);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//Copied from ctrtool
|
|
void memdump(FILE* fout, const char* prefix, const u8* data, u32 size)
|
|
{
|
|
u32 i;
|
|
u32 prefixlen = strlen(prefix);
|
|
u32 offs = 0;
|
|
u32 line = 0;
|
|
while(size)
|
|
{
|
|
u32 max = 32;
|
|
|
|
if (max > size)
|
|
max = size;
|
|
|
|
if (line==0)
|
|
fprintf(fout, "%s", prefix);
|
|
else
|
|
fprintf(fout, "%*s", prefixlen, "");
|
|
|
|
|
|
for(i=0; i<max; i++)
|
|
fprintf(fout, "%02X", data[offs+i]);
|
|
fprintf(fout, "\n");
|
|
line++;
|
|
size -= max;
|
|
offs += max;
|
|
}
|
|
}
|
|
|
|
|