Reverse(二)
反汇编理论
编程语言
- 第一代语言:机器语言(字节码),机器语言程序常被称为二进制文件
- 第二代语言:汇编语言,脱离机器语言的表查找方式
- 第三代语言:引入了关键字和结构,表达能力更接近自然语言(C、java等)
反汇编
程序员使用编译器、汇编器和链接器中的一个或几个创建可执行程序,我们使用各种工具撤销汇编和编译过程就
反汇编困难
- 编译过程中造成损失
- 编译属于多对多操作:源程序通过不同方式转换成汇编语言,而机器语言也可经过许多不同方式转换成源程序
- 反汇编器非常依赖于语言和库
- 需近乎完美的反汇编能力
模糊测试
一种发现漏洞的技术,为程序生成大量不常见的输入,希望其中一个输入会在程序中造成可被检测、分析,最终可被利用的错误
1. re1
貌似画横线这两个输出是flag
右键在这些变量上可以直接查看16进制转字符后的结果,很方便
最开始一直在想法看aFlag和aFlagGet,找不着
网上看可以看出是输入的v7拿去和各种转换后的v5进行比较
v5经历了_mm_loadu_si128和m128i_i8的转换,最开始这个xmmword_413E34很可疑,双击进入
可以看到一串16进制,点中长16进制串按下R转成字符
转成字符后倒序拼接得到:DUTCTF{We1c0met0DUTCTF}
这题本来想用OD来做着,结果不太会用(lll¬ω¬)
2.game
不得不说这题真有意思,玩个小游戏,我直接做出来了,,ԾㅂԾ,, tip:12345678
游戏大意就是你选中一行它上面的和下面的一行若亮则灭,若灭则亮,要让所有都亮
直接IDA查看,拖到最下面看到判断部分
可以看出全部亮时,进入一个sub_457AB4()的函数,双击进入查看(其实有个偷懒方法就是改条件,改成下表34567的不等于1,直接就能跳出flag)但我还是有必要学下分析代码
再进入这个sub_45E940()函数
几乎可以确定这些数字转换后就是flag了
分析它!
int sub_45E940()
{
int i; // [esp+D0h] [ebp-94h]
char v2[22]; // [esp+DCh] [ebp-88h] BYREF
char v3[32]; // [esp+F2h] [ebp-72h] BYREF
char v4[4]; // [esp+112h] [ebp-52h] BYREF
char v5[64]; // [esp+120h] [ebp-44h]
sub_45A7BE("done!!! the flag is ");
v5[0] = 18; v5[1] = 64; v5[2] = 98; v5[3] = 5; v5[4] = 2; v5[5] = 4; v5[6] = 6;
v5[7] = 3; v5[8] = 6; v5[9] = 48; v5[10] = 49; v5[11] = 65; v5[12] = 32;
v5[13] = 12; v5[14] = 48; v5[15] = 65; v5[16] = 31; v5[17] = 78; v5[18] = 62;
v5[19] = 32; v5[20] = 49; v5[21] = 32; v5[22] = 1; v5[23] = 57; v5[24] = 96;
v5[25] = 3; v5[26] = 21; v5[27] = 9; v5[28] = 4; v5[29] = 62; v5[30] = 3;
v5[31] = 5; v5[32] = 4; v5[33] = 1; v5[34] = 2; v5[35] = 3; v5[36] = 44;
v5[37] = 65; v5[38] = 78; v5[39] = 32; v5[40] = 16; v5[41] = 97; v5[42] = 54;
v5[43] = 16; v5[44] = 44; v5[45] = 52; v5[46] = 32; v5[47] = 64; v5[48] = 89;
v5[49] = 45; v5[50] = 32; v5[51] = 65; v5[52] = 15; v5[53] = 34; v5[54] = 18;
v5[55] = 16; v5[56] = 0;
qmemcpy(v2, "{ ", 2);
v2[2] = 18; v2[3] = 98; v2[4] = 119; v2[5] = 108; v2[6] = 65; v2[7] = 41;
v2[8] = 124; v2[9] = 80; v2[10] = 125; v2[11] = 38; v2[12] = 124; v2[13] = 111;
v2[14] = 74; v2[15] = 49; v2[16] = 83; v2[17] = 108; v2[18] = 94; v2[19] = 108;
v2[20] = 84; v2[21] = 6;
qmemcpy(v3, "`S,yhn _uec{", 12);
v3[12] = 127; v3[13] = 119; v3[14] = 96; v3[15] = 48; v3[16] = 107; v3[17] = 71;
v3[18] = 92; v3[19] = 29; v3[20] = 81; v3[21] = 107; v3[22] = 90; v3[23] = 85;
v3[24] = 64; v3[25] = 12; v3[26] = 43; v3[27] = 76; v3[28] = 86; v3[29] = 13;
v3[30] = 114; v3[31] = 1;
strcpy(v4, "u~");
for ( i = 0; i < 56; ++i )
{
v2[i] ^= v5[i];
v2[i] ^= 0x13u;
}
return sub_45A7BE("%s\n");
}
貌似v3数组没啥用,只看v2和v5 更正:v2(22个)+v3(32个)+2个(u~)和v1(56个)比较
v2和v5循环遍历相互异或,v2再和16进制的0x13即19异或
提取数据好麻烦啊
python实现上面伪代码作用
v5 = [18, 64, 98, 5, 2, 4, 6, 3, 6, 48, 49, 65, 32, 12, 48, 65, 31, 78, 62, 32, 49, 32, 1, 57, 96, 3, 21, 9, 4, 62, 3,
5, 4, 1, 2, 3, 44, 65, 78, 32, 16, 97, 54, 16, 44, 52, 32, 64, 89, 45, 32, 65, 15, 34, 18, 16, 0]
v2 = [123, 32, 18, 98, 119, 108, 65, 41, 124, 80, 125, 38, 124, 111, 74, 49, 83, 108, 94, 108, 84, 6, 96, 83, 44, 121,
104, 110, 32, 95, 117, 101, 99, 123, 127, 119, 96, 48, 107, 71, 92, 29, 81, 107, 90, 85, 64, 12, 43, 76, 86, 13,
114, 1, 117, 126, 0]
for i in range(56):
v2[i] ^= v5[i]
v2[i] ^= 19
flag = ""
for i in v2:
flag += chr(i)
print(flag)
得到:zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}
学习总结
IDA使用
shift+F12可以查看字符串,alt+T查找指定字符串