国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

怎樣實現.net程序的進程注入_.Net教程

2024-07-10 12:51:08
字體:
來源:轉載
供稿:網友

推薦:如何在.NET環境下為網站增加IP過濾功能
華能集團下某發電廠的企業網站(基于Asp.Net2.0實現,不允許修改源程序)要求實現廠內用戶可直接訪問整個站點的所有頁面,廠外用戶只能訪問指定的頁面的功能,本文將按照需求分析、方案設計、編碼實現、部署應用的順序逐步闡述整個解決方案的形成過程。 1.

進程注入比較常見,比如用IDE調試程序以及一些Spy程序,如果僅僅為了與調試器通訊,可以使用.net提供的Debugger接口(在EnvDTE.dll的EnvDTE命名空間下).但無論出于什么目的,進程注入都是比較好玩的事情,所以不妨一試 . 進程注入的方法貌似很多(比如像特洛伊一樣喬裝打扮讓目標進程誤認為你的程序集合法而加載到目標進程),這里提到的僅是其中的一種或某些方法的結合.

  大致原理是這樣的:

  源進程(也就是你的代碼所在的進程)獲得目標進程(也就是你的注入目標所在的進程)的ID或進程對象

  源進程提供一回調函數methodA(也就是你想要注入到目標進程后所執行的代碼)

  將目標進程和回調函數methodA的完整路徑(其所在的Assembly,Classic以及MethodName)提交給Injector(也就是我們編寫的負責注入的類),讓Injector來完成注入和讓目標進程執行回調函數

  Injector根據提供的目標進程ID取得目標進程對象,并獲得目標進程的一個線程(我們稱為目標線程)

  在目標線程中分配一塊內存,將回調函數methodA的完整路徑作為字符串存入該內存中

  Injector在目標進程中安裝一個鉤子(Hook)監視某一個Windows消息(messageA),撰寫鉤子的回調函數methodB(該方法中的內容稍后解釋)

  像目標進程發消息messageA,并將剛才分配的內存的基地址作為消息參數傳遞.

  由于我們針對messageA安裝了鉤子,所以目標進程會調用我們鉤子函數methodB,并會把分配的內存的基地址包含在函數參數中

  methodB中, 根據函數參數中的內存基地址在內存中解析出其實際對象,也就是一個表示我們的methodA的完整路徑的字符串.根據該字符串中所表示的Assembly,className, methodName利用.net反射,反射出其MethodInfo對象(注意,關鍵點,methodB被回調時已經是在目標進程的某個線程中了) Invoke反射出的MethodInfo對象, 我們的methodA得到了執行.

  下面這個圖可能會幫助你理解上面的話: 

如何實現.net程序的進程注入

    圖片看不清楚?請點擊這里查看原圖(大圖)。

  如果還沒明白的話,那就看代碼吧(這需要一點點C++/CLI知識,但我已經為每句加上了注釋,應該蠻好懂的,C++/CLI可以點擊這里了解更多.關于ManagedInjector可以點擊這里了解更多)

#include "stdafx.h"
#include "Injector.h"
#include <vcclr.h>
using namespace ManagedInjector;
//defines a new window message that is guaranteed to be unique throughout the system.
//The message value can be used when sending or posting messages.
static unsigned int WM_GOBABYGO = ::RegisterWindowMessage(L"Injector_GOBABYGO!");
static HHOOK _messageHookHandle;
//-----------------------------------------------------------------------------
//Spying Process functions follow
//-----------------------------------------------------------------------------
void Injector::Launch(System::IntPtr windowHandle, System::Reflection::Assembly^ assembly, System::String^ className, System::String^ methodName) {
    System::String^ assemblyClassAndMethod = assembly->Location + "$" + className + "$" + methodName;
    //convert String to local wchar_t* or char*
    pin_ptr<const wchar_t> acmLocal = PtrToStringChars(assemblyClassAndMethod);
    //Maps the specified executable module into the address space of the calling process.
    HINSTANCE hinstDLL = ::LoadLibrary((LPCTSTR) _T("ManagedInjector.dll"));
    if (hinstDLL)
    {
        DWORD processID = 0;
        //get the process id and thread id
        DWORD threadID = ::GetWindowThreadProcessId((HWND)windowHandle.ToPointer(), &processID);
        if (processID)
        {
            //get the target process object (handle)
            HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
            if (hProcess)
            {
                int buffLen = (assemblyClassAndMethod->Length + 1) * sizeof(wchar_t);
                //Allocates physical storage in memory or in the paging file on disk for the specified reserved memory pages.
                //The function initializes the memory to zero.
                //The return value is the base address of the allocated region of pages.
                void* acmRemote = ::VirtualAllocEx(hProcess, NULL, buffLen, MEM_COMMIT, PAGE_READWRITE);
                if (acmRemote)
                {
                    //copies the data(the assemblyClassAndMethod string)
                    //from the specified buffer in the current process
                    //to the address range of the target process
                    ::WriteProcessMemory(hProcess, acmRemote, acmLocal, buffLen, NULL);
               
                    //Retrieves the address of MessageHookProc method from the hintsDLL
                    HOOKPROC procAddress = (HOOKPROC)GetProcAddress(hinstDLL, "MessageHookProc");
                    //install a hook procedure to the target thread(before the system sends the messages to the destination window procedure)
                    _messageHookHandle = ::SetWindowsHookEx(WH_CALLWNDPROC, procAddress, hinstDLL, threadID);
                    if (_messageHookHandle)
                    {
                        //send our custom message to the target window of the target process
                        ::SendMessage((HWND)windowHandle.ToPointer(), WM_GOBABYGO, (WPARAM)acmRemote, 0);
                        //removes the hook procedure installed in a hook chain by the SetWindowsHookEx function.
                        ::UnhookWindowsHookEx(_messageHookHandle);
                    }
                    //removes a hook procedure installed in a hook chain by the SetWindowsHookEx function.
                    ::VirtualFreeEx(hProcess, acmRemote, buffLen, MEM_RELEASE);
                }
                ::CloseHandle(hProcess);
            }
        }
        //Decrements the reference count of the loaded DLL
        ::FreeLibrary(hinstDLL);
    }
}
__declspec( dllexport )
// The procedure for hooking, this will be called back after hooked
int __stdcall MessageHookProc(int nCode, WPARAM wparam, LPARAM lparam) {
    //HC_ACTION: indicate that there are argments in wparam and lparam
    if (nCode == HC_ACTION)
    {
        CWPSTRUCT* msg = (CWPSTRUCT*)lparam;
        //when the target window received our custom message
        if (msg != NULL && msg->message == WM_GOBABYGO)
        {
            //get the argument passed by the message
            //actually, the argument is the base address (a pointer)
            //of the assemblyClassAndMethod string in the target process memory
            wchar_t* acmRemote = (wchar_t*)msg->wParam;
            //gcnew: creates an instance of a managed type (reference or value type) on the garbage collected heap
            System::String^ acmLocal = gcnew System::String(acmRemote);
            //split the string into substring array with $. Under this context:
            //acmSplit[0]:the assembly's location
            //acmSplit[1]:className;
            //acmSplit[2]:methodName
            //we use these infomation to reflect the method in the source assembly, and invoke it in the target process
            cli::array<System::String^>^ acmSplit = acmLocal->Split('$');
            //refect the method, and invoke it
            System::Reflection::Assembly^ assembly = System::Reflection::Assembly::LoadFile(acmSplit[0]);
            if (assembly != nullptr)
            {
                System::Type^ type = assembly->GetType(acmSplit[1]);
                if (type != nullptr)
                {
                    System::Reflection::MethodInfo^ methodInfo =
                        type->GetMethod(acmSplit[2], System::Reflection::BindingFlags::Static | System::Reflection::BindingFlags::Public);
                    if (methodInfo != nullptr)
                    {
                        methodInfo->Invoke(nullptr, nullptr);
                    }
                }
            }
        }
    }
    return CallNextHookEx(_messageHookHandle, nCode, wparam, lparam);
}接下來,做個DEMO嘗試一下: 

如何實現.net程序的進程注入  

  解決方案中的InjectorDemo就是我們上述的源進程,它會利用Injector將下面這段代碼注入到Target進程中并執行:

public static void DoSomethingEvie()
{
    vartargetWindow = Application.Current.MainWindow;

    if(targetWindow != null)
    {
        varlb = newLabel{Content = "haha, i caught you :)"};
        targetWindow.Content = lb;
    }
}

  也就是說InjectorDemo進程會將InjectTargetApp進程的主窗口的內容修改成"haha, i caught you"這樣的一個Label.

  運行程序: 

   如何實現.net程序的進程注入

    圖片看不清楚?請點擊這里查看原圖(大圖)。 

  上面的兩個窗口分別處于不同的進程中, 點擊 "Inject it" 按鈕, 其輝調用如下代碼:

ManagedInjector.Injector.Launch(targetProcess.MainWindowHandle, typeof(InjectorWindow).Assembly, typeof(InjectorWindow).FullName, "DoSomethingEvie");

  然后:

如何實現.net程序的進程注入

 

    圖片看不清楚?請點擊這里查看原圖(大圖)。 

分享:淺談使用ASP.NET Global.asax 文件
Global.asax文件,有時候叫做ASP.NET應用程序文件,提供了一種在一個中心位置響應應用程序級或模塊級事件的方法。你可以使用這個文件實現應用程序安全性以及其它一些任務。下面讓我們詳細看一下如何在應用程序開發工作中使用這個文件。 概述 Global.asax位于

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 泾阳县| 黔西| 柳江县| 梓潼县| 池州市| 兴国县| 民勤县| 马鞍山市| 蒲城县| 正镶白旗| 荥经县| 筠连县| 新源县| 黎城县| 孟村| 泾源县| 中宁县| 扬中市| 宁陕县| 常熟市| 二手房| 广丰县| 青龙| 同德县| 宁远县| 巫溪县| 道孚县| 马山县| 含山县| 靖安县| 白河县| 望城县| 衡阳市| 呼和浩特市| 金川县| 含山县| 大田县| 澄城县| 炎陵县| 井冈山市| 洛宁县|