能力值:
( LV2,RANK:10 )
2 楼
大侠可以提供 Crackme 吗?
能力值:
( LV2,RANK:10 )
3 楼
最初由 springkang[DFCG 发布 最近跟了一个Crackme,算法基本搞懂了,在写注册机的时候,遇到一个问题,如下: 假设伪码为a,长度为j,crackme的算法为: m:=0; for i:=1 to j do ........
此代码的作用应该是将a[i]转化为16进制
DDBEE106他的十进制数字机为注册码3720274182
不知正确吗?
能力值:
( LV4,RANK:50 )
4 楼
估计是要穷举
能力值:
( LV9,RANK:970 )
5 楼
最初由 mutouren 发布 此代码的作用应该是将a转化为16进制 DDBEE106他的十进制数字机为注册码3720274182 不知正确吗?
正解,就是16进制和10进制转换。
能力值:
(RANK:410 )
6 楼
//这个算法的反算很简单。只需将机器码($DDBEE106)除2取余,得取余得到的数反转并转换成字符串就是注册码。如下是生成注册码的函数:
char* DeCrypt(unsigned long Code, char* lpOutSn)
{
for (int i = 0; Code >= 9;i++)
{
char c = (char)(Code % 8);
Code -= c;
c += (char)(Code % 2);
Code /= 2;
lpOutSn[i] = c + (char)0x30;
}
lpOutSn[i] = (char)(Code + 0x30);
for (int j = 0; j <= i; j++)
{
char tmp = lpOutSn[j];
lpOutSn[j] = lpOutSn[i];
lpOutSn[i] = tmp;
i--;
}
return lpOutSn;
}
机器码:0xDDBEE106
注册码:440444044044444044400004000006
能力值:
(RANK:410 )
7 楼
//Delphi代码
Function DeCrypt(Code:LongWord; lpOutSn:pChar):pChar;
var i,j:Integer;
c,tmp:Char;
begin
i := 0;
while Code >= 9 do
begin
c := Char(Code mod 8);
Code := Code - LongWord(c);
c := Char(LongWord(c) + Code mod 2);
Code := Code div 2;
lpOutSn[i] := Char(Byte(c) + $30);
i := i + 1;
end;
lpOutSn[i] := Char(Code+$30);
j := 0;
while j <= i do
begin
tmp := lpOutSn[j];
lpOutSn[j] := lpOutSn[i];
lpOutSn[i] := tmp;
i := i - 1;
j := j + 1;
end;
ResUlt := lpOutSn;
end;
能力值:
( LV12,RANK:450 )
8 楼
谢谢小虾,偶再看看.。
crackme上传。
上传的附件:
能力值:
( LV12,RANK:450 )
9 楼
最初由 mutouren 发布 此代码的作用应该是将a转化为16进制 DDBEE106他的十进制数字机为注册码3720274182 不知正确吗?
算法偶简化了,其实DDBEE106是根据GetVolumeInformationA再进行一些运算得出的,不是注册码。具体可以跟一下crackme。
能力值:
(RANK:410 )
10 楼
我少看了一句m := m * 4的代码,
你所说的代码是将十六进制的值转成十进制的值的函数。
能力值:
( LV12,RANK:450 )
11 楼
最初由 小虾 发布 我少看了一句m := m * 4的代码, 你所说的代码是将十六进制的值转成十进制的值的函数。1、第一句就是 m:=m*5
2、是的,如何将DDBEE106还原成十进制数。
只需将机器码($DDBEE106)除2取余,得取余得到的数反转并转换成字符串就是注册码
这是什么原理呢?
能力值:
(RANK:410 )
12 楼
跟踪了一下CreaMe,算法很简单。注册码反算代码:
Function GetDeKey(Code:String):String;
var dwTmp,dwHigh:LongWord;
dwLow:Array[0..1] of LongWord;
begin
GetVolumeInformation(nil,pChar(@dwTmp),4,pDWORD(@dwHigh),dwTmp,dwTmp,pChar(@dwLow),8);
dwHigh := dwHigh + dwLow[0];
ResUlt := IntToStr(dwHigh);
end;
能力值:
(RANK:410 )
13 楼
//这里有一处Anti-Debug代码,用插件可以很容易通过
004011A4 . E8 BB020000 CALL <JMP.&kernel32.IsDebuggerPresent> ; [IsDebuggerPresent
004011A9 . 0BC0 OR EAX,EAX
004011AB . 74 05 JE SHORT CRACKME1.004011B2
004011AD . E9 41010000 JMP CRACKME1.004012F3
004011B2 > E8 60010000 CALL CRACKME1.00401317 //取机器码函数
这个函数是取机器码函数,这个函数可以说就是注册机代码了,写注册机时可以照抄这里的代码
00401317 /$ 55 PUSH EBP
00401318 |. 8BEC MOV EBP,ESP
0040131A |. 83C4 F4 ADD ESP,-0C
//调用GetVolumeInformationA函数获取机器码
0040131D |. 68 FF000000 PUSH 0FF
00401322 |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
00401325 |. 50 PUSH EAX
00401326 |. 6A 00 PUSH 0
00401328 |> 6A 00 PUSH 0 ; |pMaxFilenameLength = NULL
0040132A |. 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4] ; |
0040132D |. 50 PUSH EAX ; |pVolumeSerialNumber
0040132E |. 68 FF000000 PUSH 0FF ; |MaxVolumeNameSize = FF (255.)
00401333 |. 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8] ; |
00401336 |. 50 PUSH EAX ; |VolumeNameBuffer
00401337 |. 6A 00 PUSH 0 ; |RootPathName = NULL
00401339 |. E8 20010000 CALL <JMP.&kernel32.GetVolumeInformation>; \GetVolumeInformationA
0040133E |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
00401341 |. 8B5D F4 MOV EBX,DWORD PTR SS:[EBP-C]
//取出ebp-4和ebp-c里的值进行相加后的和再转化成十进制的字符串就是注册码了
00401344 |. 03C3 ADD EAX,EBX
00401346 |. E8 12000000 CALL CRACKME1.0040135D
0040134B |. 2D 47434644 SUB EAX,44464347
00401350 |. 68 5C314000 PUSH CRACKME1.0040315C ; ASCII "68B20274"
00401355 |. 50 PUSH EAX
00401356 |. E8 69010000 CALL CRACKME1.004014C4
0040135B |. C9 LEAVE
0040135C \. C3 RETN
//这里开始获取用户输入的注册码开始进行验证
0040126E . 6A 14 PUSH 14 ; /Count = 14 (20.)
00401270 . 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10] ; |
00401273 . 50 PUSH EAX ; |Buffer
00401274 . FF35 35314000 PUSH DWORD PTR DS:[403135] ; |hWnd = 000007DC
//获取用户输入的注册码
0040127A . E8 8B010000 CALL <JMP.&user32.GetWindowTextA> ; \GetWindowTextA
0040127F . 8D45 F0 LEA EAX,DWORD PTR SS:[EBP-10]
00401282 . 50 PUSH EAX
//注用户输入的注册码以十进制的字符转化成十进制的Int整数类型对应Delphi的StrToInt函数
00401283 . E8 E8010000 CALL CRACKME1.00401470
对转化后注册码进行运算函数
00401288 . E8 13010000 CALL CRACKME1.004013A0
验证注册码函数
0040128D . E8 2D010000 CALL CRACKME1.004013BF
00401292 . 84C0 TEST AL,AL
00401294 . 74 46 JE SHORT CRACKME1.004012DC
能力值:
( LV12,RANK:450 )
14 楼
最初由 小虾 发布 00401339 |. E8 20010000 CALL <JMP.&kernel32.GetVolumeInformation>; \GetVolumeInformationA 0040133E |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00401341 |. 8B5D F4 MOV EBX,DWORD PTR SS:[EBP-C] //取出ebp-4和ebp-c里的值进行相加后的和再转化成十进制的字符串就是注册码了
分析得不错。
只是那个涵数的逆运算还是没搞懂。
00401394 |. C1C0 02 rol eax, 2 00401397 |. 0FC8 bswap eax 00401399 |. A3 68314000 mov [403168], eax //又跟了一下,昨天没仔细看到上面三句
多谢小虾费心了。
能力值:
(RANK:410 )
15 楼
那个函数就是和Delphi的StrToInt函数一样的。Delphi的IntToStr就是这个函数的逆运算。
m:=0;
for i:=1 to j do
begin
m:= m + m*4;
m:= Ord(a[i])-$30 + m*2;
end;
能力值:
( LV12,RANK:450 )
16 楼
在delphi里跟踪了一下,果然如小虾所说,是strtoint,难怪觉得这个涵数眼熟,好像原来见过。
顺便说一下在delphi跟踪的方法:
var
s:string;
i:integer;
begin
s:='123456';
i:= strtoint(s); //这里下断,断下后点view->debug->CPU
end;
00407CBE E851AEFFFF call @ValLong //跟进去
复制下来的汇编代码:
00402B64 742D jz +$2d
00402B66 80EB30 sub bl,$30 // ord(a[i])-$30
00402B69 80FB09 cmp bl,$09
00402B6C 7725 jnbe +$25
00402B6E 39F8 cmp eax,edi
00402B70 7721 jnbe +$21
00402B72 8D0480 lea eax,[eax+eax*4] // m:= m+m*4
00402B75 01C0 add eax,eax // m*2
00402B77 01D8 add eax,ebx //m:= ord(a[i])-$30 + m
00402B79 8A1E mov bl,[esi]
00402B7B 46 inc esi
00402B7C 84DB test bl,bl
00402B7E 75E6 jnz -$1a