科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网安全频道简单CrackMe(aescul)分析

简单CrackMe(aescul)分析

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

简单CrackMe(aescul)分析。

作者:315安全网 来源:315安全网 2008年10月16日

关键字: Crackme 加密解密

  • 评论
  • 分享微博
  • 分享邮件

  【破解作者】 analog

  【作者邮箱】 yuchaochina@hotmail.com

  【使用工具】 OllyDbgV1.10,PEidV0.93

  【破解平台】 WinXP

  【软件名称】 aescul.exe(CrackMe)

  【加壳方式】 无

  【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)

  --------------------------------------------------------------------------------

  【破解内容】

  代码段的开头可以找到DialogBoxParam

  00401024 |. 68 84314000 push aescul.00403184 ;|DlgProc = aescul.00403184

  窗口处理程序,在地址004030184下面附近下断点

  输入注册名,注册码后点OK,来到下面的代码段

  0040320A >\833D F6444000 0>cmp dword ptr ds:[4044F6],1 ;数据段是否自修改过

  00403211 . 74 11 je short aescul.00403224 ;修改过则跳

  00403213 . BE 00404000 mov esi,aescul.00404000

  00403218 . 8BFE mov edi,esi

  0040321A . B9 160B0000 mov ecx,0B16

  0040321F . E8 41020000 call aescul.00403465 ;自修改子程序(数据段修改)

  00403224 > 6A 40 push 40 ;/Count = 40 (64.)

  00403226 . 68 BA414000 push aescul.004041BA ;|Buffer = aescul.004041BA ;注册名存放地址

  0040322B . 68 E8030000 push 3E8 ;|ControlID = 3E8 (1000.)

  00403230 . FF75 08 push dword ptr ss:[ebp+8] ;|hWnd

  00403233 . E8 89020000 call <jmp.&USER32.GetDlgItemTextA> ;\GetDlgItemTextA ;获得注册名

  00403238 . BF BA414000 mov edi,aescul.004041BA

  0040323D . 33C0 xor eax,eax

  0040323F . 83C9 FF or ecx,FFFFFFFF

  00403242 . F2:AE repne scas byte ptr es:[edi]

  00403244 . F7D1 not ecx

  00403246 . 2BF9 sub edi,ecx

  00403248 . 890D 064B4000 mov dword ptr ds:[404B06],ecx ; 存注册名长度

  0040324E . 803D BA414000 0>cmp byte ptr ds:[4041BA],0 ; 比较注册名第一个字节是否为\0

  00403255 . 6A 40 push 40 ;/Count = 40 (64.)

  00403257 . 68 BA424000 push aescul.004042BA ;|Buffer = aescul.004042BA ;注册码存放地址

  0040325C . 68 E9030000 push 3E9 ;|ControlID = 3E9 (1001.)

  00403261 . FF75 08 push dword ptr ss:[ebp+8] ;|hWnd

  00403264 . E8 58020000 call <jmp.&USER32.GetDlgItemTextA> ;\GetDlgItemTextA ;获得注册码

  00403269 . BF BA424000 mov edi,aescul.004042BA

  0040326E . 33C0 xor eax,eax

  00403270 . 83C9 FF or ecx,FFFFFFFF

  00403273 . F2:AE repne scas byte ptr es:[edi]

  00403275 . F7D1 not ecx

  00403277 . 2BF9 sub edi,ecx

  00403279 . 890D 0A4B4000 mov dword ptr ds:[404B0A],ecx ; 存注册码长度

  0040327F . 803D BA424000 0>cmp byte ptr ds:[4042BA],0 ; 比较注册码第一个字节是否为\0

  00403286 . 68 0E4B4000 push aescul.00404B0E ;/pHandle = aescul.00404B0E

  0040328B . 6A 01 push 1 ;|Access = KEY_QUERY_VALUE

  0040328D . 6A 00 push 0 ;|Reserved = 0

  0040328F . 68 00404000 push aescul.00404000 ;|Subkey = "Software\Microsoft\Windows\CurrentVersion"

  00403294 . 68 02000080 push 80000002 ;|hKey = HKEY_LOCAL_MACHINE

  00403299 . E8 71020000 call <jmp.&ADVAPI32.RegOpenKeyExA> ;\RegOpenKeyExA ;打开注册表子键

  0040329E . 68 124B4000 push aescul.00404B12 ;/pBufSize = aescul.00404B12

  004032A3 . 68 BC434000 push aescul.004043BC ;|Buffer = aescul.004043BC

  004032A8 . 6A 00 push 0 ;|pValueType = NULL

  004032AA . 6A 00 push 0 ;|Reserved = NULL

  004032AC . 68 33404000 push aescul.00404033 ;|ValueName = "ProductId"

  004032B1 . FF35 0E4B4000 push dword ptr ds:[404B0E] ;|hKey = FFFFFFFF

  004032B7 . E8 4D020000 call <jmp.&ADVAPI32.RegQueryValueExA>; \RegQueryValueExA ;取键值

  004032BC . BF BA434000 mov edi,aescul.004043BA

  004032C1 . 33C0 xor eax,eax

  004032C3 . 83C9 FF or ecx,FFFFFFFF

  004032C6 . F2:AE repne scas byte ptr es:[edi]

  004032C8 . F7D1 not ecx

  004032CA . 2BF9 sub edi,ecx

  004032CC . 890D BC444000 mov dword ptr ds:[4044BC],ecx

  004032D2 . 833D FA444000 0>cmp dword ptr ds:[4044FA],1 ; FLAG,为1表示代码已修改

  004032D9 . 74 11 je short aescul.004032EC ; 不为1则跳转

  004032DB . BE 50304000 mov esi,aescul.00403050

  004032E0 . 8BFE mov edi,esi

  004032E2 . B9 34010000 mov ecx,134

  004032E7 . E8 8E010000 call aescul.0040347A ; 自修改子程序(代码段自修改)

  004032EC > E9 8F000000 jmp aescul.00403380 ; 跳到EndDialog

  下面是自修改的子程序:(简单的循环左移加密)

  00403465 /$ 33C0 xor eax,eax ; 清eax值

  00403467 |. AC lods byte ptr ds:[esi] ; 取字节

  00403468 |. D2C0 rol al,cl ; al循环左移cl次

  0040346A |. F6D0 not al ; al取反

  0040346C |. AA stos byte ptr es:[edi] ; 代码重新存回

  0040346D |.^ E2 F6 loopd short aescul.00403465 ; 循环

  0040346F |. C705 F6444000 0>mov dword ptr ds:[4044F6],1

  00403479 |. C3 retn

  0040347A |$ 33C0 xor eax,eax ; 代码自修改

  0040347C |. AC lods byte ptr ds:[esi] ; 取字节

  0040347D |. D2C0 rol al,cl ; al循环左移cl次

  0040347F |. F6D0 not al ; al取反

  00403481 |. AA stos byte ptr es:[edi] ; 代码重新存回

  00403482 |.^ E2 E1 loopd short aescul.00403465 ; 循环

  00403484 |. C705 FA444000 0>mov dword ptr ds:[4044FA],1

  0040348E \. C3 retn

  00401000 . /EB 14 jmp short aescul.<ModuleEntryPoint>

  00401002 . |58344000 dd aescul.00403458

  00401006 . |5C344000 dd aescul.0040345C

  0040100A . |8F344000 dd aescul.0040348F

  0040100E . |9E344000 dd aescul.0040349E

  00401012 . |A0344000 dd aescul.004034A0

  00401016 a>/$ \6A 00 push 0 ;/pModule = NULL

  00401018 |. E8 CE240000 call <jmp.&KERNEL32.GetModuleHandleA>; \GetModuleHandleA

  0040101D |. A3 87414000 mov dword ptr ds:[404187],eax

  00401022 |. 6A 00 push 0 ;/lParam = NULL

  00401024 |. 68 84314000 push aescul.00403184 ;|DlgProc = aescul.00403184 ;

  00401029 |. 6A 00 push 0 ;|hOwner = NULL

  0040102B |. 6A 65 push 65 ;|pTemplate = 65

  0040102D |. FF35 87414000 push dword ptr ds:[404187] ;|hInst = FFFFFFFF

  00401033 |. E8 7D240000 call <jmp.&USER32.DialogBoxParamA> ;\DialogBoxParamA

  00401038 |. 90 nop ; EndDialog之后返回到这

  00401039 |. 90 nop

  0040103A |. 90 nop

  由EndDialog返回后再系统dll中绕了半天才跳到这

  经过n多的nop到00403038,就是刚才SMC之后的代码段,MessageBox也在这,爆破是不行了

  00403038 |. 33C0 xor eax,eax

  0040303A |. 68 93334000 push aescul.00403393

  0040303F |. 64:FF30 push dword ptr fs:[eax]

  00403042 |. 64:8920 mov dword ptr fs:[eax],esp

  00403045 |. 9C pushfd

  00403046 |. 9C pushfd

  00403047 |. 58 pop eax ; eax=246H

  00403048 |. 0D 00010000 or eax,100 ; eax=346H

  0040304D |. 50 push eax

  0040304E |. 9D popfd

  0040304F |. 90 nop

  00403050 |. 33F6 xor esi,esi ; 清空寄存器

  00403052 |. 33FF xor edi,edi ; 清空寄存器

  00403054 |. 33D2 xor edx,edx ; 清空寄存器

  00403056 |. 8B2D 124B4000 mov ebp,dword ptr ds:[404B12] ; 循环次数24

  0040305C |. BF 02454000 mov edi,aescul.00404502 ; 变换后的正确注册码的地址

  00403061 |> 55 /push ebp

  00403062 |. 57 |push edi

  00403063 |. 56 |push esi

  00403064 |. BD C0444000 |mov ebp,aescul.004044C0 ; ASCII "0I5LZ7G123RXCV9OPAS6TBN48YUHJKDF0QWEM"(字符串2)

  00403069 |. BB BA434000 |mov ebx,aescul.004043BA ; ASCII "WS55661-640-0059266-23364"

  0040306E |. 8A0433 |mov al,byte ptr ds:[ebx+esi] ; 取"WS"+ProductID的一个字节放到al

  00403071 |. C1F8 04 |sar eax,4 ; eax算术右移4次

  00403074 |. 83E0 0F |and eax,0F ; eax和0F做与运算(取该字节的高四位)

  00403077 |. E8 BF000000 |call aescul.0040313B

  0040307C |. 8807 |mov byte ptr ds:[edi],al

  0040307E |. 8A0C33 |mov cl,byte ptr ds:[ebx+esi] ; 取"WS"+ProduceID的一个字节放到cl

  00403081 |. 83E1 0F |and ecx,0F ; 取ecx的低四位(取该字节的低四位)

  00403084 |. 8BC1 |mov eax,ecx ; 移动到eax

  00403086 |. E8 B0000000 |call aescul.0040313B

  0040308B |. 8847 01 |mov byte ptr ds:[edi+1],al

  0040308E |. 5E |pop esi

  0040308F |. 5F |pop edi

  00403090 |. 5D |pop ebp

  00403091 |. 46 |inc esi

  00403092 |. 83C7 02 |add edi,2

  00403095 |. 3BEE |cmp ebp,esi

  00403097 |.^ 75 C8 \jnz short aescul.00403061

  00403099 |. 33F6 xor esi,esi ; 下面依次取码比较

  0040309B |. 8B86 BA424000 mov eax,dword ptr ds:[esi+4042BA] ; 注册码

  004030A1 |. 8B9E 02454000 mov ebx,dword ptr ds:[esi+404502] ; 变化后的字符串

  004030A7 3BC0 cmp eax,eax ; 第一次比较

  004030A9 |. 75 45 jnz short aescul.004030F0

  004030AB |. 83C6 04 add esi,4

  004030AE |. 8B86 BA424000 mov eax,dword ptr ds:[esi+4042BA]

  004030B4 |. 8B9E 02454000 mov ebx,dword ptr ds:[esi+404502]

  004030BA |. 3BC3 cmp eax,ebx ; 第二次比较

  004030BC 74 32 je short aescul.004030F0 ; 不一样则跳

  004030BE |. 83C6 04 add esi,4

  004030C1 |. 8B86 BA424000 mov eax,dword ptr ds:[esi+4042BA]

  004030C7 |. 8B9E 02454000 mov ebx,dword ptr ds:[esi+404502]

  004030CD |. 3BC3 cmp eax,ebx ; 第三次比较

  004030CF 74 1F je short aescul.004030F0 ; 不一样则跳

  004030D1 |. 83C6 04 add esi,4

  004030D4 |. 8B86 BA424000 mov eax,dword ptr ds:[esi+4042BA]

  004030DA |. 8B9E 02454000 mov ebx,dword ptr ds:[esi+404502]

  004030E0 |. 3BC3 cmp eax,ebx ; 第四次比较

  004030E2 74 0C je short aescul.004030F0 ; 不一样则跳

  004030E4 |. C705 F2444000 0>mov dword ptr ds:[4044F2],1 ; 注册成功标志置1

  004030EE |. EB 0A jmp short aescul.004030FA

  004030F0 |> C705 F2444000 0>mov dword ptr ds:[4044F2],0 ; 置0(表示注册失败)

  004030FA |> 9D popfd

  004030FB |. 33C0 xor eax,eax

  004030FD |. 64:8F00 pop dword ptr fs:[eax]

  00403100 |. 83C4 04 add esp,4

  00403103 |. 833D F2444000 0>cmp dword ptr ds:[4044F2],1 ; 时否成功

  0040310A |. 75 15 jnz short aescul.00403121

  0040310C |. 6A 40 push 40 ;/Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL

  0040310E |. 68 3D404000 push aescul.0040403D ;|Title = "Congratulations..."

  00403113 |. 68 AB414000 push aescul.004041AB ;|Text = "Registered to: yuchao"

  00403118 |. 6A 00 push 0 ;|hOwner = NULL

  0040311A |. E8 A8030000 call <jmp.&USER32.MessageBoxA> ;\MessageBoxA ;注册成功

  0040311F |. EB 13 jmp short aescul.00403134

  00403121 |> 6A 30 push 30 ;/Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL

  00403123 |. 68 50404000 push aescul.00404050 ;|Title = "Error"

  00403128 |. 68 56404000 push aescul.00404056 ;|Text = "Wrong Serial Number!"

  0040312D |. 6A 00 push 0 ;|hOwner = NULL

  0040312F |. E8 93030000 call <jmp.&USER32.MessageBoxA> ;\MessageBoxA ;注册失败

  00403134 |> 6A 00 push 0 ;/ExitCode = 0

  00403136 \. E8 C8030000 call <jmp.&KERNEL32.ExitProcess> ;\ExitProcess

  0040313B /$ 8935 EE444000 mov dword ptr ds:[4044EE],esi

  00403141 |. 8B15 EA444000 mov edx,dword ptr ds:[4044EA] ; 读出上次保存的位置记录

  00403147 |. 8B0D E6444000 mov ecx,dword ptr ds:[4044E6] ; 字符串长度37

  0040314D |. 3BD1 cmp edx,ecx ; 上次call时有没有遍历完字符串

  0040314F |. 72 02 jb short aescul.00403153 ; 遍历完了则重新遍历

  00403151 |. 33D2 xor edx,edx

  00403153 |> 0FBE7415 00 /movsx esi,byte ptr ss:[ebp+edx] ; 取字符串2的字节

  00403158 |. 81E6 0F000080 |and esi,8000000F ; 取esi的低四位

  0040315E |. 79 05 |jns short aescul.00403165 ; 符号位为0时跳

  00403160 |. 4E |dec esi

  00403161 |. 83CE F0 |or esi,FFFFFFF0

  00403164 |. 46 |inc esi

  00403165 |> 3BF0 |cmp esi,eax ; 找到与eax相等的esi

  00403167 |. 74 09 |je short aescul.00403172 ; 跳出

  00403169 |. 42 |inc edx ; 计数器加1

  0040316A |. 3BD1 |cmp edx,ecx ; 是否循环了37次

  0040316C |.^ 7C E5 |jl short aescul.00403153 ; 没到则跳回

  0040316E |. 33D2 |xor edx,edx ; 清edx

  00403170 |.^ EB E1 \jmp short aescul.00403153 ; 跳回去再次遍历(字符串2)

  00403172 |> 8915 EA444000 mov dword ptr ds:[4044EA],edx ; 把所找到的位置记录下

  00403178 |. 8B35 EE444000 mov esi,dword ptr ds:[4044EE]

  0040317E |. 0FBE042A movsx eax,byte ptr ds:[edx+ebp] ; 取那个字节

  00403182 |. 42 inc edx

  00403183 \. C3 retn

  【算法总结】

  1.修改数据段,其中有重要数据"0I5LZ7G123RXCV9OPAS6TBN48YUHJKDF0QWEM"(字符串2),注册表子键名键值名"ProductId"

  2.取输入的注册名,注册码

  3.取注册表值(操作系统的ProductId号),并在在它前面加上"WS"==>(字符串1)

  4.修改代码段,EndDialog

  5.算法部分:1.从字符串1中提取一个字节(依次从第1个到第24个字符)

  2.取该字节的高四位,依次和字符串2中字符的低四位比较,相同则记录下位置和该字符

  3.取该字节的低四位,从字符串2记录位置开始向后和字符的低四位比较,记录下该字符(当比较完后未找到,则从数组开始位置向后比较)

  4.重复123(共24遍)

  5.生成48字节的注册序列

  6.注册码比较时只比较128bit(16字节),所以注册码也只要十六位

  【注册机】

  #include <windows.h>

  #include <iostream.h>

  BOOL QueryValue(BYTE,char*,int);

  char szCode[17]={0};

  int nPosition;

  int Num;

  void main()

  {

  char szProductId[26]={'W','S'};

  char szProductIdTemp[24]={0};

  BYTE bByte=0,bByteTemp=0;

  char szBase[38]={'0','I','5','L','Z','7','G','1','2','3','R','X','C','V','9','O','P','A','S','6','T','B','N','4','8','

  Y','U','H','J','K','D','F','0','Q','W','E','M'};

  char szSubKey[]="Software\\Microsoft\\Windows\\CurrentVersion";

  DWORD nLenght=sizeof(szProductIdTemp);

  HKEY hResultKey;

  if(ERROR_SUCCESS==RegOpenKeyEx

  (HKEY_LOCAL_MACHINE,szSubKey,0,KEY_QUERY_VALUE,&hResultKey))

  if(ERROR_SUCCESS==RegQueryValueEx(hResultKey,"ProductId",0,0,(PBYTE)szProductIdTemp,&nLenght))

  {

  strcat(szProductId,szProductIdTemp);

  for(int i=0;i<8;i++)

  {

  bByte=szProductId[i];

  bByteTemp=(bByte&0xf0)/16;

  QueryValue(bByteTemp,szBase,nPosition);

  bByteTemp=bByte&0x0f;

  QueryValue(bByteTemp,szBase,nPosition);

  }

  cout<<szCode<<endl;

  }

  }

  BOOL QueryValue(BYTE bByte,char* szBase,int nPositionTemp)

  {

  for(int i=nPositionTemp;i<37;i++)

  {

  if(bByte==(szBase[i]&0x0f))

  {

  szCode[Num++]=szBase[i];

  nPosition=i;

  break;

  }

  if(i==36)

  i=-1;

  }

  return 0;

  }

  该CrackMe思路相当清晰,也比较简单很适合新兵练手(我?),新手的文章难免有误,万望高手赐教

  贴上全文以供各位高手嘲笑!!!

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章