C#使用Win32?Api實(shí)現(xiàn)進(jìn)程注入到wechat的過(guò)程
引言
自從上篇使用Flaui實(shí)現(xiàn)微信自動(dòng)化之后,這段時(shí)間便一直在瞎研究微信這方面,目前破解了Window微信的本地的Sqlite數(shù)據(jù)庫(kù),使用Openssl,以及Win32Api來(lái)獲取解密密鑰,今天作為第一張,先簡(jiǎn)單寫(xiě)一下,獲取微信的一些靜態(tài)數(shù)據(jù),以及將自己寫(xiě)的c語(yǔ)言dll通過(guò)Api注入到微信進(jìn)程里面去,最后調(diào)用我們的dll的方法。話不多說(shuō),讓我們開(kāi)始吧。
逆向
靜態(tài)數(shù)據(jù)的話,需要用到的軟件 CE,
全稱是Cheat Engine,圖標(biāo)如下所示。接下來(lái)我們打開(kāi)CE,可以看到左上角有一塊綠色的按鈕,我們點(diǎn)擊按鈕是附加進(jìn)程到CE,然后我們點(diǎn)擊附加微信到CE,在下面的圖中,我們看到已經(jīng)把微信進(jìn)程加載到了CE里面去,然后我們要開(kāi)始獲取靜態(tài)數(shù)據(jù)了。


在獲取靜態(tài)數(shù)據(jù)之前,我們先開(kāi)始講幾個(gè)概念,就是內(nèi)存的概念,我們都知道,在進(jìn)程啟動(dòng)的時(shí)候,操作系統(tǒng)會(huì)給我們的進(jìn)程分配虛擬內(nèi)存,默認(rèn)應(yīng)該是4g,具體是和操作系統(tǒng)位數(shù)也有關(guān)系,然后在運(yùn)行時(shí)也會(huì)動(dòng)態(tài)的分配內(nèi)存空間,我們學(xué)過(guò)計(jì)算機(jī)原理的肯定知道,我們的內(nèi)存存儲(chǔ)結(jié)構(gòu)就像是一個(gè)鏈表或者數(shù)組,我們?cè)诮o這個(gè)進(jìn)程分配內(nèi)存空間的時(shí)候,他的樣子也是是類(lèi)似數(shù)組的這種結(jié)構(gòu),首先假如我們的進(jìn)程現(xiàn)在有一個(gè)主模塊,主模塊里面又有自己的方法,自己的類(lèi),屬性等信息,那分配的這個(gè)主模塊的內(nèi)存就是一個(gè)數(shù)組,然后我們主模塊有一個(gè)基礎(chǔ)地址,你可以將這個(gè)基礎(chǔ)地址看作是這塊內(nèi)存數(shù)組的索引0,而我們主模塊的其他的方法,類(lèi),變量信息,都是在這個(gè)0的索引進(jìn)行移動(dòng)到指定的地址,這個(gè)地址指向我們的內(nèi)存,這個(gè)內(nèi)存存儲(chǔ)著我們要的信息。簡(jiǎn)而言之,就是主模塊是的地址就是索引0,而其他變量信息可能在5,7,9等等,我們就需要判斷從0到5有多少間隔,這個(gè)就叫偏移量,我們通過(guò)屬性或者方法的內(nèi)存地址減去主模塊的地址,這個(gè)就是我們的偏移量,借這個(gè)例子就是5-0就是5,偏移量是5。
然后我們回來(lái),我們加載微信進(jìn)程到了我們的CE之后,在wechat有一個(gè)模塊叫Wechatwin,這個(gè)是window操作系統(tǒng)下的微信用到的主要模塊,我們的和微信相關(guān)的基本都在這里,當(dāng)然不包括一些resource,這個(gè)有一個(gè)專(zhuān)門(mén)的模塊,我們?cè)诖瞬欢噘樖觯晕覀兗偃缫椅覀兊撵o態(tài)數(shù)據(jù),例如微信昵稱,微信號(hào),或者手機(jī)號(hào),所在地區(qū),就需要找到我們的wechatwin的地址,這個(gè)就是這個(gè)模塊的基址,然后我們需要在CE中,檢索字符串找到我們要的數(shù)據(jù),例如昵稱,手機(jī)號(hào)等信息。然后用他的地址減去基址,得到偏移量。從而我們就可以在代碼中獲取到這些信息,接下來(lái),我先帶大家在CE中找到我們想要找的數(shù)據(jù)。
在CE上方右側(cè),有一個(gè)輸入框,我們?cè)谶@里輸入我們需要檢索的信息,支持的格式有byte,string,以及array,double等數(shù)據(jù)類(lèi)型,我們需要找到是string,所以在ValueType那里,我們選擇string。我的微信昵稱是云淡風(fēng)輕,所以在這里搜索云淡風(fēng)輕,可以看到,就檢索出來(lái)我們的昵稱信息了,找到了這么多,這里我們往最下面拉,有一個(gè)綠色開(kāi)頭的,Address是WechatWin的,就是我們要找的地址了,其他的也有的是綠色基于Wechatwin有的不是,有的就需要一個(gè)一個(gè)測(cè)試修改數(shù)據(jù)從而得到驗(yàn)證了。
我們雙擊那條綠色記錄,Wechatwin 將他加入到下面的列表去,代表我們選中的檢測(cè)的內(nèi)存,接下來(lái)我們驗(yàn)證一下,是否是找的正確的,雙擊Value,云淡風(fēng)輕,我們修改我們的Value,將云淡風(fēng)輕,改為good man 點(diǎn)擊ok,可以在下面看到,我們的微信昵稱已經(jīng)同步改為了good Man,說(shuō)明我們找到的是對(duì)的,接下來(lái),我們雙擊Address,



彈出Change address姐妹,我們復(fù)制WechatWin.dll,需要我們找到我們這個(gè)模塊的基址。然后在右邊有一個(gè)Add Address Manually,手動(dòng)添加地址,,我們把復(fù)制的WeChatWin.dll復(fù)制過(guò)去,然后點(diǎn)擊ok,在下面的列表我們就看到了這個(gè)模塊的基址,接下來(lái),我們需要判斷這個(gè)基址和昵稱之間的偏移量,按照我們剛才所說(shuō)的方式計(jì)算,轉(zhuǎn)換16進(jìn)制就是0x7ffd3d668308-0x7ffd39b40000,隨便找一個(gè)16進(jìn)制計(jì)算器,算下來(lái)的結(jié)果就是3B28308,也就是Address里面顯示的那個(gè),實(shí)際上CE已經(jīng)給我們把偏移算出來(lái)了,接下來(lái)按照同樣的方式,去搜索我們的所在地區(qū),以及手機(jī)號(hào),如果有的信息找不到的話,我們選擇我們的昵稱哪一行數(shù)據(jù),右鍵,選擇Browse this Memory region,在內(nèi)存頁(yè)顯示這個(gè)內(nèi)存記錄,然后我們?cè)谂赃吘涂梢钥吹轿覀兊膰?guó)家,以及省份地區(qū)信息了,如果有查看地址,在右側(cè),選擇我們要復(fù)制的記錄,右鍵,有一個(gè)goto Address,然后就導(dǎo)航到了我們的內(nèi)存,然后復(fù)制地址即可。



c#代碼獲取數(shù)據(jù)以及遠(yuǎn)程注入
在上面我們講了,如何使用CE,去獲取我們微信的一些靜態(tài)數(shù)據(jù),接下來(lái),我們就需要使用c#代碼,去實(shí)現(xiàn)我們獲取靜態(tài)數(shù)據(jù),以及最后寫(xiě)的一個(gè)遠(yuǎn)程注入,來(lái)調(diào)用我們寫(xiě)的一個(gè)庫(kù)。首先我們需要用到的有幾個(gè)Api函數(shù),
WaitForSingleObject,等待某個(gè)句柄多長(zhǎng)時(shí)間,在我們創(chuàng)建遠(yuǎn)程線程的時(shí)候需要使用這個(gè)函數(shù)來(lái)等待線程執(zhí)行結(jié)束。參數(shù)是等待的句柄,我們填寫(xiě)我們的線程句柄。
GetProcAddress,需要使用這個(gè)函數(shù)來(lái)調(diào)用kernel32.dll的LoadLibraryA方法,來(lái)加載我們的自己寫(xiě)的dll,因?yàn)樵诿總€(gè)進(jìn)程啟動(dòng)的時(shí)候,都會(huì)去調(diào)用這個(gè)方法來(lái)加載程序所依賴的dll,還有一個(gè)方法是LoadLibraryW,和這個(gè)方法區(qū)別在于不同針對(duì)不同的編碼來(lái)進(jìn)行調(diào)用,W結(jié)尾主要是針對(duì)UNICODE的編碼,A結(jié)尾對(duì)應(yīng)Ascii編碼,所以各位在調(diào)用的時(shí)候根據(jù)自己的編碼去調(diào)用,如果一個(gè)找不到就試試另一個(gè)。
GetModuleHandle,這個(gè)函數(shù)是用來(lái)獲取kernel32.dll,結(jié)合上面的GetProdAddress來(lái)使用。
OpenProcess,這個(gè)方法是根據(jù)指定的PID,對(duì)應(yīng)就是Process類(lèi)的Id,打開(kāi)指定的進(jìn)程,同時(shí)指定以什么權(quán)限打開(kāi)這個(gè)進(jìn)程,參數(shù)是三個(gè),第一個(gè)是權(quán)限,第二個(gè)是返回值是否可以被繼承,返回的進(jìn)程句柄是否可以被繼承,第三個(gè)參數(shù)就是我們的PID。
VirtualAllocEx,給指定的進(jìn)程分配虛擬內(nèi)存,第一個(gè)參數(shù)是進(jìn)程的句柄,OpenProcess返回值,第二個(gè)參數(shù)指定進(jìn)程內(nèi)那個(gè)內(nèi)存地址分配的內(nèi)存,此處我們只是加載dll調(diào)用方法,并不注入到某個(gè)方法或者哪里所以是Intptr.Zero,第三個(gè)參數(shù)是,分配的內(nèi)存長(zhǎng)度,我們加載dll需要dll的路徑,這里就選擇路徑.Length就行,字符串的長(zhǎng)度就可以,第三個(gè)參數(shù)是內(nèi)存分配的一些配置,可選值在后面會(huì)有,此處我們選擇Memory_Commit,第四個(gè)參數(shù)是內(nèi)存權(quán)限相關(guān),內(nèi)存是只讀還是可以讀寫(xiě),以及用來(lái)執(zhí)行代碼或者怎么樣,這里我們選擇可以讀寫(xiě)。
ReadProcessMemory,讀指定進(jìn)程的內(nèi)存,第一個(gè)參數(shù)進(jìn)程句柄,OpenProcess返回值,第二個(gè)參數(shù)是這個(gè)進(jìn)程某個(gè)內(nèi)存的地址,第三個(gè)是數(shù)據(jù)緩沖區(qū),讀取之后的內(nèi)容就在這個(gè)緩沖區(qū),我們讀取這個(gè)緩沖區(qū)就可以拿到數(shù)據(jù),第四就是緩沖區(qū)的長(zhǎng)度,第五個(gè)就是讀取的字節(jié)數(shù)量。
GetLastError,用來(lái)獲取Win32api調(diào)用的時(shí)候的errorcode,錯(cuò)誤編碼,
CloseHandle,關(guān)閉某一個(gè)句柄,關(guān)閉基礎(chǔ),關(guān)閉線程。
WriteProcessMemory,寫(xiě)入內(nèi)存,我們需要將我們的dll地址寫(xiě)入到指定內(nèi)存中去,第一個(gè)參數(shù)進(jìn)程句柄,OpenProcess返回值,第二個(gè)參數(shù),要寫(xiě)入的內(nèi)存地址基址,例如我們后期需要在某個(gè)方法進(jìn)行注入,這塊就需要寫(xiě)入這個(gè)方法的內(nèi)存地址,第三個(gè)參數(shù),寫(xiě)入的byte數(shù)據(jù),第四個(gè)參數(shù)是第三個(gè)參數(shù)的長(zhǎng)度,最后一個(gè)參數(shù)是寫(xiě)入的數(shù)據(jù)數(shù)量。
CreateRemoteThread,在指定的進(jìn)程中創(chuàng)建遠(yuǎn)程線程,第一個(gè)參數(shù) OpenProcess返回值,第二個(gè)參數(shù)是線程安全的一些特性描述,按網(wǎng)上所說(shuō),一般null或者IntPtr.Zero,第三個(gè)參數(shù)設(shè)置線程堆棧大小,默認(rèn)是0,即使用默認(rèn)的大小,第四個(gè)參數(shù)是線程函數(shù)的地址,我們要通過(guò)這個(gè)方法去調(diào)用Kernel32的LoadLibrary方法加載我們的dll,那這個(gè)參數(shù)就填寫(xiě)我們的GetProcAddress返回值,第四個(gè)參數(shù)就是創(chuàng)建這個(gè)線程的參數(shù),就是分配的遠(yuǎn)程內(nèi)存的地址VirtualAllocEx返回值,就是說(shuō)通過(guò)創(chuàng)建遠(yuǎn)程線程來(lái)調(diào)用LoadLibrary方法加載我們寫(xiě)入指定內(nèi)存地址的dll庫(kù),來(lái)實(shí)現(xiàn)注入,是這樣一個(gè)邏輯,第五個(gè)參數(shù)是線程創(chuàng)建的一些參數(shù),是創(chuàng)建后掛起還是直接運(yùn)行等,最后一個(gè)參數(shù)是輸出參數(shù),記錄創(chuàng)建的遠(yuǎn)程線程的ID。
以上是我們所需要用到的所有的Win32Api函數(shù),接下來(lái)我們進(jìn)入代碼階段。
在下面的窗體,窗體會(huì)在加載的時(shí)候就去調(diào)用注入我們的dll,同時(shí)界面在加載的時(shí)候就獲取獲取我們的靜態(tài)信息。我們的dll地址是E盤(pán)下面的一個(gè)dll,這個(gè)Dll使用c語(yǔ)言編寫(xiě)。在啟動(dòng)的時(shí)候我們?nèi)カ@取我們的微信進(jìn)程,拿到的ID,然后去注入我們的Dll,在下面的代碼里,我們判斷是否模塊是WechatWin.dll,如果是,就定義了phone,NickName,Provice,Area等int值,這個(gè)其實(shí)就是我們?cè)贑E拿到的靜態(tài)數(shù)據(jù)的內(nèi)存地址,減去我們的Wechatwin.Dll的出來(lái)的偏移量,然后定義了我們各個(gè)靜態(tài)數(shù)據(jù)的緩沖區(qū),用來(lái)讀取從微信進(jìn)程讀取的內(nèi)存數(shù)據(jù)。然后我們調(diào)用了ReadProcessMemory函數(shù)讀取內(nèi)存,獲取我們需要的靜態(tài)數(shù)據(jù)。然后使用Utf8轉(zhuǎn)為字符串,顯示到界面上。這就是獲取靜態(tài)數(shù)據(jù)的源碼,然后關(guān)閉我們的進(jìn)程句柄,并不是關(guān)閉微信,而是關(guān)閉我們獲取的這個(gè)進(jìn)程句柄。
string dllpath = @"E:\CoreRepos\ConsoleApplication2\x64\Debug\Inject.dll"; var process = Process.GetProcessesByName("wechat").FirstOrDefault();
InjectDll(process.Id, dllpath);
var pid = OpenProcess(ProcessAccessFlags.PROCESS_ALL_ACCESS, false, process.Id);
int bytesRead;
int bytesWritten;
foreach (ProcessModule item in process.Modules)
{
if (item.ModuleName.ToLower() == "WechatWin.dll".ToLower())
{
int phone = 0x3B28248;
int NickName = 0x3b28308;
int provice = 0x3B282A8;
int Area = 0x3B282C8;
var Nickbuffer = new byte[12];
var Phonebuffer = new byte[11];
var proviceBuffer= new byte[12];
var areaBuffer=new byte[12];
ReadProcessMemory(process.Handle, item.BaseAddress + NickName, Nickbuffer, Nickbuffer.Length, out bytesRead);
ReadProcessMemory(process.Handle, item.BaseAddress + phone, Phonebuffer, Phonebuffer.Length, out bytesRead);
ReadProcessMemory(process.Handle, item.BaseAddress + provice, proviceBuffer, proviceBuffer.Length, out bytesRead);
ReadProcessMemory(process.Handle, item.BaseAddress + Area, areaBuffer, areaBuffer.Length, out bytesRead);
var Nickvalue = Encoding.UTF8.GetString(Nickbuffer);
var Phonevalue = Encoding.UTF8.GetString(Phonebuffer);
var Provicevalue = Encoding.UTF8.GetString(proviceBuffer);
var Areavalue = Encoding.UTF8.GetString(areaBuffer);
label1.Text = Nickvalue;
label2.Text = Phonevalue;
label3.Text = Provicevalue;
label4.Text = Areavalue;
var buf = Encoding.UTF8.GetBytes("我是你爹");
CloseHandle(process.Handle);
}
}
然后我們開(kāi)始看看注入DLL的代碼,我們先引入了諸多函數(shù),然后定義了OpenProcess第一個(gè)參數(shù)權(quán)限的枚舉,定義了INFINITE 用來(lái)WaitForSingleObject等待指定的句柄進(jìn)行某些操作的執(zhí)行結(jié)束,當(dāng)然有一些我沒(méi)有定義完整,只定義我們此處需要的,完整的可以參考官網(wǎng)api去進(jìn)行看。在剛進(jìn)入這段代碼,我們調(diào)用OpenProcess指定最高權(quán)限打開(kāi)這個(gè)進(jìn)程,然后獲取我們的dll地址的byte數(shù)組,并將分配內(nèi)存VirtualAllocEx到我們這個(gè)進(jìn)程里面,同時(shí)最后兩個(gè)參數(shù)代表分配內(nèi)存的一些操作,例如內(nèi)存是Memory_Commit,0x1000,以及內(nèi)存是可以讀寫(xiě)的0x04,分配好內(nèi)存之后,我們?nèi)ネ覀兎峙浜玫膬?nèi)存寫(xiě)入我們的dll路徑,調(diào)用WriteProcessMemory方法,傳入進(jìn)程句柄,內(nèi)存地址,寫(xiě)入的數(shù)據(jù)等,在下面GetProcAddress和GetModuleHandle用來(lái)加載kernel32的LoadraryA方法句柄,最后我們調(diào)用了CreateRemoteThread函數(shù)將我們的dll注入到遠(yuǎn)程進(jìn)程中去。
#region 32 api
[DllImport("kernel32.dll", SetLastError = true)]
public static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, int flAllocationType, int flProtect);
[System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory(
IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead
);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(
ProcessAccessFlags dwDesiredAccess,
bool bInheritHandle,
int dwProcessId
);
[DllImport("kernel32.dll")]
static extern uint GetLastError();
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out int lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
// 進(jìn)程訪問(wèn)權(quán)限標(biāo)志位
[Flags]
public enum ProcessAccessFlags : uint
{
PROCESS_ALL_ACCESS = 0x1F0FFF,
PROCESS_CREATE_PROCESS = 0x0080,
PROCESS_QUERY_INFORMATION = 0x0400,
}
const uint INFINITE = 0xFFFFFFFF;
#endregionpublic bool InjectDll(int processId, string dllPath)
{
IntPtr hProcess = OpenProcess(ProcessAccessFlags.PROCESS_ALL_ACCESS, false, processId);
if (hProcess == IntPtr.Zero)
{
Console.WriteLine("打開(kāi)失敗");
return false;
}
byte[] dllBytes = Encoding.UTF8.GetBytes(dllPath); ;
IntPtr remoteMemory = VirtualAllocEx(hProcess, IntPtr.Zero, dllBytes.Length, 0x1000, 0x04);
int bytesWritten;
if (!WriteProcessMemory(hProcess, remoteMemory, dllBytes, dllBytes.Length, out bytesWritten))
{
var ooo = GetLastError();
Console.WriteLine("寫(xiě)入失敗");
return false;
}
IntPtr loadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
var ooaa = GetLastError();
if (loadLibraryAddr == IntPtr.Zero)
{
Console.WriteLine("獲取LoadraryA失敗");
}
// 創(chuàng)建遠(yuǎn)程線程,在目標(biāo)進(jìn)程中調(diào)用 LoadLibraryA 加載 DLL
var hRemoteThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLibraryAddr, remoteMemory, 0, IntPtr.Zero);
var ooaa1 = GetLastError();
if (hRemoteThread == IntPtr.Zero)
{
Console.WriteLine("目標(biāo)進(jìn)程創(chuàng)建遠(yuǎn)程線程失敗");
}
// 等待遠(yuǎn)程線程執(zhí)行完畢
WaitForSingleObject(hRemoteThread, 0xFFFFFFFF);
WaitForSingleObject(hRemoteThread, INFINITE);
CloseHandle(hRemoteThread);
CloseHandle(hProcess);
Console.WriteLine("注入成功");
return true;
}我們看看我寫(xiě)的dll里面是包括了什么內(nèi)容,我們的dll內(nèi)容很簡(jiǎn)單,就是創(chuàng)建一個(gè)txt文件,然后寫(xiě)入一個(gè)數(shù)據(jù)就行,這里需要注意的是,在使用vs創(chuàng)建dll的時(shí)候 選項(xiàng)必須是選擇的是動(dòng)態(tài)鏈接庫(kù),這樣才有DLLMain方法,這樣在調(diào)用LoadraryA方法的時(shí)候才會(huì)調(diào)用我們的dll,自動(dòng)調(diào)用DLLMain方法,同時(shí)里面還有一個(gè)switch case語(yǔ)句是進(jìn)程加載線程加載,以及線程卸載,進(jìn)程卸載的判斷 我們可以在這里去去一些我們的邏輯判斷,此處我并沒(méi)有寫(xiě),只是在外層創(chuàng)建了一個(gè)文件夾,接下來(lái)運(yùn)行一下我們的winform,看看有沒(méi)有獲取到靜態(tài)數(shù)據(jù),以及將我們的dll注入進(jìn)去。馬賽克手機(jī)號(hào)。


可以看到我們啟動(dòng)了界面之后,查看我們的Process.Modules,可以看到我們注入的Inject.dll,那我們看看有沒(méi)有創(chuàng)建txt呢。在下面可以看到,我們已經(jīng)成功注入到微信進(jìn)程并且創(chuàng)建了一個(gè)example.txt,并且寫(xiě)入的內(nèi)容和上圖定義的內(nèi)容是一致的,到此,我們將我們dll注入到了微信進(jìn)程中去了。


結(jié)語(yǔ)
在上面我們講了一些如何找到靜態(tài)數(shù)據(jù),以及根據(jù)基址,偏移量在進(jìn)程啟動(dòng)的時(shí)候找到我們想要的數(shù)據(jù),并且將我們的dll成功注入到進(jìn)程里面去,在后面,我可能還會(huì)在深入研究一下逆向,到時(shí)候會(huì)繼續(xù)發(fā)文,感興趣的朋友可以關(guān)注一波,同時(shí),近期,還破解了微信Sqlite本地?cái)?shù)據(jù)庫(kù)獲取了一些內(nèi)容,下面是獲取的數(shù)據(jù)內(nèi)容,這個(gè)我應(yīng)該不會(huì)開(kāi)源,但是會(huì)有一個(gè)c語(yǔ)言的寫(xiě)的解密demo開(kāi)源,同時(shí)可能會(huì)分享一部分c#獲取解密密鑰的代碼,同時(shí)也需要一些逆向的知識(shí),win32api,這個(gè)東西由于涉及個(gè)人隱私,所以我尚不確定是否開(kāi)源,因?yàn)榇嬖谟械娜巳绻麙祚R,可以竊取他人的隱私,所以后續(xù)再說(shuō),同時(shí)在寫(xiě)的,講的不對(duì)的地方,歡迎各位大佬指正。

到此這篇關(guān)于C#使用Win32 Api實(shí)現(xiàn)進(jìn)程注入到wechat的文章就介紹到這了,更多相關(guān)c#使用Win32 Api內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談C# 非模式窗體show()和模式窗體showdialog()的區(qū)別
下面小編就為大家?guī)?lái)一篇淺談C# 非模式窗體show()和模式窗體showdialog()的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07
Winform界面中實(shí)現(xiàn)通用工具欄按鈕的事件處理方法
下面小編就為大家分享一篇Winform界面中實(shí)現(xiàn)通用工具欄按鈕的事件處理方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助2017-11-11
C#實(shí)現(xiàn)強(qiáng)制關(guān)閉當(dāng)前程序進(jìn)程
這篇文章主要介紹了C#實(shí)現(xiàn)強(qiáng)制關(guān)閉當(dāng)前程序進(jìn)程,本文直接給出實(shí)現(xiàn)代碼,可以實(shí)現(xiàn)完全Kill掉不留痕跡,需要的朋友可以參考下2015-06-06
DevExpress之ChartControl實(shí)現(xiàn)餅狀圖百分比演示實(shí)例
這篇文章主要介紹了DevExpress之ChartControl實(shí)現(xiàn)餅狀圖百分比演示的方法,實(shí)例講述了窗體與圖形繪制函數(shù)的用法,需要的朋友可以參考下2014-10-10
C#操作LINQ to SQL組件進(jìn)行數(shù)據(jù)庫(kù)建模的基本教程
這篇文章主要介紹了C#操作LINQ to SQL組件進(jìn)行數(shù)據(jù)庫(kù)建模的基本教程,LINQ to SQL被集成在.NET框架之中,需要的朋友可以參考下2016-03-03

