1.解题过程:
解压得到 rev300 文件,使用 32 位打开留意一下类型,发现又是 elf 类型的执行文件
使用Linux打开执行,拒绝访问
用 IDA 找到 main 函数反编译看看有什么东西
看到整体就只有一个 if 和 else 语句,可以看到 if 真时 put 的语句翻译为:允许访问
而 if 假时 put 的语句翻译为:拒绝访问,所以明确目标
使 if 为真的条件:a1>0,且 子函数 sub_8048414 返回值为真
并且 sub_8048414 传入了两个实参,对应的 (_BYTE *a1, int a2)
所以在函数 sub_8048414 内,*a1=a2[1],a2=0
查看子函数 sub_8048538
int __cdecl sub_8048538(int a1)
{
int v2[33]; // [esp+18h] [ebp-A0h]
int i; // [esp+9Ch] [ebp-1Ch]
qmemcpy(v2, &unk_8048760, sizeof(v2));
for ( i = 0; i <= 32; ++i )
putchar(v2[i] ^ *(char *)(a1 + i % 8));
return putchar(10);
}
这里的 qmemcpy 应该为 memcpy,v2 为 33 个元素的一维数组,同时我们可以从 (a1 + i % 8) 知道是随 i 增加历遍 a1,所以 a1 也应该为一维数组 0-8 八个元素,历遍四次,每个元素与 v2 的每一个元素异或并输出,所以此处输出的应该为 flag
查看 unk_8048760 并没有直接给我们,只能硬读,一个整型的元素占四个字节
.rodata:08048760 unk_8048760 db 0Fh ; DATA XREF: sub_8048538+12↑o .rodata:08048761 db 0 .rodata:08048762 db 0 .rodata:08048763 db 0 .rodata:08048764 db 1Fh .rodata:08048765 db 0 .rodata:08048766 db 0 .rodata:08048767 db 0 .rodata:08048768 db 4 .rodata:08048769 db 0 .rodata:0804876A db 0 .rodata:0804876B db 0 .rodata:0804876C db 9 .rodata:0804876D db 0 .rodata:0804876E db 0 .rodata:0804876F db 0 .rodata:08048770 db 1Ch .rodata:08048771 db 0 .rodata:08048772 db 0 .rodata:08048773 db 0 .rodata:08048774 db 12h .rodata:08048775 db 0 .rodata:08048776 db 0 .rodata:08048777 db 0 .rodata:08048778 db 42h ; B .rodata:08048779 db 0 .rodata:0804877A db 0 .rodata:0804877B db 0 .rodata:0804877C db 9 .rodata:0804877D db 0 .rodata:0804877E db 0 .rodata:0804877F db 0 .rodata:08048780 db 0Ch .rodata:08048781 db 0 .rodata:08048782 db 0 .rodata:08048783 db 0 .rodata:08048784 db 44h ; D .rodata:08048785 db 0 .rodata:08048786 db 0 .rodata:08048787 db 0 .rodata:08048788 db 0Dh .rodata:08048789 db 0 .rodata:0804878A db 0 .rodata:0804878B db 0 .rodata:0804878C db 7 .rodata:0804878D db 0 .rodata:0804878E db 0 .rodata:0804878F db 0 .rodata:08048790 db 9 .rodata:08048791 db 0 .rodata:08048792 db 0 .rodata:08048793 db 0 .rodata:08048794 db 6 .rodata:08048795 db 0 .rodata:08048796 db 0 .rodata:08048797 db 0 .rodata:08048798 db 2Dh ; - .rodata:08048799 db 0 .rodata:0804879A db 0 .rodata:0804879B db 0 .rodata:0804879C db 37h ; 7 .rodata:0804879D db 0 .rodata:0804879E db 0 .rodata:0804879F db 0 .rodata:080487A0 db 59h ; Y .rodata:080487A1 db 0 .rodata:080487A2 db 0 .rodata:080487A3 db 0 .rodata:080487A4 db 1Eh .rodata:080487A5 db 0 .rodata:080487A6 db 0 .rodata:080487A7 db 0 .rodata:080487A8 db 0 .rodata:080487A9 db 0 .rodata:080487AA db 0 .rodata:080487AB db 0 .rodata:080487AC db 59h ; Y .rodata:080487AD db 0 .rodata:080487AE db 0 .rodata:080487AF db 0 .rodata:080487B0 db 0Fh .rodata:080487B1 db 0 .rodata:080487B2 db 0 .rodata:080487B3 db 0 .rodata:080487B4 db 8 .rodata:080487B5 db 0 .rodata:080487B6 db 0 .rodata:080487B7 db 0 .rodata:080487B8 db 1Ch .rodata:080487B9 db 0 .rodata:080487BA db 0 .rodata:080487BB db 0 .rodata:080487BC db 23h ; # .rodata:080487BD db 0 .rodata:080487BE db 0 .rodata:080487BF db 0 .rodata:080487C0 db 36h ; 6 .rodata:080487C1 db 0 .rodata:080487C2 db 0 .rodata:080487C3 db 0 .rodata:080487C4 db 7 .rodata:080487C5 db 0 .rodata:080487C6 db 0 .rodata:080487C7 db 0 .rodata:080487C8 db 55h ; U .rodata:080487C9 db 0 .rodata:080487CA db 0 .rodata:080487CB db 0 .rodata:080487CC db 2 .rodata:080487CD db 0 .rodata:080487CE db 0 .rodata:080487CF db 0 .rodata:080487D0 db 0Ch .rodata:080487D1 db 0 .rodata:080487D2 db 0 .rodata:080487D3 db 0 .rodata:080487D4 db 8 .rodata:080487D5 db 0 .rodata:080487D6 db 0 .rodata:080487D7 db 0 .rodata:080487D8 db 41h ; A .rodata:080487D9 db 0 .rodata:080487DA db 0 .rodata:080487DB db 0 .rodata:080487DC db 0Ah .rodata:080487DD db 0 .rodata:080487DE db 0 .rodata:080487DF db 0 .rodata:080487E0 db 14h .rodata:080487E1 db 0 .rodata:080487E2 db 0 .rodata:080487E3 db 0
读完得到 unk_8048760 即得到数组 v2 的内容,现在缺少 a1
v2[33]={0x0F,0x1F,0x04,0x09,0x1C,0x12,0x42,0x09,0x0C,0x44,0x0D,0x07,0x09,0x06,0x2D,0x37,0x59,0x1E,0x00,0x59,0x0F,0x08,0x1C,0x23,0x36,0x07,0x55,0x02,0x0C,0x08,0x41,0x0A,0x14}
查看子函数 sub_8048414
发现了 a1,分析代码,当 if 为真,跳转 LABEL_19 ,接着对照代码继续分析
signed int __cdecl sub_8048414(_BYTE *a1, int a2)
{
signed int result; // eax
switch ( a2 )
{
case 0:
if ( *a1 == 105 )
goto LABEL_19;
result = 0;
break;
case 1:
if ( *a1 == 101 )
goto LABEL_19;
result = 0;
break;
case 3:
if ( *a1 == 110 )
goto LABEL_19;
result = 0;
break;
case 4:
if ( *a1 == 100 )
goto LABEL_19;
result = 0;
break;
case 5:
if ( *a1 == 97 )
goto LABEL_19;
result = 0;
break;
case 6:
if ( *a1 == 103 )
goto LABEL_19;
result = 0;
break;
case 7:
if ( *a1 == 115 )
goto LABEL_19;
result = 0;
break;
case 9:
if ( *a1 == 114 )
LABEL_19:
result = sub_8048414(a1 + 1, 7 * (a2 + 1) % 11);
else
result = 0;
break;
default:
result = 1;
break;
}
return result;
}
在最后面的 LABEL_19 中可以看到,每次判断后都会将 *a1 = a1+1,a2 = 7 * (a2 + 1 % 11)
所以我们最后得到了一维数组 a1[8] = {105,115,101,110,103,97,114,100}
最后写 python 脚本将输出语句的 flag 跑出来
注意:python 中的数组表示不需要下标,元素使用 " [ ] " 而不是 “ { } ”
2.知识点:
(1)本题IDA中的涉及主要的假名字:
unk_ 未处理字节
IDA调试技巧(妥妥的干货分享) - 简书 (jianshu.com)
(2)涉及的 c 库函数:(v2[33])
memcpy(v2, &unk_8048760, sizeof(v2))
作用:从 unk_8048760 储存中复制33个字节到 v2 中
(3)0x是16进制的前缀,h是16进制的后缀



