├── .cargo
└── config.toml
├── .gitignore
├── .idea
├── .gitignore
├── modules.xml
├── rekk.iml
└── vcs.xml
├── Cargo.lock
├── Cargo.toml
├── LICENSE
├── README.md
├── common
├── .gitignore
├── Cargo.toml
└── src
│ ├── flags.rs
│ ├── jump_data.rs
│ ├── jump_data_table.rs
│ └── lib.rs
├── infector
├── .gitignore
├── Cargo.toml
└── src
│ ├── binary_parser.rs
│ ├── code_section.rs
│ ├── infestor.rs
│ ├── jump_data_exporter.rs
│ ├── main.rs
│ └── print_utils.rs
├── runtime
├── .gitignore
├── Cargo.toml
└── src
│ ├── linux_runtime.rs
│ ├── main.rs
│ └── windows_runtime.rs
└── test
└── test.c
/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | rustflags=["-C", "target-feature=+aes,+ssse3"]
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Project exclude paths
2 | /target/
3 | /test/*.o
4 | nanomite.bin
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/rekk.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | [[package]]
4 | name = "adler"
5 | version = "1.0.2"
6 | source = "registry+https://github.com/rust-lang/crates.io-index"
7 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
8 |
9 | [[package]]
10 | name = "aesni"
11 | version = "0.10.0"
12 | source = "registry+https://github.com/rust-lang/crates.io-index"
13 | checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce"
14 | dependencies = [
15 | "cipher",
16 | "opaque-debug",
17 | ]
18 |
19 | [[package]]
20 | name = "autocfg"
21 | version = "1.0.1"
22 | source = "registry+https://github.com/rust-lang/crates.io-index"
23 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
24 |
25 | [[package]]
26 | name = "bincode"
27 | version = "1.3.2"
28 | source = "registry+https://github.com/rust-lang/crates.io-index"
29 | checksum = "d175dfa69e619905c4c3cdb7c3c203fa3bdd5d51184e3afdb2742c0280493772"
30 | dependencies = [
31 | "byteorder",
32 | "serde",
33 | ]
34 |
35 | [[package]]
36 | name = "bitflags"
37 | version = "1.2.1"
38 | source = "registry+https://github.com/rust-lang/crates.io-index"
39 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
40 |
41 | [[package]]
42 | name = "block-modes"
43 | version = "0.7.0"
44 | source = "registry+https://github.com/rust-lang/crates.io-index"
45 | checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0"
46 | dependencies = [
47 | "block-padding",
48 | "cipher",
49 | ]
50 |
51 | [[package]]
52 | name = "block-padding"
53 | version = "0.2.1"
54 | source = "registry+https://github.com/rust-lang/crates.io-index"
55 | checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
56 |
57 | [[package]]
58 | name = "byteorder"
59 | version = "1.3.4"
60 | source = "registry+https://github.com/rust-lang/crates.io-index"
61 | checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
62 |
63 | [[package]]
64 | name = "cc"
65 | version = "1.0.67"
66 | source = "registry+https://github.com/rust-lang/crates.io-index"
67 | checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
68 |
69 | [[package]]
70 | name = "cfg-if"
71 | version = "1.0.0"
72 | source = "registry+https://github.com/rust-lang/crates.io-index"
73 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
74 |
75 | [[package]]
76 | name = "chrono"
77 | version = "0.4.19"
78 | source = "registry+https://github.com/rust-lang/crates.io-index"
79 | checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
80 | dependencies = [
81 | "libc",
82 | "num-integer",
83 | "num-traits",
84 | "time",
85 | "winapi",
86 | ]
87 |
88 | [[package]]
89 | name = "cipher"
90 | version = "0.2.5"
91 | source = "registry+https://github.com/rust-lang/crates.io-index"
92 | checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801"
93 | dependencies = [
94 | "generic-array",
95 | ]
96 |
97 | [[package]]
98 | name = "common"
99 | version = "0.1.0"
100 | dependencies = [
101 | "aesni",
102 | "bincode",
103 | "block-modes",
104 | "num-derive",
105 | "num-traits",
106 | "serde",
107 | ]
108 |
109 | [[package]]
110 | name = "crc32fast"
111 | version = "1.2.1"
112 | source = "registry+https://github.com/rust-lang/crates.io-index"
113 | checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
114 | dependencies = [
115 | "cfg-if",
116 | ]
117 |
118 | [[package]]
119 | name = "flate2"
120 | version = "1.0.20"
121 | source = "registry+https://github.com/rust-lang/crates.io-index"
122 | checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
123 | dependencies = [
124 | "cfg-if",
125 | "crc32fast",
126 | "libc",
127 | "miniz_oxide",
128 | ]
129 |
130 | [[package]]
131 | name = "generic-array"
132 | version = "0.14.4"
133 | source = "registry+https://github.com/rust-lang/crates.io-index"
134 | checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
135 | dependencies = [
136 | "typenum",
137 | "version_check",
138 | ]
139 |
140 | [[package]]
141 | name = "getrandom"
142 | version = "0.2.2"
143 | source = "registry+https://github.com/rust-lang/crates.io-index"
144 | checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
145 | dependencies = [
146 | "cfg-if",
147 | "libc",
148 | "wasi",
149 | ]
150 |
151 | [[package]]
152 | name = "goblin"
153 | version = "0.3.4"
154 | source = "registry+https://github.com/rust-lang/crates.io-index"
155 | checksum = "669cdc3826f69a51d3f8fc3f86de81c2378110254f678b8407977736122057a4"
156 | dependencies = [
157 | "log",
158 | "plain",
159 | "scroll",
160 | ]
161 |
162 | [[package]]
163 | name = "hex"
164 | version = "0.4.3"
165 | source = "registry+https://github.com/rust-lang/crates.io-index"
166 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
167 |
168 | [[package]]
169 | name = "iced-x86"
170 | version = "1.10.3"
171 | source = "registry+https://github.com/rust-lang/crates.io-index"
172 | checksum = "644fd8d7e49d1ccae568a8fbb873a7ee7fcb3bc9214a474a5e55c03b6d1fa5ac"
173 | dependencies = [
174 | "lazy_static",
175 | "rustc_version",
176 | "static_assertions",
177 | ]
178 |
179 | [[package]]
180 | name = "infector"
181 | version = "0.1.0"
182 | dependencies = [
183 | "bincode",
184 | "common",
185 | "goblin",
186 | "iced-x86",
187 | "num-derive",
188 | "num-traits",
189 | "rand",
190 | "snap",
191 | "termcolor",
192 | ]
193 |
194 | [[package]]
195 | name = "lazy_static"
196 | version = "1.4.0"
197 | source = "registry+https://github.com/rust-lang/crates.io-index"
198 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
199 |
200 | [[package]]
201 | name = "libc"
202 | version = "0.2.87"
203 | source = "registry+https://github.com/rust-lang/crates.io-index"
204 | checksum = "265d751d31d6780a3f956bb5b8022feba2d94eeee5a84ba64f4212eedca42213"
205 |
206 | [[package]]
207 | name = "log"
208 | version = "0.4.14"
209 | source = "registry+https://github.com/rust-lang/crates.io-index"
210 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
211 | dependencies = [
212 | "cfg-if",
213 | ]
214 |
215 | [[package]]
216 | name = "miniz_oxide"
217 | version = "0.4.4"
218 | source = "registry+https://github.com/rust-lang/crates.io-index"
219 | checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
220 | dependencies = [
221 | "adler",
222 | "autocfg",
223 | ]
224 |
225 | [[package]]
226 | name = "nix"
227 | version = "0.20.0"
228 | source = "registry+https://github.com/rust-lang/crates.io-index"
229 | checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a"
230 | dependencies = [
231 | "bitflags",
232 | "cc",
233 | "cfg-if",
234 | "libc",
235 | ]
236 |
237 | [[package]]
238 | name = "ntapi"
239 | version = "0.3.6"
240 | source = "registry+https://github.com/rust-lang/crates.io-index"
241 | checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
242 | dependencies = [
243 | "winapi",
244 | ]
245 |
246 | [[package]]
247 | name = "num-derive"
248 | version = "0.2.5"
249 | source = "registry+https://github.com/rust-lang/crates.io-index"
250 | checksum = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2"
251 | dependencies = [
252 | "proc-macro2 0.4.30",
253 | "quote 0.6.13",
254 | "syn 0.15.44",
255 | ]
256 |
257 | [[package]]
258 | name = "num-integer"
259 | version = "0.1.44"
260 | source = "registry+https://github.com/rust-lang/crates.io-index"
261 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
262 | dependencies = [
263 | "autocfg",
264 | "num-traits",
265 | ]
266 |
267 | [[package]]
268 | name = "num-traits"
269 | version = "0.2.14"
270 | source = "registry+https://github.com/rust-lang/crates.io-index"
271 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
272 | dependencies = [
273 | "autocfg",
274 | ]
275 |
276 | [[package]]
277 | name = "opaque-debug"
278 | version = "0.3.0"
279 | source = "registry+https://github.com/rust-lang/crates.io-index"
280 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
281 |
282 | [[package]]
283 | name = "plain"
284 | version = "0.2.3"
285 | source = "registry+https://github.com/rust-lang/crates.io-index"
286 | checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
287 |
288 | [[package]]
289 | name = "ppv-lite86"
290 | version = "0.2.10"
291 | source = "registry+https://github.com/rust-lang/crates.io-index"
292 | checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
293 |
294 | [[package]]
295 | name = "proc-macro2"
296 | version = "0.4.30"
297 | source = "registry+https://github.com/rust-lang/crates.io-index"
298 | checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
299 | dependencies = [
300 | "unicode-xid 0.1.0",
301 | ]
302 |
303 | [[package]]
304 | name = "proc-macro2"
305 | version = "1.0.24"
306 | source = "registry+https://github.com/rust-lang/crates.io-index"
307 | checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
308 | dependencies = [
309 | "unicode-xid 0.2.1",
310 | ]
311 |
312 | [[package]]
313 | name = "procfs"
314 | version = "0.9.1"
315 | source = "registry+https://github.com/rust-lang/crates.io-index"
316 | checksum = "ab8809e0c18450a2db0f236d2a44ec0b4c1412d0eb936233579f0990faa5d5cd"
317 | dependencies = [
318 | "bitflags",
319 | "byteorder",
320 | "chrono",
321 | "flate2",
322 | "hex",
323 | "lazy_static",
324 | "libc",
325 | ]
326 |
327 | [[package]]
328 | name = "quote"
329 | version = "0.6.13"
330 | source = "registry+https://github.com/rust-lang/crates.io-index"
331 | checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
332 | dependencies = [
333 | "proc-macro2 0.4.30",
334 | ]
335 |
336 | [[package]]
337 | name = "quote"
338 | version = "1.0.9"
339 | source = "registry+https://github.com/rust-lang/crates.io-index"
340 | checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
341 | dependencies = [
342 | "proc-macro2 1.0.24",
343 | ]
344 |
345 | [[package]]
346 | name = "rand"
347 | version = "0.8.3"
348 | source = "registry+https://github.com/rust-lang/crates.io-index"
349 | checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
350 | dependencies = [
351 | "libc",
352 | "rand_chacha",
353 | "rand_core",
354 | "rand_hc",
355 | ]
356 |
357 | [[package]]
358 | name = "rand_chacha"
359 | version = "0.3.0"
360 | source = "registry+https://github.com/rust-lang/crates.io-index"
361 | checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
362 | dependencies = [
363 | "ppv-lite86",
364 | "rand_core",
365 | ]
366 |
367 | [[package]]
368 | name = "rand_core"
369 | version = "0.6.2"
370 | source = "registry+https://github.com/rust-lang/crates.io-index"
371 | checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
372 | dependencies = [
373 | "getrandom",
374 | ]
375 |
376 | [[package]]
377 | name = "rand_hc"
378 | version = "0.3.0"
379 | source = "registry+https://github.com/rust-lang/crates.io-index"
380 | checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
381 | dependencies = [
382 | "rand_core",
383 | ]
384 |
385 | [[package]]
386 | name = "runtime"
387 | version = "0.1.0"
388 | dependencies = [
389 | "aesni",
390 | "bincode",
391 | "block-modes",
392 | "common",
393 | "nix",
394 | "ntapi",
395 | "procfs",
396 | "snap",
397 | "winapi",
398 | ]
399 |
400 | [[package]]
401 | name = "rustc_version"
402 | version = "0.2.3"
403 | source = "registry+https://github.com/rust-lang/crates.io-index"
404 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
405 | dependencies = [
406 | "semver",
407 | ]
408 |
409 | [[package]]
410 | name = "scroll"
411 | version = "0.10.2"
412 | source = "registry+https://github.com/rust-lang/crates.io-index"
413 | checksum = "fda28d4b4830b807a8b43f7b0e6b5df875311b3e7621d84577188c175b6ec1ec"
414 | dependencies = [
415 | "scroll_derive",
416 | ]
417 |
418 | [[package]]
419 | name = "scroll_derive"
420 | version = "0.10.5"
421 | source = "registry+https://github.com/rust-lang/crates.io-index"
422 | checksum = "aaaae8f38bb311444cfb7f1979af0bc9240d95795f75f9ceddf6a59b79ceffa0"
423 | dependencies = [
424 | "proc-macro2 1.0.24",
425 | "quote 1.0.9",
426 | "syn 1.0.61",
427 | ]
428 |
429 | [[package]]
430 | name = "semver"
431 | version = "0.9.0"
432 | source = "registry+https://github.com/rust-lang/crates.io-index"
433 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
434 | dependencies = [
435 | "semver-parser",
436 | ]
437 |
438 | [[package]]
439 | name = "semver-parser"
440 | version = "0.7.0"
441 | source = "registry+https://github.com/rust-lang/crates.io-index"
442 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
443 |
444 | [[package]]
445 | name = "serde"
446 | version = "1.0.123"
447 | source = "registry+https://github.com/rust-lang/crates.io-index"
448 | checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
449 | dependencies = [
450 | "serde_derive",
451 | ]
452 |
453 | [[package]]
454 | name = "serde_derive"
455 | version = "1.0.123"
456 | source = "registry+https://github.com/rust-lang/crates.io-index"
457 | checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
458 | dependencies = [
459 | "proc-macro2 1.0.24",
460 | "quote 1.0.9",
461 | "syn 1.0.61",
462 | ]
463 |
464 | [[package]]
465 | name = "snap"
466 | version = "1.0.4"
467 | source = "registry+https://github.com/rust-lang/crates.io-index"
468 | checksum = "dc725476a1398f0480d56cd0ad381f6f32acf2642704456f8f59a35df464b59a"
469 |
470 | [[package]]
471 | name = "static_assertions"
472 | version = "0.3.4"
473 | source = "registry+https://github.com/rust-lang/crates.io-index"
474 | checksum = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
475 |
476 | [[package]]
477 | name = "syn"
478 | version = "0.15.44"
479 | source = "registry+https://github.com/rust-lang/crates.io-index"
480 | checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
481 | dependencies = [
482 | "proc-macro2 0.4.30",
483 | "quote 0.6.13",
484 | "unicode-xid 0.1.0",
485 | ]
486 |
487 | [[package]]
488 | name = "syn"
489 | version = "1.0.61"
490 | source = "registry+https://github.com/rust-lang/crates.io-index"
491 | checksum = "ed22b90a0e734a23a7610f4283ac9e5acfb96cbb30dfefa540d66f866f1c09c5"
492 | dependencies = [
493 | "proc-macro2 1.0.24",
494 | "quote 1.0.9",
495 | "unicode-xid 0.2.1",
496 | ]
497 |
498 | [[package]]
499 | name = "termcolor"
500 | version = "1.1.2"
501 | source = "registry+https://github.com/rust-lang/crates.io-index"
502 | checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
503 | dependencies = [
504 | "winapi-util",
505 | ]
506 |
507 | [[package]]
508 | name = "time"
509 | version = "0.1.43"
510 | source = "registry+https://github.com/rust-lang/crates.io-index"
511 | checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
512 | dependencies = [
513 | "libc",
514 | "winapi",
515 | ]
516 |
517 | [[package]]
518 | name = "typenum"
519 | version = "1.12.0"
520 | source = "registry+https://github.com/rust-lang/crates.io-index"
521 | checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
522 |
523 | [[package]]
524 | name = "unicode-xid"
525 | version = "0.1.0"
526 | source = "registry+https://github.com/rust-lang/crates.io-index"
527 | checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
528 |
529 | [[package]]
530 | name = "unicode-xid"
531 | version = "0.2.1"
532 | source = "registry+https://github.com/rust-lang/crates.io-index"
533 | checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
534 |
535 | [[package]]
536 | name = "version_check"
537 | version = "0.9.2"
538 | source = "registry+https://github.com/rust-lang/crates.io-index"
539 | checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
540 |
541 | [[package]]
542 | name = "wasi"
543 | version = "0.10.2+wasi-snapshot-preview1"
544 | source = "registry+https://github.com/rust-lang/crates.io-index"
545 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
546 |
547 | [[package]]
548 | name = "winapi"
549 | version = "0.3.9"
550 | source = "registry+https://github.com/rust-lang/crates.io-index"
551 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
552 | dependencies = [
553 | "winapi-i686-pc-windows-gnu",
554 | "winapi-x86_64-pc-windows-gnu",
555 | ]
556 |
557 | [[package]]
558 | name = "winapi-i686-pc-windows-gnu"
559 | version = "0.4.0"
560 | source = "registry+https://github.com/rust-lang/crates.io-index"
561 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
562 |
563 | [[package]]
564 | name = "winapi-util"
565 | version = "0.1.5"
566 | source = "registry+https://github.com/rust-lang/crates.io-index"
567 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
568 | dependencies = [
569 | "winapi",
570 | ]
571 |
572 | [[package]]
573 | name = "winapi-x86_64-pc-windows-gnu"
574 | version = "0.4.0"
575 | source = "registry+https://github.com/rust-lang/crates.io-index"
576 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
577 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = [
3 | "common",
4 | "infector",
5 | "runtime",
6 | ]
7 |
8 | [profile.release]
9 | lto="fat"
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rekk
2 | rekk is set of tools written in Rust to protect binaries with nanomites. It includes an infector, which disassembles a program and places nanomites, and both a Windows and Linux runtime to execute the nanomite infected binary.
3 |
4 | ## What are nanomites?
5 |
6 | Nanomites are breakpoint instructions (`int 3`). Any conditional jump(`je`, `jne`, `jb`, etc) in a program is replaced with a nanomite. The conditional jump is stored in a table, called the jump data table. The table contains the offset of the nanomite, the target of the jump, and the size of the jump instruction. Each entry is encrypted with a unique key.
7 |
8 | The runtime is complied with the jump data table, and the infected binary. The runtime will then decompress the infected binary, execute it as a child process, then debug it. Eventually, a nanomite will transfer execution to the runtime, since a breakpoint exception has occured. The runtime then looks up the entry in the jump data table, decrypts it, emulates the jump, then adjusts the RIP accordingly.
9 |
10 | # Usage
11 |
12 | Ensure you have Rust installed. First, we need to infect a binary with nanomites. We do this by running the infector program.
13 |
14 | ```
15 | cargo run --release --bin infector -- [TARGET BINARY]
16 | ```
17 |
18 | The infector program will generate two files in the main directory, `nanomite.bin`, the compressed binary with nanomites added, and `jdt.bin`, the compressed & encrypted jump data table.
19 |
20 | Next, compile the runtime using the two files.
21 |
22 | ```
23 | cargo build --release --bin runtime
24 | ```
25 |
26 | When the runtime is built, it will automatically include `nanomite.bin` and `jdt.bin`, and store it in the runtime binary itself. The runtime binary will be available in `target/release/runtime` or `target/release/runtime.exe`.
27 |
28 | That's it! The runtime will then execute the original program transparently.
29 |
--------------------------------------------------------------------------------
/common/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | Cargo.lock
3 |
--------------------------------------------------------------------------------
/common/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "common"
3 | version = "0.1.0"
4 | authors = ["Justin Perez "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 |
11 | aesni = "0.10"
12 | bincode = "1.3"
13 | serde={version = "1.0", features = ["derive"]}
14 | num-traits = "0.2"
15 | num-derive = "0.2"
16 | block-modes = "0.7"
--------------------------------------------------------------------------------
/common/src/flags.rs:
--------------------------------------------------------------------------------
1 | #[derive(Copy, Clone)]
2 | pub enum Flags {
3 | CarryFlag = 0x0001,
4 | ParityFlag = 0x0004,
5 | AdjustFlag = 0x0010,
6 | ZeroFlag = 0x0040,
7 | SignFlag = 0x0080,
8 | TrapFlag = 0x0100,
9 | InterruptEnableFlag = 0x0200,
10 | DirectionFlag = 0x0400,
11 | OverflowFlag = 0x0800,
12 | }
13 |
14 | impl Flags {
15 | pub fn get_flag(&self, eflags: u64) -> bool {
16 | let flag = *self as u64;
17 | eflags & flag != 0
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/common/src/jump_data.rs:
--------------------------------------------------------------------------------
1 | use block_modes::BlockMode;
2 | use serde::{Deserialize, Serialize};
3 |
4 | use crate::flags::Flags;
5 | use crate::{Aes256Cbc, EncryptedJumpData, JumpType, RekkEncKey};
6 |
7 | /// Contains the necessary information to emulate the jump.
8 | #[derive(Serialize, Deserialize, Debug)]
9 | pub struct JumpData {
10 | /// The type of jump.
11 | jump_type: JumpType,
12 |
13 | /// The displacement to jump to if the jump is true.
14 | j_true: isize,
15 |
16 | /// The displacement to jump to if the jump is false.
17 | j_false: usize,
18 | }
19 |
20 | impl JumpData {
21 | pub fn new(jump_type: JumpType, j_true: isize, j_false: usize) -> JumpData {
22 | JumpData {
23 | jump_type,
24 | j_true,
25 | j_false,
26 | }
27 | }
28 |
29 | pub fn encrypt(&self, key: RekkEncKey, iv: &[u8; 16]) -> EncryptedJumpData {
30 | // serialize the object.
31 | let cereal = bincode::serialize(self).unwrap();
32 |
33 | // encrypt it.
34 | let aes = Aes256Cbc::new_var(key.0.as_ref(), iv).unwrap();
35 |
36 | let enc = aes.encrypt_vec(cereal.as_slice());
37 |
38 | EncryptedJumpData { key, data: enc }
39 | }
40 |
41 | pub fn get_ip_offset(&self, eflags: u64) -> isize {
42 | let flag_to_check;
43 |
44 | match self.jump_type {
45 | JumpType::None => {
46 | panic!("unknown err")
47 | }
48 | JumpType::JumpOverflow => {
49 | flag_to_check = (Flags::OverflowFlag, true);
50 | }
51 | JumpType::JumpNotOverflow => {
52 | flag_to_check = (Flags::OverflowFlag, false);
53 | }
54 | JumpType::JumpBelow => {
55 | flag_to_check = (Flags::CarryFlag, true);
56 | }
57 | JumpType::JumpAboveEqual => {
58 | flag_to_check = (Flags::CarryFlag, false);
59 | }
60 | JumpType::JumpEqual => {
61 | flag_to_check = (Flags::ZeroFlag, true);
62 | }
63 | JumpType::JumpNotEqual => {
64 | flag_to_check = (Flags::ZeroFlag, false);
65 | }
66 | JumpType::JumpBelowEqual => {
67 | if Flags::CarryFlag.get_flag(eflags) || Flags::ZeroFlag.get_flag(eflags) {
68 | return self.j_true;
69 | }
70 |
71 | return self.j_false as isize;
72 | }
73 | JumpType::JumpAbove => {
74 | if !Flags::CarryFlag.get_flag(eflags) && !Flags::ZeroFlag.get_flag(eflags) {
75 | return self.j_true;
76 | }
77 |
78 | return self.j_false as isize;
79 | }
80 | JumpType::JumpSigned => {
81 | flag_to_check = (Flags::SignFlag, true);
82 | }
83 | JumpType::JumpNotSigned => {
84 | flag_to_check = (Flags::SignFlag, false);
85 | }
86 | JumpType::JumpParity => {
87 | flag_to_check = (Flags::ParityFlag, true);
88 | }
89 | JumpType::JumpNotParity => {
90 | flag_to_check = (Flags::ParityFlag, false);
91 | }
92 | JumpType::JumpLess => {
93 | if Flags::SignFlag.get_flag(eflags) != Flags::OverflowFlag.get_flag(eflags) {
94 | return self.j_true;
95 | }
96 |
97 | return self.j_false as isize;
98 | }
99 | JumpType::JumpGreaterEqual => {
100 | if Flags::SignFlag.get_flag(eflags) == Flags::OverflowFlag.get_flag(eflags) {
101 | return self.j_true;
102 | }
103 |
104 | return self.j_false as isize;
105 | }
106 | JumpType::JumpLessEqual => {
107 | if Flags::ZeroFlag.get_flag(eflags)
108 | || (Flags::SignFlag.get_flag(eflags) != Flags::OverflowFlag.get_flag(eflags))
109 | {
110 | return self.j_true;
111 | }
112 |
113 | return self.j_false as isize;
114 | }
115 | JumpType::JumpGreater => {
116 | if !Flags::ZeroFlag.get_flag(eflags)
117 | && (Flags::SignFlag.get_flag(eflags) == Flags::OverflowFlag.get_flag(eflags))
118 | {
119 | return self.j_true;
120 | }
121 |
122 | return self.j_false as isize;
123 | }
124 | }
125 |
126 | let flag = flag_to_check.0.get_flag(eflags);
127 |
128 | if flag == flag_to_check.1 {
129 | self.j_true
130 | } else {
131 | self.j_false as isize
132 | }
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/common/src/jump_data_table.rs:
--------------------------------------------------------------------------------
1 | use error::Error;
2 | use std::collections::HashMap;
3 | use std::fmt::Formatter;
4 | use std::{error, fmt};
5 |
6 | use block_modes::BlockMode;
7 | use serde::{Deserialize, Serialize};
8 |
9 | use crate::jump_data::JumpData;
10 | use crate::{Aes256Cbc, EncryptedJumpData};
11 |
12 | #[derive(Serialize, Deserialize, Debug)]
13 | pub struct JumpDataTable {
14 | pub table: HashMap,
15 | pub iv: [u8; 16],
16 | }
17 |
18 | #[derive(Debug)]
19 | pub struct JDTError;
20 |
21 | impl fmt::Display for JDTError {
22 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
23 | write!(f, "unknown err")
24 | }
25 | }
26 |
27 | impl Error for JDTError {}
28 |
29 | impl JumpDataTable {
30 | fn new() -> JumpDataTable {
31 | JumpDataTable {
32 | table: HashMap::new(),
33 | iv: [0; 16],
34 | }
35 | }
36 |
37 | pub fn get_jump_data(&self, addr: u64) -> Result> {
38 | // Look up the EncryptedJumpData from the hashmap.
39 | // Then, decrypt the data, deserialize it, and give it to the user.
40 | let enc_data = self.table.get(&addr).ok_or(JDTError)?;
41 |
42 | let aes = Aes256Cbc::new_var(enc_data.key.0.as_ref(), self.iv.as_ref()).unwrap();
43 | let data = aes.decrypt_vec(enc_data.data.as_ref())?;
44 |
45 | let jump_data: JumpData = bincode::deserialize(data.as_ref())?;
46 |
47 | Ok(jump_data)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/common/src/lib.rs:
--------------------------------------------------------------------------------
1 | use aesni::Aes256;
2 | use block_modes::block_padding::Pkcs7;
3 | use block_modes::Cbc;
4 | use num_derive::FromPrimitive;
5 | use serde::{Deserialize, Serialize};
6 |
7 | pub type Aes256Cbc = Cbc;
8 |
9 | pub mod flags;
10 | pub mod jump_data;
11 | pub mod jump_data_table;
12 |
13 | /// A 32 byte encryption key.
14 | #[derive(Serialize, Deserialize, Debug)]
15 | pub struct RekkEncKey(pub [u8; 32]);
16 |
17 | /// An encrypted jump data struct.
18 | #[derive(Serialize, Deserialize, Debug)]
19 | pub struct EncryptedJumpData {
20 | key: RekkEncKey,
21 | data: Vec,
22 | }
23 |
24 | /// The type of jump to be emulated.
25 | #[derive(Serialize, Deserialize, FromPrimitive, Debug)]
26 | pub enum JumpType {
27 | /// The instruction doesn't have a condition code
28 | None = 0,
29 |
30 | /// Overflow (`OF=1`)
31 | JumpOverflow = 1,
32 |
33 | /// Not overflow (`OF=0`)
34 | JumpNotOverflow = 2,
35 |
36 | /// Below (unsigned) (`CF=1`)
37 | JumpBelow = 3,
38 |
39 | /// Above or equal (unsigned) (`CF=0`)
40 | JumpAboveEqual = 4,
41 |
42 | /// Equal / zero (`ZF=1`)
43 | JumpEqual = 5,
44 |
45 | /// Not equal / zero (`ZF=0`)
46 | JumpNotEqual = 6,
47 |
48 | /// Below or equal (unsigned) (`CF=1 or ZF=1`)
49 | JumpBelowEqual = 7,
50 |
51 | /// Above (unsigned) (`CF=0 and ZF=0`)
52 | JumpAbove = 8,
53 |
54 | /// Signed (`SF=1`)
55 | JumpSigned = 9,
56 |
57 | /// Not signed (`SF=0`)
58 | JumpNotSigned = 10,
59 |
60 | /// Parity (`PF=1`)
61 | JumpParity = 11,
62 |
63 | /// Not parity (`PF=0`)
64 | JumpNotParity = 12,
65 |
66 | /// Less (signed) (`SF!=OF`)
67 | JumpLess = 13,
68 |
69 | /// Greater than or equal (signed) (`SF=OF`)
70 | JumpGreaterEqual = 14,
71 |
72 | /// Less than or equal (signed) (`ZF=1 or SF!=OF`)
73 | JumpLessEqual = 15,
74 |
75 | /// Greater (signed) (`ZF=0 and SF=OF`)
76 | JumpGreater = 16,
77 | }
78 |
--------------------------------------------------------------------------------
/infector/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/infector/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "infector"
3 | version = "0.1.0"
4 | authors = ["Justin Perez "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | iced-x86 = "1.10"
11 | goblin = "0.3"
12 | termcolor = "1.1"
13 | rand = "0.8"
14 | common = {path = "../common"}
15 | num-traits = "0.2"
16 | num-derive = "0.2"
17 | bincode = "1.3"
18 | snap="1.0"
19 |
20 | [profile.release]
21 | lto="fat"
--------------------------------------------------------------------------------
/infector/src/binary_parser.rs:
--------------------------------------------------------------------------------
1 | use std::collections::HashMap;
2 |
3 | use goblin::elf::program_header::PT_LOAD;
4 | use goblin::elf::Elf;
5 | use goblin::pe::section_table::IMAGE_SCN_MEM_EXECUTE;
6 | use goblin::pe::PE;
7 |
8 | use common::jump_data::JumpData;
9 |
10 | use crate::code_section::CodeSection;
11 | use crate::infestor::infest;
12 |
13 | const DEFAULT_SECTION_NAME: &str = "unknown section";
14 |
15 | pub(crate) fn handle_elf(data: &mut Vec, elf: Elf) -> Vec> {
16 | let mut jdts = Vec::new();
17 |
18 | let base_header = elf
19 | .program_headers
20 | .iter()
21 | .find(|x| x.is_executable() && x.p_type == PT_LOAD)
22 | .expect("Couldn't find ELF image base");
23 |
24 | println!("base 0x{:X}", base_header.p_vaddr);
25 |
26 | for header in elf.section_headers {
27 | if !header.is_executable() {
28 | continue;
29 | }
30 |
31 | let start = header.sh_offset;
32 | let end = start + header.sh_size;
33 |
34 | let mut section = CodeSection::new(
35 | start,
36 | header.sh_addr,
37 | base_header.p_vaddr,
38 | &mut data[start as usize..end as usize],
39 | elf.shdr_strtab.get(header.sh_name).unwrap().unwrap(),
40 | );
41 | jdts.push(infest(&mut section, if elf.is_64 { 64 } else { 32 }));
42 | }
43 |
44 | jdts
45 | }
46 |
47 | pub(crate) fn handle_pe(data: &mut Vec, pe: PE) -> Vec> {
48 | let mut jdts = Vec::new();
49 |
50 | for sec in pe.sections {
51 | if sec.characteristics & IMAGE_SCN_MEM_EXECUTE == 0 {
52 | continue;
53 | }
54 |
55 | let start = sec.pointer_to_raw_data as usize;
56 | let end = start + sec.size_of_raw_data as usize;
57 | let default_sec_name = DEFAULT_SECTION_NAME.to_string();
58 | let sec_name = sec.real_name.unwrap_or(default_sec_name);
59 |
60 | let mut section = CodeSection::new(
61 | start as u64,
62 | sec.virtual_address as u64 + pe.image_base as u64,
63 | pe.image_base as u64,
64 | &mut data[start..end],
65 | sec_name.as_str(),
66 | );
67 |
68 | jdts.push(infest(&mut section, if pe.is_64 { 64 } else { 32 }));
69 | }
70 |
71 | jdts
72 | }
73 |
--------------------------------------------------------------------------------
/infector/src/code_section.rs:
--------------------------------------------------------------------------------
1 | pub(crate) struct CodeSection<'a, 'b> {
2 | file_offset: u64,
3 | vaddr: u64,
4 | base: u64,
5 | data: &'a mut [u8],
6 | name: &'b str,
7 | }
8 |
9 | impl<'a, 'b> CodeSection<'a, 'b> {
10 | pub fn file_offset(&self) -> u64 {
11 | self.file_offset
12 | }
13 | pub fn vaddr(&self) -> u64 {
14 | self.vaddr
15 | }
16 | pub fn base(&self) -> u64 {
17 | self.base
18 | }
19 | pub fn data_ref(&self) -> &[u8] {
20 | self.data
21 | }
22 | pub fn write_data(&mut self, data: &[u8]) {
23 | self.data.copy_from_slice(data);
24 | }
25 | pub fn name(&self) -> &'b str {
26 | self.name
27 | }
28 | }
29 |
30 | impl<'a, 'b> CodeSection<'a, 'b> {
31 | pub fn new(file_offset: u64, vaddr: u64, base: u64, data: &'a mut [u8], name: &'b str) -> Self {
32 | CodeSection {
33 | file_offset,
34 | vaddr,
35 | base,
36 | data,
37 | name,
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/infector/src/infestor.rs:
--------------------------------------------------------------------------------
1 | use std::collections::HashMap;
2 |
3 | use iced_x86::{Decoder, DecoderOptions, FlowControl, Formatter, Instruction, NasmFormatter};
4 | use num_traits::FromPrimitive;
5 | use rand::Rng;
6 | use termcolor::Color;
7 |
8 | use common::jump_data::JumpData;
9 | use common::JumpType;
10 |
11 | use crate::code_section::CodeSection;
12 | use crate::print_utils::print_color;
13 |
14 | const HEXBYTES_COLUMN_BYTE_LENGTH: usize = 10;
15 |
16 | pub(crate) fn infest(section: &mut CodeSection, bitness: u32) -> HashMap {
17 | let result = create_nanomites(section, bitness);
18 |
19 | section.write_data(result.0.as_ref());
20 | result.1
21 | }
22 |
23 | fn create_nanomites(section: &CodeSection, bitness: u32) -> (Vec, HashMap) {
24 | print_color(
25 | &*format!("\n[[ disassembling {} ]]\n\n", section.name()),
26 | Color::Blue,
27 | );
28 |
29 | let mut decoder = Decoder::new(bitness, section.data_ref(), DecoderOptions::NONE);
30 | let mut instruction = Instruction::default();
31 | let mut instructions = Vec::new();
32 | let mut formatter = NasmFormatter::new();
33 | let mut rng = rand::thread_rng();
34 |
35 | // Change some options, there are many more
36 | formatter.options_mut().set_digit_separator("`");
37 | formatter.options_mut().set_first_operand_char_index(10);
38 | formatter.options_mut().set_branch_leading_zeroes(false);
39 | formatter.options_mut().set_hex_prefix("0x");
40 |
41 | let mut output = String::new();
42 | let mut jump_entry;
43 | let mut jump_entries = HashMap::new();
44 |
45 | decoder.set_ip(section.vaddr());
46 | while decoder.can_decode() {
47 | // decode the instruction.
48 | decoder.decode_out(&mut instruction);
49 |
50 | print!("{:016X} ", instruction.ip());
51 |
52 | // get the bytes that make up the instruction
53 | let start_index = (instruction.ip() - section.vaddr()) as usize;
54 | let instr_bytes = §ion.data_ref()[start_index..start_index + instruction.len()];
55 |
56 | // does the instruction contain an 0xCC (int 3)?
57 | let mut contains_cc = false;
58 |
59 | // print each hex byte in the instruction.
60 | for b in instr_bytes.iter() {
61 | print!("{:02X} ", b);
62 |
63 | if b.eq(&0xCC_u8) {
64 | contains_cc = true;
65 | }
66 | }
67 |
68 | // Print padding
69 | if instr_bytes.len() < HEXBYTES_COLUMN_BYTE_LENGTH {
70 | for _ in 0..HEXBYTES_COLUMN_BYTE_LENGTH - instr_bytes.len() {
71 | print!(" ");
72 | }
73 | }
74 |
75 | // format the instruction & print to the console.
76 | output.clear();
77 | formatter.format(&instruction, &mut output);
78 | print!(" {}", output);
79 |
80 | // reset the jump entry that might be added to the jdt
81 | jump_entry = None;
82 |
83 | if contains_cc {
84 | print_color(" << FAKE NANOMITE >> ", Color::Red);
85 |
86 | // todo this should be random.
87 | jump_entry = Some(JumpData::new(JumpType::JumpParity, 100, 1000));
88 | }
89 |
90 | // was this instruction patched to an 0xCC?
91 | let mut patched = true;
92 |
93 | match instruction.flow_control() {
94 | FlowControl::ConditionalBranch => {
95 | // Found a (un)conditional branch. Replace the code with INT 3, and replace the extra
96 | // bytes with random bytes. The random bytes are needed, as we don't want to fixup jump locations.
97 | print_color(" <=========== [[ NANOMITE ]]", Color::Green);
98 | jump_entry = Some(instr_to_jump_entry(instruction));
99 |
100 | // Push the int 3 opcode.
101 | instructions.push(0xCC_u8);
102 |
103 | // Add junk bytes.
104 | for (i, _) in instr_bytes.iter().enumerate() {
105 | if i == 0 {
106 | continue;
107 | }
108 |
109 | let rnd_byte: u8 = rng.gen();
110 | instructions.push(rnd_byte);
111 | }
112 | }
113 | _ => patched = false,
114 | }
115 |
116 | println!();
117 |
118 | // The instruction was not patched, and needs to be added to the code buffer.
119 | if !patched {
120 | instructions.extend_from_slice(instr_bytes);
121 | }
122 |
123 | // If there was a jcc, then add the jump entry to the jdt
124 | if let Some(entry) = jump_entry {
125 | println!("key {:X}", instruction.ip() - section.base());
126 | jump_entries.insert(instruction.ip() - section.base(), entry);
127 | }
128 | }
129 |
130 | print_color(" [[ placing nanomites ]]\n", Color::Cyan);
131 |
132 | println!(
133 | "section size: {}\nnanomite'd size: {}\njdt size: {}",
134 | section.data_ref().len(),
135 | instructions.len(),
136 | jump_entries.len()
137 | );
138 |
139 | (instructions, jump_entries)
140 | }
141 |
142 | fn instr_to_jump_entry(instr: Instruction) -> JumpData {
143 | let cc = instr.condition_code() as u8;
144 | let jump_type: Option = FromPrimitive::from_u8(cc);
145 |
146 | let j_true = instr.near_branch_target() as i64 - instr.ip() as i64;
147 | let j_false = instr.len();
148 | assert_ne!(j_true, 0);
149 |
150 | JumpData::new(jump_type.unwrap(), j_true as isize, j_false)
151 | }
152 |
--------------------------------------------------------------------------------
/infector/src/jump_data_exporter.rs:
--------------------------------------------------------------------------------
1 | use std::collections::HashMap;
2 |
3 | use rand::{thread_rng, Rng};
4 |
5 | use common::jump_data::JumpData;
6 | use common::jump_data_table::JumpDataTable;
7 | use common::RekkEncKey;
8 |
9 | pub fn export_jdt(table: Vec>) -> Vec {
10 | let mut master_jdt = HashMap::new();
11 |
12 | // merge all the jdts into one "master" jdt
13 | for jdt in table {
14 | for (key, value) in jdt.into_iter() {
15 | // If we insert a duplicate, the old value is returned. Assert that there are no
16 | // duplicates, or we'll have a bad time.
17 | assert!(master_jdt.insert(key, value).is_none());
18 | }
19 | }
20 |
21 | // Convert the JumpData to EncryptedJumpData
22 | let mut encrypted_jdt = HashMap::new();
23 | let mut rng = thread_rng();
24 |
25 | let iv = rng.gen::<[u8; 16]>();
26 |
27 | for (key, value) in master_jdt.into_iter() {
28 | let enc_key = rng.gen::<[u8; 32]>();
29 | encrypted_jdt.insert(key, value.encrypt(RekkEncKey(enc_key), &iv));
30 | }
31 |
32 | let jdt = JumpDataTable {
33 | table: encrypted_jdt,
34 | iv,
35 | };
36 |
37 | let serialized_jdt = bincode::serialize(&jdt).unwrap();
38 | let mut encoder = snap::raw::Encoder::new();
39 |
40 | encoder.compress_vec(&serialized_jdt).unwrap()
41 | }
42 |
--------------------------------------------------------------------------------
/infector/src/main.rs:
--------------------------------------------------------------------------------
1 | use core::fmt;
2 | use std::env;
3 | use std::error::Error;
4 | use std::fs;
5 | use std::path::Path;
6 |
7 | use goblin::Object;
8 |
9 | use crate::binary_parser::*;
10 | use crate::jump_data_exporter::export_jdt;
11 |
12 | mod binary_parser;
13 | mod code_section;
14 | mod infestor;
15 | mod jump_data_exporter;
16 | mod print_utils;
17 |
18 | #[derive(Debug, Clone)]
19 | struct InvalidFileError;
20 |
21 | impl fmt::Display for InvalidFileError {
22 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 | write!(f, "supplied file was not a PE/ELF file.")
24 | }
25 | }
26 |
27 | impl Error for InvalidFileError {}
28 |
29 | fn run() -> Result<(), Box> {
30 | for (i, arg) in env::args().enumerate() {
31 | if i == 1 {
32 | let path = Path::new(arg.as_str());
33 | let data = fs::read(path)?;
34 |
35 | let object = { Object::parse(&data) };
36 |
37 | let mut data = data.to_vec();
38 | let jdts;
39 |
40 | if let Ok(Object::PE(pe)) = object {
41 | jdts = Some(handle_pe(&mut data, pe));
42 | } else if let Ok(Object::Elf(elf)) = object {
43 | jdts = Some(handle_elf(&mut data, elf));
44 | } else {
45 | return Err(InvalidFileError.into());
46 | }
47 |
48 | // compress the binary.
49 | let mut encoder = snap::raw::Encoder::new();
50 | let compressed_binary = encoder.compress_vec(&data)?;
51 |
52 | fs::write(Path::new("jdt.bin"), export_jdt(jdts.unwrap()))?;
53 | fs::write(Path::new("nanomite.bin"), compressed_binary)?;
54 | }
55 | }
56 | Ok(())
57 | }
58 |
59 | fn main() {
60 | if let Err(e) = run() {
61 | println!("error: {}", e);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/infector/src/print_utils.rs:
--------------------------------------------------------------------------------
1 | use std::io::Write;
2 |
3 | use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
4 |
5 | pub(crate) fn print_color(text: &str, color: Color) {
6 | let mut stdout = StandardStream::stdout(ColorChoice::Always);
7 | stdout
8 | .set_color(ColorSpec::new().set_fg(Some(color)))
9 | .expect("error setting term color");
10 | write!(&mut stdout, "{}", text).expect("error writing to console");
11 | stdout.reset().expect("error setting term color");
12 | }
13 |
--------------------------------------------------------------------------------
/runtime/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/runtime/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "runtime"
3 | version = "0.1.0"
4 | authors = ["Justin Perez "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | aesni = "0.10"
11 | bincode = "1.3"
12 | block-modes = "0.7"
13 | snap = "1.0"
14 | common = { path = "../common" }
15 |
16 |
17 | [target.'cfg(target_os = "linux")'.dependencies]
18 | nix = "0.20"
19 | procfs = "0.9"
20 |
21 |
22 | [target.'cfg(target_os = "windows")'.dependencies]
23 | winapi = { version = "0.3", features = ["handleapi", "processthreadsapi", "memoryapi", "synchapi", "debugapi"] }
24 | ntapi = "0.3"
25 |
26 | # optimize release for small builds.
27 | [profile.release]
28 | opt-level = "s"
29 | lto = "fat"
30 | panic = 'abort'
31 |
--------------------------------------------------------------------------------
/runtime/src/linux_runtime.rs:
--------------------------------------------------------------------------------
1 | use common::jump_data_table::JumpDataTable;
2 | use nix::sys::memfd::{memfd_create, MemFdCreateFlag};
3 | use nix::sys::ptrace;
4 | use nix::sys::signal::Signal;
5 | use nix::sys::wait::{waitpid, WaitStatus};
6 | use nix::unistd;
7 | use nix::unistd::{fexecve, fork, ForkResult, Pid};
8 | use procfs::process::Process;
9 | use std::ffi::CString;
10 | use std::sync::atomic::{AtomicU64, Ordering};
11 | use std::{env, error};
12 |
13 | pub fn run() {
14 | match unsafe { fork() } {
15 | Ok(ForkResult::Parent { child }) => parent(child).unwrap(),
16 | Ok(ForkResult::Child) => run_binary().unwrap(),
17 | Err(_) => panic!("unknown err"),
18 | }
19 | }
20 |
21 | fn run_binary() -> Result<(), Box> {
22 | let binary = include_bytes!("../../nanomite.bin");
23 |
24 | // create the memory file descriptor
25 | let fd_name = CString::new("child")?;
26 | let fd = memfd_create(&fd_name, MemFdCreateFlag::MFD_CLOEXEC)?;
27 |
28 | // decompress the binary.
29 | let mut decoder = snap::raw::Decoder::new();
30 | let d_bin = decoder.decompress_vec(binary)?;
31 |
32 | unistd::write(fd, d_bin.as_slice())?;
33 |
34 | ptrace::traceme()?;
35 |
36 | let args: Vec = env::args().map(|s| CString::new(s).unwrap()).collect();
37 | let env: Vec = env::vars()
38 | .map(|s| CString::new(format!("{}={}", s.0, s.1)).unwrap())
39 | .collect();
40 |
41 | fexecve(fd, args.as_slice(), env.as_slice())?;
42 |
43 | Ok(())
44 | }
45 |
46 | fn parent(child_pid: Pid) -> Result<(), Box> {
47 | let jdt = include_bytes!("../../jdt.bin");
48 |
49 | let mut first_stop = true;
50 |
51 | loop {
52 | let status = waitpid(child_pid, None).unwrap();
53 |
54 | match status {
55 | WaitStatus::Exited(_, _) => {
56 | break;
57 | }
58 | WaitStatus::Signaled(_, _, _) => {}
59 | WaitStatus::Stopped(pid, signal) => {
60 | if first_stop && signal == Signal::SIGTRAP {
61 | first_stop = false;
62 | ptrace::cont(pid, None)?;
63 | continue;
64 | }
65 |
66 | if signal == Signal::SIGTRAP {
67 | handle_int3(jdt, pid)?;
68 | }
69 |
70 | if signal == Signal::SIGILL {
71 | let regs = ptrace::getregs(pid).unwrap();
72 | println!("SIGILL 0x{:X}", regs.rip);
73 | break;
74 | }
75 |
76 | if signal == Signal::SIGSEGV {
77 | let regs = ptrace::getregs(pid).unwrap();
78 | println!("SIGSEGV 0x{:X}", regs.rip);
79 | break;
80 | }
81 |
82 | if signal == Signal::SIGCHLD {}
83 | }
84 | WaitStatus::PtraceEvent(_, _, _) => {}
85 | WaitStatus::PtraceSyscall(_) => {}
86 | WaitStatus::Continued(_) => {}
87 | WaitStatus::StillAlive => {}
88 | }
89 | }
90 |
91 | Ok(())
92 | }
93 |
94 | static VADDR: AtomicU64 = AtomicU64::new(0);
95 |
96 | fn handle_int3(comp_enc_jdt: &[u8], pid: Pid) -> Result<(), Box> {
97 | // decompress JDT.
98 | let mut decoder = snap::raw::Decoder::new();
99 | let raw_jdt = decoder.decompress_vec(comp_enc_jdt)?;
100 |
101 | let mut vaddr = VADDR.load(Ordering::Relaxed);
102 |
103 | if vaddr == 0 {
104 | let proc = Process::new(pid.as_raw())?;
105 | let proc_maps = proc.maps()?;
106 |
107 | let map = proc_maps.iter().find(|x| x.perms.contains('x')).unwrap();
108 |
109 | VADDR.store(map.address.0, Ordering::Relaxed);
110 | vaddr = map.address.0;
111 | }
112 |
113 | let jdt: JumpDataTable = bincode::deserialize(raw_jdt.as_slice()).unwrap();
114 |
115 | // get the ip
116 |
117 | let regs = ptrace::getregs(pid);
118 |
119 | if regs.is_err() {
120 | return Ok(());
121 | }
122 |
123 | let mut regs = regs?;
124 | let jump_data = jdt.get_jump_data(regs.rip - vaddr - 1);
125 |
126 | if jump_data.is_err() {
127 | ptrace::cont(pid, None)?;
128 | return Ok(());
129 | }
130 |
131 | let jump_data = jump_data.unwrap();
132 | let ip_offset = jump_data.get_ip_offset(regs.eflags);
133 | regs.rip = (regs.rip as i64 + ip_offset as i64 - 1) as u64;
134 |
135 | ptrace::setregs(pid, regs)?;
136 | ptrace::cont(pid, None)?;
137 |
138 | Ok(())
139 | }
140 |
--------------------------------------------------------------------------------
/runtime/src/main.rs:
--------------------------------------------------------------------------------
1 | #[cfg(target_os = "linux")]
2 | mod linux_runtime;
3 |
4 | #[cfg(target_os = "linux")]
5 | use crate::linux_runtime::run;
6 |
7 | #[cfg(target_os = "windows")]
8 | mod windows_runtime;
9 |
10 | #[cfg(target_os = "windows")]
11 | use crate::windows_runtime::run;
12 |
13 | fn main() {
14 | run();
15 | }
16 |
--------------------------------------------------------------------------------
/runtime/src/windows_runtime.rs:
--------------------------------------------------------------------------------
1 | use std::ffi::CString;
2 | use std::ptr::null_mut;
3 | use std::{error, mem};
4 |
5 | use ntapi::ntpebteb::PEB;
6 | use ntapi::ntpsapi::{
7 | NtQueryInformationProcess, ProcessBasicInformation, PROCESS_BASIC_INFORMATION,
8 | };
9 | use snap::raw::Decoder;
10 | use winapi::_core::ffi::c_void;
11 | use winapi::shared::minwindef::{DWORD, MAX_PATH, TRUE};
12 | use winapi::shared::ntdef::HANDLE;
13 | use winapi::shared::winerror::SUCCEEDED;
14 | use winapi::um::debugapi::{ContinueDebugEvent, WaitForDebugEvent};
15 | use winapi::um::fileapi::{
16 | CreateFileA, DeleteFileA, GetTempFileNameA, GetTempPathA, WriteFile, CREATE_ALWAYS,
17 | };
18 | use winapi::um::handleapi::CloseHandle;
19 | use winapi::um::memoryapi::ReadProcessMemory;
20 | use winapi::um::minwinbase::DEBUG_EVENT;
21 | use winapi::um::processenv::GetCommandLineA;
22 | use winapi::um::processthreadsapi::{
23 | CreateProcessA, GetThreadContext, OpenThread, ResumeThread, SetThreadContext, SuspendThread,
24 | PROCESS_INFORMATION, STARTUPINFOA,
25 | };
26 | use winapi::um::synchapi::WaitForSingleObject;
27 | use winapi::um::winbase::{DEBUG_PROCESS, INFINITE};
28 | use winapi::um::winnt::{
29 | CONTEXT, CONTEXT_CONTROL, DBG_CONTINUE, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
30 | FILE_SHARE_WRITE, GENERIC_WRITE, THREAD_ALL_ACCESS,
31 | };
32 |
33 | use common::jump_data_table::JumpDataTable;
34 |
35 | pub fn run() {
36 | unsafe {
37 | //run_binary();
38 | let result = run_binary().unwrap();
39 | run_handler(result.0, result.1);
40 | }
41 | }
42 |
43 | unsafe fn run_handler(proc_info: PROCESS_INFORMATION, proc_name: String) {
44 | let mut debug_event = mem::zeroed::();
45 |
46 | // Calculate the address the image was loaded into.
47 | let base_addr = read_remote_peb(proc_info.hProcess).ImageBaseAddress as u64;
48 |
49 | // Unpack the JDT
50 | let mut decoder = Decoder::new();
51 | let unpacked = decoder
52 | .decompress_vec(include_bytes!("../../jdt.bin"))
53 | .unwrap();
54 | let jdt: JumpDataTable = bincode::deserialize(unpacked.as_slice()).unwrap();
55 |
56 | loop {
57 | WaitForDebugEvent(&mut debug_event, INFINITE);
58 |
59 | match debug_event.dwDebugEventCode {
60 | // Received an exception.
61 | 1 => handle_int3(debug_event.dwThreadId, base_addr, &jdt),
62 | // The process has exited.
63 | 5 => {
64 | break;
65 | }
66 | // Something no bueno happened.
67 | 0 => {
68 | panic!();
69 | }
70 | _ => {}
71 | }
72 |
73 | ContinueDebugEvent(
74 | debug_event.dwProcessId,
75 | debug_event.dwThreadId,
76 | DBG_CONTINUE,
77 | );
78 | }
79 |
80 | // Let the process terminate.
81 | ContinueDebugEvent(
82 | debug_event.dwProcessId,
83 | debug_event.dwThreadId,
84 | DBG_CONTINUE,
85 | );
86 |
87 | // Wait for the process to terminate.
88 | WaitForSingleObject(proc_info.hProcess, INFINITE);
89 |
90 | // Free handles
91 | CloseHandle(proc_info.hProcess);
92 | CloseHandle(proc_info.hThread);
93 |
94 | // Delete the dropped file.
95 | DeleteFileA(proc_name.as_ptr() as *const _);
96 | }
97 |
98 | unsafe fn read_remote_peb(proc_handle: HANDLE) -> PEB {
99 | let mut pbi = mem::zeroed::();
100 | let mut written = 0;
101 |
102 | // Get the ProcessBasicInformation to locate the address of the PEB.
103 | NtQueryInformationProcess(
104 | proc_handle,
105 | ProcessBasicInformation,
106 | &mut pbi as *mut _ as _,
107 | mem::size_of::() as u32,
108 | &mut written as *mut _ as _,
109 | );
110 |
111 | let mut peb = mem::zeroed::();
112 | let mut written = 0;
113 |
114 | // Read the PEB.
115 | ReadProcessMemory(
116 | proc_handle,
117 | pbi.PebBaseAddress as *const _,
118 | &mut peb as *mut _ as _,
119 | mem::size_of::(),
120 | &mut written as *mut _ as _,
121 | );
122 |
123 | peb
124 | }
125 |
126 | unsafe fn handle_int3(thread_id: DWORD, base_addr: u64, jdt: &JumpDataTable) {
127 | // Open a handle to the thread.
128 | let handle = OpenThread(THREAD_ALL_ACCESS, TRUE, thread_id);
129 |
130 | if !SUCCEEDED(handle as i32) {
131 | panic!();
132 | }
133 |
134 | // GetThreadContext requires the thread is suspended. It should already be suspended, this is for redundancy.
135 | SuspendThread(handle);
136 |
137 | let mut context = mem::zeroed::();
138 | context.ContextFlags = CONTEXT_CONTROL; // We only need RIP and EFLAGS.
139 |
140 | // Get the thread context.
141 | let ret = GetThreadContext(handle, &mut context);
142 |
143 | // LdrpInitializeProcess will trigger a breakpoint if the process is being debugged when it is
144 | // created. This function will handle that breakpoint, but GetThreadContext only allows us to
145 | // get the context of threads we own. Thus, if GetThreadContext fails we should just move on.
146 | if ret == 0 {
147 | ResumeThread(handle);
148 | CloseHandle(handle);
149 | return;
150 | }
151 |
152 | let jump_data = jdt.get_jump_data(context.Rip - 1 - base_addr);
153 |
154 | // If there was an error getting the jump data, jump to the next instruction and hope for the
155 | // best.
156 | if jump_data.is_err() {
157 | context.Rip += 1;
158 | SetThreadContext(handle, &context);
159 | ResumeThread(handle);
160 | CloseHandle(handle);
161 | return;
162 | }
163 |
164 | let jump_data = jump_data.unwrap();
165 |
166 | // Add the signed offset to RIP.
167 | let offset = jump_data.get_ip_offset(context.EFlags as u64);
168 | context.Rip = (context.Rip as i64 + offset as i64 - 1) as u64;
169 |
170 | // Update RIP, resume the thread, and get rid of our handle.
171 | SetThreadContext(handle, &context);
172 | ResumeThread(handle);
173 | CloseHandle(handle);
174 | }
175 |
176 | unsafe fn run_binary() -> Result<(PROCESS_INFORMATION, String), Box> {
177 | let binary = include_bytes!("../../nanomite.bin");
178 |
179 | // decompress the binary.
180 | let mut decoder = Decoder::new();
181 | let d_bin = decoder.decompress_vec(binary)?;
182 |
183 | // Get the path to %temp%.
184 | let mut buf: [u8; MAX_PATH] = [0; MAX_PATH];
185 | GetTempPathA(MAX_PATH as u32, buf.as_mut_ptr() as *mut _);
186 |
187 | let prefix = CString::new("").unwrap();
188 |
189 | // Get a random file name in that directory.
190 | let mut temp_file_name_buf: [u8; MAX_PATH] = [0; MAX_PATH];
191 | GetTempFileNameA(
192 | buf.as_mut_ptr() as *mut _,
193 | prefix.as_ptr(),
194 | 0,
195 | temp_file_name_buf.as_mut_ptr() as *mut _,
196 | );
197 |
198 | // Create a file with the generated name to write to.
199 | let h_file = CreateFileA(
200 | temp_file_name_buf.as_ptr() as *mut _,
201 | GENERIC_WRITE,
202 | FILE_SHARE_READ | FILE_SHARE_WRITE,
203 | null_mut(),
204 | CREATE_ALWAYS,
205 | FILE_ATTRIBUTE_NORMAL,
206 | null_mut(),
207 | );
208 |
209 | // Write the nanomite'd binary to the new file.
210 | let mut written = 0;
211 | WriteFile(
212 | h_file,
213 | d_bin.as_ptr() as *const c_void,
214 | d_bin.len() as u32,
215 | &mut written,
216 | null_mut(),
217 | );
218 |
219 | // Flush the changes.
220 | CloseHandle(h_file);
221 |
222 | // Create the new process, and debug it.
223 | let mut startup_info = mem::zeroed::();
224 | let mut process_info = mem::zeroed::();
225 |
226 | CreateProcessA(
227 | temp_file_name_buf.as_ptr() as *const _,
228 | GetCommandLineA(),
229 | null_mut(),
230 | null_mut(),
231 | TRUE,
232 | DEBUG_PROCESS,
233 | null_mut(),
234 | null_mut(),
235 | &mut startup_info,
236 | &mut process_info,
237 | );
238 |
239 | Ok((
240 | process_info,
241 | std::str::from_utf8(&temp_file_name_buf)
242 | .unwrap()
243 | .to_string(),
244 | ))
245 | }
246 |
--------------------------------------------------------------------------------
/test/test.c:
--------------------------------------------------------------------------------
1 | //
2 | // Created by justin on 1/29/21.
3 | //
4 |
5 | #include
6 | #include
7 |
8 | int compare(int a, int b) {
9 | if (a == b) {
10 | return 0;
11 | }
12 |
13 | if (a > b) {
14 | return 1;
15 | } else {
16 | return -1;
17 | }
18 | }
19 |
20 | int main(int argc, char **argv) {
21 | if (argc < 3) {
22 | printf("no args given\n");
23 | return 1;
24 | }
25 |
26 | char *num = argv[1];
27 | char *num2 = argv[2];
28 |
29 | int a = atoi(num);
30 | int b = atoi(num2);
31 |
32 | printf("cmp: %d\n", compare(a, b));
33 | printf("cmp to 0xCC: %d\n", compare(a, 0xCC));
34 | return 0;
35 | }
36 |
37 |
--------------------------------------------------------------------------------