好友
阅读权限20
听众
最后登录1970-1-1
|
楼主|
反沉沦
发表于 2016-2-23 19:55
破解160个CrackMe之066
本帖最后由 反沉沦 于 2016-3-25 10:53 编辑
破解160个CrackMe之066
运行程序,随便输入Name和Serial,点击Check,弹出对话框"Wrong Serial-try again"
打开OD,载入程序,来到OEP,发现与VC、VB、.Net等开发的程序的OEP都不像,继续往下浏览,看到了许多api函数的调用,比如LoadIconA
,SetClassLongA,SendDlgItemMessageA等等,由此判断程序是用汇编语言开发的,并未加壳。
使用OD搜索字符串功能,搜不到有用的字符串,字符串应该是被加密了
浏览代码,发现有两个地方调用了GetDlgItemTextA和GetDlgItemInt,在这两个地方下断,
004013AB |. 53 push ebx
004013AC |. 56 push esi
004013AD |. 57 push edi
004013AE |. 8B5D 08 mov ebx,[arg.1] ; figugegl.<ModuleEntryPoint>
004013B1 |. 6A 14 push 0x14 ; /Count = 14 (20.)
004013B3 |. 8D45 EB lea eax,dword ptr ss:[ebp-0x15] ; |
004013B6 |. 50 push eax ; |Buffer = NULL
004013B7 |. 6A 65 push 0x65 ; |ControlID = 65 (101.)
004013B9 |. 53 push ebx ; |hWnd = 7FFD6000
004013BA |. E8 1D020000 call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
00401409 |. 6A 00 push 0x0 ; /IsSigned = FALSE
0040140B |. 8D45 C8 lea eax,[local.14] ; |
0040140E |. 50 push eax ; |pSuccess = NULL
0040140F |. 6A 66 push 0x66 ; |ControlID = 66 (102.)
00401411 |. 53 push ebx ; |hWnd = 7FFD6000
00401412 |. E8 AD010000 call <jmp.&USER32.GetDlgItemInt> ; \GetDlgItemInt
跟踪堆栈发现,调用GetDlgItemTextA获取输入的Name,调用GetDlgItemInt获取Serial
下面用三种方法来进行破解
爆破方法:
00401417 |. 39C6 cmp esi,eax
00401419 |. 75 19 jnz short figugegl.00401434
eax中保存了用户输入的Serial,esi中保存了程序根据Name计算出的Serial,两者相等即通过验证。
此处是爆破的关键,把jnz short figugegl.00401434这一句nop掉即可爆破
追码方法:
004013D1 |. 31F6 xor esi,esi
004013D3 |> 0FB67C35 EB /movzx edi,byte ptr ss:[ebp+esi-0x15]
004013D8 |. 0FB65435 F5 |movzx edx,byte ptr ss:[ebp+esi-0xB]
004013DD |. 89F8 |mov eax,edi
004013DF |. 31D0 |xor eax,edx ; ntdll.KiFastSystemCallRet
004013E1 |. B9 0A000000 |mov ecx,0xA
004013E6 |. 99 |cdq
004013E7 |. F7F9 |idiv ecx
004013E9 |. 83C2 30 |add edx,0x30
004013EC |. 885435 D6 |mov byte ptr ss:[ebp+esi-0x2A],dl
004013F0 |. 46 |inc esi
004013F1 |. 39CE |cmp esi,ecx
004013F3 |.^ 7C DE \jl short figugegl.004013D3
004013F5 |. 6A 0A push 0xA ; /radix = A (10.)
004013F7 |. 8D45 CC lea eax,[local.13] ; |
004013FA |. 50 push eax ; |endptr = NULL
004013FB |. 8D45 D6 lea eax,dword ptr ss:[ebp-0x2A] ; |
004013FE |. 50 push eax ; |s = NULL
004013FF |. E8 80020000 call <jmp.&CRTDLL.strtoul> ; \strtoul
这段代码的功能是根据输入的Name字符串计算出对应的Serial字符串,然后调用strtoul函数将Serial字符串转化为整数,在00401417 处进
行比较
在004013FF下断,观察堆栈数据,即可看到正确的Serial
当Name是figugegl时,堆栈数据如下:
0012FA14 0012FA3A |s = "0315191600"
0012FA18 0012FA30 |endptr = 0012FA30
0012FA1C 0000000A \radix = A (10.)
那么正确的Serial就应该是0315191600
keygen分析:
004013D1 |. 31F6 xor esi,esi
004013D3 |> 0FB67C35 EB /movzx edi,byte ptr ss:[ebp+esi-0x15]
004013D8 |. 0FB65435 F5 |movzx edx,byte ptr ss:[ebp+esi-0xB]
004013DD |. 89F8 |mov eax,edi
004013DF |. 31D0 |xor eax,edx ; ntdll.KiFastSystemCallRet
004013E1 |. B9 0A000000 |mov ecx,0xA
004013E6 |. 99 |cdq
004013E7 |. F7F9 |idiv ecx
004013E9 |. 83C2 30 |add edx,0x30
004013EC |. 885435 D6 |mov byte ptr ss:[ebp+esi-0x2A],dl
004013F0 |. 46 |inc esi
004013F1 |. 39CE |cmp esi,ecx
004013F3 |.^ 7C DE \jl short figugegl.004013D3
生成Serial的流程大致:
1、获取Name,判断其长度,如果小于20,在字符串最后补充0x20,使其长度等于20
2、取Name的第一个字节到eax中,取Name的第11个字节到edx,
eax和edx异或,然后将edx赋值为0,ecx赋值为0xA,除以ecx,将余数加上0x30,作为Serial的第一个字节
然后取Name的第二个字节,重复上面的过程
3、这种生成Serial的算法隐含一个限制条件,生成的Serial第一个字节必须是0x30,否则在调用strtoul函数时会发生溢出,strtoul函数
返回值就变成了0xFFFFFFFF。
要想第一个字节是0x30,Name的第一个字节必须是f,同时Name的长度不大于10。
如果满足这两个条件,f与0x20异或,结果是0x46,除以0xA,余数为0,加上0x30,还是等于0x30。
keygen代码如下:
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <process.h>
int _tmain(int argc, _TCHAR* argv[])
{
char Name[100] = {0};
char serial[100] = {0};
int nLength=0;
int i;
unsigned int nameByte,serialByte;
printf("Input your Name:");
gets_s(Name,100);
if ('f'==Name[0])
{
nLength=strlen(Name) ;
if (( nLength > 0) &&(nLength<11))
{
if (nLength<0x14)
{
for (i=nLength;i<0x14;i++)
{
Name=0x20;
}
}
for (i=0;i<0xA;i++)
{
nameByte=Name^Name[i+10];
serialByte=(nameByte%0xA)+0x30;
serial=(char)serialByte;
}
printf("Serial: %s\r\n",serial);
}else{
printf("input name length error!\r\n");
}
}else{
printf("the name's first char must be 'f'!\r\n");
}
system("pause");
return 0;
}
提供一组Name和Serial:
Name:figugegl Serial:0315191600
|
|