逆向
将exe文件放入ida之中运行,然后使用f5将其转换成类似c语言的形式,在使用R键将那些串转换成字符,再按照strcmp指示,得出flag。
将文件按照txt格式打开,可得到汇编代码。
注释加的可能有些错误
进行题目的时候汇编了解不多,也没有将这些东西重新变回所执行的操作,只是简单的类似翻译英文时直接按照字典的方法,把一个一个单词翻译成汉语。但没有理解其中所表达的意思。
附注:十六进制转换表
那么转换思想把其转换成c语言的代码,两者结合去理解这些汇编语言。
之后,再次进行解题
1,第一次发现在其中有0x1c的数,正好对应input数组中所有的元素个数,说明应该是对数组中所有数操作。
2,之后在后方有一个jle<28的判断说明确实按照此操作进行,当>28时执行结束
(其中 rdx——rax
edx——rcx
rcx——rdx 作为累加)
3 ,之后判断操作是什么,其中有xor,该指令是异或操作
4,因为只能看懂这些,但具体如何落实到每一个数组中的元素便要继续更细致解读
5,结合c语言传入形参数组时的操作进行(因为不太明白汇编的进程)
6,那么按照c语言的形式,其中func函数传入两个形参input[28],另外一个为28
7,第一行是进栈
8,三四两句便是存入两个参数
9,其它按照注释进行,那么意思便是将一个数和当前位置进行异或运算
10,但不明白异或运算进行时应该是否转换成二进制在进行
11,在判断时,我看成是把当前元素和前面的元素进行异或运算,但发现结果实在是出乎意料
12,继续钻空子,因为这是ctf题目,提交的时候我可以确定前面五个和最后一个应该是什么,flag{}
13,那么我便把这些按照表中的字符一 一对应,找到应该是那些数字
14,找到规律,通过这种方式,找到func()函数是怎么进行的
15,先是用c语言尝试出结果但因为dev编译器上的异或运算似乎有错误,便没有继续进行
16,在之后看了一点python
17,得到flag
下方附上这道题用上的东西:
1.movsxd 指令为扩展至零
将32位的寄存器和内存操作数符号扩展到64位的寄存器
2.逻辑异或运算指令 XOR
XOR OPRD1,OPRD2
实现两个操作数按位‘异或’(异为真,相同为假)运算,结果送至目的操作数中.
OPRD1<--OPRD1 XOR OPRD2
3.JLE
小于等于时转移
- rdx——rax
edx——rcx
rcx——rdx 作为累加
input = [0x67,0x6e,0x62,0x63,0x7e,0x74, 0x62, 0x69, 0x6d, 0x55, 0x6a, 0x7f, 0x60, 0x51, 0x66, 0x63, 0x4e, 0x66, 0x7b,0x71, 0x4a, 0x74, 0x76, 0x6b, 0x70, 0x79, 0x66 , 0x1c]
十进制为:input={0,103,110,98,99,126,116,98,105,109,85,106,127,96,81,102,99,78,102,123,113,74,116,118,107,112,121,102};
c语言解出:
include<stdio.h>
int main()
{
int i,j=1;
int a;
int input[28]={0,103,110,98,99,126,116,98,105,109,85,106,127,96,81,102,99,78,102,123,113,74,116,118,107,112,121,102};
for(i=1;i<28;i++)
{
a=input[i]^i;
printf("%c",a);
}
return 0;
}
1, qword 八个字节
2,dword 四个字节
脚本跑出flag:
https://c.runoob.com/compile/6
python:
a = [0x67,0x6e,0x62,0x63,0x7e,0x74, 0x62, 0x69, 0x6d, 0x55, 0x6a, 0x7f, 0x60, 0x51, 0x66, 0x63, 0x4e, 0x66, 0x7b,0x71, 0x4a, 0x74, 0x76, 0x6b, 0x70, 0x79, 0x66 , 0x1c]
b = ""
for x in range(1,29):
b=b+chr(a[x-1] ^ x)
print b
flag{read_asm_is_the_basic}
总结:
1,在关键位置判断失误,看成了和前面的元素进行异或运算
2,在用c语言运行的时候,没有发现错误,英语不好,没发现用的是八进制
3,把所有的东西转换成自己知道的