这题有相当多的解,应当至少是65^23组解
算法如下:
首先是楼主的main函数:
[C] 纯文本查看 复制代码
int main_0()
{
char v1; // [sp+Ch] [bp-110h]@1
int curchar; // [sp+4Ch] [bp-D0h]@3
char encryptedstr; // [sp+50h] [bp-CCh]@57
int i; // [sp+B4h] [bp-68h]@1
char inputstr[100]; // [sp+B8h] [bp-64h]@1
memset(&v1, 0xCCu, 0x110u);
i = 0;
printf("start your crack!\n");
scanf("%s", inputstr);
while ( inputstr[i] )
{
curchar = inputstr[i];
curchar -= 65;
switch ( curchar )
{
case 0:
inputstr[i] = 122;
break;
case 1:
inputstr[i] = 121;
break;
case 2:
inputstr[i] = 120;
break;
case 3:
inputstr[i] = 119;
break;
case 4:
inputstr[i] = 118;
break;
case 5:
inputstr[i] = 117;
break;
case 6:
inputstr[i] = 116;
break;
case 7:
inputstr[i] = 115;
break;
case 8:
inputstr[i] = 114;
break;
case 9:
inputstr[i] = 113;
break;
case 10:
inputstr[i] = 112;
break;
case 11:
inputstr[i] = 111;
break;
case 12:
inputstr[i] = 110;
break;
case 13:
inputstr[i] = 109;
break;
case 14:
inputstr[i] = 108;
break;
case 15:
inputstr[i] = 107;
break;
case 16:
inputstr[i] = 106;
break;
case 17:
inputstr[i] = 105;
break;
case 18:
inputstr[i] = 104;
break;
case 19:
inputstr[i] = 103;
break;
case 20:
inputstr[i] = 102;
break;
case 21:
inputstr[i] = 101;
break;
case 22:
inputstr[i] = 100;
break;
case 23:
inputstr[i] = 99;
break;
case 24:
inputstr[i] = 98;
break;
case 25:
inputstr[i] = 97;
break;
case 57:
inputstr[i] = 65;
break;
case 56:
inputstr[i] = 66;
break;
case 55:
inputstr[i] = 67;
break;
case 54:
inputstr[i] = 68;
break;
case 53:
inputstr[i] = 69;
break;
case 52:
inputstr[i] = 70;
break;
case 51:
inputstr[i] = 71;
break;
case 50:
inputstr[i] = 72;
break;
case 49:
inputstr[i] = 73;
break;
case 48:
inputstr[i] = 74;
break;
case 47:
inputstr[i] = 75;
break;
case 46:
inputstr[i] = 76;
break;
case 45:
inputstr[i] = 77;
break;
case 44:
inputstr[i] = 78;
break;
case 43:
inputstr[i] = 79;
break;
case 42:
inputstr[i] = 80;
break;
case 41:
inputstr[i] = 81;
break;
case 40:
inputstr[i] = 82;
break;
case 39:
inputstr[i] = 83;
break;
case 38:
inputstr[i] = 84;
break;
case 37:
inputstr[i] = 85;
break;
case 36:
inputstr[i] = 86;
break;
case 35:
inputstr[i] = 87;
break;
case 34:
inputstr[i] = 88;
break;
case 33:
inputstr[i] = 89;
break;
case 32:
inputstr[i] = 90;
break;
default:
break;
}
++i;
}
j_TextEncrypt((int)inputstr, (int)&encryptedstr);
printf("%s\n", &encryptedstr);
if ( !strcmp(&encryptedstr, "Th1s_crAcKme_1s_S0_juNk") )
printf("you_got_it!\n");
else
printf("nonono\n");
system("pause");
return 0;
}
可见一开始做了个字符替换
然后是楼主的TextEncrypt函数:
[C] 纯文本查看 复制代码
int __cdecl TextEncrypt(int inputstr, int resultstr)
{
char strbuf; // [sp+Ch] [bp-58h]@1
int ch1; // [sp+4Ch] [bp-18h]@1
int ch2; // [sp+50h] [bp-14h]@1
int ch3; // [sp+54h] [bp-10h]@1
int ch4; // [sp+58h] [bp-Ch]@1
int j; // [sp+5Ch] [bp-8h]@1
int i; // [sp+60h] [bp-4h]@1
memset(&strbuf, 0xCCu, 0x58u);
i = 0;
j = 0;
ch1 = 0;
ch2 = 0;
ch3 = 0;
ch4 = 0;
while ( *(_BYTE *)(i + inputstr) )
{
ch1 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr));
ch2 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr + 1));
*(_BYTE *)(j++ + resultstr) = (ch2 >> 4) & 3 | 4 * ch1 & 0xFC;
if ( *(_BYTE *)(i + inputstr + 2) != 61 ) // 61是等号
{
ch3 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr + 2));
*(_BYTE *)(j++ + resultstr) = (ch3 >> 2) & 0xF | 16 * ch2 & 0xF0;
if ( *(_BYTE *)(i + inputstr + 3) != 61 )
{
ch4 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr + 3));
*(_BYTE *)(j++ + resultstr) = ch4 & 0x3F | ((_BYTE)ch3 << 6) & 0xC0;
}
}
i += 4;
}
*(_BYTE *)(j + resultstr) = 0;
return 0;
}
做了一些神秘的二进制运算
然后是楼主的GetCharOffset函数
[C] 纯文本查看 复制代码
int __cdecl sub_401220(char *a1, char a2)
{
int result; // eax@2
char v3; // [sp+Ch] [bp-44h]@1
char *v4; // [sp+4Ch] [bp-4h]@1
memset(&v3, 0xCCu, 0x44u);
v4 = strchr(a1, a2);
if ( v4 )
result = v4 - a1;
else
result = -1;
return result;
}
就是在一个给定的串中获取字符的索引
串为:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
上面的算法很明显了,直接暴力求解即可:
[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _20190521
{
class Program
{
static string strlist = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
static int GetCharOffset(string str,char ch)
{
return str.IndexOf(ch);
}
static string TextEncrypt(string str)
{
char ch1,ch2,ch3,ch4;
string r = "";
ch1 = (char)GetCharOffset(strlist,str[0]);
ch2 = (char)GetCharOffset(strlist,str[1]);
ch3 = (char)GetCharOffset(strlist,str[2]);
ch4 = (char)GetCharOffset(strlist,str[3]);
r += (char)((ch2 >> 4) & 3 | 4 * ch1 & 0xFC);
if(str[2] != '=')
{
r += (char)((ch3 >> 2) & 0xF | 16 * ch2 & 0xF0);
if(str[3] != '=')
{
r += (char)(ch4 & 0x3F | (ch3 << 6) & 0xC0);
}
}
return r;
}
static void Main(string[] args)
{
string target = "Th1s_crAcKme_1s_S0_juNk";
string result = "";
int i,j,k,l;
int index;
string str1 = "zyxwvutsrqponmlkjihgfedcbaABCDEFGHIJKLMNOPQRSTUVWXYZ";
string str2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZzyxwvutsrqponmlkjihgfedcba";
var map = new Dictionary<char,char>();
for(i = 0;i < str1.Length;i++)
{
map[str1[i]] = str2[i];
}
for(index = 0;index < target.Length;)
{
bool flag = false;
for(i = 0;i < strlist.Length;i++)
{
for(j = 0;j < strlist.Length;j++)
{
//for(k = 0;k < strlist.Length;k++)
{
//for(l = 0;l < strlist.Length;l++)
{
string str = TextEncrypt("" + strlist[i] + strlist[j] + "==");//后面两个字符直接取等于号即可,使用前面两个字符就能凑出全部的字符
if(((target.Length - index) >= str.Length) && (str == target.Substring(index,str.Length)))
{
result += "" + strlist[i] + strlist[j] + "==";
index += str.Length;
flag = true;
goto next;
}
}
}
}
}
next:
if(flag == false)
{
throw new Exception();
}
else
{
Console.WriteLine(result);
}
}
Console.WriteLine(result);
var result2 = "";
for(i = 0;i < result.Length;i++)
{
if(map.ContainsKey(result[i]))
{
result2 += map[result[i]];
}
else
{
result2 += result[i];
}
}
Console.WriteLine(result2);
while(true);
}
}
}
|