首页
社区
课程
招聘
1
[原创]kanxuectf2019 第七题
发表于: 2019-3-23 13:48 8379

[原创]kanxuectf2019 第七题

2019-3-23 13:48
8379
第一步:先去混淆,题目大致采用了一下混淆方法:
1.两条判断条件相反的跳转指令
1
2
3
4
5
6
7
8
9
10
jump_set = [
    ('jge','jl'),('jl','jge'),
    ('jbe','ja'),('ja','jbe'),
    ('jnb','jb'),('jb','jnb'),
    ('jp','jnp'),('jnp','jp'),
    ('jle','jg'),('jg','jle'),
    ('jno','jo'),('jo','jno'),
    ('js','jns'),('jns','js'),
    ('jnz','jz'),('jz','jnz'),
]
2.call; add esp,4指令组
3.call;add [esp+4],6 ; ret 指令组
4.push;call;pop;pop 指令组
5.clc;jnb指令组
6.stc;jb指令组
7.形如 jnz,jl,jmp,jz这样的指令组
第二步:patch掉一处函数(004B97E6  call sub_4B3F00),该函数的分析有问题,影响ida的反编译功能。
第三部:此时ida就能够正常反编译了,整体流程长这样(截取了几个片段)。
整个程序逻辑还是分成清晰的,主要实现了一下功能
(1)检查是否patch了程序,一共有三处
第一处:4B8E55
第二处:4029B2
第三处:4025DE
可以看一下check_patch函数
可以看到check_patch的检查思路为:如果参数1不为0,那么以参数1为起始地址,参数2为要检查的Dword数,进行如图所示的运算。然后将结果存入以special_value(004BC080)为起始地址,返回地址+4处字节为偏移的地方。如果参数1为0,那么以返回地址作为起始地址。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import os
import idaapi
 
 
def ror(x,i):
    return ((x>>9)&0x007fffff) | ((x<<23)&0xfffffe00)
 
def calc_check_value(addr,ret_addr,size):
    = 0
    for in range(size):
        data = Dword(addr+i*4)
        data = data ^ t
        data = data ^ 0x78563412
        #print hex(data)
        = ror(data,9)
        #print hex(t)
    return hex(t^Dword(ret_addr))
 
addr = 0x00401F58 + 5
print calc_check_value(addr,0x004025F2,0x68)
addr = 0x004B8E5A + 5
print calc_check_value(addr,0x004B8E5A,0x25a)
addr = 0x004025D3 + 5
print calc_check_value(addr,0x004029C6,0xf0)
(2)读取输入,做十六进制转十进制
(3)做一个大数乘法,乘数1为刚才check_patch函数计算得到的值,乘数2为一个固定值
1
2
3
= 0xc23f6401c93adb
= 0xeedcea3743d03a263af94f386de1
= x*y
其中作者用了一种自定义的大数结构,如下图所示:
numbuff字段存放数据的每一位,idx_buff字段为数据每一位的索引,之所以这样做猜测作者是为了防止数据连续出现,用来干扰分析者的。
(4)以乘法结果z的每一位进行判断,如果该位小于等于9,最终的key中存放z的这一位,如果该位大于9,则存放输入内容,具体翻译过后的c代码如下所示:
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
while True:
    if == 0:
        break
    tmp = % 0x10
    if tmp == 0:
        /= 0x10
        continue
    if tmp <= 9:
        x1 = cnt
        x2 = tmp + 9 * (cnt/9+ 0x50
        x3 = tmp + 9 * (cnt%9+ 0xa1
        x4 = tmp + 9 * (3 * (cnt/27+ (cnt%9)/3+ 0xf2
        #print x1,x2,x3,x4
        cnt = cnt + 1
    else:
        for in range(tmp-9):
            for in range(9):
                x1 = cnt
                x2 = + 9 * (cnt/9+ 0x51
                x3 = + 9 * (cnt%9+ 0xa2
                x4 = + 9 * ((cnt%9/ 3 + 3 * (cnt/27)) + 0xf3
                #print x1,x2,x3,x4
            #lo.append(cnt)
            #print cnt,
            cnt = cnt + 1
        if (z/0x10)%0x10 >9:
            print cnt
    /= 0x10
其中同时记录了当前值与位置的关系。
(5)反调试
作者一共用了9中反调试的手法,大家自行去分析吧,这里不再赘述,并将反调试的结果也作为一位加了进去(第40位),用来影响后面的分析。最后通过实际测试这9中反调试在正常环境运行时有7中返回值为0,2种返回时不为0。
(6)进行置换操作(5步),并将结果(value*9)^0x37
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
= [0x860x890x840x8D0xA70x830xA60x250x470x14
  0x350x1D0x0F0x1E0x970x9C0x950x010xAE0x3F
  0x370xB60x020x140x0B0x170x8A0x1F0x930xAC
  0x960x020x2D0x0E0x070x9F0x920x8C0x150xBE
  0x0A0x860x070xA40x030x850x2F0x8C0x8E0x0B
  0x9B0x050x0F0x840x800x9E0x8D0x000x160x01
]
 
= [0xBD0x480x2B0xAA0xB00xA30xB90x420xCF0x98
  0x4D0xB80x3C0xA00x320x410x210x910x3A0x45
  0x3B0x440x9A0xBB0x190x380x100x280x400x4C
  0xA90xCD0x430x330xC60x300x490xA20xBA0x4E
  0xC50xC90xC80xCB0xCC0x340xB10xC30x410xC4
  0xCA0x4A0x400xCB0x080x310xC20xCF0x390x4E]
for in range(len(g)):
    g[i] = g[i] & 0x7f
for in range(len(s)):
    s[i] = s[i] & 0x7f
for in range(4):
    for in range(len(g)):
        c[a[g[i]]] += 1
        c[a[s[i]]] += 1
        = a[g[i]]
        a[g[i]] = a[s[i]]
        a[s[i]] = t
(7)比较结果,这里使用od脚本记录下比较索引和比较值,然后直接爆破即可
od脚本如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
@START:
ifeq eip,004b96fc
    wrta "out.txt",eax
endif
 
ifeq eip,004b9731
    wrta "out1.txt",eax
endif
 
STO
ifneq eip,004B9778
    jmp @START
endif
最终爆破脚本:
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import os
 
sn_data = 0x380x390x070xE00x5A0x180x1E0xE70x5E0x3B
  0xEB0xA50xAE0x070x060x270x0D0x890xF10x6E
  0xD80x0D0x3A0xE00x1E0x960xA70xB20x7D0x15
  0x160x370x010x410x4B0x080x1C0x1D0x330x2B
  0x400x490x790xE30x040xFA0x050x470x660x1B
  0xDB0x9E0x2C0x2D0x4E0x200x870x9E0xBB0xE9
  0x140x8A0x360x7E0xD50x630x510x710x3C0x41
  0x370xA80x2E0x010x020x230x240x630x460xE9
  0x080x090x190x2B0x480x4D0xBD0xBC0x220x11
  0x6C0x330x340x770xE00x270x180x6C0x350x3B
  0xB60x8F0x460x100xC30x430x220x5E0x440xB3
  0x8C0x530x280xA40xCB0xF00x810xD60x960x0F
  0x5C0x310x320x190xF00xDA0x500x4E0x940xF7
  0x270x4E0x400x7A0x330x1F0x200x410x420x6C
  0x660x050x490xA40x480x490x300xAC0x0C0xBE
  0x2E0x2F0x300x9D0x180x2A0x230x230x6F0x0B
  0x200x210x2A0x6E0x4F0x830x3E0x3F0x510x63
  0x9A0x030x530x250x260x480xCF0x4C0x0A0x0B
  0x980xB70x880x4F0xE90xD30x1E0x130x570x35
  0xD20xF20x080x9A0x1A0x1B0x840x3D0xC90x66
  0x0E0x8B0xB40x580xD00x450xDA0x190xA50xB9
  0x2A0x1C0x4C0x2B0xDB0x070xFF0x190x120x31
  0x1E0x960xE20x880x4B0x190x3A0x190x1A0x19
  0xE60xDE0x000x210xF70x430x4B0x320x320x07
  0x460x290x4A0x4B0x290x970x0E0x190x100xE0
  0x900x730x650xE40x4C0x17]
 
= [0x860x890x840x8D0xA70x830xA60x250x470x14
  0x350x1D0x0F0x1E0x970x9C0x950x010xAE0x3F
  0x370xB60x020x140x0B0x170x8A0x1F0x930xAC
  0x960x020x2D0x0E0x070x9F0x920x8C0x150xBE
  0x0A0x860x070xA40x030x850x2F0x8C0x8E0x0B
  0x9B0x050x0F0x840x800x9E0x8D0x000x160x01
]
 
= [0xBD0x480x2B0xAA0xB00xA30xB90x420xCF0x98
  0x4D0xB80x3C0xA00x320x410x210x910x3A0x45
  0x3B0x440x9A0xBB0x190x380x100x280x400x4C
  0xA90xCD0x430x330xC60x300x490xA20xBA0x4E
  0xC50xC90xC80xCB0xCC0x340xB10xC30x410xC4
  0xCA0x4A0x400xCB0x080x310xC20xCF0x390x4E]
 
 
fp = open('out.txt','r')
check_data = []
for in fp.read():
    if == '\x0d' or == '\x0a' or == '\x20':
        continue
    check_data.append(int(x))
    #print x,
print len(check_data)
print check_data
fp.close()
fp = open('out1.txt','r')
idx_data = []
data_list = fp.readlines()
for data in data_list:
    if data == '\x0a':
        continue
    #print hex(ord(data[0])),hex(ord(data[1]))
    idx_data.append(int(data[:-1],16))
print len(idx_data)
print idx_data
 
= 0xc23f6401c93adb
 
= 0xeedcea3743d03a263af94f386de1
= x*y
print len(str(z))
cnt = 0
cnt1 = 0
lo = []
while True:
    if == 0:
        break
    tmp = % 0x10
    if tmp == 0:
        /= 0x10
        continue
    if tmp <= 9:
        cnt = cnt + 1
        cnt1 += 1
    else:
        for in range(tmp-9):
            lo.append(cnt)
            #print cnt,
            cnt = cnt + 1
    /= 0x10
print cnt1
print lo
 
= []
= []
for in range(0x80):
    a.append(i)
    c.append(0)
 
for in range(len(g)):
    g[i] = g[i] & 0x7f
for in range(len(s)):
    s[i] = s[i] & 0x7f
'''
for j in range(1):
    for i in range(len(g)):
        c[a[g[i]]] += 1
        c[a[s[i]]] += 1
        t = a[g[i]]
        a[g[i]] = a[s[i]]
        a[s[i]] = t
'''
'''
for i in range(4):
    c[a[g[i]]] += 1
    c[a[s[i]]] += 1
    t = a[g[i]]
    a[g[i]] = a[s[i]]
    a[s[i]] = t
 
t = a[s[4]]
a[s[4]] = a[g[4]]
c[a[s[4]]] += 1
'''
 
 
#print ''
 
def search(x,cnt):
    for in range(10):
        = i
        for in range(cnt):
            = (t*9)^0x37
        t &= 0xff
        #print t,
        if == x:
            #print i
            return i
    return -1
 
def calc_m(x,cnt):
    = x
    for in range(cnt):
        = (t*9)^0x37
    return t&0xff
 
real_lo = []
 
def check_zero(x):
    for in range(len(x)):
        if x[i] == '0':
            return 1
    return 0
 
real_ans = []
for in range(58):
    real_ans.append('1')
 
for in range(10000000):
    c[a[g[i%len(g)]]] += 1
    c[a[s[i%len(g)]]] += 1
    = a[g[i%len(g)]]
    a[g[i%len(g)]] = a[s[i%len(g)]]
    a[s[i%len(g)]] = t
    ans = ''
    for i1 in range(len(lo)):
        flag = 0
        for in range(len(a)):
            if a[j] == lo[i1]:
                change_lo = j
                break
         
        for in range(len(idx_data)):
            if idx_data[j] == change_lo:
                flag = j
                break
        = check_data[flag]
        idx = 0
        for in range(len(sn_data)):
            if == sn_data[j]:
                idx = j
                value = search(idx,c[lo[i1]])
                #print j,value
                if value != -1:
                    ans += str(value)
                    #real_ans[real_lo[i]] = str(value)
                    #print ans
                    #print hex(int(ans[::-1]))[2:-1].upper()[::-1]
    if len(ans) >= 58:
        h_ans = hex(int(ans[::-1]))[2:-1].upper()[::-1]
        print h_ans
        if check_zero(h_ans) == 0:
            print h_ans
            break

1
2
3
4
5
6
7
8
9
10
jump_set = [
    ('jge','jl'),('jl','jge'),
    ('jbe','ja'),('ja','jbe'),
    ('jnb','jb'),('jb','jnb'),
    ('jp','jnp'),('jnp','jp'),
    ('jle','jg'),('jg','jle'),
    ('jno','jo'),('jo','jno'),
    ('js','jns'),('jns','js'),
    ('jnz','jz'),('jz','jnz'),
]
2.call; add esp,4指令组
3.call;add [esp+4],6 ; ret 指令组
4.push;call;pop;pop 指令组
5.clc;jnb指令组
6.stc;jb指令组
7.形如 jnz,jl,jmp,jz这样的指令组
第二步:patch掉一处函数(004B97E6  call sub_4B3F00),该函数的分析有问题,影响ida的反编译功能。
第三部:此时ida就能够正常反编译了,整体流程长这样(截取了几个片段)。
整个程序逻辑还是分成清晰的,主要实现了一下功能
(1)检查是否patch了程序,一共有三处
第一处:4B8E55
第二处:4029B2
第三处:4025DE
可以看一下check_patch函数
可以看到check_patch的检查思路为:如果参数1不为0,那么以参数1为起始地址,参数2为要检查的Dword数,进行如图所示的运算。然后将结果存入以special_value(004BC080)为起始地址,返回地址+4处字节为偏移的地方。如果参数1为0,那么以返回地址作为起始地址。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import os
import idaapi
 
 
def ror(x,i):
    return ((x>>9)&0x007fffff) | ((x<<23)&0xfffffe00)
 
def calc_check_value(addr,ret_addr,size):
    = 0
    for in range(size):
        data = Dword(addr+i*4)
        data = data ^ t
        data = data ^ 0x78563412
        #print hex(data)
        = ror(data,9)
        #print hex(t)
    return hex(t^Dword(ret_addr))
 
addr = 0x00401F58 + 5
print calc_check_value(addr,0x004025F2,0x68)
addr = 0x004B8E5A + 5
print calc_check_value(addr,0x004B8E5A,0x25a)
addr = 0x004025D3 + 5
print calc_check_value(addr,0x004029C6,0xf0)
(2)读取输入,做十六进制转十进制
(3)做一个大数乘法,乘数1为刚才check_patch函数计算得到的值,乘数2为一个固定值
1
2
3
= 0xc23f6401c93adb
= 0xeedcea3743d03a263af94f386de1
= x*y
其中作者用了一种自定义的大数结构,如下图所示:
numbuff字段存放数据的每一位,idx_buff字段为数据每一位的索引,之所以这样做猜测作者是为了防止数据连续出现,用来干扰分析者的。
(4)以乘法结果z的每一位进行判断,如果该位小于等于9,最终的key中存放z的这一位,如果该位大于9,则存放输入内容,具体翻译过后的c代码如下所示:
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
while True:
    if == 0:
        break
    tmp = % 0x10
    if tmp == 0:
        /= 0x10
        continue
    if tmp <= 9:
        x1 = cnt
        x2 = tmp + 9 * (cnt/9+ 0x50
        x3 = tmp + 9 * (cnt%9+ 0xa1
        x4 = tmp + 9 * (3 * (cnt/27+ (cnt%9)/3+ 0xf2
        #print x1,x2,x3,x4
        cnt = cnt + 1
    else:
        for in range(tmp-9):
            for in range(9):
                x1 = cnt
                x2 = + 9 * (cnt/9+ 0x51
                x3 = + 9 * (cnt%9+ 0xa2
                x4 = + 9 * ((cnt%9/ 3 + 3 * (cnt/27)) + 0xf3
                #print x1,x2,x3,x4
            #lo.append(cnt)
            #print cnt,
            cnt = cnt + 1
        if (z/0x10)%0x10 >9:
            print cnt
    /= 0x10
其中同时记录了当前值与位置的关系。
(5)反调试
作者一共用了9中反调试的手法,大家自行去分析吧,这里不再赘述,并将反调试的结果也作为一位加了进去(第40位),用来影响后面的分析。最后通过实际测试这9中反调试在正常环境运行时有7中返回值为0,2种返回时不为0。
(6)进行置换操作(5步),并将结果(value*9)^0x37
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
= [0x860x890x840x8D0xA70x830xA60x250x470x14
  0x350x1D0x0F0x1E0x970x9C0x950x010xAE0x3F
  0x370xB60x020x140x0B0x170x8A0x1F0x930xAC
  0x960x020x2D0x0E0x070x9F0x920x8C0x150xBE
  0x0A0x860x070xA40x030x850x2F0x8C0x8E0x0B
  0x9B0x050x0F0x840x800x9E0x8D0x000x160x01
]
 
= [0xBD0x480x2B0xAA0xB00xA30xB90x420xCF0x98
  0x4D0xB80x3C0xA00x320x410x210x910x3A0x45
  0x3B0x440x9A0xBB0x190x380x100x280x400x4C
  0xA90xCD0x430x330xC60x300x490xA20xBA0x4E
  0xC50xC90xC80xCB0xCC0x340xB10xC30x410xC4
  0xCA0x4A0x400xCB0x080x310xC20xCF0x390x4E]
for in range(len(g)):
    g[i] = g[i] & 0x7f
for in range(len(s)):
    s[i] = s[i] & 0x7f
for in range(4):
    for in range(len(g)):
        c[a[g[i]]] += 1
        c[a[s[i]]] += 1
        = a[g[i]]
        a[g[i]] = a[s[i]]
        a[s[i]] = t
(7)比较结果,这里使用od脚本记录下比较索引和比较值,然后直接爆破即可
od脚本如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
@START:
ifeq eip,004b96fc
    wrta "out.txt",eax
endif
 
ifeq eip,004b9731
    wrta "out1.txt",eax
endif
 
STO
ifneq eip,004B9778
    jmp @START
endif
最终爆破脚本:
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import os
 
sn_data = 0x380x390x070xE00x5A0x180x1E0xE70x5E0x3B
  0xEB0xA50xAE0x070x060x270x0D0x890xF10x6E
  0xD80x0D0x3A0xE00x1E0x960xA70xB20x7D0x15
  0x160x370x010x410x4B0x080x1C0x1D0x330x2B
  0x400x490x790xE30x040xFA0x050x470x660x1B
  0xDB0x9E0x2C0x2D0x4E0x200x870x9E0xBB0xE9
  0x140x8A0x360x7E0xD50x630x510x710x3C0x41
  0x370xA80x2E0x010x020x230x240x630x460xE9
  0x080x090x190x2B0x480x4D0xBD0xBC0x220x11
  0x6C0x330x340x770xE00x270x180x6C0x350x3B
  0xB60x8F0x460x100xC30x430x220x5E0x440xB3
  0x8C0x530x280xA40xCB0xF00x810xD60x960x0F
  0x5C0x310x320x190xF00xDA0x500x4E0x940xF7
  0x270x4E0x400x7A0x330x1F0x200x410x420x6C
  0x660x050x490xA40x480x490x300xAC0x0C0xBE
  0x2E0x2F0x300x9D0x180x2A0x230x230x6F0x0B
  0x200x210x2A0x6E0x4F0x830x3E0x3F0x510x63
  0x9A0x030x530x250x260x480xCF0x4C0x0A0x0B
  0x980xB70x880x4F0xE90xD30x1E0x130x570x35
  0xD20xF20x080x9A0x1A0x1B0x840x3D0xC90x66
  0x0E0x8B0xB40x580xD00x450xDA0x190xA50xB9
  0x2A0x1C0x4C0x2B0xDB0x070xFF0x190x120x31
  0x1E0x960xE20x880x4B0x190x3A0x190x1A0x19
  0xE60xDE0x000x210xF70x430x4B0x320x320x07
  0x460x290x4A0x4B0x290x970x0E0x190x100xE0
  0x900x730x650xE40x4C0x17]
 
= [0x860x890x840x8D0xA70x830xA60x250x470x14
  0x350x1D0x0F0x1E0x970x9C0x950x010xAE0x3F
  0x370xB60x020x140x0B0x170x8A0x1F0x930xAC
  0x960x020x2D0x0E0x070x9F0x920x8C0x150xBE
  0x0A0x860x070xA40x030x850x2F0x8C0x8E0x0B
  0x9B0x050x0F0x840x800x9E0x8D0x000x160x01
]
 
= [0xBD0x480x2B0xAA0xB00xA30xB90x420xCF0x98
  0x4D0xB80x3C0xA00x320x410x210x910x3A0x45
  0x3B0x440x9A0xBB0x190x380x100x280x400x4C
  0xA90xCD0x430x330xC60x300x490xA20xBA0x4E
  0xC50xC90xC80xCB0xCC0x340xB10xC30x410xC4
  0xCA0x4A0x400xCB0x080x310xC20xCF0x390x4E]
 
 
fp = open('out.txt','r')
check_data = []
for in fp.read():
    if == '\x0d' or == '\x0a' or == '\x20':
        continue
    check_data.append(int(x))
    #print x,
print len(check_data)
print check_data
fp.close()
fp = open('out1.txt','r')
idx_data = []
data_list = fp.readlines()
for data in data_list:
    if data == '\x0a':
        continue
    #print hex(ord(data[0])),hex(ord(data[1]))
    idx_data.append(int(data[:-1],16))
print len(idx_data)
print idx_data
 
= 0xc23f6401c93adb
 
= 0xeedcea3743d03a263af94f386de1
= x*y
print len(str(z))
cnt = 0
cnt1 = 0
lo = []
while True:
    if == 0:
        break
    tmp = % 0x10
    if tmp == 0:
        /= 0x10
        continue
    if tmp <= 9:
        cnt = cnt + 1
        cnt1 += 1
    else:
        for in range(tmp-9):
            lo.append(cnt)
            #print cnt,
            cnt = cnt + 1
    /= 0x10
print cnt1
print lo
 
= []
= []
for in range(0x80):
    a.append(i)
    c.append(0)
 
for in range(len(g)):
    g[i] = g[i] & 0x7f
for in range(len(s)):
    s[i] = s[i] & 0x7f
'''
for j in range(1):
    for i in range(len(g)):
        c[a[g[i]]] += 1
        c[a[s[i]]] += 1
        t = a[g[i]]
        a[g[i]] = a[s[i]]
        a[s[i]] = t
'''
'''
for i in range(4):
    c[a[g[i]]] += 1
    c[a[s[i]]] += 1
    t = a[g[i]]
    a[g[i]] = a[s[i]]
    a[s[i]] = t
 
t = a[s[4]]
a[s[4]] = a[g[4]]
c[a[s[4]]] += 1
'''
 
 
#print ''
 
def search(x,cnt):
    for in range(10):
        = i
        for in range(cnt):
            = (t*9)^0x37
        t &= 0xff
        #print t,
        if == x:
            #print i
            return i
    return -1
 
def calc_m(x,cnt):
    = x
    for in range(cnt):
        = (t*9)^0x37
    return t&0xff
 
real_lo = []
 
def check_zero(x):
    for in range(len(x)):
        if x[i] == '0':
            return 1
    return 0
 
real_ans = []
for in range(58):
    real_ans.append('1')
 
for in range(10000000):
    c[a[g[i%len(g)]]] += 1
    c[a[s[i%len(g)]]] += 1
    = a[g[i%len(g)]]
    a[g[i%len(g)]] = a[s[i%len(g)]]
    a[s[i%len(g)]] = t
    ans = ''
    for i1 in range(len(lo)):
        flag = 0
        for in range(len(a)):
            if a[j] == lo[i1]:
                change_lo = j
                break
         
        for in range(len(idx_data)):
            if idx_data[j] == change_lo:
                flag = j
                break
        = check_data[flag]
        idx = 0
        for in range(len(sn_data)):
            if == sn_data[j]:
                idx = j
                value = search(idx,c[lo[i1]])
                #print j,value
                if value != -1:
                    ans += str(value)
                    #real_ans[real_lo[i]] = str(value)
                    #print ans
                    #print hex(int(ans[::-1]))[2:-1].upper()[::-1]
    if len(ans) >= 58:
        h_ans = hex(int(ans[::-1]))[2:-1].upper()[::-1]
        print h_ans
        if check_zero(h_ans) == 0:
            print h_ans
            break

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import os
import idaapi
 
 
def ror(x,i):
    return ((x>>9)&0x007fffff) | ((x<<23)&0xfffffe00)
 
def calc_check_value(addr,ret_addr,size):
    = 0
    for in range(size):
        data = Dword(addr+i*4)
        data = data ^ t
        data = data ^ 0x78563412
        #print hex(data)
        = ror(data,9)
        #print hex(t)
    return hex(t^Dword(ret_addr))
 
addr = 0x00401F58 + 5
print calc_check_value(addr,0x004025F2,0x68)
addr = 0x004B8E5A + 5
print calc_check_value(addr,0x004B8E5A,0x25a)
addr = 0x004025D3 + 5
print calc_check_value(addr,0x004029C6,0xf0)
(2)读取输入,做十六进制转十进制
(3)做一个大数乘法,乘数1为刚才check_patch函数计算得到的值,乘数2为一个固定值

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
PLEBFE
为你点赞~
2023-1-28 01:12
最新回复 (7)
雪    币: 6051
活跃值: (1441)
能力值: ( LV15,RANK:1473 )
在线值:
发帖
回帖
粉丝
2
太暴力了
2019-3-25 17:24
0
雪    币: 166
活跃值: (411)
能力值: ( LV12,RANK:583 )
在线值:
发帖
回帖
粉丝
3
od调的时候测了下是跑4轮,后面写代码的时候就懒得改了
2019-3-25 17:50
0
雪    币: 19097
活跃值: (1415)
能力值: ( LV15,RANK:936 )
在线值:
发帖
回帖
粉丝
4
中了9种反调试的招,没注意看后面的几个函数,被里面很多9给迷惑了,以为计算的结果应该是9。
2019-3-25 17:56
0
雪    币: 166
活跃值: (411)
能力值: ( LV12,RANK:583 )
在线值:
发帖
回帖
粉丝
5
我刚开始也是,都没仔细看。直接想当然了,后面跑出来一个带0的解,才感觉不对
2019-3-25 18:05
0
雪    币: 6051
活跃值: (1441)
能力值: ( LV15,RANK:1473 )
在线值:
发帖
回帖
粉丝
6
中了惯性思维的毒,设计时本来只用了7种,后来想着多加二种返回为0的会不会更有趣?
2019-3-25 18:08
0
雪    币: 19097
活跃值: (1415)
能力值: ( LV15,RANK:936 )
在线值:
发帖
回帖
粉丝
7
skytar 我刚开始也是,都没仔细看。直接想当然了,后面跑出来一个带0的解,才感觉不对[em_85]
是,我也出了个带0的解。。。
2019-3-25 18:40
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
真的是……
2019-10-18 19:01
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册