HGAME2020-re-Level-Week1-bitwise_operation2
新手一枚,如有错误(不足)请指正,谢谢!!
<mark>个人博客:点击进入</mark>
题目链接:HGAME2020-re-Level-Week1-bitwise_operation2
题目下载:点击下载
题目描述
还记得第三次C语言培训的作业“位运算”吗?这是2.0
学习资料:http://q42u2raim.bkt.clouddn.com/bitwise-hint1-xor.png
题目地址 http://q42u2raim.bkt.clouddn.com/bitwise_operation2_9d9dc26c1359ec66
题解
分析题目
void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
signed int i; // [rsp+4h] [rbp-6Ch]
signed int j; // [rsp+8h] [rbp-68h]
signed int k; // [rsp+Ch] [rbp-64h]
char v6[8]; // [rsp+10h] [rbp-60h]
__int64 data_1; // [rsp+20h] [rbp-50h]
char v8; // [rsp+28h] [rbp-48h]
__int64 data_2; // [rsp+30h] [rbp-40h]
char v10; // [rsp+38h] [rbp-38h]
char user_input[40]; // [rsp+40h] [rbp-30h]
unsigned __int64 v12; // [rsp+68h] [rbp-8h]
v12 = __readfsqword(0x28u);
sub_4007E6();
v6[0] = 76;
v6[1] = 60;
v6[2] = -42;
v6[3] = 54;
v6[4] = 80;
v6[5] = -120;
v6[6] = 32;
v6[7] = -52;
__isoc99_scanf("%39s", user_input);
if ( strlen(user_input) == 39
&& user_input[0] == 'h'
&& user_input[1] == 'g'
&& user_input[2] == 'a'
&& user_input[3] == 'm'
&& user_input[4] == 'e'
&& user_input[5] == '{'
&& user_input[38] == '}' )
{
data_1 = 0LL;
v8 = 0;
data_2 = 0LL;
v10 = 0;
sub_400616(&data_1, &user_input[6]); // 加密下标6~21
sub_400616(&data_2, &user_input[22]); // 加密下标22~38
for ( i = 0; i <= 7; ++i ) // 进行运算
{
*(&data_1 + i) = ((*(&data_1 + i) & 224) >> 5) | 8 * *(&data_1 + i);
*(&data_1 + i) = *(&data_1 + i) & 0x55 ^ ((*(&data_2 + 7 - i) & 0xAA) >> 1) | *(&data_1 + i) & 0xAA;
*(&data_2 + 7 - i) = 2 * (*(&data_1 + i) & 0x55) ^ *(&data_2 + 7 - i) & 0xAA | *(&data_2 + 7 - i) & 0x55;
*(&data_1 + i) = *(&data_1 + i) & 0x55 ^ ((*(&data_2 + 7 - i) & 0xAA) >> 1) | *(&data_1 + i) & 0xAA;
}
for ( j = 0; j <= 7; ++j )
{
*(&data_1 + j) ^= v6[j]; // 异或运算
if ( *(&data_1 + j) != byte_602050[j] ) // 进行比较
{
puts("sry, wrong flag");
exit(0);
}
}
for ( k = 0; k <= 7; ++k )
{
*(&data_2 + k) ^= *(&data_1 + k) ^ v6[k]; // 异或运算
if ( *(&data_2 + k) != byte_602060[k] ) // 进行比较
{
puts("Just one last step");
exit(0);
}
}
puts("Congratulations! You are already familiar with bitwise operation.");
puts("Flag is your input.");
exit(0);
}
puts("Illegal input!");
exit(0);
}
大体流程为,用户输入39个字符。
然后验证一下长度,前六个字符是否等于"hgame{",最后一个字符是否等于"}"
然后sub_400616每次将16个字符加密成8个字符。
然后进行了一堆位运算
之后进行了两个异或然后进行比较
exp
#include <stdio.h>
int main()
{
int i;
char flag[40] = { 'h','g','a','m','e','{' ,0,0 };
flag[38] = '}';
unsigned char data0[] = { 76,60,-42,54,80,-120,32,-52 };
int j, k;
char data1[9] = "e4sy_Re_";
char data2[9] = "Easylif3";
unsigned char data_1[9] = { 0 }, data_2[9] = {0};
unsigned char input1[9] = { 0 }, input2[9] = {0};
for (i = 0; i < 8; i++)
data_2[i] = data2[i] ^ data0[i] ^ data1[i];
for (i = 0; i < 8; i++)
data_1[i] = data1[i] ^ data0[i];
for (i = 0; i < 8; i++)//正向爆破
{
for (j = 0; j < 256; j++)
{
for (k = 0; k < 256; k++)
{
int a1 = j, a2 = k;
a1 = ((a1 & 0xE0) >> 5) | 8 * a1;
a1 = a1 & 0x55 ^ ((a2 & 0xAA) >> 1) | a1 & 0xAA;
a2 = 2 * (a1 & 0x55) ^ a2 & 0xAA | a2 & 0x55;
a1 = a1 & 0x55 ^ ((a2 & 0xAA) >> 1) | a1 & 0xAA;
if (a1 == data_1[i] && a2 == data_2[7 - i])
{
input1[i] = j;
input2[7 - i] = k;
}
}
}
}
for (i = 0; i < 8; i++)//正向爆破
{
for (j = 0; j < 16; j++)
{
for (k = 0; k < 16; k++)
{
if (input1[i] == 16 * j + k)
{
if (j > 9)
flag[6 + 2 * i] = j + 87;
else
flag[6 + 2 * i] = j + 48;
if (k > 9)
flag[7 + 2 * i] = k + 87;
else
flag[7 + 2 * i] = k + 48;
}
if (input2[i] == 16 * j + k)
{
if (j > 9)
flag[22 + 2 * i] = j + 87;
else
flag[22 + 2 * i] = j + 48;
if (k > 9)
flag[23 + 2 * i] = k + 87;
else
flag[23 + 2 * i] = k + 48;
}
}
}
}
puts(flag);
return 0;
}
运行得到flag
hgame{0f233e63637982d266cbf41ecb1b0102}