Files
Project_CTR/utils.c
2014-02-16 16:55:00 +08:00

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;
}
}