首页 > 技术文章 > NoString --- bugku

xiaochaofang 2021-04-28 23:00 原文

下载得到一个exe程序,是32位的

大概程序逻辑就是我们输入正确的flag,就会提示正确。
1.字符串搜索大法SHift+F12,但是根据题目说NoString可能我们搜索不到

2.因为我们搜索不到字符串,所以我们考虑是被加密了,需要分析代码

3.使用IDA打开程序进行反编译,查看main函数,分析代码获取逻辑:

int wmain()
{
  signed int v0; // ecx          //定义的一些变量
  signed int i; // eax
  signed int v2; // ecx
  signed int j; // eax
  int k; // eax
  int v5; // eax
  signed int v6; // ecx
  signed int l; // eax
  signed int v8; // ecx
  signed int m; // eax
  char v11; // [esp+0h] [ebp-18h] BYREF
  __int128 v12; // [esp+1h] [ebp-17h]
  __int16 v13; // [esp+11h] [ebp-7h]

  v0 = strlen(Format);    //计算字符串 Format 的长度
  for ( i = 0; i < v0; ++i )
    Format[i] ^= 9u;      //a=a^9u 按位异或并赋值,这可能是加密操作
  printf("yelhzl)`gy|})|)oehnl3");   //可能是加密的输出,推测很有可能是开头让我们输入flage的提示 
  v11 = 0;      
  v13 = 0;
  v12 = 0i64;
  v2 = strlen(a80z);      //计算字符串 a80z 的长度
  for ( j = 0; j < v2; ++j )
    a80z[j] ^= 9u;          //加密操作安位异或
    scanf(a80z, &v11);      //读取用户输入数据, &v11代表用户输入数据,a80z代表获得用户输入的变量
  for ( k = 0; k < 19; ++k )
    *(&v11 + k) ^= 9u;
  v5 = strcmp(&v11, aOehnl3rHfCcgpt);      //比较两个字符串的大小,用户输入是否长度大于aOehnl3rHfCcgpt
  if ( v5 )
    v5 = v5 < 0 ? -1 : 1;    //v5小于0的话就是-1,否则就是1
  if ( v5 )                  //v5为1所执行的代码
  {
    v6 = strlen(aLF);      
    for ( l = 0; l < v6; ++l )
      aLF[l] ^= 9u;
    printf("l{{f{");
  }
  else                      //v5为-1执行的代码
  {
    v8 = strlen(aNa);
    for ( m = 0; m < v8; ++m )
      aNa[m] ^= 9u;
    printf("{`na}");
  }
  printf("\r\n");
  system("pause");
  return 0;
}

根据上面的代码分析,xx经过9u异或操作,得到了printf的内容

4.我们需要知道异或(^)操作
举例:11001001^00110001=11111000
10=1;01=1;11=0;00=0
当我们得到11111000和00110001,我们怎么得到11001001?当然也是异或
11111000^00110001=11001001
5.我们可以试着写出解密脚本:

#include<stdio.h>
#include <string.h>

int  main(){
	char a[] = "l{{f{";
	int len = strlen(a);
	
	for(int i = 0;i < len ; i++)    //按位异或
	{
		a[i] ^= 9u;
	}
	printf("%s",a);
}



此时提交的flag的是错误的,看看我们遗漏了什么



推荐阅读