VB進程注入代碼
前段時間在網上搜遠線程代碼,全是VC和Delphi的,看了很多POST都說VB做不了。真的這樣嗎?
不,仔細研究了網上流傳的VC版的dll注入代碼後,先用VC做了個,然後翻譯成VB的,中間經過不少曲折(我太菜,高手別笑我啊),現將經驗寫出來,供和我一樣的新手參考,如有不對之處還望高手指出。
首先我們要寫一個dll供注入,目的程式就選“記事本”好了(notepad.exe)
因為沒有裝CompileController之類插件的VB環境只能寫ActiveX Dll,所以dll就用vc寫一個,其實是從網上抄來的啦,嘿嘿,代碼如下:
test.cpp:
#include “stdafx.h“
#include “test.h“
#include
BOOL APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID lpReserved)
{
●CSOL木馬網站●[64] ;
switch ( reason )
{
case DLL_PROCESS_ATTACH:
{
_itoa ( GetCurrentProcessId(), szProcessId, 10 );
MessageBox ( NULL, szProcessId, “RemoteDLL“, MB_OK );
}
default:
return TRUE;
}
}
//用嚮導新建的一個簡單dll,添加以上代碼,作用是在dll注入以後報出自己的“門牌號”便於驗證
然後編譯,把test.dll放到C:下麵
打開vb6新建一個標準exe
添加一個標準模組,添加以下代碼:
Option Explicit
Public Const PROCESS_VM_READ = &H10
Public Const TH32CS_SNAPPROCESS = &H2
Public Const MEM_COMMIT = 4096
Public Const PAGE_READWRITE = 4
Public Const PROCESS_CREATE_THREAD = (&H2)
Public Const PROCESS_VM_OPERATION = (&H8)
Public Const PROCESS_VM_WRITE = (&H20)
’Public Declare Function ReadProcessMemory Lib “kernel32“ (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByVal lpBuffer As String, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
’Public Declare Function GetLastError Lib “kernel32“ () As Long
Public Declare Function VirtualAllocEx Lib “kernel32“ (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Public Declare Function WriteProcessMemory Lib “kernel32“ (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByVal lpBuffer As String, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Public Declare Function GetProcAddress Lib “kernel32“ (ByVal hModule As Long, ByVal lpProcName As String) As Long
Public Declare Function GetModuleHandle Lib “kernel32“ Alias “GetModuleHandleA“ (ByVal lpModuleName As String) As Long
Public Declare Function Process32First Lib “kernel32“ (ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long
Public Declare Function CreateToolhelp32Snapshot Lib “kernel32“ (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
Public Declare Function CreateRemoteThread Lib “kernel32“ (ByVal hProcess As Long, ByVal lpThreadAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, ByVal lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
Public Declare Function OpenProcess Lib “kernel32“ (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Public Declare Function Process32Next Lib “kernel32“ (ByVal hSapshot As Long, lppe As PROCESSENTRY32) As Long
Public Declare Function CloseHandle Lib “kernel32“ (ByVal hObject As Long) As Long
Public Type PROCESSENTRY32
dwSize As Long
cntUseage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
swFlags As Long
szExeFile As String * 1024
End Type
雙擊Form1表單,把代碼改成下面的樣子:
Option Explicit
Public Sub EnumAndInject()
Dim MySnapHandle As Long
Dim ProcessInfo As PROCESSENTRY32
Dim MyRemoteProcessId As Long
Dim MyDllFileLength As Long
Dim MyDllFileBuffer As Long
Dim MyReturn As Long
Dim MyStartAddr As Long
Dim MyResult As Long
Dim temp As Long
Dim DllFileName As String
MySnapHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
ProcessInfo.dwSize = Len(ProcessInfo)
If Process32First(MySnapHandle, ProcessInfo) <> 0 Then
Do
If InStr(ProcessInfo.szExeFile, “notepad.exe“) > 0 Then
’遍曆進程,查找notepad.exe
MyRemoteProcessId = OpenProcess(PROCESS_CREATE_THREAD + PROCESS_VM_OPERATION + PROCESS_VM_WRITE + PROCESS_VM_READ, False, ProcessInfo.th32ProcessID)
’打開進程獲得notepad的控制碼供後面的操作使用
DllFileName = “c:\test.dll“
MyDllFileLength = Len(DllFileName)+1
’學過C語言的朋友應該知道字串最後要一個ASCII 0標誌結尾,所以要加1
MyDllFileBuffer = VirtualAllocEx(MyRemoteProcessId, 0, MyDllFileLength, MEM_COMMIT, PAGE_READWRITE)
’在指定進程堨蚑苳@塊記憶體區域出來供我們存放字串“c:\test.dll“
’傳string給api時,byval byref有區別,應該使用byval,這樣會傳給api一個標準的C字元指標,不能byref,否則函數調用沒問題
’但是起不到預期效果,VirtualAllocEx返回的是申請到的記憶體位址值.
MyReturn = WriteProcessMemory(MyRemoteProcessId, MyDllFileBuffer, DllFileName, MyDllFileLength, temp)
’向剛才申請的記憶體中寫入dll檔路徑字串
’順便說一下,很多api流覽器上的api聲明都是錯的,包括VB6自帶的也不例外,writeprocessmemory第二個參數要的是
’lpBaseAddress 但是這個值不能傳址得到,如果你按byref傳址,實際上傳的是MyDllFileBuffer變數的位址,而不是它堶惘s放的那個數字
’上面說了MyDllFileBuffer的數值才是WriteProcessMemory要的位址,所以聲明API的時候一定要byval,大家知道空著不寫就是默認byref
’下面還有幾處不該傳址的參數,只要搞清楚API函數要的到底是什麼值才可以確定到底傳值還是傳址,API流覽器僅能供參考,還是要仔細閱讀MSDN
MyStartAddr = GetProcAddress(GetModuleHandle(“Kernel32“), “LoadLibraryA“)
’獲取loadlibrary函數的位址,這個函數可以載入指定的dll檔,那他的參數呢?就是我們剛才在notepad.exe進程媦g入的“c:\test.dll“
’不過還得讓CreateRemoteThread告訴他.另外簡單的說一下windows下應用程式的記憶體管理,我也不很懂,呵呵,win32下的應用程式
’的記憶體區域是隔開的,每個程式有自己的一塊記憶體不能直接訪問別的程式的記憶體區,當然,這婼掍峈煽X個系統函數有訪問別的程式記憶體區域的特權
’而且每個應用程式的記憶體區域都映射到系統記憶體區域,也就是說在這GetProcAddress得到的VB程式LoadLibraryA函數的入口位址和
’notepad程式堛LoadLibraryA函數位址是一致的(映射的作用),所以不必擔心.另外在VB寫的程式
’要使用LoadLibraryA,notepad不是用vc寫的嗎?要注意根notepad沒關係,我們現在是在自己的VB程式堶惕LoadLibraryA函數的入口.
’還有要注意函數大小寫,api函數和vb不一樣的。
MyResult = CreateRemoteThread(MyRemoteProcessId, 0, 0, MyStartAddr, MyDllFileBuffer, 0, temp)
’好了,現在該讓LoadLibrary載入“c:\test.dll“吧,現在CreateRemoteThread做的就是在notepad進程中把控制權轉到LoadLibraryA的入口
’然後把notepad記憶體區域中的“c:\test.dll“字串當作參數傳給LoadLibraryA。現在我們的dll檔就在notepad程式中運行了
’dll被注入notepad.exe以後會主動彈出對話方塊顯示出notepad.exe的進程ID,表明注入成功.
End If
Loop While Process32Next(MySnapHandle, ProcessInfo) <> 0
End If
CloseHandle MySnapHandle
End Sub
Private Sub Form_Load()
EnumAndInject
End Sub
以上調用的API詳細參數請參考MSDN,沒它寸步難行,=.=!
|