恶意代码实验3

实验3

一、分析感染后的可执行程序

1.分析节表相关项

image-20210507160904650
图1

感染后的程序包括4个节,这个可以从映像文件头结构的3-4字节这两个字节即0x0004得到

或者通过节表的名字来判断,如图所示共有text、radta、data、hum共四个节表

或者通过PEview等软件来查看

image-20210507163640982

图2

节表部分前三个节没有变化,只是增加了第四个节

image-20210507184923353

图3

image-20210508105133534

图4

hum节表的节表属性为0xE0000020,0xE0000000=0x60000000+0x80000000,即可写(0x80000000)和可执行(0x60000000),0x20为可读

image-20210508105734681

图5

上表为节表的一些属性对应的值,参考博客PE文件格式---节和节表 - 地势坤 - 博客园 (cnblogs.com)

PE程序的入口地址从0x401000被变为0x4042DC,0x4000对应0xA00,再加上0x2DC即为0xCDC,为病毒程序的汇编代码入口

image-20210507185441622

图6

2.分析病毒是否反复感染同一文件

;在modipe.asm中
cmp    word  ptr [esi],'ZM' 
jne    CouldNotInfect 
add    esi,[esi+3ch]        
cmp    word  ptr [esi],'EP' 
jne    CouldNotInfect       
cmp    dword ptr [esi+8],'dark'  ;比较在特定位置是否有dark
je     CouldNotInfect       ;跳转的函数在main-new.asm中

;在main-new.asm中
CouldNotInfect:
lea    eax,[ebp+u32] 
push   eax 
call   dword ptr [ebp+aLoadLibrary] 
test   eax,eax 
jnz    @g12       
@g12: 
    lea    EDX,[EBP+sMessageBoxA] 
push   edx 
push   eax 
mov    eax,dword ptr [ebp+aGetProcAddress]  
call   eax 
mov    [ebp+aMessageBoxA],eax 

push 10040h
call No_caption
db "没有感染!",0
No_caption:
call _tips
db "本程序仅感染本目录下未被感染过的test.exe程序。",0 
_tips:
push 0
call [ebp+aMessageBoxA]

在在modipe.asm中会通过cmp比较文件中是否有“dark”字符串来判断文件是否被感染,如果有dark的话就会跳转到CouldNotInfect函数,弹出弹窗“本程序仅感染本目录下未被感染过的test.exe程序”,但是增加文件大小还是会执行,文件会增大4kb的0x00

_where:                                         
xor    eax,eax          ;判断是否是已经附加感染标志 'dark' 
push   eax 
call   [ebp+aGetModuleHandle];获得本启动(或HOST)程序的加载模块
mov    esi,eax 
add    esi,[esi+3ch]    ; esi->程序本身的Pe_header 
cmp    dword ptr [esi+8],'dark';判断是已经正在运行的HOST程序,还是启动程序? 
je     jmp_oep 	              ;是HOST程序,控制权交给HOST
jmp    _xit                   ;调用启动程序的退出部分语句
jmp_oep: 
add    eax,[ebp+oldEip]         
jmp    eax                    ;跳到宿主程序的入口点

在这个函数中也判断了dark,cmp如果相等ZF位置1,否则置0,而je只有在ZF=1则跳转

image-20210507184044805

图7

在文件中判断过程如图所示

二、分析源程序main.asm

1.分析重定位相关代码

_delta:
pop    ebp                                  ;得到delta地址
sub    ebp,offset _delta                    ;以便于后面变量重定位
mov    dword ptr [ebp+appBase],ebp
mov    eax,[esp]                            ;返回地址
xor    edx,edx 

存储相应偏差位移量的寄存器是ebp。

首先得到ebp指针(即调用函数的地址),也是delta在程序执行时的实际偏移,然后减掉代码头到delta的偏移从而得到偏差位移量,然后存到ebp+appBase对应的地址(一个4字节的空间),appBase在s_api.asm中定义为appBase dd ?

2.分析kernel32.dll

getK32Base: 
dec    eax               ;逐字节比较验证,速度比较慢,不过功能一样
mov    ax,0;低16为0
mov    dx,word  ptr [eax+IMAGE_DOS_HEADER.e_lfanew]  ;就是ecx+3ch
test   dx,0f000h         ;Dos Header+stub不可能太大,超过4096byte
jnz    getK32Base        ;加速检验,下一个
cmp    eax,dword ptr [eax+edx+IMAGE_NT_HEADERS.OptionalHeader.ImageBase]
jnz    getK32Base        ;看Image_Base值是否等于ecx即模块起始值
mov    [ebp+k32Base],eax ;如果是,就认为找到kernel32的模块装入地址
lea    edi,[ebp+aGetModuleHandle] ;edi指向API函数地址存放位置
lea    esi,[ebp+lpApiAddrs] ;esi指向API函数名字串偏移地址(此地址需重定位)

jnz为ZF=0则跳转,test判断0x3c的位置是否为0x00f0,不一致则继续循环,再cmp判断Image_Base值,不等就继续循环执行getK32Base直到相等为止,装载装在eax中,然后存到ebp+k32Base对应的地址

image-20210508131227868

图8

kernel32.dll的0x3c处的值为0x00F0

三、修复程序

思路:将感染程序的入口改为原来的入口,即0x401000,将节表数改为0x03,然后将hum节表置为全0,将病毒代码置为全0或者删掉,保留dark这样感染程序就会认为此程序已经被感染从而实现免疫

入口位置的偏移即0x1000可以通过text节表中的virtualAddress得到(text节表的12-16字节)

image-20210507191005646

图9

修改0xB6的位置值为0x03(节表数),修改0xD8的位置值为0x1000(首条指令地址),将0x220的节表全置为0(多修改了8字节,并不影响结果)

image-20210507191053076

图10

将原先的病毒代码全部置0

image-20210507191552735

图11

运行,程序恢复正常,在win10上运行正常,但不能在XP中运行

image-20210507191638103

图12

运行感染程序,感染程序认为没有目标去感染,实现免疫,直接删掉0xA00后的内容也是成功的

image-20210508112755031

图13

大小为3KB与原文件一致,文件链接,提取码:kqn2

四、编译asm方法

需要先修改头文件,头文件的位置要根据自己安装的masm32的位置,比如说我安装的位置就是D:\masm32

include D:\masm32\include\windows.inc
include D:\masm32\include\comctl32.inc 
includelib D:\masm32\lib\comctl32.lib

运行以下指令编译成exe文件

ml /c /coff main-new.asm
link /subsystem:windows /section:.text,RWE main-new.obj /section:.text,RWE

image-20210508112215306

图14

是一个正常的病毒感染程序,可以在X64环境下运行

五、在XP中运行

在XP中不可以运行的原因是文件中的size of image的值被病毒程序增加了0x1000

image-20210508125609062

图15

将0x5000改回0x4000即可以在XP中正常运行

原因是增加了hum节,hum节在内存中存了0x1000(实际上只有没有这么多的内容)

原文地址:https://www.cnblogs.com/wqnmlkb/p/14742485.html