@@ -9,21 +9,47 @@ module Alpha2
9
9
class AlphaUpper < Generic
10
10
def self . default_accepted_chars ; ( 'B' .. 'Z' ) . to_a + ( '0' .. '9' ) . to_a ; end
11
11
12
- def self . gen_decoder_prefix ( reg , offset )
13
- if ( offset > 20 )
14
- raise "Critical: Offset is greater than 20"
12
+ # Generates the decoder stub prefix
13
+ #
14
+ # @param [String] reg the register pointing to the encoded payload
15
+ # @param [Fixnum] offset the offset to reach the encoded payload
16
+ # @param [Array] modified_registers accounts the registers modified by the stub
17
+ # @return [String] the alpha upper decoder stub prefix
18
+ def self . gen_decoder_prefix ( reg , offset , modified_registers = [ ] )
19
+ if offset > 20
20
+ raise 'Critical: Offset is greater than 20'
15
21
end
16
22
23
+ mod_registers = [ ]
24
+ nop_regs = [ ]
25
+ mod_regs = [ ]
26
+ edx_regs = [ ]
27
+
17
28
# use inc ebx as a nop here so we still pad correctly
18
29
if ( offset <= 10 )
19
30
nop = 'C' * offset
31
+ nop_regs . push ( Rex ::Arch ::X86 ::EBX ) unless nop . empty?
32
+
20
33
mod = 'I' * ( 10 - offset ) + nop + 'QZ' # dec ecx,,, push ecx, pop edx
34
+ mod_regs . push ( Rex ::Arch ::X86 ::ECX ) unless offset == 10
35
+ mod_regs . concat ( nop_regs )
36
+ mod_regs . push ( Rex ::Arch ::X86 ::EDX )
37
+
21
38
edxmod = 'J' * ( 11 - offset )
39
+ edx_regs . push ( Rex ::Arch ::X86 ::EDX ) unless edxmod . empty?
22
40
else
23
41
mod = 'A' * ( offset - 10 )
42
+ mod_regs . push ( Rex ::Arch ::X86 ::ECX ) unless mod . empty?
43
+
24
44
nop = 'C' * ( 10 - mod . length )
45
+ nop_regs . push ( Rex ::Arch ::X86 ::EBX ) unless nop . empty?
46
+
25
47
mod << nop + 'QZ'
48
+ mod_regs . concat ( nop_regs )
49
+ mod_regs . push ( Rex ::Arch ::X86 ::EDX )
50
+
26
51
edxmod = 'B' * ( 11 - ( offset - 10 ) )
52
+ edx_regs . push ( Rex ::Arch ::X86 ::EDX ) unless edxmod . empty?
27
53
end
28
54
regprefix = {
29
55
'EAX' => 'PY' + mod , # push eax, pop ecx
@@ -33,20 +59,41 @@ def self.gen_decoder_prefix(reg, offset)
33
59
'ESP' => 'TY' + mod , # push esp, pop ecx
34
60
'EBP' => 'UY' + mod , # push ebp, pop ecx
35
61
'ESI' => 'VY' + mod , # push esi, pop ecx
36
- 'EDI' => 'WY' + mod , # push edi, pop edi
62
+ 'EDI' => 'WY' + mod , # push edi, pop ecx
37
63
}
38
64
39
65
reg . upcase!
40
- if ( not regprefix . keys . include? reg )
66
+ unless regprefix . keys . include? ( reg )
41
67
raise ArgumentError . new ( "Invalid register name" )
42
68
end
43
- return regprefix [ reg ]
44
69
70
+ case reg
71
+ when 'EDX'
72
+ mod_registers . concat ( edx_regs )
73
+ mod_registers . concat ( nop_regs )
74
+ mod_registers . push ( Rex ::Arch ::X86 ::ECX )
75
+ else
76
+ mod_registers . push ( Rex ::Arch ::X86 ::ECX )
77
+ mod_registers . concat ( mod_regs )
78
+ end
79
+
80
+ mod_registers . uniq!
81
+ modified_registers . concat ( mod_registers )
82
+
83
+ return regprefix [ reg ]
45
84
end
46
85
47
- def self . gen_decoder ( reg , offset )
86
+ # Generates the decoder stub
87
+ #
88
+ # @param [String] reg the register pointing to the encoded payload
89
+ # @param [Fixnum] offset the offset to reach the encoded payload
90
+ # @param [Array] modified_registers accounts the registers modified by the stub
91
+ # @return [String] the alpha upper decoder stub
92
+ def self . gen_decoder ( reg , offset , modified_registers = [ ] )
93
+ mod_registers = [ ]
94
+
48
95
decoder =
49
- gen_decoder_prefix ( reg , offset ) +
96
+ gen_decoder_prefix ( reg , offset , mod_registers ) +
50
97
"V" + # push esi
51
98
"T" + # push esp
52
99
"X" + # pop eax
@@ -73,6 +120,18 @@ def self.gen_decoder(reg, offset)
73
120
"JJ" + # jnz * --------------------
74
121
"I" # first encoded char, fixes the above J
75
122
123
+ mod_registers . concat (
124
+ [
125
+ Rex ::Arch ::X86 ::ESP ,
126
+ Rex ::Arch ::X86 ::EAX ,
127
+ Rex ::Arch ::X86 ::ESI ,
128
+ Rex ::Arch ::X86 ::ECX ,
129
+ Rex ::Arch ::X86 ::EDX
130
+ ] )
131
+
132
+ mod_registers . uniq!
133
+ modified_registers . concat ( mod_registers )
134
+
76
135
return decoder
77
136
end
78
137
0 commit comments