查壳
ELF文件,无壳
IDA
逻辑很简单,判断输入的字符串长度是否为14,然后是judge(s)的函数判断,都正确则输出right
那么重点就是judge函数。双击进入,发现是长度为181的字符串,将其ASCⅡ提取出来后转字符串,发现毫无意义。
然后……只能看看别人的wp看看咋回事(#_<-)>)
这题是SMC,judge函数在运行时会进行自解密操作,否则静态分析时无法窥探其真正内容。
SMC虽然还没整太明白,但是可以动调试试。既然静态分析他不肯露面,那么动态分析它说不定会自己一层一层剥给我看_(:з」∠)_
解题
在伪函数的judge那行下断点。开始动调,flag输入瞎输入14个字符。看到call judge F7步进跟入
好家伙,和之前的181个字符串截然不同,有点函数的样子了。
步步跟踪到jmp跳转,这里有个和 0x0D(13)的比较,若不等于13则跳转到另一处地址。之前知道了14是输入字符串的长度,而[rbp-4]初始赋值是0,那么[rbp-4]就是字符串下标
进入jle跳转,走一步,用鼠标放到寄存器上看值得变化:发现B4F处的[rbp-28h]存储着我们输入的asdfasdfasdfas。继续往下走,有个异或操作,上下结合分析有:
600B49处函数作用:14位字符串挨个与自己的字符串下标异或
Tips:MOVSX说明:带符号扩展传送指令
符号扩展的意思是,当计算机存储某一个有符号数时,
符号位位于该数的第一位.
所以,当扩展一个负数的时候需要将扩展的高位全赋为1.
对于正数而言,符号扩展和零扩展MOVZX是一样的,将扩展的高位全赋为0.
另:其中80H的高位是1
14次异或结束后函数来到loc_600B80函数:
600B86将异或处理的字符串赋值给rax;
在600B95处,将judge开始时的字符串载入到eax中
Tips:CDQE复制EAX寄存器双字的符号位(bit 31)到RAX的高32位
接着往下走,发现对比了dl和al。dl观察发现,dl是异或数组第一位,al是自带数组第一位
基表后,将根据结果进行跳转,最后输出right/wrong
EXP
由于字符串第五位是DEL删除键,无法表示,用a顶替,后续单独异或
decode='fmcdak7d;V`;np'
i=0
for flag in decode:
if(i==4):
print(chr(0x7F^i),end='')
i+=1
continue
flag=chr(ord(flag)^i)
print(flag,end='')
i+=1
flag
flag{n1c3_j0b}
坑
1.judge有值,但是放回题目这181个值用不上……
看wp说是judge有隐藏函数,以后再看……
这里是SMC自解,不过这次直接动调出来了,还没来得及学写IDC脚本解judge自加密(っ °Д °;)っ 那就……再套一个坑,改天填填
2.[rbp-28]为何是输入字符串
8说了,写EXP才发现是自己眼瞎了……
3.最后al和dl进行比较的时候,是比较两个的第一位还是全部比较
尝试输入 flageeeeeeeeee,发现这里也是个循环……也有下标+1和下标是否14的循环判断。
4.al和dl是rax和rdx的低8位,为什么要去字符串地址的低8位来取得字符串的第一个字符?
闹乌龙了,之前的movzx传的是取值,不是地址……所以cmp al,dl 对比的就是第一个存入的值……一个寄存器依旧只能存值,要么地址,要么字符串。