首先把程序放进IDA分析,找到真正的main,反编译代码如下:
注意到有一个写死的byte数组:
首先使用IDC脚本,拿到byte_100001040:
auto i; for(i = 0; i < 57; i++){Message("0x%x,",byte(0x100001040 + i));}
注意第七行,是start和sub两个函数的地址差值,到汇编代码中寻找地址,发现二者分别为0x100000CB0和0x100000C90,继续向下分析,看一下result赋值的那个函数:
注意23、25行,23行实际上result仍然为0,因为v4=0,25行意味着result在0、1之中取一个值。
返回去看main,发现result必须为0,否则下面的逻辑就不能执行了,现在根据得到的信息,我们可以根据main自己写一个程序拿flag了:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int b[57] ={0x41,0x10,0x11,0x11,0x1b,0xa,0x64,0x67,0x6a,0x68,0x62,0x68,0x6e,0x67,0x68,0x6b,0x62,0x3d,0x65,
0x6a,0x6a,0x3d,0x68,0x4,0x5,0x8,0x3,0x2,0x2,0x55,0x8,0x5d,0x61,0x55,0xa,0x5f,0xd,0x5d,0x61,0x32,0x17,0x1d,0x19,0x1f,
0x18,0x20,0x4,0x2,0x12,0x16,0x1e,0x54,0x20,0x13,0x14,0x0,0x0};
int sub_100000CE0()
{
int result;// eax
signed intv1; // [rsp+1Ch] [rbp-14h]
int v2; //[rsp+24h] [rbp-Ch]
v2 =((unsigned __int64)(0x100000CB0 - 0x100000C90) >> 2) ^ b[0];
printf("%d\n", v2);
result = 0;
if (!(result & 1) )
{
v1 = 0;
while (v1 < 55 )
{
b[v1]-= 2;
b[v1]^= v2;
++v1;
++v2;
}
for(int i= 1; i < 57; i++) {
printf("%c", b[i]);
}
}
return result;
}
int main() {
int a =sub_100000CE0();
return 0;
}