【攻防世界】logmein
收获
熟悉大端序、小端序存放方式
找一下如果 IDA 反编译出的伪代码有问题时,有没有好的解决办法
思路
将得到的 64位 elf 文件拖入 IDA
逻辑很简单,sub_4007C0()
函数用来提示输入错误并结束程序,执行 sub_4007F0()
就代表破解成功
而通过
if ( v3 < strlen(v8) )
sub_4007C0();
和
if ( i >= strlen(v8) )
sub_4007C0();
并且循环条件 i 的范围是 for ( i = 0; i < strlen(s); ++i )
可以推断输入的字符串 s 的长度 strlen(s) = strlen(v8) = 17
因此只需满足 s[i] == (char)(v8[i % v6 - 8] ^ v8[i]) 的 s[i]
组成的就是 flag
但是这里想半天也没有搞明白 v8[i % v6 - 8]
是个什么写法,第一次循环的时候 i = 0
,岂不是 v8[ -8 ]
?
后来看网上的 writeup,发现别人反汇编出来的伪代码跟我不一样 … …
虽然做题的时候也遇到过好几次这样的情况,但是也找不到好的解决办法
别人的伪代码:这里的条件是:
s[i] == (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i]) )
注意这里 v7
的定义:
__int64 v7;
v7 = 0x65 62 6D 61 72 61 68LL;
v7 的类型为 int64,即 64位 整型,属于 dq 类型的数据,存放时采用 小端序
所以 v7
的首地址处存的是 0x68,以此类推:
*((_BYTE *)&v7 + 0 % v6) = 0x68
*((_BYTE *)&v7 + 1 % v6) = 0x61
*((_BYTE *)&v7 + 2 % v6) = 0x72
*((_BYTE *)&v7 + 3 % v6) = 0x61
*((_BYTE *)&v7 + 4 % v6) = 0x6D
*((_BYTE *)&v7 + 5 % v6) = 0x62
*((_BYTE *)&v7 + 6 % v6) = 0x65
根据 (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i]) )
,求解出 s[i]
并输出,得到 flag
脚本
#include <iostream>
#include <string.h>
using namespace std;
int main() {
string v8 = ":\"AL_RT^L*.?+6/46";
__int64 v7 = 0x65626D61726168LL;
int key[] = {0x68,0x61,0x72,0x61,0x6d,0x62,0x65};
int v9 = 0,v6 = 7;
string flag = "";
for (int i = 0; i < v8.length(); ++i )
{
flag += (char)(key[i % v6] ^ v8[i]);
}
cout<<flag;
return 0;
}
结果
RC3-2016-XORISGUD
评论