日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

redistemplate注入为null_Windows DLL 注入技术

發(fā)布時(shí)間:2023/12/13 windows 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redistemplate注入为null_Windows DLL 注入技术 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Windows DLL 注入技術(shù)

本文主要介紹四種常見的 Windows DLL 注入技術(shù)。

分別為全局鉤子、遠(yuǎn)線程鉤子、突破 SESSION 0 隔離的遠(yuǎn)線程注入和 APC 注入。

全局鉤子注入

Windows 中大部分應(yīng)用是基于 Windows 的消息機(jī)制,Windows提供截獲這些消息的鉤子函數(shù)。

根據(jù)鉤子作用的不同范圍,鉤子可以被分為全局和局部鉤子。局部鉤子是針對某個(gè)線程的,全局鉤子是只要有使用消息機(jī)制的應(yīng)用。接下來我們主要來看下利用SetWindowsHookEx實(shí)現(xiàn)全局鉤子。

SetWindowsHookEx函數(shù)介紹

HHOOK?SetWindowsHookEx(int???????idHook,?//?要安裝的鉤子程序的類型
??HOOKPROC??lpfn,?//?指向鉤子函數(shù)的指針
??HINSTANCE?hmod,?//?指向鉤子過程的DLL的句柄
??DWORD?????dwThreadId?//?與鉤子進(jìn)程關(guān)聯(lián)的線程標(biāo)識(shí)符
);
//?具體詳細(xì)介紹可以查閱msdn文檔,里面有更為詳細(xì)的介紹

實(shí)現(xiàn)過程

首先我們需要?jiǎng)?chuàng)建一個(gè)windowsHookDll DLL,這個(gè)DLL在安裝全局鉤子后只要系統(tǒng)中的其他進(jìn)程接收到可以發(fā)出鉤子的消息,這個(gè)DLL就會(huì)被加載到此進(jìn)程的地址空間中。這樣便實(shí)現(xiàn)了Dll注入。

具體實(shí)現(xiàn)代碼如下:

#include?"Hook.h"
#include?

extern?HMODULE?g_hDllModule;
//?共享內(nèi)存
#pragma?data_seg("mydata")?
HHOOK?g_hHook?=?NULL;
#pragma?data_seg()
#pragma?comment(linker,?"/SECTION:mydata,RWS")


//?鉤子回調(diào)函數(shù)
LRESULT?GetMsgProc(int?code,
?WPARAM?wParam,
?LPARAM?lParam){
?return?::CallNextHookEx(g_hHook,?code,?wParam,?lParam);
}

//?注冊鉤子
BOOL?SetHook(){
?g_hHook?=?SetWindowsHookEx(WH_GETMESSAGE,?(HOOKPROC)GetMsgProc,?g_hDllModule,?0);?//使用WH_GETMESSAGE?確保DLL能夠注入所有的進(jìn)程
?if?(g_hHook)
?{
??return?TRUE;
?}
?return?FALSE;
}

//?卸載鉤子
BOOL?UnSetHook(){
?if?(g_hHook)
?{
??UnhookWindowsHookEx(g_hHook);
?}
?return?TRUE;
}

試驗(yàn)結(jié)果

新建TestHook.exe程序,首先加載windowsHookDll.dll導(dǎo)出函數(shù)SetHook并調(diào)用。在注冊成功后用ProcessExplorer.exe察看explorer.exe中的加載情況。

windowsHookDll成功被explorer.exe加載

如果想要卸載可調(diào)用函數(shù)UnSetHook,執(zhí)行完成后再觀察explorer.exe是否加載了windowsHookDll.dll。

遠(yuǎn)線程注入

遠(yuǎn)線程注入是指一個(gè)進(jìn)程在另一個(gè)進(jìn)程中創(chuàng)建線程的技術(shù)。主要是利用LoadLibrary在所有進(jìn)程空間中的地址是一樣,進(jìn)程在另一個(gè)進(jìn)程中創(chuàng)建線程時(shí)傳入LoadLibrary的地址和我們要注入的DLL的路徑,這樣在另一個(gè)進(jìn)程中就能通過LoadLibray加載DLL到進(jìn)程空間中。

說起來簡單,但是實(shí)現(xiàn)起來卻有幾大難點(diǎn)需要注意的。

  • 如何將DLL路徑傳給另一個(gè)進(jìn)程,因?yàn)檫M(jìn)程之間是相互隔離的,所以我們要在我們要注入的進(jìn)程中申請內(nèi)存。
  • 需要對打開的進(jìn)程進(jìn)行提權(quán),這就要求我們的注入程序要有管理員以上的權(quán)限。

函數(shù)介紹

HANDLE?OpenProcess(
??DWORD?dwDesiredAccess,?//?進(jìn)程訪問權(quán)限
??BOOL??bInheritHandle,?//?子進(jìn)程是否繼承此句柄
??DWORD?dwProcessId?//?要打開的進(jìn)程id
);

//?分配指定進(jìn)程的內(nèi)存
LPVOID?VirtualAllocEx(
??HANDLE?hProcess,?//?進(jìn)程句柄
??LPVOID?lpAddress,?//?要分配內(nèi)存起始地址,為NULL則自動(dòng)分配
??SIZE_T?dwSize,?//?要分配的內(nèi)存大小
??DWORD??flAllocationType,//?內(nèi)存分配類型
??DWORD??flProtect?//?內(nèi)存保護(hù)(讀寫)
);

//?寫入內(nèi)存數(shù)據(jù)
BOOL?WriteProcessMemory(
??HANDLE??hProcess,?//?進(jìn)程句柄
??LPVOID??lpBaseAddress,?//?目標(biāo)進(jìn)程緩沖區(qū)地址
??LPCVOID?lpBuffer,?//?要寫入數(shù)據(jù)的地址
??SIZE_T??nSize,?//?數(shù)據(jù)大小
??SIZE_T??*lpNumberOfBytesWritten?//?寫入數(shù)據(jù)的返回大小,?為NULL則忽略此參數(shù)
);

//?在另一個(gè)進(jìn)程中創(chuàng)建線程
HANDLE?CreateRemoteThread(
??HANDLE?????????????????hProcess,?//?進(jìn)程句柄
??LPSECURITY_ATTRIBUTES??lpThreadAttributes,?//?線程安全描述符
??SIZE_T?????????????????dwStackSize,?//?堆棧的初始大小
??LPTHREAD_START_ROUTINE?lpStartAddress,?//?函數(shù)地址(存在于另一個(gè)進(jìn)程中)
??LPVOID?????????????????lpParameter,?//?函數(shù)的參數(shù)
??DWORD??????????????????dwCreationFlags,?//?線程創(chuàng)建標(biāo)志
??LPDWORD????????????????lpThreadId?//?線程標(biāo)識(shí)符
);

//?詳細(xì)信息可參閱msdn

代碼實(shí)現(xiàn)


/*dwProcessId:?目標(biāo)進(jìn)程的pid
**pszDllFileName:?要注入DLL的路徑
*/
BOOL?CreateRemoteThreadInjectDll(DWORD?dwProcessId,?char?*pszDllFileName){
?HANDLE?hProcess?=?NULL;
?SIZE_T?dwSize?=?0;
?LPVOID?pDllAddr?=?NULL;
?FARPROC?pFuncProcAddr?=?NULL;

?//?打開注入進(jìn)程,獲取進(jìn)程句柄
?hProcess?=?::OpenProcess(PROCESS_ALL_ACCESS,?FALSE,?dwProcessId);
?if?(NULL?==?hProcess)
?{
??EP_ShowError("OpenProcess");
??return?FALSE;
?}
?//?在注入進(jìn)程中申請內(nèi)存
?dwSize?=?1?+?::lstrlenA(pszDllFileName);
?pDllAddr?=?::VirtualAllocEx(hProcess,?NULL,?dwSize,?MEM_COMMIT,?PAGE_READWRITE);
?if?(NULL?==?pDllAddr)
?{
??EP_ShowError("VirtualAllocEx");
??return?FALSE;
?}
?//?向申請的內(nèi)存中寫入數(shù)據(jù)
?if?(FALSE?==?::WriteProcessMemory(hProcess,?pDllAddr,?pszDllFileName,?dwSize,?NULL))
?{
??EP_ShowError("WriteProcessMemory");
??return?FALSE;
?}
?//?獲取LoadLibraryA函數(shù)地址
?pFuncProcAddr?=?::GetProcAddress(::GetModuleHandleA("kernel32.dll"),?"LoadLibraryA");
?if?(NULL?==?pFuncProcAddr)
?{
??EP_ShowError("GetProcAddress_LoadLibraryA");
??return?FALSE;
?}
?//?使用?CreateRemoteThread?創(chuàng)建遠(yuǎn)線程,?實(shí)現(xiàn)?DLL?注入
?HANDLE?hRemoteThread?=?::CreateRemoteThread(hProcess,?NULL,?0,?(LPTHREAD_START_ROUTINE)pFuncProcAddr,?pDllAddr,?0,?NULL);
?if?(NULL?==?hRemoteThread)
?{
??EP_ShowError("CreateRemoteThread");
??return?FALSE;
?}
?//?關(guān)閉句柄
?::CloseHandle(hProcess);

?return?TRUE;
}

試驗(yàn)結(jié)果

注入成功后效果圖在explorer.exe中RemoteThreadDll.dll被正確加載

遠(yuǎn)線程注冊進(jìn)階 突破SESSION 0隔離

在系統(tǒng)普通進(jìn)程中可以使用遠(yuǎn)線程注入DLL,但如果要注入系統(tǒng)服務(wù)則不行,因?yàn)橛蠸ESSION 0隔離。想要突破隔離需要使用ZwCreateThreadEx函數(shù)。這也是和遠(yuǎn)線程注入的區(qū)別。

ZwCreateThreadEx 是未公開的函數(shù),在ntdll.dll中,它的函數(shù)聲明如下:

#ifdef?_WIN64
?typedef?DWORD(WINAPI?*typedef_ZwCreateThreadEx)(
??PHANDLE?ThreadHandle,
??ACCESS_MASK?DesiredAccess,
??LPVOID?ObjectAttributes,
??HANDLE?ProcessHandle,
??LPTHREAD_START_ROUTINE?lpStartAddress,
??LPVOID?lpParameter,
??ULONG?CreateThreadFlags,
??SIZE_T?ZeroBits,
??SIZE_T?StackSize,
??SIZE_T?MaximumStackSize,
??LPVOID?pUnkown);
#else
?typedef?DWORD(WINAPI?*typedef_ZwCreateThreadEx)(
??PHANDLE?ThreadHandle,
??ACCESS_MASK?DesiredAccess,
??LPVOID?ObjectAttributes,
??HANDLE?ProcessHandle,
??LPTHREAD_START_ROUTINE?lpStartAddress,
??LPVOID?lpParameter,
??BOOL?CreateSuspended,
??DWORD?dwStackSize,
??DWORD?dw1,
??DWORD?dw2,
??LPVOID?pUnkown);
#endif

具體實(shí)現(xiàn)代碼:

//?使用?ZwCreateThreadEx?實(shí)現(xiàn)遠(yuǎn)線程注入
BOOL?ZwCreateThreadExInjectDll(DWORD?dwProcessId,?char?*pszDllFileName){
?HANDLE?hProcess?=?NULL;
?SIZE_T?dwSize?=?0;
?LPVOID?pDllAddr?=?NULL;
?FARPROC?pFuncProcAddr?=?NULL;
?HANDLE?hRemoteThread?=?NULL;
?DWORD?dwStatus?=?0;

?//?打開注入進(jìn)程,獲取進(jìn)程句柄
?hProcess?=?::OpenProcess(PROCESS_ALL_ACCESS,?FALSE,?dwProcessId);
?if?(NULL?==?hProcess)
?{
??EP_ShowError("OpenProcess");
??return?FALSE;
?}
?//?在注入進(jìn)程中申請內(nèi)存
?dwSize?=?1?+?::lstrlenA(pszDllFileName);
?pDllAddr?=?::VirtualAllocEx(hProcess,?NULL,?dwSize,?MEM_COMMIT,?PAGE_READWRITE);
?if?(NULL?==?pDllAddr)
?{
??EP_ShowError("VirtualAllocEx");
??return?FALSE;
?}
?//?向申請的內(nèi)存中寫入數(shù)據(jù)
?if?(FALSE?==?::WriteProcessMemory(hProcess,?pDllAddr,?pszDllFileName,?dwSize,?NULL))
?{
??EP_ShowError("WriteProcessMemory");
??return?FALSE;
?}
?//?加載?ntdll.dll
?HMODULE?hNtdllDll?=?::LoadLibraryA("ntdll.dll");
?if?(NULL?==?hNtdllDll)
?{
??EP_ShowError("LoadLirbary");
??return?FALSE;
?}
?//?獲取LoadLibraryA函數(shù)地址
?pFuncProcAddr?=?::GetProcAddress(::GetModuleHandleA("Kernel32.dll"),?"LoadLibraryA");
?if?(NULL?==?pFuncProcAddr)
?{
??EP_ShowError("GetProcAddress_LoadLibraryA");
??return?FALSE;
?}
?//?獲取ZwCreateThread函數(shù)地址
#ifdef?_WIN64
?typedef?DWORD(WINAPI?*typedef_ZwCreateThreadEx)(
??PHANDLE?ThreadHandle,
??ACCESS_MASK?DesiredAccess,
??LPVOID?ObjectAttributes,
??HANDLE?ProcessHandle,
??LPTHREAD_START_ROUTINE?lpStartAddress,
??LPVOID?lpParameter,
??ULONG?CreateThreadFlags,
??SIZE_T?ZeroBits,
??SIZE_T?StackSize,
??SIZE_T?MaximumStackSize,
??LPVOID?pUnkown);
#else
?typedef?DWORD(WINAPI?*typedef_ZwCreateThreadEx)(
??PHANDLE?ThreadHandle,
??ACCESS_MASK?DesiredAccess,
??LPVOID?ObjectAttributes,
??HANDLE?ProcessHandle,
??LPTHREAD_START_ROUTINE?lpStartAddress,
??LPVOID?lpParameter,
??BOOL?CreateSuspended,
??DWORD?dwStackSize,
??DWORD?dw1,
??DWORD?dw2,
??LPVOID?pUnkown);
#endif
?typedef_ZwCreateThreadEx?ZwCreateThreadEx?=?(typedef_ZwCreateThreadEx)::GetProcAddress(hNtdllDll,?"ZwCreateThreadEx");
?if?(NULL?==?ZwCreateThreadEx)
?{
??EP_ShowError("GetProcAddress_ZwCreateThread");
??return?FALSE;
?}
?//?使用?ZwCreateThreadEx?創(chuàng)建遠(yuǎn)線程,?實(shí)現(xiàn)?DLL?注入
?dwStatus?=?ZwCreateThreadEx(&hRemoteThread,?PROCESS_ALL_ACCESS,?NULL,?hProcess,?(LPTHREAD_START_ROUTINE)pFuncProcAddr,?pDllAddr,?0,?0,?0,?0,?NULL);
?if?(NULL?==?hRemoteThread)
?{
??EP_ShowError("ZwCreateThreadEx");
??return?FALSE;
?}
?//?關(guān)閉句柄
?::CloseHandle(hProcess);
?::FreeLibrary(hNtdllDll);

?return?TRUE;
}

試驗(yàn)結(jié)果

同遠(yuǎn)線程注入一致,只是在服務(wù)程序中不能彈窗。

APC注入

APC(Asynchronous Procedure Call)為異步過程調(diào)用,APC注入是指利用線程本身的APC隊(duì)列進(jìn)行DLL注入。

函數(shù)介紹

//?將異步調(diào)用函數(shù)添加到指定線程的APC隊(duì)列中
DWORD?QueueUserAPC(
??PAPCFUNC??pfnAPC,?//?函數(shù)指針
??HANDLE????hThread,?//?線程句柄
??ULONG_PTR?dwData?//?函數(shù)參數(shù)
);

//?詳細(xì)信息可參閱msdn

實(shí)現(xiàn)原理

APC隊(duì)列中的函數(shù)需要等待線程掛起時(shí)才會(huì)被執(zhí)行,所以要保證我們注入的程序能被執(zhí)行需要將我們的函數(shù)插入到進(jìn)程的所有線程中。具體代碼實(shí)現(xiàn)如下:

//?apc.h
#include?
#include?


//?根據(jù)進(jìn)程名稱獲取PID
DWORD?GetProcessIdByProcessName(char?*pszProcessName);

//?根據(jù)PID獲取所有的相應(yīng)線程ID
BOOL?GetAllThreadIdByProcessId(DWORD?dwProcessId,?DWORD?**ppThreadId,?DWORD?*dwThreadIdLength);

//?APC注入
BOOL?ApcInjectDll(char?*pszProcessName,?char?*pszDllName);


//apc.cpp
#include?"APC.h"


void?ShowError(char?*pszText){
?char?szErr[MAX_PATH]?=?{?0?};
?::wsprintf(szErr,?"%s?Error[%d]\n",?pszText);
?::MessageBox(NULL,?szErr,?"ERROR",?MB_OK?|?MB_ICONERROR);
}


//?根據(jù)進(jìn)程名稱獲取PID
DWORD?GetProcessIdByProcessName(char?*pszProcessName){
?DWORD?dwProcessId?=?0;
?PROCESSENTRY32?pe32?=?{?0?};
?HANDLE?hSnapshot?=?NULL;
?BOOL?bRet?=?FALSE;
?::RtlZeroMemory(&pe32,?sizeof(pe32));
?pe32.dwSize?=?sizeof(pe32);

?//?獲取進(jìn)程快照
?hSnapshot?=?::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,?0);
?if?(NULL?==?hSnapshot)
?{
??ShowError("CreateToolhelp32Snapshot");
??return?dwProcessId;
?}

?//?獲取第一條進(jìn)程快照信息
?bRet?=?::Process32First(hSnapshot,?&pe32);
?while?(bRet)
?{
??//?獲取快照信息
??if?(0?==?::lstrcmpi(pe32.szExeFile,?pszProcessName))
??{
???dwProcessId?=?pe32.th32ProcessID;
???break;
??}

??//?遍歷下一個(gè)進(jìn)程快照信息
??bRet?=?::Process32Next(hSnapshot,?&pe32);
?}

?return?dwProcessId;
}


//?根據(jù)PID獲取所有的相應(yīng)線程ID
BOOL?GetAllThreadIdByProcessId(DWORD?dwProcessId,?DWORD?**ppThreadId,?DWORD?*pdwThreadIdLength){
?DWORD?*pThreadId?=?NULL;
?DWORD?dwThreadIdLength?=?0;
?DWORD?dwBufferLength?=?1000;
?THREADENTRY32?te32?=?{?0?};
?HANDLE?hSnapshot?=?NULL;
?BOOL?bRet?=?TRUE;

?do
?{
??//?申請內(nèi)存
??pThreadId?=?new?DWORD[dwBufferLength];
??if?(NULL?==?pThreadId)
??{
???ShowError("new");
???bRet?=?FALSE;
???break;
??}
??::RtlZeroMemory(pThreadId,?(dwBufferLength?*?sizeof(DWORD)));

??//?獲取線程快照
??::RtlZeroMemory(&te32,?sizeof(te32));
??te32.dwSize?=?sizeof(te32);
??hSnapshot?=?::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,?0);
??if?(NULL?==?hSnapshot)
??{
???ShowError("CreateToolhelp32Snapshot");
???bRet?=?FALSE;
???break;
??}

??//?獲取第一條線程快照信息
??bRet?=?::Thread32First(hSnapshot,?&te32);
??while?(bRet)
??{
???//?獲取進(jìn)程對應(yīng)的線程ID
???if?(te32.th32OwnerProcessID?==?dwProcessId)
???{
????pThreadId[dwThreadIdLength]?=?te32.th32ThreadID;
????dwThreadIdLength++;
???}

???//?遍歷下一個(gè)線程快照信息
???bRet?=?::Thread32Next(hSnapshot,?&te32);
??}

??//?返回
??*ppThreadId?=?pThreadId;
??*pdwThreadIdLength?=?dwThreadIdLength;
??bRet?=?TRUE;

?}?while?(FALSE);

?if?(FALSE?==?bRet)
?{
??if?(pThreadId)
??{
???delete[]pThreadId;
???pThreadId?=?NULL;
??}
?}

?return?bRet;
}


//?APC注入
BOOL?ApcInjectDll(char?*pszProcessName,?char?*pszDllName){
?BOOL?bRet?=?FALSE;
?DWORD?dwProcessId?=?0;
?DWORD?*pThreadId?=?NULL;
?DWORD?dwThreadIdLength?=?0;
?HANDLE?hProcess?=?NULL,?hThread?=?NULL;
?PVOID?pBaseAddress?=?NULL;
?PVOID?pLoadLibraryAFunc?=?NULL;
?SIZE_T?dwRet?=?0,?dwDllPathLen?=?1?+?::lstrlen(pszDllName);
?DWORD?i?=?0;

?do
?{
??//?根據(jù)進(jìn)程名稱獲取PID
??dwProcessId?=?GetProcessIdByProcessName(pszProcessName);
??if?(0?>=?dwProcessId)
??{
???bRet?=?FALSE;
???break;
??}

??//?根據(jù)PID獲取所有的相應(yīng)線程ID
??bRet?=?GetAllThreadIdByProcessId(dwProcessId,?&pThreadId,?&dwThreadIdLength);
??if?(FALSE?==?bRet)
??{
???bRet?=?FALSE;
???break;
??}

??//?打開注入進(jìn)程
??hProcess?=?::OpenProcess(PROCESS_ALL_ACCESS,?FALSE,?dwProcessId);
??if?(NULL?==?hProcess)
??{
???ShowError("OpenProcess");
???bRet?=?FALSE;
???break;
??}

??//?在注入進(jìn)程空間申請內(nèi)存
??pBaseAddress?=?::VirtualAllocEx(hProcess,?NULL,?dwDllPathLen,?MEM_COMMIT?|?MEM_RESERVE,?PAGE_EXECUTE_READWRITE);
??if?(NULL?==?pBaseAddress)
??{
???ShowError("VirtualAllocEx");
???bRet?=?FALSE;
???break;
??}
??//?向申請的空間中寫入DLL路徑數(shù)據(jù)?
??::WriteProcessMemory(hProcess,?pBaseAddress,?pszDllName,?dwDllPathLen,?&dwRet);
??if?(dwRet?!=?dwDllPathLen)
??{
???ShowError("WriteProcessMemory");
???bRet?=?FALSE;
???break;
??}

??//?獲取?LoadLibrary?地址
??pLoadLibraryAFunc?=?::GetProcAddress(::GetModuleHandle("kernel32.dll"),?"LoadLibraryA");
??if?(NULL?==?pLoadLibraryAFunc)
??{
???ShowError("GetProcessAddress");
???bRet?=?FALSE;
???break;
??}

??//?遍歷線程,?插入APC
??i?=?dwThreadIdLength;
??for?(;?i?>?0;?--i)
??{
???//?打開線程
???hThread?=?::OpenThread(THREAD_ALL_ACCESS,?FALSE,?pThreadId[i]);
???if?(hThread)
???{
????//?插入APC
????::QueueUserAPC((PAPCFUNC)pLoadLibraryAFunc,?hThread,?(ULONG_PTR)pBaseAddress);
????//?關(guān)閉線程句柄
????::CloseHandle(hThread);
????hThread?=?NULL;
???}
??}

??bRet?=?TRUE;

?}?while?(FALSE);

?//?釋放內(nèi)存
?if?(hProcess)
?{
??::CloseHandle(hProcess);
??hProcess?=?NULL;
?}
?if?(pThreadId)
?{
??delete[]pThreadId;
??pThreadId?=?NULL;
?}

?return?bRet;
}

總結(jié)

Windows注入技術(shù)可以方便我們對目標(biāo)進(jìn)程作修改,但是也可能使目標(biāo)進(jìn)程崩潰,在使用的時(shí)候需要小心謹(jǐn)慎。

長按圖片自動(dòng)識(shí)別~~~關(guān)注我哦~~~~- END -

總結(jié)

以上是生活随笔為你收集整理的redistemplate注入为null_Windows DLL 注入技术的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。