A-new 发表于 2017-11-20 12:56

一个小程序自校验分析

本帖最后由 A-new 于 2017-11-21 12:19 编辑

看这个小程序源于@刘统宝 的一个求助贴https://www.52pojie.cn/thread-660923-1-1.html
仔细看了一下这个小程序自校验方法比较经典吧,就给大家写一下
首先是分析的总结这个程序自校验涉及三个自校验点:1、文件修改时间校验2、文件大小校验、3CRC校验
原程序加了Aspack壳,脱壳就不介绍了ESP就可以搞定直接进入主题
整个校验流程就在这一段0045F93C   .8B00          mov   eax, dword ptr 0045F93E   .E8 09BEFFFF   call    <Forms.TApplication.GetExeName>
0045F943      C705 6C1F4700>mov   dword ptr , 0x35C14    ;文件大小
0045F94D   .8B45 F0       mov   eax, dword ptr
0045F950   .E8 A3F0FFFF   call    <MiFareProg.sub_0045E9F8> ;读取文件大小
0045F955   .A3 701F4700   mov   dword ptr , eax
0045F95A   .33C0          xor   eax, eax
0045F95C   .55            push    ebp
0045F95D   .68 80F94500   push    0045F980
0045F962   .64:FF30       push    dword ptr fs:
0045F965   .64:8920       mov   dword ptr fs:, esp
0045F968   .B8 B4FF4500   mov   eax, 0045FFB4                  ;2017-07-18 10:10
0045F96D   .E8 52BCFAFF   call    <SysUtils.StrToDateTime>
0045F972   .DD5D E0       fstp    qword ptr
0045F975   .9B            wait
0045F976   .33C0          xor   eax, eax
0045F978   .5A            pop   edx
0045F979   .59            pop   ecx
0045F97A   .59            pop   ecx
0045F97B   .64:8910       mov   dword ptr fs:, edx
0045F97E   .EB 18         jmp   short 0045F998
0045F980   .^ E9 8342FAFF   jmp   <System.@HandleAnyException>
0045F985   .B8 D0FF4500   mov   eax, 0045FFD0                  ;2017/07/18 10:10
0045F98A   .E8 35BCFAFF   call    <SysUtils.StrToDateTime>
0045F98F   .DD5D E0       fstp    qword ptr
0045F992   .9B            wait
0045F993   .E8 D845FAFF   call    <System.@DoneExcept>
0045F998   >BA 02000000   mov   edx, 0x2
0045F99D   .8B45 F0       mov   eax, dword ptr
0045F9A0   .E8 77EFFFFF   call    <MiFareProg.sub_0045E91C>
0045F9A5   .DD5D E8       fstp    qword ptr
0045F9A8   .9B            wait
0045F9A9   .EB 0C         jmp   short 0045F9B7
0045F9AB   >A1 E0054700   mov   eax, dword ptr
0045F9B0   .8B00          mov   eax, dword ptr
0045F9B2   .E8 71B8FFFF   call    <Forms.TApplication.Terminate>
0045F9B7   >FF75 EC       push    dword ptr
0045F9BA   .FF75 E8       push    dword ptr
0045F9BD   .FF75 E4       push    dword ptr
0045F9C0   .FF75 E0       push    dword ptr
0045F9C3   .E8 8CCCFFFF   call    <_Unit58.sub_0045C654>
0045F9C8   .48            dec   eax
0045F9C9    ^ 7F E0         jg      short 0045F9AB
0045F9CB   .A1 701F4700   mov   eax, dword ptr
0045F9D0   .3B05 6C1F4700 cmp   eax, dword ptr
0045F9D6   .7C 1F         jl      short 0045F9F7
0045F9D8   .8B45 FC       mov   eax, dword ptr
0045F9DB   .8B80 F8020000 mov   eax, dword ptr
0045F9E1   .BA ECFF4500   mov   edx, 0045FFEC                  ;请交出你的比特币,嗯哼.....
0045F9E6   .E8 55BFFDFF   call    <Controls.TControl.SetText>
0045F9EB   .A1 E0054700   mov   eax, dword ptr
0045F9F0   .8B00          mov   eax, dword ptr
0045F9F2   .E8 31B8FFFF   call    <Forms.TApplication.Terminate>
0045F9F7   >B8 7C1F4700   mov   eax, 00471F7C
0045F9FC   .BA 10004600   mov   edx, 00460010                  ;IC卡操作软件Ver1.0 For Acr122u
0045FA01   .E8 064BFAFF   call    <System.@LStrAsg>
0045FA06   .8B15 7C1F4700 mov   edx, dword ptr
0045FA0C   .A1 0C1C4700   mov   eax, dword ptr
0045FA11   .E8 2ABFFDFF   call    <Controls.TControl.SetText>
0045FA16   .68 30004600   push    00460030                         ; /myhotkey
0045FA1B   .E8 E46BFAFF   call    <Windows.kernel32.GlobalAddAtomA>; \GlobalAddAtomA
0045FA20   .0FB7C0      movzx   eax, ax
0045FA23   .2D 00C00000   sub   eax, 0xC000
0045FA28   .A3 5C1F4700   mov   dword ptr , eax
0045FA2D   .6A 79         push    0x79
0045FA2F   .6A 00         push    0x0
0045FA31   .A1 5C1F4700   mov   eax, dword ptr
0045FA36   .50            push    eax
0045FA37   .8B45 FC       mov   eax, dword ptr
0045FA3A   .E8 CD27FEFF   call    <Controls.TWinControl.GetHandle>
0045FA3F   .50            push    eax                              ; |hWnd
0045FA40   .E8 AF72FAFF   call    <Windows.user32.RegisterHotKey>; \RegisterHotKey
0045FA45   .C605 601F4700>mov   byte ptr , 0x0
0045FA4C   .33C0          xor   eax, eax
0045FA4E   .A3 581F4700   mov   dword ptr , eax
0045FA53   .8D55 D4       lea   edx, dword ptr
0045FA56   .A1 E0054700   mov   eax, dword ptr
0045FA5B   .8B00          mov   eax, dword ptr
0045FA5D   .E8 EABCFFFF   call    <Forms.TApplication.GetExeName>
0045FA62   .8B45 D4       mov   eax, dword ptr
0045FA65   .8D55 D8       lea   edx, dword ptr
0045FA68   .E8 F390FAFF   call    <SysUtils.ExtractFilePath>
0045FA6D   .8D45 D8       lea   eax, dword ptr
0045FA70   .BA 44004600   mov   edx, 00460044                  ;sysinf.ini
0045FA75   .E8 064DFAFF   call    <System.@LStrCat>
0045FA7A   .8B4D D8       mov   ecx, dword ptr
0045FA7D   .B2 01         mov   dl, 0x1
0045FA7F   .A1 DCB34200   mov   eax, dword ptr       ;附B
0045FA84   .E8 03BAFCFF   call    <IniFiles.TIniFile.Create>
0045FA89   .A3 541F4700   mov   dword ptr , eax
0045FA8E   .68 58004600   push    00460058                         ;ABCDEF9876543210
0045FA93   .8D45 D0       lea   eax, dword ptr
0045FA96   .50            push    eax
0045FA97   .B9 74004600   mov   ecx, 00460074                  ;zcm
0045FA9C   .BA 80004600   mov   edx, 00460080                  ;softinfo
0045FAA1   .A1 541F4700   mov   eax, dword ptr
0045FAA6   .8B18          mov   ebx, dword ptr
0045FAA8   .FF13          call    dword ptr
0045FAAA   .8B55 D0       mov   edx, dword ptr
0045FAAD   .B8 681F4700   mov   eax, 00471F68
0045FAB2   .E8 554AFAFF   call    <System.@LStrAsg>
0045FAB7   .68 94004600   push    00460094                         ;33434E44314332443336
0045FABC   .8D45 CC       lea   eax, dword ptr
0045FABF   .50            push    eax
0045FAC0   .B9 B4004600   mov   ecx, 004600B4                  ;sellerID
0045FAC5   .BA 80004600   mov   edx, 00460080                  ;softinfo
0045FACA   .A1 541F4700   mov   eax, dword ptr
0045FACF   .8B18          mov   ebx, dword ptr
0045FAD1   .FF13          call    dword ptr
0045FAD3   .8B55 CC       mov   edx, dword ptr
0045FAD6   .B8 741F4700   mov   eax, 00471F74
0045FADB   .E8 2C4AFAFF   call    <System.@LStrAsg>
0045FAE0   .8D55 F8       lea   edx, dword ptr
0045FAE3   .A1 741F4700   mov   eax, dword ptr
0045FAE8   .E8 0BEBFFFF   call    <MiFareProg.sub_0045E5F8>
0045FAED   .68 741F4700   push    00471F74
0045FAF2   .B9 08000000   mov   ecx, 0x8
0045FAF7   .BA 02000000   mov   edx, 0x2
0045FAFC   .8B45 F8       mov   eax, dword ptr
0045FAFF   .E8 D44EFAFF   call    <System.@LStrCopy>
0045FB04   .8D55 DC       lea   edx, dword ptr
0045FB07   .8B45 F0       mov   eax, dword ptr
0045FB0A   .E8 E1E6FFFF   call    <MiFareProg.sub_0045E1F0>      ;crc
0045FB0F   .8B45 DC       mov   eax, dword ptr
0045FB12   .F7D0          not   eax
0045FB14   .33D2          xor   edx, edx
0045FB16   .52            push    edx                              ;4AE770C6
0045FB17   .50            push    eax
0045FB18   .8D55 C8       lea   edx, dword ptr
0045FB1B   .B8 08000000   mov   eax, 0x8
0045FB20   .E8 C38BFAFF   call    <SysUtils.IntToHex>
0045FB25   .8B45 C8       mov   eax, dword ptr
0045FB28   .E8 4B4EFAFF   call    <System.@LStrToPChar>
0045FB2D   .8BD0          mov   edx, eax
0045FB2F   .B8 781F4700   mov   eax, 00471F78
0045FB34   .E8 774BFAFF   call    <System.@LStrFromPChar>
0045FB39   .EB 0C         jmp   short 0045FB47
0045FB3B   >A1 E0054700   mov   eax, dword ptr
0045FB40   .8B00          mov   eax, dword ptr
0045FB42   .E8 E1B6FFFF   call    <Forms.TApplication.Terminate>
0045FB47   >A1 741F4700   mov   eax, dword ptr
0045FB4C   .8B15 781F4700 mov   edx, dword ptr
0045FB52   .E8 6D4DFAFF   call    <System.@LStrCmp>
0045FB57    ^ 75 E2         jnz   short 0045FB3B
0045FB59   .E8 2AE9FFFF   call    <MiFareProg.sub_0045E488>

1、文件时间校验
0045F968   .B8 B4FF4500   mov   eax, 0045FFB4                  ;2017-07-18 10:10
0045F96D   .E8 52BCFAFF   call    <SysUtils.StrToDateTime>
0045F972   .DD5D E0       fstp    qword ptr
0045F975   .9B            wait
0045F976   .33C0          xor   eax, eax
0045F978   .5A            pop   edx
0045F979   .59            pop   ecx
0045F97A   .59            pop   ecx
0045F97B   .64:8910       mov   dword ptr fs:, edx
0045F97E   .EB 18         jmp   short 0045F998
0045F980   .^ E9 8342FAFF   jmp   <System.@HandleAnyException>
0045F985   .B8 D0FF4500   mov   eax, 0045FFD0                  ;2017/07/18 10:10
0045F98A   .E8 35BCFAFF   call    <SysUtils.StrToDateTime>
0045F98F   .DD5D E0       fstp    qword ptr
0045F992   .9B            wait
0045F993   .E8 D845FAFF   call    <System.@DoneExcept>
0045F998   >BA 02000000   mov   edx, 0x2
0045F99D   .8B45 F0       mov   eax, dword ptr
0045F9A0   .E8 77EFFFFF   call    <MiFareProg.sub_0045E91C>
0045F9A5   .DD5D E8       fstp    qword ptr

对比的时间是可能是2017-07-18 10:10
原文件的修改时间是2017-07-18,12:54:48
刚开始没注意这个浪费了不少时间
再看他如何获取文件修改时间的
注意这个call 0045F9A0   .E8 77EFFFFF   call    <MiFareProg.sub_0045E91C>函数主要内容
0045E950|.50            push    eax                              ; |FileName
0045E951|.E8 D67BFAFF   call    <Windows.kernel32.FindFirstFileA>; \FindFirstFileA
0045E956|.83F8 FF       cmp   eax, -0x1
0045E959|.74 76         je      short 0045E9D1
0045E95B|.83EB 01       sub   ebx, 0x1                         ;Switch (cases 1..2)
0045E95E|.72 07         jb      short 0045E967
0045E960|.74 19         je      short 0045E97B
0045E962|.4B            dec   ebx
0045E963|.74 2A         je      short 0045E98F
0045E965|.EB 3A         jmp   short 0045E9A1
0045E967|>8B95 A4FEFFFF mov   edx, dword ptr
0045E96D|.8955 E0       mov   dword ptr , edx
0045E970|.8B95 A8FEFFFF mov   edx, dword ptr
0045E976|.8955 E4       mov   dword ptr , edx
0045E979|.EB 26         jmp   short 0045E9A1
0045E97B|>8B95 ACFEFFFF mov   edx, dword ptr        ;Case 1 of switch 0045E95B
0045E981|.8955 E0       mov   dword ptr , edx
0045E984|.8B95 B0FEFFFF mov   edx, dword ptr
0045E98A|.8955 E4       mov   dword ptr , edx
0045E98D|.EB 12         jmp   short 0045E9A1
0045E98F|>8B95 B4FEFFFF mov   edx, dword ptr        ;Case 2 of switch 0045E95B
0045E995|.8955 E0       mov   dword ptr , edx
0045E998|.8B95 B8FEFFFF mov   edx, dword ptr
0045E99E|.8955 E4       mov   dword ptr , edx
0045E9A1|>50            push    eax                              ; /hSearch; Default case of switch 0045E95B
0045E9A2|.E8 7D7BFAFF   call    <Windows.kernel32.FindClose>   ; \FindClose
0045E9A7|.8D45 E8       lea   eax, dword ptr
0045E9AA|.50            push    eax                              ; /pLocalFileTime
0045E9AB|.8D45 E0       lea   eax, dword ptr       ; |
0045E9AE|.50            push    eax                              ; |pFileTime
0045E9AF|.E8 687BFAFF   call    <Windows.kernel32.FileTimeToLoca>; \FileTimeToLocalFileTime
0045E9B4|.8D45 FC       lea   eax, dword ptr
0045E9B7|.50            push    eax                              ; /pDOSTime
0045E9B8|.8D45 FE       lea   eax, dword ptr          ; |
0045E9BB|.50            push    eax                              ; |pDOSDate
0045E9BC|.8D45 E8       lea   eax, dword ptr       ; |
0045E9BF|.50            push    eax                              ; |pFileTime
0045E9C0|.E8 4F7BFAFF   call    <Windows.kernel32.FileTimeToDosD>; \FileTimeToDosDateTime
0045E9C5|.8B45 FC       mov   eax, dword ptr
0045E9C8|.E8 4BA3FAFF   call    <SysUtils.FileDateToDateTime>
0045E9CD|.DD5D F0       fstp    qword ptr
0045E9D0|.9B            wait
0045E9D1|>33C0          xor   eax, eax

FindFirstFileA这个函数比较有意思一直以为获取文件时间要用GetFileTime之类
原来用这个HANDLE WINAPI FindFirstFile(
_In_LPCTSTR         lpFileName,
_Out_ LPWIN32_FIND_DATA lpFindFileData
);
返回值已经包含了文件的好多信息
typedef struct _WIN32_FIND_DATA {DWORD    dwFileAttributes;//文件属性FILETIME ftCreationTime;//文件的创建日期FILETIME ftLastAccessTime;//文件的最后存取日期FILETIME ftLastWriteTime;//文件的最后修改日期DWORD    nFileSizeHigh;//文件长度的高32位DWORD    nFileSizeLow;//文件长度的低32位DWORD    dwReserved0;DWORD    dwReserved1;TCHAR    cFileName;//本次找到的文件名TCHAR    cAlternateFileName;//文件的8.3结构的短文件名} WIN32_FIND_DATA, *PWIN32_FIND_DATA, *LPWIN32_FIND_DATA;
这里简单的方法是修改脱壳文件修改时间这就要用到NewFileTime这个小工具
2、大小校验
0045F943      C705 6C1F4700>mov   dword ptr , 0x35C14    ; 写定大小
0045F94D   .8B45 F0       mov   eax, dword ptr
0045F950   .E8 A3F0FFFF   call    <MiFareProg.sub_0045E9F8>获取运行文件大小
0045F955   .A3 701F4700   mov   dword ptr , eax

对比位置
0045F9CB   .A1 701F4700   mov   eax, dword ptr
0045F9D0   .3B05 6C1F4700 cmp   eax, dword ptr
0045F9D6   .7C 1F         jl      short 0045F9F7
0045F9D8   .8B45 FC       mov   eax, dword ptr

这个简单直接把0x35C14改的大于脱壳文件就好了
3、CRC32校验
这个CRC校验稍微有点变化不是直接对比文件hash值而是对hash值又稍作处理
这里最好把脱壳程序拖进ida查找加密算法因为这个是CRC,主要是一个CRC_tab,ida可以直接定位引用代码
46FF28: found const array CRC32_m_tab (used in CRC32)
Found 1 known constant arrays in total.
CODE:0045E287 loc_45E287:                           ; CODE XREF: sub_45E1F0+B9j
CODE:0045E287               xor   ecx, ecx
CODE:0045E289               mov   cl,
CODE:0045E28B               mov   esi,
CODE:0045E28D               and   esi, 0FFh
CODE:0045E293               xor   ecx, esi
CODE:0045E295               mov   ecx, ds:CRC32_m_tab;这里
CODE:0045E29C               mov   esi,
CODE:0045E29E               shr   esi, 8
CODE:0045E2A1               xor   ecx, esi
CODE:0045E2A3               mov   , ecx
CODE:0045E2A5               inc   eax
CODE:0045E2A6               dec   dx
CODE:0045E2A9               jnz   short loc_45E287
CODE:0045E2AB
CODE:0045E2AB loc_45E2AB:                           ; CODE XREF: sub_45E1F0+8Fj
CODE:0045E2AB               cmp   , 0
CODE:0045E2AF               jnz   short loc_45E25E
CODE:0045E2B1
CODE:0045E2B1 loc_45E2B1:                           ; CODE XREF: sub_45E1F0+6Cj
从段首可以查看在此处计算文件CRC
0045FB0A   .E8 E1E6FFFF   call    <MiFareProg.sub_0045E1F0>      ;crc
0045FB0F   .8B45 DC       mov   eax, dword ptr
0045FB12   .F7D0          not   eax;取反
0045FB14   .33D2          xor   edx, edx
0045FB16   .52            push    edx                              ;4AE770C6
0045FB17   .50            push    eax

这里取反了一下计算出字符串4AE770C6导致最后比较的时候觉得不是CRC的错觉
0045FB47   > \A1 741F4700   mov   eax, dword ptr
0045FB4C   .8B15 781F4700 mov   edx, dword ptr
0045FB52   .E8 6D4DFAFF   call    <System.@LStrCmp>

这个软件CRC校验对比的hash在sysinf.ini中3345403435403131343F(加密的CRC)
通过函数0045FAE8   .E8 0BEBFFFF   call    <MiFareProg.sub_0045E5F8>
进行解密主要解密过程如下
0045E646|> /8D45 E8       /lea   eax, dword ptr
0045E649|. |50            |push    eax
0045E64A|. |8BC7          |mov   eax, edi
0045E64C|. |2BC6          |sub   eax, esi
0045E64E|. |40            |inc   eax
0045E64F|. |8BD0          |mov   edx, eax
0045E651|. |03D2          |add   edx, edx
0045E653|. |4A            |dec   edx
0045E654|. |B9 02000000   |mov   ecx, 0x2
0045E659|. |8B45 FC       |mov   eax, dword ptr
0045E65C|. |E8 7763FAFF   |call    <System.@LStrCopy>
0045E661|. |8B4D E8       |mov   ecx, dword ptr
0045E664|. |8D45 EC       |lea   eax, dword ptr
0045E667|. |BA DCE64500   |mov   edx, 0045E6DC                   ;$
0045E66C|. |E8 5361FAFF   |call    <System.@LStrCat3>
0045E671|. |8B45 EC       |mov   eax, dword ptr
0045E674|. |E8 9FA0FAFF   |call    <SysUtils.StrToInt>
0045E679|. |8BD0          |mov   edx, eax
0045E67B|. |83F2 77       |xor   edx, 0x77
0045E67E|. |8D45 F0       |lea   eax, dword ptr
0045E681|. |E8 1A60FAFF   |call    <System.@LStrFromChar>
0045E686|. |8B55 F0       |mov   edx, dword ptr
0045E689|. |8D45 F4       |lea   eax, dword ptr
0045E68C|. |E8 EF60FAFF   |call    <System.@LStrCat>
0045E691|. |46            |inc   esi
0045E692|. |4B            |dec   ebx
0045E693|.^\75 B1         \jnz   short 0045E646

其实关键就是与0x77异或
就是把3345403435403131343F看做0x3345403435403131343F,逐字节与0x77异或解密出来为01D20A8448 43 46 46 37 42 43 37 32 44                  HCFF7BC72D
然后取中间8个字符串CFF7BC72,这里只有8个字符就不用写代码了直接拿计算器把文件算出的hash:4AE770C6 加密一下写回sysinf.ini就好了我这里算出来的是33413447404032364336
大家也自己操作一下玩玩吧
也可以用peid插件修改文件CRC值为not CFF7BC72也就是3008438D,其实每处的修改方法应该都不止一种自己发挥吧
有哪里不对请拍砖
也可以试试这个 软件不同校验一样

刘统宝 发表于 2017-11-23 10:37

A-new 发表于 2017-11-22 18:55
都改了,并且,你脱壳后的和我脱壳修复后的可能不一样,根据自己计算出来的改

"4AE770C6 加密一下写回sysinf.ini就好了我这里算出来的是33413447404032364336"

A版的这句话含金量极高,小白请教,是怎么加密回去的呢
文科生太菜了,不好意思~

A-new 发表于 2017-11-22 18:55

刘统宝 发表于 2017-11-22 17:10
最后一段:

【这里只有8个字符就不用写代码了直接拿计算器把文件算出的hash:4AE770C6 加密一下写回sysi ...

都改了,并且,你脱壳后的和我脱壳修复后的可能不一样,根据自己计算出来的改

刘统宝 发表于 2017-11-20 13:41

我来了,我要第一个拜读版主大作!跟大神靠近,鸡冻~

kushua 发表于 2017-11-20 14:01

先留名,后面再来看内容

Je11y 发表于 2017-11-20 14:04

先留名,后面再来看内容

影风 发表于 2017-11-20 14:12

做个标记。稍后观看内容。。
话说为嘛大牛都是些图文教程多一点。而不是出视频教程,那不是更省力一点么

小百一个 发表于 2017-11-20 14:21

坐稳板凳,等待内容~~~~{:1_918:}

牛刀小试 发表于 2017-11-20 14:44

努力让积分高于10000{:301_997:}

_Spider 发表于 2017-11-20 14:57

david743 发表于 2017-11-20 15:00

坐板凳,稍后看内容.....

ytw6176 发表于 2017-11-20 15:04

后排围观来了
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 一个小程序自校验分析