我的第一篇增加PE檔案功能的文章,獻醜了。 (4千字)

看雪資料發表於2015-11-15

Winamp有個迷你歌詞外掛,可以方便地下載、管理歌詞。但用了總覺得有個地方不順手,就是如果winamp顯示歌曲為“xxx -  無標題 ”時,總是要將後邊的詞去掉才能正常下載。偏偏我的大多數歌曲都是這種情況。於是就向外掛下手了,目標是在搜尋歌詞前自動去掉“ -  無標題”。
經過跟蹤得知winamp是呼叫MiniLyrics.dll,如果搜尋不到歌詞,則彈出對話方塊“不能找到相匹配的歌詞,請您試試用其他歌曲名搜尋!”,開啟中文選單檔案mschs.ini,找到這句,前面的英文是:Can't find any match lyrics, please try other name!
好了,用OD載入winamp,執行,檢視MiniLyrics.dll模組,搜尋Can't find any match lyrics, 設斷點。然後在下載對話方塊中點選“搜尋”按鈕,中斷在OD中。仔細跟蹤找到如下程式碼:
00FF2E40  SUB ESP,100
00FF2E46  PUSH ESI
00FF2E47  PUSH 100
00FF2E4C  LEA EAX,DWORD PTR SS:[ESP+8]
00FF2E50  PUSH EAX
00FF2E51  MOV ESI,ECX
00FF2E53  MOV ECX,DWORD PTR DS:[ESI+4]
00FF2E56  PUSH 44E
00FF2E5B  PUSH ECX
00FF2E5C  CALL DWORD PTR DS:[<&USER32.GetDlgItemTe>; USER32.GetDlgItemTextA
00FF2E62  MOV AL,BYTE PTR SS:[ESP+4]   --->歌曲名
00FF2E66  TEST AL,AL
00FF2E68  JNZ SHORT MiniLyri.00FF2EA0  --->有歌名就跳
00FF2E6A  MOV EDX,DWORD PTR DS:[ESI+4]
00FF2E6D  PUSH 0
00FF2E6F  PUSH 40
00FF2E71  PUSH EDX
00FF2E72  PUSH MiniLyri.010368F0                    ASCII "Please input the song name!"
00FF2E77  MOV ECX,MiniLyri.01043898
00FF2E7C  CALL MiniLyri.00FE96D0
00FF2E81  PUSH EAX
00FF2E82  CALL MiniLyri.00FE7BC0
程式跳到這:
00FF2EA0  PUSH EBX
00FF2EA1  PUSH EBP
00FF2EA2  PUSH EDI
00FF2EA3  PUSH 7F02
00FF2EA8  PUSH 0
00FF2EAA  CALL DWORD PTR DS:[<&USER32.LoadCursorA>>; USER32.LoadCursorA
00FF2EB0  MOV EDI,EAX
00FF2EB2  CALL DWORD PTR DS:[<&USER32.GetCursor>]   USER32.GetCursor
00FF2EB8  MOV EBP,DWORD PTR DS:[<&USER32.SetCursor>; USER32.SetCursor
00FF2EBE  PUSH EDI
00FF2EBF  MOV EBX,EAX
00FF2EC1  CALL EBP
00FF2EC3  PUSH 1
00FF2EC5  LEA ECX,DWORD PTR SS:[ESP+14]
00FF2EC9  PUSH ECX
00FF2ECA  MOV ECX,ESI
00FF2ECC  CALL MiniLyri.00FF2B40
00FF2ED1  TEST EAX,EAX
00FF2ED3  PUSH EBX
00FF2ED4  JNZ SHORT MiniLyri.00FF2F03
00FF2ED6  CALL EBP
00FF2ED8  MOV EDX,DWORD PTR DS:[ESI+4]
00FF2EDB  PUSH 0
00FF2EDD  PUSH 40
00FF2EDF  PUSH EDX
00FF2EE0  PUSH MiniLyri.010368BC                    ASCII "Can't find any match lyrics, please try other name!"
00FF2EE5  MOV ECX,MiniLyri.01043898
00FF2EEA  CALL MiniLyri.00FE96D0

修改如下:
00FF2EA0  JMP MiniLyri.01033490     --->跳到修改的程式碼
00FF2EA5  NOP                       --->補充位元組,下同
00FF2EA6  NOP
00FF2EA7  NOP
跳到這修改:
01033490  PUSHAD                    --->儲存堆疊資料
01033491  MOV EBX,25                --->esp減小了20,故應加回
01033496  MOV AL,BYTE PTR DS:[ESP+EBX]  --->歌曲名第二位元組
0103349A  CMP AL,0                      --->沒有?
0103349C  JE SHORT MiniLyri.010334D0    --->跳到結束
0103349E  INC BL                        
010334A0  CMP AL,20                     --->等於20?(空格)
010334A2  JE SHORT MiniLyri.010334A6    --->進一步判斷
010334A4  JMP SHORT MiniLyri.01033496   --->迴圈
010334A6  MOV AL,BYTE PTR SS:[ESP+EBX]  --->下一位元組
010334A9  INC BL
010334AB  CMP AL,2D                     --->等於2D?即"-"號
010334AD  JE SHORT MiniLyri.010334B1
010334AF  JMP SHORT MiniLyri.01033496
010334B1  MOV AL,BYTE PTR SS:[ESP+EBX]
010334B4  INC BL
010334B6  CMP AL,20
010334B8  JE SHORT MiniLyri.010334BC
010334BA  JMP SHORT MiniLyri.01033496
010334BC  MOV AL,BYTE PTR SS:[ESP+EBX]
010334BF  INC BL
010334C1  CMP AL,20
010334C3  JE SHORT MiniLyri.010334C7
010334C5  JMP SHORT MiniLyri.01033496
010334C7  SUB BL,4                      --->下面不想判斷了,有“ -  "四個位元組就當作無用的,將其置0,先回到第一個空格
010334CA  NOP
010334CB  NOP
010334CC  NOP
010334CD  NOP
010334CE  NOP
010334CF  NOP
010334D0  NOP
010334D1  NOP
010334D2  NOP
010334D3  MOV DWORD PTR SS:[ESP+EBX],0      --->四個位元組置0
010334DA  POPAD                             --->恢復堆疊資料
010334DB  PUSH EBX                    --->恢復原始碼,下同
010334DC  PUSH EBP
010334DD  PUSH EDI
010334DE  PUSH 7F02
010334E3  JMP MiniLyri.00FF2EA8       --->返回原程式繼續執行


再次執行,OK!
首次用匯編程式碼修改PE功能,花了5個多小時,中間走了些彎路,真的好累!


--------------------------------------------------------------------------------

標 題:順便帖一下讓winamp工作列滾動文字正常顯示中文 (1千字)
發信人:lzqgj  
時 間:2003-08-17 23:26:06
詳細資訊:



winamp工作列可以滾動顯示歌名,但如果是中文,將會時而出現亂碼,因為中文是雙位元組,而winamp並沒有考慮,仍當作單位元組處理。當滾過第一位元組後,第二位元組就無法正常顯示。
用OD載入winamp,下斷點:setwindowtexta,中斷後回到這裡:
0042EE53  LEA EAX,DWORD PTR [EBP-1000]    --->[EBP-1000]為工作列中要顯示的文字
0042EE59  PUSH EAX                        
0042EE5A  PUSH DWORD PTR DS:[453320]      --->HWnd
0042EE60  CALL DWORD PTR DS:[<&USER32.SetWindo>; \SetWindowTextA
向上分析文字是怎麼滾動的:
0042ED40  PUSH ESI                             --->文字  
0042ED41  STOS BYTE PTR ES:[EDI]               
0042ED42  CALL             --->長度
0042ED47  POP ECX
0042ED48  MOV ECX,DWORD PTR DS:[451248]        --->重要:取第幾位元組的記數器
0042ED4E  CMP ECX,EAX
0042ED50  JGE SHORT Winamp.0042EDA9            --->大於就跳,計數器重新置0
0042ED52  LEA EAX,DWORD PTR DS:[ECX+4538C0]    --->[4538C0]中放置完整的文字
0042ED58  PUSH EAX                             
0042ED59  LEA EAX,DWORD PTR SS:[EBP-1000]      
0042ED5F  PUSH EAX                             
0042ED60  CALL             --->取得文字複製到[EBP-1000]中
下略。
明顯程式用[451248]記憶取到第幾位數,然後取得文字複製到[EBP-1000]中讓工作列顯示,只要判斷取得的第一個文字是否中文,是則將計數器加1,就可跳過該中文的第二位元組。

修改程式如下:
0042EE53  JMP Winamp.0043D4E0        --->在工作列顯示前先處理文字
0043D4E0  MOV AL,BYTE PTR SS:[EBP-1000]   --->取第一位元組
0043D4E6  CMP AL,9F                  --->中文一般大於9F?我猜的
0043D4E8  JB SHORT Winamp.0043D4F0   --->是則跳
0043D4EA  INC DWORD PTR DS:[451248]  --->計數器加1
0043D4F0  LEA EAX,DWORD PTR SS:[EBP-1000]   --->恢復原始碼
0043D4F6  JMP Winamp.0042EE59        --->回原程式繼續執行   看雪學院技術論壇(www.pediy.com) 並保持文章的完整性! 


--------------------------------------------------------------------------------

相關文章