测试文件:https://adworld.xctf.org.cn/media/task/attachments/a5c0e8322d9645468befabddfe0cb51d.exe

1.准备

获取信息

  • 32位文件

2.IDA打开

 int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // edx
unsigned int v4; // ecx
__m128i v5; // xmm1
unsigned int v6; // esi
const __m128i *v7; // eax
__m128i v8; // xmm0
int v9; // eax
char v11; // [esp+0h] [ebp-CCh]
char v12; // [esp+1h] [ebp-CBh]
char v13; // [esp+64h] [ebp-68h]
char v14; // [esp+65h] [ebp-67h]
unsigned int v15; // [esp+C8h] [ebp-4h] printf("please input your flah:");
v11 = ;
memset(&v12, , 0x63u);
scanf("%s", &v11);
v13 = ;
memset(&v14, , 0x63u);
sub_401000(&v15, &v13, (unsigned __int8 *)&v11, strlen(&v11));
v3 = v15;
v4 = ;
if ( v15 )
{
if ( v15 >= 0x10 )
{
v5 = _mm_load_si128((const __m128i *)&xmmword_414F20);// 这部分对我们的结果没有影响
v6 = v15 - (v15 & 0xF);
v7 = (const __m128i *)&v13;
do
{
v8 = _mm_loadu_si128(v7);
v4 += ;
++v7;
_mm_storeu_si128((__m128i *)&v7[-], _mm_xor_si128(v8, v5));
}
while ( v4 < v6 );
}
for ( ; v4 < v3; ++v4 ) // 对每位字符进行异或0x25
*(&v13 + v4) ^= 0x25u;
}
v9 = strcmp(&v13, "you_know_how_to_remove_junk_code");// 处理之后的字符串为"you_know_how_to_remove_junk_code"
if ( v9 )
v9 = -(v9 < ) | ;
if ( v9 )
printf("wrong\n");
else
printf("correct\n");
system("pause");
return ;
}

其中的一些函数解释

__m128i _mm_load_si128 (__m128i *p);
//返回可以存放在代表寄存器的变量中的值,即*p的值 __m128i _mm_load_si128 (__m128i *p);
//返回可以存放在代表寄存器的变量中的值,即*p的值 void _mm_storeu_si128 ( __m128i *p, __m128i a);
//将__m128i 变量a的值存储到p所指定的变量中去;

3.代码分析

这道题思路很清晰,就是逆向操作结果字符串就行。

我们输入v11,在下面有个关键的sub_401000(&v15, &v13, (unsigned __int8 *)&v11, strlen(&v11));函数

 signed int __usercall sub_401000@<eax>(unsigned int *a1@<edx>, _BYTE *a2@<ecx>, unsigned __int8 *a3, unsigned int a4)
{
int v4; // ebx
unsigned int v5; // eax
int v6; // ecx
unsigned __int8 *v7; // edi
int v8; // edx
bool v9; // zf
unsigned __int8 v10; // cl
char v11; // cl
_BYTE *v12; // esi
unsigned int v13; // ecx
int v14; // ebx
unsigned __int8 v15; // cl
char v16; // dl
_BYTE *v18; // [esp+Ch] [ebp-Ch]
unsigned int *v19; // [esp+10h] [ebp-8h]
int v20; // [esp+14h] [ebp-4h]
unsigned int v21; // [esp+14h] [ebp-4h]
int i; // [esp+24h] [ebp+Ch] v4 = ;
v18 = a2;
v5 = ;
v6 = ;
v19 = a1;
v20 = ;
if ( !a4 )
return ;
v7 = a3;
do
{
v8 = ;
v9 = v5 == a4;
if ( v5 < a4 )
{
do
{
if ( a3[v5] != )
break;
++v5;
++v8;
}
while ( v5 < a4 );
v9 = v5 == a4;
}
if ( v9 )
break;
if ( a4 - v5 >= && a3[v5] == && a3[v5 + ] == || (v10 = a3[v5], v10 == ) )
{
v6 = v20;
}
else
{
if ( v8 )
return ;
if ( v10 == && (unsigned int)++v4 > )
return ;
if ( v10 > 0x7Fu )
return ;
v11 = byte_414E40[v10];
if ( v11 == || (unsigned __int8)v11 < 0x40u && v4 )
return ;
v6 = v20++ + ;
}
++v5;
}
while ( v5 < a4 );
if ( !v6 )
return ;
v12 = v18;
v13 = ((unsigned int)( * v6 + ) >> ) - v4;
if ( v18 && *v19 >= v13 )
{
v21 = ;
v14 = ;
for ( i = ; v5; --v5 )
{
v15 = *v7;
if ( *v7 != && v15 != && v15 != )
{
v16 = byte_414E40[v15];
v21 -= v16 == ;
v14 = v16 & 0x3F | (v14 << );
if ( ++i == )
{
i = ;
if ( v21 )
*v12++ = BYTE2(v14);
if ( v21 > )
*v12++ = BYTE1(v14);
if ( v21 > )
*v12++ = v14;
}
}
++v7;
}
*v19 = v12 - v18;
return ;
}
*v19 = v13;
return -;
}

对于这段函数实际上是base64解密,关键代码在于

 if ( v18 && *v19 >= v13 )
{
v21 = ;
v14 = ;
for ( i = ; v5; --v5 )
{
v15 = *v7;
if ( *v7 != && v15 != && v15 != )
{
v16 = byte_414E40[v15];
v21 -= v16 == ;
v14 = v16 & 0x3F | (v14 << );
if ( ++i == ) // 4字节为一组处理
{
i = ;
if ( v21 ) // 分为3字节输出
*v12++ = BYTE2(v14);
if ( v21 > )
*v12++ = BYTE1(v14);
if ( v21 > )
*v12++ = v14;
}
}
++v7;
}

要了解base64加密原理可以看:https://www.cnblogs.com/Mayfly-nymph/p/11644823.html

解密代码可以看:https://blog.csdn.net/prsniper/article/details/7097643

byte_414E40

00414E40  7F 7F 7F 7F 7F 7F 7F 7F  7F 7F 7F 7F 7F 7F 7F 7F  ................
00414E50 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F ................
00414E60 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 7F 3E 7F 7F 7F 3F ...........>...?
00414E70 3A 3B 3C 3D 7F 7F 7F 7F 7F :;<=...@..
00414E80 7F 0A 0B 0C 0D 0E ................
00414E90 0F 7F 7F 7F 7F 7F ................
00414EA0 7F 1A 1B 1C 1D 1E 1F ....... !"#$%&'(
00414EB0 29 2A 2B 2C 2D 2E 2F 30 31 32 33 7F 7F 7F 7F 7F )*+,-./0123.....

也可以猜测是base64相关的操作

4.脚本解密

import base64

str1='you_know_how_to_remove_junk_code'

flag=''

for i in str1:
flag += chr(ord(i)^0x25) print(base64.b64encode(flag))

5.get flag!

XEpQek5LSlJ6TUpSelFKeldASEpTQHpPUEtOekZKQUA=

最新文章

  1. Linux进程学习
  2. [LeetCode] Total Hamming Distance 全部汉明距离
  3. 常见http错误码解读
  4. 谷歌/微软/必应web页面免费翻译插件
  5. Swift3.0语言教程使用Unicode范式标准化获取字符串
  6. ScrollView反弹效果 仿小米私密短信效果
  7. 开发服务器端&mdash;&mdash;工程配置
  8. 基于jQuery简单实用的Tabs选项卡插件
  9. PHP读取CSV大文件导入数据库的示例
  10. 根据反射获取属性信息并创建DataTable
  11. 解决Qt程序在Linux下无法输入中文的办法
  12. CSS实现三角形图标的原理《转载》
  13. nginx之 nginx + tomcat + redis 负载均衡且session一致性
  14. Linux和win7(win10)双系统时间错误问题 时间相差8小时
  15. CentOS7 +vsftpd (一)之 匿名
  16. DOM操作中,getElementByXXXX 和 querySelector 的区别
  17. P2708 硬币翻转(简单模拟)
  18. Redis 实现安全队列
  19. css特殊样式
  20. 九度 1464:Hello World for U

热门文章

  1. CSS盒子模型中的Padding属性
  2. Java冠军程序员告诉你如何提升技术
  3. Python pdfkit
  4. HDU 6205 card card card ( 思维 )
  5. R 画散点图
  6. Leetcode 8. String to Integer (atoi)(模拟题,水)
  7. CF1012F Passports
  8. [BZOJ4817][SDOI2017]树点涂色:Link-Cut Tree+线段树
  9. vue-router 2.0 跳转之router.push()
  10. Wowza 4.5 修改 manager 端口号