因为沙老师的题目。。。
//详情看上一篇blog
怎么说呢。。。写那题的时候我还在想为什么ida pro那么nb的工具会出现反编译错误这种低级问题
害得我看汇编
而且调试的时候也发现,汇编有点奇怪。。。
有时候几步一走,有些指令都没跑。
这篇blog我来说下对于32位程序中调用了64位的学习
32-64之初体验
一开始我还不知道有这种骚操作
先看一下程序吧
题目是护网杯的
一眼过去啥也没有
查找字符串也只有俩sorry
运行一下程序看看
看到这就能猜到是smc了
下好断点开始单步调试
可以看到字符串是加密的,程序运行是对其解密
那段数据其实就是input_code
程序停在了输入段
可以看到下面就有个长度验证//猜测
大于18
看看下面的check
稍微看一下
//因为我是在中午休息的时候写这题的,只有20分钟时间写,然后就要去上课了。
其实不难啊
和hgame的很像
//太天真了,那时候我还没意识到什么32调用64
先看看check1
很简单,输入的前6个与0x22异或后再与上面的数据对比
解一下可以看到前6个字符是hwbctf
然后看看check2
不需多说
它还透露出俩个花括号内有11个字符
说明我们输入的字符数应该是19
看看最后一个check
问题就出在这
仔细看,其实只有10个被check了
难不成还有一个字符是随便输入?
和tamuctf的一样???
那这出题人也太没水平了吧//打死
照着反编译代码用z3写一下
显示unsat
我透???
难不成又要我手解???
初步看一下应该可以手解,但是有明显的矛盾
看看这三句
1 | ((unsigned __int8)(*(a1 - 1) ^ *(a1 - 1) ^ a1[1]) != 54) |
可以定出来a1[1],但是俩次解出来都是不一样
说明有问题
没办法
调试看汇编
问题马上就出来了
反编译出错了
其实应该是验证11个的
我们输入hwbctf{0123456789a}
这样更有利于定位check的下标
这些movzx eax, byte ptr [eax]
重点关注下
可以看到对应的下标
然后发现是反编译出错了
。。。
重新些脚本
1 | # -*- coding: UTF-8 -*- |
所以输入应该是hwbctf{1’m n0t 4n5}
感觉挺有趣的,因为好奇特别想知道这题是怎么出的?
他在考我们什么?
比较懵逼
然后问了下老师
据说是32位和64位的切换,那时候没注意哪来的64位
只是以为要看汇编
哎。。。。。。。。。
正巧又看到了一篇不错的文章也讲到了这题
//貌似还很新哟,最近的文章。
好了。
学习 start!!!
Let’s 深入32-64
首先讲的是区别,32位与64位的主要区别就在于cs
一个是0x23一个是0x33
但如何判断程序是否调用了64位呢?
文章中作者也写到了
靠的就是那个retf
retf吧栈中的0x33给了cs,由此来调用64位
我们可以看到有retf
还有0x33
说明下面就是开始64位了
调试的话也能发现程序有时候是几步一走的
那如何调试???
用gdbserver
//忽视我的背景
//才不是色图呢
然后照着文章写的去做
就ok啦
静态分析的话可以用py来dump
1 | import idaapi |
也可以用作者的idc脚本
1 | static main(void) |
然后放ida64里
这边就没有反编译错误了
小试牛刀
文章中附赠了资源,其中有win的题目
我来试一下吧
然后很成功的没写出来。。。
40min。。。
还是看作者的wp吧。。。
dump出来后看到很多什么memory就很懵逼
看完wp后发现这题果然超出我的认知范围了。。。
没办法
那就TODO吧