無聊的時候看電影,一般用pps的人不少,但是對于只有2G內(nèi)存的本本來講,任何程序占用多余的內(nèi)存,都是屬于奢侈的事情,所以這次對pps的進程分析了一下,啟動pps只有一個主進程[PPStream.exe],在看電影的過程中,會多啟動一個進程[PPSAP.exe],最受不了的就是,pps退出后,PPSAP進程一直霸占著內(nèi)存,不釋放,人家不釋放,咱得動點邪惡的念頭.
描述:
ppstream每次啟動都會另開一個進程“網(wǎng)絡(luò)加速器”(ppsap.exe) ,
(1) 每次開機都會自動運行(可手動禁止),
(2) 退出ppstream之后會繼續(xù)存在,
(3) 可手動在任務(wù)管理器里結(jié)束,
(4) 自動訪問網(wǎng)絡(luò)。也就是說,即使你退出ppstream了,你的電腦還在為其他觀看者提供網(wǎng)絡(luò)流量。占用一定帶寬 。
以上描述來源百度百科,可以用網(wǎng)絡(luò)流量監(jiān)控軟件,試試,退出后該進程是否還會上傳數(shù)據(jù),
1:占內(nèi)存
2:占帶寬
這次diy的目的是,在退出PPStream.exe的時候,也把ppsap.exe進程干掉,
為了簡寫代碼,用PostMessage來關(guān)閉該進程.
PostMessage 函數(shù)說明:
函數(shù)功能:該函數(shù)將一個消息放入(寄送)到與指定窗口創(chuàng)建的線程相聯(lián)系消息隊列里,不等待線程處理消息就返回,是異步消息模式。消息隊列里的消息通過調(diào)用GetMessage和PeekMessage取得。
函數(shù)原型:B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
參數(shù)
hWnd:其窗口程序接收消息的窗口的句柄?扇∮刑囟êx的兩個值:
HWND_BROADCAST:消息被寄送到系統(tǒng)的所有頂層窗口,包括無效或不可見的非自身擁有的窗口、被覆蓋的窗口和彈出式窗口。消息不被寄送到子窗口。
NULL:此函數(shù)的操作和調(diào)用參數(shù)dwThread設(shè)置為當前線程的標識符PostThreadMessage函數(shù)一樣。
Msg:指定被寄送的消息。
wParam:指定附加的消息特定的信息。
IParam:指定附加的消息特定的信息。
返回值:如果函數(shù)調(diào)用成功,返回非零值:如果函數(shù)調(diào)用失敗,返回值是零。若想獲得更多的錯誤信息,請調(diào)用GetLastError函數(shù)。
為了關(guān)閉該進程,先要獲取到hWnd,
使用FindWindow
HWND FindWindow
(
LPCSTR lpClassName,
LPCSTR lpWindowName
);
lpClassName
指向一個以null結(jié)尾的、用來指定類名的字符串或一個可以確定類名字符串的原子。如果這個參數(shù)是一個原子,那么它必須是一個在調(diào)用此函數(shù)前已經(jīng)通過GlobalAddAtom函數(shù)創(chuàng)建好的全局原子。這個原子(一個16bit的值),必須被放置在lpClassName的低位字節(jié)中,lpClassName的高位字節(jié)置零。
如果該參數(shù)為null時,將會尋找任何與lpWindowName參數(shù)匹配的窗口。
lpWindowName
指向一個以null結(jié)尾的、用來指定窗口名(即窗口標題)的字符串。如果此參數(shù)為NULL,則匹配所有窗口名。
簡單介紹了一下這2個API,開始實戰(zhàn)了,先用FindWindow的lpWindowName ,使用VS自帶的工具,spy++,Ctrl+P快捷鍵,找到ppsap.exe進程,發(fā)現(xiàn)標題為[PPStream 網(wǎng)絡(luò)加速器]
用API大概可以這樣寫
::PostMessage(::FindWindow( NULL, "PPStream 網(wǎng)絡(luò)加速器") ,WM_CLOSE,0,0);
現(xiàn)在最關(guān)鍵的是將這句話翻譯為匯編,并加入到PPStream.exe里面,且在退出的時候走一下剛加的代碼就完成了.
第一,翻譯為匯編,用VC編譯一下.用od載入,把匯編的二進制摳出來就行了
如果熟悉匯編,也可以手動寫
以下用內(nèi)聯(lián)匯編寫,調(diào)試環(huán)境VC6.0
CString tmp;
tmp = "PPStream 網(wǎng)絡(luò)加速器";
HMODULE hMod = LoadLibrary("user32.dll");
FARPROC Find = GetProcAddress(hMod,"FindWindowA");
FARPROC Post = GetProcAddress(hMod,"PostMessageA");
__asm
{
mov ebx,tmp
push ebx
push 0
call Find ;調(diào)用FindWindowA
push 0
push 0
push 16
push eax ;eax是FindWindow返回的結(jié)果
call Post ;調(diào)用PostMessageA
}
FreeLibrary(hMod);
用od載入PPStream.exe,找一段代碼,把對應(yīng)的匯編寫進去,
最關(guān)鍵的問題就是怎么定位FindWindowA.PostMessageA的地址.
使用od的bpx hmemcpy命令,把調(diào)用的api都找出來,看看有沒有FindWindowA.PostMessageA的地址.
如果存在,就不用再找了,幸運的是里面有這2個API地址.
接下來就是,找到退出的地方,一般程序退出使用的ExitProcess
--下面是本機上的
00631610 /E9 F0701100 jmp 00748709 ; ExitProcess //把這里改成上面新加匯編代碼地址,執(zhí)行完P(guān)ostMessage再跳回00631615
00631615 |. |FF75 08 push dword ptr [ebp+8]
00631618 |. |E8 C8FFFFFF call 006315E5
0063161D |. |59 pop ecx
0063161E |. |FF75 08 push dword ptr [ebp+8] ; /ExitCode
00631621 \. |FF15 68937400 call dword ptr [<&KERNEL32.ExitProces>; \ExitProcess
以下代碼是找了一段空白的地址,加入的關(guān)閉ppsap進程功能,注意007486EA
00748709 6A 00 push 0
0074870B 6A 00 push 0
0074870D 6A 10 push 10
0074870F 68 EA867400 push 007486EA //這個值就是存放"PPStream 網(wǎng)絡(luò)加速器",也就是FindWindow的參數(shù)
00748714 6A 00 push 0
00748716 FF15 7C987400 call dword ptr [<&USER32.FindWindowA>>; USER32.FindWindowA
0074871C 50 push eax
0074871D FF15 049A7400 call dword ptr [<&USER32.PostMessageA>; USER32.PostMessageA
00748723 90 nop
00748724 90 nop
00748725 90 nop
00748726 90 nop
00748727 8BFF mov edi, edi //修復一下上面jmp占用的幾個字節(jié).
00748729 55 push ebp
0074872A 8BEC mov ebp, esp
0074872C 90 nop
0074872D 90 nop
0074872E 90 nop
0074872F 90 nop
00748730 90 nop
00748731 90 nop
00748732 90 nop
00748733 90 nop
00748734 90 nop
00748735 90 nop
00748736 90 nop
00748737 ^ E9 D98EEEFF jmp 00631615 //跳回原始ExitProcess的空間....
基本能達到目的了.
在退出pps窗口之后,ppsap進程都會被干掉了.