From cea361e998cf2d8c18e844a23805049e6d49ee88 Mon Sep 17 00:00:00 2001 From: Cool-Y <1072916769@qq.com> Date: Mon, 1 Apr 2019 15:21:38 +0800 Subject: [PATCH] Site updated: 2019-04-01 15:21:24 --- 2000/01/01/hello-world/index.html | 2 +- .../BIBA访问控制模型实现(python)/index.html | 2 +- 2018/12/15/miio-control/index.html | 2 +- 2018/12/23/基于规则引擎发现IOT设备/index.html | 2 +- 2018/12/25/TCPDUMP拒绝服务攻击漏洞/index.html | 2 +- .../wifi半双工侧信道攻击学习笔记/index.html | 2 +- 2019/02/22/qq数据库的加密解密/index.html | 2 +- 2019/03/16/小米固件工具mkxqimage/index.html | 2 +- 2019/03/23/auto-send-WX/index.html | 2 +- 2019/03/25/Samba-CVE/index.html | 2 +- 2019/03/28/逆向工程实验/index.html | 31 +++++++++++-------- about/index.html | 2 +- archives/2000/01/index.html | 2 +- archives/2000/index.html | 2 +- archives/2018/11/index.html | 2 +- archives/2018/12/index.html | 2 +- archives/2018/index.html | 2 +- archives/2019/01/index.html | 2 +- archives/2019/02/index.html | 2 +- archives/2019/03/index.html | 2 +- archives/2019/index.html | 2 +- archives/index.html | 2 +- archives/page/2/index.html | 2 +- bookmarks/index.html | 2 +- categories/IOT/index.html | 2 +- categories/index.html | 2 +- categories/二进制/index.html | 2 +- categories/加密解密/index.html | 2 +- categories/杂七杂八/index.html | 2 +- categories/理论学习/index.html | 2 +- categories/顶会论文/index.html | 2 +- index.html | 6 ++-- page/2/index.html | 2 +- search.xml | 2 +- sitemap.xml | 2 +- tags/CVE/index.html | 2 +- tags/QQ/index.html | 2 +- tags/SSH/index.html | 2 +- tags/Samba/index.html | 2 +- tags/TCPDUMP/index.html | 2 +- tags/USENIX/index.html | 2 +- tags/index.html | 2 +- tags/itchat/index.html | 2 +- tags/miio/index.html | 2 +- tags/python/index.html | 2 +- tags/wifi/index.html | 2 +- tags/中间人/index.html | 2 +- tags/侧信道攻击/index.html | 2 +- tags/密码/index.html | 2 +- tags/小米/index.html | 2 +- tags/微信/index.html | 2 +- tags/拒绝服务攻击/index.html | 2 +- tags/数据库/index.html | 2 +- tags/数据挖掘/index.html | 2 +- tags/文件格式/index.html | 2 +- tags/模型实现/index.html | 2 +- tags/破解/index.html | 2 +- tags/自然语言处理/index.html | 2 +- tags/访问控制/index.html | 2 +- tags/远程执行/index.html | 2 +- tags/逆向/index.html | 2 +- tags/重放攻击/index.html | 2 +- 62 files changed, 81 insertions(+), 76 deletions(-) diff --git a/2000/01/01/hello-world/index.html b/2000/01/01/hello-world/index.html index bc11c523..baca7330 100644 --- a/2000/01/01/hello-world/index.html +++ b/2000/01/01/hello-world/index.html @@ -651,7 +651,7 @@ - 16.9k + 17k diff --git a/2018/11/16/BIBA访问控制模型实现(python)/index.html b/2018/11/16/BIBA访问控制模型实现(python)/index.html index fdac4c09..4292e35f 100644 --- a/2018/11/16/BIBA访问控制模型实现(python)/index.html +++ b/2018/11/16/BIBA访问控制模型实现(python)/index.html @@ -839,7 +839,7 @@ - 16.9k + 17k diff --git a/2018/12/15/miio-control/index.html b/2018/12/15/miio-control/index.html index 6f7a4922..2fb8370f 100644 --- a/2018/12/15/miio-control/index.html +++ b/2018/12/15/miio-control/index.html @@ -741,7 +741,7 @@ - 16.9k + 17k diff --git a/2018/12/23/基于规则引擎发现IOT设备/index.html b/2018/12/23/基于规则引擎发现IOT设备/index.html index a6a87df5..497c239d 100644 --- a/2018/12/23/基于规则引擎发现IOT设备/index.html +++ b/2018/12/23/基于规则引擎发现IOT设备/index.html @@ -741,7 +741,7 @@ - 16.9k + 17k diff --git a/2018/12/25/TCPDUMP拒绝服务攻击漏洞/index.html b/2018/12/25/TCPDUMP拒绝服务攻击漏洞/index.html index 397fa822..ad535815 100644 --- a/2018/12/25/TCPDUMP拒绝服务攻击漏洞/index.html +++ b/2018/12/25/TCPDUMP拒绝服务攻击漏洞/index.html @@ -746,7 +746,7 @@ - 16.9k + 17k diff --git a/2019/01/16/wifi半双工侧信道攻击学习笔记/index.html b/2019/01/16/wifi半双工侧信道攻击学习笔记/index.html index c9c9042b..77938925 100644 --- a/2019/01/16/wifi半双工侧信道攻击学习笔记/index.html +++ b/2019/01/16/wifi半双工侧信道攻击学习笔记/index.html @@ -869,7 +869,7 @@ Server -------wire----------| - 16.9k + 17k diff --git a/2019/02/22/qq数据库的加密解密/index.html b/2019/02/22/qq数据库的加密解密/index.html index ecd46f98..cfc3c8c4 100644 --- a/2019/02/22/qq数据库的加密解密/index.html +++ b/2019/02/22/qq数据库的加密解密/index.html @@ -718,7 +718,7 @@ - 16.9k + 17k diff --git a/2019/03/16/小米固件工具mkxqimage/index.html b/2019/03/16/小米固件工具mkxqimage/index.html index d462d10b..2157417c 100644 --- a/2019/03/16/小米固件工具mkxqimage/index.html +++ b/2019/03/16/小米固件工具mkxqimage/index.html @@ -725,7 +725,7 @@ - 16.9k + 17k diff --git a/2019/03/23/auto-send-WX/index.html b/2019/03/23/auto-send-WX/index.html index dbfaf977..1903b390 100644 --- a/2019/03/23/auto-send-WX/index.html +++ b/2019/03/23/auto-send-WX/index.html @@ -735,7 +735,7 @@ - 16.9k + 17k diff --git a/2019/03/25/Samba-CVE/index.html b/2019/03/25/Samba-CVE/index.html index 21b4f2c1..8cbfacfd 100644 --- a/2019/03/25/Samba-CVE/index.html +++ b/2019/03/25/Samba-CVE/index.html @@ -760,7 +760,7 @@ - 16.9k + 17k diff --git a/2019/03/28/逆向工程实验/index.html b/2019/03/28/逆向工程实验/index.html index 9e1cbaaf..f7ba27ea 100644 --- a/2019/03/28/逆向工程实验/index.html +++ b/2019/03/28/逆向工程实验/index.html @@ -79,13 +79,13 @@ - + - + @@ -96,10 +96,10 @@ - + - + @@ -417,7 +417,7 @@ - 2.2k 字 + 2.3k 字 @@ -464,8 +464,7 @@
反调试技术,程序用它来识别是否被调试,或者让调试器失效。为了阻止调试器的分析,当程序意识到自己被调试时,它们可能改变正常的执行路径或者修改自身程序让自己崩溃,从而增加调试时间和复杂度。
+反调试技术,程序用它来识别是否被调试,或者让调试器失效。为了阻止调试器的分析,当程序意识到自己被调试时,它们可能改变正常的执行路径或者修改自身程序让自己崩溃,从而增加调试时间和复杂度。
IsDebuggerPresent
CheckRemoteDebuggerPresent
NtQueryInformationProcess
OutputDebuggString
crack.exe,28.0 KB
可以看出,生成注册码主要在for循环中完成,之后将生成的注册码与输入相比较,判断是否正确。
所以,只要能弄明白v6,v12,v10,v15
的含义,我们就可以轻松的编写注册机。
打开ollybdg,在进入循环之前设下断点,动态调试程序1
2
3
4
5
6
7
8004010CC |> /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
11v12 = 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对该程序进行调试时,程序会自动退出
计算出”testname”的对应注册码
注册成功!
CrackMe1.exe 1641.0 KB
无保护措施:无壳、未加密、无反调试措施
使用OllyDbg对该程序进行调试时,程序会自动退出
CrackMe2.exe 9.00 KB
保护措施:部分加花、部分加密、简单反调试
根据(提示)[https://res.cloudinary.com/dozyfkbg3/raw/upload/v1553779403/%E8%BD%AF%E4%BB%B6%E7%A0%B4%E8%A7%A3/Crackme2%E6%8F%90%E7%A4%BA.docx]分析该程序
反调试技术,程序用它来识别是否被调试,或者让调试器失效。为了阻止调试器的分析,当程序意识到自己被调试时,它们可能改变正常的执行路径或者修改自身程序让自己崩溃,从而增加调试时间和复杂度。
IsDebuggerPresent
CheckRemoteDebuggerPresent
NtQueryInformationProcess
OutputDebuggString
rdstc
QueryPerformanceCounter
GetTickCount
,有如下两种方式探测时钟:crack.exe,28.0 KB
当输入错误验证码时,程序会输出“Bad Boy”,因此我们将程序拖入IDA,以流程图显示函数内部的跳转。查找“Bad Boy”字符串,我们可以定位到显示注册结果的相关代码:
用鼠标选中程序分支点,按空格切换回汇编指令界面
可以看到,这条指令位于PE文件的.text节,并且IDA已经自动将地址转换为运行时的内存地址VA:004010F9
Ctrl+G
直接跳到由IDA得到的VA:004010F9
处查看那条引起程序分支的关键指令验证函数的返回值存于EAX寄存器中,if语句通过以下两条指令执行
1 | cmp eax,ecx |
也就是说,当序列号输入错误时,EAX中的值为0,跳转将被执行。
如果我们把jnz
这条指令修改为jz
,那么整个程序的逻辑就会反过来。
双击jnz
这条指令,将其改为jz
,单击”汇编”将其写入内存
可以看到此时程序执行了相反的路径
上面只是在内存中修改程序,我们还需要在二进制文件中也修改相应的字节,这里考察VA与文件地址之间的关系
1 | 文件偏移地址 = VA - Image Base - 节偏移 |
也就是说,这条指令在PE文件中位于10F9
字节处,使用010Editer打开crack.exe,将这一字节的75(JNZ)`
改为74(JZ)`
,保存后重新执行,破解成功!
通过查找字符串“good boy”等,我们可以找到显示注册结果的相关代码
因为检测密钥是否正确时会将结果返回到EAX寄存器中,因此,在检测密钥前必然会对EAX寄存器清空,由此我们可以找到注册码验证的相关代码。
分析上图算法,按tab键转换为高级语言1
2
3
4for ( 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
8004010CC |> /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
11v12 = 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对该程序进行调试时,程序会自动退出
CrackMe2.exe 9.00 KB
保护措施:部分加花、部分加密、简单反调试
根据(提示)[https://res.cloudinary.com/dozyfkbg3/raw/upload/v1553779403/%E8%BD%AF%E4%BB%B6%E7%A0%B4%E8%A7%A3/Crackme2%E6%8F%90%E7%A4%BA.docx]分析该程序
反调试技术,程序用它来识别是否被调试,或者让调试器失效。为了阻止调试器的分析,当程序意识到自己被调试时,它们可能改变正常的执行路径或者修改自身程序让自己崩溃,从而增加调试时间和复杂度。
IsDebuggerPresent
CheckRemoteDebuggerPresent
NtQueryInformationProcess
OutputDebuggString
rdstc
QueryPerformanceCounter
GetTickCount
,有如下两种方式探测时钟:crack.exe,28.0 KB
当输入错误验证码时,程序会输出“Bad Boy”,因此我们将程序拖入IDA,以流程图显示函数内部的跳转。查找“Bad Boy”字符串,我们可以定位到显示注册结果的相关代码:
用鼠标选中程序分支点,按空格切换回汇编指令界面
可以看到,这条指令位于PE文件的.text节,并且IDA已经自动将地址转换为运行时的内存地址VA:004010F9
Ctrl+G
直接跳到由IDA得到的VA:004010F9
处查看那条引起程序分支的关键指令验证函数的返回值存于EAX寄存器中,if语句通过以下两条指令执行
1 | cmp eax,ecx |
也就是说,当序列号输入错误时,EAX中的值为0,跳转将被执行。
如果我们把jnz
这条指令修改为jz
,那么整个程序的逻辑就会反过来。
双击jnz
这条指令,将其改为jz
,单击”汇编”将其写入内存
可以看到此时程序执行了相反的路径
上面只是在内存中修改程序,我们还需要在二进制文件中也修改相应的字节,这里考察VA与文件地址之间的关系
1 | 文件偏移地址 = VA - Image Base - 节偏移 |
也就是说,这条指令在PE文件中位于10F9
字节处,使用010Editer打开crack.exe,将这一字节的75(JNZ)`
改为74(JZ)`
,保存后重新执行,破解成功!
通过查找字符串“good boy”等,我们可以找到显示注册结果的相关代码
因为检测密钥是否正确时会将结果返回到EAX寄存器中,因此,在检测密钥前必然会对EAX寄存器清空,由此我们可以找到注册码验证的相关代码。
分析上图算法,按tab键转换为高级语言1
2
3
4for ( 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
8004010CC |> /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
11v12 = 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对该程序进行调试时,程序会自动退出
CrackMe2.exe 9.00 KB
保护措施:部分加花、部分加密、简单反调试
根据(提示)[https://res.cloudinary.com/dozyfkbg3/raw/upload/v1553779403/%E8%BD%AF%E4%BB%B6%E7%A0%B4%E8%A7%A3/Crackme2%E6%8F%90%E7%A4%BA.docx]分析该程序