一个小程序自校验分析
本帖最后由 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,其实每处的修改方法应该都不止一种自己发挥吧
有哪里不对请拍砖
也可以试试这个 软件不同校验一样 A-new 发表于 2017-11-22 18:55
都改了,并且,你脱壳后的和我脱壳修复后的可能不一样,根据自己计算出来的改
"4AE770C6 加密一下写回sysinf.ini就好了我这里算出来的是33413447404032364336"
A版的这句话含金量极高,小白请教,是怎么加密回去的呢
文科生太菜了,不好意思~ 刘统宝 发表于 2017-11-22 17:10
最后一段:
【这里只有8个字符就不用写代码了直接拿计算器把文件算出的hash:4AE770C6 加密一下写回sysi ...
都改了,并且,你脱壳后的和我脱壳修复后的可能不一样,根据自己计算出来的改 我来了,我要第一个拜读版主大作!跟大神靠近,鸡冻~ 先留名,后面再来看内容 先留名,后面再来看内容 做个标记。稍后观看内容。。
话说为嘛大牛都是些图文教程多一点。而不是出视频教程,那不是更省力一点么 坐稳板凳,等待内容~~~~{:1_918:} 努力让积分高于10000{:301_997:} 坐板凳,稍后看内容..... 后排围观来了