• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Gallopsled / pwntools / 5499425242

pending completion
5499425242

Pull #2205

github-actions

web-flow
Merge 81f463e2c into 8b4cacf8b
Pull Request #2205: Fix stable Python 2 installation from a built wheel

3936 of 6604 branches covered (59.6%)

12074 of 16876 relevant lines covered (71.55%)

0.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

7.08
/pwnlib/encoders/arm/alphanumeric/builder.py
1
# Copyright (c) 2013 Pratik Kumar Sahu, Nagendra Chowdary, Anish Mathuria
2
# Ported to Python by Gallopsled
3
from __future__ import absolute_import
1✔
4
from __future__ import division
1✔
5

6
from . import alphanum_byte
1✔
7
from . import ARM_Instructions
1✔
8
from . import random_funcs
1✔
9

10
#+---------------------------------------------------+*/
11
#|                Builder Functions                  |*/
12
#+---------------------------------------------------+*/
13

14
EOR = 1
1✔
15
SUB = 2
1✔
16
RSB = 3
1✔
17
MI  = 4
1✔
18
PL  = 5
1✔
19
LDR = 6
1✔
20
STR = 7
1✔
21
LDM = 8
1✔
22
STM = 9
1✔
23
ROR = 10
1✔
24
LSR = 11
1✔
25

26
class builder:
1✔
27

28
   def __init__(self):
1✔
29
      self.I = 0
×
30
      self.size = 0
×
31
      self.i = 0
×
32
      self.j = 0
×
33
      self.k = 0
×
34
      self.x = 0
×
35
      self.addr = 0
×
36
      self.addr_offset = 0
×
37

38
   def enc_data_builder(self, input):
1✔
39
      if len(input) == 0:
×
40
         return ''
×
41
      output = ''
×
42
      arr = [1,2,3,4,5,6,7,8,9]
×
43
      self.I = random_funcs.randel(arr)
×
44
      for _, ab in enumerate(bytearray(input)):
×
45
         b = ab & 0x0f
×
46
         e0 = random_funcs.enc_data_msn(b, self.I)
×
47
         e0 = e0 << 4
×
48
         ef = e0 | b
×
49
         d = ((ab & 0xf0) ^ e0) >> 4
×
50
         c0 = random_funcs.enc_data_msn(d, self.I) << 4
×
51
         cd = c0 | d
×
52
         output += chr(cd & 0xff)
×
53
         output += chr(ef & 0xff)
×
54
      #Last two bytes to stop the decoder_loop*/
55
      max = 0x30 | self.I
×
56
      output += chr(alphanum_byte.alphanumeric_get_byte())
×
57
      output += chr(alphanum_byte.alphanumeric_get_byte_ltmax(max))
×
58
      return output
×
59

60
   def DecoderLoopBuilder(self, icache_flush):
1✔
61
      dec_loop = ''
×
62
      # Select p,s,t and q */
63
      arr = [3, 7]
×
64
      p = random_funcs.randel(arr)
×
65
      if p == 3:
×
66
         s = 7
×
67
      else:
68
         s = 3
×
69
      t = 6
×
70
      arr2 = [8, 9]
×
71
      q = random_funcs.randel(arr2)
×
72

73
      # Add the instructions*/
74
      if icache_flush != 0:
×
75
         dec_loop += ARM_Instructions.swi(MI)
×
76

77
      rsalnum = alphanum_byte.alphanumeric_get_byte()
×
78

79
      if icache_flush != 0:
×
80
         #EORMIS rp, r4, #(randomly selected alphanumeric value)*/
81
         dec_loop += ARM_Instructions.dpimm(EOR, MI, 1, p, 4, rsalnum)
×
82

83
      if icache_flush == 1:
×
84
         dist = 0x2c
×
85
      else:
86
         dist = 0x28
×
87

88
      offset = alphanum_byte.off_gen(dist + 0x04)
×
89

90
      #SUBPL rs, r4, #(dist+0x04+offset)*/
91
      dec_loop += ARM_Instructions.dpimm(SUB, PL, 0, s, 4, chr(dist + 0x04 + offset))
×
92

93
      #SUBPL rs, pc, rs LSR r4*/
94
      dec_loop += ARM_Instructions.dpshiftreg(SUB, 0, s, 0x0f, s, LSR, 4)
×
95

96
      #EORPLS rt, r4, rs LSR r4*/
97
      dec_loop += ARM_Instructions.dpshiftreg(EOR, 1, t, 4, s, LSR, 4)
×
98

99
      #EORMIS rp, r4, #rsalnum*/
100
      rsalnum = alphanum_byte.alphanumeric_get_byte()
×
101
      dec_loop += ARM_Instructions.dpimm(EOR, MI, 1, p, 4, rsalnum)
×
102

103
      #LDRPLB rp, [rs, #(-offset)]*/
104
      dec_loop += ARM_Instructions.lsbyte(LDR, PL, p, s, offset)
×
105

106
      #SUBPL rs, rs, r5 LSR r4*/
107
      dec_loop += ARM_Instructions.dpshiftreg(SUB, 0, s, s, 5, LSR, 4)
×
108

109
      #LDRPLB rq, [rs, #(-offset)]*/
110
      dec_loop += ARM_Instructions.lsbyte(LDR, PL, q, s, offset)
×
111

112
      #EORPLS rp, rq, rp ROR #28*/
113
      dec_loop += ARM_Instructions.dpshiftimm(EOR, 1, p, q, p, 28)
×
114

115
      #STRPLB rp, [rt, #(-offset)]*/
116
      dec_loop += ARM_Instructions.lsbyte(STR, PL, p, t, offset)
×
117

118
      #SUBPL rt, rt, r5 LSR r4*/
119
      dec_loop += ARM_Instructions.dpshiftreg(SUB, 0, t, t, 5, LSR, 4)
×
120

121
      #SUBPL rs, rs, r5 LSR r4*/
122
      dec_loop += ARM_Instructions.dpshiftreg(SUB, 0, s, s, 5, LSR, 4)
×
123

124
      #RSBPLS rq, rq, #0x3I*/
125
      dec_loop += ARM_Instructions.dpimm(RSB, PL, 1, q, q, 0x30 | self.I)
×
126

127
      #BMI 0xfffff4*/
128
      dec_loop += ARM_Instructions.bmi()
×
129

130
      #STRPLB r4, [rt, #-(offset+1)]*/
131
      dec_loop += ARM_Instructions.lsbyte(STR, PL, 4, t, offset + 1)
×
132

133
      if icache_flush == 1:
×
134
         #SWIPL 0x9f0002*/
135
         dec_loop += ARM_Instructions.swi(PL)
×
136
      return dec_loop
×
137

138
   def encDecoderLoopBuilder(self, input):
1✔
139
      output = ''
×
140
      if len(input) == 0:
×
141
         return output
×
142
      for p in input:
×
143
         if not alphanum_byte.alphanumeric_check(p):
×
144
            output += chr(alphanum_byte.alphanumeric_get_byte())
×
145
         else:
146
            output += p
×
147
      return output
×
148

149
   def DecoderBuilder(self, input, icache_flush):
1✔
150
      if len(input) == 0:
×
151
         return ''
×
152
      output = ''
×
153

154
      #Register selections*/
155
      arr = [4,6]
×
156
      self.addr  = random_funcs.randel(arr)
×
157
      arr2 = [3, 5, 7]
×
158
      self.i = random_funcs.randel(arr2)
×
159
      arr3 = [0, 0]
×
160
      q = 0
×
161
      for p in range(3):
×
162
         if arr2[p] != self.i:
×
163
            arr3[q] = arr2[p]
×
164
            q += 1
×
165
      self.j = random_funcs.randel(arr3)
×
166
      for p in range(2):
×
167
         if arr3[p] != self.j:
×
168
            self.k = arr3[p]
×
169
            break
×
170

171
      self.x = alphanum_byte.off_gen(0x01)
×
172
      offset = 0x91
×
173
      if icache_flush != 0:
×
174
         output += self.algo1(input, 0, 3)
×
175
         output += self.gap_traverse(0x1e)
×
176
         output += self.algo1(input, 33, 5)
×
177
      else:
178
         output += self.gap_traverse(0x19)
×
179
         output += self.algo1(input, 25, 5)
×
180
      output += self.gap_traverse(0x0f)
×
181
      if icache_flush != 0:
×
182
         output += self.algo1(input, 53, 15)
×
183
      else:
184
         output += self.algo1(input, 45, 11)
×
185
      #trucate the last instruction, which increments raddr by 1, from the output*/
186
      output = output[:-4]
×
187
      self.size -= 4
×
188
      #Setting r0, r1, r2 for parameter passing*/
189
      #SUBPLS ri, ri, #x*/
190
      output += ARM_Instructions.dpimm(SUB, PL, 1, self.i, self.i, self.x)
×
191
      #SUBPL r4, ri, ri LSR ri*/
192
      output += ARM_Instructions.dpshiftreg(SUB, 0, 4, self.i, self.i, LSR, self.i)
×
193
      #SUBPL r6, ri, ri LSR ri*/
194
      output += ARM_Instructions.dpshiftreg(SUB, 0, 6, self.i, self.i, LSR, self.i)
×
195
      #SUBPL r5, rj, r4 ROR r6*/
196
      output += ARM_Instructions.dpshiftreg(SUB, 0, 5, self.j, 4, ROR, 6)
×
197

198
      self.size += 4 * 4
×
199

200
      if icache_flush:
×
201
         arr4 = [3,7]
×
202
         m = random_funcs.randel(arr4)
×
203

204
         c = alphanum_byte.off_gen(24)
×
205
         arr5 = [2,4,6,8,10,12,14,16,18]
×
206
         arr6 = [4,6]
×
207
         arr7 = [1,2,4,8]
×
208
         reglH = 0x40 | random_funcs.randel(arr7)
×
209
         #SUBPL rm, sp, #(c+24) */
210
         output += ARM_Instructions.dpimm(SUB, PL, 0, m, 13, c + 24)
×
211

212
         #Store 4 0x00*/
213
         #STRPLB random_funcs.randel(arr6), [!rm, -(r5 ROR #random_funcs.randel(arr5))]*/
214
         output += ARM_Instructions.sbyteposti(random_funcs.randel(arr6), m, 5, random_funcs.randel(arr5))
×
215
         output += ARM_Instructions.sbyteposti(random_funcs.randel(arr6), m, 5, random_funcs.randel(arr5))
×
216
         output += ARM_Instructions.sbyteposti(random_funcs.randel(arr6), m, 5, random_funcs.randel(arr5))
×
217
         output += ARM_Instructions.sbyteposti(random_funcs.randel(arr6), m, 5, random_funcs.randel(arr5))
×
218

219
         #Store 4 0xff*/
220
         #STRPLB r5, [!rm, -(r5 ROR #random_funcs.randel(arr5))]*/
221
         output += ARM_Instructions.sbyteposti(5, m, 5, random_funcs.randel(arr5))
×
222
         output += ARM_Instructions.sbyteposti(5, m, 5, random_funcs.randel(arr5))
×
223
         output += ARM_Instructions.sbyteposti(5, m, 5, random_funcs.randel(arr5))
×
224
         output += ARM_Instructions.sbyteposti(5, m, 5, random_funcs.randel(arr5))
×
225

226
         #Store 4 0x00*/
227
         #STRPLB random_funcs.randel(arr6), [!rm, -(r5 ROR #random_funcs.randel(arr5))]*/
228
         output += ARM_Instructions.sbyteposti(random_funcs.randel(arr6), m, 5, random_funcs.randel(arr5))
×
229
         output += ARM_Instructions.sbyteposti(random_funcs.randel(arr6), m, 5, random_funcs.randel(arr5))
×
230
         output += ARM_Instructions.sbyteposti(random_funcs.randel(arr6), m, 5, random_funcs.randel(arr5))
×
231
         output += ARM_Instructions.sbyteposti(random_funcs.randel(arr6), m, 5, random_funcs.randel(arr5))
×
232

233
         #SUBPL rm, sp, #c*/
234
         output += ARM_Instructions.dpimm(SUB, PL, 0, m, 13, c)
×
235

236
         #LDMPLDB rm!, {r0, r1, r2, r6, r8/9/10/11, r14}*/
237
         output += ARM_Instructions.lmul(m, reglH, 0x47)
×
238

239
         #SUBPLS rm, r5, r4 ROR rm*/
240
         output += ARM_Instructions.dpshiftreg(SUB, 1, m, 5, 4, ROR, m)
×
241

242
         self.size += 4 * 16
×
243
      return output
×
244

245
   def algo1(self, input, begin_inp, iter):
1✔
246
      if len(input) == 0:
×
247
         return ''
×
248
      output = ''
×
249
      offset = 0x91
×
250
      for p in range(begin_inp, begin_inp + iter):
×
251
         y = ord(input[p])
×
252
         if alphanum_byte.alphanumeric_check(y):
×
253
            #SUBPL raddr, raddr, rj ROR rk*/
254
            output += ARM_Instructions.dpshiftreg(SUB, 0, self.addr, self.addr, self.j, ROR, self.k)
×
255
            self.size += 4
×
256
            continue
×
257
         if y >= 0x80:
×
258
            if alphanum_byte.alphanumeric_check(~y):
×
259
               #EORPLS rk, rj, #~y*/
260
               output += ARM_Instructions.dpimm(EOR, PL, 1, self.k, self.j, ~y)
×
261
               #STRMIB rk, [raddr, #(-offset)]*/
262
               output += ARM_Instructions.lsbyte(STR, MI, self.k, self.addr, offset)
×
263
               #SUBMIS rk, ri, #x*/
264
               output += ARM_Instructions.dpimm(SUB, MI, 1, self.k, self.i, self.x)
×
265
               #SUBPL raddr, raddr, rj ROR rk*/
266
               output += ARM_Instructions.dpshiftreg(SUB, 0, self.addr, self.addr, self.j, ROR, self.k)
×
267

268
               self.size += 4 * 4
×
269
               continue
×
270

271
            a = alphanum_byte.alphanumeric_get_complement(~y)
×
272
            b = (a ^ ~y) & 0xff
×
273
            #EORPLS rk, rj, #a*/
274
            output += ARM_Instructions.dpimm(EOR, PL, 1, self.k, self.j, a)
×
275
            #EORMIS  rk,  rk, #b*/
276
            output += ARM_Instructions.dpimm(EOR, MI, 1, self.k, self.k, b)
×
277
            #STRMIB rk, [raddr, #(-offset)]*/
278
            output += ARM_Instructions.lsbyte(STR, MI, self.k, self.addr, offset)
×
279
            #SUBMIS rk, ri, #x*/
280
            output += ARM_Instructions.dpimm(SUB, MI, 1, self.k, self.i, self.x)
×
281
            #SUBPL raddr, raddr, rj ROR rk*/
282
            output += ARM_Instructions.dpshiftreg(SUB, 0, self.addr, self.addr, self.j, ROR, self.k)
×
283

284
            self.size += 4 * 5
×
285
            continue
×
286
         if self.x > y:
×
287
            z1 = self.x - y
×
288
            if alphanum_byte.alphanumeric_check(z1):
×
289
               #SUBPL rk, ri, #z*/
290
               output += ARM_Instructions.dpimm(SUB, PL, 0, self.k, self.i, z1)
×
291
               #STRPLB rk, [raddr, #(-offset)]*/
292
               output += ARM_Instructions.lsbyte(STR, PL, self.k, self.addr, offset)
×
293
               #SUBPL raddr, raddr, rj ROR rk*/
294
               output += ARM_Instructions.dpshiftreg(SUB, 0, self.addr, self.addr, self.j, ROR, self.k)
×
295

296
               self.size += 4 * 3
×
297
               continue
×
298
         z2 = self.x + y
×
299
         if alphanum_byte.alphanumeric_check(z2):
×
300
            #RSBPL rk, ri, #z*/
301
            output += ARM_Instructions.dpimm(RSB, PL, 0, self.k, self.i, z2)
×
302
            #STRPLB rk, [raddr, #(-offset)]*/
303
            output += ARM_Instructions.lsbyte(STR, PL, self.k, self.addr, offset)
×
304
            #SUBPL raddr, raddr, rj ROR rk*/
305
            output += ARM_Instructions.dpshiftreg(SUB, 0, self.addr, self.addr, self.j, ROR, self.k)
×
306

307
            self.size += 4 * 3
×
308
            continue
×
309
         z3 = self.x ^ y
×
310
         if alphanum_byte.alphanumeric_check(z3):
×
311
            #EORPLS rk, ri, #z*/
312
            output += ARM_Instructions.dpimm(EOR, PL, 1, self.k, self.i, z3)
×
313
            #STRPLB rk, [raddr, #(-offset)]*/
314
            output += ARM_Instructions.lsbyte(STR, PL, self.k, self.addr, offset)
×
315
            #SUBPL raddr, raddr, rj ROR rk*/
316
            output += ARM_Instructions.dpshiftreg(SUB, 0, self.addr, self.addr, self.j, ROR, self.k)
×
317

318
            self.size += 4 * 3
×
319
            continue
×
320
         a2 = alphanum_byte.alphanumeric_get_complement(z3)
×
321
         b2 = a2 ^ z3
×
322
         #EORPLS rk, ri, #a*/
323
         output += ARM_Instructions.dpimm(EOR, PL, 1, self.k, self.i, a2)
×
324
         #EORPLS rk, rk, #b*/
325
         output += ARM_Instructions.dpimm(EOR, PL, 1, self.k, self.k, b2)
×
326
         #STRPLB rk, [raddr, #(-offset)]*/
327
         output += ARM_Instructions.lsbyte(STR, PL, self.k, self.addr, offset)
×
328
         #SUBPL raddr, raddr, rj ROR rk*/
329
         output += ARM_Instructions.dpshiftreg(SUB, 0, self.addr, self.addr, self.j, ROR, self.k)
×
330

331
         self.size += 4 * 4
×
332

333

334
      return output
×
335

336
   def gap_traverse(self, gap):
1✔
337
      output = ''
×
338
      g = alphanum_byte.off_gen(gap)
×
339
      h = g + gap
×
340
      #SUBPL rj, ri, #x*/
341
      output += ARM_Instructions.dpimm(SUB, PL, 0, self.j, self.i, self.x)
×
342
      #EORPLS rk, rj, #g*/
343
      output += ARM_Instructions.dpimm(EOR, PL, 1, self.k, self.j, g)
×
344
      #SUBPL rk, rk, #h*/
345
      output += ARM_Instructions.dpimm(SUB, PL, 0, self.k, self.k, h)
×
346
      #SUBPL raddr, raddr, rk LSR rj*/
347
      output += ARM_Instructions.dpshiftreg(SUB, 0, self.addr, self.addr, self.k, LSR, self.j)
×
348
      #SUBPL rj, ri, #(x+1)*/
349
      output += ARM_Instructions.dpimm(SUB, PL, 0, self.j, self.i, self.x + 1)
×
350

351
      self.size += 4 * 5
×
352
      return output
×
353

354

355
   def buildInit(self, input):
1✔
356
      if len(input) == 0:
×
357
         return ('', input)
×
358
      output = ''
×
359

360
      #Select values of v and w*/
361
      total = 0x70
×
362
      arr1 = [0x30, 0x34, 0x38]
×
363
      v1 = random_funcs.randel(arr1)
×
364
      v2 = random_funcs.randel(arr1)
×
365

366
      topv = ((total - (v1 + v2)) // 4) + 1
×
367

368
      w1 = random_funcs.randel(arr1)
×
369
      w2 = random_funcs.randel(arr1)
×
370

371
      topw = ((total - (w1 + w2)) // 4) + 2
×
372

373
      arrop = [EOR, SUB, RSB]
×
374
      arrcond = [PL, MI]
×
375
      arrs = [0, 1]
×
376
      arrd = [3, 5, 7]
×
377
      arrn = [1, 2, 3, 4, 5, 6, 7, 8, 9]
×
378
      p = 1
×
379
      while p <= ((total-8) // 4):
×
380
         op = random_funcs.randel(arrop)
×
381
         cond = random_funcs.randel(arrcond)
×
382
         if op == EOR:
×
383
            s = 1
×
384
         else:
385
            s = random_funcs.randel(arrs)
×
386
         d = random_funcs.randel(arrd)
×
387
         n = random_funcs.randel(arrn)
×
388
         if p == topv or p == topw:
×
389
            output += ARM_Instructions.dpimm(op, cond, s, d, n, self.x)
×
390
         else:
391
            output += ARM_Instructions.dpimm(op, cond, s, d, n, alphanum_byte.alphanumeric_get_byte())
×
392
         p += 1
×
393

394
      #SUBPL ri, pc, #v1*/
395
      output += ARM_Instructions.dpimm(SUB, PL, 0, self.i, 15, v1)
×
396
      #SUBMI ri, pc, #w1*/
397
      output += ARM_Instructions.dpimm(SUB, MI, 0, self.i, 15, w1)
×
398
      #LDRPLB ri, [ri, #(-v2)]*/
399
      output += ARM_Instructions.lsbyte(LDR, PL, self.i, self.i, v2)
×
400
      #LDRMIB ri, [ri, #(-w2)]*/
401
      output += ARM_Instructions.lsbyte(LDR, MI, self.i, self.i, w2)
×
402

403
      output += self.algo2()
×
404

405
      #SUBPL rj, ri, #(x+1)*/
406
      output += ARM_Instructions.dpimm(SUB, PL, 0, self.j, self.i, self.x + 1)
×
407
      #Initializer built!!*/
408

409
      #Replace 0x91s in decoder with addr_offset*/
410
      input_new = ''
×
411
      for p in input:
×
412
         if p == "\x91":
×
413
            input_new += chr(self.addr_offset)
×
414
         else:
415
            input_new += p
×
416
      return (output, input_new)
×
417

418
   def algo2(self):
1✔
419
      output = ''
×
420
      self.size += 4
×
421
      #SUBMIS rk, ri, #x*/
422
      output += ARM_Instructions.dpimm(SUB, MI, 1, self.k, self.i, self.x)
×
423
      #SUBPLS rk, ri, #x*/
424
      output += ARM_Instructions.dpimm(SUB, PL, 1, self.k, self.i, self.x)
×
425
      #SUBPL rj, ri, #x*/
426
      output += ARM_Instructions.dpimm(SUB, PL, 0, self.j, self.i, self.x)
×
427

428
      quo = (self.size - 4) // 0x7a
×
429
      if quo >= 1:
×
430
         for p in range(quo):
×
431
            #SUBPL rj, rj, #0x7a*/
432
            output += ARM_Instructions.dpimm(SUB, PL, 0, self.j, self.j, 0x7a)
×
433

434
      rem = (self.size - 4) % 0x7a
×
435
      if rem >= 1 and rem <= 0x4a:
×
436
         self.addr_offset = alphanum_byte.off_gen(rem)
×
437
         #SUBPL rj, rj, #(offset+rem)*/
438
         output += ARM_Instructions.dpimm(SUB, PL, 0, self.j, self.j, self.addr_offset + rem)
×
439

440
      if rem >= 0x4b and rem < 0x7a:
×
441
         if alphanum_byte.alphanumeric_check(rem):
×
442
            self.addr_offset = alphanum_byte.alphanumeric_get_byte()
×
443
            #SUBPL rj, rj, #(rem)*/
444
            output += ARM_Instructions.dpimm(SUB, PL, 0, self.j, self.j, rem)
×
445
            #SUBPL rj, rj, #(offset)*/
446
            output += ARM_Instructions.dpimm(SUB, PL, 0, self.j, self.j, self.addr_offset)
×
447
         else:
448
            self.addr_offset = alphanum_byte.off_gen(rem - 0x5a)
×
449
            #SUBPL rj, rj, #0x5a*/
450
            output += ARM_Instructions.dpimm(SUB, PL, 0, self.j, self.j, 0x5a)
×
451
            #SUBPL rj, rj, #(offset + (rem - 0x5a))*/
452
            output += ARM_Instructions.dpimm(SUB, PL, 0, self.j, self.j, self.addr_offset + rem - 0x5a)
×
453

454
      #SUBPL raddr, pc, rj ROR rk*/
455
      output += ARM_Instructions.dpshiftreg(SUB, 0, self.addr, 15, self.j, ROR, self.k)
×
456
      return output
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc