summaryrefslogtreecommitdiff
path: root/other/shellkit/x86.c
diff options
context:
space:
mode:
authorRoot THC2026-02-24 12:42:47 +0000
committerRoot THC2026-02-24 12:42:47 +0000
commitc9cbeced5b3f2bdd7407e29c0811e65954132540 (patch)
treeaefc355416b561111819de159ccbd86c3004cf88 /other/shellkit/x86.c
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'other/shellkit/x86.c')
-rw-r--r--other/shellkit/x86.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/other/shellkit/x86.c b/other/shellkit/x86.c
new file mode 100644
index 0000000..dd580c6
--- /dev/null
+++ b/other/shellkit/x86.c
@@ -0,0 +1,124 @@
1/* x86.c - generic x86 functions
2 *
3 * by team teso
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include "shellcode.h"
9#include "x86.h"
10
11
12static unsigned long int x86_nop_rwreg (void);
13static unsigned long int x86_nop_xfer (char *xferstr);
14
15
16static unsigned long int
17x86_nop_rwreg (void)
18{
19 unsigned long int reg;
20
21 do {
22 reg = random_get (0, 7);
23 } while (reg == 4); /* 4 = $esp */
24
25 return (reg);
26}
27
28
29static unsigned long int
30x86_nop_xfer (char *xferstr)
31{
32 int bw = 0; /* bitfield walker */
33 unsigned char tgt; /* resulting instruction */
34
35 /* in a valid xferstr we trust */
36 for (tgt = 0 ; xferstr != NULL && xferstr[0] != '\0' ; ++xferstr) {
37 switch (xferstr[0]) {
38 case ('0'):
39 BSET (tgt, 1, 0, bw);
40 break;
41 case ('1'):
42 BSET (tgt, 1, 1, bw);
43 break;
44 case ('r'):
45 BSET (tgt, 3, x86_nop_rwreg (), bw);
46 break;
47 case ('.'):
48 break; /* ignore */
49 default:
50 fprintf (stderr, "on steroids, huh?\n");
51 exit (EXIT_FAILURE);
52 break;
53 }
54 }
55
56 if (bw != 8) {
57 fprintf (stderr, "invalid bitwalker: bw = %d\n", bw);
58 exit (EXIT_FAILURE);
59 }
60
61 return (tgt);
62}
63
64
65unsigned int
66x86_nop (unsigned char *dest, unsigned int dest_len,
67 unsigned char *bad, int bad_len)
68{
69 int walk;
70 int bcount; /* bad counter */
71 char * xs;
72 char * xferstr[] = {
73 "0011.0111", /* aaa */
74 "0011.1111", /* aas */
75 "1001.1000", /* cbw */
76 "1001.1001", /* cdq */
77 "1111.1000", /* clc */
78 "1111.1100", /* cld */
79 "1111.0101", /* cmc */
80 "0010.0111", /* daa */
81 "0010.1111", /* das */
82 "0100.1r", /* dec <reg> */
83 "0100.0r", /* inc <reg> */
84 "1001.1111", /* lahf */
85 "1001.0000", /* nop */
86 "1111.1001", /* stc */
87 "1111.1101", /* std */
88 "1001.0r", /* xchg al, <reg> */
89 NULL,
90 };
91 unsigned char tgt;
92
93/*
94 * XXX: those nops are only one byte long. they could be used as byte values
95 * in opcodes like mov (add, sub, or, ...) as value. that would increase the
96 * randomness of the string. since the value is "nop save" we have no problem
97 * if the execution starts within this nop.
98 * now, having word sized nops, even larger nops are possible (again increasssing
99 * the randomness of the nop string).
100 * however, its a little complicated ;)
101 */
102
103 for (walk = 0 ; dest_len > 0 ; dest_len -= 1 , walk += 1) {
104 /* avoid endless loops on excessive badlisting */
105 for (bcount = 0 ; bcount < 16384 ; ++bcount) {
106 xs = xferstr[random_get (0, 15)];
107 tgt = x86_nop_xfer (xs);
108
109 dest[walk] = tgt;
110 if (badstr (&dest[walk], 1, bad, bad_len) == 0)
111 break;
112 }
113
114 /* should not happen */
115 if (bcount >= 16384) {
116 fprintf (stderr, "too much blacklisting, giving up...\n");
117 exit (EXIT_FAILURE);
118 }
119 }
120
121 return (walk);
122}
123
124