我的CrackMe8的设计思路

这个CrackMe的整体思路是想通过异常来打断程序的正常流程,以达到迷惑的目的!

代码是用VC8来完成的!
首先是按钮事件的触发:


case IDC_REGISTER:
          {
          TCHAR szContent[1024];
          memset(szContent,0,1024);
          for(int i=0;info1[i];i++)
            szContent[i]=info1[i]^0x78;

          TCHAR szT[128];
          memset(szT,0,128);
          for(int i=0;szTitle[i];i++)
            szT[i]=szTitle[i]^0x78;

          int nRet=GetDlgItemText(hDlg,IDC_USERNAME,strName,STR_LEN);
          if(nRet<5){
            MessageBox(NULL,szContent,szT,MB_OK);
            return TRUE;
          }

          memset(szContent,0,1024);
          for(int i=0;info2[i];i++)
            szContent[i]=info2[i]^0x78;
          nRet=GetDlgItemText(hDlg,IDC_PWD,strCode,STR_LEN);
          if(nRet!=16){
            MessageBox(NULL,szContent,szT,MB_OK);
            return TRUE;
          }
          __try{
            _asm int 3
          }
          __except(EXCEPTION_BREAKPOINT==GetExceptionCode()){
            SendMessage(hDlg,IAWEN_VERIFY,0,0);
          }
          }
          return TRUE;  

在这个事件中,我只是做一个简单的判断与验证是否符合要求!
其关键的地方是这里:


__try{
            _asm int 3
          }
          __except(EXCEPTION_BREAKPOINT==GetExceptionCode()){
            SendMessage(hDlg,IAWEN_VERIFY,0,0);
          }

通过人为的int3异常,跳转到了一个自定义的消息里,然后再转向真实的验证地址,当然我们还可以在这里玩更多的花样,呵呵!


case IAWEN_VERIFY:
      RegistMyCrackMe(hDlg);
      return TRUE;

2、在真实的验证函数里,同样也利用到了异常来强行改变程序的流程:


__try{
    _asm int 3
    _asm int 3
  }
  __except(GetExceptionCode() == EXCEPTION_BREAKPOINT)
  {
    if((dwCode1==dwHash2-0x1234567) &&(dwCode2==dwHash1+0x0123456)){
      memset(szContent,0,1024);
      for(int i=0;info4[i];i++)
        szContent[i]=info4[i]^0x78;

      SendMessage(GetDlgItem(hDlg,IDC_USERNAME),EM_SETREADONLY,(WPARAM)TRUE,0);
      SendMessage(GetDlgItem(hDlg,IDC_PWD),EM_SETREADONLY,(WPARAM)TRUE,0);
      SetWindowText(hDlg,szContent);
      }
  }

这里将最后的判断再次强行转换了个位置!

3、同时,为了增加一些难度,增加了一个线程来反对在关键的函数(验证函数RegistMyCrackMe(hDlg)):
[codes]
BOOL WINAPI VerifyPro(LPVOID lParam){
  const BYTE *dwAddr=(BYTE*)RegistMyCrackMe;

  while(1){
    for(int i=0;;i++){
      if(*(dwAddr+i) == 0xCC)
      {
        if( *(dwAddr+i+1)!=0xCC)
          ExitProcess(0);
        else
          break;
      }
    }
    Sleep(50);
  }
  return TRUE;
}

首先获取验证函数的首地址,然后逐位判断是否等于0xCC,即int3中断,在OD等调试器里,也就是一般的F2断点。所以如果在跟踪程序时,如果在该函数里下F2断点的话,运行的话的,都将自动退出!

下载源码:
CrackMe.8.rar

发表评论