diff --git a/2019/03/28/逆向工程实验/index.html b/2019/03/28/逆向工程实验/index.html index 7af310e5..34816579 100644 --- a/2019/03/28/逆向工程实验/index.html +++ b/2019/03/28/逆向工程实验/index.html @@ -96,7 +96,7 @@ - + @@ -517,27 +517,27 @@

爆破

查找显示注册结果相关代码

当输入错误验证码时,程序会输出“Bad Boy”,因此我们将程序拖入IDA,以流程图显示函数内部的跳转。查找“Bad Boy”字符串,我们可以定位到显示注册结果的相关代码:

查找注册码验证相关代码

用鼠标选中程序分支点,按空格切换回汇编指令界面

-

可以看到,这条指令位于PE文件的.text节,并且IDA已经自动将地址转换为运行时的内存地址VA:004010F9

+

可以看到,这条指令位于PE文件的.text节,并且IDA已经自动将地址转换为运行时的内存地址VA:004010F9

修改程序跳转

-

也就是说,这条指令在PE文件中位于10F9字节处,使用010Editer打开crack.exe,将这一字节的75(JNZ)改为74(JZ),保存后重新执行,破解成功!

+

也就是说,这条指令在PE文件中位于10F9字节处,使用010Editer打开crack.exe,将这一字节的75(JNZ)`改为74(JZ)`,保存后重新执行,破解成功!

编写注册机

查找显示注册结果相关代码

通过查找字符串“good boy”等,我们可以找到显示注册结果的相关代码

查找注册码验证相关代码

因为检测密钥是否正确时会将结果返回到EAX寄存器中,因此,在检测密钥前必然会对EAX寄存器清空,由此我们可以找到注册码验证的相关代码。

根据注册码验证代码编写注册机

分析上图算法,按tab键转换为高级语言

1
2
3
4
for ( i = 0; i < v6; v12 = v10 )
v10 = (v6 + v12) * lpStringa[i++];
if ( (v12 ^ 0xA9F9FA) == atoi(v15) )
MessageBoxA(hDlg, aTerimaKasihKer, aGoodBoy, 0);

-

可以看出,生成注册码主要在for循环中完成,之后将生成的注册码与输入相比较,判断是否正确。
所以,只要能弄明白v6,v12,v10,v15的含义,我们就可以轻松的编写注册机。
打开ollybdg,在进入循环之前设下断点,动态调试程序

1
2
3
4
5
6
7
8
004010CC  |> /8B4D 10       |mov ecx,[arg.3]  //此时ecx为name
004010CF |. 8B55 0C |mov edx,[arg.2] //edx为0x1908
004010D2 |. 03D3 |add edx,ebx //edx加上name的长度(ebx)
004010D4 |. 0FBE0C08 |movsx ecx,byte ptr ds:[eax+ecx] //ecx=61h
004010D8 |. 0FAFCA |imul ecx,edx //61h(a) * edx
004010DB |. 40 |inc eax //eax加1(初始为0)
004010DC |. 894D 0C |mov [arg.2],ecx
004010DF |. 3BC3 |cmp eax,ebx //循环是否结束

-

arg.3为输入的name,arg.2初始为0x1908,ebx为name的长度,eax每次循环加1直到等于长度
因此,我们可以对参数的含义进行解释如下

1
2
3
4
5
6
7
8
9
10
11
v12 = 6408;   //0x1908
v10 = 6408; //0x1908
v6 = len(name);
v12 = input_serial;
for ( i = 0; i < v6; i++ ){
v12 = v10;
v10 = (v6 + v12) * lpStringa[i];
}
if ((v12 ^ 0xA9F9FA) == atoi(v15)){
MessageBoxA(hDlg, aTerimaKasihKer, aGoodBoy, 0);
}

-

可见,v12^0xA9F9FA的结果即是正确的注册码,我们编写一个简单的程序帮助我们生成注册码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include<stdio.h>

using namespace::std;
int main(){
int v12;
int v10 = 6408; //0x1908
string name;
cout << "请输入name: ";
cin >> name;
int len = name.size();
for(int i = 0; i < len+1; i++ ){
v12 = v10;
v10 = (len + v12) * name[i];
}
cout<<"\n"<<"注册码为: "<<(v12 ^ 0xA9F9FA)<<endl;
return 0;
}

+

可以看出,生成注册码主要在for循环中完成,之后将生成的注册码与输入相比较,判断是否正确。
所以,只要能弄明白v6,v12,v10,v15的含义,我们就可以轻松的编写注册机。
打开ollybdg,在进入循环之前设下断点,动态调试程序

1
2
3
4
5
6
7
8
004010CC  |> /8B4D 10       |mov ecx,[arg.3]  //此时ecx为name
004010CF |. 8B55 0C |mov edx,[arg.2] //edx为0x1908
004010D2 |. 03D3 |add edx,ebx //edx加上name的长度(ebx)
004010D4 |. 0FBE0C08 |movsx ecx,byte ptr ds:[eax+ecx] //ecx=61h
004010D8 |. 0FAFCA |imul ecx,edx //61h(a) * edx
004010DB |. 40 |inc eax //eax加1(初始为0)
004010DC |. 894D 0C |mov [arg.2],ecx
004010DF |. 3BC3 |cmp eax,ebx //循环是否结束

+

arg.3为输入的namearg.2初始为0x1908ebxname的长度,eax每次循环加1直到等于长度
因此,我们可以对参数的含义进行解释如下

1
2
3
4
5
6
7
8
9
10
11
v12 = 6408;   //0x1908
v10 = 6408; //0x1908
v6 = len(name);
v12 = input_serial;
for ( i = 0; i < v6; i++ ){
v12 = v10;
v10 = (v6 + v12) * lpStringa[i];
}
if ((v12 ^ 0xA9F9FA) == atoi(v15)){
MessageBoxA(hDlg, aTerimaKasihKer, aGoodBoy, 0);
}

+

可见,v12^0xA9F9FA的结果即是正确的注册码,我们编写一个简单的程序帮助我们生成注册码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include<stdio.h>

using namespace::std;
int main(){
int v12;
int v10 = 6408; //0x1908
string name;
cout << "请输入name: ";
cin >> name;
int len = name.size();
for(int i = 0; i < len+1; i++ ){
v12 = v10;
v10 = (len + v12) * name[i];
}
cout<<"\n"<<"注册码为: "<<(v12 ^ 0xA9F9FA)<<endl;
return 0;
}

计算出”testname”的对应注册码

注册成功!

实验二:软件反动态调试技术分析

对象

CrackMe1.exe 1641.0 KB
无保护措施:无壳、未加密、无反调试措施
使用OllyDbg对该程序进行调试时,程序会自动退出

要求

    diff --git a/search.xml b/search.xml index 331ea0f2..fcdecbe5 100644 --- a/search.xml +++ b/search.xml @@ -3,7 +3,7 @@ <![CDATA[逆向工程与软件破解]]> %2F2019%2F03%2F28%2F%E9%80%86%E5%90%91%E5%B7%A5%E7%A8%8B%E5%AE%9E%E9%AA%8C%2F - + 二进制 diff --git a/sitemap.xml b/sitemap.xml index 8d7ce051..c2fde40f 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -4,7 +4,7 @@ https://cool-y.github.io/2019/03/28/%E9%80%86%E5%90%91%E5%B7%A5%E7%A8%8B%E5%AE%9E%E9%AA%8C/ - 2019-03-30T09:36:07.633Z + 2019-03-30T09:39:39.837Z