萌新的第一个CM
本帖最后由 H1ghker 于 2019-5-21 22:57 编辑如题,萌新的第一个CM,希望大佬们在破解的同时附上图文,让菜鸡楼主再学习一波,感谢了~
输入正确key后会弹出如下字符串
更新一下字符表,纯爆破没啥营养
zyxwvutsrqponmlkjihgfedcba
ABCDEFGHIJKLMNOPQRSTUVWXYZ
这题有相当多的解,应当至少是65^23组解
算法如下:
首先是楼主的main函数:
int main_0()
{
char v1; // @1
int curchar; // @3
char encryptedstr; // @57
int i; // @1
char inputstr; // @1
memset(&v1, 0xCCu, 0x110u);
i = 0;
printf("start your crack!\n");
scanf("%s", inputstr);
while ( inputstr )
{
curchar = inputstr;
curchar -= 65;
switch ( curchar )
{
case 0:
inputstr = 122;
break;
case 1:
inputstr = 121;
break;
case 2:
inputstr = 120;
break;
case 3:
inputstr = 119;
break;
case 4:
inputstr = 118;
break;
case 5:
inputstr = 117;
break;
case 6:
inputstr = 116;
break;
case 7:
inputstr = 115;
break;
case 8:
inputstr = 114;
break;
case 9:
inputstr = 113;
break;
case 10:
inputstr = 112;
break;
case 11:
inputstr = 111;
break;
case 12:
inputstr = 110;
break;
case 13:
inputstr = 109;
break;
case 14:
inputstr = 108;
break;
case 15:
inputstr = 107;
break;
case 16:
inputstr = 106;
break;
case 17:
inputstr = 105;
break;
case 18:
inputstr = 104;
break;
case 19:
inputstr = 103;
break;
case 20:
inputstr = 102;
break;
case 21:
inputstr = 101;
break;
case 22:
inputstr = 100;
break;
case 23:
inputstr = 99;
break;
case 24:
inputstr = 98;
break;
case 25:
inputstr = 97;
break;
case 57:
inputstr = 65;
break;
case 56:
inputstr = 66;
break;
case 55:
inputstr = 67;
break;
case 54:
inputstr = 68;
break;
case 53:
inputstr = 69;
break;
case 52:
inputstr = 70;
break;
case 51:
inputstr = 71;
break;
case 50:
inputstr = 72;
break;
case 49:
inputstr = 73;
break;
case 48:
inputstr = 74;
break;
case 47:
inputstr = 75;
break;
case 46:
inputstr = 76;
break;
case 45:
inputstr = 77;
break;
case 44:
inputstr = 78;
break;
case 43:
inputstr = 79;
break;
case 42:
inputstr = 80;
break;
case 41:
inputstr = 81;
break;
case 40:
inputstr = 82;
break;
case 39:
inputstr = 83;
break;
case 38:
inputstr = 84;
break;
case 37:
inputstr = 85;
break;
case 36:
inputstr = 86;
break;
case 35:
inputstr = 87;
break;
case 34:
inputstr = 88;
break;
case 33:
inputstr = 89;
break;
case 32:
inputstr = 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函数:
int __cdecl TextEncrypt(int inputstr, int resultstr)
{
char strbuf; // @1
int ch1; // @1
int ch2; // @1
int ch3; // @1
int ch4; // @1
int j; // @1
int i; // @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函数
int __cdecl sub_401220(char *a1, char a2)
{
int result; // eax@2
char v3; // @1
char *v4; // @1
memset(&v3, 0xCCu, 0x44u);
v4 = strchr(a1, a2);
if ( v4 )
result = v4 - a1;
else
result = -1;
return result;
}
就是在一个给定的串中获取字符的索引
串为:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
上面的算法很明显了,直接暴力求解即可:
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);
ch2 = (char)GetCharOffset(strlist,str);
ch3 = (char)GetCharOffset(strlist,str);
ch4 = (char)GetCharOffset(strlist,str);
r += (char)((ch2 >> 4) & 3 | 4 * ch1 & 0xFC);
if(str != '=')
{
r += (char)((ch3 >> 2) & 0xF | 16 * ch2 & 0xF0);
if(str != '=')
{
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] = str2;
}
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 + strlist + "==");//后面两个字符直接取等于号即可,使用前面两个字符就能凑出全部的字符
if(((target.Length - index) >= str.Length) && (str == target.Substring(index,str.Length)))
{
result += "" + strlist + strlist + "==";
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))
{
result2 += map];
}
else
{
result2 += result;
}
}
Console.WriteLine(result2);
while(true);
}
}
}
这样吗?
repobor 发表于 2019-5-21 22:31
这样吗?
不对不对哦 lizhirui 发表于 2019-5-21 23:28
这题有相当多的解,应当至少是65^23组解
算法如下:
首先是楼主的main函数:
变形的base64编码 cdevil 发表于 2019-5-22 12:34
变形的base64编码
原来如此 cdevil 发表于 2019-5-22 12:34
变形的base64编码
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;
}
}
没研究出来这块怎么直接逆向
所以就直接暴力枚举了 变形base64的话,那还是挺简单的
页:
[1]