能力值:
( LV2,RANK:10 )
|
-
-
151 楼
不错啊 学习了哦 支持
|
能力值:
( LV2,RANK:10 )
|
-
-
152 楼
,调试MFC程序,需先倒入MFC的LIB文件,否则MFC里面的函数将无法解析。deg--->select import libraries--->MFC42.LIB,MFC71.LIB ,然后点击process.
额
|
能力值:
( LV2,RANK:10 )
|
-
-
153 楼
这个必须要学习,占位!
|
能力值:
( LV3,RANK:20 )
|
-
-
154 楼
回复标记下 方便下次看 谢谢楼主
|
能力值:
( LV2,RANK:10 )
|
-
-
155 楼
新手,分析了 zenghw的crackme系列,不能在原帖处直接回复,只好在这里把过程分享一下:
http://bbs.pediy.com/showthread.php?t=93936
尝试破解crackme04修正版。
这个程序除了对用户名和cpuid信息进行hash运算之外,还对程序的代码段进行了验证,因为是第一次分析这样的程序,费了些时间:
.text:00401150 sub_401150 proc near
.text:00401150 push 0FFFFFFFFh
.text:00401152 push offset SEH_401150 ; Microsoft VisualC 2-10/net runtime
.text:00401152 ; MFC 3.1-10.0 32bit
.text:00401157 mov eax, large fs:0
.text:0040115D push eax
.text:0040115E mov large fs:0, esp
.text:00401165 sub esp, 0F8h
.text:0040116B push esi
.text:0040116C mov esi, ecx
.text:0040116E call ds:InitCommonControls
.text:00401174 mov ecx, esi
.text:00401176 call ?InitInstance@CWinApp@@UAEHXZ ; CWinApp::InitInstance(void)
.text:0040117B push 0
... ...
.text:004011A3 mov [esp+108h+var_4], 0
.text:004011AE call ?DoModal@CDialog@@UAEHXZ ; 这里显示主对话框
.text:004011B3 cmp eax, 1
.text:004011B6 jnz short loc_40121C ;如果domal返回1,才会进行后面的内存校验,进而显示提示成功的对话框
.text:004011B8 push 0 ; lpIconName
.text:004011BA lea ecx, [esp+10Ch+var_104]
.text:004011BE call sub_4012F0
.text:004011C3 lea eax, [esp+108h+var_104]
.text:004011C7 push 0 ; lpModuleName
.text:004011C9 mov byte ptr [esp+10Ch+var_4], 1
.text:004011D1 mov [esi+20h], eax
.text:004011D4 call ds:GetModuleHandleA
.text:004011DA mov ecx, [eax+3Ch]
.text:004011DD movzx edx, word ptr [ecx+eax+14h]
.text:004011E2 mov esi, [ecx+eax-4]
.text:004011E6 add ecx, eax
.text:004011E8 lea ecx, [edx+ecx+18h]
.text:004011EC mov edx, [ecx+8]
.text:004011EF mov ecx, [ecx+0Ch]
.text:004011F2 push edx; 跟踪得知,第2个参数是 0x001A94,代码段的长度
.text:004011F3 add ecx, eax
.text:004011F5 push ecx ; 跟踪得知,第1个参数是 0x401000,代码段开始的位置
.text:004011F6 call sub_401040 ;对crackme04的代码段进行校验
.text:004011FB add esp, 8
.text:004011FE cmp esi, eax ; 和0x4000EC处读出的值【0x44EEA41C】比较,相等表明crackme04代码段没有被篡改
.text:00401200 lea ecx, [esp+108h+var_104]
.text:00401204 jnz short loc_40120F
sub_401040 对代码段进行校验,基本的算法是:
1,首先,填充一个0x400字节长的buffer:
计算从nc从0增加到0xFF,每次加1。对于每步中n的数值,其值有几个bit 1,就把该该值右移一位后于0x0EDB88320做异或操作。
并把得到的填充到一个0x400字节长的buffer中,凭自己的理解整理下:
char buffer[0x100]; /*0x400字节长*/
for(n=0;n<0x100;n+1)
{
for(x=0,m=n;;x<8;)
{
m>>1;
if(m & 1)
{
m ^= 0x0EDB88320;
}
}
buffer[n]=m;
2,令p = -1;
然后从buffer中位置y取值k,位置y等于0x401000的第x个字节的值与p异或后所得到的值),
再 p = (p>>8) ^k
x从0到0x001A94,x实际上是覆盖了所有的代码段
最后返回 not p(~p)
0x4000EC中保存的是exe文件的dos 文件头的最后一个字节。
|
能力值:
( LV2,RANK:10 )
|
-
-
156 楼
0x0EDB88320,这个特征码
|
能力值:
( LV2,RANK:10 )
|
-
-
157 楼
有意思,呵呵
|
能力值:
( LV7,RANK:100 )
|
-
-
158 楼
crack3答案贴的对么?
abcdef为例
不是 除数=a*b*c*2 && 余数=e*d*3?
AAAAAA
54925012675
|
能力值:
( LV7,RANK:100 )
|
-
-
159 楼
crackme4 的注册机
void Docode1BycpuId(char* str)
{
char cpuid0[14];
int a1,a2,a3;
strcpy(cpuid0, "------------");
CString strCpu0,strCpu1,strCpu2;
_asm
{
pushad
pushfd
mov eax,0
cpuid
mov a1,ebx
mov a2,edx
mov a3,ecx
popfd
popad
}
*(DWORD *)cpuid0 = a1;
*(DWORD *)&cpuid0[4] = a2;
*(DWORD *)&cpuid0[8] = a3;
strCpu0.Format("%s-",cpuid0);//cpu name
_asm
{
pushad
pushfd
mov eax,1
cpuid
mov a1,edx
mov a2,eax
popfd
popad
}
strCpu1.Format( "%08X%08X", a1, a2);
_asm
{
pushad
pushfd
mov eax,3
cpuid
mov a1,edx
mov a2,ecx
popfd
popad
}
strCpu2.Format( "%08X%08X", a1, a2);
strCpu0 = strCpu1 + strCpu2;
strcpy(str,strCpu0);
}
int HexStringToInt(char* sz)
{
int lenth = strlen(sz);
int sum = 0;
int temp;
for (int i=0;i<lenth;i++)
{
if (sz[lenth-i-1]>='0' && sz[lenth-i-1]<= '9')
{
temp =sz[lenth-i-1] - '0';
}
else
{
switch(sz[lenth-i-1])
{
case 'A':
case 'a':
temp = 0xAu;
break;
case 'B':
case 'b':
temp = 0xBu;
break;
case 'C':
case 'c':
temp = 0xCu;
break;
case 'D':
case 'd':
temp = 0xDu;
break;
case 'E':
case 'e':
temp = 14;
break;
case 'F':
case 'f':
temp = 15;
break;
default:
break;
}
}
temp = temp <<(4*i);
sum+=temp;
}
//printf("HexStringToInt 0x%8x\n",sum);
return sum;
}
int GetHash(char* sz)
{
char szTemp[10] = {0};
int arr[4];
CString strTrans;
//字符串分成四组
//printf("string is %s\n",sz);
for (int i=0;i<4;i++)
{
memcpy(szTemp,&sz[i*8],8);
szTemp[8] = 0;
arr[i] = HexStringToInt(szTemp);
}
int temp = arr[0]^arr[2]^arr[1]^arr[3];
//intf("0x%8x",temp);
return temp;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int mulPlus = 2;
char* userName = "abcdef";
int i = 0;
char cpuid[0x50];
char szTemp[0x200];
while (1)
{
char tempChar = userName[i];
mulPlus = mulPlus*tempChar;
i++;
if (i>=3 && strlen(userName) == 6)
{
Docode1BycpuId(cpuid);
int retHash = GetHash(cpuid);
sprintf(szTemp,"%x",mulPlus|retHash);
printf("xor Hash is %s\n",szTemp);
system("pause");
char szDigest[60];
MD5Digest(szTemp,strlen(szTemp),szDigest);
for (int k=0;k<16;k++)
{
sprintf(&szTemp[k*2],"%02X",(UCHAR)szDigest[k]);
}
printf("md5 is %s\n",szTemp);
retHash = GetHash(szTemp);
printf("reg code is %I64d\n",retHash);
system("pause");
return 0;
}
}
return 0;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
160 楼
不错 正好学习下
|
能力值:
( LV3,RANK:20 )
|
-
-
161 楼
学习了,每天一破,已经到2了,顶楼主,顶楼上的各位大大
|
能力值:
( LV3,RANK:20 )
|
-
-
162 楼
crack3算法已出,搞死偶等菜鸟了
|
能力值:
( LV3,RANK:20 )
|
-
-
163 楼
发个贴,偶等菜鸟终于将crack4爆破鸟,貌似算法有点复杂,发完贴再破!!
|
能力值:
( LV2,RANK:10 )
|
-
-
164 楼
好强的帖子啊。。
|
能力值:
( LV3,RANK:20 )
|
-
-
165 楼
crack4内出现了注册码明码比较啊。。。
|
能力值:
( LV3,RANK:20 )
|
-
-
166 楼
crack4真心跟得蛋疼。。。大致的加密步骤搞懂了,妹的4018B0实在不想跟了。。。发个牢骚,继续跟!!
|
能力值:
( LV3,RANK:20 )
|
-
-
167 楼
CrackMe4修正版serial num 木用啊,就只对name进行了操作。。。偶放弃搞Reverse了。。。爆破吧,我的神奇宝贝
|
能力值:
( LV2,RANK:10 )
|
-
-
168 楼
如果没看错的话,MD5之后再处理,和0x59A16298比较已经知道只能用穷举的方法来写注册机了。。
|
能力值:
( LV2,RANK:10 )
|
-
-
169 楼
4里面是如何下中断的?我不知道这样的如何去下中断
|
能力值:
( LV2,RANK:10 )
|
-
-
170 楼
呜呜,才把第一个破解了
|
能力值:
( LV2,RANK:10 )
|
-
-
171 楼
成功完成第2个的爆破
|
能力值:
( LV2,RANK:10 )
|
-
-
172 楼
我在64位机下调试,为何使用Ultra String Reference没有提示字符串。使用immunity debugger查找字符串也找不到,请问是何原因?
|
能力值:
( LV2,RANK:10 )
|
-
-
173 楼
一个都玩不动
|
能力值:
( LV2,RANK:10 )
|
-
-
174 楼
好像只有第一个显式调用字符串,其他都是一个byte一个byte赋值的,当然找不到
|
能力值:
( LV3,RANK:20 )
|
-
-
175 楼
MFCbutton断点
参考:
http://bbs.pediy.com/showthread.php?t=20078
|
|
|