1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
| #!/usr/bin/env python
def split_reg(reg):
reg8h = reg >> 8
reg8l = reg & 0xff
return (reg8h, reg8l)
def make_reg16_from_hl(reg8h, reg8l):
return (reg8h << 8) | reg8l
rol = lambda val, r_bits, max_bits=8: \
(val << r_bits % max_bits) & (2**max_bits - 1) | \
((val & (2**max_bits - 1)) >> (max_bits - (r_bits % max_bits)))
# xor ebx, ebx
bx = 0
# mov ecx, 25h
cx = 0x25
user_buffer = []
# already in reversed
encrypt_buffer = [0xa8, 0x9a, 0x90, 0xb3, 0xb6, 0xbc, 0xb4, 0xab, 0x9d, 0xae, 0xf9, 0xb8, 0x9d, 0xb8, 0xaf, 0xba, 0xa5, 0xa5, 0xba, 0x9a, 0xbc, 0xb0, 0xa7, 0xc0, 0x8a, 0xaa, 0xae, 0xaf, 0xba, 0xa4, 0xec, 0xaa, 0xae, 0xeb, 0xad, 0xaa, 0xaf]
stack = []
ax = 0
dx = 0
for c, i in enumerate(encrypt_buffer):
saved_ax = ax
saved_bx = bx
saved_cx = cx
saved_dx = dx
# brute force
for probe_char in range(255):
# mov dx, bx
dx = bx
#(dh, dl) = split_reg(dx)
# and dx, 3
dx = dx & 0x3
(dh, dl) = split_reg(dx)
# mov ax, 0x1C7
ax = 0x1C7
(ah, al) = split_reg(ax)
# push eax
stack.append(ax)
# sahf
cf = 1
# lodsb
al = probe_char
# xor al, [esp + 4]
al = al ^ 0xC7
ax = make_reg16_from_hl(ah, al)
# xchg cl, dl
saved_dx = dx
dx = cx
cx = saved_dx
(ch, cl) = split_reg(cx)
# rol ah, cl
ah = rol(ah, cl)
ax = make_reg16_from_hl(ah, al)
# adc al, ah
al = al + ah + cf
ax = make_reg16_from_hl(ah, al)
# xchg cl, dl
saved_dx = dx
dx = cx
cx = saved_dx
(ch, cl) = split_reg(cx)
(dh, dl) = split_reg(dx)
# xor edx, edx
dx = 0
# and eax, FFh
ax = ax & 0xff
(ah, al) = split_reg(ax)
# add bx, ax
bx = bx + ax
if ax == encrypt_buffer[c]:
user_buffer.append(probe_char)
ax = stack.pop()
cx -= 1
break
else:
ax = saved_ax
bx = saved_bx
cx = saved_cx
dx = saved_dx
print(''.join([chr(i) for i in user_buffer]))
|