Rizin
unix-like reverse engineering framework and cli tools
egg_xor.c File Reference
#include <rz_egg.h>

Go to the source code of this file.

Macros

#define DEFAULT_XOR_KEY   "0xFF"
 
#define STUBLEN   18
 

Functions

static RzBufferbuild (RzEgg *egg)
 

Variables

RzEggPlugin rz_egg_plugin_xor
 

Macro Definition Documentation

◆ DEFAULT_XOR_KEY

#define DEFAULT_XOR_KEY   "0xFF"

Definition at line 7 of file egg_xor.c.

◆ STUBLEN

#define STUBLEN   18

Function Documentation

◆ build()

static RzBuffer* build ( RzEgg egg)
static

Definition at line 9 of file egg_xor.c.

9  {
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 }
lzma_index ** i
Definition: index.h:629
#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
#define DEFAULT_XOR_KEY
Definition: egg_xor.c:7
#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
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
@ RZ_SYS_ARCH_X86
Definition: rz_types.h:532
RzBuffer * bin
Definition: rz_egg.h:96
int arch
Definition: rz_egg.h:106

References rz_egg_t::arch, rz_egg_t::bin, DEFAULT_XOR_KEY, eprintf, free(), i, key, NULL, rz_buf_append_buf(), rz_buf_append_bytes(), rz_buf_free(), rz_buf_new_with_bytes(), rz_buf_read8_at(), rz_buf_set_bytes(), rz_buf_size(), rz_buf_write_at(), rz_egg_option_get(), rz_num_math(), RZ_SYS_ARCH_X86, sc, strdup(), STUBLEN, autogen_x86imm::tmp, and v.

Variable Documentation

◆ rz_egg_plugin_xor

RzEggPlugin rz_egg_plugin_xor
Initial value:
= {
.name = "xor",
.desc = "xor encoder for shellcode",
.build = (void *)build
}
static RzBuffer * build(RzEgg *egg)
Definition: egg_xor.c:9
#define RZ_EGG_PLUGIN_ENCODER
Definition: rz_egg.h:20

Definition at line 104 of file egg_xor.c.