首页
社区
课程
招聘
[原创]Visual Assist 10.8.2029.0破解分析
发表于: 2015-1-4 23:59 32587

[原创]Visual Assist 10.8.2029.0破解分析

2015-1-4 23:59
32587
Visual Assist 10.8.2029.0破解分析
  围观看雪已经很久了,只是自己太菜了,一直不敢迈出第一步,前些天找到个机会,于是就有现在这篇文章,初次发帖,难免有错误,请大家批评指正!

重装电脑,装了VS2010,相信大家都知道Visual Assist这款插件,是VS的必备插件!在网上找到了10.8.2029.0版本的,算是比较新的版本了,老是找不到对应的破解补丁(后来在国外网站上找到了)……国内的大神都不舍得分享,小菜我只能自己动手了!

先在“Enter Key”对话框中随意输入一段字符,然后弹出如下对话框:
       

接着打开任务管理器,打算找到VA的进程,然后附加到OD的,但是任务管理器里没有找到VA的独立进程,只有VS的进程:
        
那么这个破解思路就断在这里了,出师不利……

接着找到对应的破解补丁,如下图:
         

在打上这个patch之后,VA就算破解完成了,而我们也可以观察到,打上了这个补丁之后,“Enter Key”对话框里仍然留白,并且在VA目录--  “C:\Users\Binky\AppData\Local\Microsoft\VisualStudio\10.0\Extensions\Whole Tomato Software\Visual Assist\10.8.2029.0”里多出一个文件:
        
因为在用这个补丁之前,我之前用过其他版本的补丁,以前用的补丁都是要送入到VA的安装目录然后再点击安装才能成功,否则提示无法找到VA的安装目录,此补丁也有”search file manually”,由此可以推断,破解是通过修改并替换掉VA_X.dll达到的!

先来脱壳,先前说了,ASPack 2.12 -> Alexey Solodovnikov不足为惧,脱壳很简单,用esp定律就ok了:
              

脱壳之后,发现代码还算容易阅读(没有什么垃圾代码和乱跳的填充),但是看到”About”按钮后有一点疑惑:
       
 

后来去找了工具,发现确实没有穿山甲的保护:
        

先来看看程序起始的地方:
0047048C >  55                 push ebp
0047048D    8BEC               mov ebp,esp
0047048F    83C4 F0            add esp,-10
00470492    B8 D4024700        mov eax,dumped_.004702D4
00470497    E8 A861F9FF        call dumped_.00406644
0047049C    A1 14F74700        mov eax,dword ptr ds:[47F714]
004704A1    8B00               mov eax,dword ptr ds:[eax]
004704A3    E8 8C73FEFF        call dumped_.00457834
004704A8    A1 14F74700        mov eax,dword ptr ds:[47F714]
004704AD    8B00               mov eax,dword ptr ds:[eax]
004704AF    BA EC044700        mov edx,dumped_.004704EC             ; ASCII "Visual Assist X - Patch by BRD"
004704B4    E8 7B6FFEFF        call dumped_.00457434
004704B9    8B0D 04F84700      mov ecx,dword ptr ds:[47F804]        ; dumped_.00492DEC
004704BF    A1 14F74700        mov eax,dword ptr ds:[47F714]
004704C4    8B00               mov eax,dword ptr ds:[eax]
004704C6    8B15 10EA4600      mov edx,dword ptr ds:[46EA10]        ; dumped_.0046EA5C
004704CC    E8 7B73FEFF        call dumped_.0045784C                ; CreateForm 
004704D1    A1 14F74700        mov eax,dword ptr ds:[47F714]
004704D6    8B00               mov eax,dword ptr ds:[eax]
004704D8    E8 EF73FEFF        call dumped_.004578CC                ; Run
004704DD    E8 9E41F9FF        call dumped_.00404680                ; Halt0


在004704CC处有个CreateForm,给后面的调试带来不小麻烦,没办法,屏幕小被遮住了!在004704D8处F7至004578CC

在ida中跟进,来感受一下,这个004578CC有多少个”Xrefs  from”:
       
嗯,有点复杂,但是这是个delphi程序,通过找到按钮事件可以节省我们很多时间!

用DeDe载入dumped_,转存后点击”过程—事件”,如下图:
       
btnPatchClick的rva为0046f334,直接在ida中”G”,跟到0046f334,这里就是关键的按钮事件的起始地址了!
这里先说说这个0046F334     _TForm1_btnPatchClick的基本功能,基本上就是定位安装了va的当前的vs版本,然后为其打上补丁,我安装的vs2010,所以我待会儿走流程分析的时候我就只分析vs2010这个分支,其他的分支都大同小异,他的功能就是patch里所描述的那样:
** Locating VS 6.0-2008 installation **
--------------------------------------------------------
VS 6.0-2008 not found...
Done...


** Locating VS 2010 installation **
--------------------------------------------------------
C:\Users\Binky\AppData\Local\Microsoft\VisualStudio\10.0\Extensions\Whole Tomato Software\Visual Assist\10.8.2029.0\VA_X.dll
ERROR: CRC missmatch. Wrong version?
Done...


** Locating VS 2012 installation **
--------------------------------------------------------
VS 2012 not found...
Done...


** Locating VS 2013 installation **
--------------------------------------------------------
VS 2013 not found...
Done...


我这里已经打过补丁了,所以会提示”ERROR: CRC missmatch. Wrong version?”顺带也附上sub_0046F334的概览图:
      

在调试的过程中无法得到即时回馈:
     

下面来调试dumped_文件,在0046F334  F2下断,shift+F9后点击Patch按钮,就停下来了,前面是vc++6.0—vs2008版本的补丁段,我这里直接F4到0046f4ff,这里是给VS2010打补丁的段落:
0046F4FF    8B45 FC         mov eax,dword ptr ss:[ebp-4]     ; VS2010 处
0046F502    8B80 2C030000   mov eax,dword ptr ds:[eax+32C]
0046F508    8B80 20020000   mov eax,dword ptr ds:[eax+220]
0046F50E    33D2            xor edx,edx                      ; 清零
0046F510    8B08            mov ecx,dword ptr ds:[eax]
0046F512    FF51 38         call dword ptr ds:[ecx+38]
0046F515    8B45 FC         mov eax,dword ptr ss:[ebp-4]
0046F518    8B80 2C030000   mov eax,dword ptr ds:[eax+32C]
0046F51E    8B80 20020000   mov eax,dword ptr ds:[eax+220]
0046F524    33D2            xor edx,edx
0046F526    8B08            mov ecx,dword ptr ds:[eax]
0046F528    FF51 38         call dword ptr ds:[ecx+38]
0046F52B    8B45 FC         mov eax,dword ptr ss:[ebp-4]
0046F52E    8B80 2C030000   mov eax,dword ptr ds:[eax+32C]
0046F534    8B80 20020000   mov eax,dword ptr ds:[eax+220]
0046F53A    BA 74FB4600     mov edx,dumped_.0046FB74         ; 定位"** Locating VS 2010 installation **"
0046F53F    8B08            mov ecx,dword ptr ds:[eax]
0046F541    FF51 38         call dword ptr ds:[ecx+38]
0046F544    8B45 FC         mov eax,dword ptr ss:[ebp-4]
0046F547    8B80 2C030000   mov eax,dword ptr ds:[eax+32C]
0046F54D    8B80 20020000   mov eax,dword ptr ds:[eax+220]
0046F553    BA A4FA4600     mov edx,dumped_.0046FAA4         ; 华丽的分割线
0046F558    8B08            mov ecx,dword ptr ds:[eax]
0046F55A    FF51 38         call dword ptr ds:[ecx+38]
0046F55D    B2 01           mov dl,1
0046F55F    A1 88E44600     mov eax,dword ptr ds:[46E488]
0046F564    E8 1FF0FFFF     call dumped_.0046E588            ; Registry::TRegistry::TRegistry(void)
0046F569    8945 EC         mov dword ptr ss:[ebp-14],eax
0046F56C    BA 01000080     mov edx,80000001
0046F571    8B45 EC         mov eax,dword ptr ss:[ebp-14]
0046F574    E8 AFF0FFFF     call dumped_.0046E628            ; Registry::TRegistry::SetRootKey(uint)
0046F579    33C9            xor ecx,ecx
0046F57B    BA A0FB4600     mov edx,dumped_.0046FBA0         ; 注册表路径--"SOFTWARE\Microsoft\VisualStudio\10.0\ExtensionManager\EnabledExtensions"
0046F580    8B45 EC         mov eax,dword ptr ss:[ebp-14]
0046F583    E8 04F1FFFF     call dumped_.0046E68C            ; Registry::TRegistry::OpenKey(System::AnsiString,bool)
0046F588    84C0            test al,al
0046F58A    0F84 8A000000   je dumped_.0046F61A
0046F590    8D4D E4         lea ecx,dword ptr ss:[ebp-1C]
0046F593    BA F0FB4600     mov edx,dumped_.0046FBF0         ; 获取注册表键值
0046F598    8B45 EC         mov eax,dword ptr ss:[ebp-14]
0046F59B    E8 B4F2FFFF     call dumped_.0046E854            ; Registry::TRegistry::ReadString(System::AnsiString)
0046F5A0    837D E4 00      cmp dword ptr ss:[ebp-1C],0      ; purge
0046F5A4    74 74           je short dumped_.0046F61A
0046F5A6    BA F0FB4600     mov edx,dumped_.0046FBF0         ; "44630d46-96b5-488c-8df926e21db8c1a3,10.8.2029.0"
0046F5AB    8D4D F8         lea ecx,dword ptr ss:[ebp-8]
0046F5AE    8B45 EC         mov eax,dword ptr ss:[ebp-14]    ; C:\Users\Binky\AppData\Local\Microsoft\VisualStudio\10.0\Extensions\Whole Tomato Software\Visual Assist\10.8.2029.0\
0046F5B1    E8 9EF2FFFF     call dumped_.0046E854            ; Registry::TRegistry::ReadString(System::AnsiString)
0046F5B6    8D45 F8         lea eax,dword ptr ss:[ebp-8]
0046F5B9    BA 28FC4600     mov edx,dumped_.0046FC28         ; "VA_X.dll"
0046F5BE    E8 7D54F9FF     call dumped_.00404A40            ; System::__linkproc__ LStrCat(void)
0046F5C3    8B45 FC         mov eax,dword ptr ss:[ebp-4]
0046F5C6    8B80 2C030000   mov eax,dword ptr ds:[eax+32C]
0046F5CC    8B80 20020000   mov eax,dword ptr ds:[eax+220]
0046F5D2    8B55 F8         mov edx,dword ptr ss:[ebp-8]
0046F5D5    8B08            mov ecx,dword ptr ds:[eax]
0046F5D7    FF51 38         call dword ptr ds:[ecx+38]
0046F5DA    8D4D F0         lea ecx,dword ptr ss:[ebp-10]
0046F5DD    8B55 F4         mov edx,dword ptr ss:[ebp-C]     ; "BINKY-PC"
0046F5E0    8B45 F8         mov eax,dword ptr ss:[ebp-8]     ; "C:\Users\Binky\AppData\Local\Microsoft\VisualStudio\10.0\Extensions\Whole Tomato Software\Visual Assist\10.8.2029.0\VA_X.dll"
0046F5E3    E8 64F9FFFF     call dumped_.0046EF4C            ; 关键call,各版本VS都是用此函数来修改VA_X


获取注册表键值:
     
之前看到过44630d46-96b5-488c-8df926e21db8c1a3这个字符串,以为是注册码……
我对delphi不是很了解,就是百度了也找不到相关API函数的详细解释,所以在阅读代码的时候遇到有关delphi的api函数就见名知意吧,在0046F5E3就是关键call了,F7进去:
0046EF4C    55              push ebp
0046EF4D    8BEC            mov ebp,esp
0046EF4F    81C4 9CFEFFFF   add esp,-164
0046EF55    53              push ebx
0046EF56    56              push esi
0046EF57    57              push edi
0046EF58    33DB            xor ebx,ebx
0046EF5A    899D 9CFEFFFF   mov dword ptr ss:[ebp-164],ebx
0046EF60    895D F0         mov dword ptr ss:[ebp-10],ebx
0046EF63    894D F4         mov dword ptr ss:[ebp-C],ecx
0046EF66    8955 F8         mov dword ptr ss:[ebp-8],edx     ; BINKY-PC
0046EF69    8945 FC         mov dword ptr ss:[ebp-4],eax     ; "C:\Users\Binky\AppData\Local\Microsoft\VisualStudio\10.0\Extensions\Whole Tomato Software\Visual Assist\10.8.2029.0\VA_X.dll"
0046EF6C    8B45 FC         mov eax,dword ptr ss:[ebp-4]
0046EF6F    E8 B45CF9FF     call dumped_.00404C28            ; 没找到相关说明System::__linkproc__ LStrAddRef(void *)
0046EF74    8B45 F8         mov eax,dword ptr ss:[ebp-8]
0046EF77    E8 AC5CF9FF     call dumped_.00404C28            ; System::__linkproc__ LStrAddRef(void *)
0046EF7C    33C0            xor eax,eax                      ; 用完清零
0046EF7E    55              push ebp
0046EF7F    68 9DF14600     push dumped_.0046F19D
0046EF84    64:FF30         push dword ptr fs:[eax]
0046EF87    64:8920         mov dword ptr fs:[eax],esp
0046EF8A    33D2            xor edx,edx
0046EF8C    55              push ebp
0046EF8D    68 35F14600     push dumped_.0046F135
0046EF92    64:FF32         push dword ptr fs:[edx]
0046EF95    64:8922         mov dword ptr fs:[edx],esp
0046EF98    8D55 EC         lea edx,dword ptr ss:[ebp-14]
0046EF9B    8B45 FC         mov eax,dword ptr ss:[ebp-4]
0046EF9E    E8 39FEFFFF     call dumped_.0046EDDC            ; 
0046EFA3    A1 14F74700     mov eax,dword ptr ds:[47F714]
0046EFA8    8B00            mov eax,dword ptr ds:[eax]
0046EFAA    E8 7987FEFF     call dumped_.00457728            ; Forms::TApplication::HandleMessage(void)
0046EFAF    8B45 EC         mov eax,dword ptr ss:[ebp-14]
0046EFB2    33D2            xor edx,edx
0046EFB4    52              push edx
0046EFB5    50              push eax
0046EFB6    8D95 9CFEFFFF   lea edx,dword ptr ss:[ebp-164]
0046EFBC    B8 06000000     mov eax,6
0046EFC1    E8 8A9AF9FF     call dumped_.00408A50            ; Sysutils::IntToHex(__int64,int)
0046EFC6    8B85 9CFEFFFF   mov eax,dword ptr ss:[ebp-164]   ; "CA398E13" ?
0046EFCC    BA B4F14600     mov edx,dumped_.0046F1B4         ; "FE4274C7" ?
0046EFD1    E8 AE5BF9FF     call dumped_.00404B84            ; System::__linkproc__ LStrCmp(void)
0046EFD6    0F85 2D010000   jnz dumped_.0046F109
0046EFDC    8D45 F0         lea eax,dword ptr ss:[ebp-10]
0046EFDF    B9 C8F14600     mov ecx,dumped_.0046F1C8         ; ASCII ".bak"
0046EFE4    8B55 FC         mov edx,dword ptr ss:[ebp-4]
0046EFE7    E8 985AF9FF     call dumped_.00404A84            ; System::__linkproc__ LStrCat3(void)
0046EFEC    8B45 F0         mov eax,dword ptr ss:[ebp-10]
0046EFEF    E8 389EF9FF     call dumped_.00408E2C            ; 判断文件是否存在 Sysutils::FileExists(System::AnsiString)
0046EFF4    84C0            test al,al
0046EFF6    75 19           jnz short dumped_.0046F011       ; 为了看流程 zf=0
0046EFF8    6A 00           push 0                           ; bFailIfExists
0046EFFA    8B45 F0         mov eax,dword ptr ss:[ebp-10]
0046EFFD    E8 365CF9FF     call dumped_.00404C38            ; System::__linkproc__ LStrToPChar(System::AnsiString)
0046F002    50              push eax                         ; lpNewFileName --"C:\Users\Binky\AppData\Local\Microsoft\VisualStudio\10.0\Extensions\Whole Tomato Software\Visual Assist\10.8.2029.0\VA_X.dll.bak"
0046F003    8B45 FC         mov eax,dword ptr ss:[ebp-4]     ; eax存着".../VA_X.dll.bak",ss:[0012F5E8]中存着".../VA_X.dll"
0046F006    E8 2D5CF9FF     call dumped_.00404C38
0046F00B    50              push eax                         ; lpExistingFileName--".../VA_X.dll"
0046F00C    E8 3378F9FF     call <jmp.&kernel32.CopyFileA>   ; CopyFileA把原来的VA_X.dll拷贝一份并改名VA_X.dll.bak
0046F011    8B55 FC         mov edx,dword ptr ss:[ebp-4]
0046F014    8D85 A0FEFFFF   lea eax,dword ptr ss:[ebp-160]
0046F01A    E8 713FF9FF     call dumped_.00402F90            ; System::__linkproc__ Assign(System::TTextRec &,System::AnsiString)
0046F01F    A1 94F74700     mov eax,dword ptr ds:[47F794]
0046F024    C600 01         mov byte ptr ds:[eax],1
0046F027    BA 01000000     mov edx,1
0046F02C    8D85 A0FEFFFF   lea eax,dword ptr ss:[ebp-160]
0046F032    E8 9D43F9FF     call dumped_.004033D4            ; System::__linkproc__ ResetFile(System::TFileRec &,int)
0046F037    E8 B83BF9FF     call dumped_.00402BF4            ; System::__linkproc__ _IOTest(void)
0046F03C    BA C7731400     mov edx,1473C7
0046F041    8D85 A0FEFFFF   lea eax,dword ptr ss:[ebp-160]
0046F047    E8 A443F9FF     call dumped_.004033F0            ; 这里是寻找写入地址,和写入的整数个字符的数量System::__linkproc__ Seek(System::TFileRec &,uint)
0046F04C    E8 A33BF9FF     call dumped_.00402BF4
0046F051    6A 00           push 0
0046F053    BA 242B4700     mov edx,dumped_.00472B24         ; "l\n"
0046F058    B9 07000000     mov ecx,7
0046F05D    8D85 A0FEFFFF   lea eax,dword ptr ss:[ebp-160]
0046F063    E8 A040F9FF     call dumped_.00403108            ; 这里开始写入VA_X.dll  System::__linkproc__ BlockWrite(System::TFileRec &,void *,int,int &)
0046F068    E8 873BF9FF     call dumped_.00402BF4
0046F06D    BA 00201E00     mov edx,1E2000
0046F072    8D85 A0FEFFFF   lea eax,dword ptr ss:[ebp-160]
0046F078    E8 7343F9FF     call dumped_.004033F0            ; System::__linkproc__ Seek(System::TFileRec &,uint)
0046F07D    E8 723BF9FF     call dumped_.00402BF4            ; System::__linkproc__ _IOTest(void)
0046F082    6A 00           push 0
0046F084    BA 2C2B4700     mov edx,dumped_.00472B2C
0046F089    B9 BA000000     mov ecx,0BA
0046F08E    8D85 A0FEFFFF   lea eax,dword ptr ss:[ebp-160]
0046F094    E8 6F40F9FF     call dumped_.00403108            ; System::__linkproc__ BlockWrite(System::TFileRec &,void *,int,int &)
0046F099    E8 563BF9FF     call dumped_.00402BF4            ; System::__linkproc__ _IOTest(void)
0046F09E    8D85 A0FEFFFF   lea eax,dword ptr ss:[ebp-160]
0046F0A4    E8 7F40F9FF     call dumped_.00403128            ; System::__linkproc__ Close(System::TTextRec &)
0046F0A9    E8 463BF9FF     call dumped_.00402BF4
0046F0AE    B2 01           mov dl,1
0046F0B0    A1 88E44600     mov eax,dword ptr ds:[46E488]
0046F0B5    E8 CEF4FFFF     call dumped_.0046E588            ; Registry::TRegistry::TRegistry(void)
0046F0BA    8BD8            mov ebx,eax
0046F0BC    BA 01000080     mov edx,80000001
0046F0C1    8BC3            mov eax,ebx
0046F0C3    E8 60F5FFFF     call dumped_.0046E628
0046F0C8    B1 01           mov cl,1
0046F0CA    BA D8F14600     mov edx,dumped_.0046F1D8         ; ASCII "SOFTWARE\Whole Tomato\Visual Assist X"
0046F0CF    8BC3            mov eax,ebx
0046F0D1    E8 B6F5FFFF     call dumped_.0046E68C            ; Registry::TRegistry::OpenKey(System::AnsiString,bool)
0046F0D6    84C0            test al,al
0046F0D8    74 20           je short dumped_.0046F0FA
0046F0DA    8B4D F8         mov ecx,dword ptr ss:[ebp-8]     ; "BINKY-PC"
0046F0DD    BA 08F24600     mov edx,dumped_.0046F208         ; ASCII "UserName"
0046F0E2    8BC3            mov eax,ebx                      ; "*@"
0046F0E4    E8 3FF7FFFF     call dumped_.0046E828            ; "BINKY-PC"和"UserName"匹配--Registry::TRegistry::WriteString(System::AnsiString,System::AnsiString)
0046F0E9    B9 1CF24600     mov ecx,dumped_.0046F21C         ; ASCII "You will never defeat the riddle of the Black Riders..."
0046F0EE    BA 5CF24600     mov edx,dumped_.0046F25C         ; ASCII "UserKey"
0046F0F3    8BC3            mov eax,ebx
0046F0F5    E8 2EF7FFFF     call dumped_.0046E828            ; Registry::TRegistry::WriteString(System::AnsiString,System::AnsiString)
0046F0FA    8B45 F4         mov eax,dword ptr ss:[ebp-C]
0046F0FD    BA 6CF24600     mov edx,dumped_.0046F26C         ; ASCII "SUCCESS: File patched successfully!"
0046F102    E8 C556F9FF     call dumped_.004047CC            ; System::__linkproc__ LStrAsg(void *,void *)
0046F107    EB 22           jmp short dumped_.0046F12B
0046F109    837D EC 00      cmp dword ptr ss:[ebp-14],0
0046F10D    75 0F           jnz short dumped_.0046F11E
0046F10F    8B45 F4         mov eax,dword ptr ss:[ebp-C]
0046F112    BA 98F24600     mov edx,dumped_.0046F298         ; ASCII "ERROR: File does not exist..."
0046F117    E8 B056F9FF     call dumped_.004047CC
0046F11C    EB 0D           jmp short dumped_.0046F12B
0046F11E    8B45 F4         mov eax,dword ptr ss:[ebp-C]
0046F121    BA C0F24600     mov edx,dumped_.0046F2C0         ; ASCII "ERROR: CRC missmatch. Wrong version?"
0046F126    E8 A156F9FF     call dumped_.004047CC
0046F12B    33C0            xor eax,eax
0046F12D    5A              pop edx
0046F12E    59              pop ecx
0046F12F    59              pop ecx
0046F130    64:8910         mov dword ptr fs:[eax],edx
0046F133    EB 3A           jmp short dumped_.0046F16F
0046F135  ^ E9 924EF9FF     jmp dumped_.00403FCC
0046F13A    0200            add al,byte ptr ds:[eax]
0046F13C    0000            add byte ptr ds:[eax],al
0046F13E    D878 40         fdivr dword ptr ds:[eax+40]
0046F141    004E F1         add byte ptr ds:[esi-F],cl
0046F144    46              inc esi
0046F145    0000            add byte ptr ds:[eax],al
0046F147    0000            add byte ptr ds:[eax],al
0046F149    005D F1         add byte ptr ss:[ebp-F],bl
0046F14C    46              inc esi
0046F14D    008B 45F4BAF0   add byte ptr ds:[ebx+F0BAF445],c>
0046F153    F2:             prefix repne:
0046F154    46              inc esi
0046F155    00E8            add al,ch
0046F157    71 56           jno short dumped_.0046F1AF
0046F159    F9              stc
0046F15A    FFEB            jmp far ebx                      ; 非法使用寄存器
0046F15C    0D 8B45F4BA     or eax,BAF4458B
0046F161    1C F3           sbb al,0F3
0046F163    46              inc esi
0046F164    00E8            add al,ch
0046F166    6256 F9         bound edx,qword ptr ds:[esi-7]
0046F169    FFE8            jmp far eax                      ; 非法使用寄存器
0046F16B    99              cdq
0046F16C    50              push eax
0046F16D    F9              stc
0046F16E    FF33            push dword ptr ds:[ebx]
0046F170    C05A 59 59      rcr byte ptr ds:[edx+59],59
0046F174    64:8910         mov dword ptr fs:[eax],edx
0046F177    68 A4F14600     push dumped_.0046F1A4
0046F17C    8D85 9CFEFFFF   lea eax,dword ptr ss:[ebp-164]
0046F182    E8 F155F9FF     call dumped_.00404778            ; System::__linkproc__ LStrClr(void *)
0046F187    8D45 F0         lea eax,dword ptr ss:[ebp-10]
0046F18A    E8 E955F9FF     call dumped_.00404778            ; System::__linkproc__ LStrClr(void *)
0046F18F    8D45 F8         lea eax,dword ptr ss:[ebp-8]
0046F192    BA 02000000     mov edx,2
0046F197    E8 0056F9FF     call dumped_.0040479C            ; System::__linkproc__ LStrArrayClr(void *,int)
0046F19C    C3              retn


在0046F047 有个seek函数、0046F063 BlockWrite,还有就是0046F078-seek和0046F094-BlockWrite,seek函数调用了Kernel32.SetFilePointer(),以设置当前的读写位置,然后在BlockWrite()就很显而易见,不猜都能知道他Hook了Kernel32.WriteFile()来改写VA_X.dll,因为很多感染型病毒都是这样来修改文件的,下面来看看0046F047-Seek():
004033F0    89C1            mov ecx,eax                    
004033F2    0FB740 04       movzx eax,word ptr ds:[eax+4]
004033F6    2D B1D70000     sub eax,0D7B1
004033FB    83F8 02         cmp eax,2
004033FE    77 19           ja short dumped_.00403419
00403400    6A 00           push 0                         ; dwMoveMethod
00403402    8B41 08         mov eax,dword ptr ds:[ecx+8]
00403405    F7E2            mul edx
00403407    6A 00           push 0                         ; lpDistanceToMoveHigh
00403409    50              push eax                       ; lDistanceToMove
0040340A    FF31            push dword ptr ds:[ecx]        ; hFile
0040340C    E8 2BDEFFFF     call <jmp.&kernel32.SetFilePoi>
00403411    40              inc eax                        ; 返回+1字节偏移量
00403412  ^ 0F84 0CF8FFFF   je dumped_.00402C24
00403418    C3              retn


他在调用了SetFilePointer()时各参数的值:
    

0046f063-BlockWrite():
00403108    55              push ebp
00403109    8BEC            mov ebp,esp
0040310B    53              push ebx
0040310C    8B5D 08         mov ebx,dword ptr ss:[ebp+8]
0040310F    53              push ebx
00403110    68 B2D70000     push 0D7B2
00403115    68 54304000     push <jmp.&kernel32.WriteFile>
0040311A    6A 65           push 65
0040311C    E8 3BFFFFFF     call dumped_.0040305C
00403121    5B              pop ebx
00403122    5D              pop ebp
00403123    C2 0400         retn 4

Hook kernel32.WriteFile后,此处堆栈上个参数的值:
       
接着看0046F078-Seek():
004033F0    89C1            mov ecx,eax
004033F2    0FB740 04       movzx eax,word ptr ds:[eax+4]
004033F6    2D B1D70000     sub eax,0D7B1
004033FB    83F8 02         cmp eax,2
004033FE    77 19           ja short dumped_.00403419
00403400    6A 00           push 0
00403402    8B41 08         mov eax,dword ptr ds:[ecx+8]
00403405    F7E2            mul edx
00403407    6A 00           push 0
00403409    50              push eax
0040340A    FF31            push dword ptr ds:[ecx]
0040340C    E8 2BDEFFFF     call <jmp.&kernel32.SetFilePoin>
00403411    40              inc eax 
00403412  ^ 0F84 0CF8FFFF   je dumped_.00402C24
00403418    C3              retn


调用SetFilePointer()时堆栈上变量的值:
      

0046F094-BlockWrite():
00403108    55              push ebp
00403109    8BEC            mov ebp,esp
0040310B    53              push ebx
0040310C    8B5D 08         mov ebx,dword ptr ss:[ebp+8]
0040310F    53              push ebx
00403110    68 B2D70000     push 0D7B2
00403115    68 54304000     push <jmp.&kernel32.WriteFile>
0040311A    6A 65           push 65
0040311C    E8 3BFFFFFF     call dumped_.0040305C
00403121    5B              pop ebx
00403122    5D              pop ebp
00403123    C2 0400         retn 4


Hook kernel32.WriteFile后,此处堆栈上个参数的值:
     

一路走过来还算顺利,但是我对delphi不熟悉,所以在写入VA_X.dll这个过程中分析起来很吃力,其实走到这里,含糊一点就可以收官了,因为流程走到下面所示代码,就算分析完成了,代码如下:
0046F047    E8 A443F9FF     call dumped_.004033F0            ; System::__linkproc__ Seek(System::TFileRec &,uint)
0046F04C    E8 A33BF9FF     call dumped_.00402BF4            ; IOTest(void)
0046F051    6A 00           push 0
0046F053    BA 242B4700     mov edx,dumped_.00472B24         ; "l\n"
0046F058    B9 07000000     mov ecx,7
0046F05D    8D85 A0FEFFFF   lea eax,dword ptr ss:[ebp-160]
0046F063    E8 A040F9FF     call dumped_.00403108            ; System::__linkproc__ BlockWrite(这里开始写入VA_X.dll System::TFileRec &,void *,int,int &)
0046F068    E8 873BF9FF     call dumped_.00402BF4            ; RuntimeError
0046F06D    BA 00201E00     mov edx,1E2000
0046F072    8D85 A0FEFFFF   lea eax,dword ptr ss:[ebp-160]
0046F078    E8 7343F9FF     call dumped_.004033F0            ; System::__linkproc__ Seek(System::TFileRec &,uint)
0046F07D    E8 723BF9FF     call dumped_.00402BF4            ; System::__linkproc__ _IOTest(void)
0046F082    6A 00           push 0
0046F084    BA 2C2B4700     mov edx,dumped_.00472B2C
0046F089    B9 BA000000     mov ecx,0BA
0046F08E    8D85 A0FEFFFF   lea eax,dword ptr ss:[ebp-160]
0046F094    E8 6F40F9FF     call dumped_.00403108            ; System::__linkproc__ BlockWrite(System::TFileRec &,void *,int,int &)
0046F099    E8 563BF9FF     call dumped_.00402BF4            ; System::__linkproc__ _IOTest(void)
0046F09E    8D85 A0FEFFFF   lea eax,dword ptr ss:[ebp-160]
0046F0A4    E8 7F40F9FF     call dumped_.00403128            ; System::__linkproc__ Close(System::TTextRec &)


就是经过了两个BlockWrite()后,再Close(),在VA安装目录下就马上完成了对VA_X.dll修改:
    
根本就不用管下面的流程:
0046F0DA    8B4D F8         mov ecx,dword ptr ss:[ebp-8]   ; "BINKY-PC"
0046F0DD    BA 08F24600     mov edx,dumped_.0046F208       ; ASCII "UserName"
0046F0E2    8BC3            mov eax,ebx                    ; "*@"
0046F0E4    E8 3FF7FFFF     call dumped_.0046E828          ; 这里写入注册表--Registry::TRegistry::WriteString(System::AnsiString,System::AnsiString)
0046F0E9    B9 1CF24600     mov ecx,dumped_.0046F21C       ; ASCII "You will never defeat the riddle of the Black Riders..."
0046F0EE    BA 5CF24600     mov edx,dumped_.0046F25C       ; ASCII "UserKey"
0046F0F3    8BC3            mov eax,ebx
0046F0F5    E8 2EF7FFFF     call dumped_.0046E828          ; Registry::TRegistry::WriteString(System::AnsiString,System::AnsiString)


我本来以为还要往注册表里写入所谓的"UserName"和"UserKey"呢,走完了,才发现,作者只是想开个玩笑--"You will never defeat the riddle of the Black Riders...",你永远无法解开黑暗骑士之谜,我了个……
说到这,那么问题就来了,因为小菜我想用MFC重写这个补丁,但是对delphi的BlockWrite(),只有如下了解:
delphi BlockWrite(System::TFileRec &,void *,int,int &)
BlockWrite(F2, Buf, NumRead, Numwritten)

procedure BlockWrite(var f: File; var Buf; Count: Integer [; var AmtTransferred: Integer]);

Description
F is an untyped file variable, Buf is any variable, Count is an expression of type Integer, and AmtTransferred is an optional variable of type Integer.
BlockWrite writes Count or fewer records to the file F from memory, starting at the first byte occupied by Buf. The actual number of complete records written (less than or equal to Count) is returned in AmtTransferred.
The entire block transferred occupies at most Count * RecSize bytes. RecSize is the record size specified when the file was opened (or 128 if the record size was unspecified).
If the entire block is transferred, AmtTransferred is equal to Count on return.
If AmtTransferred is less than Count, the disk became full before the transfer was complete. In this case, if the file's record size is greater than 1, AmtTransferred returns the number of complete records written.
BlockWrite advances the current file position by AmtTransferred records.
If AmtTransferred isn't specified, an I/O error occurs if the number written isn't equal to Count. If the $I+ compiler directive is in effect, errors raise an EInOutError exception.


大致意思是,BlockWrite从内存写入一定数量字节到文件F,从缓冲区第一个字节开始,真正写入字节的数量存储于第4个参数。
在汇编代码中,并没有找到他push这4个参数,缓冲数据在哪,写入位置在哪,写入的字节数是多少,都找不到,所以要用WriteFile()来改写此补丁的话,我在这里卡了好久!
好,问题在哪就回溯到哪,F7进入第1处BlockWrite():
      
在ida继续跟进,看看这个dumped_.0040305c有多少个”Xrefs  from”:
      
第1处BlockWrite()之后,启动VS就不会再弹出VA的注册框(VA呈灰色),但是在退出VS的时候会出现异常!
      
      
 
 
说明注册是分两步(两次BlockWrite())来完成的,第一步去除主窗口,第二步完成注册!
第一次,调用WriteFile()的函数在sub_0040305c,如下:
0040305C    55              push ebp                           ; 调用writefile成功
0040305D    8BEC            mov ebp,esp
0040305F    51              push ecx
00403060    53              push ebx
00403061    56              push esi
00403062    57              push edi
00403063    8BF1            mov esi,ecx
00403065    8BFA            mov edi,edx
00403067    8BD8            mov ebx,eax
00403069    8B45 10         mov eax,dword ptr ss:[ebp+10]
0040306C    0FB753 04       movzx edx,word ptr ds:[ebx+4]
00403070    23D0            and edx,eax
00403072    3BC2            cmp eax,edx
00403074    75 58           jnz short dumped_.004030CE
00403076    6A 00           push 0                             ; lpOverlapped=0,不是以FILE_FLAG_OVERLAPPED方式打开
00403078    8D45 FC         lea eax,dword ptr ss:[ebp-4]
0040307B    50              push eax                           ; lpNumberOfBytesWritten=0012F438
0040307C    8B43 08         mov eax,dword ptr ds:[ebx+8]
0040307F    F7EE            imul esi
00403081    50              push eax                           ; nNumberOfBytesToWrite=7
00403082    57              push edi                           ; lpBuffer=00472B24
00403083    8B03            mov eax,dword ptr ds:[ebx]
00403085    50              push eax                           ; hFile=0000025c
00403086    FF55 0C         call dword ptr ss:[ebp+C]          ; 00403054 (<jmp.&kernel32.WriteFile>)
00403089    85C0            test eax,eax                       ; eax=00000001 writefile调用成功
0040308B    75 11           jnz short dumped_.0040309E


而写入的缓冲数据保存于001473c7的7个byte:
 E9346C0A009090     

第二次调用WriteFile(),如下:
0040305C    55              push ebp                         ; 调用writefile成功
0040305D    8BEC            mov ebp,esp
0040305F    51              push ecx
00403060    53              push ebx
00403061    56              push esi
00403062    57              push edi
00403063    8BF1            mov esi,ecx
00403065    8BFA            mov edi,edx
00403067    8BD8            mov ebx,eax
00403069    8B45 10         mov eax,dword ptr ss:[ebp+10]
0040306C    0FB753 04       movzx edx,word ptr ds:[ebx+4]
00403070    23D0            and edx,eax
00403072    3BC2            cmp eax,edx
00403074    75 58           jnz short dumped_.004030CE
00403076    6A 00           push 0                           ; lpOverlapped=0,不是以FILE_FLAG_OVERLAPPED方式打开
00403078    8D45 FC         lea eax,dword ptr ss:[ebp-4]
0040307B    50              push eax                         ; lpNumberOfBytesWritten=0012F438
0040307C    8B43 08         mov eax,dword ptr ds:[ebx+8]
0040307F    F7EE            imul esi
00403081    50              push eax                         ; nNumberOfBytesToWrite=BA
00403082    57              push edi                         ; lpBuffer=00472B2C
00403083    8B03            mov eax,dword ptr ds:[ebx]
00403085    50              push eax                         ; hFile=0000025c
00403086    FF55 0C         call dword ptr ss:[ebp+C]        ; 00403054 (<jmp.&kernel32.WriteFile>)
00403089    85C0            test eax,eax                     ; eax=00000001 writefile调用成功
0040308B    75 11           jnz short dumped_.0040309E


而写入的缓冲数据在001E2000的186byte:
60 9C 8B 4C 24 24 81 39 4F 75 74 70 75 1A 81 79
04 75 74 44 65 75 11 81 79 08 62 75 67 53 75 08
C7 44 24 20 58 40 6D 1F 81 39 56 69 72 74 75 1A
81 79 04 75 61 6C 50 75 11 81 79 08 72 6F 74 65
75 08 C7 44 24 20 8B 40 6D 1F 9D 61 89 45 E4 83
7D E4 00 E9 74 93 F5 FF 8B 04 24 81 78 1E 33 51
14 33 75 23 C7 45 EC C0 BA 30 66 C7 45 E4 34 57
86 6C C7 45 E0 73 B8 88 F5 C7 45 DC CD 9D 2A E0
C7 45 D8 13 BB 96 E8 33 C0 40 C3 C6 44 24 0C 40
83 3D 00 10 D0 1E 00 74 1B C7 05 DF C2 D8 1E 33
C0 40 E9 C7 05 E3 C2 D8 1E 39 06 00 00 C6 05 31
6A E0 1E 32 FF 25 34 42 6E 1F

只要在winhex里找到001473c7和001E2000这两个地址,并替换成上述所给的数据,即可破解!

FB!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 3
支持
分享
最新回复 (46)
雪    币: 112
活跃值: (27)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
2
没想到这么冷清,之前已经看过下边“相似的主题”的文章了,都是直接放补丁,还好有一个前辈分析过VA_X.dll。他是直接分析了VA_X.dll,而我是绕道,通过补丁的分析来到达破解目的……

还有就是对论坛的功能还不是很熟悉,有些东西没法上传,这里一并给出:
http://pan.baidu.com/s/1mgyvuOg
破解的视频的视频也录制好了,放在百度云盘共享里

真心求个“优秀”,好让我能转正
2015-1-5 11:52
0
雪    币: 27
活跃值: (90)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
楼主写得很详细,谢谢楼主
2015-1-5 13:00
0
雪    币: 1810
活跃值: (1783)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
好文章,必须顶...
2015-1-5 13:20
0
雪    币: 111
活跃值: (35)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
分析得很好,学习了,更加好奇他添加的这些是什么
2015-1-5 14:28
0
雪    币: 112
活跃值: (27)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
6
,老大这些是opcode呀,比如说nop 就90,55对应着push ebp
609C8B4C242481394F757470751A817904757444657511817908627567537508C744242058406D1F813956697274751A81790475616C507511817908726F74657508C74424208B406D1F9D618945E4837DE400E97493F5FF8B042481781E335114337523C745ECC0BA3066C745E43457866CC745E073B888F5C745DCCD9D2AE0C745D813BB96E833C040C3C644240C40833D0010D01E00741BC705DFC2D81E33C040E9C705E3C2D81E39060000C605316AE01E32FF2534426E1F

对应着如下汇编指令:
L_00000000:   pusha 
L_00000001:   pushf 
L_00000002:   mov ecx, [esp+0x24]
L_00000006:   cmp dword [ecx], 0x7074754f
L_0000000C:   jnz 0x28
L_0000000E:   cmp dword [ecx+0x4], 0x65447475
L_00000015:   jnz 0x28
L_00000017:   cmp dword [ecx+0x8], 0x53677562
L_0000001E:   jnz 0x28
L_00000020:   mov dword [esp+0x20], 0x1f6d4058
L_00000028:   cmp dword [ecx], 0x74726956
L_0000002E:   jnz 0x4a
L_00000030:   cmp dword [ecx+0x4], 0x506c6175
L_00000037:   jnz 0x4a
L_00000039:   cmp dword [ecx+0x8], 0x65746f72
L_00000040:   jnz 0x4a
L_00000042:   mov dword [esp+0x20], 0x1f6d408b
L_0000004A:   popf 
L_0000004B:   popa 
L_0000004C:   mov [ebp-0x1c], eax
L_0000004F:   cmp dword [ebp-0x1c], 0x0
L_00000053:   jmp 0xfffffffffff593cc
L_00000058:   mov eax, [esp]
L_0000005B:   cmp dword [eax+0x1e], 0x33145133
L_00000062:   jnz 0x87
L_00000064:   mov dword [ebp-0x14], 0x6630bac0
L_0000006B:   mov dword [ebp-0x1c], 0x6c865734
L_00000072:   mov dword [ebp-0x20], 0xf588b873
L_00000079:   mov dword [ebp-0x24], 0xe02a9dcd
L_00000080:   mov dword [ebp-0x28], 0xe896bb13
L_00000087:   xor eax, eax
L_00000089:   inc eax
L_0000008A:   ret 
L_0000008B:   mov byte [esp+0xc], 0x40
L_00000090:   cmp dword [0x1ed01000], 0x0
L_00000097:   jz 0xb4
L_00000099:   mov dword [0x1ed8c2df], 0xe940c033
L_000000A3:   mov dword [0x1ed8c2e3], 0x639
L_000000AD:   mov byte [0x1ee06a31], 0x32
L_000000B4:   jmp [0x1f6e4234]
2015-1-5 15:07
0
雪    币: 112
活跃值: (27)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
7
谢谢您的支持
2015-1-5 15:25
0
雪    币: 112
活跃值: (27)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
8
谢谢您的支持
2015-1-5 15:27
0
雪    币: 79
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
支持下楼主 分析的不错
2015-1-8 23:34
0
雪    币: 1556
活跃值: (853)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
10
分析得挺不错的
2015-1-11 16:51
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
新手看不懂
2015-1-12 07:51
0
雪    币: 112
活跃值: (27)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
12
已经附送视频了…
看不懂,要先从c/c++和汇编开始慢慢学,学习只有勤奋,没有捷径!
2015-1-12 11:34
0
雪    币: 112
活跃值: (27)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
13
今天可真热闹,ida6.6在看雪独家泄露,大神您就在隔壁的52破解分享了,神速呀
2015-1-14 23:20
0
雪    币: 1556
活跃值: (853)
能力值: ( LV9,RANK:320 )
在线值:
发帖
回帖
粉丝
14
如此神器,应该造福全人类
2015-1-15 00:27
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
坐等大神视频教学了
2015-1-16 15:24
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
好东西啊,学习啦
2015-1-16 15:51
0
雪    币: 205
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
来学习了,感谢楼主无私奉献。
2015-1-19 11:23
0
雪    币: 112
活跃值: (27)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
18
介个嘛,视频不是已经在2楼放出来了吗?
2015-1-30 18:25
0
雪    币: 27
活跃值: (90)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
感谢了!!!
2015-2-4 09:57
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
支持下楼主 分析的不错
2015-2-4 21:26
0
雪    币: 38
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
mark一下
2015-2-4 23:42
0
雪    币: 196
活跃值: (15)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
为麻不直接对比 VA_X.dll 和VA_X.dll.bak的二进制数据,结果和你这一整套下来是一样一样的!
2015-2-5 23:39
0
雪    币: 112
活跃值: (27)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
23
用什么工具对比,对比了之后往哪改?!

对比二进制?!010101010?!笑
2015-2-6 00:27
0
雪    币: 196
活跃值: (15)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
24
10.8.2048.0

上传的附件:
2015-2-6 12:04
0
雪    币: 112
活跃值: (27)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
25
[QUOTE=carmenlee;1352180]10.8.2048.0

[/QUOTE]

1.哈哈,其实我兴奋你来找茬,总比被一味的被捧要好!实不相瞒,在之前我就用bindiff对比二者到底哪里不同了,但是很遗憾,没有找到不同之处。您用的是什么工具,找到二者不同的?

2.希望你能分清楚十六进制Hex和二进制Bin的区别,您的贴图是十六进制OK,若是二进制估计你要眼花

3.您用的这工具是怎么找到在哪个rva不同,除非您事先就已经知道在哪不同。这样吧,我们极端一下环境,我有两个文件一个dota.exe和dota.se.exe(希望您知道se意味着什么),那你能通过您的“二进制差异”法,把dota.se.exe还原成-->dota.exe?!
2015-2-6 12:22
0
游客
登录 | 注册 方可回帖
返回
//