1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
/* sparc.c - generic sparc functions
*
* by team teso
*/
#include <stdio.h>
#include <stdlib.h>
#include "shellcode.h"
#include "sparc.h"
static int sparc_torf (void);
static unsigned long int sparc_getinstr (unsigned char *pat,
unsigned char *bad, int bad_len);
static int
sparc_torf (void)
{
return (random_get (0, 1));
}
static unsigned long int
sparc_getinstr (unsigned char *pat, unsigned char *bad, int bad_len)
{
int x; /* bitfield walker */
unsigned char bc = 0;
unsigned long int i = 0; /* generated instruction */
for (x = 31 ; x > 0 ; --x) {
switch (pat[x]) {
case '.':
if (badstr (&bc, 1, bad, bad_len)) {
/*x -= 8;*/
printf ("redo byte! #muh\n");
}
bc = 0;
break;
case '0':
break;
case '1':
i |= (1 << x);
bc |= (1 << (x % 8));
break;
case 'v':
if (badstr (&bc, 1, bad, bad_len)) {
i |= (1 << x);
bc |= (1 << (x % 8));
} else if (sparc_torf ()) {
i |= (1 << x);
bc |= (1 << (x % 8));
}
break;
case 'r':
case 'f':
case 's':
if (badstr (&bc, 1, bad, bad_len)) {
i |= (1 << x);
bc |= (1 << (x % 8));
} else if (sparc_torf ()) {
i |= (1 << x);
bc |= (1 << (x % 8));
}
break;
default:
fprintf (stderr, "sorry, can not generate nop's for "
"trinary sparcs ...\n");
exit (EXIT_FAILURE);
break;
}
}
return (i);
}
/* XXX: DO NOT USE UNTESTED! */
unsigned int
sparc_nop (unsigned char *dest, unsigned int dest_len,
unsigned char *bad, int bad_len)
{
unsigned long int * dest_p = NULL;
unsigned int count = 0;
/* abstract representation of a sparc instruction.
* '1', '0': real bits of the instruction
* 'r', 'f', 's': destination, first and second source register
* 'v': either a 1 or 0 bit (any value)
*
* for details see "The SPARC Architecture Manual", chapter 5
* ("Instructions") and appendix F + B.
*/
unsigned char * pat = NULL;
unsigned char * instr_format[] = {
"10rrrrr0.00011fff.ff000000.000sssss",
"10rrrrr0.00011fff.ff1vvvvv.vvvvvvvv", /* xor */
"10rrrrr0.00111fff.ff000000.000sssss",
"10rrrrr0.00111fff.ff1vvvvv.vvvvvvvv", /* xnor */
"10rrrrr0.00100fff.ff000000.000sssss",
"10rrrrr0.00100fff.ff1vvvvv.vvvvvvvv", /* sub */
"10rrrrr0.00010fff.ff000000.000sssss",
"10rrrrr0.00010fff.ff1vvvvv.vvvvvvvv", /* or */
"10rrrrr0.00000fff.ff000000.000sssss",
"10rrrrr0.00000fff.ff1vvvvv.vvvvvvvv", /* add */
"10rrrrr0.00001fff.ff000000.000sssss",
"10rrrrr0.00001fff.ff1vvvvv.vvvvvvvv", /* and */
/* XXX/TODO: add more codes */
NULL,
};
/* take care of instruction size
*/
dest_len = dest_len - (dest_len % 4);
dest_p = (unsigned long int *) dest;
for ( ; count < dest_len ; count += 4) {
pat = instr_format[rand () % 12];
*dest_p++ = sparc_getinstr (pat, bad, bad_len);
}
return (count);
}
|