Rizin
unix-like reverse engineering framework and cli tools
egg_xor.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2011-2016 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 /* based on @santitox patch */
5 #include <rz_egg.h>
6 
7 #define DEFAULT_XOR_KEY "0xFF"
8 
9 static RzBuffer *build(RzEgg *egg) {
10  RzBuffer *buf, *sc;
11  ut8 aux[32], nkey;
12  const char *default_key = DEFAULT_XOR_KEY;
13  char *key = rz_egg_option_get(egg, "key");
14 
15  if (!key || !*key) {
16  free(key);
17  key = strdup(default_key);
18  eprintf("XOR key not provided. Using (%s) as the key\n", key);
19  }
20  nkey = rz_num_math(NULL, key);
21  if (nkey == 0) {
22  eprintf("Invalid key (%s)\n", key);
23  free(key);
24  return false;
25  }
26  if (nkey != (nkey & 0xff)) {
27  nkey &= 0xff;
28  eprintf("xor key wrapped to (%d)\n", nkey);
29  }
30  if (rz_buf_size(egg->bin) > 240) { // XXX
31  eprintf("shellcode is too long :(\n");
32  free(key);
33  return NULL;
34  }
35  sc = egg->bin; // hack
36  if (!rz_buf_size(sc)) {
37  eprintf("No shellcode found!\n");
38  free(key);
39  return NULL;
40  }
41 
42  for (size_t i = 0; i < rz_buf_size(sc); i++) {
43  // eprintf ("%02x -> %02x\n", sc->buf[i], sc->buf[i] ^nkey);
44  ut8 tmp;
45  if (!rz_buf_read8_at(sc, i, &tmp)) {
46  free(key);
47  return NULL;
48  }
49 
50  if ((tmp ^ nkey) == 0) {
51  eprintf("This xor key generates null bytes. Try again.\n");
52  free(key);
53  return NULL;
54  }
55  }
56 
59 
60  // TODO: alphanumeric? :D
61  // This is the x86-32/64 xor encoder
62  rz_buf_append_buf(sc, egg->bin);
63  if (egg->arch == RZ_SYS_ARCH_X86) {
64 #define STUBLEN 18
65  ut8 stub[STUBLEN] =
66  "\xe8\xff\xff\xff\xff" // call $$+4
67  "\xc1" // ffc1 = inc ecx
68  "\x5e" // pop esi
69  "\x48\x83\xc6\x0d" // add rsi, xx ... 64bit
70  // loop0:
71  "\x30\x1e" // xor [esi], bl
72  "\x48\xff\xc6" // inc rsi
73  "\xe2\xf9"; // loop loop0
74  // ecx = length
75  aux[0] = 0x6a; // push length
76  aux[1] = rz_buf_size(sc);
77  aux[2] = 0x59; // pop ecx
78  // ebx = key
79  aux[3] = 0x6a; // push key
80  aux[4] = nkey;
81  aux[5] = 0x5b; // pop ebx
82  rz_buf_set_bytes(buf, aux, 6);
83 
85 
86  for (size_t i = 0; i < rz_buf_size(sc); i++) {
87  ut8 v;
88  if (!rz_buf_read8_at(sc, i, &v)) {
89  free(key);
90  return NULL;
91  }
92 
93  v ^= nkey;
94  rz_buf_write_at(sc, i, &v, sizeof(v));
95  }
97  }
98  rz_buf_free(sc);
99  free(key);
100  return buf;
101 }
102 
103 // TODO: rename plugin to run
105  .name = "xor",
106  .type = RZ_EGG_PLUGIN_ENCODER,
107  .desc = "xor encoder for shellcode",
108  .build = (void *)build
109 };
110 
111 #if 0
112 #ifndef RZ_PLUGIN_INCORE
115  .data = &rz_egg_plugin_xor,
116  .version = RZ_VERSION
117 };
118 #endif
119 #endif
RZ_API RzLibStruct rizin_plugin
lzma_index ** i
Definition: index.h:629
#define RZ_API
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
const char * v
Definition: dsignal.c:12
RZ_API char * rz_egg_option_get(RzEgg *egg, const char *key)
Definition: egg.c:534
static char sc[]
Definition: egg_cb.c:6
RzEggPlugin rz_egg_plugin_xor
Definition: egg_xor.c:104
#define DEFAULT_XOR_KEY
Definition: egg_xor.c:7
static RzBuffer * build(RzEgg *egg)
Definition: egg_xor.c:9
#define STUBLEN
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API bool rz_buf_append_bytes(RZ_NONNULL RzBuffer *b, RZ_NONNULL const ut8 *buf, ut64 len)
Append an array of bytes to the buffer.
Definition: buf.c:732
RZ_API st64 rz_buf_write_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL const ut8 *buf, ut64 len)
Write len bytes of the buffer at the specified address.
Definition: buf.c:1197
RZ_API bool rz_buf_read8_at(RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *result)
Read a byte at the specified address in the buffer.
Definition: buf.c:876
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
RZ_API bool rz_buf_append_buf(RZ_NONNULL RzBuffer *b, RZ_NONNULL RzBuffer *a)
Append the content of the buffer a to the buffer b.
Definition: buf.c:685
RZ_API bool rz_buf_set_bytes(RZ_NONNULL RzBuffer *b, RZ_NONNULL const ut8 *buf, ut64 len)
Replace the content of the buffer with the bytes array.
Definition: buf.c:905
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_bytes(RZ_NULLABLE RZ_BORROW const ut8 *bytes, ut64 len)
Creates a new buffer with a bytes array.
Definition: buf.c:465
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
#define RZ_EGG_PLUGIN_ENCODER
Definition: rz_egg.h:20
@ RZ_LIB_TYPE_EGG
Definition: rz_lib.h:84
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
@ RZ_SYS_ARCH_X86
Definition: rz_types.h:532
#define RZ_VERSION
Definition: rz_version.h:8
const char * name
Definition: rz_egg.h:23
RzBuffer * bin
Definition: rz_egg.h:96
int arch
Definition: rz_egg.h:106