-
-
[原创]看雪 2016 CTF 第六题 Solution
-
发表于: 2016-11-14 11:31 2444
-
结果性描述: 加载,断 00401910,输入key确认,断下,堆栈里就有注册码 33053055C3055C2E3030553055C2
易语言,N年前听说它的时候玩体验过一下,那时候还是在校学生,到如今仅局限于知道有这个一个存在。
(整体的感觉是,真难为吴涛了)
样本802KB,实际是静态链接了 krnln.fnr 库的原因。
出于事后试验对比,尝试用易语言(临时下载搭建其环境)编译一个只带一个按钮的窗体,
消息响应只显示一个弹框[信息框("TestButton",0,"Tips",0)]的情形下。
动态编译的结果是 8K,没错就是8K,其执行需要携带 1.256M 大小的支持库 krnln.fnr
而静态链接时676K,可独立执行
事后对比,料想原易程序正如作者所言,几分钟整出来的,也极其简单。
动态编译的启动过程如下,与破解无关,后面把数据地址直接传给了支持库加载执行。
start{
retcode = boot_run();
ExitProcess(retcode);
}
boot_run{
funpoit = "krnln.fnr".GetnewSock(0x3E8);
funpoit(&hMoudle.data)
}
----------------------------------------------
静态编译许多及时支持库的加载处理过程,由于消息机制被封装了,不熟悉的情况下,
短时间只能做有效的摸索,这要碰到大型复杂的,还需要理清易语言的消息封装分发机制。
GetWindowTextA 断下来再往后就跟丢了,其属于统一封装的api之一。没辙,
在断GetWindowTextA获取key后,后续断了 strlen api,直到其输入参数是key,
然后以内存断点断访问key的位置,进行逐步跟进,最终在 00401910 断下,
这里简单进行key的简单比对,于是就出来了(其调用栈实时数据如下面所列)。
(后面是Win10,程序基地址不如愿加载到400000的实例情形)
需要在基址0x950000,0x400000之间做些变换做参考
.text:00401910 8B 02 mov eax, [edx]
.text:00401912 3A 01 cmp al, [ecx]
.text:00401914 75 2B jnz short loc_401941
.text:00401916 0A C0 or al, al
.text:00401918 74 24 jz short loc_40193E
00951910 |> 8B02 /MOV EAX,DWORD PTR DS:[EDX]
00951912 |. 3A01 |CMP AL,BYTE PTR DS:[ECX]
00951914 |. 75 2B |JNZ SHORT CrackMe.00951941
00951916 |. 0AC0 |OR AL,AL
00951918 |. 74 24 |JE SHORT CrackMe.0095193E
在00951910 即 00401910 处断下的堆栈数据
0378FB48 009521BD RETURN to CrackMe.009521BD from CrackMe.009518E2
0378FB4C 01319010 ASCII "123456789a"
0378FB50 013166D0 ASCII "33053055C3055C2E3030553055C2"
0378FB54 01318FD0 ASCII "3055c2e4eb28af4cd195a2c4bc88ec04"
0378FB58 01316DF8 ASCII "3055c2e4eb28af4cd195a2c4bc88ec04112"
易语言,N年前听说它的时候玩体验过一下,那时候还是在校学生,到如今仅局限于知道有这个一个存在。
(整体的感觉是,真难为吴涛了)
样本802KB,实际是静态链接了 krnln.fnr 库的原因。
出于事后试验对比,尝试用易语言(临时下载搭建其环境)编译一个只带一个按钮的窗体,
消息响应只显示一个弹框[信息框("TestButton",0,"Tips",0)]的情形下。
动态编译的结果是 8K,没错就是8K,其执行需要携带 1.256M 大小的支持库 krnln.fnr
而静态链接时676K,可独立执行
事后对比,料想原易程序正如作者所言,几分钟整出来的,也极其简单。
动态编译的启动过程如下,与破解无关,后面把数据地址直接传给了支持库加载执行。
start{
retcode = boot_run();
ExitProcess(retcode);
}
boot_run{
funpoit = "krnln.fnr".GetnewSock(0x3E8);
funpoit(&hMoudle.data)
}
----------------------------------------------
静态编译许多及时支持库的加载处理过程,由于消息机制被封装了,不熟悉的情况下,
短时间只能做有效的摸索,这要碰到大型复杂的,还需要理清易语言的消息封装分发机制。
GetWindowTextA 断下来再往后就跟丢了,其属于统一封装的api之一。没辙,
在断GetWindowTextA获取key后,后续断了 strlen api,直到其输入参数是key,
然后以内存断点断访问key的位置,进行逐步跟进,最终在 00401910 断下,
这里简单进行key的简单比对,于是就出来了(其调用栈实时数据如下面所列)。
(后面是Win10,程序基地址不如愿加载到400000的实例情形)
需要在基址0x950000,0x400000之间做些变换做参考
.text:00401910 8B 02 mov eax, [edx]
.text:00401912 3A 01 cmp al, [ecx]
.text:00401914 75 2B jnz short loc_401941
.text:00401916 0A C0 or al, al
.text:00401918 74 24 jz short loc_40193E
00951910 |> 8B02 /MOV EAX,DWORD PTR DS:[EDX]
00951912 |. 3A01 |CMP AL,BYTE PTR DS:[ECX]
00951914 |. 75 2B |JNZ SHORT CrackMe.00951941
00951916 |. 0AC0 |OR AL,AL
00951918 |. 74 24 |JE SHORT CrackMe.0095193E
在00951910 即 00401910 处断下的堆栈数据
0378FB48 009521BD RETURN to CrackMe.009521BD from CrackMe.009518E2
0378FB4C 01319010 ASCII "123456789a"
0378FB50 013166D0 ASCII "33053055C3055C2E3030553055C2"
0378FB54 01318FD0 ASCII "3055c2e4eb28af4cd195a2c4bc88ec04"
0378FB58 01316DF8 ASCII "3055c2e4eb28af4cd195a2c4bc88ec04112"
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
- [原创] KCTF 2022 Win. 第六题 约束与伪随机 6745
- [原创] KCTF 2021 Win. 第二题 排排坐 21175
- [原创] KCTF 2021 Win. 第一题 算力与攻击模式 4118
- 鸿蒙通识 26032
- [原创] KCTF 2021 Spr. 第二题 未选择的路 9250
看原图
赞赏
雪币:
留言: