1. 程式人生 > >c++實現dll注入其它程序

c++實現dll注入其它程序

DLL注入其他程序技術
閱讀本篇文章,需要有《執行緒注入其他程序技術》基礎。
DLL注入技術才具有強大的功能和使用性,同時簡單易用,因為DLL中可以實現複雜的功能和很多的技術。
 
 
技術要點:
1、宿主程序呼叫LoadLibrary,就可以完成DLL的遠端注入。可以通過CreateRemoteThread將LoadLibrary作為宿主程序的一個執行緒來啟動,就可以完成“控制目標程序呼叫LoadLibrary”的工作。
2、標準DLL中DllMain,是DLL執行的入口;使用MFC的DLL中InitInstance,是DLL執行的入口,但是沒有訊息迴圈。
   注意:
   a、如果是需要多執行緒,只能使用有DLLMain的標準DLL。因為使用MFC的DLL,在InitInstance中啟動新的執行緒,會在啟動執行緒的地方阻塞不繼續執行。即說,使用帶MFC的DLL只能單執行緒作業。
   b、如果需要使用多執行緒和MFC。可以在標準DLL中先啟動執行緒,再呼叫使用MFC的DLL。
 

實現步驟
1、將DLL的地址拷貝到宿主程序地址空間中
2、通過CreateRemoteThread將LoadLibrary作為宿主程序的一個執行緒來啟動
 
 
可以正確執行的示例程式碼(拷貝後直接可以使用):
應用程式檔案內容:
// #pragma once

#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <time.h>

// 提升程序訪問許可權
bool enableDebugPriv()
{
    HANDLE  hToken;
    LUID    sedebugnameValue;
    TOKEN_PRIVILEGES tkp;
    if  ( !OpenProcessToken(  GetCurrentProcess(),
                            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)
        )
    {
        return false;
    }
    if( !LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue) )
    {
        CloseHandle(hToken);
        return false;
    }
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = sedebugnameValue;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    if( !AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL) )
    {
        CloseHandle(hToken);
        return false;
    }
    return true;
}

// 根據程序名稱得到程序ID,如果有多個執行例項的話,返回第一個列舉到的程序的ID
DWORD processNameToId(LPCTSTR lpszProcessName)
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 pe;
    pe.dwSize = sizeof(PROCESSENTRY32);
    if( !Process32First(hSnapshot, &pe) )
    {
        MessageBox( NULL,
                    "The frist entry of the process list has not been copyied to the buffer",
                    "Notice",
                    MB_ICONINFORMATION | MB_OK
                    );
        return 0;
    }
    while( Process32Next(hSnapshot, &pe) )
    {
        if( !strcmp(lpszProcessName, pe.szExeFile) )
        {
            return pe.th32ProcessID;
        }
    }
    return 0;
}

int main(int argc, char* argv[])
{
    // 定義執行緒體的大小
    const DWORD dwThreadSize = 5 * 1024;
    DWORD dwWriteBytes;
    // 提升程序訪問許可權
    enableDebugPriv();
    // 等待輸入程序名稱,注意大小寫匹配
    std::cout << "Please input the name of target process !" << std::endl;
    char szExeName[MAX_PATH] = { 0 };
    std::cin >> szExeName;
    DWORD dwProcessId = processNameToId(szExeName);
    if( dwProcessId == 0 )
    {
        MessageBox( NULL,
                    "The target process have not been found !",
                    "Notice",
                    MB_ICONINFORMATION | MB_OK
                    );
        return -1;
    }

    // 根據程序ID得到程序控制代碼
    HANDLE hTargetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if( !hTargetProcess )
    {
        MessageBox( NULL,
                    "Open target process failed !",
                    "Notice",
                    MB_ICONINFORMATION | MB_OK
                    );
        return 0;
    }

    // 在宿主程序中為執行緒體開闢一塊儲存區域
    // 在這裡需要注意MEM_COMMIT記憶體非配型別以及PAGE_EXECUTE_READWRITE記憶體保護型別
    // 其具體含義請參考MSDN中關於VirtualAllocEx函式的說明。
    void* pRemoteThread = VirtualAllocEx(   hTargetProcess,
                                            0,
                                            dwThreadSize,
                                            MEM_COMMIT , PAGE_EXECUTE_READWRITE);
    if( !pRemoteThread )
    {
        MessageBox( NULL,
                    "Alloc memory in target process failed !",
                    "notice",
                    MB_ICONINFORMATION | MB_OK
                    );
        return 0;
    }
    // 設定需要注入的DLL名稱
    char szDll[256];
    memset(szDll, 0, 256);
    strcpy(szDll, "E:\\mydll.dll");
    // 拷貝注入DLL內容到宿主空間
    if( !WriteProcessMemory(    hTargetProcess,
                                pRemoteThread,
                                (LPVOID)szDll,
                                dwThreadSize,
                                0) )
    {
        MessageBox( NULL,
                    "Write data to target process failed !",
                    "Notice",
                    MB_ICONINFORMATION | MB_OK
                    );
        return 0;
    }

    LPVOID pFunc = LoadLibraryA;
    //在宿主程序中建立執行緒
    HANDLE hRemoteThread = CreateRemoteThread(  hTargetProcess,
                                                NULL,
                                                0,
                                                (LPTHREAD_START_ROUTINE)pFunc,
                                                pRemoteThread,
                                                0,
                                                &dwWriteBytes);
     if( !hRemoteThread )
     {
         MessageBox(    NULL,
                        "Create remote thread failed !",
                        "Notice",
                        MB_ICONINFORMATION | MB_OK
                        );
         return 0;
     }
     // 等待LoadLibraryA載入完畢
     WaitForSingleObject(hRemoteThread, INFINITE );
     VirtualFreeEx(hTargetProcess, pRemoteThread, dwThreadSize, MEM_COMMIT);
     CloseHandle( hRemoteThread );
     CloseHandle( hTargetProcess );
     return 0;
}
 
 
實驗的標準DLL檔案:
// mydll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
DWORD WINAPI MyThreadProc1( LPVOID pParam );
DWORD WINAPI MyThreadProc2( LPVOID pParam );
 
BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch ( ul_reason_for_call )
    {
        case DLL_PROCESS_ATTACH:
        {
            MessageBox( NULL, "DLL已進入目標程序。", "資訊", MB_ICONINFORMATION );
            DWORD dwThreadId;
            HANDLE myThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThreadProc1, NULL, 0, &dwThreadId);
            HANDLE myThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThreadProc2, NULL, 0, &dwThreadId);
            break;
        }
        case DLL_PROCESS_DETACH:
        {
            MessageBox( NULL, "DLL已從目標程序解除安裝。", "資訊", MB_ICONINFORMATION );
            break;
        }
    }
    return TRUE;
}
 
DWORD WINAPI MyThreadProc1( LPVOID pParam )
{
    MessageBox( NULL, "DLL已進入執行緒1。", "資訊", MB_ICONINFORMATION );
    return 0;
}

DWORD WINAPI MyThreadProc2( LPVOID pParam )
{
    MessageBox( NULL, "DLL已進入執行緒2。", "資訊", MB_ICONINFORMATION );
 

相關推薦

c++實現dll注入其它程序

DLL注入其他程序技術 閱讀本篇文章,需要有《執行緒注入其他程序技術》基礎。 DLL注入技術才具有強大的功能和使用性,同時簡單易用,因為DLL中可以實現複雜的功能和很多的技術。     技術要點: 1、宿主程序呼叫LoadLibrary,就可以完成DLL的遠端注入。可以通過

DLL注入:用CreateRemoteThread實現DLL注入

實驗環境:WINXP VS2010 功能:注入到notepad.exe程式,並從網上下一個檔案 實驗程式: (一)myhack.dll,即要注入的dll程式 #include "windows.h" #include "tchar.h" #pragma comment(lib,"url

java設定熱鍵(C++實現dll匯入)

java設定全域性熱鍵(咧: Shift+S)jar包 注: jar檔案匯入後,兩個dll檔案一定要放在com.melloware.jintellitype包下.其餘可以捨棄 使用案咧: // 程

利用c#實現dll動態庫,並在c++中呼叫的方法

           近期,在進行一個大專案開發。其中涉及多語言協同開發。主要是c#dll和c++dll的開發和應用,其中,需要在c++中呼叫c#dll的內容。現在把開發中的經驗、教訓和注意事項總結整理如下,希望對其他人能有所幫助。           1.建立c#dll,

Windows核心程式設計_遠執行緒方式實現Dll注入

之前有介紹過HOOK的方式注入,這次介紹以其它方式注入,而無須HOOK,要知道在Windows這個浩蕩的海洋裡,API就是寶藏,找到足夠多的寶藏那麼你就是海賊王~! 實現思路如下: 首先開啟一個程序的地址空間,然後開闢一塊空間將動態庫copy進去,然後找到動態庫要呼叫

如何用C#實現依賴注入

1. 問題的提出 開發中,尤其是大型專案的開發中,為了降低模組間、類間的耦合關係,比較提倡基於介面開發,但在實現中也必須面臨最終是“誰”提供實體類的問題。Martin Fowler在《Inversion of Control Containers and the Dependency Injection pa

VC++實現DLL注入

所謂DLL注入就是將一個DLL放進某個程序的地址空間裡,讓它成為那個程序的一部分。要實現DLL注入,首先需要開啟目標程序。   hRemoteProcess = OpenProcess( PROCESS_CREATE_THREAD | //允許遠端建立執行緒   PROCES

使用fatjar來實現將包括第三方jar包的項目到處成一個jar包供其它程序使用

選中項 text sin jar dmv padding 安裝 cli itl 一、在線安裝fat jar在線安裝步驟:eclipse菜單條 help >software updates >Search for new features to install&

C#實現聯通短信Sgip協議程序源碼

可用 window 技術分享 配置 網關 實例 alt 100% 模擬器 此程序為中國聯通Sgip協議程序接口,適合在中國聯通申請了短信發送端口的公司使用。 短信群發已經成為現在軟件系統、網絡營銷等必不可少的應用工具。可應用在短信驗證、信息群發、遊戲虛擬商品購買、事件提醒

C# 版dll 程序集合並工具

集合 命令 支持 log 基本 ron 其他 依賴 使用 微軟的ILMerge工具。 下載地址:https://www.microsoft.com/en-us/download/details.aspx?id=17630 這個支持將EXE依賴的DLL合並到EXE

C#實現SMTP郵件發送程序實例

lin ice 效果 using exceptio length string false ack 通常來說郵件發送功能在網站應用程序中經常會用到,包括大家經常看到的博客,在添加評論後,系統會自動發送郵件通知到我郵箱的,把系統發送郵件的功能整理了下,本文展示了一個客戶端D

HTML C# ajax結合ashx處理程序實現文件上傳

chan erro radius 處理 插件 nbsp 成功 jquer dex ajax結合ashx處理程序實現文件上傳 一、ajaxFileUpload是一個異步上傳文件的jQuery插件。   ajaxFileUpload參數說明:(copy了別人的參數說明) 1、u

c實現的四則運算程序

fop correct 等價 int 運行程序 fprintf bsp github項目 完成 github項目地址:https://github.com/xinxianquan/ruangong 成員:馬朝濱,王誌聰。 題目:實現一個自動生成小學四則運算題目的命令行程序。

C++實現的一個打印日歷程序

ace c++ chm 分享 std mon gets int start setw C++實現的一個打印日歷程序 說明:總共有三個文件 1、month.h為定義函數的頭文件 2、month.cpp為函數的實現代碼 3、mainprog.cpp為主函數的實現代碼

典型C/S模式___多程序實現

一、思路 server程序通過accept()接收了一個連線請求。然後,子程序將作為“種籽”的server方插口關閉,而使用新的插口與client程序通訊併為之提供服務。而父程序則把新的插口關閉,並再一次呼叫accept(),通過“種籽”插口來接收新的連線請求。 子程序注意事項有

c++實現程序間的通訊(匿名管道方法)

#include<stdio.h> #include<unistd.h> int main() { int fd[2]; pipe(fd); int pid=fork()

程序通訊之一 使用WM_COPYDATA C++及C#實現

                程序間通訊最簡單的方式就是傳送WM_COPYDATA訊息。本文提供C++及C#程式相互通訊的二種實現方式。這樣訊息的接收端可以用C++實現,傳送端可以用C++或C#實現。傳送WM_COPYDATA訊息:SendMessage(接收視窗控制代碼, WM_COPYDATA, (WP

幾種程序排程演算法模擬C++實現

先到先服務(FCFS)最短作業優先排程演算法(SJF)#include <iostream> #include <queue> #include <algorithm> #include <cstdio> #include &l

安全之路 —— C++實現程序守護

簡介 所謂程序守護,就是A程序為了保護自己不被結束,建立了一個守護執行緒來保護自己,一旦被結束程序,便重新啟動。程序守護的方法多被應用於惡意軟體,是一個保護自己程序的一個簡單方式,在ring3下即可輕鬆實現。而建立守護執行緒的方法多采用遠端執行緒注入的方式,筆

c#實現動態載入Dll

1、利用反射進行動態載入和呼叫. Assembly assembly=Assembly.LoadFrom(DllPath); //利用dll的路徑載入,同時將此程式集所依賴的程式集載入進來,需後輟名.dllAssembly.LoadFile 只加載指定檔案,並不會自動載入依賴程式集.Assmbly.Load無