Converter Shellcode/Hex/ASCII
12. November 2012 04:26

Ein C Programm, welches bei der Shellcode-Entwicklung helfen soll.

                    /*

 	Utility for Shellcode Work
 	2010 tuxwave.net
 	
 	Have phun!

 */
#include <unistd.h>
#include <stdlib.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>

struct code
{
	long length;
	void *code;
};

static void usage(char *argv[]);
static void encode(char *val, char *exec, char *output);
static void decode(char *val, char *exec, char *output);
static void execute(void *code);
static void tool(char *output);

static int is_little_endian(void);
static int fileread(char *filename, struct code *codeinfo);
static short htos (const short *ptr);

void ascii_hex(char *output);
void hex_ascii(char *output);
void decimal_hex(char *output);
void hex_decimal(char *output);

int main(int argc, char *argv[], char *envp[])
{
	int option;
	char *encval = (char *) 0, *decval = (char *) 0, *exeval = (char *) 0, *tval = (char *) 0, *output = (char *) 0;

	if(argc == 1) usage(argv);
	while((option = getopt(argc, argv, ":he:d:xt")) != -1)
	{
		switch(option)
		{
			case 'e':
				encval = optarg;
				break;
			case 'd':
				decval = optarg;
				break;
			case 'x':
				exeval = (char *)0x1;
				break;
			case 't':
				tval = (char *)0x1;
				break;
			case 'h':
			case '?':
			default:
				usage(argv);
				break;
		}
	}
	if(argv[optind] != NULL)
	{
		output = argv[optind];
	}
	if(encval != (char *) 0) encode(encval, exeval, output);
	else if(decval != (char *) 0) decode(decval, exeval, output);
	else if(tval != (char *) 0) tool(output);
	else exit(EXIT_SUCCESS);
}

static void usage(char *argv[])
{
	fprintf(stderr, "%s "
	"[options] {output}\n"
	"----------------------------------------------------------------\n"
	"\t-h = help\n"
	"\t-e [file] = encode binary file to hexencoded-binary\n"
	"\t-d [file] = decode hexencoded-binary from file\n"
	"\t-x = execute code\n"
	"\t-t = interactive tool for small stuff\n",
	argv[0]);
	exit(EXIT_FAILURE);
}

static void encode(char *val, char *exec, char *output)
{
	struct code codeinfo;
	int count = 0, col = 0, cols = 14;
	FILE *outfile = NULL;
	if(output == NULL || output[0] == '-')
	{
		outfile = stdout;
	}
	else if(output != NULL)
	{
		outfile = fopen(output, "w");
		if(outfile == NULL)
		{
			fprintf(stderr, "Error opening %s for writing. Error: %s", output, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}
	
	fileread(val, &codeinfo);

	fprintf(outfile, "char shellcode[] = \n");
	for(count = 0; count < codeinfo.length; ++count)
	{
		if(col >= cols)
		{
			fprintf(outfile, "\"\n");
			col = 0;
		}
		if(col == 0)
		{
			fprintf(outfile, "\"");
		}
		fprintf(outfile, "\\x%02x", ((unsigned char *)codeinfo.code)[count]);
		++col;
        }
	fprintf(outfile, "\";\n");
	fflush(outfile);
	if(exec != NULL)
	{
		execute(codeinfo.code);	
	}
	free(codeinfo.code);
}

static void decode(char *val, char *exec, char *output)
{
	struct code codeinfo;
	FILE *outfile = NULL;
	if(output == NULL || output[0] == '-')
	{
		outfile = stdout;
	}
	else if(output != NULL)
	{
		outfile = fopen(output, "w");
		if(outfile == NULL)
		{
			fprintf(stderr, "Error opening %s for writing. Error: %s", output, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}
	
	fileread(val, &codeinfo);

	int i = 0, buflen = 0;
	char *buffer = (char *) malloc(codeinfo.length);
	memset(buffer, '\0', codeinfo.length);
	for(i = 0;i < codeinfo.length;i++)
	{
		if(i < 19) continue; /*bypass char shellcode[] =*/
		if(((char *)codeinfo.code)[i] == '"') continue;
		if(((char *)codeinfo.code)[i] == ';') continue;
		if(((char *)codeinfo.code)[i] == '\\') continue;
		if(((char *)codeinfo.code)[i] == 'x') continue;
		if(((char *)codeinfo.code)[i] == '\n') continue;
		buffer[buflen] = ((char *)codeinfo.code)[i];
		buflen++;
	}
	int byc = 0;
	short *buf = (short *) malloc(2);
	memset(buf, 0, 2);
	short byte;
	memset(codeinfo.code, '\0', codeinfo.length);
	codeinfo.length = 0;
	for(i = 0;i < buflen;i++)
	{
		if(buffer[i] == '\0') break;
		buf[byc] = buffer[i];
		byc++;
		if(byc == 2)
		{
			byte = htos(buf);
			((unsigned char *)codeinfo.code)[codeinfo.length] = byte;
			codeinfo.length++;
			if(!((fwrite(&byte, 1, 1, outfile)) > 0))
			{
				fprintf(stderr, "Error writing to file %s. Error: %s\n", output, strerror(errno));
				exit(EXIT_FAILURE);
			}
			byc = 0;
			continue;
		}
	}
	fflush(outfile);
	if(exec != NULL)
	{
		execute(codeinfo.code);	
	}
	free(buffer);
	free(codeinfo.code);
}

static void execute(void *code)
{
	printf("Executing code...\n");
	void (*fptr)(void);		/*function pointer fptr*/
	fptr = (void (*)(void)) code; /*fptr gets address of -> code gets casted into -> void function(void)*/ 
        (*fptr)();			/*call function*/
	return;
}

static int fileread(char *filename, struct code *codeinfo)
{
	FILE *file = fopen(filename, "r");
	struct stat statbuf;

	if(stat(filename, &statbuf) != 0)
	{
		fprintf(stderr, "Could not stat file: %s Error: %s\n", filename, strerror(errno));
		exit(EXIT_FAILURE);
	}
	codeinfo->length = (long)statbuf.st_size;

	if(!(codeinfo->code = (void *) malloc(codeinfo->length)))
	{
		fprintf(stderr, "malloc error: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	memset(codeinfo->code, '\0', codeinfo->length);
	if(fread(codeinfo->code, 1, codeinfo->length, file) != codeinfo->length)
	{
		fprintf(stderr, "fread error: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
	return(0);
}

static int is_little_endian(void)
{
	unsigned short word = 0x1234;
	unsigned char *p = (unsigned char *) &word;
	if(p[0] == 0x34)
	{
		return(1);
	}
	return(0);
}

static short htos (const short *ptr)
{
	short value = 0;
	short ch = *ptr;
	while (ch == ' ' || ch == '\t')
	ch = *(++ptr);
	for (;;)
	{
		if (ch >= '0' && ch <= '9')
			value = (value << 4) + (ch - '0');
		else if (ch >= 'A' && ch <= 'F')
			value = (value << 4) + (ch - 'A' + 10);
		else if (ch >= 'a' && ch <= 'f')
			value = (value << 4) + (ch - 'a' + 10);
		else
		return value;
		ch = *(++ptr);
	}
}

static void tool(char *output)
{
	if(!isatty(0))
	{
		fprintf(stderr, "Must be a tty!\n");
		exit(EXIT_FAILURE);
	}

	
	struct termios oldterm, newterm;
	tcgetattr(0,&oldterm);
	newterm = oldterm;
	newterm.c_lflag &= ~ECHO;
	newterm.c_lflag &= ~ICANON;

	while(1)
	{
		printf(	".........................................\n"
		"Chose:\n"
		".........................................\n"
		"a - ascii to hex\n"
		"h - hex to ascii\n"
		"d - decimal to hex\n"
		"n - hex to decimal\n"
		"q - quit\n"
		".........................................\n");
		tcsetattr(0, TCSANOW, &newterm);
		int choice = getchar();
		tcsetattr(0, TCSANOW, &oldterm);
		if(choice == EOF || choice == 'q')
		{
			exit(EXIT_SUCCESS);
		}
		switch(choice)
		{
			case 'a':
				ascii_hex(output);
				break;
			case 'h':
				hex_ascii(output);
				break;
			case 'd':
				decimal_hex(output);
				break;
			case 'n':
				hex_decimal(output);
				break;
			default:
			break;
		}
	}
}
	/*
	 * 	Ausgabe:
	 * 	Endianness beachten!
	 * 	ascii-to-hex -> hex, hex little endian, hex-ascii codiert(rückwärts+vorwärts), 0xfff und 0xff 0xff
	 * 	hex to ascii -> nach ascii, 0xfffff und 0xff 0xff 0xff formate
	 * 	decimal-to-hex -> hex, hex little endian
	 * 	hex-to-decimal -> decimal little endian, big endian
	 */

void ascii_hex(char *output)
{
	FILE *outfile = NULL;
	if(output != NULL)
	{
		outfile = fopen(output, "w");
		if(outfile == NULL)
		{
			fprintf(stderr, "Error opening %s for writing. Error: %s", output, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	int in, size = 100, count = 0;
	char *input = (char *) malloc(sizeof(char)*size);

	struct termios oldterm, newterm;
	tcgetattr(0,&oldterm);
	newterm = oldterm;
	newterm.c_lflag &= ~ICANON;

	if(input == NULL)
	{
		perror("malloc");
	}
	memset(input, '\0', sizeof(char)*size);

	printf("Enter String: ");

	tcsetattr(0, TCSANOW, &newterm);
	fflush(stdin);
	while((in = fgetc(stdin)))
	{
		if((char)in == '\n') {break;}
		*(input+count) = (char) in;	
		count++;
		if(size == count)
		{
			size += 100;
			if((input = realloc(input, sizeof(char)*size)) == NULL)
			{
				perror("realloc");
				exit(EXIT_FAILURE);
			}
			memset(input+count, '\0', (sizeof(char)*size)-count);
		}
	}
	tcsetattr(0, TCSANOW, &oldterm);
	if(*(input) == '\0') return;
	int i;

	if(output != NULL) fprintf(outfile, "%s\n", input);

	printf("String (reversed): ");
	for(i = count-1;i >= 0;i--)
	{
		if(*(input+i) == '\0') break;
		printf("%c", *(input+i));
		if(output != NULL) fprintf(outfile, "%c", *(input+i));
	}
	if(output != NULL) fprintf(outfile, "\n");

	printf("\nHex-String: 0x");
	if(output != NULL) fprintf(outfile, "0x");
	for(i = 0;i < count;i++)
	{
		if(*(input+i) == '\0') break;
		printf("%02x", *(input+i));
		if(output != NULL) fprintf(outfile, "%02x", *(input+i));
	}
	if(output != NULL) fprintf(outfile, "\n");

	printf("\nHex-String (reversed): 0x");
	if(output != NULL) fprintf(outfile, "0x");
	for(i = count-1;i >= 0;i--)
	{
		if(*(input+i) == '\0') break;
		printf("%02x", *(input+i));
		if(output != NULL) fprintf(outfile, "%02x", *(input+i));
	}
	if(output != NULL) fprintf(outfile, "\n");

	printf("\nHex-String (with 0x): ");
	for(i = 0;i < count;i++)
	{
		if(*(input+i) == '\0') break;
		printf("0x%02x ", *(input+i));
		if(output != NULL) fprintf(outfile, "0x%02x ", *(input+i));
	}
	if(output != NULL) fprintf(outfile, "\n");

	printf("\nHex-String (with 0x, reversed): ");
	for(i = count-1;i >= 0;i--)
	{
		if(*(input+i) == '\0') break;
		printf("0x%02x ", *(input+i));
		if(output != NULL) fprintf(outfile, "0x%02x ", *(input+i));
	}
	if(output != NULL) fprintf(outfile, "\n");
	printf("\n");

	return;
}

void hex_ascii(char *output)
{
	FILE *outfile = NULL;
	if(output != NULL)
	{
		outfile = fopen(output, "w");
		if(outfile == NULL)
		{
			fprintf(stderr, "Error opening %s for writing. Error: %s", output, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	int in, size = 100, count = 0;
	char *input = (char *) malloc(sizeof(char)*size);

	struct termios oldterm, newterm;
	tcgetattr(0,&oldterm);
	newterm = oldterm;
	newterm.c_lflag &= ~ICANON;

	if(input == NULL)
	{
		perror("malloc");
	}
	memset(input, '\0', sizeof(char)*size);

	printf("Enter Hex-String: ");

	tcsetattr(0, TCSANOW, &newterm);
	fflush(stdin);

	int lastchar;
	while((in = fgetc(stdin)))
	{
		if((char)in == '\n') {break;}
		if(lastchar == '0' && ((char)in) != 'x' && ((char)in) != 'X')
		{
			*(input+count) = '0';	
			count++;
			if(size == count)
			{
				size += 100;
				if((input = realloc(input, sizeof(char)*size)) == NULL)
				{
					perror("realloc");
					exit(EXIT_FAILURE);
				}
				memset(input+count, '\0', (sizeof(char)*size)-count);
			}
		}
		lastchar = in;
		if(((char)in) == '0' || ((char)in) == 'x' || ((char)in) == 'X') continue;
		*(input+count) = (char) in;	
		count++;
		if(size == count)
		{
			size += 100;
			if((input = realloc(input, sizeof(char)*size)) == NULL)
			{
				perror("realloc");
				exit(EXIT_FAILURE);
			}
			memset(input+count, '\0', (sizeof(char)*size)-count);
		}
	}
	if(*(input) == '\0') return;
	tcsetattr(0, TCSANOW, &oldterm);

	int byc = 0, i = 0;
	short *buf = (short *) malloc(2);
	memset(buf, 0, 2);
	printf("In ASCII: ");
	for(i = 0;i < count;i++)
	{
		if(input[i] == '\0') break;
		buf[byc] = input[i];
		byc++;
		if(byc == 2)
		{
			printf("%c", htos(buf));
			if(output != NULL) fprintf(outfile, "%c", htos(buf));
			byc = 0;
			continue;
		}
	}
	printf("\n");
	if(output != NULL) fprintf(outfile, "\n");
	return;
}

void decimal_hex(char *output)
{
	FILE *outfile = NULL;
	if(output != NULL)
	{
		outfile = fopen(output, "w");
		if(outfile == NULL)
		{
			fprintf(stderr, "Error opening %s for writing. Error: %s", output, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	int in, size = 100, count = 0;
	char *input = (char *) malloc(sizeof(char)*size);

	struct termios oldterm, newterm;
	tcgetattr(0,&oldterm);
	newterm = oldterm;
	newterm.c_lflag &= ~ICANON;

	if(input == NULL)
	{
		perror("malloc");
	}
	memset(input, '\0', sizeof(char)*size);

	printf("Enter decimal number: ");
	fflush(stdin);
	tcsetattr(0, TCSANOW, &newterm);
	while((in = fgetc(stdin)))
	{
		if((char)in == '\n') {break;}
		*(input+count) = (char) in;	
		count++;
		if(size == count)
		{
			size += 100;
			if((input = realloc(input, sizeof(char)*size)) == NULL)
			{
				perror("realloc");
				exit(EXIT_FAILURE);
			}
			memset(input+count, '\0', (sizeof(char)*size)-count);
		}
	}
	if(*(input) == '\0') return;
	tcsetattr(0, TCSANOW, &oldterm);
	
	int number = atoi(input);
	printf("In Hex: %#x\n", number);
	fprintf(outfile, "%#x\n", number);
	return;
}

void hex_decimal(char *output)
{
	FILE *outfile = NULL;
	if(output != NULL)
	{
		outfile = fopen(output, "w");
		if(outfile == NULL)
		{
			fprintf(stderr, "Error opening %s for writing. Error: %s", output, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	int in, size = 100, count = 0;
	char *input = (char *) malloc(sizeof(char)*size);

	struct termios oldterm, newterm;
	tcgetattr(0,&oldterm);
	newterm = oldterm;
	newterm.c_lflag &= ~ICANON;

	if(input == NULL)
	{
		perror("malloc");
	}
	memset(input, '\0', sizeof(char)*size);

	printf("Enter Hex-String: ");

	tcsetattr(0, TCSANOW, &newterm);
	fflush(stdin);

	int lastchar;
	while((in = fgetc(stdin)))
	{
		if((char)in == '\n') {break;}
		if(lastchar == '0' && ((char)in) != 'x' && ((char)in) != 'X')
		{
			*(input+count) = '0';	
			count++;
			if(size == count)
			{
				size += 100;
				if((input = realloc(input, sizeof(char)*size)) == NULL)
				{
					perror("realloc");
					exit(EXIT_FAILURE);
				}
				memset(input+count, '\0', (sizeof(char)*size)-count);
			}
		}
		lastchar = in;
		if(((char)in) == '0' || ((char)in) == 'x' || ((char)in) == 'X') continue;
		*(input+count) = (char) in;	
		count++;
		if(size == count)
		{
			size += 100;
			if((input = realloc(input, sizeof(char)*size)) == NULL)
			{
				perror("realloc");
				exit(EXIT_FAILURE);
			}
			memset(input+count, '\0', (sizeof(char)*size)-count);
		}
	}
	if(*(input) == '\0') return;
	tcsetattr(0, TCSANOW, &oldterm);
	long number;
	sscanf(input, "%lx", &number);
	printf("In decimal: %d\n", number); 
	if(output != NULL) fprintf(outfile, "%d\n", number);

	return;
}

                    
        
Download