远程注入小记

原作者连接

提权方法
64位的一定要生成64的,网上说32和64内存隔开的。

//注入程序
#include "stdafx.h"
#include "Remote injection.h"
#include "tlhelp32.h"
using namespace std;
extern int ListProcess();
extern int EnableDebugPriv(const WCHAR *);

int _tmain(int argc, TCHAR *argv[], TCHAR *env[])
{
    //为了成功使用CreateRemoteThread()函数,必须:
    //1.利用OpenProcess()获得远程进程的句柄
    //2.利用VirtualAllocEx(),WriteProcessMemory()写入DLL路径字符串
    //3.获得远程进程中LoadLibrary()的确切地址

    //输入进程ID获得进程句柄
    char YesNo;
    printf("是否查看当前进程列表获得进程ID: Y or N?");
    scanf("%c", &YesNo);
    Sleep(250);
    if (YesNo == 'Y' || YesNo == 'y')
        ListProcess();
    printf("请输入要注入的进程ID【‘’表示自身进程】:\n");
    DWORD dwRemoteProcessId;
    scanf("%d", &dwRemoteProcessId);
    //如果输入“”表示向自身进程注入
    if (dwRemoteProcessId == 0)
        dwRemoteProcessId = GetCurrentProcessId();

    //获得调试权限
    if (EnableDebugPriv(SE_DEBUG_NAME))
    {
        printf("Add Privilege error\n");
        return -1;
    }
    //调用OpenProcess()获得句柄
    HANDLE hRemoteProcess;
    if ((hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwRemoteProcessId)) == NULL)
    {
        printf("OpenProcess error\n");
        printf("Error Code:%d\n", GetLastError());
        system("pause");
        return -2;
    }

    //在远程进程中分配内存,准备拷入DLL路径字符串
    //取得当前DLL路径
    char DllPath[260]; //Windows路径最大为
    GetCurrentDirectoryA(260, DllPath);  //获取当前进程执行目录
    printf("Proces***e Directory is %s\n", DllPath);
    strcat(DllPath, "\\..\\Debug\\MyDLL.dll"); //链接到DLL路径
    LPVOID pRemoteDllPath = VirtualAllocEx(hRemoteProcess, NULL, strlen(DllPath) + 1, MEM_COMMIT, PAGE_READWRITE);
    if (pRemoteDllPath == NULL)
    {
        printf("VirtualAllocEx error\n");
        return -3;
    }

    //向远程进程空间中写入DLL路径字符串
    printf("DllPath is %s\n", DllPath);
    DWORD Size;
    if (WriteProcessMemory(hRemoteProcess, pRemoteDllPath, DllPath, strlen(DllPath) + 1, &Size) == NULL)
    {
        printf("WriteProcessMemory error\n");
        return -4;
    }
    printf("WriteRrmoyrProcess Size is %d\n\n", Size);

    //获得远程进程中LoadLibrary()的地址
    LPTHREAD_START_ROUTINE pLoadLibrary = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
    if (pLoadLibrary == NULL)
    {
        printf("GetProcAddress error\n");
        return -5;
    }
    else
    {
        printf("LoadLibrary's Address is 0x%x\n\n", pLoadLibrary);
    }

    //启动远程线程
    DWORD dwThreadId;
    HANDLE hThread;
    hThread = CreateRemoteThread(hRemoteProcess, NULL, 0, pLoadLibrary, pRemoteDllPath, 0, &dwThreadId);
    if (hThread == NULL)
    {
        printf("CreateRemoteThread error\n");
        return -6;
    }
    else
    {
        WaitForSingleObject(hThread, INFINITE);
        printf("dwThreadId is %d\n\n", dwThreadId);
        printf("Inject is done\n");
    }

    //释放分配内存
    if (VirtualFreeEx(hRemoteProcess, pRemoteDllPath, 0, MEM_RELEASE) == 0)
    {
        printf("VitualFreeEx error\n");
        return -8;
    }

    //释放句柄
    if (hThread != NULL) CloseHandle(hThread);
    if (hRemoteProcess != NULL) CloseHandle(hRemoteProcess);

    system("pause");
    return 0;
}

int ListProcess()
{
    //获取系统快照
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //不要写错CreateToolhelp32Snapshot()
    if (hProcessSnap == INVALID_HANDLE_VALUE)
    {
        printf("CreateToolHelp32Snapshot error!\n");
        return -1;
    }

    //创建单个进程快照结构体,初始化大小
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);  //务必提前初始化,否则默认的大小不一定满足要求

    //初始化缓冲区
    WCHAR buff[1024] = { 0 }; //PROCESSENTRY32中的szExeFile为WCHAR类型数组,此处应一致,使用Unicode码

    //枚举系统快照链表中的第一个进程项目
    BOOL bProcess = Process32First(hProcessSnap, &pe32);
    while (bProcess)
    {

        //格式化进程名和进程ID,这里要使用printf的宽字符版
        //格式字符串“”都需要用L转换为宽字符形式
        wsprintf(buff, L"FileName:%-30sID:%-6d\r\n", pe32.szExeFile, pe32.th32ProcessID);
        wprintf(L"%s\n", buff);
        //缓冲区复位
        memset(buff, 0, sizeof(buff));
        //继续枚举下一个进程
        bProcess = Process32Next(hProcessSnap, &pe32);
    }

    CloseHandle(hProcessSnap);
    return 0;
}

int EnableDebugPriv(const WCHAR *name)
{
    HANDLE hToken;   //进程令牌句柄
    TOKEN_PRIVILEGES tp;  //TOKEN_PRIVILEGES结构体,其中包含一个【类型+操作】的权限数组
    LUID luid;       //上述结构体中的类型值

    //打开进程令牌环
    //GetCurrentProcess()获取当前进程的伪句柄,只会指向当前进程或者线程句柄,随时变化
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        printf("OpenProcessToken error\n");
        return -8;
    }

    //获得本地进程name所代表的权限类型的局部唯一ID
    if (!LookupPrivilegeValue(NULL, name, &luid))
    {
        printf("LookupPrivilegeValue error\n");
    }

    tp.PrivilegeCount = 1;    //权限数组中只有一个“元素”
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  //权限操作
    tp.Privileges[0].Luid = luid;   //权限类型

    //调整进程权限
    if (!AdjustTokenPrivileges(hToken, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
    {
        printf("AdjustTokenPrivileges error!\n");
        return -9;
    }

    return 0;
}
//Dll
// MyDll.cpp : 定义 DLL 的初始化例程。
//

#include "stdafx.h"
#include "MyDll.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//
//TODO:  如果此 DLL 相对于 MFC DLL 是动态链接的,
//      则从此 DLL 导出的任何调入
//      MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
//      该函数的最前面。
//
//      例如: 
//
//      extern "C" BOOL PASCAL EXPORT ExportedFunction()
//      {
//          AFX_MANAGE_STATE(AfxGetStaticModuleState());
//          // 此处为普通函数体
//      }
//
//      此宏先于任何 MFC 调用
//      出现在每个函数中十分重要。  这意味着
//      它必须作为函数中的第一个语句
//      出现,甚至先于所有对象变量声明,
//      这是因为它们的构造函数可能生成 MFC
//      DLL 调用。
//
//      有关其他详细信息,
//      请参阅 MFC 技术说明 33 和 58。
//

// CMyDllApp

BEGIN_MESSAGE_MAP(CMyDllApp, CWinApp)
END_MESSAGE_MAP()

void test(CString text);
// CMyDllApp 构造

CMyDllApp::CMyDllApp()
{
    // TODO:  在此处添加构造代码,
    // 将所有重要的初始化放置在 InitInstance 中
    test(L"2");
}


// 唯一的一个 CMyDllApp 对象

CMyDllApp theApp;


// CMyDllApp 初始化

BOOL CMyDllApp::InitInstance()
{
    CWinApp::InitInstance();
    test(L"1");
    return TRUE;
}

void test(CString text){
    text += L"DLL has been mapped!";
    MessageBox(NULL, text, text, MB_OK);
    FILE *fp = fopen("C:\\test.txt", "w");
    fputs("一个DLL测试文本\n", fp);
    fclose(fp);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值