之前文章讲过的技巧和知识,就不再详细描述了,如果有不明白的地方建议按照做题题目顺序查看。
打开关键代码页面,要成功运行到success函数,需要避开方框内的雷,sub_4007C0是失败函数

来看看我们输入的v3怎么才可以得到flag
一、长度等于v8,变量v8的长度是17

二、s[i] = (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i])
写出解密代码,但是为什么是乱码不该是flag吗

回到图1,重新分析代码,看有没有看错什么,以下是伪代码 v7 = 'ebmarah';的汇编代码,可以看出从ds段拿出数据装给rax寄存器,然后再放到rbp+var_28这个地方开始的堆栈里。qword_4008D0是rax的数据dq按R转换成‘ebmarah’,虽然放入堆栈是整个rax一起放进去,但是从堆栈里面取出来却是按byte取出见图5。
在计算机里数据是按照小端存储所以‘ebmarah’实际放到计算机里的样子是图6那样的,所以如果从堆栈里面byte一个一个取出会是和存入时的相反顺序。



伪指令db、dw、dd、dq都可以定义字符串,但最多的是用db来定义字符串,第一个原因是dw、dd定义的字符串到了内存中排序是相反的
在字符串'abcd'中,元素按从高位向低位线性排序。在内存中,数据由低位向高位线性排序,因此字符串'abcd'在内存中的顺序是从低位向高位排序的,所以相反。
第二个原因是不同版本编译器对dw与dd定义字符串的指令格式支持不一样。
db定义字节类型变量,一个字节数据占1个字节单元,读完一个,偏移量加1
dw定义字类型变量,一个字数据占2个字节单元,读完一个,偏移量加2
dd定义双字类型变量,一个双字数据占4个字节单元,读完一个,偏移量加4
dq定义四字类型变量,一个四字数据占8个字节单元,读完一个,偏移量加8
可能你会问为什么‘ebmarah’字符串下面的'Welcome to the RC3 secure password guesser.'却没有全部反着存储呢,这是因为变量的长度定义的不一样,dq代表四字,db是一字节,所以当然按顺序一个一个存储。


将‘ebmarah’的顺序倒过来重新写代码,这道题在字符串存储上挖坑给大家跳~~~