工农路

2025-10-07

工农路

文/汪月婷

20.11.1再读留念

Read More

逆向练习#12

2020-12-22

BUUCTF-[2019红帽杯]easyRE

1.信息收集:无加壳,64位文件

2.IDA64位,搜索关键代码,如下

Read More

逆向练习#11

2020-11-13

Buuctf-CrackRTF

1.

惯例exeinfo查看信息,放进ida后搜索字符串进入关键函数

2.

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
int main_0()
{
DWORD v0; // eax
DWORD v1; // eax
CHAR String; // [esp+4Ch] [ebp-310h]
int v4; // [esp+150h] [ebp-20Ch]
CHAR String1; // [esp+154h] [ebp-208h]
BYTE pbData; // [esp+258h] [ebp-104h]

memset(&pbData, 0, 0x104u);
memset(&String1, 0, 0x104u);
v4 = 0;
printf("pls input the first passwd(1): ");
scanf("%s", &pbData);
if ( strlen((const char *)&pbData) != 6 ) //长度等于6位
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
v4 = atoi((const char *)&pbData); //转换为字符串形式
if ( v4 < 100000 )
ExitProcess(0);
strcat((char *)&pbData, "@DBApp"); //在输入后面加入@DBApp
v0 = strlen((const char *)&pbData);
sub_40100A(&pbData, v0, &String1); //加密函数
if ( !_strcmpi(&String1, "6E32D0943418C2C33385BC35A1470250DD8923A9") )
{
printf("continue...\n\n");
printf("pls input the first passwd(2): "); //第二次输入
memset(&String, 0, 0x104u);
scanf("%s", &String);
if ( strlen(&String) != 6 )
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
strcat(&String, (const char *)&pbData);
memset(&String1, 0, 0x104u);
v1 = strlen(&String);
sub_401019((BYTE *)&String, v1, &String1);
if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", &String1) )
{
if ( !(unsigned __int8)sub_40100F(&String) )
{
printf("Error!!\n");
ExitProcess(0);
}
printf("bye ~~\n");
}
}
return 0;
}

能发现sub_40100A是对输入进行加密处理的函数,且使结果等于6E32D0943418C2C33385BC35A1470250DD8923A9

进入sub_40100A

image-20201113094531546

百度能明白,这是用系统自带的hash加密算法。0x8004u是加密标识码,表示加密方式。

查询便可得知是sh1加密。于是写脚本把密码爆破。

1
2
3
4
5
6
7
import hashlib
flag2='@DBApp'
for i in range(100000,999999):
h2 = hashlib.sha1((str(i)+flag2).encode("utf-8"))
flags = h2.hexdigest()
if "6e32d0943418c2c33385bc35a1470250dd8923a9" == flags:
print (str(i)+flag2)

网上的wp脚本python版本都不同了,好在这个很容易写😉

得出结果: 123321@DBApp

接下来看下面,有第二次输入

过程类似,进入第二次加密函数sub_401019

image-20201113101213702

这次换了加密方式,查询得是MD5加密,然而并没有更多的提示了,得不出结果。

3.

在下面的比较中,还有个sub_40100F函数,这是这题的重点。

进入后

image-20201113103600853

大意为:从AAA中取出数据与我们的输入进行处理,生成一个dbapp.rtf的文件

这里还有个sub_401005函数,进入后可以知道是将AAA与我们的输入进行异或

image-20201113104417413

a2代表AAA中的首部指针,v5是字符串的长度

麻烦的是,还需要用工具 ResourceHacker 去查看文件中的AAA

由于生成了一个rtf文件,则搜索rtf文件头:{\rtfl

且由于我们知道密码是六位的

于是我们拿rtf文件前六位,正好就是文件头,与AAA文件中的前六位进行异或(此为反操作)

1
2
3
4
5
6
7
8
9
s = "{\\rtf1"

a = [0x05,0x7D,0x41,0x15,0x26,0x01]

flag = ""
for i in range(0,len(s)):
x = ord(s[i]) ^ a[i]
flag += chr(x)
print(flag)

得到结果:~!3a@0

于是运行程序,输入密码,正确,生成了flag文件

Flag{N0_M0re_Free_Bugs} 搞定!

Read More

逆向练习#10

2020-10-30

Buuctf-rsa

前言:rsa加密确实是很有名。但这应该是密码学范畴吧?

公钥n = p * q,其中p和q是两个大素数

e是随机选择的数,作为公钥

d是跟e有关的一个数,满足条件式:ed=1(mod phi(n))

phi(n)是欧拉函数,phi(n)=(p-1)(q-1)

加密过程:设明文为m,密文为c

c = m^e(mod n)

解密过程:

m=c^d (mod n)

RSA密钥体制中,n和e作为公钥,是都可以得到的值;d作为私钥,是私人拥有的

要破解RSA,最常用的方法是大素数分解,即:找到p和q,使得n=p*q成立

1.

下载来文件有两个,flag.enc和pub.key。

用UE打开pub.key后,会转换里面的十六进制,得

1
2
3
4
-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMAzLFxkrkcYL2wch21CM2kQVFpY9+7+
/AvKr1rzQczdAgMBAAE=
-----END PUBLIC KEY-----

2.

然后将公钥进行分析,提取n,e

key长度: 256
模数: C0332C5C64AE47182F6C1C876D42336910545A58F7EEFEFC0BCAAF5AF341CCDD
指数: 65537 (0x10001)

借助了在线解密工具

即e=65537

n=86934482296048119190666062003494800588905656017203025617216654058378322103517(十进制)

3.

再通过n解析p,q

这里也是借助在线工具 地址

得出

p = 285960468890451637935629440372639283459

q = 304008741604601924494328155975272418463

4.

再用脚本解密flag.enc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import gmpy2
import rsa

e = 65537
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463

phin = (q-1)*(p-1)
d = gmpy2.invert(e, phin)

key = rsa.PrivateKey(n, e, int(d), p, q)

with open("flag.enc", "rb+") as f: #你对应的文件位置
f = f.read()
print(rsa.decrypt(f, key))

5.

得到flag:flag{decrypt_256} 搞定!

不过这道题,只能算是拓展阅历吧。

Read More

逆向练习#9

2020-10-30

BUUCTF-简单注册器

前言:本来想着,简单题目没必要写笔记了吧。但还是得写啊。还得补学C语言与python,毕竟难的东西一下写不出来。先不偷懒。

1.

本题是apk文件,需要apk逆向工具,我去吾爱论坛上下载了破解好的jeb3。解压即可用,非常方便。

2.

进入jeb,打开apk文件。可以直接发现关键函数在MainActivity层级中,再按下Tab可以实现类似IDA的伪代码功能。选中十六进制数按B键能够转换进制。

image-20201030174748004

虽然这是JAVA伪代码,但其实很直观。

3.

于是改写成python

1
2
3
4
5
6
7
8
9
10
11
flagtrue = "dd2940c04462b4dd7c450528835cca15"
x = [i for i in flagtrue]
x[2] = chr(ord(x[2]) + ord(x[3]) - 50)
x[4] = chr(ord(x[2]) + ord(x[5]) - 48)
x[30] = chr(ord(x[31]) + ord(x[9]) - 48)
x[14] = chr(ord(x[0x1b]) + ord(x[0x1c]) - 97)

for i in range(16):
x[i],x[31-i] = x[31-i],x[i]

print ("flag{"+ ''.join(x) + "}")

扒来的,完全能够看懂,但自己写不出来,这些语法很值得学习。

4.

得出flag:flag{59acc538825054c7de4b26440c0999dd} 搞定!

Read More

逆向练习#8

2020-10-25

BUUCTF-re-[GXYCTF2019]luck_guy

前言:上个星期去写了科技协会的招新ctf题目。re勉强写,有些没写出来😥。

misc很简单导致自己写misc冲分上瘾(?这是招新题好吧)

1.

检查信息没有问题,放进ida64

2.

main函数里出现了个红框

image-20201025162621418

重点是这个红框,本地动态分配失败。让我有些搞不懂,但是好像不影响题目。

3.

用shift+f12,很容易就能找到关键的函数

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
unsigned __int64 get_flag()
{
unsigned int v0; // eax
char v1; // al
signed int i; // [rsp+4h] [rbp-3Ch]
signed int j; // [rsp+8h] [rbp-38h]
__int64 s; // [rsp+10h] [rbp-30h]
char v6; // [rsp+18h] [rbp-28h]
unsigned __int64 v7; // [rsp+38h] [rbp-8h]

v7 = __readfsqword(0x28u);
v0 = time(0LL); // 获取时间
srand(v0); // 用时间作为种子来生成随机数
for ( i = 0; i <= 4; ++i )
{
switch ( rand() % 200 ) // 生成随机数0~199
{
case 1:
puts("OK, it's flag:");
memset(&s, 0, 0x28uLL);
strcat((char *)&s, f1); // f1='GXY{do_not_'
strcat((char *)&s, &f2); // f2初始为空
printf("%s", &s);
break;
case 2:
printf("Solar not like you");
break;
case 3:
printf("Solar want a girlfriend");
break;
case 4:
v6 = 0;
s = 0x7F666F6067756369LL;
strcat(&f2, (const char *)&s);
break;
case 5:
for ( j = 0; j <= 7; ++j )
{
if ( j % 2 == 1 )
v1 = *(&f2 + j) - 2;
else
v1 = *(&f2 + j) - 1;
*(&f2 + j) = v1;
}
break;
default:
puts("emmm,you can't find flag 23333");
break;
}
}
return __readfsqword(0x28u) ^ v7;
}

随机0~199,进入5个case,还得按顺序进对的,确实是luckyguy了。2,3的case是无用的。

看case4,似乎是把s赋值给f2。case5中f2还要再处理一遍,1是把f1,f2拼在一起。所以应该是先4再5,1.

4.

写python脚本。(难在自己写脚本,不过这个只需要按着改就行了,好耶)

1
2
3
4
5
6
7
8
9
10
11
f1='GXY{do_not_'
f2=[0x69,0x63,0x75,0x67,0x60,0x6f,0x66,0x7f]
f3=''
for i in range(len(f2)):
if (i % 2 ==1):
f2[i] -= 2
else:
f2[i] -= 1
for i in range(len(f2)):
f3+=chr(f2[i])
print(f1+f3)

实测GXT需要改成flag

搞定!

Read More

逆向练习#7

2020-10-17

[BUUCTF-刮开有奖]

1.

丢进exeinfo查看信息,没加壳,需要用ida32位。

2.

发现是winmain函数,也许是因为这是个窗口程序。

image-20201017145150884

属实有点懵。那就再跟进这个函数DialogFunc

3.

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
BOOL __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
{
const char *v4; // esi
const char *v5; // edi
int v7; // [esp+8h] [ebp-20030h]
int v8; // [esp+Ch] [ebp-2002Ch]
int v9; // [esp+10h] [ebp-20028h]
int v10; // [esp+14h] [ebp-20024h]
int v11; // [esp+18h] [ebp-20020h]
int v12; // [esp+1Ch] [ebp-2001Ch]
int v13; // [esp+20h] [ebp-20018h]
int v14; // [esp+24h] [ebp-20014h]
int v15; // [esp+28h] [ebp-20010h]
int v16; // [esp+2Ch] [ebp-2000Ch]
int v17; // [esp+30h] [ebp-20008h]
CHAR String; // [esp+34h] [ebp-20004h]
char v19; // [esp+35h] [ebp-20003h]
char v20; // [esp+36h] [ebp-20002h]
char v21; // [esp+37h] [ebp-20001h]
char v22; // [esp+38h] [ebp-20000h]
char v23; // [esp+39h] [ebp-1FFFFh]
char v24; // [esp+3Ah] [ebp-1FFFEh]
char v25; // [esp+3Bh] [ebp-1FFFDh]
char v26; // [esp+10034h] [ebp-10004h]
char v27; // [esp+10035h] [ebp-10003h]
char v28; // [esp+10036h] [ebp-10002h]

if ( a2 == 272 )
return 1;
if ( a2 != 273 )
return 0;
if ( (_WORD)a3 == 1001 )
{
memset(&String, 0, 0xFFFFu); //使string清零
GetDlgItemTextA(hDlg, 1000, &String, 0xFFFF);//获取输入值为string
if ( strlen(&String) == 8 )
{
v7 = 'Z';
v8 = 'J';
v9 = 'S';
v10 = 'E';
v11 = 'C';
v12 = 'a';
v13 = 'N';
v14 = 'H';
v15 = '3';
v16 = 'n';
v17 = 'g'; //这应该是v7[]的数组形式,但我不知道怎么显示
sub_4010F0(&v7, 0, 10); //升序排序操作
memset(&v26, 0, 0xFFFFu);//&v26清零,就是v9组
//(v9只是个名字罢了,因为参考里面是这样的)
v26 = v23;
v28 = v25;
v27 = v24;
v4 = (const char *)sub_401000(&v26, strlen(&v26));//base64加密
memset(&v26, 0, 0xFFFFu);
v27 = v21;
v26 = v20;
v28 = v22;
v5 = (const char *)sub_401000(&v26, strlen(&v26));
if ( String == v7 + 34 //string=U
&& v19 == v11 //string[1]=J
&& 4 * v20 - 141 == 3 * v9 //string[2]=W
&& v21 / 4 == 2 * (v14 / 9) //string[3]=P 请注意这里的位置是升序过后的,下面会讲
&& !strcmp(v4, "ak1w")
&& !strcmp(v5, "V1Ax") )
{
MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0);
}
}
return 0;
}
if ( (_WORD)a3 != 1 && (_WORD)a3 != 2 )
return 0;
EndDialog(hDlg, (unsigned __int16)a3);
return 1;
}

一个重要问题就是,sub_4010F0这个函数做了什么事情。

Read More

逆向练习#6

2020-10-14

[BUUCTF-SimpleRev]

1.

放进exeinfo查看信息,是elf文件,丢进IDA64位。

2.

搜索关键字段进入主要函数

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
unsigned __int64 Decry()
{
char v1; // [rsp+Fh] [rbp-51h]
int v2; // [rsp+10h] [rbp-50h]
int v3; // [rsp+14h] [rbp-4Ch]
int i; // [rsp+18h] [rbp-48h]
int v5; // [rsp+1Ch] [rbp-44h]
char src[8]; // [rsp+20h] [rbp-40h]
__int64 v7; // [rsp+28h] [rbp-38h]
int v8; // [rsp+30h] [rbp-30h]
__int64 v9; // [rsp+40h] [rbp-20h]
__int64 v10; // [rsp+48h] [rbp-18h]
int v11; // [rsp+50h] [rbp-10h]
unsigned __int64 v12; // [rsp+58h] [rbp-8h]

v12 = __readfsqword(0x28u);
*(_QWORD *)src = 'SLCDN';
v7 = '\0';
v8 = 0;
v9 = 'wodah';
v10 = 0LL;
v11 = 0;
text = join(key3, (const char *)&v9); //join是自定义函数,简单的把两个字符串拼接
//即在key3后面增添V9,text='killshadow'
strcpy(key, key1);
strcat(key, src); //key="ADSFKNDCLS"
v2 = 0;
v3 = 0;
getchar();
v5 = strlen(key);
for ( i = 0; i < v5; ++i )
{
if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )
//if(key[v3]>64 && key[v3]<=90)
//把key每一位大写变小写
key[i] = key[v3 % v5] + 32;
++v3;
} //这个v3不知道做什么的
printf("Please input your flag:", src);
while ( 1 )
{
v1 = getchar();
if ( v1 == '\n' )
break;
if ( v1 == ' ' ) //遍历字符,是换行符结束,进入下一个判断:空格跳过
{
++v2; //v2表示字符串中字符的位号,这里判断是空格,于是+1
}
else
{
if ( v1 <= '`' || v1 > 'z' )
{
if ( v1 > '@' && v1 <= 'Z' )
str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97; //v2是会逐增的
//str2[v2] = (v1-key[v3]+58)%26 + 97
}
else
{
str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
//以上为加密操作,所以我们根据这些反推。
}
if ( !(v3 % v5) ) //如果循环到key的最后一位
putchar(32); //输出空格
++v2;
}
}
if ( !strcmp(text, str2) ) //与text对比
puts("Congratulation!\n");
else
puts("Try again!\n");
return __readfsqword(0x28u) ^ v12;
}

key3跟进,是字符串”kills”。key1是”ADSFK”。

由于字符串小端序存储,反过来写,所以注释中text与key是这个结果。

一般来说,x86系列cpu都是小端序存储,大端序一般用于网络协议。

经验:遇到不明数字最好转换成char类型看看,不然可能会找不到解题关键。

Read More

特难题折腾#1

2020-10-12

[2019红帽杯]xx

1.

exeinfo查看信息,无壳,然后放入ida64位。

2.

找到关键字符串,跟进看伪代码。

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
int64 __fastcall sub_1400011A0(__int64 a1, __int64 a2)
{
signed __int64 v2; // rbx
signed __int64 v3; // rax
__int64 v4; // rax
__int64 v5; // r11
__int128 *v6; // r14
int v7; // edi
_BYTE *v8; // rsi
char v9; // r10
int v10; // edx
__int64 v11; // r8
unsigned __int64 v12; // rcx
signed __int64 v13; // rcx
unsigned __int64 v14; // rax
unsigned __int64 i; // rax
__int64 v16; // rax
size_t v17; // rsi
_BYTE *v18; // rbx
_BYTE *v19; // r9
signed int v20; // er11
char *v21; // r8
signed __int64 v22; // rcx
char v23; // al
signed __int64 v24; // r9
signed __int64 v25; // rdx
__int64 v26; // rax
size_t Size; // [rsp+20h] [rbp-48h]
__int128 v29; // [rsp+28h] [rbp-40h]
int v30; // [rsp+38h] [rbp-30h]
int v31; // [rsp+3Ch] [rbp-2Ch]
int Code[4]; // [rsp+40h] [rbp-28h]
int v33; // [rsp+50h] [rbp-18h]

*(_OWORD *)Code = 0i64;
v33 = 0;
sub_1400018C0(std::cin, a2, Code);
v2 = -1i64;
v3 = -1i64;
do
++v3;
while ( *((_BYTE *)Code + v3) );
if ( v3 != 19 )
{
sub_140001620(std::cout, "error\n");
_exit((unsigned __int64)Code);
}
v4 = sub_140001E5C(5ui64);
v5 = *(_QWORD *)&::Code;
v6 = (__int128 *)v4;
v7 = 0;
v8 = (_BYTE *)v4;
do
{
v9 = v8[(_QWORD)Code - v4];
v10 = 0;
*v8 = v9;
v11 = 0i64;
v12 = -1i64;
do
++v12;
while ( *(_BYTE *)(v5 + v12) );
if ( v12 )
{
do
{
if ( v9 == *(_BYTE *)(v5 + v11) )
break;
++v10;
++v11;
}
while ( v10 < v12 );
}
v13 = -1i64;
do
++v13;
while ( *(_BYTE *)(v5 + v13) );
if ( v10 == v13 )
_exit(v5);
++v8;
}
while ( (signed __int64)&v8[-v4] < 4 );
*(_BYTE *)(v4 + 4) = 0;
do
++v2;
while ( *((_BYTE *)Code + v2) );
v14 = 0i64;
v29 = *v6;
while ( *((_BYTE *)&v29 + v14) )
{
if ( !*((_BYTE *)&v29 + v14 + 1) )
{
++v14;
break;
}
if ( !*((_BYTE *)&v29 + v14 + 2) )
{
v14 += 2i64;
break;
}
if ( !*((_BYTE *)&v29 + v14 + 3) )
{
v14 += 3i64;
break;
}
v14 += 4i64;
if ( v14 >= 0x10 )
break;
}
for ( i = v14 + 1; i < 0x10; ++i )
*((_BYTE *)&v29 + i) = 0;
v16 = sub_140001AB0(Code, v2, &v29, &Size);
v17 = Size;
v18 = (_BYTE *)v16;
v19 = (_BYTE *)sub_140001E5C(Size);
v20 = 1;
*v19 = v18[2];
v21 = v19 + 1;
v19[1] = *v18;
v19[2] = v18[3];
v19[3] = v18[1];
v19[4] = v18[6];
v19[5] = v18[4];
v19[6] = v18[7];
v19[7] = v18[5];
v19[8] = v18[10];
v19[9] = v18[8];
v19[10] = v18[11];
v19[11] = v18[9];
v19[12] = v18[14];
v19[13] = v18[12];
v19[14] = v18[15];
v19[15] = v18[13];
v19[16] = v18[18];
v19[17] = v18[16];
v19[18] = v18[19];
v19[19] = v18[17];
v19[20] = v18[22];
v19[21] = v18[20];
v19[22] = v18[23];
for ( v19[23] = v18[21]; v20 < v17; ++v21 )
{
v22 = 0i64;
if ( v20 / 3 > 0 )
{
v23 = *v21;
do
{
v23 ^= v19[v22++];
*v21 = v23;
}
while ( v22 < v20 / 3 );
}
++v20;
}
*(_QWORD *)&v29 = -4569681940847739698i64;
v24 = v19 - (_BYTE *)&v29;
*((_QWORD *)&v29 + 1) = 3819887636644928495i64;
v25 = 0i64;
v30 = -939386845;
v31 = -95004953;
do
{
if ( *((_BYTE *)&v29 + v25) != *((_BYTE *)&v29 + v25 + v24) )
_exit(v7 * v7);
++v7;
++v25;
}
while ( v25 < 24 );
v26 = sub_140001620(std::cout, "You win!");
std::basic_ostream<char,std::char_traits<char>>::operator<<(v26, sub_1400017F0);
return 0i64;
}

真的是很难了…

Read More

记一次IDA7.0插件安装过程

2020-10-12

记一次IDA7.0插件安装过程

插件:findcrypt

安装了很久,浪费了许多时间。这倒没什么,主要是因为tmd磨人心智。

1.

因为我的IDA是看雪学院下载的破解版本(似乎和吾爱破解的一样),所以自带python27文件夹,这是IDA许多插件所引用的python版本。然后findcrypt插件需要python的yara-python插件,这就搞得很麻烦。因此首先我们要编辑环境变量,再打开CMD用pip下载yara-python插件。如果电脑有装其他版本的Python,则需要先删去其他版本的环境变量,否则插件会错装到另外版本上去。(装好后再把其他版本的环境变量还原)

image-20201011231724807

2.

重点在于检索资料的时候,我发现很多博客都说如果IDA有python27\Scripts,可以直接用pip安装,然后把findcrypt插件装进去就好了。结果我整半天都搞不好,每次要用pip安装时就提示找不到。

[Fatal error in launcher: Unable to create process using]

我本以为是我路径没设置好,或者路径名称太长了,或者是其他库没有装好。

后来一次尝试发现,我得再装一遍pip。气死。不知道哪里出问题了,反正重装了一遍。

首先要去网站下python2.7的setools

如上图,首先添加我的IDA 7.0连带安装的python 2.7-x64环境变量到path,之后安装setuptools,因为要安装pip,必须先安装setuptools,它的安装命令:

1
python setup.py install

setup.py是解压之后可以看到的文件,命令行执行时一定要在切换到解压目录下(shift+鼠标右键),不然会提示找不到文件。

然后安装pip

首先去官网下载pip-10.0.1.tar.gz文件,下载链接:https://pypi.org/project/pip/#files,解压之后切换到该目录之后,用命令行执行以下命令:

1
python setup.py install

直到出现Finished processing dependencies for pip==10.0.1(随便什么版本均可),才算是安装成功。

3.

鉴于我的失败经验,把所有的库也重装了一遍。

VC++14.0

Vc++ compiler for python2.7支持库

4.

确认环境变量设置好后,任意位置

pip install yara-python==3.11.0

最新的yara不再支持python2了,在windows下使用pip安装的时候实际上不是用wheel来安装。必须得指定3.11.0版本才能安装成功

结果又出现错误

Could not install packages due to an EnvironmentError: HTTPSConnectionPool(host= 'files.pythonhosted.org', port=443): Max retries exceeded with url: /packages/96 /af/03015aec2c11a1e6b2221cb82e01bc5d153bb0813b044ca0da50d3d9a1f9/pycryptodome-3. 9.4-cp37-cp37m-win_amd64.whl (Caused by ReadTimeoutError("HTTPSConnectionPool(ho st='files.pythonhosted.org', port=443): Read timed out. (read timeout=15)"))

解决方法

在本地创建:
C:\Users\Administrator\pip

pip.ini 文件

1
2
3
4
5
[global]

trusted-host=mirrors.aliyun.com

index-url=http://mirrors.aliyun.com/pypi/simple/

就能成功解决

(这我不太能理解为什么,似乎是源文件地址外网连不上了,所以转到一个镜像地址下载?)

5.

下载来findcrpyt插件

image-20201011233317939

把这两个复制进ida的plugin文档就完事了!再打开ida,edit中plugins就能看到findcrypt插件。

记得把环境变量改回来。

明明步骤很简单,但就是横生出好多问题。(抹泪)

实用参考:

插件安装流程

pip安装错误

Read More