首页
社区
课程
招聘
[原创]Hide Window Hotkey V2.5注册算法分析(适合新手)
发表于: 2010-4-9 23:07 7997

[原创]Hide Window Hotkey V2.5注册算法分析(适合新手)

2010-4-9 23:07
7997

【文章标题】: Hide Window HotkeyV2.5注册算法分析
【文章作者】: TyroneKing
【作者邮箱】: tyroneking@126.com
【软件名称】: Hide Window Hotkey
【下载地址】:  HWHSetup.rar
【KeyGen】:  KeyGen.rar
【加壳方式】: ASPack 2.12 -> Alexey Solodovnikov
【保护方式】: 注册名+序列号
【编写语言】: Borland Delphi 6.0 - 7.0
【使用工具】: OD + PEiD+DeDe + MD5计算器+AspackDie+ IDA (可以不用,加强分析)
【操作平台】: WIN XP +SP3、 VC++6.0
【软件介绍】: 隐藏运行的窗口和应用程序软件。
【作者声明】: 只是为了学习,没有其他目的。失误之处敬请诸位大侠赐教!
【分析过程】
1、用PEiD查壳,为ASPack 2.12 -> Alexey Solodovnikov,用ESP定律很容易就可以脱壳了,不过这里还是用AspackDie,不对如何脱壳详说(我也是新手,脱一些简单的行,强壳,还得继续努力呀,:))。
2、用AspackDie脱壳,用PEiD查为Borland Delphi 6.0 - 7.0编写, KANAL 算法识别插件分析,软件用了MD5(地址004B549A)算法,用,直接运行脱壳后程序没啥反应,应该是自检验了。
3、用OD加载下bp GetFileSize 断点,程序中断在GetFileSize函数中,按Alt+F9返回程序领空 004030A1

MD5_CTX context;
  long dtLength;
  int i;
  int len;
  int j;
  TCHAR *szKeyStr="5497312680";
  TCHAR sTemp=' ';

  TCHAR szName[MAXINPUTLEN]={0};
  TCHAR szHash[MAXINPUTLEN]={0};
  TCHAR szBuffer[MAXINPUTLEN]={0};

  dtLength=GetDlgItemText(hWnd, IDC_TXT0, szName, sizeof(szName)/sizeof(TCHAR)+1);  
  len=strlen(szName);
  if (len<=8)//长度判断
  {
    SetDlgItemText(hWnd, IDC_TXT1, "Name必须大于8位!");
    return FALSE;
  }
  for(i=0;i < len; i++)//是否包含 空格
    if(szName[i]==' ')
    {
    SetDlgItemText(hWnd, IDC_TXT1, "Name不能包含空格!");
    return FALSE;
    }      
  sTemp=szName[0];
  i=1;
  while(i<len)
  {
    if(sTemp==szName[i])
      i++;
    else
      break;
  }
  if(i>=len)
  {
    SetDlgItemText(hWnd, IDC_TXT1, "Name不能为单一字符!");
    return FALSE;
  }

  for(i=0;i < len -1; i++)
    szName[i]=szName[i] | szName[i+1];
  szName[len-1]=szName[len-1] | sTemp;//各字节进行 OR 运算
  
  sTemp=szName[len-1];
  for(i=len-1; i > 0 ;i--)
    szName[i]=szName[i-1];
  szName[0]=sTemp;//循环右移一字节

  MD5Init(&context);
  MD5Update(&context, szName, dtLength);//该函数里的MD5Transform函数变形了
  MD5Final(szHash, &context);
  for(i=0; i < 16; i++)   // 将szHash[]中的16进制转换成字符形式显示
  {
    wsprintf(&szBuffer[i*2], "%02X", *(byte*)(szHash+i));
  }//变形MD5
  
  i=0;
  len=0;
  while(len<10 && i<32)
  {
    if(szBuffer[i]>='0' && szBuffer[i]<='9')
    {
      szName[len]=szBuffer[i];
      len+=1;
    }
    i++;
  }//取前10位数字
  szName[len]='\0';
  if(len<1)
  {
    SetDlgItemText(hWnd, IDC_TXT1,"注册码为空?!");       
    return TRUE;
  }

  sTemp=szName[len-1];
  for(i=len-1; i > 0 ;i--)
    szName[i]=szName[i-1];
  szName[0]=sTemp;//循环右移一字节

  for(i=0; i < len ;i++)
  {
    j=szName[i]-'0';
    szName[i]=szKeyStr[j];//根据szName[i]值对取应szKeyStr值
  }

  SetDlgItemText(hWnd, IDC_TXT1,szName);       
  return TRUE;  
00403097  |.  6A 00         PUSH 0                                   ; /pFileSizeHigh = NULL
00403099  |.  8B03          MOV EAX,DWORD PTR DS:[EBX]               ; |
0040309B  |.  50            PUSH EAX                                 ; |hFile
0040309C  |.  E8 FBE1FFFF   CALL <JMP.&kernel32.GetFileSize>         ; \GetFileSize
004030A1  |.  8BF0          MOV ESI,EAX                              ;  EAX=文件大小
……
004030C8  \.  C3            RETN
004C4B86  |.  E8 79DDF3FF   CALL unpacked.00402904               ;  取文件大小
004C4B8B  |.  3D 20A10700   CMP EAX,7A120                        ;  EAX为文件大小
004C4B90  |.  7E 15         JLE SHORT unpacked.004C4BA7          ;  <=7A120则跳,原文件大小6E000,现EAX=1A2000没跳
004C4B92  |.  8D85 ACFEFFFF LEA EAX,DWORD PTR SS:[EBP-154]       ;  将4C4B90跳为JMP,或将7A120改为比1A2000即可
004C4B98  |.  E8 3FE3F3FF   CALL unpacked.00402EDC
004C4B9D  |.  E8 62DDF3FF   CALL unpacked.00402904
004C4BA2  |.  E8 49F9F3FF   CALL unpacked.004044F0               ;  该函数中调用ExitProcess,退出程序
004C4BA7  |>  8D85 ACFEFFFF LEA EAX,DWORD PTR SS:[EBP-154]
004B609C  /.  55            PUSH EBP                                  ;  OKButton
……
004B60BE  |.  8D55 FC       LEA EDX,DWORD PTR SS:[EBP-4]
004B60C1  |.  8B83 2C030000 MOV EAX,DWORD PTR DS:[EBX+32C]            ;  TfrmRegister.eName
004B60C7  |.  E8 5061FAFF   CALL <Crack.TControl.GetText(TControl)>   ;  这里函数名是作了标签的,具体是哪个函数参考DeDe
004B60CC  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]              ;  Tips:知道函数名后进入函数,按Shift+;(即输入冒号)给该函数作标签
004B60CF  |.  E8 ECE7F4FF   CALL <Crack.@LStrLen(String)>
004B60D4  |.  83F8 08       CMP EAX,8
004B60D7  |.  7D 3E         JGE SHORT Crack.004B6117                  ;  Name的长度<8 则提示错误
004B60D9  |.  6A 10         PUSH 10
004B60DB  |.  8D55 F8       LEA EDX,DWORD PTR SS:[EBP-8]
004B60DE  |.  A1 30E74C00   MOV EAX,DWORD PTR DS:[4CE730]
004B60E3  |.  E8 4005F5FF   CALL <Crack.LoadResString(PResStringRec)>
004B60E8  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-8]
004B60EB  |.  E8 D0E9F4FF   CALL <Crack.@LStrToPChar(String)>
004B60F0  |.  50            PUSH EAX
004B60F1  |.  8D55 F4       LEA EDX,DWORD PTR SS:[EBP-C]
004B60F4  |.  A1 C4E64C00   MOV EAX,DWORD PTR DS:[4CE6C4]
004B60F9  |.  E8 2A05F5FF   CALL <Crack.LoadResString(PResStringRec)> ;  在资源文件中提取“提示字符串”,避免通过字符串查找破解
004B60FE  |.  8B45 F4       MOV EAX,DWORD PTR SS:[EBP-C]
004B6101  |.  E8 BAE9F4FF   CALL <Crack.@LStrToPChar(String)>
004B6106  |.  50            PUSH EAX                                  ; |Text
004B6107  |.  E8 5010F5FF   CALL <JMP.&user32.GetActiveWindow>        ; |[GetActiveWindow
004B610C  |.  50            PUSH EAX                                  ; |hOwner
004B610D  |.  E8 7A12F5FF   CALL <JMP.&user32.MessageBoxA>            ; \MessageBoxA
004B6112  |.  E9 4F010000   JMP Crack.004B6266
004B6117  |>  8D55 F0       LEA EDX,DWORD PTR SS:[EBP-10]
004B611A  |.  8B83 2C030000 MOV EAX,DWORD PTR DS:[EBX+32C]            ;  (初始 cpu 选择)
004B6120  |.  E8 F760FAFF   CALL <Crack.TControl.GetText(TControl)>
004B6125  |.  8B55 F0       MOV EDX,DWORD PTR SS:[EBP-10]             ;  取Name
004B6128  |.  B8 DC624B00   MOV EAX,Crack.004B62DC                    ;  空格 20H
004B612D  |.  E8 D2EAF4FF   CALL <Crack.@LStrPos>                     ;  Name是否包含空格
004B6132  |.  85C0          TEST EAX,EAX
004B6134  |.  7E 3E         JLE SHORT Crack.004B6174                  ;  不包含则跳
……
004B6174  |>  8D55 E4       LEA EDX,DWORD PTR SS:[EBP-1C]
004B6177  |.  8B83 2C030000 MOV EAX,DWORD PTR DS:[EBX+32C]
004B617D  |.  E8 9A60FAFF   CALL <Crack.TControl.GetText(TControl)>
004B6182  |.  8B45 E4       MOV EAX,DWORD PTR SS:[EBP-1C]
004B6185  |.  E8 36E7F4FF   CALL <Crack.@LStrLen(String)>
004B618A  |.  8BF0          MOV ESI,EAX
004B618C  |.  83EE 02       SUB ESI,2
004B618F  |.  7C 36         JL SHORT Crack.004B61C7                   ;  Name的长度小于2,则错误
004B6191  |.  46            INC ESI                                   ;  /------------------------
004B6192  |.  BF 02000000   MOV EDI,2
004B6197  |>  8D55 E0       /LEA EDX,DWORD PTR SS:[EBP-20]
004B619A  |.  8B83 2C030000 |MOV EAX,DWORD PTR DS:[EBX+32C]
004B61A0  |.  E8 7760FAFF   |CALL <Crack.TControl.GetText(TControl)>  ;  取Name
004B61A5  |.  8B45 E0       |MOV EAX,DWORD PTR SS:[EBP-20]
004B61A8  |.  8A4438 FF     |MOV AL,BYTE PTR DS:[EAX+EDI-1]           ;  AL=Name[EDI-1]
004B61AC  |.  50            |PUSH EAX
004B61AD  |.  8D55 DC       |LEA EDX,DWORD PTR SS:[EBP-24]
004B61B0  |.  8B83 2C030000 |MOV EAX,DWORD PTR DS:[EBX+32C]
004B61B6  |.  E8 6160FAFF   |CALL <Crack.TControl.GetText(TControl)>
004B61BB  |.  8B45 DC       |MOV EAX,DWORD PTR SS:[EBP-24]
004B61BE  |.  5A            |POP EDX
004B61BF  |.  3A10          |CMP DL,BYTE PTR DS:[EAX]                 ;  Name[EDI-1]与Name[0]比较
004B61C1  |.  75 04         |JNZ SHORT Crack.004B61C7
004B61C3  |.  47            |INC EDI                                  ;  相等则 EDI+1
004B61C4  |.  4E            |DEC ESI
004B61C5  |.^ 75 D0         \JNZ SHORT Crack.004B6197
004B61C7  |>  8D55 D8       LEA EDX,DWORD PTR SS:[EBP-28]
004B61CA  |.  8B83 2C030000 MOV EAX,DWORD PTR DS:[EBX+32C]
004B61D0  |.  E8 4760FAFF   CALL <Crack.TControl.GetText(TControl)>
004B61D5  |.  8B45 D8       MOV EAX,DWORD PTR SS:[EBP-28]
004B61D8  |.  E8 E3E6F4FF   CALL <Crack.@LStrLen(String)>
004B61DD  |.  3BF8          CMP EDI,EAX
004B61DF  |.  7E 3B         JLE SHORT Crack.004B621C                  ;  EDI>EAX 提示出错
004B61E1  |.  6A 10         PUSH 10                                   ;  \若用户名为单一字符,出提示错误
……
004B621C  |>  8D55 CC       LEA EDX,DWORD PTR SS:[EBP-34]
004B621F  |.  8B83 2C030000 MOV EAX,DWORD PTR DS:[EBX+32C]
004B6225  |.  E8 F25FFAFF   CALL <Crack.TControl.GetText(TControl)>   ;  取Name
004B622A  |.  8B55 CC       MOV EDX,DWORD PTR SS:[EBP-34]
004B622D  |.  8BC3          MOV EAX,EBX
004B622F  |.  E8 CC020000   CALL Crack.004B6500                       ;  计算Code
004B6234  |.  8D55 C8       LEA EDX,DWORD PTR SS:[EBP-38]
004B6237  |.  8B83 30030000 MOV EAX,DWORD PTR DS:[EBX+330]
004B623D  |.  E8 DA5FFAFF   CALL <Crack.TControl.GetText(TControl)>   ;  取假Code
004B6242  |.  8B55 C8       MOV EDX,DWORD PTR SS:[EBP-38]
004B6245  |.  8D83 38030000 LEA EAX,DWORD PTR DS:[EBX+338]            ;  保假Code
004B624B  |.  E8 04E4F4FF   CALL <Crack.@LStrAsg>
004B652D  |.  837D F8 00    CMP DWORD PTR SS:[EBP-8],0
004B6531  |.  0F84 FB000000 JE Crack.004B6632                      ;  Name为空?
004B6537  |.  8D45 F4       LEA EAX,DWORD PTR SS:[EBP-C]           ;  /-----------
004B653A  |.  8B55 F8       MOV EDX,DWORD PTR SS:[EBP-8]
004B653D  |.  E8 56E1F4FF   CALL <Crack.@LStrLAsg(void;void;void;v>
004B6542  |.  8B45 F4       MOV EAX,DWORD PTR SS:[EBP-C]
004B6545  |.  E8 76E3F4FF   CALL <Crack.@LStrLen(String)>          ;  取Name的长度
004B654A  |.  8BF8          MOV EDI,EAX
004B654C  |.  8B45 F4       MOV EAX,DWORD PTR SS:[EBP-C]           ;  Name
004B654F  |.  8A00          MOV AL,BYTE PTR DS:[EAX]               ;  AL=Name[0]
004B6551  |.  8845 F3       MOV BYTE PTR SS:[EBP-D],AL
004B6554  |.  8BF7          MOV ESI,EDI                            ;  ESI=Name的长度
004B6556  |.  4E            DEC ESI
004B6557  |.  85F6          TEST ESI,ESI
004B6559  |.  7E 22         JLE SHORT Crack.004B657D
004B655B  |.  BB 01000000   MOV EBX,1
004B6560  |>  8D45 F4       /LEA EAX,DWORD PTR SS:[EBP-C]
004B6563  |.  E8 B0E5F4FF   |CALL <Crack.InternalUniqueString>     ;  UniqueString is used only in cases where an application casts a string to a PChar or PWideChar and then modifies the contents of the string.
004B6568  |.  8B55 F4       |MOV EDX,DWORD PTR SS:[EBP-C]
004B656B  |.  8A541A FF     |MOV DL,BYTE PTR DS:[EDX+EBX-1]        ;  DL=Name[EBX-1]
004B656F  |.  8B4D F4       |MOV ECX,DWORD PTR SS:[EBP-C]
004B6572  |.  0A1419        |OR DL,BYTE PTR DS:[ECX+EBX]           ;  DL=Name[EBX-1] OR Name[EBX]
004B6575  |.  885418 FF     |MOV BYTE PTR DS:[EAX+EBX-1],DL        ;  结果存在[EBP-C]的EBX-1中
004B6579  |.  43            |INC EBX
004B657A  |.  4E            |DEC ESI
004B657B  |.^ 75 E3         \JNZ SHORT Crack.004B6560              ;  处理完Len-1位了?
004B657D  |>  8D45 F4       LEA EAX,DWORD PTR SS:[EBP-C]
004B6580  |.  E8 93E5F4FF   CALL <Crack.InternalUniqueString>
004B6585  |.  8B55 F4       MOV EDX,DWORD PTR SS:[EBP-C]
004B6588  |.  8A543A FF     MOV DL,BYTE PTR DS:[EDX+EDI-1]         ;  DL=Name的最后一位
004B658C  |.  0A55 F3       OR DL,BYTE PTR SS:[EBP-D]              ;  与004B6551对应,即Name[0]
004B658F  |.  885438 FF     MOV BYTE PTR DS:[EAX+EDI-1],DL         ;  DL=Name[Len-1] OR Name[0]
004B6593  |.  8D4D EC       LEA ECX,DWORD PTR SS:[EBP-14]          ;  \--对Name的第i位与第i+1位(最后一位与第0位)进行OR运算
004B6596  |.  8B55 F4       MOV EDX,DWORD PTR SS:[EBP-C]           ;  记为NameOR,这里="][_OOOKOOW"
004B6599  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
004B659C  |.  E8 C3000000   CALL Crack.004B6664                    ;  第二层运算

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (3)
雪    币: 433
活跃值: (1895)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
2
support!
2010-4-10 12:51
0
雪    币: 22
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习了,第一次写注册机。。。
2012-11-21 07:05
0
雪    币: 136
活跃值: (65)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
4
新人,正在学习,谢谢分享
2013-2-21 12:57
0
游客
登录 | 注册 方可回帖
返回