我也没有NT4 vm
你的链接指向几个样本
提供准确MD5/SHA/some verifiable checksum
的样本可以在回答时消除歧义
这里是使用基本十六进制编辑器和基本反汇编器的一个小步骤,说明为什么可能会生成该异常。
using winxp sp3 vm hxd hexeditor and ollydbg 1.10 in a basic dis-aaseembler mode
下载了 openmalware 中的第一个样本
MD5: f40547d521818f7c34754710f8603d5a
SHA1: f9e3c0e824dda984046b4eedeef06f938805983b
SHA256: a9beda469c835abbf416ea8da5462170eafdef215b96ac68523045600883855b
OCID: 245478739
Original Filename: Virus.Win32.Bolzano.5572
拖放到 vpc 2007 xp sp3 vm
使用给定的密码解压缩感染
拖入 hxd hexeditor and verified checksums
MD-5: F40547D521818F7C34754710F8603D5A
SHA-1: F9E3C0E824DDA984046B4EEDEEF06F938805983B
SHA-256: A9BEDA469C835ABBF416EA8DA5462170EAFDEF215B96AC68523045600883855B
所有三个校验和都匹配正常
WORD MajorSubsystemVersion
WORD MinorSubsystemVersion
Contains the minimum subsystem version required to run the executable.
A typical value for this field is 3.10 (meaning Windows NT 3.1).
http://msdn.microsoft.com/en-us/library/ms809762.aspx
使用 ollydbg 作为反汇编程序
view -> file -> malware.exe -> right click -> speacial -> pe header
ctrl+g 100
pe标题显示
00000148 0300 DW 0003 ; MajorSubsystemVersion = 3
0000014A 0A00 DW 000A ; MinorSubsystemVersion = A (10.)
00000200 00100000 DD 00001000 ; VirtualSize = 1000 (4096.)
00000204 00100000 DD 00001000 ; VirtualAddress = 1000 <-----
00000208 00020000 DD 00000200 ; SizeOfRawData = 200 (512.)
0000020C 00060000 DD 00000600 ; PointerToRawData = 600
00000228 00200000 DD 00002000 ; VirtualSize = 2000 (8192.)
0000022C 00200000 DD 00002000 ; VirtualAddress = 2000
00000230 00200000 DD 00002000 ; SizeOfRawData = 2000 (8192.)
00000234 00080000 DD 00000800 ; PointerToRawData = 800 <------
00000128 00100000 DD 00001000 ; AddressOfEntryPoint = 1000
所以我们可以从 0x600 开始反汇编
ctrl+g 600 right click -> disassemble
拆卸
1. 00000600 60 PUSHAD
2. 00000601 E9 FA0F0000 JMP 00001600
正如我们之前看到的那样,section 的虚拟大小是 1000
所以它跳转到下一个 section
下一个 section 从 0x800 开始,正如我们之前看到的
ctrl+g 800 disassemble
拆卸
00000800 E8 D50E0000 CALL 000016DA (402eda) 400000 +2000 + (16da-800)
下列的
000016DA E8 00000000 CALL 000016DF $+5 (402edf) 400000+ 2000+ (16df-800)
000016DF 5D POP EBP ebp will be 402edf
000016E0 81ED DF0E0000 SUB EBP, 0EDF ebp will be 402000
000016E6 C3 RETN will return to 805 or 402005
ctrl+g 805 反汇编
00000805 BF 000C0100 MOV EDI, 10C00
0000080A B9 00010000 MOV ECX, 100
0000080F 33C0 XOR EAX, EAX
00000811 F3:AE REPE SCAS BYTE PTR ES:[EDI]
scan all bytes from 10c00 to 10d00 for 0
00000813 75 0C JNZ SHORT 00000821
if all not zero go to win95/98
00000815 BE 2D110000 MOV ESI, 112D win nt
0000081A BF 0000F077 MOV EDI, 77F00000 k32 base
0000081F EB 0A JMP SHORT 0000082B
00000821 BE 25110000 MOV ESI, 1125 win 95 / 98
00000826 BF 0000F7BF MOV EDI, BFF70000 k32 base
sets the base of kernel32.dll to edi
字节扫描的目的是
查看从 10c00 开始的所有 100 个字节是否为零,
如果它们是零集kernel base to 77f00000
(win nt k32 base no aslr fixed)
否则为bff70000
(win 95 / 98 kernel32 base no aslr fixed)
esi到一些偏移
( esi = 1125 or 112d) ( ebp = 402000) 40312d/25 1925 or 192d (800+1125 or 112d)
0000082B 03F5 ADD ESI, EBP
(so esi will be either 403125 or 40312d)
0000082D 89BD C8170000 MOV DWORD PTR SS:[EBP+17C8], EDI
saves the pointer kernel base guess why ??
00000833 BA 00000400 MOV EDX, 40000
00000838 FC CLD
00000839 B9 08000000 MOV ECX, 8
0000083E 56 PUSH ESI
0000083F 57 PUSH EDI
00000840 F3:A6 REPE CMPS BYTE PTR ES:[EDI], BYTE PTR>
00000842 5F POP EDI
00000843 5E POP ESI
byte pattern
在 k32 dll 中进行比较
对于95/98
这种模式
00001925 C2 0400 RETN 4
00001928 57 PUSH EDI
00001929 6A 22 PUSH 22
0000192B 2BD2 SUB EDX, EDX
对于win nt
这种模式
0000192D C2 0400 RETN 4
00001930 55 PUSH EBP
00001931 8B4C24 0C MOV ECX, DWORD PTR SS:[ESP+C]
跳到 ok 或 not ok
00000844 74 0A JE SHORT 00000850 `right user with right os jump`
00000846 47 INC EDI
00000847 4A DEC EDX
00000848 0F84 CD000000 JE 0000091B `wrong user with wrong os jump`
0000084E ^ EB E9 JMP SHORT 00000839
如果它发现模式将转到 850
否则 91b
在 91b 有
0000091B E8 BA0D0000 CALL 000016DA
所以这将返回到 920(参见上面的 retn 到 402005)
00000920 8B5424 20 MOV EDX, DWORD PTR SS:[ESP+20]
00000924 B9 40000000 MOV ECX, 40
00000929 83EA 05 SUB EDX, 5
0000092C BE 4F180000 MOV ESI, 184F
这将返回到内核或退出线程地址(pushad == 0x20)
所有其他都是垃圾
exe 在 204f 到 224f 不包含任何内容将通过 retn 简单地退出
(184f+800 ecx = 40 两个 lodsd = 80 dwords = 200 字节 = 224f)
如果该区域与 retn 值比较 ok - 5(参见 sub edx,5)
,应用程序将崩溃并且 ollydbg 可以发出该警告
00000931 03F5 ADD ESI, EBP
00000933 AD LODS DWORD PTR DS:[ESI]
00000934 3BC2 CMP EAX, EDX
00000936 AD LODS DWORD PTR DS:[ESI]
00000937 74 04 JE SHORT 0000093D
00000939 ^ E2 F8 LOOPD SHORT 00000933
0000093B 61 POPAD
0000093C C3 RETN
0000093D 8985 47010000 MOV DWORD PTR SS:[EBP+147], EAX
00000943 61 POPAD
00000944 EB 00 JMP SHORT 00000946
00000946 68 00000000 PUSH 0 <---- apllication will crash
0000094B C3 RETN eip not valid or 0
ollydbg 将显示不知道如何步进,因为地址 0 处的内存不可读尝试更改 Eip 或将异常传递给程序,如果它到达这里
在 850 或 402050 拆卸
00000850 83C7 03 ADD EDI, 3 add 3 to bytepattern address
00000853 BE E70E0000 MOV ESI, 0EE7
00000858 03F5 ADD ESI, EBP 402ee7 = 16e7 (ee7 -800 + 1000)
0000085A 8BC6 MOV EAX, ESI
0000085C 83C0 07 ADD EAX, 7 16e7+7 = 16ee
16ee 处的字节模式
000016EE 43 72 65 61 74 65 46 69 6C 65 4D 61 70 70 69 6E CreateFileMappin
000016FE 67 41 gA
进一步拆解
0000085F 50 PUSH EAX **pushes string CreateFileMapping**
00000860 8B85 C8170000 MOV EAX, DWORD PTR SS:[EBP+17C**8]
00000866 50 PUSH EAX** pushes kernel base
00000867 FFD7 CALL NEAR EDI (can you guess ?? what api ??)
试着向前走一点:)