From the book “Buffer Overflow Attacks” by Foster and others, I came across this very handy tool for testing developing shellcode. It takes your assembly and puts it into a well commented C array to be tested by execution or simply printing to the screen.
To compile thes program, type gcc -o printshell printshellcode.c
Now, if you want to try out your shellcode assembly,
- Type the instructions in a .S file
- Execute nasm -o <filename> <filename>.S
- To print the shellcode use printshellcode -p <filename>.
- To execute the shellcode use printshellcode -e <filename>
/*printshellcode.c*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
/*Print message function*/
static void croak(const char *msg){
fprintf(stderr, "%s\n", msg);
fflush(stderr);
}
/*Usage funcion*/
static void usage(const char *prgnam){
fprintf(stderr, "\nExecute code : %s -e \n", prgnam);
fflush(stderr);
exit(1);
}
/*Signal error and bail out*/
static void barf(const char *msg){
perror(msg);
exit(1);
}
/*main*/
int main(int argc, char **argv){
FILE *fp;
void *code;
int i,l,arg;
int m=15; /* max number of bytes on a line*/
struct stat sbuf;
long flen; /*assume files are < 2**32*/
void (*fptr)(void);
if(argc < 3) usage(argv[0]);
if(stat(argv[2], &sbuf)) barf("failed to stat file");
flen = (long) sbuf.st_size;
if(!(code = malloc(flen))) barf("failed to grab enough memory");
if(!(fp = fopen(argv[2], "rb"))) barf("failed to open file");
if(fclose(fp)) barf("failed to close file");
while ((arg = getopt (argc, argv, "e:p:")) != 1){
switch(arg){
case 'e':
croak("Calling code ...");
fptr = (void (*)(void)) code;
(*fptr)();
break;
case 'p':
printf("\n/* The following shellcode is %d bytes long: */\n",flen);
printf("\nchar shellcode[] = \n");
l = m;
for(i = 0; i= m){
if(i) printf("\"\n");
printf( "\t\"");
l = 0;
}
++l;
printf("\\x%02x", ((unsigned char *)code)[i]);
}
printf("\";\n\n\n");
break;
default:
usage(argv[0]);
}
}
return 0;
}