能力值:
( LV2,RANK:10 )
226 楼
写的很详细,谢谢!
能力值:
( LV2,RANK:10 )
227 楼
呵呵。第一次比较系统的分析这个crackMe,用了差不多1天的时间才把这些算法给搞成C格式。运行了下,还算行是可以用,只是不晓得是不是不够精简,希望大侠们给点意见
UINT calc()
{
UINT a;
t *= 0x343fd;
t += 0x269ec3;
a = t >>0x10;
a &= 0x7fff;
return a;
}
void main (int argc, char *argv[])
{
UINT tmpvalue;
char strname[16] = {'a','a','a','a','\0'}; //输入的注册名称
char strreg[16] ; //输入的注册系列号
char strtmp[16]; //中间根据注册名产生的正确的注册系列号
t = (byte)strname[0] % (byte)strname[1];
t = t * (byte)strname[2] +1;
t = 0xffffffff / t;
for (UINT i = 0; i < 15; i++)
{
tmpvalue = calc();
tmpvalue %= 0x1a;
tmpvalue += 0x41;
strtmp[i] = (char)tmpvalue;
}
for (i = 0; i < strlen(strname); i++)
{
int tval,edx,ebx=0;
char tmpch = strname[i];
tmpch >>= 5;
tval = tmpch;
edx = 5 * tval;
tval *= 123;
for (int j = tval; j > 0; j--)
calc();
tmpvalue = calc();
tmpvalue %= 0x1a;
tmpvalue += 0x41;
strtmp[i] = (char)tmpvalue;
tmpvalue -= strreg[i];
tmpvalue ^= edx;
tmpvalue -= edx;
ebx += tmpvalue;
}
}
能力值:
( LV2,RANK:10 )
228 楼
最后行市废话,可以去掉,呵呵,对生产序列号没有什么意向,是输入比较的时候用的。见谅
能力值:
( LV2,RANK:10 )
229 楼
受益匪浅~~~
能力值:
( LV2,RANK:10 )
230 楼
支持下啊..........
能力值:
( LV13,RANK:388 )
231 楼
给出我的算法 ,你比较看看
#include "stdafx.h"
#include <string.h>
unsigned int var_4050ac,var_eax; //DWORD
void sub_40134a()
{
var_4050ac=var_4050ac*0x343FD+0x269EC3;
var_eax=var_4050ac>>16;
var_eax=var_eax&32767;
}
int main(int argc, char* argv[])
{
char name[10],serial[10];
int i,p,t;
printf("Plz input your name:");
scanf("%s",name);
var_eax=0xFFFFFFFF/((name[0]%name[1])*name[2]+1);
var_4050ac=var_eax;
for(i=0;i<15;i++) //riijj版主的破文里认为要循环16次,其实是15次
{
sub_40134a();
}
for(i=0;i<strlen(name);i++)
{
var_eax=name[i]>>5;
var_eax=var_eax*123;
t=var_eax;
for(p=0;p<=t;p++)
{
sub_40134a();
}
serial[i]=var_eax%0x1a+0x41;
}
serial[strlen(name)]='\0';
printf("Your serial is:%s\n",serial);
return 0;
}
能力值:
( LV3,RANK:30 )
232 楼
真是个好帖,特别是下面的代码感觉很经典。受益了。。。 谢谢,riijj大大。
004012FF |. 0FBE4C34 2C |MOVSX ECX, BYTE PTR SS:[ESP+ESI+2C]
00401304 |. 80C2 41 |ADD DL, 41
00401307 |. 0FBEC2 |MOVSX EAX, DL
0040130A |. 2BC1 |SUB EAX, ECX
0040130C |. 885434 1C |MOV BYTE PTR SS:[ESP+ESI+1C], DL
00401310 |. 99 |CDQ
00401311 |. 33C2 |XOR EAX, EDX
00401313 |. 83C9 FF |OR ECX, FFFFFFFF
00401316 |. 2BC2 |SUB EAX, EDX
00401318 |. 03D8 |ADD EBX, EAX
0040131A |. 33C0 |XOR EAX, EAX
0040131C |. 46 |INC ESI
0040131D |. F2:AE |REPNE SCAS BYTE PTR ES:[EDI]
0040131F |. F7D1 |NOT ECX
00401321 |. 49 |DEC ECX
00401322 |. 3BF1 |CMP ESI, ECX
00401324 |.^ 72 A7 \JB SHORT ncrackme.004012CD
00401326 |> 5F POP EDI
00401327 |. 8BC3 MOV EAX, EBX Reg name: kanxue
Reg key: MPFUMR
能力值:
( LV2,RANK:10 )
233 楼
不懂哦。。。。看不懂第二部分就开始看不懂了
能力值:
( LV2,RANK:10 )
234 楼
第一次写这个。。。
#include <stdio.h>
#include <string.h>
int getvalue(int *save);
int main(void)
{
int val1,save,i_name,tmp;
char name[16];
char str[100];
printf("请输入用户名:");
gets(name);
if(strlen(name) < 3)
{
printf("用户名太短\n");
return 1;
}
save = 0xffffffff/((name[0]%name[1])*name[2]+1);
for(int i=0;i < 15;i++)
getvalue(&save);
for(int j=0;j < strlen(name);j++)
{
i_name = name[j];
i_name >>= 0x5;
tmp = i_name+i_name*4;
i_name = i_name+tmp*8;
i_name = i_name+i_name*2;
for(int k=0;k < i_name;k++)
getvalue(&save);
val1 = getvalue(&save);
str[j] = val1 % 0x1A + 0x41;
}
str[j] = '\0';
printf("序列号为:");
puts(str);
getchar();
return 0;
}
int getvalue(int *save)
{
int tmp;
*save = *save * 0x343FD + 0x269EC3;
tmp = *save;
tmp >>= 0x10;
tmp &= 0x7FFF;
return tmp;
}
能力值:
( LV12,RANK:200 )
235 楼
OD加载的内容和楼主的好像不一样!
能力值:
( LV2,RANK:10 )
236 楼
不错,学习了
能力值:
( LV15,RANK:280 )
237 楼
能力值:
( LV2,RANK:10 )
238 楼
请帖留名
能力值:
( LV2,RANK:10 )
239 楼
很详细,得努力学习。
能力值:
( LV2,RANK:10 )
240 楼
潜水好多年,决心认真学习,支持
能力值:
( LV2,RANK:10 )
241 楼
感谢楼主分享。破解还是需要汇编基础的。
能力值:
( LV4,RANK:50 )
242 楼
好文章,收藏起来学习!
能力值:
( LV2,RANK:10 )
243 楼
从基础学起,好文!
能力值:
( LV2,RANK:10 )
244 楼
好文章,一定要收藏
能力值:
( LV4,RANK:50 )
245 楼
void main()
{
char UserName[] = "steven";
int len = strlen(UserName);
if(len < 3)return;
srand(0xFFFFFFFFu / (UserName[2] * (UserName[0] % UserName[1]) + 1));
for (int j = 0; j < 0xF; j++)rand();
for (int i = 0; i < len; i++)
{
for (int k = 123 * (UserName[i] >> 5); k > 0; k--) rand();
printf("%c\t",rand() % 26 + 65);//获取注册密码
}
}
能力值:
( LV2,RANK:10 )
246 楼
同意15楼的观点,继续学习中,虽然现在看的还有点吃力,但是跟着楼主的教程先努力跟一遍,找点经验先....
能力值:
( LV3,RANK:20 )
247 楼
支持!!! 加油哇!
能力值:
( LV2,RANK:10 )
248 楼
楼主你上面的基本上我搞懂了一些,但是最后一点还是有点疑问:我们把 crackme 再运行一次,在 0040130A 设下断点,记录每一个 EAX 的值
50 4d 51 4a 44
把这些值转换成 ASCII,那就是
P M Q J D
现在,我们再运行 crackme ,以 riijj 作为名字, PMQJD 作为序号,成功注册了!
可是我的问题是:当你再次运行的时候,在 0040130A 处设下了断点,可是当你按F9运行,然后就会弹出一个注册框,此时你还不清楚具体的注册码,所以我就随便输了一个,然后再次按F9,每次记录其中EAX寄存器的值,可是得到只是我输入的字符串的值啊,得不到PMQJD啊?不好意思,我是菜鸟,可能问题有点弱,可是我尝试了,一直得不到答案。
能力值:
( LV2,RANK:10 )
249 楼
学习了 谢谢lz,
能力值:
( LV2,RANK:10 )
250 楼
这种讲解详细的文章对于我这个破解菜鸟来说就是福音啊!
顶LZ,希望再多发表几篇这样的好文章,让我们这些菜鸟多学习学习