這幾天研究關於hook api的問題,dll寫了一大堆,倒是略有所得
但是都是用的鉤子進行注入,而且還是全域性鉤子,載入dll時要進行一大堆判斷,不然操作失誤波及一大片程序估計會系統崩潰
所以就試著自己寫了個遠端執行緒植入dll的工具
c#寫的介面呼叫c++寫的dll 完成植入功能
本來打算全部實現都寫到exe程式裡的,但是用了c#以後感覺mfc實在太重了,傷不起
下面貼出dll的**
這是匯出函式的標頭檔案 export.h
#pragma once
#define export_c extern "c" __declspec(dllexport)
export_c bool loaddll(dword, lpctstr);
export_c bool freedll();
export_c int testsum(int a, int b);
c#呼叫的話,是在主類中做靜態宣告
[dllimport("remotethreaddll.dll", entrypoint = "loaddll", charset = charset.unicode)]
public static extern bool loaddll(int pid, string szdllname);
[dllimport("remotethreaddll.dll", entrypoint = "freedll")]
public static extern bool freedll();
[dllimport("remotethreaddll.dll", entrypoint = "testsum")]
public static extern int testsum(int a, int b);
一開始呼叫loaddll函式沒翻譯,不得以又去用c++ win32程式除錯(c#無法跟進dll中除錯。不給力啊),結果一切正常
後來幾經求索,原來匯入函式的時候,匯入設定必須正確
charset = charset.unicode
這個一開始沒有顯示宣告,應為c#和dll都是用的unicode編碼,以為沒有問題
結果c#呼叫傳進去的 包含dll檔案的string是亂碼,汗
callingconvention = callingconvention .stdcal
本來還有這一條的,表示用__stdcall呼叫匯入函式,和c++的標準呼叫約定是一樣的,但是是預設的,所以省略
另外,c#呼叫的c++ dll中 dllmain中不能執行**(非託管**?)不知道為什麼,不過沒有大礙就沒去管它
首先是提公升許可權的函式
bool enableprivilege()
if (!lookupprivilegevalue(null, se_debug_name, &uid))
tp.privilegecount = 1;
tp.privileges[0].luid = uid;
tp.privileges[0].attributes = se_privilege_enabled;
if (!adjusttokenprivileges(htoken, false, &tp, sizeof(token_privileges),
(ptoken_privileges)null, (pdword)null))
return true;
}
以下是dll中的 loaddll函式植入遠端植入dll的**
bool loaddll(dword pid, lpctstr szdllname)
g_pid = pid;
dwsize = (lstrlen(szdllname) + 1) * sizeof(tchar);
g_szdllname = new tchar[lstrlen(szdllname) + 1];
zeromemory(g_szdllname, dwsize);
lstrcpy(g_szdllname, szdllname);
int istep = 0; //已經執行完的步驟
switch(1)
tchar szbreakmsg[32] = {};
//執行過程中斷,掃尾工作
switch(istep)
return false;
}
一開始沒用switch這種格式,結果每執行一步都要判斷是否成功,不成功還要close之前開啟的handle
重複**成片成片,可讀性極差,不由得想到了goto,但是忍住了沒用,後來靈感突現,就想到了這一格式
寫完之後總體感覺看起來不錯,還方便除錯輸出(不用切c++跟步除錯了),不得不說c++的switch特性真是nice啊(vb的話就自動幫你break了。。。)
以下是freedll遠端解除安裝dll的**
bool freedll()
waitforsingleobject(hgetmodthread,infinite);
getexitcodethread(hgetmodthread, (lpdword)&hmodule); //獲取植入dll的基址
closehandle(hgetmodthread);
hfreethread = createremotethread(hprocess, null, 0,
pfnfreelibrary, hmodule, 0, null);
if (hfreethread == null)
waitforsingleobject(hfreethread, infinite);
getexitcodethread(hfreethread, (lpdword)&dwret);
closehandle(hfreethread);
} while (dwret != 0); // 如果getexitcodethread返回非零表明呼叫成功,需要再次呼叫
// 確保 dll 被釋放,否則,表明該dll已被成功釋放
if(bbreakwhile)
break;
g_pid = 0;
g_binjected = false;
delete g_szdllname;
g_szdllname = null;
virtualfreeex(hprocess, lpbase, dwsize, mem_decommit);
closehandle(hprocess);
return true;
} tchar szbreakmsg[32] = {};
//執行中斷,掃尾
switch(istep)
return false;
}
最後是c#的介面程式,幾個控制項一擺,幾行**就完事了,各位可以自己去寫,後面也有整個原始碼的位址
大概是功能就是乙個combo載入系統所有的程序,然後乙個textbox是要傳入的dll檔案(完整路徑)
兩個按鈕,乙個呼叫loaddll,乙個呼叫freedll
關於c#遍歷程序 .net庫里已經有個非常方便的類封裝好了(c++真是苦逼,這個完全要自己寫)
using system.diagnostics;
class***
}}
syspros陣列中儲存了每個程序的資訊,包括程序名(沒有字尾)和pid
原始碼
遠端執行緒DLL注入
在其他程序中,建立乙個新的執行緒來loadlibrarya我們的dll。include include void main 給程序分配記憶體 lpvoid baseaddress char strdllname int len strlen strdllname 1 baseaddress virt...
DLL注入 遠端執行緒
dll include stdafx.h include include include bool apientry dllmain hmodule hmodule,dword ul reason for call,lpvoid lpreserved return true 注入器 include ...
IPC 遠端植入木馬
ipc ipc inter process communication 程序間通訊,是共享 命名管道 的資源,它是為了讓程序間通訊而開放的命名管道,通過提供可信任的使用者名稱和口令,連線雙方可以建立安全的通道並以此通道進行加密資料的交換,從而實現對遠端計算機的訪問 ipc是nt 2000的一項新功能...