我太菜了,呜呜呜

reverse
GetTheTable-100
这个说要用正确的解密软件解密,我还想了好久,想不到有啥解密软件,直接IDA

先查壳

找到主函数,分析代码逻辑
// local variable allocation has failed, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
   
   
  char str12581[59]; // [rsp+20h] [rbp-60h] BYREF
  char flag[32]; // [rsp+60h] [rbp-20h] BYREF
  char str[27]; // [rsp+80h] [rbp+0h] BYREF
  int j; // [rsp+A0h] [rbp+20h]
  int index; // [rsp+A4h] [rbp+24h]
  char *encryption; // [rsp+A8h] [rbp+28h]
  _BYTE len[12]; // [rsp+B4h] [rbp+34h] OVERLAPPED
  int n; // [rsp+C4h] [rbp+44h]
  int n1; // [rsp+C8h] [rbp+48h]
  int j_1; // [rsp+CCh] [rbp+4Ch]
  int j_0; // [rsp+D0h] [rbp+50h]
  int carry; // [rsp+D4h] [rbp+54h]
  int high; // [rsp+D8h] [rbp+58h]
  int i; // [rsp+DCh] [rbp+5Ch]
  _main();
  n1 = 18;
  strcpy(str, "ERaQux2kCQGLeLwddrgMCKtL6x");    // flag最终的变化形式
  scanf("%s", flag);
  n = strlen(flag);
  if ( n <= 32 )                                // flag长度小于32
  {
   
   
    *(_QWORD *)&len[4] = 0i64;
    *(_QWORD *)len = (unsigned int)(138 * strlen(flag) / 0x64) + 1;// len=36
    strcpy(str12581, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
    encryption = (char *)malloc(*(int *)len);
    index = 0;
    memset(encryption, 0, *(int *)len);
    high = *(_DWORD *)len - 1;                  // high=35
    j = 0;
    i = 0;
    while ( i < strlen(flag) )
    {
   
   
      carry = flag[i];
      for ( j_0 = *(_DWORD *)len - 1; j_0 > high || carry; --j_0 )
      {
   
   
        carry += encryption[j_0] << 8;
        encryption[j_0] = (char)carry % 58;
        carry /= 58;
        if ( !j_0 )
          break;
      }
      ++i;
      high = j;
    }
    for ( i = 0; !encryption[i]; ++i )
      ;
    j_1 = 0;
    while ( *(int *)len > i )
    {
   
   
      if ( str[j_1] != str12581[encryption[i]] )
      {
   
   
        printf("Wrong answer!");
        system("pause");
        return 0;
      }
      ++i;
      ++j_1;
    }
    printf("Your input is the right answer!");
    system("pause");
    return 0;
  }
  else
  {
   
   
    printf("Wrong answer!");
    system("pause");
    return 0;
  }
}
主要就是这一段的加密方式,我乍一眼也没看明白,然后跑了下这个加密方式
while ( i < strlen(flag) )
    {
   
   
      carry = flag[i];
      for ( j_0 = *(_DWORD *)len - 1; j_0 > high || carry; --j_0 )
      {
   
   
        carry += encryption[j_0] << 8;
        encryption[j_0] = (char)carry % 58;
        carry /= 58;
        if ( !j_0 )
          break;
      }
      ++i;
      high = j;
    }
随便整个字符串试一下
char flag[] = "ISCC{hello_word}";
  int carry;
  int j_0,i=0,j=0,high=22,len=23,k;
  char en[24]={
   
   0};
  while(i < strlen(flag))
  {
   
   
      carry = flag[i];
      for(j_0 = 22; j_0 > high || carry ; --j_0)
      {
   
   
          //printf("carry = %d\n",carry);
          carry += en[j_0] << 8;
          en[j_0] = carry % 58;
          carry /= 58;
          if(!j_0) break;
      }
      printf("i = %d\n",i);
      for(k = 0 ; k < 23;k++)
      {
   
   
          printf("%d ",en[k]);
      }
         ++i;
      high=j;
  }
运行结果:

这样就好看多了,可以看出都是从最后一位开始加密,每轮加密都会比上面的多两个数,第一个数是carry除以58的商,第二个数是carry除以58的余数,根据这个可以算出上一个carry,以及上一轮的最后一轮的第一个数。
根据这个可以写出脚本
Str = "ERaQux2kCQGLeLwddrgMCKtL6x"
Str_1 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
en = []
for i in range(len(Str)):
    en.append(Str_1.find(Str[i]))
print(en)
def f(list):
    last_list = []
    carry = 0
    for i in range(0,len(list)):
        carry *= 58
        carry += list[i]
        t = carry // 256
        last_list.append( t)
        carry -= (t * 256)
    del last_list[0]   #删除掉开始的零元素
    print(last_list)
    return carry,last_list
flag = [0] * 26
for i in range(25,-1,-1):
     flag[i],en = f(en) 
for i in flag:
    if i > 0:
        print(chr(i),end="")
print(flag)
运行结果
[13, 24, 33, 23, 52, 55, 1, 43, 11, 23, 15, 19, 37, 19, 54, 36, 36, 49, 39, 20, 11, 18, 51, 
19, 5, 55]
[3, 2, 22, 56, 36, 0, 39, 47, 22, 56, 27, 28, 27, 2, 14, 37, 17, 23, 54, 39, 27, 2, 0, 43, 43]
[0, 39, 55, 55, 24, 27, 19, 51, 56, 23, 38, 49, 28, 45, 21, 25, 38, 48, 27, 19, 47, 20, 49, 
6]
[0, 9, 3, 9, 22, 17, 56, 35, 45, 49, 44, 34, 45, 2, 7, 7, 10, 9, 9, 47, 31, 6, 57]
[0, 2, 2, 56, 55, 20, 22, 19, 51, 36, 11, 26, 52, 46, 14, 17, 28, 7, 29, 50, 11, 7]
[0, 0, 26, 55, 28, 49, 27, 41, 38, 24, 56, 3, 48, 12, 16, 48, 21, 18, 53, 25, 24]
[0, 0, 6, 6, 13, 19, 21, 13, 30, 0, 12, 40, 43, 5, 29, 10, 55, 33, 42, 53]
[0, 0, 1, 22, 14, 46, 30, 37, 2, 41, 42, 43, 38, 44, 17, 2, 1, 41, 36]
[0, 0, 0, 18, 10, 35, 0, 34, 39, 7, 37, 18, 55, 26, 20, 9, 56, 33]
[0, 0, 0, 4, 6, 54, 8, 43, 11, 33, 52, 23, 45, 10, 55, 18, 33]
[0, 0, 0, 0, 54, 7, 42, 44, 13, 2, 40, 24, 24, 16, 30, 38]
[0, 0, 0, 0, 12, 15, 20, 6, 22, 51, 47, 12, 45, 21, 50]
[0, 0, 0, 0, 2, 45, 9, 31, 20, 34, 22, 54, 5, 43]
[0, 0, 0, 0, 0, 36, 29, 46, 30, 28, 36, 53, 2]
[0, 0, 0, 0, 0, 8, 15, 47, 14, 9, 11, 57]
[0, 0, 0, 0, 0, 1, 50, 41, 3, 38, 19]
[0, 0, 0, 0, 0, 0, 24, 36, 28, 27]
[0, 0, 0, 0, 0, 0, 5, 33, 37]
[0, 0, 0, 0, 0, 0, 1, 15]
[0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0]
[0, 0]
[0]
[]
ISCC{
   
   T5xr15ruVEyXI}[0, 0, 0, 0, 0, 0, 0, 73, 83, 67, 67, 123, 84, 53, 120, 114, 49, 53, 114, 117, 86, 69, 121, 88, 73, 125]
得到flag: ISCC{T5xr15ruVEyXI}
Poetry-100
这题0解,还是等着看别人的wp吧

Amy’s Code-100

还是先查看信息

IDA查看字符串,直接定位到关键函数

代码很简单,就一个异或和一个加法

写个脚本出来就行
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
   
   
 int v9[20] = {
   
   0};
 char v6[21] = "LWHFUENGDJGEFHYDHIGJ";
 char flag[21];
 int i,j,k;
 v9[0] = 149;
  v9[1] = 169;
  v9[2] = 137;
  v9[3] = 134;
  v9[4] = 212;
  v9[5] = 188;
  v9[6] = 177;
  v9[7] = 184;
  v9[8] = 177;
  v9[9] = 197;
  v9[10] = 192;
  v9[11] = 179;
  v9[12] = 153;
  v9[13] = 142;
  v9[14] = 191;
  v9[15] = 130;
  v9[16] = 167;
  v9[17] = 191;
  v9[18] = 104;
  v9[19] = 184;
  for (i = 0 ; i < 20 ; i ++)
  {
   
   
      flag[i] = v9[i] - v6[i];
      flag[i] ^= i;
      printf("%c",flag[i]);
  }
  return 0;
}
运行结果:

How_decode-150

还是先查下壳

查看字符串,然后定位到主函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
   
   
  void *v3; // rsp
  int v2[32]; // [rsp+20h] [rbp-60h] BYREF
  int k[4]; // [rsp+A0h] [rbp+20h] BYREF
  char v[32]; // [rsp+B0h] [rbp+30h] BYREF
  int n; // [rsp+DCh] [rbp+5Ch]
  int (*p_v1)[]; // [rsp+E0h] [rbp+60h]
  __int64 v10; // [rsp+E8h] [rbp+68h]
  int n1; // [rsp+F4h] [rbp+74h]
  int i; // [rsp+F8h] [rbp+78h]
  int i_0; // [rsp+FCh] [rbp+7Ch]
  _main();
  n1 = 18;
  v10 = 17i64;
  v3 = alloca(80i64);
  p_v1 = (int (*)[])v2;
  v2[0] = 0x8D7FFB13;
  v2[1
 
                   
                   
                   
                   本文介绍了ISCC 2022中涉及的逆向工程问题,包括不同类型的加密解密算法分析,如基于位操作、异或、Base64的变种和自定义加密函数。通过解密过程,获取了多个flag。
本文介绍了ISCC 2022中涉及的逆向工程问题,包括不同类型的加密解密算法分析,如基于位操作、异或、Base64的变种和自定义加密函数。通过解密过程,获取了多个flag。
           最低0.47元/天 解锁文章
最低0.47元/天 解锁文章
                           
                       
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
                     
              
             
                   582
					582
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
					 
					 
					


 
            