新手破解练习Crackme160之052 - egis.1(太难,搞不定)
-
脱壳, 在window10下脱壳失败, 在xp下成功了, 用PEiD的通用脱壳器,
-
暴力破解, OD加载搜索关键字定位到00401E7A, 上面的关键跳00401E71改为jmp 00401ECB直接跳到成功分支, 保存, 搞定~
-
正常破解, 程序非常长, 放弃~ 有时间倒可以从内存中分析一下当前输入用户名对应的注册码是什么, 资源工具看到程序中还有一个另外一个窗口, 估计作者还有什么大招没放出来呢~
附上大佬的注册机代码:(我用的编辑器是Dev-C++ 5.9.2, 所以代码经过了小调整, 菜单->工具->编译选项->在连接器命令行加入 -std=c++11)
#include <cassert>
#include <array>
#include <cstring>
#include <string.h>
#include <windows.h>
std::array<std::pair<int, int>, 16> constAddr1 = {
std::pair<int,int>(0x41b0b0, 0xD76AA478),
std::pair<int,int>(0x41b0b4, 0xE8C7B756),
std::pair<int,int>(0x41b0b8, 0x242070DB),
std::pair<int,int>(0x41b0bc, 0xC1BDCEEE),
std::pair<int,int>(0x41b0c0, 0xF57C0FAF),
std::pair<int,int>(0x41b0c4, 0x4787C62A),
std::pair<int,int>(0x41b0c8, 0xA8304613),
std::pair<int,int>(0x41b0cc, 0xFD469501),
std::pair<int,int>(0x41b0d0, 0x698098D8),
std::pair<int,int>(0x41b0d4, 0x8B44F7AF),
std::pair<int,int>(0x41b0d8, 0xFFFF5BB1),
std::pair<int,int>(0x41b0dc, 0x895CD7BE),
std::pair<int,int>(0x41b0e0, 0x6B901122),
std::pair<int,int>(0x41b0e4, 0xFD987193),
std::pair<int,int>(0x41b0e8, 0xA679438E),
std::pair<int,int>(0x41b0ec, 0x49B40821),
};
std::array<std::pair<int, int>, 16> constAddr2 = {
std::pair<int,int>(0x41b0f0, 0xF61E2562),
std::pair<int,int>(0x41b0f4, 0xC040B340),
std::pair<int,int>(0x41b0f8, 0x265E5A51),
std::pair<int,int>(0x41b0fc, 0xE9B6C7AA),
std::pair<int,int>(0x41b100, 0xD62F105D),
std::pair<int,int>(0x41b104, 0x02441453),
std::pair<int,int>(0x41b108, 0xD8A1E681),
std::pair<int,int>(0x41b10c, 0xE7D3FBC8),
std::pair<int,int>(0x41b110, 0x21E1CDE6),
std::pair<int,int>(0x41b114, 0xC33707D6),
std::pair<int,int>(0x41b118, 0xF4D50D87),
std::pair<int,int>(0x41b11c, 0x455A14ED),
std::pair<int,int>(0x41b120, 0xA9E3E905),
std::pair<int,int>(0x41b124, 0xFCEFA3F8),
std::pair<int,int>(0x41b128, 0x676F02D9),
std::pair<int,int>(0x41b12c, 0x8D2A4C8A),
};
std::array<std::pair<int, int>, 16> constAddr3 = {
std::pair<int,int>(0x41b130, 0xFFFA3942),
std::pair<int,int>(0x41b134, 0x8771F681),
std::pair<int,int>(0x41b138, 0x6D9D6122),
std::pair<int,int>(0x41b13c, 0xFDE5380C),
std::pair<int,int>(0x41b140, 0xA4BEEA44),
std::pair<int,int>(0x41b144, 0x4BDECFA9),
std::pair<int,int>(0x41b148, 0xF6BB4B60),
std::pair<int,int>(0x41b14c, 0xBEBFBC70),
std::pair<int,int>(0x41b150, 0x289B7EC6),
std::pair<int,int>(0x41b154, 0xEAA127FA),
std::pair<int,int>(0x41b158, 0xD4EF3085),
std::pair<int,int>(0x41b15c, 0x04881D05),
std::pair<int,int>(0x41b160, 0xD9D4D039),
std::pair<int,int>(0x41b164, 0xE6DB99E5),
std::pair<int,int>(0x41b168, 0x1FA27CF8),
std::pair<int,int>(0x41b16c, 0xC4AC5665),
};
std::array<std::pair<int, int>, 16> constAddr4 = {
std::pair<int,int>(0x41b170, 0xF4292244),
std::pair<int,int>(0x41b174, 0x432AFF97),
std::pair<int,int>(0x41b178, 0xAB9423A7),
std::pair<int,int>(0x41b17c, 0xFC93A039),
std::pair<int,int>(0x41b180, 0x655B59C3),
std::pair<int,int>(0x41b184, 0x8F0CCC92),
std::pair<int,int>(0x41b188, 0xFFEFF47D),
std::pair<int,int>(0x41b18c, 0x85845DD1),
std::pair<int,int>(0x41b190, 0x6FA87E4F),
std::pair<int,int>(0x41b194, 0xFE2CE6E0),
std::pair<int,int>(0x41b198, 0xA3014314),
std::pair<int,int>(0x41b19c, 0x4E0811A1),
std::pair<int,int>(0x41b1a0, 0xF7537E82),
std::pair<int,int>(0x41b1a4, 0xBD3AF235),
std::pair<int,int>(0x41b1a8, 0x2AD7D2BB),
std::pair<int,int>(0x41b1ac, 0xEB86D391),
};
DWORD AddressValue(DWORD addr)
{
for (auto& p : constAddr1) if (p.first == addr) return p.second;
for (auto& p : constAddr2) if (p.first == addr) return p.second;
for (auto& p : constAddr3) if (p.first == addr) return p.second;
for (auto& p : constAddr4) if (p.first == addr) return p.second;
assert("address not found." && 0);
return 0;
}
int Rol(int a1, char a2)
{
__asm__( //AT&T模式 ,参数位置相反
"rol %%cl, %%eax"
:"=a"(a1)
:"a"(a1),"c"(a2)
);
return a1;
}
// 0x401700
unsigned int* ComputeKey(char* str, unsigned int *key)
{
int esi = key[0];
int edi = key[1];
int ebp = key[2];
int ebx = key[3];
PDWORD v11 = PDWORD(str + 8);
int ii = 0;
for (int i = 0; i < 4; ++i)
{
esi = edi + Rol(constAddr1[ii].second + (edi & ebp | ebx & ~edi) + esi + v11[-2], 7);
ebx = esi + Rol(constAddr1[ii+1].second + (esi & edi | ebp & ~esi) + ebx + v11[-1], 12);
ebp = ebx + Rol(AddressValue((DWORD)((char *)v11 + constAddr1[0].first - str)) + (esi & ebx | edi & ~ebx) + ebp + v11[0], 17);
edi = ebp + Rol(AddressValue((DWORD)((char *)v11 + constAddr1[1].first - str)) + (ebp & ebx | esi & ~ebp) + edi + v11[1], 22);
ii += 4;
v11 += 4; // 一次加 16 字节
}
ii = 0;
BYTE original_6 = 6;
for (int i = 0; i < 4; ++i)
{
int v1 = Rol(constAddr2[ii].second + (edi & ebx | ebp & ~ebx) + esi + *PDWORD(str + 4 * ((original_6 - 5) & 0xF)), 5);
esi = edi + v1;
int v2 = Rol(constAddr2[ii+1].second + ((edi + v1) & ebp | edi & ~ebp) + ebx + *PDWORD(str + 4 * (original_6 & 0xF)), 9);
ebx = esi + v2;
int v3 = Rol(constAddr2[ii+2].second + (edi & (esi + v2) | esi & ~edi) + ebp + *PDWORD(str + 4 * ((original_6 + 5) & 0xF)), 14);
ebp = ebx + v3;
edi = ebp + Rol(constAddr2[ii+3].second + (esi & (ebx + v3) | ebx & ~esi) + edi + *PDWORD(str + 4 * ((original_6 - 6) & 0xF)), 20);
original_6 += 4;
ii += 4;
}
ii = 0;
int v33 = ebp ^ ebx;
BYTE original_neg_5 = -5;
int original_neg_8 = -8;
for (int i = 0; i < 4; ++i)
{
int v1 = Rol(constAddr3[ii].second + (edi ^ v33) + esi + *PDWORD(str + 4 * ((original_neg_5 - 6) & 0xF)), 4);
esi = edi + v1;
int v2 = Rol(constAddr3[ii+1].second + ((edi + v1) ^ edi ^ ebp) + ebx + *PDWORD(str + 4 * (original_neg_8 & 0xF)), 11);
ebx = esi + v2;
int v3 = Rol(constAddr3[ii+2].second + (esi ^ edi ^ (esi + v2)) + ebp + *PDWORD(str + 4 * (original_neg_5 & 0xF)), 16);
ebp = ebx + v3;
int v4 = ebp ^ ebx;
edi = ebp + Rol(constAddr3[ii+3].second + (esi ^ v4) + edi + *PDWORD(str + 4 * ((original_neg_5 + 3) & 0xF)), 23);
v33 = v4;
original_neg_8 -= 4;
original_neg_5 -= 4;
ii += 4;
}
ii = 0;
BYTE original_0 = 0;
BYTE original_neg_2 = -2;
for (int i = 0; i < 4; ++i)
{
int v1 = Rol(constAddr4[ii].second + (ebp ^ (edi | ~ebx)) + esi + *PDWORD(str + 4 * (original_0 & 0xF)), 6);
esi = edi + v1;
int v2 = Rol(constAddr4[ii+1].second + (edi ^ ((edi + v1) | ~ebp)) + ebx + *PDWORD(str + 4 * ((original_neg_2 - 7) & 0xF)), 10);
ebx = esi + v2;
int v3 = Rol(constAddr4[ii+2].second + (esi ^ ((esi + v2) | ~edi)) + ebp + *PDWORD(str + 4 * (original_neg_2 & 0xF)), 15);
ebp = ebx + v3;
edi = ebp + Rol(constAddr4[ii+3].second + (ebx ^ ((ebx + v3) | ~esi)) + edi + *PDWORD(str + 4 * ((original_neg_2 + 7) & 0xF)), 21);
original_0 -= 4;
original_neg_2 -= 4;
ii += 4;
}
key[0] += esi;
key[1] += edi;
key[2] += ebp;
key[3] += ebx;
return key;
}
unsigned __int64 Lshl(DWORD high, DWORD low, int shift, PDWORD high1, PDWORD low1)
{
unsigned __int64 v1 = (unsigned __int64)high << 32 | low;
v1 <<= shift;
*high1 = (DWORD)(v1 >> 32);
*low1 = (DWORD)v1;
return v1;
}
unsigned __int64 Rol64(unsigned __int64 a, char shift, PDWORD high1, PDWORD low1)
{
unsigned __int64 v1 = (a << shift) | (a >> (64 - shift));
*high1 = (DWORD)(v1 >> 32);
*low1 = (DWORD)v1;
return v1;
}
unsigned __int64 Ror64(unsigned __int64 a, char shift, PDWORD high1, PDWORD low1)
{
unsigned __int64 v1 = (a >> shift) | (a << (64 - shift));
*high1 = (DWORD)(v1 >> 32);
*low1 = (DWORD)v1;
return v1;
}
unsigned int* ParseCodeReverse(unsigned int *a1, int a2)
{
DWORD esi, edi;
esi = a1[0];
edi = a1[1];
while (a2--)
{
edi ^= (!!(esi & 0x4) ^ !!(esi & 0x2000) ^ !!(esi & 0x80000000));
Ror64((unsigned __int64)edi << 32 | esi, 1, &edi, &esi);
}
a1[0] = esi;
a1[1] = edi;
return 0;
}
unsigned int* ParseCode(unsigned int *a1, int a2)
{
DWORD esi, edi;
esi = a1[0];
edi = a1[1];
while (a2--)
{
Rol64((unsigned __int64)edi << 32 | esi, 1, &edi, &esi);
edi ^= (!!(esi & 0x4) ^ !!(esi & 0x2000) ^ !!(esi & 0x80000000));
}
a1[0] = esi;
a1[1] = edi;
return 0;
}
int main()
{
char str[512] = {0};
char usr[50] = {0}; //username
char str1[50] = {0}; //username rev
//char *pid; //ProductId
//char *rid; //RegisteredOwner
printf("用户名: ");
scanf("%s", usr);
sprintf(str1,"%s",usr);
_strrev(str1);
sprintf(str,"%s%s%s%s", usr,str1,str1,str1); //win10没有后两个,直接用反串顶
memset(str + strlen(str), 0, sizeof(str) - strlen(str));
int pos = 0x40 - (strlen(str) + 1) & 0x3f;
if (pos <= 7) pos += 0x40;
pos += strlen(str) + 1;
str[strlen(str)] = '\x80';
*PDWORD(str + pos - 8) = strlen(str) * 8;
unsigned int key[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
for (int i = 0; i < pos; i += 0x40)
ComputeKey(str + i, key);
key[0] &= 0xffff;
for (int i = 2; i >= 0; --i) // i 也要倒过来
ParseCodeReverse(&key[i], 0xbadc0de / (0x50 + i));
printf("注册码: %X %X %X %X\n", key[0], key[1], key[2], key[3]);
scanf("%s", str);
return 0;
}
运行示例:
用户名: 52pojie.cn
注册码: 3DCC2E7F 5372B58F D4794A48 26E8502B
1~160每个破解过程,在吾爱破解论坛都有高手破解过了,也有整理好现成的, 我这边主要就是自己动手操作的过程,与他们的不太一样
附上高手们的连接: 点击前往查看
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载
新人入门教程"玩玩破解,写给新人看" 点击前往查看
我就是从这里开始的,对我这样的小白感觉超级友好~
下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~


浙公网安备 33010602011771号