• 2007-06-25

    Virus.Win32.Downloader.c分析 - [病毒技术]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://romio64.blogbus.com/logs/6131875.html

    【分析环境】VMWARE+WINDOWS XP SP2+OLLYDBG+PEID+PEInfo
    首先用PEID扫描一下没有扫描出壳或者编译器特征,入口点RVA是0x70000,进一步使用PE分析工具查看关键的数据信息,我这里使用的是PEInfo:可以看到,代码入口不是在常规的.text节里而是在.rdata节里
    再看输入表信息:输入表的RVA是0x70660,程序只导入了kernel32.dll里的GetProcAddress和LoadLibraryA这两个函数。

    下面是详细的代码分析:

    ; 重定位到当前导入表
    00470005 68 90184000 PUSH QQLiveUp.00401890
    0047000A E8 71020000 CALL QQLiveUp.00470280

    QQLiveUp.00470280这个函数的作用就是重定位地址:
    00470280 55 PUSH EBP
    00470281 8BEC MOV EBP, ESP
    00470283 E8 00000000 CALL QQLiveUp.00470288 ;典型的重定位
    00470288 58 POP EAX
    00470289 2D B8144000 SUB EAX, QQLiveUp.004014B8
    0047028E 0345 08 ADD EAX, DWORD PTR SS:[EBP+8] ;要重定位的地址
    00470291 5D POP EBP
    00470292 C3 RETN

    上面的代码是病毒经常使用的重定位,汇编格式就是这样:
    call delta
    delta:
    pop ebx
    sub ebx,offset delta
    00470280函数的函数原型就是
    DWORD ReAllocAddr(DWORD dwAddr) ;其中参数是要重定位的地址

    ; 这里保存的就是宿主程序的入口点
    00470015 8DB8 80000000 LEA EDI, DWORD PTR DS:[EAX+80]

    ; 指向病毒的导入表
    0047001B 894424 60 MOV DWORD PTR SS:[ESP+60], EAX
    0047001F 894C24 2C MOV DWORD PTR SS:[ESP+2C], ECX
    00470023 8B09 MOV ECX, DWORD PTR DS:[ECX]

    ; ESI指向病毒导入表,后面程序会频繁用到
    00470025 8BF0 MOV ESI, EAX
    00470027 8B07 MOV EAX, DWORD PTR DS:[EDI]
    00470029 83C4 04 ADD ESP, 4
    0047002C 85C9 TEST ECX, ECX
    0047002E 894C24 24 MOV DWORD PTR SS:[ESP+24], ECX
    00470032 897C24 20 MOV DWORD PTR SS:[ESP+20], EDI

    ; 得到原程序入口
    00470036 894424 1C MOV DWORD PTR SS:[ESP+1C], EAX
    0047003A 74 0A JE SHORT QQLiveUp.00470046
    0047003C 8B4C24 64 MOV ECX, DWORD PTR SS:[ESP+64]
    00470040 894C24 08 MOV DWORD PTR SS:[ESP+8], ECX
    00470044 EB 19 JMP SHORT QQLiveUp.0047005F

    ; 重定位到病毒入口点
    00470046 68 30124000 PUSH QQLiveUp.00401230
    0047004B E8 30020000 CALL QQLiveUp.00470280

    ; 保存了当前节的VirtualAddress
    00470050 8B8E 88000000 MOV ECX, DWORD PTR DS:[ESI+88]
    00470056 83C4 04 ADD ESP, 4

    ; 得到程序的基址BaseAddress
    00470059 2BC1 SUB EAX, ECX
    0047005B 894424 08 MOV DWORD PTR SS:[ESP+8], EAX

    ;用宿主的基址加上宿主入口的RVA得到宿主程序的入口地址(VirtualAddress)
    ;病毒执行完后将跳回该地址
    0047005F 8B07 MOV EAX, DWORD PTR DS:[EDI]
    00470061 8B5424 08 MOV EDX, DWORD PTR SS:[ESP+8]
    00470065 8B8E 38010000 MOV ECX, DWORD PTR DS:[ESI+138]
    0047006B 03C2 ADD EAX, EDX
    0047006D 85C9 TEST ECX, ECX
    0047006F 894424 2C MOV DWORD PTR SS:[ESP+2C], EAX

    ;载入kernel32.dll和user32.dll
    ;动态获取病毒需要的API地址
    ;但是病毒只用到了WinExec
    ; 获取CreateFile的地址(其他函数的获取过程和下面的代码一样,故略去)
    0047009D 8D8E 90000000 LEA ECX, DWORD PTR DS:[ESI+90]
    004700A3 51 PUSH ECX
    004700A4 57 PUSH EDI
    004700A5 FFD3 CALL NEAR EBX

    下面的代码的作用就是模拟系统Loader,获取函数地址写入IAT中

    ; 得到宿主程序的IMAGE_IMPORT_DESCRIPTOR
    IMAGE_IMPORT_DESCRIPTOR的结构如下:

    typedef struct _IMAGE_IMPORT_DESCRIPTOR{
    union { //OFFSET 0
    DWORD Characteristics ;
    DWORD OriginalFirstThunk ;
    };
    DWORD TimeDateStamp ; //OFFSET 0x4
    DWORD ForwarderChain ; //OFFSET 0x8
    DWORD Name ; //OFFSET 0xC
    DWORD FirstThunk ; //OFFSET 0x10
    } IMAGE_IMPORT_DESCRIPTOR ;

    ;指向宿主的IMAGE_IMPORT_DESCRIPTOR
    00470117 8B5424 10 MOV EDX, DWORD PTR SS:[ESP+10]
    0047011B 894424 60 MOV DWORD PTR SS:[ESP+60], EAX
    0047011F 8BBE 84000000 MOV EDI, DWORD PTR DS:[ESI+84]
    00470125 03FA ADD EDI, EDX
    00470127 897C24 18 MOV DWORD PTR SS:[ESP+18], EDI
    ;得到IMAGE_IMPORT_DESCRIPTOR的Name,也就是DLL的名字的RVA
    0047012B 8B47 0C MOV EAX, DWORD PTR DS:[EDI+C] ; Name
    0047012E 85C0 TEST EAX, EAX
    00470130 0F84 98000000 JE QQLiveUp.004701CE
    00470136 EB 04 JMP SHORT QQLiveUp.0047013C
    00470138 8B6C24 1C MOV EBP, DWORD PTR SS:[ESP+1C]
    0047013C 8B0F MOV ECX, DWORD PTR DS:[EDI]

    ;得到IMAGE_IMPORT_DESCRIPTOR的FirstThunk
    0047013E 8B57 10 MOV EDX, DWORD PTR DS:[EDI+10]
    00470141 85C9 TEST ECX, ECX
    00470143 894C24 14 MOV DWORD PTR SS:[ESP+14], ECX
    00470147 895424 20 MOV DWORD PTR SS:[ESP+20], EDX
    0047014B 75 04 JNZ SHORT QQLiveUp.00470151
    0047014D 895424 14 MOV DWORD PTR SS:[ESP+14], EDX

    ;载入IMAGE_IMPORT_DESCRIPTOR中指定的DLL
    00470151 8B4C24 10 MOV ECX, DWORD PTR SS:[ESP+10]
    00470155 03C1 ADD EAX, ECX
    00470157 50 PUSH EAX
    00470158 FFD5 CALL NEAR EBP ; 调用kernel32.LoadLibraryA
    0047015A 8BE8 MOV EBP, EAX
    0047015C 85ED TEST EBP, EBP
    0047015E 75 05 JNZ SHORT QQLiveUp.00470165
    00470160 50 PUSH EAX
    00470161 FF5424 5C CALL NEAR DWORD PTR SS:[ESP+5C]

    ;得到IMAGE_IMPORT_DESCRIPTOR的OriginalFirstThunk的地址
    00470165 8B4C24 10 MOV ECX, DWORD PTR SS:[ESP+10] ; BaseAddress
    00470169 8B5424 14 MOV EDX, DWORD PTR SS:[ESP+14] ; OriginalFirstThunk
    0047016D 8D040A LEA EAX, DWORD PTR DS:[EDX+ECX]
    00470170 8B140A MOV EDX, DWORD PTR DS:[EDX+ECX]
    00470173 85D2 TEST EDX, EDX
    00470175 74 45 JE SHORT QQLiveUp.004701BC

    ; 得到IAT的地址
    00470177 8BF8 MOV EDI, EAX
    00470179 8B4424 20 MOV EAX, DWORD PTR SS:[ESP+20]
    0047017D 03C1 ADD EAX, ECX
    0047017F 894424 14 MOV DWORD PTR SS:[ESP+14], EAX
    00470183 EB 04 JMP SHORT QQLiveUp.00470189
    00470185 8B4C24 10 MOV ECX, DWORD PTR SS:[ESP+10]

    ;是以序号导入还是以名字导入
    00470189 8B07 MOV EAX, DWORD PTR DS:[EDI]
    0047018B A9 00000080 TEST EAX, 80000000
    00470190 74 08 JE SHORT QQLiveUp.0047019A

    ; 以序号导入
    00470192 25 FFFF0000 AND EAX, 0FFFF
    00470197 50 PUSH EAX
    00470198 EB 05 JMP SHORT QQLiveUp.0047019F

    ; 以名字导入
    0047019A 8D4C08 02 LEA ECX, DWORD PTR DS:[EAX+ECX+2]
    0047019E 51 PUSH ECX

    ;加载DLL
    0047019F 55 PUSH EBP
    004701A0 FFD3 CALL NEAR EBX ; 调用kernel32.GetProcAddress

    ;把上面获取的函数地址写入宿主的IAT中(也就是FirstThunk指向的数组)
    004701A2 83C7 04 ADD EDI, 4
    004701A5 8B4C24 14 MOV ECX, DWORD PTR SS:[ESP+14]
    004701A9 8901 MOV DWORD PTR DS:[ECX], EAX
    004701AB 8B07 MOV EAX, DWORD PTR DS:[EDI]
    004701AD 83C1 04 ADD ECX, 4
    004701B0 85C0 TEST EAX, EAX
    004701B2 894C24 14 MOV DWORD PTR SS:[ESP+14], ECX
    004701B6 ^75 CD JNZ SHORT QQLiveUp.00470185

    ; 指向下一个IMAGE_IMPORT_DESCRIPTOR
    004701B8 8B7C24 18 MOV EDI, DWORD PTR SS:[ESP+18]
    004701BC 8B47 20 MOV EAX, DWORD PTR DS:[EDI+20]
    004701BF 83C7 14 ADD EDI, 14
    004701C2 85C0 TEST EAX, EAX
    004701C4 897C24 18 MOV DWORD PTR SS:[ESP+18], EDI
    004701C8 ^0F85 6AFFFFFF JNZ QQLiveUp.00470138

    ;执行病毒程序,由于我手头上没有该程序,因此没有分析
    ;可以猜测这个svchost.exe就是病毒的主程序,并向其他可执行文件插入感染代码
    0047022F 51 PUSH ECX ;C:\WINDOWS\system32\IME\svchost.exe
    00470230 FF50 24 CALL NEAR DWORD PTR DS:[EAX+24] ;调用WinExec
    00470233 B8 01000000 MOV EAX, 1
    00470238 C3 RETN

    ;返回到宿主文件入口
    0047020A 51 PUSH ECX
    0047020B 8B4C24 68 MOV ECX, DWORD PTR SS:[ESP+68]
    0047020F 52 PUSH EDX
    00470210 51 PUSH ECX
    00470211 FFD0 CALL NEAR EAX ; 返回到宿主文件入口


    收藏到:Del.icio.us