好友
阅读权限35
听众
最后登录1970-1-1
|
本帖最后由 solly 于 2019-4-13 16:22 编辑
看看160个crackme集合大多数都在这里有教程,只有少数几个没有,选择了一个没有的试一下。
我选择了第152个,The AntiXryst,好象这个还没有教程,于是动手了。
这个程序在 CHM集合的列表中説是delphi编写的。先检查一下看看。
没检测到壳,省事不少。
有个RCDATA资源表,并含有一个TFORM1的资源,再通过UltraEdit看一下:
标准的Delphi程序第1节内容,是Delphi编写没有错了,通过 DeDeDark打开程序文件:
只有一个表单,而且只有一个事件 OnTimer,一看就是定时器事件,进入事件:
记住事件的起始地址:0x00457AF8。并记住一些delphi的系统调用,这些系统调用在OD中就不用去跟踪了。
启动OD,载入Crackme程序,直接右键”转到->表达式“,输入前面的地址:
来到 OnTimer 事件处理程序,先不下断,F9进入程序,输入一个用户名。
这个crackme的注册码通过一个checkbox矩陈来输入注册码。
回到OD下断,稍等一下OD就断下了程序,原来是通过定时器不停的来验证注册码。
下面是其汇编代码:
[Asm] 纯文本查看 复制代码 ; 以下是 Timer 的事件处理函数
00457AF8 /. 55 push ebp
00457AF9 |. 8BEC mov ebp, esp
00457AFB |. 83C4 8C add esp, -74
00457AFE |. 53 push ebx
00457AFF |. 56 push esi
00457B00 |. 57 push edi
00457B01 |. 33C9 xor ecx, ecx
00457B03 |. 894D 8C mov dword ptr [ebp-74], ecx
00457B06 |. 894D F8 mov dword ptr [ebp-8], ecx
00457B09 |. 8BD8 mov ebx, eax
00457B0B |. 33C0 xor eax, eax
00457B0D |. 55 push ebp
00457B0E |. 68 337C4500 push 00457C33 ; SEH 地址
00457B13 |. 64:FF30 push dword ptr fs:[eax] ; 保存上一个SEH地址
00457B16 |. 64:8920 mov dword ptr fs:[eax], esp ; 设置当前SEH地址为 0x00457C33
00457B19 |. 8D55 F8 lea edx, dword ptr [ebp-8]
00457B1C |. 8B83 68040000 mov eax, dword ptr [ebx+468]
00457B22 |. E8 A9F4FDFF call 00436FD0 ; GetText,读取注册名
00457B27 |. 8D55 8C lea edx, dword ptr [ebp-74]
00457B2A |. 8B45 F8 mov eax, dword ptr [ebp-8] ; eax==>注册名
00457B2D |. E8 16FBFAFF call 00407648 ; Delphi 函数:Trim()
00457B32 |. 837D 8C 00 cmp dword ptr [ebp-74], 0 ; 是否空串
00457B36 |. 0F84 D9000000 je 00457C15
00457B3C |. 8D45 A0 lea eax, dword ptr [ebp-60]
00457B3F |. E8 0CE9FFFF call 00456450 ; MD5初始化,4个DWORD引子
00457B44 |. 8B45 F8 mov eax, dword ptr [ebp-8] ; eax==>注册名
00457B47 |. E8 8CBFFAFF call 00403AD8 ; 取注册码名的长度
00457B4C |. 83F8 40 cmp eax, 40 ; eax=注册码的长度
00457B4F |. 7D 18 jge short 00457B69 ; 长度大于或等于0x40则跳过注册名复制加长
00457B51 |> 8D45 F8 /lea eax, dword ptr [ebp-8]
00457B54 |. 8B55 F8 |mov edx, dword ptr [ebp-8] ; edx==>注册名
00457B57 |. E8 84BFFAFF |call 00403AE0 ; 复制用户名并连接成一个新串,regName = regName + regName
00457B5C |. 8B45 F8 |mov eax, dword ptr [ebp-8] ; eax==>克隆后的注册名
00457B5F |. E8 74BFFAFF |call 00403AD8 ; 重新计算长度
00457B64 |. 83F8 40 |cmp eax, 40 ; eax 由 5,10,20,40,80...递增
00457B67 |.^ 7E E8 \jle short 00457B51
00457B69 |> 8B45 F8 mov eax, dword ptr [ebp-8]
00457B6C |. E8 67BFFAFF call 00403AD8 ; 最后取得克隆后的字符串长度
00457B71 |. 83F8 40 cmp eax, 40 ; eax==0x50==80
00457B74 |. 7E 24 jle short 00457B9A ; 长度小于或等于则跳转
00457B76 |> 8B45 F8 /mov eax, dword ptr [ebp-8] ; eax==>克隆加长后的注册名
00457B79 |. E8 5ABFFAFF |call 00403AD8 ; 取长度
00457B7E |. 8BD0 |mov edx, eax
00457B80 |. 8D45 F8 |lea eax, dword ptr [ebp-8]
00457B83 |. B9 01000000 |mov ecx, 1 ; 删除的字符数
00457B88 |. E8 8FC1FAFF |call 00403D1C ; 删除注册名最后1个字符
00457B8D |. 8B45 F8 |mov eax, dword ptr [ebp-8]
00457B90 |. E8 43BFFAFF |call 00403AD8 ; 计算长度
00457B95 |. 83F8 40 |cmp eax, 40 ; 是否长度为0x40
00457B98 |.^ 75 DC \jnz short 00457B76 ; 不是0x40则继续去删除最后1个字符
00457B9A |> 33D2 xor edx, edx ; int i = 0
00457B9C |. 8D45 B0 lea eax, dword ptr [ebp-50] ; 指向字符串第0字节,即delphi短String类型的保存长度的位置
00457B9F |> 8B4D F8 /mov ecx, dword ptr [ebp-8] ; ecx==>缩短后注册名,长度为0x40
00457BA2 |. 8A4C11 FF |mov cl, byte ptr [ecx+edx-1] ; 取string(i-1)位置字符, 第1次读取的字符为delphi字符串长度的高8位,为0
00457BA6 |. 8808 |mov byte ptr [eax], cl ; 复制注册名,第1个字节为'\0',前面缩短的注册名最后1字节没有复制
00457BA8 |. 42 |inc edx
00457BA9 |. 40 |inc eax
00457BAA |. 83FA 40 |cmp edx, 40
00457BAD |.^ 75 F0 \jnz short 00457B9F
00457BAF |. 8D55 A0 lea edx, dword ptr [ebp-60] ; edx==>MD5算法引子,0019FCD8: 01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10
00457BB2 |. 8D45 B0 lea eax, dword ptr [ebp-50] ; eax==>'\0' + 注册名前0x3F个字符
00457BB5 |. E8 FEE8FFFF call 004564B8 ; MD5运算
00457BBA |. 8D75 A0 lea esi, dword ptr [ebp-60] ; esi==>MD5计算后的值
00457BBD |. 8D7D 90 lea edi, dword ptr [ebp-70]
00457BC0 |. B9 04000000 mov ecx, 4
00457BC5 |. F3:A5 rep movs dword ptr es:[edi], dword ptr [esi]
00457BC7 |. 8D55 90 lea edx, dword ptr [ebp-70] ; edx==>前面MD5计算值,当作下一次的MD5引子
00457BCA |. 8D45 B0 lea eax, dword ptr [ebp-50] ; eax==>'\0' + 注册名前0x3F个字符
00457BCD |. E8 E6E8FFFF call 004564B8 ; MD5运算
00457BD2 |. 8B45 A0 mov eax, dword ptr [ebp-60] ; EAX=MD5_1[0],即第1次计算后的MD5第1个整数
00457BD5 |. 2B45 A4 sub eax, dword ptr [ebp-5C] ; EAX=MD5_1[0] - MD5_1[1]
00457BD8 |. 2B45 A8 sub eax, dword ptr [ebp-58] ; EAX=MD5_1[0] - MD5_1[1] - MD5_1[2]
00457BDB |. 0345 AC add eax, dword ptr [ebp-54] ; EAX=MD5_1[0] - MD5_1[1] - MD5_1[2] + MD5_1[3]
00457BDE |. 8945 A0 mov dword ptr [ebp-60], eax ; [EBP-60]=MD5_1[0] - MD5_1[1] - MD5_1[2] + MD5_1[3], 保存第1个SN整数
00457BE1 |. 8B45 90 mov eax, dword ptr [ebp-70] ; EAX=MD5_2[0],即第2次计算后的MD5第1个整数
00457BE4 |. 2B45 94 sub eax, dword ptr [ebp-6C] ; EAX=MD5_2[0] - MD5_2[1]
00457BE7 |. 2B45 98 sub eax, dword ptr [ebp-68] ; EAX=MD5_2[0] - MD5_2[1] - MD5_2[2]
00457BEA |. 0345 9C add eax, dword ptr [ebp-64] ; EAX=MD5_2[0] - MD5_2[1] - MD5_2[2] + MD5_2[3]
00457BED |. 8945 90 mov dword ptr [ebp-70], eax ; [ebp-70]=MD5_2[0] - MD5_2[1] - MD5_2[2] + MD5_2[3],保存第2个SN整数
00457BF0 |. 8D55 F0 lea edx, dword ptr [ebp-10] ; eax,edx两个整数缓冲区,用来保存checkbox的状态
00457BF3 |. 8D45 F4 lea eax, dword ptr [ebp-C]
00457BF6 |. E8 B1F8FFFF call 004574AC ; 取 CheckBox 的状态,生成两个32位无符号数,过程简单统一,不深入解释了
00457BFB |. 8B45 F0 mov eax, dword ptr [ebp-10] ; 参数4,第2个checkbox状态值
00457BFE |. 50 push eax
00457BFF |. 8B4D F4 mov ecx, dword ptr [ebp-C] ; 参数3,第1个checkbox状态值
00457C02 |. 8B55 90 mov edx, dword ptr [ebp-70] ; 参数2,第2个MD5计算值变形运算后的数值
00457C05 |. 8B45 A0 mov eax, dword ptr [ebp-60] ; 参数1,第1个MD5运算值变形运算后的数值
00457C08 |. E8 AFFEFFFF call 00457ABC ; 注册码比较调用,对比两组整数,不相等则用随机数取得一个索引地址
00457C0D |. 8945 FC mov dword ptr [ebp-4], eax ; eax 为上面调用通过查表返回的一个地址
00457C10 |. 8B45 FC mov eax, dword ptr [ebp-4] ; eax为调用入口地址,注册不成功是地址范围 0x0045746C~004574A8 内的一个随机地址,成功则是 0x004573C8
00457C13 |. FFD0 call eax ; 如果注册成功,则显示成功注册,不然就继续显示失败。
00457C15 |> 33C0 xor eax, eax ; 指示 SEH 头的索引
00457C17 |. 5A pop edx ; 取保存的SEH地址
00457C18 |. 59 pop ecx
00457C19 |. 59 pop ecx
00457C1A |. 64:8910 mov dword ptr fs:[eax], edx ; 恢复SEH
00457C1D |. 68 3A7C4500 push 00457C3A ; 下面的 retn 返回地址
00457C22 |> 8D45 8C lea eax, dword ptr [ebp-74]
00457C25 |. E8 32BCFAFF call 0040385C ; Delphi 资源释放过程
00457C2A |. 8D45 F8 lea eax, dword ptr [ebp-8]
00457C2D |. E8 2ABCFAFF call 0040385C ; Delphi 资源释放过程
00457C32 \. C3 retn ; 跳转到 0x00457C3A
00457C33 .^ E9 E4B6FAFF jmp 0040331C ; SEH 异常处理
00457C38 .^ EB E8 jmp short 00457C22 ; SEH 处理完成后,跳回到这里
00457C3A . 5F pop edi
00457C3B . 5E pop esi
00457C3C . 5B pop ebx
00457C3D . 8BE5 mov esp, ebp
00457C3F . 5D pop ebp
00457C40 . C3 retn
以上是主验证过程,其取得用户名,如果长度没有64个字符,就一直重复拼接直到超过64个字符,然后再截短为64个字符。
再进行MD5处理。不过,其传入的用户名在进行MD5处理时,只取了前63个字符填充在MD5输入缓冲区的后63字节中,而缓冲区第1个字符位置填充的是'\0'(这个在C/C++中就不好计算长度了,需要从第2个字符开始处理)。
这个生成的 '\0' + 重复注册名 字符串,进行两次 MD5处理,头一次是标准的,并且不需要padding填充。第二次直接用第一次的MD5码作为初始化引子,进行MD5计算。
下面是 MD 5 运算调用的过程,汇编代码太长,反正是一个标准过程,因此中间删除了一部分,免得显示得太长:
[Asm] 纯文本查看 复制代码 0045646C /$ 53 push ebx
0045646D |. 56 push esi
0045646E |. 57 push edi
0045646F |. 83C4 C0 add esp, -40
00456472 |. 8BF0 mov esi, eax
00456474 |. 8D3C24 lea edi, dword ptr [esp]
00456477 |. B9 10000000 mov ecx, 10 ; 长度,16 * 4 字节
0045647C |. F3:A5 rep movs dword ptr es:[edi], dword ptr [esi] ; 一次移动4字节,一共移动16次
0045647E |. BB 10000000 mov ebx, 10 ; 循环16次 int n = 16
00456483 |. 8BC4 mov eax, esp
00456485 |. 8BCA mov ecx, edx
00456487 |> 0FB630 /movzx esi, byte ptr [eax] ; 读取注册名第1个字符,第1个是'\0'
0045648A |. 0FB678 01 |movzx edi, byte ptr [eax+1] ; 读取注册名第2个字符,其实就是注册名的第1个字符
0045648E |. C1E7 08 |shl edi, 8
00456491 |. 0BF7 |or esi, edi
00456493 |. 0FB678 02 |movzx edi, byte ptr [eax+2] ; 第3个
00456497 |. C1E7 10 |shl edi, 10
0045649A |. 0BF7 |or esi, edi
0045649C |. 0FB678 03 |movzx edi, byte ptr [eax+3] ; 第4个
004564A0 |. C1E7 18 |shl edi, 18
004564A3 |. 0BF7 |or esi, edi
004564A5 |. 8931 |mov dword ptr [ecx], esi ; 将每4字节一组转换成16进制数字保存
004564A7 |. 83C1 04 |add ecx, 4
004564AA |. 83C0 04 |add eax, 4
004564AD |. 4B |dec ebx ; n--
004564AE |.^ 75 D7 \jnz short 00456487 ; 循环转换
004564B0 |. 83C4 40 add esp, 40
004564B3 |. 5F pop edi
004564B4 |. 5E pop esi
004564B5 |. 5B pop ebx
004564B6 \. C3 retn
004564B7 90 nop
004564B8 /$ 55 push ebp
004564B9 |. 8BEC mov ebp, esp
004564BB |. 81C4 64FFFFFF add esp, -9C
004564C1 |. 53 push ebx
004564C2 |. 56 push esi
004564C3 |. 57 push edi
004564C4 |. 33C9 xor ecx, ecx
004564C6 |. 894D E4 mov dword ptr [ebp-1C], ecx ; [ebp-1C] = 0
004564C9 |. 8BF0 mov esi, eax ; esi==>'\0' + 注册名前0x3F字符
004564CB |. 8D7D A4 lea edi, dword ptr [ebp-5C] ; edi=0x0019FC48
004564CE |. B9 10000000 mov ecx, 10
004564D3 |. F3:A5 rep movs dword ptr es:[edi], dword ptr [esi] ; 复制16*4字节注册名
004564D5 |. 8955 FC mov dword ptr [ebp-4], edx ; [ebp-4]==>MD5引子
004564D8 |. 33C0 xor eax, eax
004564DA |. 55 push ebp
004564DB |. 68 B9734500 push 004573B9
004564E0 |. 64:FF30 push dword ptr fs:[eax]
004564E3 |. 64:8920 mov dword ptr fs:[eax], esp
004564E6 |. 8D95 64FFFFFF lea edx, dword ptr [ebp-9C]
004564EC |. 8D45 A4 lea eax, dword ptr [ebp-5C] ; eax==>注册名
004564EF |. E8 78FFFFFF call 0045646C ; 字符串复制,复制64字节
004564F4 |. E8 13C3FAFF call 0040280C ; 随机数引子初始化,即当前时间的毫秒值
004564F9 |. 8B45 FC mov eax, dword ptr [ebp-4] ; EAX==>MD5算法引子
004564FC |. 8B00 mov eax, dword ptr [eax] ; eax=第1个整数,0x67452301
004564FE |. 8945 F8 mov dword ptr [ebp-8], eax
00456501 |. 8B45 FC mov eax, dword ptr [ebp-4]
00456504 |. 8B40 04 mov eax, dword ptr [eax+4]
00456507 |. 8945 F0 mov dword ptr [ebp-10], eax
0045650A |. 8B75 FC mov esi, dword ptr [ebp-4]
0045650D |. 8B76 08 mov esi, dword ptr [esi+8]
00456510 |. 8B5D FC mov ebx, dword ptr [ebp-4]
00456513 |. 8B5B 0C mov ebx, dword ptr [ebx+C]
00456516 |. 8B45 F0 mov eax, dword ptr [ebp-10]
00456519 |. 8945 F4 mov dword ptr [ebp-C], eax
0045651C |. 8B7D F8 mov edi, dword ptr [ebp-8]
0045651F |. 8975 F8 mov dword ptr [ebp-8], esi
00456522 |. F755 F4 not dword ptr [ebp-C]
00456525 |. 8B45 F0 mov eax, dword ptr [ebp-10]
00456528 |. 2145 F8 and dword ptr [ebp-8], eax
0045652B |. 215D F4 and dword ptr [ebp-C], ebx
0045652E |. 8B45 F4 mov eax, dword ptr [ebp-C]
00456531 |. 0945 F8 or dword ptr [ebp-8], eax
00456534 |. B8 65000000 mov eax, 65
00456539 |. E8 92C4FAFF call 004029D0 ; 生成0~100的随机数
0045653E |. 8B1485 F09245>mov edx, dword ptr [eax*4+4592F0] ; 查一个表(0~0x64)取地址,不过该表保存是同一个地址0x0045642C,该地址(edx)指向“MatrixxxMadness1 - UNREGISTERED!”
00456545 |. 8D45 E4 lea eax, dword ptr [ebp-1C] ; 保存上面读取到的字符串地址
00456548 |. E8 A7D3FAFF call 004038F4 ; 保存地址到[eax]
0045654D |. 8B85 64FFFFFF mov eax, dword ptr [ebp-9C]
00456553 |. 8945 F4 mov dword ptr [ebp-C], eax
00456556 |. 8B45 F4 mov eax, dword ptr [ebp-C]
00456559 |. 0145 F8 add dword ptr [ebp-8], eax
0045655C |. 037D F8 add edi, dword ptr [ebp-8]
0045655F |. 81EF 885B9528 sub edi, 28955B88 ; MD5 标准写法是加法,因此这里实际上是 edi += 0xd76aa478
00456565 |. 897D F4 mov dword ptr [ebp-C], edi
00456568 |. 8B45 F4 mov eax, dword ptr [ebp-C]
0045656B |. 8945 F8 mov dword ptr [ebp-8], eax
0045656E |. C165 F8 07 shl dword ptr [ebp-8], 7 ; 左7右25,模拟循环左移7位
00456572 |. C16D F4 19 shr dword ptr [ebp-C], 19
00456576 |. 8B45 F4 mov eax, dword ptr [ebp-C]
00456579 |. 0945 F8 or dword ptr [ebp-8], eax
0045657C |. 8B45 F0 mov eax, dword ptr [ebp-10]
0045657F |. 8945 F4 mov dword ptr [ebp-C], eax
00456582 |. 8B45 F0 mov eax, dword ptr [ebp-10]
00456585 |. 0145 F8 add dword ptr [ebp-8], eax
00456588 |. 8B7D F8 mov edi, dword ptr [ebp-8]
0045658B |. 8B45 F8 mov eax, dword ptr [ebp-8]
0045658E |. 2145 F4 and dword ptr [ebp-C], eax
00456591 |. F7D7 not edi
00456593 |. 23FE and edi, esi
00456595 |. 097D F4 or dword ptr [ebp-C], edi
00456598 |. 8BBD 68FFFFFF mov edi, dword ptr [ebp-98]
0045659E |. 017D F4 add dword ptr [ebp-C], edi
;
;此处省略n行汇编代码,都是MD5算法的代码
;
004572EC |. 0375 F8 add esi, dword ptr [ebp-8]
004572EF |. 81C6 BBD2D72A add esi, 2AD7D2BB
004572F5 |. 8B5D 88 mov ebx, dword ptr [ebp-78]
004572F8 |. 8975 F8 mov dword ptr [ebp-8], esi
004572FB |. C165 F8 0F shl dword ptr [ebp-8], 0F
004572FF |. C1EE 11 shr esi, 11
00457302 |. 0975 F8 or dword ptr [ebp-8], esi
00457305 |. 8BF7 mov esi, edi
00457307 |. 8B45 F0 mov eax, dword ptr [ebp-10]
0045730A |. 0145 F8 add dword ptr [ebp-8], eax
0045730D |. F7D6 not esi
0045730F |. 0B75 F8 or esi, dword ptr [ebp-8]
00457312 |. 3375 F0 xor esi, dword ptr [ebp-10]
00457315 |. 03F3 add esi, ebx
00457317 |. B8 65000000 mov eax, 65
0045731C |. E8 AFB6FAFF call 004029D0
00457321 |. 8B1485 F09245>mov edx, dword ptr [eax*4+4592F0]
00457328 |. 8D45 E4 lea eax, dword ptr [ebp-1C]
0045732B |. E8 C4C5FAFF call 004038F4
00457330 |. 8B5D FC mov ebx, dword ptr [ebp-4]
00457333 |. 8B1B mov ebx, dword ptr [ebx]
00457335 |. 03DF add ebx, edi
00457337 |. 0375 F4 add esi, dword ptr [ebp-C]
0045733A |. 81EE 6F2C7914 sub esi, 14792C6F
00457340 |. 8975 F4 mov dword ptr [ebp-C], esi
00457343 |. 8B75 FC mov esi, dword ptr [ebp-4]
00457346 |. 8B76 04 mov esi, dword ptr [esi+4]
00457349 |. 8B7D F4 mov edi, dword ptr [ebp-C]
0045734C |. 8B45 FC mov eax, dword ptr [ebp-4]
0045734F |. 8918 mov dword ptr [eax], ebx
00457351 |. C1EF 0B shr edi, 0B
00457354 |. C165 F4 15 shl dword ptr [ebp-C], 15
00457358 |. 0B7D F4 or edi, dword ptr [ebp-C]
0045735B |. 8B45 FC mov eax, dword ptr [ebp-4]
0045735E |. 8B40 08 mov eax, dword ptr [eax+8]
00457361 |. 8945 F4 mov dword ptr [ebp-C], eax
00457364 |. 037D F8 add edi, dword ptr [ebp-8]
00457367 |. 8B45 F8 mov eax, dword ptr [ebp-8]
0045736A |. 0145 F4 add dword ptr [ebp-C], eax
0045736D |. 8B45 FC mov eax, dword ptr [ebp-4]
00457370 |. 8B40 0C mov eax, dword ptr [eax+C]
00457373 |. 8945 F8 mov dword ptr [ebp-8], eax
00457376 |. 03F7 add esi, edi
00457378 |. 8B45 F0 mov eax, dword ptr [ebp-10]
0045737B |. 0145 F8 add dword ptr [ebp-8], eax
0045737E |. 8B45 FC mov eax, dword ptr [ebp-4]
00457381 |. 8B55 F4 mov edx, dword ptr [ebp-C]
00457384 |. 8950 08 mov dword ptr [eax+8], edx
00457387 |. 8B45 FC mov eax, dword ptr [ebp-4]
0045738A |. 8B55 F8 mov edx, dword ptr [ebp-8]
0045738D |. 8950 0C mov dword ptr [eax+C], edx
00457390 |. 8B45 FC mov eax, dword ptr [ebp-4]
00457393 |. 8970 04 mov dword ptr [eax+4], esi
00457396 |. 8B55 E4 mov edx, dword ptr [ebp-1C] ; edx==>“MatrixxxMadness1 - UNREGISTERED!”
00457399 |. A1 08A84500 mov eax, dword ptr [45A808]
0045739E |. E8 5DFCFDFF call 00437000 ; SetText,显示上面的字符串
004573A3 |. 33C0 xor eax, eax
004573A5 |. 5A pop edx
004573A6 |. 59 pop ecx
004573A7 |. 59 pop ecx
004573A8 |. 64:8910 mov dword ptr fs:[eax], edx
004573AB |. 68 C0734500 push 004573C0
004573B0 |> 8D45 E4 lea eax, dword ptr [ebp-1C]
004573B3 |. E8 A4C4FAFF call 0040385C
004573B8 \. C3 retn
004573B9 .^ E9 5EBFFAFF jmp 0040331C
004573BE .^ EB F0 jmp short 004573B0
004573C0 . 5F pop edi
004573C1 . 5E pop esi
004573C2 . 5B pop ebx
004573C3 . 8BE5 mov esp, ebp
004573C5 . 5D pop ebp
004573C6 . C3 retn
下面是注册码比较过程:
[Asm] 纯文本查看 复制代码
00457ABC /$ 55 push ebp
00457ABD |. 8BEC mov ebp, esp
00457ABF |. 53 push ebx
00457AC0 |. 56 push esi
00457AC1 |. 57 push edi
00457AC2 |. 8BF9 mov edi, ecx ; 参数3,第1个checkbox状态值
00457AC4 |. 8BF2 mov esi, edx ; 参数2,第2个MD5计算值变形运算后的数值
00457AC6 |. 8BD8 mov ebx, eax ; 参数1,第1个MD5运算值变形运算后的数值
00457AC8 |. E8 3FADFAFF call 0040280C
00457ACD |. 2BDF sub ebx, edi ; 参数1与参数3比较
00457ACF |. 75 09 jnz short 00457ADA
00457AD1 |. 2B75 08 sub esi, dword ptr [ebp+8] ; 参数2与参数4比较,[ebp+8]为参数4,第2个checkbox状态值
00457AD4 |. 75 04 jnz short 00457ADA
00457AD6 |. 33C0 xor eax, eax ; 都相等则生成索引 0
00457AD8 |. EB 0A jmp short 00457AE4
00457ADA |> B8 00010000 mov eax, 100 ; 生成0~0xFF范围内的随机数
00457ADF |. E8 ECAEFAFF call 004029D0 ; 生成随机数
00457AE4 |> 25 FF000000 and eax, 0FF ; 限制索引在0~0xFF范围内
00457AE9 |. 8B0485 849445>mov eax, dword ptr [eax*4+459484] ; 通过索引查表返回调用地址
00457AF0 |. 5F pop edi
00457AF1 |. 5E pop esi
00457AF2 |. 5B pop ebx
00457AF3 |. 5D pop ebp
00457AF4 \. C2 0400 retn 4
如果注册码不相等,则会调用下面这些函数,都是空函数,只有一个retn:
[Asm] 纯文本查看 复制代码 ///////////////// 注册失败时的 call eax 调用的函数列表 ////////////////////////
0045746C . C3 retn
0045746D 8D40 00 lea eax, dword ptr [eax]
00457470 . C3 retn
00457471 8D40 00 lea eax, dword ptr [eax]
00457474 . C3 retn
00457475 8D40 00 lea eax, dword ptr [eax]
00457478 . C3 retn
00457479 8D40 00 lea eax, dword ptr [eax]
0045747C . C3 retn
0045747D 8D40 00 lea eax, dword ptr [eax]
00457480 . C3 retn
00457481 8D40 00 lea eax, dword ptr [eax]
00457484 . C3 retn
00457485 8D40 00 lea eax, dword ptr [eax]
00457488 . C3 retn
00457489 8D40 00 lea eax, dword ptr [eax]
0045748C . C3 retn
0045748D 8D40 00 lea eax, dword ptr [eax]
00457490 . C3 retn
00457491 8D40 00 lea eax, dword ptr [eax]
00457494 . C3 retn
00457495 8D40 00 lea eax, dword ptr [eax]
00457498 . C3 retn
00457499 8D40 00 lea eax, dword ptr [eax]
0045749C . C3 retn
0045749D 8D40 00 lea eax, dword ptr [eax]
004574A0 . C3 retn
004574A1 8D40 00 lea eax, dword ptr [eax]
004574A4 . C3 retn
004574A5 8D40 00 lea eax, dword ptr [eax]
004574A8 . C3 retn
004574A9 8D40 00 lea eax, dword ptr [eax]
这个Crackme 输入注册码的方式比较特别,是通过一个checkbox矩陈来输入的。
序列号共两个整数,每个整数32bits,分成4行,每行输入8bits,一起8行x8位,完成SN的输入。
通过上面分析,输入用户名:solly,得到 SN:919D5B79-3826ACAC,再转成二进制矩陈显示如下,”1“表示选中,”0“表示不选中:
SN Matrix:
1 0 0 1 0 0 0 1
1 0 0 1 1 1 0 1
0 1 0 1 1 0 1 1
0 1 1 1 1 0 0 1
0 0 1 1 1 0 0 0
0 0 1 0 0 1 1 0
1 0 1 0 1 1 0 0
1 0 1 0 1 1 0 0
输入注册码,成功画面如下:
注册码验证过程分析完毕,以下是注册机,其中MD5代码参考网上代码,并按crackme的要求作一定修改,源码如下,共3个文件:
[C++] 纯文本查看 复制代码 /*
main.cpp
*/
#include <stdio.h>
#include <stdlib.h>
#include "MD5.hpp"
int main(int argc, char** argv) {
unsigned char decrypt[16];
//unsigned char regname[] = "\0sollysollysollysollysollysollysollysollysollysollysollysollysol";
char temp[256];
char regname[80];
printf("Keygen for 152 - 'The AntiXryst' of 160 crackme.\n");
//// 输入用户名
printf("Enter your name: ");
gets(temp); //// 输入用户名
//// 用户名处理
int n = strlen(temp);
char * p = regname[1]; /// 从第2个字节开始保存连接的用户名
strncpy(p, temp, 64);
int m = n;
while(m<63) {
strcat(p+n, temp);
m += n;
}
regname[0] = '\0'; /// 第1个字节设为'\0'
regname[64] = '\0'; /// 字符串null结束符
//printf("Name: %s\n", p);
////MD5算法
int len = 0x40; /// 固定长度为64
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5, (unsigned char *)regname, len);
MD5Final(&md5, decrypt);
//////
unsigned int sn[2];
sn[0] = md5.state2[0] - md5.state2[1] - md5.state2[2] + md5.state2[3];
sn[1] = md5.state[0] - md5.state[1] - md5.state[2] + md5.state[3];
////
printf("\n\nSN: %08X-%08X\n", sn[0], sn[1]);
printf("SN Matrix:\n");
for(int i=0; i<2; i++) {
unsigned int a = sn[i];
unsigned int b = 0x80000000;
for(int j=1; j<=32; j++) {
if(a & b) {
printf("1 ");
} else {
printf("0 ");
}
b >>=1;
if((j % 8) == 0) {
printf("\n");
}
}
}
system("pause");
return 0;
}
第二个是 MD5.cpp:
[C++] 纯文本查看 复制代码 #include "Md5.hpp"
unsigned char PADDING[] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
void MD5Init(MD5_CTX *context){
context->count[0]=0;
context->count[1]=0;
context->state[0]=0x67452301;
context->state[1]=0xEFCDAB89;
context->state[2]=0x98BADCFE;
context->state[3]=0x10325476;
//// context->buffer[64];
}
void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen){
unsigned int i=0,index=0,partlen=0;
index=(context->count[0]>>3)&0x3F;
partlen=64-index;
context->count[0]+=inputlen<<3;
if(context->count[0]<(inputlen<<3)) context->count[1]++;
context->count[1]+=inputlen>>29;
if(inputlen>=partlen){
memcpy(&context->buffer[index], input, partlen);
MD5Transform(context->state, context->buffer);
for(i=partlen;i+64<=inputlen;i+=64) MD5Transform(context->state,&input[i]);
index=0;
//// 相对标准MD5第1处改动, 在第1次基础上直接进行第2次MD5计算/////////////
context->state2[0] = context->state[0]; //// 保存第1次的MD5值
context->state2[1] = context->state[1]; //// 保存第1次的MD5值
context->state2[2] = context->state[2]; //// 保存第1次的MD5值
context->state2[3] = context->state[3]; //// 保存第1次的MD5值
MD5Transform(context->state, context->buffer);
for(i=partlen;i+64<=inputlen;i+=64) MD5Transform(context->state,&input[i]);
index=0;
//////////////////////////////////////////////////////////////////////////
}
else i=0;
memcpy(&context->buffer[index], &input[i], inputlen-i);
}
void MD5Final(MD5_CTX *context, unsigned char digest[16]){
unsigned int index=0,padlen=0;
unsigned char bits[8];
index=(context->count[0]>>3)&0x3F;
padlen=(index<56)?(56-index):(120-index);
////// 相对标准MD5第2处改动, 因为主注册名已经有64字节,并且由于其第1字节为'\0',会padding掉全部内容,所以不进行Padding处理
// MD5Update(context,PADDING,padlen); //// no padding, comments by solly
//////////////////////////////////////////////////////////////////////////////////
MD5Update(context,bits,8);//index=0
/////
MD5Encode(digest,context->state,16);
}
void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len){
unsigned int i = 0, j = 0;
while (j<len){
output[j]=input[i] & 0xFF;
output[j+1]=(input[i]>>8)&0xFF;
output[j+2]=(input[i]>>16)&0xFF;
output[j+3]=(input[i]>>24)&0xFF;
i++;
j += 4;
}
}
void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len){
unsigned int i = 0, j = 0;
while (j < len){
output[i] = (input[j]) |
(input[j + 1] << 8) |
(input[j + 2] << 16) |
(input[j + 3] << 24);
i++;
j += 4;
}
}
void MD5Transform(unsigned int state[4], unsigned char block[64]){
unsigned int a = state[0];
unsigned int b = state[1];
unsigned int c = state[2];
unsigned int d = state[3];
unsigned int x[16];
MD5Decode(x, block, 64);
FF(a, b, c, d, x[0], 7, 0xd76aa478);
FF(d, a, b, c, x[1], 12, 0xe8c7b756);
FF(c, d, a, b, x[2], 17, 0x242070db);
FF(b, c, d, a, x[3], 22, 0xc1bdceee);
FF(a, b, c, d, x[4], 7, 0xf57c0faf);
FF(d, a, b, c, x[5], 12, 0x4787c62a);
FF(c, d, a, b, x[6], 17, 0xa8304613);
FF(b, c, d, a, x[7], 22, 0xfd469501);
FF(a, b, c, d, x[8], 7, 0x698098d8);
FF(d, a, b, c, x[9], 12, 0x8b44f7af);
FF(c, d, a, b, x[10], 17, 0xffff5bb1);
FF(b, c, d, a, x[11], 22, 0x895cd7be);
FF(a, b, c, d, x[12], 7, 0x6b901122);
FF(d, a, b, c, x[13], 12, 0xfd987193);
FF(c, d, a, b, x[14], 17, 0xa679438e);
FF(b, c, d, a, x[15], 22, 0x49b40821);
GG(a, b, c, d, x[1], 5, 0xf61e2562);
GG(d, a, b, c, x[6], 9, 0xc040b340);
GG(c, d, a, b, x[11], 14, 0x265e5a51);
GG(b, c, d, a, x[0], 20, 0xe9b6c7aa);
GG(a, b, c, d, x[5], 5, 0xd62f105d);
GG(d, a, b, c, x[10], 9, 0x2441453);
GG(c, d, a, b, x[15], 14, 0xd8a1e681);
GG(b, c, d, a, x[4], 20, 0xe7d3fbc8);
GG(a, b, c, d, x[9], 5, 0x21e1cde6);
GG(d, a, b, c, x[14], 9, 0xc33707d6);
GG(c, d, a, b, x[3], 14, 0xf4d50d87);
GG(b, c, d, a, x[8], 20, 0x455a14ed);
GG(a, b, c, d, x[13], 5, 0xa9e3e905);
GG(d, a, b, c, x[2], 9, 0xfcefa3f8);
GG(c, d, a, b, x[7], 14, 0x676f02d9);
GG(b, c, d, a, x[12], 20, 0x8d2a4c8a);
HH(a, b, c, d, x[5], 4, 0xfffa3942);
HH(d, a, b, c, x[8], 11, 0x8771f681);
HH(c, d, a, b, x[11], 16, 0x6d9d6122);
HH(b, c, d, a, x[14], 23, 0xfde5380c);
HH(a, b, c, d, x[1], 4, 0xa4beea44);
HH(d, a, b, c, x[4], 11, 0x4bdecfa9);
HH(c, d, a, b, x[7], 16, 0xf6bb4b60);
HH(b, c, d, a, x[10], 23, 0xbebfbc70);
HH(a, b, c, d, x[13], 4, 0x289b7ec6);
HH(d, a, b, c, x[0], 11, 0xeaa127fa);
HH(c, d, a, b, x[3], 16, 0xd4ef3085);
HH(b, c, d, a, x[6], 23, 0x4881d05);
HH(a, b, c, d, x[9], 4, 0xd9d4d039);
HH(d, a, b, c, x[12], 11, 0xe6db99e5);
HH(c, d, a, b, x[15], 16, 0x1fa27cf8);
HH(b, c, d, a, x[2], 23, 0xc4ac5665);
II(a, b, c, d, x[0], 6, 0xf4292244);
II(d, a, b, c, x[7], 10, 0x432aff97);
II(c, d, a, b, x[14], 15, 0xab9423a7);
II(b, c, d, a, x[5], 21, 0xfc93a039);
II(a, b, c, d, x[12], 6, 0x655b59c3);
II(d, a, b, c, x[3], 10, 0x8f0ccc92);
II(c, d, a, b, x[10], 15, 0xffeff47d);
II(b, c, d, a, x[1], 21, 0x85845dd1);
II(a, b, c, d, x[8], 6, 0x6fa87e4f);
II(d, a, b, c, x[15], 10, 0xfe2ce6e0);
II(c, d, a, b, x[6], 15, 0xa3014314);
II(b, c, d, a, x[13], 21, 0x4e0811a1);
II(a, b, c, d, x[4], 6, 0xf7537e82);
II(d, a, b, c, x[11], 10, 0xbd3af235);
II(c, d, a, b, x[2], 15, 0x2ad7d2bb);
II(b, c, d, a, x[9], 21, 0xeb86d391);
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}
第三个是 MD5.hpp:
[C++] 纯文本查看 复制代码 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
typedef struct{
unsigned int count[2];
unsigned int state[4];
unsigned char buffer[64];
unsigned int state2[4]; //// 这里是改动之三,不对算法产生影响,只是用来备份第1次MD5结果
} MD5_CTX;
#define F(x,y,z) ((x&y)|(~x&z))
#define G(x,y,z) ((x&z)|(y&~z))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y^(x|~z))
#define ROTATE_LEFT(x,n) ((x<<n)|(x>>(32-n)))
#define FF(a,b,c,d,x,s,ac) { a+=F(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
#define GG(a,b,c,d,x,s,ac) { a+=G(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
#define HH(a,b,c,d,x,s,ac) { a+=H(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
#define II(a,b,c,d,x,s,ac) { a+=I(b,c,d)+x+ac; a=ROTATE_LEFT(a,s); a+=b;}
void MD5Init(MD5_CTX *context);
void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen);
void MD5Final(MD5_CTX *context, unsigned char digest[16]);
void MD5Transform(unsigned int state[4], unsigned char block[64]);
void MD5Encode(unsigned char *output, unsigned int *input, unsigned int len);
void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len);
以上代码是在 Dev-C++上调试通过的。
///////
完毕,码字不易!!!!评分免费!!!!
|
-
-
免费评分
-
查看全部评分
|