课程设计简单程序的密码破解.docx

上传人:b****1 文档编号:14538819 上传时间:2023-06-24 格式:DOCX 页数:29 大小:314.55KB
下载 相关 举报
课程设计简单程序的密码破解.docx_第1页
第1页 / 共29页
课程设计简单程序的密码破解.docx_第2页
第2页 / 共29页
课程设计简单程序的密码破解.docx_第3页
第3页 / 共29页
课程设计简单程序的密码破解.docx_第4页
第4页 / 共29页
课程设计简单程序的密码破解.docx_第5页
第5页 / 共29页
课程设计简单程序的密码破解.docx_第6页
第6页 / 共29页
课程设计简单程序的密码破解.docx_第7页
第7页 / 共29页
课程设计简单程序的密码破解.docx_第8页
第8页 / 共29页
课程设计简单程序的密码破解.docx_第9页
第9页 / 共29页
课程设计简单程序的密码破解.docx_第10页
第10页 / 共29页
课程设计简单程序的密码破解.docx_第11页
第11页 / 共29页
课程设计简单程序的密码破解.docx_第12页
第12页 / 共29页
课程设计简单程序的密码破解.docx_第13页
第13页 / 共29页
课程设计简单程序的密码破解.docx_第14页
第14页 / 共29页
课程设计简单程序的密码破解.docx_第15页
第15页 / 共29页
课程设计简单程序的密码破解.docx_第16页
第16页 / 共29页
课程设计简单程序的密码破解.docx_第17页
第17页 / 共29页
课程设计简单程序的密码破解.docx_第18页
第18页 / 共29页
课程设计简单程序的密码破解.docx_第19页
第19页 / 共29页
课程设计简单程序的密码破解.docx_第20页
第20页 / 共29页
亲,该文档总共29页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

课程设计简单程序的密码破解.docx

《课程设计简单程序的密码破解.docx》由会员分享,可在线阅读,更多相关《课程设计简单程序的密码破解.docx(29页珍藏版)》请在冰点文库上搜索。

课程设计简单程序的密码破解.docx

课程设计简单程序的密码破解

目录

1.题目要求2

2.使用工具2

3.破解正文2

3.1查看程序2

3.2查找关键点3

3.3逆向主要函数4

4.总结15

6.参考文献21

简单程序的密码破解

1.题目要求

自己写一个简单的Windows程序,要求输入密码,在密码不正确时,提示“passworderror”。

如果正确,则出现一个新的界面。

对于生成的执行文件进行反汇编,阅读和跟踪执行,暴力破解(生成新版本的执行程序)或找出密码。

2.使用工具

Olldbg,IDA,PEid,RadASM,VC++

3.破解正文

3.1查看程序

先使用PEid载入程序,如图3.1.1所示,显示界面为win32GUI,情况确实如此,此程序界面是用VC6++直接做出来的。

有最下面那个Nothingfound*可知程序并没有使用任何加壳手段。

图3.3.1

直接运行程序,输入任意字符如:

123456,123456点击注册,查看是否有任何提示信息,如图3.1.2所示

图3.1.2

3.2查找关键点

首先用OD载入程序,这里使用三种方式查找关键点,第一种方式是查找关键字符串passworderror,右键中文搜索引擎—>搜索ASCII码,即可查看所有字符串。

中文搜索引擎

地址反汇编文本字符串

0040113FpushKeShe.00402050汇编

00401144pushKeShe.00402038passworderror

00401172pushKeShe.00402050汇编

00401177pushKeShe.00402038passworderror

0040126FpushKeShe.00402050汇编

00401274pushKeShe.00402047注册正确

004012FBcall(InitialCPUselection)

0040133ApushKeShe.00402050汇编

0040133FpushKeShe.00402038passworderror

这里有三处出现关键字符passworderror,而且字符串——注册正确肯定也很重要。

分别双击跟进去,即有可能找到关键代码段。

第二种方式是给相关函数下断点,这里首先要输入字符串,则很有可能用到GetDlgItemText之类的API,所以给GetDlgItemText下断点,就能在输入用户名,密码后跟踪到程序,来分析关键代码。

第三种方式是根据程序的类型结构,直接分析。

004012FB>call;[InitCommonControls

00401300push0x0;/pModule=NULL

00401302call;\GetModuleHandleA

00401307movdwordptrds:

[0x40317C],eax

0040130Cpush0x0;/pThreadId=NULL

0040130Epush0x0;|CreationFlags=0

00401310push0x0;|pThreadParm=NULL

00401312pushKeShe.00401000;|ThreadFunction=KeShe.00401000

00401317push0x0;|StackSize=0

00401319push0x0;|pSecurity=NULL

0040131Bcall;\CreateThread

00401320push0x0;/lParam=NULL

00401322pushKeShe.0040128B;|DlgProc=KeShe.0040128B

00401327push0x0;|hOwner=NULL

00401329push0x65;|pTemplate=65

0040132Bpushdwordptrds:

[0x40317C];|hInst=NULL

00401331call;\DialogBoxParamA

00401336jmpXKeShe.0040134B

00401338push0x0;/Style=MB_OK|MB_APPLMODAL

0040133ApushKeShe.00402050;|汇编

0040133FpushKeShe.00402038;|passworderror

00401344push0x0;|hOwner=NULL

00401346call;\MessageBoxA

0040134Bpush0x0;/ExitCode=0

0040134Dcall;\ExitProcess

这是OD中刚载入时的代码,左边为内存地址,中间是汇编代码,右边为注释。

由上代码,很明显可以看出程序调用了GetModuleHandleA,DialogBoxParamA,ExitProcess。

则可以得出这里典型的win32程序,用DialogBoxParamA载入窗口资源,然后消息循环,ExitProcess为退出程序。

因此由DialogBoxParamA即可找到消息处理函数。

不过应注意一下这里使用了CreateThread函数来创建线程,肯定有什么目的需要关注一下。

3.3逆向主要函数

3.3.1逆向消息处理函数

由3.1的第三种方式中,DialogBoxParamA的第四个参数就可以找到消息处理函数的地址。

00401322pushKeShe.0040128B;|DlgProc=KeShe.0040128B

则消息处理函数的地址为0040128B,用OD来到此地址。

0040128B/.55pushebp

0040128C|.8BECmovebp,esp

0040128E|.53pushebx

0040128F|.57pushedi

00401290|.56pushesi

00401291|.8B450Cmoveax,[arg.2]

00401294|.83F810cmpeax,0x10;Switch(cases10..111)

00401297|.750CjnzXKeShe.004012A5

00401299|.6A00push0x0;/Result=0;Case10(WM_CLOSE)ofswitch00401294

0040129B|.FF7508push[arg.1];|hWnd

0040129E|.E8B5000000call;\EndDialog

004012A3|.EB4AjmpXKeShe.004012EF

004012A5|>3D10010000cmpeax,0x110

004012AA|.7502jnzXKeShe.004012AE

004012AC|.EB41jmpXKeShe.004012EF;Case110(WM_INITDIALOG)ofswitch00401294

004012AE|>3D11010000cmpeax,0x111

004012B3|.752EjnzXKeShe.004012E3

004012B5|.8B4510moveax,[arg.3];Case111(WM_COMMAND)ofswitch00401294

004012B8|.3DE8030000cmpeax,0x3E8

004012BD|.7513jnzXKeShe.004012D2

004012BF|.FF7514push[arg.4]

004012C2|.FF7510push[arg.3]

004012C5|.FF750Cpush[arg.2]

004012C8|.FF7508push[arg.1]

004012CB|.E84CFEFFFFcallKeShe.0040111C;关键注册响应函数

004012D0|.EB1DjmpXKeShe.004012EF

004012D2|>83F864cmpeax,0x64

004012D5|.7518jnzXKeShe.004012EF

004012D7|.6A00push0x0;/Result=0

004012D9|.FF7508push[arg.1];|hWnd

004012DC|.E877000000call;\EndDialog

004012E1|.EB0CjmpXKeShe.004012EF

004012E3|>B800000000moveax,0x0;Defaultcaseofswitch00401294

004012E8|.5Epopesi

004012E9|.5Fpopedi

004012EA|.5Bpopebx

004012EB|.C9leave

004012EC|.C21000retn0x10

004012EF|>B801000000moveax,0x1

004012F4|.5Epopesi

004012F5|.5Fpopedi

004012F6|.5Bpopebx

004012F7|.C9leave

004012F8\.C21000retn0x10

观察上面这个典型的消息处理函数,并有程序界面可以看出,这里使用了两次EndDialog,一次为点程序的叉的消息处理,还有一次为点取消键的消息处理。

则在两次EndDialog之间

004012CB|.E84CFEFFFFcallKeShe.0040111C

即是点注册键的消息处理函数。

3.3.2逆向线程函数

使用OD来到内存地址0040111C处,按F2设下断点如图3.3.2(A)

图3.3.2(A)

然后,按F9直接让程序运行,输入123456,123456,如下图:

不过,这里还没有输入用户名和注册码,就弹出了passworderror消息框,确定后就结束程序了。

没输入用户名和对话框就弹出了错误消息,是因为程序检测出了程序正在被调试器动态调试。

观察关于线程的窗口,如下图:

除了主线程,还有别的线程,这就和开始的CreateThread相对应,其中一个线程地址为00401000,在CreateThread函数中创建的线程函数也为该地址,用OD来到此处。

00401000movdwordptrds:

[0x4032D7],KeShe.004011>;入口地址

0040100Amovdwordptrds:

[0x4032DB],KeShe.004012>

00401014movebx,dwordptrds:

[0x4032D7]

0040101Axoredx,edx

0040101Cmovzxeax,byteptrcs:

[ebx]

00401020addedx,eax;累加

00401022incebx

00401023cmpebx,dwordptrds:

[0x4032DB]

00401029jnzXKeShe.0040101C

0040102Bcmpedx,0x777D;关键对比

00401031jnzXKeShe.00401049

00401033push0x0;/pThreadId=NULL

00401035push0x0;|CreationFlags=0

00401037push0x0;|pThreadParm=NULL

00401039pushKeShe.00401000;|ThreadFunction=KeShe.00401000

0040103Epush0x0;|StackSize=0

00401040push0x0;|pSecurity=NULL

00401042call;\CreateThread

00401047jmpXKeShe.0040104E

00401049jmpKeShe.00401338

0040104Eretn

分析这段程序的算法,作用为将地址0x40111C到地址0x40128B之间的机器码进行累加到EDX中,最后让EDX与0x777D比较,若不相等则跳转到00401249处,在401049处再跳转到401338h处,即弹出错误消息框然后结束程序。

如果不在40111C到40128B中设断点,测试得EDX刚好为777Dh,在线程结束之前又调用了CreateThread函数来创建线程继续进行校验和来防止设断点。

在动态调试下,设断点会改变机器码,即可检测出有调试器加载。

这里采用了多线程反动态调试技术,若不下断点,当输入用户名和注册码后,点注册程序会直接跑掉。

3.3.3分析注册函数

由于使用了多线程反调试技术,当然可以将线程挂起再调试,不过这里我使用静态分析这部分代码,使用IDA静态分析。

直接来到0x40111C处。

这里调用了GetDlgItemTextA函数,返回值为eax与6比较,如下图相等则跳转,不相等这出现错误提示信息,则用户名的长度必须为6。

在401157h处调用了第二个GetDlgItemTextA函数,返回值与0Bh比较,则密码长度必须为11,否则会显示失败,如下图:

当检验长度成功后,跳转到401188h处,这里压栈了五个参数,然后调用了sub_40104F函数,0040104F处不在地址0x40111C到地址0x40128B之间,因此可以下断点,这里现有OD调试这个函数,分析加密算法。

在0040104F处下断点,F9运行,用户名输:

123456密码:

12345678911

成功在此处断下,查看堆栈,如下图:

最上一行为返回地址,下面5行为参数,分别为1.2.3.4.5,这里用户名的第6个参数没有传进来。

0040104Fpushebp

00401050movebp,esp

00401052pushKeShe.0040328C;/pSystemInfo=KeShe.0040328C

00401057call;\GetSystemInfo

这里调用了GetSystemInfo函数,查MSDN得获取系统信息的结构体为

typedefstruct_SYSTEM_INFO{

union{

DWORDdwOemId;

struct{

WORDwProcessorArchitecture;

WORDwReserved;

};

};

DWORDdwPageSize;

LPVOIDlpMinimumApplicationAddress;

LPVOIDlpMaximumApplicationAddress;

DWORDdwActiveProcessorMask;

DWORDdwNumberOfProcessors;

DWORDdwProcessorType;

DWORDdwAllocationGranularity;

WORDwProcessorLevel;

WORDwProcessorRevision;

}SYSTEM_INFO,*LPSYSTEM_INFO;

则内存地址0040328C返回的是该结构体,如下图

0040105Cmovebx,dwordptrds:

[0x403290]

这里的403290刚好偏移4个字节,则是把DWORDdwPageSize给ebx,本电脑为00001000.

00401062orbl,byteptrss:

[ebp+0x8]

Ebp+8为第一个参数,与bl异或。

00401065andebx,0xFF

0040106Bmoval,byteptrds:

[ebx+0x403000]

这里ebx的值为31h,查看403000处发现填充了大量数据,如下图,这里将0x403000+31h处的字符给al,为’O’。

00401071cmpal,byteptrds:

[0x403180]

将0x403180处的字符与al做比对,查看该处的数据如下图,发现为密码数据,这里即为’1’

00401077jnzKeShe.00401338;不相等则跳转的结束,这里修改标志寄存器不让跳转

0040107Dmovebx,dwordptrds:

[0x4032A0]

这里偏移14h个字节,为dwNumberOfProcessors,本电脑为4

00401083orbl,byteptrss:

[ebp+0xC]

与第二个参数异或,的ebx为36h

00401086moval,byteptrds:

[ebx+0x403000]

0040108Ccmpal,byteptrds:

[0x403181]

403000h+36h处的字符这里为’F’,与密码的第二个字符’2’作比对

00401092jnzKeShe.00401338

00401098pushKeShe.004032B0;/pSystemTime=KeShe.004032B0

0040109Dcall;\GetSystemTime

获取系统时间,由MSDN,该结构为

typedefstruct_SYSTEMTIME{

WORDwYear;//07DD

WORDwMonth;//0006

WORDwDayOfWeek;//0006

WORDwDay;//000F

WORDwHour;//000F

WORDwMinute;//0002

WORDwSecond;//0009

WORDwMilliseconds;//0238

}SYSTEMTIME,

*PSYSTEMTIME;

返回的数据地址为004032B0h如下图,这为此时的系统时间:

004010A2movbx,wordptrds:

[0x4032B8]

这里相对于SYSTEMTIME偏移8字节,为wHour,即000F

004010A9orbl,byteptrss:

[ebp+0x10]

004010ACmoval,byteptrds:

[ebx+0x403000]

004010B2cmpal,byteptrds:

[0x403182]

Bl与第三个参数异或,则ebx为3Fh,将403000h+3Fh处的字符’h’给al,并与第三个密码字符’3’比对。

004010B8jnzKeShe.00401338

004010BEmovbx,wordptrds:

[0x4032BA]

004010C5orbl,byteptrss:

[ebp+0x14]

004010C8moval,byteptrds:

[ebx+0x403000]

004010CEcmpal,byteptrds:

[0x403183]

这里相对于SYSTEMTIME偏移10字节,为wMinute,即0002,Bl与第四个参数异或,则ebx为36h,将403000h+36h处的字符’F’给al,并与第四个密码字符’4’比对。

004010D4jnzKeShe.00401338

004010DApushKeShe.004032C0;/pSystemTime=KeShe.004032C0

004010DFcall;\GetSystemTime

这里又一次获取系统时间,

wMinute;wSecond;wMilliseconds发生变化

004010E4movax,wordptrds:

[0x4032BC]

004010EAmovbx,wordptrds:

[0x4032CC]

004010F1cmpax,bx

004010F4jnzKeShe.00401338

比较两次的wSecond,若不调试应该是同一个值,但这里调试了,所以时间不一样,所以跳转到结束,显示失败。

不过这里仍然要改变标志寄存器不使其跳转,这里根据时间差来反调试。

004010FAxorebx,ebx

004010FCmovbx,wordptrds:

[0x4032C4]

00401103orbl,byteptrss:

[ebp+0x18]

00401106moval,byteptrds:

[ebx+0x403000]

0040110Ccmpal,byteptrds:

[0x403184]

这里相对于SYSTEMTIME偏移4字节,为wDayOfWeek,即0006,Bl与第五个参数异或,则ebx为37h,将403000h+37h处的字符’E’给al,并与第五个密码字符’5’比对。

00401112jnzKeShe.00401338

00401118leave

00401119retn0x14

现在继续用IDA静态分析注册函数的代码:

Eax为3的平方9,将403000h+9的字符这里为’O’,赋值给String1

Eax为4的立方40h,将403000h+40h的字符’4’,赋值给String1_1

Eax为5的立方7Dh,将403000h+7Dh的字符’s’,赋值给String1_2

Eax为6的立方D8h,将403000h+D8h的字符’i’,赋值给String1_3

Eax为7的平方31h,将403000h+31h的字符’O’,赋值给String1_4,

将用户名的第六个字符给bl,这里输入的是6,则ebx为36h,则403000h+36h处的字符为’F’

比对密码的后六个字符,成功则显示成功。

则若用户名为:

123456密码为:

OF***O4siOF其中三个星号要根据具体的小时,分钟,所在星期的天数来觉得,具体看上

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2