1. 程式人生 > 實用技巧 >DLL遠執行緒注入

DLL遠執行緒注入

DLL遠執行緒注入

遠端執行緒建立和記憶體自由分配

遠執行緒注入技術:

強制建立一個目標程序的執行緒:將我們的外掛木馬DLL載入進去

載入

LoadLibrary api函式來處理

強制建立一個目標程序的執行緒

CreateRemoteThread

HANDLE CreateRemoteThread( HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId );

作用:

建立在另一個程序的虛擬空間中執行的執行緒

引數

HANDLE hProcess

要在程序中建立執行緒的程序控制代碼

採用OpenProcess函式來獲取程序控制代碼開啟現有的本地程序物件

HANDLE OpenProcess( DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId );

獲取控制代碼函式引數:

第一個dwDesiredAccess表示程序的訪問許可權,一般採用第一個巨集PROCESS_ALL_ACCESS表示獲得所有的訪問許可權

第二個 BOOL binheritHandle

如果該值為TRUE,則此程序建立的程序將繼承該控制代碼。否則,程序將不會繼承此控制代碼。

這裡我們只是採用注入所以不用繼承

第三個 dwProcessId

要開啟的本地程序的識別符號。也就是程序ID

LPSECURITY_ATTRIBUTES lpThreadAttributes
lpThreadAttributes

指向SECURITY_ATTRIBUTES結構的指標,該 結構為新執行緒指定安全描述符,並確定子程序是否可以繼承返回的控制代碼。如果lpThreadAttributesNULL,則執行緒獲取預設的安全描述符,並且該控制代碼無法繼承。執行緒的預設安全描述符中的訪問控制列表(ACL)來自建立者的主要令牌。

這裡我們不用深究,通常直接採用NULL就好

SIZE_T dwStackSize

堆疊的初始大小,如果引數為0就使用預設值,我們直接採用預設值好了

LPTHREAD_START_ROUTINE lpStartAddress,

指向由執行緒執行的,型別為LPTHREAD_START_ROUTINE的應用程式定義的函式的指標,該指標表示遠端程序中執行緒的起始地址。

也就是說該變數必須為LPTHREAD_START_ROUTINE型別的回撥函式,表示遠端程序中執行緒的起始位置,所以這裡需要賦值為遠端程序的地址。

其實就是需要呼叫的函式的函式指標,只是型別必須用指定的LPTHREAD_START_ROUTINE型別來處理也就是你要插入執行緒的函式的程序函式名。

這個引數的名稱就相當於是一個回撥函式的名字,

LPVOID lpParameter,

指向要傳遞執行緒函式的變數(可以理解為引數)的指標。

也就是執行緒要執行的函式的引數的變數

這裡需要用到VirtualAllocEx()函式

VirtualAllocEx():在指定程序的虛擬地址空間內保留,提交或更改記憶體區域的狀態。該函式將其分配的記憶體初始化為零。因為CreateRemoteThread是建立一個在另一個程序的虛擬地址空間中執行的執行緒

LPVOID VirtualAllocEx( HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect );

分配虛擬記憶體函式

引數

第一個hProcess表示程序的控制代碼

lpAddress表示需要分配的頁面起始地址,一般直接採用NULL用預設值就好。

dwSize:分配記憶體區域的大小分配給要執行的函式的變數,也就是函式引數dll所在路徑的位置。也就是傳的一個檔案路徑的大小

flAllocationType:也就是記憶體的型別,一般情況下采用第一個巨集定義就好了MEM_COMMIT

flProtect:需要指定一個記憶體保護常量來處理, PAGE_READWRITE這個巨集表示即可以讀也可以寫

返回值:

如果申請成功會返回一個虛擬記憶體的基質

申請完一個虛擬記憶體後還要寫入

相當於申明一個變數後給變數賦值

使用WriteProcessMemory函式來處理

BOOL WriteProcessMemory( HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten );

hProcess表示程序控制代碼

lpBaseAddress表示基質的位置也就是用VirtualAllocEX申請的虛擬記憶體地址的基質

lpBuffer表示指向緩衝區的指標,也就是需要寫入的字串的指標

nSize:表示寫入的位元組數

lpNumberOfBytesWritten:

指向變數的指標,該變數接收傳輸到指定程序中的位元組數。此引數是可選的。如果lpNumberOfBytesWrittenNULL,則忽略該引數。一般填NULL,這個沒啥用

DWORD dwCreationFlags,

控制執行緒建立的標誌。

含義
0 執行緒在建立後立即執行。
CREATE_SUSPENDED0x00000004 該執行緒以掛起狀態建立,並且直到呼叫ResumeThread函式後才執行 。
STACK_SIZE_PARAM_IS_A_RESERVATION0x00010000 所述dwStackSize引數指定堆疊的初始保留大小。如果未指定此標誌,則dwStackSize指定提交大小。
LPDWORD lpThreadId

指向接收執行緒識別符號的變數的指標。

如果此引數為NULL,則不返回執行緒識別符號。

程式碼實現:

https://github.com/skrandy/dll_input