re-BABYRE-攻防世界
有关花指令和异或加密
第一步查壳

可以看出是ELF文件,拖进IDA里面看一下,shift+F12查看字符串,双击“Please input flag:”或者“Right!"跳转到反汇编窗口

进入mian函数并F5查看伪代码
点击查看代码
int __fastcall main(int argc, const char **argv, const char **envp)
{
char s[24]; // [rsp+0h] [rbp-20h] BYREF
int v5; // [rsp+18h] [rbp-8h]
int i; // [rsp+1Ch] [rbp-4h]
for ( i = 0; i <= 181; ++i )
judge[i] ^= 0xCu;
printf("Please input flag:");
__isoc99_scanf("%20s", s);
v5 = strlen(s);
if ( v5 == 14 && (*(unsigned int (__fastcall **)(char *))judge)(s) )
puts("Right!");
else
puts("Wrong!");
return 0;
}
代码中有个花指令:*(unsigned int (__fastcall **)(char *))judge)(input)
意思是:调用函数指针judge指向的函数,并传递回参数input,传递的值为unsigned int 类型,
为什么是花指令:因为judge在加密前为数组,加密后通过花指令被作为函数指针调用
现在双击judge跳转至数据界面

这一串是被异或加密的数据,现在进行解密,使用IDA python:
点击查看代码
import idc
s = 0x600B00
for i in range(182):
idc.patch_byte(s+i,idc.get_bytes(s+i,1)[0]^0xc)
此时复选judge数据段,按下c(汇编),在复选按下P(function),此时在函数窗口会生成judge,双击进入并F5查看伪代码
点击查看代码
__int64 __fastcall judge(__int64 a1)
{
char v2[5]; // [rsp+8h] [rbp-20h] BYREF
char v3[9]; // [rsp+Dh] [rbp-1Bh] BYREF
int i; // [rsp+24h] [rbp-4h]
qmemcpy(v2, "fmcd", 4);
v2[4] = 127;
qmemcpy(v3, "k7d;V`;np", sizeof(v3));
for ( i = 0; i <= 13; ++i )
*(_BYTE *)(i + a1) ^= i;
for ( i = 0; i <= 13; ++i )
{
if ( *(_BYTE *)(i + a1) != v2[i] )
return 0LL;
}
return 1LL;
}
解密,
点击查看代码
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char v2[5];
char v3[9];
char flag[15] = {0};
// 初始化相同的密钥数组
memcpy(v2, "fmcd", 4);
v2[4] = 127;
memcpy(v3, "k7d;V`;np", sizeof(v3));
// 将v2和v3合并成一个14字节的数组
char encrypted[15];
memcpy(encrypted, v2, 5);
memcpy(encrypted + 5, v3, 9);
// 逆向异或操作得到原始flag
for (int i = 0; i <= 13; ++i) {
flag[i] = encrypted[i] ^ i;
}
flag[14] = '\0';
std::cout << "解密后的flag: " << flag << std::endl;
return 0;
}
最终flag:flag{n1c3_j0b}

浙公网安备 33010602011771号