看雪CTF 2016_第八题分析

用exeinfo查看发现是x64程序,所以用平常的OD调试器是调试不到的,需要用x64的调试器

我这里是用x64dbug 这个调试器来进行调试分析

经过一步一步调试,发现程序调用RtlMoveMemory 这个api来进行获取我们输入的注册码

Rax的内存地址即为我们输入的假码

我们先不要一步一步分析下去,直接来到提示注册码不正确那里。

我们来到上图的地方,走到000000013F5018E1 | E8 4E 8D 00 00 | call crackme.13F50A634 | 这里提示注册码不正确

然后上面有个跳转,为了验证是否为关键跳转,我们修改zf标志位使跳转成立,看看是不是提示成功,经过证实是提示成功,所以这个就是关键跳转。

然后我们看看它是使什么条件成立才跳转的呢。

000000013F5018A7 | 48 63 C6 | movsxd rax,esi |

000000013F5018AA | 49 63 D6 | movsxd rdx,r14d |

000000013F5018AD | 48 8D 0C 90 | lea rcx,qword ptr ds:[rax+rdx*4] |

000000013F5018B1 | 48 03 D1 | add rdx,rcx |

000000013F5018B4 | 48 8D 05 05 44 02 00 | lea rax,qword ptr ds:[13F525CC0] |

000000013F5018BB | 8B 0D 63 44 02 00 | mov ecx,dword ptr ds:[13F525D24] |

000000013F5018C1 | 0F AF CF | imul ecx,edi |

000000013F5018C4 | 03 0C 90 | add ecx,dword ptr ds:[rax+rdx*4] |

000000013F5018C7 | 8D 04 7F | lea eax,dword ptr ds:[rdi+rdi*2] |

000000013F5018CA | 3B C8 | cmp ecx,eax |

000000013F5018CC | 48 8D 0D A5 06 02 00 | lea rcx,qword ptr ds:[13F521F78] |

000000013F5018D3 | 74 07 | je crackme.13F5018DC |

这段汇编是对比ecx是否等于eax,如果等于就是为正确的注册码。

那么ecx的值和eax的值是怎么来的。

我们来分析一下:

movsxd rax,esi // esi=2

movsxd rdx,r14d //r14d=2

lea rcx,qword ptr ds:[rax+rdx*4] // [rax+rdx*4] 2+2*4=A

add rdx,rcx // rdx=A+2=C

lea rax,qword ptr ds:[13F525CC0] // [13F5B5CC0] =134

mov ecx,dword ptr ds:[13F525D24] // [13F5B5D24] =2=ecx

imul ecx,edi //这里的edi是个变量 我输入的假码是123456 所以这里edi=A678 ecx=2*A678=14cf0

add ecx,dword ptr ds:[rax+rdx*4] // dword [rax+rdx*4]=00000134 ecx=14cf0+134=14E24

lea eax,dword ptr ds:[rdi+rdi*2] // eax= [rdi+rdi*2]=A678+A678*2=1F368

所以很明显ecx != eax

上面的值除了变量之外,其余的都是固定的,你可以其他假码进行测试,我这里就不再举例了。

所以由上面得出:

设edi 为X

2X+134=3X

X=134

所以只要变量等于134,就是正确的注册码,然而134是怎么计算出来的,即上面的edi=A678是怎么来的。

经过向上分析,我们得出edi的结果是下面这个call计算出来的

000000013F2D197B | E8 80 F9 FF FF | call crackme.13F2D1300 |

000000013F2D1980 | 85 C0 | test eax,eax |

000000013F2D1982 | 75 2B | jne crackme.13F2D19AF |

000000013F2D1984 | 48 8D 0D 8D 06 02 00 | lea rcx,qword ptr ds:[13F2F2018] |

我们进入这个call分析

000000013F921300 | 45 33 C9 | xor r9d,r9d |

000000013F921303 | 44 8B D9 | mov r11d,ecx |

000000013F921306 | 41 B8 01 00 00 00 | mov r8d,1 |

000000013F92130C | 45 8B D1 | mov r10d,r9d |

000000013F92130F | 81 F9 6A 03 00 00 | cmp ecx,36A | 和注册码对比 ecx为注册码

000000013F921315 | 75 04 | jne crackme.13F92131B |

000000013F921317 | 83 C8 FF | or eax,FFFFFFFF |

000000013F92131A | C3 | ret |

当前ecx=1E240 十进制是123456 是我刚才出入的假码 它和36A对比 36A十进制是874

这里不是很清楚为什么注册码不能为874,因为我这样分析在前面丢失了很多细节,不过没所谓,我们继续分析下去。

000000013F92131B | 81 F9 B1 68 DE 3A | cmp ecx,3ADE68B1 | 注册码和3ADE68B1 对比 十进制为987654321 即注册码不能是987654321

000000013F921321 | 74 F4 | je crackme.13F921317 |

000000013F921323 | 85 C9 | test ecx,ecx |

000000013F921325 | 75 09 | jne crackme.13F921330 |

000000013F921327 | 45 8B D0 | mov r10d,r8d |

000000013F92132A | EB 21 | jmp crackme.13F92134D |

下面这段是检测注册码长度是否少于1

000000013F921330 | B8 67 66 66 66 | mov eax,66666667 |

000000013F921335 | 41 FF C2 | inc r10d |

000000013F921338 | F7 E9 | imul ecx |

000000013F92133A | 8B CA | mov ecx,edx |

000000013F92133C | C1 F9 02 | sar ecx,2 |

000000013F92133F | 8B C1 | mov eax,ecx |

000000013F921341 | C1 E8 1F | shr eax,1F |

000000013F921344 | 03 C8 | add ecx,eax |

000000013F921346 | 75 E8 | jne crackme.13F921330 |

000000013F921348 | 45 3B D0 | cmp r10d,r8d | 检测注册码长度要大于1

000000013F92134B | 7C 13 | jl crackme.13F921360 |

循环计算出r8的值 后面用来进行运算 这里r8=F4240 十进制是 1000000

000000013F92134D | 41 8B C2 | mov eax,r10d | 输入的长度

000000013F921350 | 47 8D 04 80 | lea r8d,dword ptr ds:[r8+r8*4] |

000000013F921354 | 45 03 C0 | add r8d,r8d |

000000013F921357 | 48 83 E8 01 | sub rax,1 |

000000013F92135B | 75 F3 | jne crackme.13F921350 |

--------------------------------------------------------------------------------------------------------------------------------------------------------------------

000000013F921360 | 41 FF C1 | inc r9d |

000000013F921363 | 41 8B C1 | mov eax,r9d |

000000013F921366 | 41 0F AF C1 | imul eax,r9d |

000000013F92136A | 99 | cdq |

000000013F92136B | 41 F7 F8 | idiv r8d |

000000013F92136E | 41 3B D3 | cmp edx,r11d | r11d等于输入的假码

000000013F921371 | 75 ED | jne crackme.13F921360 |

000000013F921373 | 41 8B C1 | mov eax,r9d |

000000013F921376 | C3 | ret |

这里就是计算出上面edi=A678 值的地方

用易语言是这么实现的

所以我们上面说到X=134就能得出正确的注册码,注意这里的134是十六进制,转换10进制是等于308

所以r9d=308时,eax=eax*eax 就是正确的注册码,计算得出注册码为:94864

文档和CM下载地址:http://www.vdisk.cn/down/index/19775196

原文地址:https://www.cnblogs.com/Sendige/p/9601045.html

时间: 2024-10-10 00:08:57

看雪CTF 2016_第八题分析的相关文章

看雪CTF 2016_第二十一题分析

高清文档及CM下载地址:http://url.cn/42VhonH 原文地址:https://www.cnblogs.com/Sendige/p/9604899.html

看雪CTF2016CrackMe攻防大赛——第一题

前言 暑假来了,不知道做些什么好,就拿看雪CTF的题来练习练习,学习下大佬们的操作.这是2016年CrackMe攻防赛的第一题,我就被难到了.本来都已经放弃了,但是幸得大佬分享,故跟随大佬的步伐粗略分析了下. 准备 系统:Windows 7 x64 ultimate 工具:IDA pro v7.0(最好用7.0,用6.8会有些问题) 分析 首先运行Crack_Me. 有一个密码输入框,一个OK按钮和一个计数框. 随便输入密码,获得失败提示,提示失败. 载入OD,先运行一下,可是却发现程序直接终止

看雪CTF第八题

vm_context 00000000 vm_context struc ; (sizeof=0x70, mappedto_32) 00000000 r0 dd ? 00000004 r1 dd ? 00000008 r2 dd ? 0000000C r3 dd ? 00000010 r4 dd ? 00000014 opcode dd ? 00000018 cmdA0 dd ? 0000001C fn_set_imm dd ? 00000020 cmdA1 dd ? 00000024 fn_x

OCJP(1Z0-851) 模拟题分析(八)

Exam : 1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam 以下分析全都是我自己分析或者参考网上的,定有疏漏,还请大家对我的分析提出质疑. QUESTION 235Given:5. class Payload {6. private int weight;7. public Payload (int w) { weight = w; }8. public void setWeight(int w) {

POJ1742 Coins(男人八题之一)

前言 大名鼎鼎的男人八题,终于见识了... 题面 http://poj.org/problem?id=1742 分析 § 1 多重背包 这很显然是一个完全背包问题,考虑转移方程: DP[i][j]表示用前i种硬币能否取到金额j,ture表示可以,false表示不行. 则有 DP[i][j] = DP[i - 1][j] | DP[i - 1][j - k * Ai], 0 ≤ k ≤ Ci, j - k * Ai ≥ 0 这是一个O(N3)的算法,考虑到数据范围1 ≤ N ≤ 100, M ≤

LCT男人八题系列

楼教的男人八题名气甚大,今天做了一道感觉还是涨了不少姿势的,然而估计之后的每道题都要看题解吧,姑且先记录一下.以后再做再更 1737 Connected Graph 1100 [email protected] 1738 An old Stone Game 407 [email protected] 1739 Tony's Tour 671 [email protected] 1740 A New Stone Game 2240 [email protected] 1741 Tree 1728

楼天城[男人必做八题]

六月了,离九校联考又近了一点. 之前的任务都结束地差不多了,下礼拜一听完课就要准备期末考了吧. 暑假里准备联赛去,在那之前先鏼一下loutiancheng男人必做八题 传送门:http://wenku.baidu.com/link?url=7BJZ9bqoGrBJoeeiFdQtQgx3bKwyurWrWBuH9UGKAJETJipFaAUsKW0qohnINsvXILOCq0NC4uTuOZfyRruMkHh_huDfnbCi5wvxdB91NW7 poj1742 背包 卡着常过的...惭愧

“金山杯2007逆向分析挑战赛”第一阶段第一题分析

题目来自于如下网址: http://www.pediy.com/kssd/ 第13篇 论坛活动 \ 金山杯2007逆向分析挑战赛 \ 第一阶段 \ 第一题 \ 题目 \ [第一阶段 第一题]: 现将此题目概述粘贴如下: CrackMe.exe 是一个简单的注册程序,见附件,请写一个注册机: 要求: 1. 注册机是KeyGen,不是内存注册机或文件Patch 2. 注册机可以使用ASM,VC,BC,VB,Delphi等语言书写,其他谢绝使用. 3. 注册机必须可以运行在Windows系统上. ..

经典算法题每日演练——第八题 AC自动机

原文:经典算法题每日演练--第八题 AC自动机 上一篇我们说了单模式匹配算法KMP,现在我们有需求了,我要检查一篇文章中是否有某些敏感词,这其实就是多模式匹配的问题. 当然你也可以用KMP算法求出,那么它的时间复杂度为O(c*(m+n)),c:为模式串的个数.m:为模式串的长度,n:为正文的长度,那 么这个复杂度就不再是线性了,我们学算法就是希望能把要解决的问题优化到极致,这不,AC自动机就派上用场了. 其实AC自动机就是Trie树的一个活用,活用点就是灌输了kmp的思想,从而再次把时间复杂度优