SecureCRT 7.1的crack过程,已放弃
2023-2-20 08:1:17 Author: 奶牛安全(查看原文) 阅读量:24 收藏

现象



思路

在分析之前,先整理一下程序流程。整个流程可以分解为以下几步:

  1. 填写注册信息
  2. 点击next按钮,触发事件
  3. 事件处理函数会获取文本框里的注册码
  4. 程序校验注册码,得出校验结果
  5. 根据校验结果来显示失败或成功的信息

破解一般是从第3步或第5步进行。因为从文本框获取信息无非就是几个函数GetWindowText, GetDlgItemText, CWnd::GetWindowText。而显示校验结果的也无非是几个函数,SetWindowText, SetDlgItemText, CWnd::SetWindowText, CWnd::SetDlgItemText,MessageBox, DoModal等,当然校验结果的信息也可以通过搜索内存来达到。

一般情况下,先从第5点开始分析,因为通过栈回溯一般很容易找到关键的校验点。

重新启动SCRT程序,


选择“Enter License Data”,出现


windbg附加到进程里。这个进程名称叫licenseHelper


由于这个程序并不会弹出对话框,所以,MessageBox, DoModal之类的函数不用关注,只要看一下SetWindowText, SetDlgItemText, CWnd::SetWindowText, CWnd::SetDlgItemText.

搜索一下SetWindowText, SetDlgItemText, CWnd::SetWindowText, CWnd::SetDlgItemText这些符号


由于SetWindowText, SetDlgItemText是在user32.dll定义的, CWnd这个类是MFC库定义, 且windows默认是unicode编码,SetWindowTextA调用SetWindowTextW, SetDlgItemTextA调用SetDlgItemTextW

同时CWnd::SetWindowTextW是调用SetWindowTextWCWnd::SetDlgItemTextW是调用SetDlgItemTextW,所以在这里选取在

  77d2960e USER32!SetWindowTextW = <no  type information>  
  77d2736c USER32!SetDlgItemTextW = <no  type information>  

打断点


运行结果如下:

  0:000> g  
  Breakpoint 0 hit  eax=00000001 ebx=2001f958 ecx=77d2934b  edx=7c92e401 esi=00aa0f78 edi=003fe1d4  
  eip=77d2960e esp=0012ef1c ebp=0012ef2c  iopl=0     nv up ei pl zr na pe nc  
  cs=001b   ss=0023 ds=0023 es=0023   fs=003b gs=0000       efl=00000246  
  USER32!SetWindowTextW:  
  77d2960e 8bff      mov   edi,edi  
  0:000> kb  
  ChildEBP RetAddr Args to Child         
  0012ef18 7884a04e 0002042e 2001f958  003fe108 USER32!SetWindowTextW  
  0012ef2c 200073de 2001f958 003fe1d4  0012efb4 mfc100u!CWnd::SetWindowTextW+0x42  
  WARNING: Stack unwind information not  available. Following frames may be wrong.  
  0012ef44 2000418d ffffff00 2001f958  20007cb0 LicenseUI70U!ShowInvalidLicenseDialog+0x169e  
  0012ef7c 787df50d 003fe240 0000004e  00159670 LicenseUI70U+0x418d  
  0012ef90 78834c72 00000000 0012f338  0012efb4 mfc100u!CPropertyPage::OnNotify+0xe9  
  0012f058 78834bad 0000004e 00000000  0012f338 mfc100u!CWnd::OnWndMsg+0x9e  
  0012f078 78832fcc 0000004e 00000000  0012f338 mfc100u!CWnd::WindowProc+0x24  
  0012f0f0 78833258 003fe240 00020420  0000004e mfc100u!AfxCallWndProc+0xb5  
  0012f114 78729faf 00020420 0000004e  00000000 mfc100u!AfxWndProc+0x37  
  0012f158 77d18734 00020420 0000004e  00000000 mfc100u!AfxWndProcBase+0x56  
  0012f184 77d18816 78729f59 00020420  0000004e USER32!InternalCallWinProc+0x28  
  0012f1ec 77d2927b 0015c3b0 78729f59  00020420 USER32!UserCallWinProcCheckWow+0x150  
  0012f228 77d292e3 00743160 006f77a8 00000000  USER32!SendMessageWorker+0x4a5  
  0012f248 7719ab34 00020420 0000004e  00000000 USER32!SendMessageW+0x7f  
  0012f2e0 7719b17c 0012f2f8 ffffff31  0012f338 COMCTL32!CCSendNotify+0x748  
  0012f31c 771887d9 00020420 000a02a4  ffffff31 COMCTL32!SendNotifyEx+0x57  
  0012f348 7718a55f 0015f210 00000000  ffffff31 COMCTL32!_Ppd_SendNotify+0x2b  
  0012f368 7718c154 0015f210 ffffff31  00003024 COMCTL32!WizNextBack+0x2a  
  0012f384 7718c67b 0015f210 00003024  0002043a COMCTL32!Prsht_OnCommand+0x14f  
  0012f3fc 77d18734 000a02a4 00000111 00003024  COMCTL32!PropSheetDlgProc+0x4b1  
  0:000> du 2001f958
  2001f958   "&Extend Evaluation"
  0:000> g  
  Breakpoint 0 hit  eax=00000001 ebx=2001f928 ecx=77d2934b  edx=7c92e401 esi=00aa0f78 edi=003fe1d4  
  eip=77d2960e esp=0012ece8 ebp=0012ecf8  iopl=0     nv up ei pl zr na pe nc  
  cs=001b   ss=0023 ds=0023 es=0023   fs=003b gs=0000       efl=00000246  
  USER32!SetWindowTextW:  
  77d2960e 8bff      mov   edi,edi  
  0:000> kb  
  ChildEBP RetAddr Args to Child         
  0012ece4 7884a04e 0002042e 2001f928  003fe108 USER32!SetWindowTextW  
  0012ecf8 200073de 2001f928 003fe35c  003fe1d4 mfc100u!CWnd::SetWindowTextW+0x42  
  WARNING: Stack unwind information not  available. Following frames may be wrong.  
  0012ed10 2000419d 7c92e401 2001f928  20007ed4 LicenseUI70U!ShowInvalidLicenseDialog+0x169e  
  0012ed44 787df4b6 003fe35c 0000004e  00159670 LicenseUI70U+0x419d  
  0012ed58 78834c72 00000000 0012f100  0012ed7c mfc100u!CPropertyPage::OnNotify+0x92  
  0012ee20 78834bad 0000004e 00000000  0012f100 mfc100u!CWnd::OnWndMsg+0x9e  
  0012ee40 78832fcc 0000004e 00000000  0012f100 mfc100u!CWnd::WindowProc+0x24  
  0012eeb8 78833258 003fe35c 001e06f8  0000004e mfc100u!AfxCallWndProc+0xb5  
  0012eedc 78729faf 001e06f8 0000004e  00000000 mfc100u!AfxWndProc+0x37  
  0012ef20 77d18734 001e06f8 0000004e  00000000 mfc100u!AfxWndProcBase+0x56  
  0012ef4c 77d18816 78729f59 001e06f8  0000004e USER32!InternalCallWinProc+0x28  
  0012efb4 77d2927b 0015c3b0 78729f59  001e06f8 USER32!UserCallWinProcCheckWow+0x150  
  0012eff0 77d292e3 0074f900 006f77a8  00000000 USER32!SendMessageWorker+0x4a5  
  0012f010 7719ab34 001e06f8 0000004e  00000000 USER32!SendMessageW+0x7f  
  0012f0a8 7719b17c 0012f0c0 ffffff38  0012f100 COMCTL32!CCSendNotify+0x748  
  0012f0e4 771887d9 001e06f8 000a02a4  ffffff38 COMCTL32!SendNotifyEx+0x57  
  0012f110 7718a17c 0015f210 00000001  ffffff38 COMCTL32!_Ppd_SendNotify+0x2b  
  0012f32c 7718a526 0015f210 00000001  0015f210 COMCTL32!PageChange+0x2e7  
  0012f348 7718a582 0015f210 00000000  00000001 COMCTL32!PageSetSelection+0x95  
  0012f368 7718c154 0015f210 ffffff31  00003024 COMCTL32!WizNextBack+0x4d  
  0:000> du 2001f928
  2001f928   "&Enter License Manually"
  0:000> g  
  (efc.588): C++ EH exception - code  e06d7363 (first chance)  
  Breakpoint 0 hit  
  eax=00000001 ebx=00aa15b4 ecx=77d2934b  edx=00aa0901 esi=003fc6d8 edi=00000000  
  eip=77d2960e esp=0012ed08 ebp=0012ed18  iopl=0     nv up ei pl zr na pe nc  
  cs=001b   ss=0023 ds=0023 es=0023   fs=003b gs=0000       efl=00000246  
  USER32!SetWindowTextW:  
  77d2960e 8bff      mov   edi,edi  
  0:000> kb  
  ChildEBP RetAddr Args to Child         
  0012ed04 7884a04e 0003070a 00aa15b4  003fe35c USER32!SetWindowTextW  
  0012ed18 20007f77 00aa15b4 b20107b6  0012f100 mfc100u!CWnd::SetWindowTextW+0x42  
  WARNING: Stack unwind information not  available. Following frames may be wrong.  
  0012ed44 787df4b6 003fe35c 0000004e  00159670 LicenseUI70U!ShowLicenseWizard+0xa27  
  0012ed58 78834c72 00000000 0012f100  0012ed7c mfc100u!CPropertyPage::OnNotify+0x92  
  0012ee20 78834bad 0000004e 00000000  0012f100 mfc100u!CWnd::OnWndMsg+0x9e  
  0012ee40 78832fcc 0000004e 00000000  0012f100 mfc100u!CWnd::WindowProc+0x24 
  0012eeb8 78833258 003fe35c 001e06f8  0000004e mfc100u!AfxCallWndProc+0xb5  
  0012eedc 78729faf 001e06f8 0000004e  00000000 mfc100u!AfxWndProc+0x37  
  0012ef20 77d18734 001e06f8 0000004e  00000000 mfc100u!AfxWndProcBase+0x56  
  0012ef4c 77d18816 78729f59 001e06f8 0000004e  USER32!InternalCallWinProc+0x28  
  0012efb4 77d2927b 0015c3b0 78729f59  001e06f8 USER32!UserCallWinProcCheckWow+0x150  
  0012eff0 77d292e3 0074f900 006f77a8  00000000 USER32!SendMessageWorker+0x4a5  
  0012f010 7719ab34 001e06f8 0000004e  00000000 USER32!SendMessageW+0x7f  
  0012f0a8 7719b17c 0012f0c0 ffffff38  0012f100 COMCTL32!CCSendNotify+0x748  
  0012f0e4 771887d9 001e06f8 000a02a4  ffffff38 COMCTL32!SendNotifyEx+0x57  
  0012f110 7718a17c 0015f210 00000001  ffffff38 COMCTL32!_Ppd_SendNotify+0x2b  
  0012f32c 7718a526 0015f210 00000001  0015f210 COMCTL32!PageChange+0x2e7  
  0012f348 7718a582 0015f210 00000000  00000001 COMCTL32!PageSetSelection+0x95  
  0012f368 7718c154 0015f210 ffffff31  00003024 COMCTL32!WizNextBack+0x4d  
  0012f384 7718c67b 0015f210 00003024  0002043a COMCTL32!Prsht_OnCommand+0x14f  
  0:000> du 00aa15b4
  00aa15b4 "The  license data was not valid.."
  00aa15f4   "...Press the Back button to try "
  00aa1634 "again  or press the Enter License"
  00aa1674 "  Manually button to enter the li"
  00aa16b4 "cense  data by hand..."
  0:000> g  
  Breakpoint 0 hit  
  eax=0012f1c4 ebx=77d2af56 ecx=0012f0d8  edx=7c92e4f4 esi=0015f210 edi=77d2929a  
  eip=77d2960e esp=0012f11c ebp=0012f32c  iopl=0     nv up ei pl nz na po nc  
  cs=001b   ss=0023 ds=0023 es=0023   fs=003b gs=0000       efl=00000202  
  USER32!SetWindowTextW:  
  77d2960e 8bff      mov   edi,edi  
  0:000> kb  
  ChildEBP RetAddr Args to Child         
  0012f118 7718a331 000a02a4 0012f1c4  0015f210 USER32!SetWindowTextW  
  0012f32c 7718a526 0015f210 00000001  0015f210 COMCTL32!PageChange+0x49c  
  0012f348 7718a582 0015f210 00000000  00000001 COMCTL32!PageSetSelection+0x95  
  0012f368 7718c154 0015f210 ffffff31  00003024 COMCTL32!WizNextBack+0x4d  
  0012f384 7718c67b 0015f210 00003024  0002043a COMCTL32!Prsht_OnCommand+0x14f  
  0012f3fc 77d18734 000a02a4 00000111 00003024  COMCTL32!PropSheetDlgProc+0x4b1  
  0012f428 77d23ce4 7718c1ca 000a02a4  00000111 USER32!InternalCallWinProc+0x28  
  0012f494 77d23b30 001592a0 7718c1ca  000a02a4 USER32!UserCallDlgProcCheckWow+0x146  
  0012f4dc 77d23d5c 00000000 00000111  00003024 USER32!DefDlgProcWorker+0xa8  
  0012f4f8 77d18734 000a02a4 00000111  00003024 USER32!DefDlgProcW+0x22  
  0012f524 77d18816 77d23d3a 000a02a4  00000111 USER32!InternalCallWinProc+0x28  
  0012f58c 77d2a013 001592a0 77d23d3a  000a02a4 USER32!UserCallWinProcCheckWow+0x150  
  0012f5bc 77d2a039 77d23d3a 000a02a4  00000111 USER32!CallWindowProcAorW+0x98  
  0012f5dc 78833b50 77d23d3a 000a02a4  00000111 USER32!CallWindowProcW+0x1b  
  0012f5fc 78834bc4 00000111 00003024  0002043a mfc100u!CWnd::DefWindowProcW+0x44  
  0012f618 78832fcc 00000111 00003024 0002043a  mfc100u!CWnd::WindowProc+0x3b  
  0012f690 78833258 003fe108 000a02a4  00000111 mfc100u!AfxCallWndProc+0xb5  
  0012f6b4 78729faf 000a02a4 00000111  00003024 mfc100u!AfxWndProc+0x37  
  0012f6f8 77d18734 000a02a4 00000111  00003024 mfc100u!AfxWndProcBase+0x56  
  0012f724 77d18816 78729f59 000a02a4  00000111 USER32!InternalCallWinProc+0x28  
  0:000> du 0012f1c4
  0012f1c4   "License Wizard"

可以看到出错界面显示的字符串都在上面。

由于堆栈

0012ed04 7884a04e 0003070a 00aa15b4  003fe35c USER32!SetWindowTextW  
0012ed18 20007f77  00aa15b4 b20107b6 0012f100 mfc100u!CWnd::SetWindowTextW+0x42  
WARNING: Stack unwind information not  available. Following frames may be wrong.  
0012ed44 787df4b6  003fe35c 0000004e 00159670 LicenseUI70U!ShowLicenseWizard+0xa27  
0012ed58 78834c72 00000000 0012f100  0012ed7c mfc100u!CPropertyPage::OnNotify+0x92  

才是显示那出错信息的。

所以,看一下返回地址20007f77所指向的函数是怎样

.text:20007F53         lea   edx, [ebp+var_10]  
.text:20007F56         push  edx  
.text:20007F57         mov   ecx, ebx  
.text:20007F59         call    sub_20002890  
.text:20007F5E         mov   ebx, [ebp+var_10]  
.text:20007F61         push  ebx  
.text:20007F62         push  7EFh  
.text:20007F67         mov   ecx, esi    ; this pointer  
.text:20007F69         call  ds:mfc100u_4805 ; CWnd::GetDlgItem  
.text:20007F6F         mov   ecx, eax    ; ecx store this pointer  
.text:20007F71         call  ds:mfc100u_12951 ; CWnd::SetWindowTextW  
.text:20007F77         mov   ecx, esi  

根据CWnd::GetDlgItemCWnd::SetWindowTextW的原型:

  CWnd* GetDlgItem( int nID ) const;     
  void SetWindowText( LPCTSTR lpszString );     

可知,ebx应该是lpszString的指针。在20007F71打断点:

0:001> bp 20007F71  
0:001> g  
(efc.588): C++ EH exception - code  e06d7363 (first chance)  
(efc.588): C++ EH exception - code  e06d7363 (first chance)  
Breakpoint 0 hit  
eax=003fc6d8 ebx=00aa15b4 ecx=003fc6d8  edx=00aa095c esi=003fe35c edi=00000000  
eip=20007f71 esp=0012ed20 ebp=0012ed44  iopl=0     nv up ei pl zr na pe nc  
cs=001b   ss=0023 ds=0023 es=0023   fs=003b gs=0000       efl=00000246  
LicenseUI70U!ShowLicenseWizard+0xa21:  
20007f71 ff1578f20120  call    dword ptr [LicenseUI70U!ShowOfferHelpDialog+0x12458 (2001f278)]  ds:0023:2001f278={mfc100u!CWnd::SetWindowTextW (7884a00c)}  
0:000> du ebx  
00aa15b4   "The license data was not valid.."  
00aa15f4   "...Press the Back button to try "  
00aa1634   "again or press the Enter License"  
00aa1674   " Manually button to enter the li"  
00aa16b4   "cense data by hand..."  

果然是由ebx传入的。而ebx是在这一系列中

.text:20007F53         lea   edx, [ebp+var_10]  
.text:20007F56         push  edx  
.text:20007F57         mov   ecx, ebx  
.text:20007F59         call  sub_20002890  
.text:20007F5E         mov   ebx, [ebp+var_10]  

sub_20002890取出的值。而由


可知没有任何其它参数传入得到这个值,这个值是完全由20002890得出的。

而看一下整个函数

.text:20007E60 sub_20007E60  proc near        ; DATA XREF: .rdata:20020E54o  
.text:20007E60  .text:20007E60 var_10     = dword ptr -10h  
.text:20007E60 var_C      = dword ptr -0Ch  
.text:20007E60 var_4      = dword ptr -4  
.text:20007E60  
.text:20007E60         push  ebp  
.text:20007E61         mov   ebp, esp  
.text:20007E63         push  0FFFFFFFFh  
.text:20007E65         push  offset  [email protected]@[email protected]@@Z_20  .text:20007E6A         mov   eax, large fs:0  
.text:20007E70         push  eax  
.text:20007E71         push  ecx  
.text:20007E72         push  ebx  
.text:20007E73         push  esi  
.text:20007E74         push  edi  
.text:20007E75         mov   eax, dword_20038018  
.text:20007E7A         xor   eax, ebp  
.text:20007E7C         push  eax  
.text:20007E7D         lea   eax, [ebp+var_C]  
.text:20007E80         mov   large fs:0, eax  
.text:20007E86         mov   esi, ecx  
.text:20007E88         mov   eax, [esi+20h]  
.text:20007E8B         push  eax       ; hWnd  
.text:20007E8C         call  ds:GetParent  
.text:20007E92         push  eax  
.text:20007E93         call  ds:mfc100u_4360 ; CWnd::FromHandle  
.text:20007E99         push  0  
.text:20007E9B         push  offset off_20038208  
.text:20007EA0         push  offset off_2003805C  
.text:20007EA5         push  0  
.text:20007EA7         push  eax  
.text:20007EA8         call  __RTDynamicCast  
.text:20007EAD         add   esp, 14h  
.text:20007EB0         push  1        ; lParam  .
text:20007EB2         push  0        ; wParam  
.text:20007EB4         mov   edi, eax  
.text:20007EB6         mov   ecx, [edi+20h]  
.text:20007EB9         push  470h      ; Msg  
.text:20007EBE         push  ecx       ; hWnd  
.text:20007EBF         call  ds:PostMessageW  
.text:20007EC5         lea   ebx, [edi+0CCh]  
.text:20007ECB         mov   dl, 1  
.text:20007ECD         mov   ecx, ebx  
.text:20007ECF         call  sub_20004190  
.text:20007ED4         mov   eax, edi  
.text:20007ED6         call  sub_20007310  
.text:20007EDB         mov   edx, [esi+0C8h]  
.text:20007EE1         xor   edi, edi  
.text:20007EE3         push  edi       ; lParam  
.text:20007EE4         push  eax       ; wParam  
.text:20007EE5         push  170h      ; Msg  
.text:20007EEA         push  edx       ; hWnd  
.text:20007EEB         call  ds:SendMessageW  
.text:20007EF1         test  byte ptr dword_200405C8, 2  
.text:20007EF8         jnz   short  loc_20007F3A   
.text:20007EFA         or   dword_200405C8, 2  
.text:20007F01         mov   eax, 1  
.text:20007F06         mov   [ebp+var_4], eax  
.text:20007F09         xor   ecx, ecx  
.text:20007F0B         mov   word_200405AC, cx  
.text:20007F12         mov   Addend, eax  
.text:20007F17         mov   dword_200405A4, edi  
.text:20007F1D         mov   dword_2004059C, edi  
.text:20007F23         mov   dword_20040598, edi  
.text:20007F29         mov   dword_200405A0, offset word_200405AC  
.text:20007F33         mov   [ebp+var_4], 0FFFFFFFFh  
.text:20007F3A  
.text:20007F3A loc_20007F3A:              ; CODE XREF:  sub_20007E60+98j  
.text:20007F3A         push  offset Addend  ; lpAddend  
.text:20007F3F         call  ds:InterlockedIncrement  
.text:20007F45         mov   [ebp+var_10], offset word_200405AC  
.text:20007F4C         mov   [ebp+var_4], 2  
.text:20007F53         lea   edx, [ebp+var_10]  
.text:20007F56         push  edx  
.text:20007F57         mov   ecx, ebx  
.text:20007F59         call  sub_20002890  
.text:20007F5E         mov   ebx, [ebp+var_10]  
.text:20007F61         push  ebx  
.text:20007F62         push  7EFh  
.text:20007F67         mov   ecx, esi    ; this pointer  
.text:20007F69         call  ds:mfc100u_4805 ; CWnd::GetDlgItem
.text:20007F6F         mov   ecx, eax    ; ecx store this pointer
.text:20007F71         call  ds:mfc100u_12951 ; CWnd::SetWindowTextW
.text:20007F77         mov   ecx, esi  
.text:20007F79         call  ds:__imp_mfc100u_10352 ;  CPropertyPage::OnSetActive  
.text:20007F7F         mov   edi, eax  
.text:20007F81         mov   [ebp+var_4], 0FFFFFFFFh  
.text:20007F88         lea   esi, [ebx-14h]  
.text:20007F8B         lea   eax, [esi+10h]  
.text:20007F8E         push  eax       ; lpAddend  
.text:20007F8F         call  ds:InterlockedDecrement  
.text:20007F95         test  eax, eax  
.text:20007F97         jg   short loc_20007FB9  
.text:20007F99         cmp   dword ptr [esi+0Ch], 1  
.text:20007F9D         jnz   short loc_20007FAF  
.text:20007F9F         mov   ecx, [esi]  
.text:20007FA1         add   ecx, 14h  
.text:20007FA4         mov   eax, esi  
.text:20007FA6         jz   short loc_20007FAF  
.text:20007FA8  
.text:20007FA8 loc_20007FA8:              ; CODE XREF: sub_20007E60+14Dj  
.text:20007FA8         mov   byte ptr [eax], 0  
.text:20007FAB         inc   eax  
.text:20007FAC         dec   ecx  
.text:20007FAD         jnz   short loc_20007FA8  
.text:20007FAF  
.text:20007FAF loc_20007FAF:              ; CODE XREF:  sub_20007E60+13Dj  
.text:20007FAF                     ;  sub_20007E60+146j  
.text:20007FAF         push  esi       ; Memory  
.text:20007FB0         call    ds:free  
.text:20007FB6         add   esp, 4  
.text:20007FB9  
.text:20007FB9 loc_20007FB9:              ; CODE XREF:  sub_20007E60+137j  
.text:20007FB9         mov   eax, edi  
.text:20007FBB         mov   ecx, [ebp+var_C]  
.text:20007FBE         mov   large fs:0, ecx  
.text:20007FC5         pop   ecx  
.text:20007FC6         pop   edi  
.text:20007FC7         pop   esi  
.text:20007FC8         pop   ebx  
.text:20007FC9         mov   esp, ebp  
.text:20007FCB         pop   ebp  
.text:20007FCC         retn  
.text:20007FCC sub_20007E60  endp  

虽然20007F3A这一跳转地址,但无论如何,函数都会执行到显示出“The license data was not valid”的字符串。说明sub_20007E60是位于license校验失败的分支流程中。

由于调用sub_20007E60的函数是MFC库的函数,所以,在这里,通过校验结果来破解是行不通的。

由于上面的分析失败,尝试一下通过GetWindowText, GetDlgItemText, CWnd::GetWindowText等API来分析。

由于MFC是对user32的封装。所以只看GetWindowText, GetDlgItemText


结果一运行

0:001> g  
Breakpoint 0 hit  
eax=0015ee40 ebx=00168278 ecx=0000000a  edx=00730001 esi=7c9300a4 edi=00000014  
eip=77d2a5cd esp=0012f664 ebp=0012f74c  iopl=0     nv up ei pl nz na pe nc  
cs=001b   ss=0023 ds=0023 es=0023   fs=003b gs=0000       efl=00000206  
USER32!GetWindowTextW:  
77d2a5cd 6a0c      push  0Ch  
0:000> kb  
ChildEBP RetAddr Args to Child         
0012f660 771a8566 0002043a 0015ee40  0000000a USER32!GetWindowTextW  
0012f74c 771a88c5 00000000 ea011aa2  00000001 COMCTL32!Button_DrawThemed+0x262  
0012f7c4 771a8e09 00000001 ea011aa2 00000001  COMCTL32!Button_DrawPush+0x44  
0012f840 771a9130 00000001 ea011aa2  0012f938 COMCTL32!Button_Paint+0x2e6  
0012f8d0 77d18734 0002043a 0000000f  00000000 COMCTL32!Button_WndProc+0x271  
0012f8fc 77d18816 771a8ebf 0002043a  0000000f USER32!InternalCallWinProc+0x28  
0012f964 77d2a013 001592a0 771a8ebf  0002043a USER32!UserCallWinProcCheckWow+0x150  
0012f994 77d2a039 771a8ebf 0002043a  0000000f USER32!CallWindowProcAorW+0x98  
0012f9b4 77191b72 771a8ebf 0002043a  0000000f USER32!CallWindowProcW+0x1b  
0012f9d0 77191ec5 0002043a 0000000f  00000000 COMCTL32!CallOriginalWndProc+0x1a  
0012fa2c 77192087 00168468 0002043a  0000000f COMCTL32!CallNextSubclassProc+0x3c  
0012fa50 7718866f 0002043a 0000000f  00000000 COMCTL32!DefSubclassProc+0x46  
0012fa6c 77191ec5 0002043a 0000000f 00000000  COMCTL32!Prsht_ButtonSubclassProc+0x69  
0012fac8 771920ea 00168468 0002043a  0000000f COMCTL32!CallNextSubclassProc+0x3c  
0012fb1c 77d18734 0002043a 0000000f  00000000 COMCTL32!MasterSubclassProc+0x54  
0012fb48 77d18816 77192096 0002043a  0000000f USER32!InternalCallWinProc+0x28  
0012fbb0 77d28ea0 001592a0 77192096  0002043a USER32!UserCallWinProcCheckWow+0x150  
0012fc04 77d28eec 00744248 0000000f  00000000 USER32!DispatchClientMessage+0xa3  
0012fc2c 7c92e453 0012fc3c 00000018  00744248 USER32!__fnDWORD+0x24  
0012fc50 77d194d2 77d28f10 001596a0  001596a0 ntdll!KiUserCallbackDispatcher+0x13  

界面根本就没办法显示,老是断在断点。这是因为windows子系统会不断刷新界面,对文本框也是不断调用GetWindowTextW

所以,只能在CWnd::GetWindowTextW, CWnd::GetDlgItemTextW打断点


操作如下图


然后点击下一步,得到如下堆栈:


看一下20007cd9附近的代码


非常疑惑,那些mfc100u_296, mfc100u_4805,mfc100u_7006是哪些函数?可以用下面方法来确认:


其中20007CB3,20007CCB,20007CD3分别调用了mfc100u_296, mfc100u_4805,mfc100u_7006

那么20007cd9附近的代码如下:


由类CWnd的成员函数原型

CWnd* GetDlgItem(  int nID ) const;     
void GetWindowText(  CString& rString ) const;

可从

.text:20007CC0         lea   ecx, [ebp+var_10]  
.text:20007CC3         push  ecx  

知,ebp-10h存放着的内容应该是”hello”.验证一下


也就是说,这里就是获取注册码的关键函数。说不定在这个函数会调用校验注册表的函数。

看一下20007cd9所在的函数20007C50

.text:20007C50 sub_20007C50  proc near        ; DATA XREF: .rdata:20020CACo  
.text:20007C50  
.text:20007C50 var_18     = dword ptr -18h  
.text:20007C50 var_14     = dword ptr -14h  
.text:20007C50 var_10     = byte ptr -10h  
.text:20007C50 var_C      = dword ptr -0Ch  
.text:20007C50 var_4      = dword ptr -4  
.text:20007C50  
.text:20007C50         push  ebp  
.text:20007C51         mov   ebp, esp  
.text:20007C53         push  0FFFFFFFFh  
.text:20007C55         push  offset loc_2001E1A1  
.text:20007C5A         mov   eax, large fs:0  
.text:20007C60         push  eax  
.text:20007C61         sub   esp, 0Ch  
.text:20007C64         push  esi  
.text:20007C65         push  edi  
.text:20007C66         mov    eax, dword_20038018  
.text:20007C6B         xor   eax, ebp  
.text:20007C6D         push  eax  
.text:20007C6E         lea   eax, [ebp+var_C]  
.text:20007C71         mov   large fs:0, eax  
.text:20007C77         mov   edi, ecx  
.text:20007C79         mov   eax, [edi+20h]  
.text:20007C7C         push  eax       ; hWnd  
.text:20007C7D         call  ds:GetParent  
.text:20007C83         push  eax  
.text:20007C84         call  ds:mfc100u_4360 ; CWnd::FromHandle  
.text:20007C8A         push  0  
.text:20007C8C         push  offset off_20038208  
.text:20007C91         push  offset off_2003805C  
.text:20007C96         push  0  
.text:20007C98         push  eax  
.text:20007C99         call  __RTDynamicCast  
.text:20007C9E         lea   esi, [eax+0CCh]  
.text:20007CA4         add   esp, 14h  
.text:20007CA7         xor   dl, dl  
.text:20007CA9         mov   ecx, esi  
.text:20007CAB         call  sub_20004180  
.text:20007CB0         lea   ecx, [ebp+var_10]  
.text:20007CB3         call  ds:mfc100u_296 ; ATL::CStringT::CStringT  
.text:20007CB9         mov    [ebp+var_4], 0  
.text:20007CC0         lea   ecx, [ebp+var_10]  
.text:20007CC3         push  ecx  
.text:20007CC4         push  7D3h  
.text:20007CC9         mov   ecx, edi  
.text:20007CCB         call  ds:mfc100u_4805 ; CWnd::GetDlgItem  
.text:20007CD1         mov   ecx, eax  
.text:20007CD3         call  ds:mfc100u_7006 ; CWnd::GetWindowText  
.text:20007CD9         push  0  
.text:20007CDB         lea   edx, [ebp+var_10]  
.text:20007CDE         push  edx  
.text:20007CDF         lea   ecx, [ebp+var_14]  
.text:20007CE2         call    ds:[email protected]@[email protected]?$CStringT@_WV?$StrTraitMFC_DLL@_WV?$ChTraitsCRT@[email protected]@@@@@[email protected]@[email protected]@@@Z  ;  VString::VString(ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>  const &,Str::SensitiveState)  
.text:20007CE8         mov   byte ptr [ebp+var_4], 1  
.text:20007CEC         mov   eax, [eax]  
.text:20007CEE         mov   ecx, esi  
.text:20007CF0         call  sub_200045D0
.text:20007CF5         mov   [ebp+var_18], eax  
.text:20007CF8         mov   byte ptr [ebp+var_4], 0  
.text:20007CFC         mov   esi, [ebp+var_14]  
.text:20007CFF         add   esi, 0FFFFFFECh  
.text:20007D02         lea   eax, [esi+10h]  
.text:20007D05         push  eax       ; lpAddend  
.text:20007D06         call  ds:InterlockedDecrement  
.text:20007D0C         test  eax, eax  
.text:20007D0E         jg   short loc_20007D31  
.text:20007D10         cmp   dword ptr [esi+0Ch], 1  
.text:20007D14         jnz   short loc_20007D27  
.text:20007D16         mov   ecx, [esi]  
.text:20007D18         add   ecx, 14h  
.text:20007D1B         mov   eax, esi  
.text:20007D1D         jz   short loc_20007D27  
.text:20007D1F         nop  
.text:20007D20  
.text:20007D20 loc_20007D20:              ; CODE XREF: sub_20007C50+D5j  
.text:20007D20         mov   byte ptr [eax], 0  
.text:20007D23         inc   eax  
.text:20007D24         dec   ecx  
.text:20007D25         jnz   short loc_20007D20  
.text:20007D27  
.text:20007D27 loc_20007D27:              ; CODE XREF:  sub_20007C50+C4j  
.text:20007D27                     ;  sub_20007C50+CDj  
.text:20007D27         push  esi       ; Memory  
.text:20007D28         call  ds:free  
.text:20007D2E         add   esp, 4  
.text:20007D31  
.text:20007D31 loc_20007D31:              ; CODE XREF:  sub_20007C50+BEj  
.text:20007D31         mov   esi, [ebp+var_18]  
.text:20007D34         test  esi, esi  
.text:20007D36         jns   short loc_20007D42 ;  CMFCVisualManager::GetDockingPaneCaptionExtraHeight  .text:20007D38         mov   ecx, edi  
.text:20007D3A         call  ds:__imp_mfc100u_10936  
.text:20007D40         mov    esi, eax  
.text:20007D42  
.text:20007D42 loc_20007D42:              ; CODE XREF:  sub_20007C50+E6j  
.text:20007D42         mov   [ebp+var_4], 0FFFFFFFFh  
.text:20007D49         lea   ecx, [ebp+var_10]  
.text:20007D4C         call  ds:mfc100u_902 ; ATL::CStringT::~CStringT  
.text:20007D52         mov   eax, esi  
.text:20007D54         mov   ecx, [ebp+var_C]  
.text:20007D57         mov   large fs:0, ecx  
.text:20007D5E         pop    ecx  
.text:20007D5F         pop   edi  
.text:20007D60         pop   esi  
.text:20007D61         mov   esp, ebp  
.text:20007D63         pop   ebp  
.text:20007D64         retn  
.text:20007D64 sub_20007C50  endp  

可以看到,除了20007CF0调用了sub_200045D0,其它地方调用的函数从名字来看,都不太可能是校验注册码。

现在看一下sub_200045D0

.text:200045D0 sub_200045D0  proc near        ; CODE XREF: sub_20007C50+A0p  
.text:200045D0         push  edi  
.text:200045D1         mov   edi, ecx  
.text:200045D3         call  sub_20003EC0  
.text:200045D8         test  eax, eax  
.text:200045DA         jnz   short loc_200045E6  
.text:200045DC         mov   eax, [edi]
.text:200045DE         mov   edx, [eax+18h]
.text:200045E1         mov   ecx, edi  
.text:200045E3         pop   edi  
.text:200045E4         jmp   edx
.text:200045E6 ;  ---------------------------------------------------------------------------  .text:200045E6  
.text:200045E6 loc_200045E6:              ; CODE XREF:  sub_200045D0+Aj  
.text:200045E6         cmp   byte ptr [edi+29h], 0  
.text:200045EA         jz   short loc_200045F6  
.text:200045EC         mov   eax, [edi]
.text:200045EE         mov   edx, [eax+28h]
.text:200045F1         mov   ecx, edi  
.text:200045F3         pop   edi  
.text:200045F4         jmp   edx
.text:200045F6 ;  ---------------------------------------------------------------------------  .text:200045F6  
.text:200045F6 loc_200045F6:              ; CODE XREF:  sub_200045D0+1Aj  
.text:200045F6         cmp   eax, 1  
.text:200045F9         jz   short loc_20004605  
.text:200045FB         mov   eax, [edi]
.text:200045FD         mov   edx, [eax+4]
.text:20004600         mov   ecx, edi  
.text:20004602         pop   edi  
.text:20004603         jmp   edx
.text:20004605 ;  ---------------------------------------------------------------------------  .text:20004605  
.text:20004605 loc_20004605:              ; CODE XREF:  sub_200045D0+29j  
.text:20004605         or   eax, 0FFFFFFFFh  
.text:20004608         pop   edi  
.text:20004609         retn  
.text:20004609 sub_200045D0  endp  

这个函数有三处”jmp edx”,非常奇怪。在200045DA打断点,通过windbg来确认那几处”jmp edx”是跳转什么地方.


可以得到三个地址20006e20, 20006e70, 20006eb0

看一下这三处地方的代码

.text:20006E20 sub_20006E20  proc near        ; DATA XREF: .rdata:20020458o  
.text:20006E20         mov   eax, 7EBh  
.text:20006E25         retn  
.text:20006E25 sub_20006E20  endp     
.text:20006E70 sub_20006E70  proc near        ; DATA XREF: .rdata:2002046Co  
.text:20006E70         mov   eax, 7DAh 
.text:20006E75         retn  
.text:20006E75 sub_20006E70  endp     
.text:20006EB0 sub_20006EB0  proc near        ; DATA XREF: .rdata:2002047Co  
.text:20006EB0         mov   eax, 7E9h  
.text:20006EB5         retn  
.text:20006EB5 sub_20006EB0  endp  

再加上

.text:20004605 loc_20004605:              ; CODE XREF:  sub_200045D0+29j  
.text:20004605         or   eax, 0FFFFFFFFh  
.text:20004608         pop   edi  
.text:20004609         retn  

可知sub_200045D0有四个返回值:7EB, 7DA, 7E9, -1

看一下不同的返回值会对程序有什么影响。在20007CF5(为调用sub_200045D0的下一条指令)打断点.

当返回值为7EB



当返回值为7DA时,



当返回值为7E9时,



当返回值为-1时,



可知,上面四个返回值中,7DA表明是注册码有效。那么研究一下sub_200045D0在什么情况下返回7DA

由上面的分析,7DA是从sub_200045D0里下面分支

  .text:200045DC         mov   eax, [edi]
  .text:200045DE         mov   edx, [eax+18h]     

得来的,而这个分支从这段代码来看

.text:200045D0         push  edi  
.text:200045D1         mov   edi, ecx  
.text:200045D3         call  sub_20003EC0  
.text:200045D8         test  eax, eax  
.text:200045DA         jnz   short loc_200045E6  
.text:200045DC         mov   eax, [edi]
.text:200045DE         mov   edx, [eax+18h]
.text:200045E1         mov   ecx, edi  
.text:200045E3         pop   edi  
.text:200045E4         jmp   edx  

是当sub_20003EC0的返回值为0时,sub_200045D0才会返回7DA这个返回值。

.text:20007CDB         lea   edx, [ebp+var_10]  
.text:20007CDE         push  edx  
.text:20007CDF         lea   ecx, [ebp+var_14]  
.text:20007CE2         call    ds:[email protected]@[email protected]?$CStringT@_WV?$StrTraitMFC_DLL@_WV?$ChTraitsCRT@[email protected]@@@@@[email protected]@[email protected]@@@Z  ; VString::VString(ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>  const &,Str::SensitiveState)  
.text:20007CE8         mov   byte ptr [ebp+var_4], 1  
.text:20007CEC         mov   eax, [eax]  
.text:20007CEE         mov   ecx, esi  
.text:20007CF0         call  sub_200045D0  

可知,当sub_20007C50调用sub_200045D0之前,把VString构造函数的返回值(即this指针)所指向的内容通过eax传到sub_200045D0,而VString构造函数第一个参数则是ebp-10这个地址,按照上面分析是输入的注册码”hello”

看一下VString返回值的内容是怎样?


可知,VString返回值指向地址存放着ASCII编码的注册码“hello”

   根据返回值7DA可以得到license的字符串格式是

Name:[hello]
Company:[world]
Serial Number:[123456]
License Key:[7890abcdef]
Issue Date:[2020-12-31]
Features:[All]

但最后还是放弃了。虽然这个程序没加壳,也没做什么保护,个人对windows和MFC那一套不熟悉,且这个licenseHelper用了近500个函数来做检验。

花近2个月才筛选出13个关键函数。

暗号:53f4e


文章来源: http://mp.weixin.qq.com/s?__biz=MzU4NjY0NTExNA==&mid=2247488501&idx=1&sn=c2e5b225786932b037fbb0e0d934b720&chksm=fdf978e0ca8ef1f6d366abf8ff525da2191f385e7fbc8411a2a055de7baa18f387abbb163867#rd
如有侵权请联系:admin#unsafe.sh