DLL注入

原创 2016年06月01日 19:11:16

前两篇文章介绍了DLL的编写与加载,现在来讲一下在内存攻击中会使用到的DLL注入

附 : 转载请注明来源 enjoy5512的博客 http://blog.csdn.net/enjoy5512


DLL注入的一般步骤:
1, EnableDebugPriv(自己编写)获取远程进程的调试权限
2,OpenProcess获得要注入进程的句柄
3,VirtualAllocEx在远程进程中开辟出一段内存,长度为 strlen(dllname)+1;
4,WriteProcessMemory将Dll的名字写入第三步开辟出的内存中。
5,CreateRemoteThread将LoadLibraryA作为线程函数,参数为Dll的名称,创建新线程
6,CloseHandle关闭进程和远程线程句柄


代码如下:


/////////////////////////////////////////////////////////////////////////////
//  文件名 : inject.c
//  作者 : enjoy5512   修改者 : enjoy5512   最后优化注释者 : enjoy5512
//  个人技术博客 : blog.csdn.net/enjoy5512
//  个人GitHub   : github.com/whu-enjoy
//  描述 : 对用户给定的进程PID对所选进程进行dll注入
//  主要函数 :
//      int EnableDebugPriv(const char *name)  //获取调试权限
//
//  版本 : 最终确定版  完成日期 : 2016年6月1日 19:09:03
//  修改 :
//  参考文献 :
/////////////////////////////////////////////////////////////////////////////


#include <stdio.h>
#include <windows.h>


    //函数说明开始
    //==================================================================================
    //  功能 : 获取进程的调试权限
    //  参数 : const char *name
    //  (入口)  name : 指向权限名称,我们这里用到SE_DEBUG_NAME
    //    #define          SE_BACKUP_NAME           TEXT("SeBackupPrivilege")
    //    #define          SE_RESTORE_NAME          TEXT("SeRestorePrivilege")
    //    #define          SE_SHUTDOWN_NAME         TEXT("SeShutdownPrivilege")
    //    #define          SE_DEBUG_NAME            TEXT("SeDebugPrivilege")
    //  返回 : -1表示获取权限失败, 0表示获取权限成功
    //  主要思路 : 先打开进程令牌环,然后获得本地进程name所代表的权限类型的局部唯一ID
    //             最后调整进程权限
    //  调用举例 : EnableDebugPriv(SE_DEBUG_NAME)
    //  日期 : 2016年6月1日 19:08:22(注释日期)
    //==================================================================================
    //程序说明结束
int EnableDebugPriv(const char *name)
{
    HANDLE hToken;        //进程令牌句柄
    TOKEN_PRIVILEGES tp;  //TOKEN_PRIVILEGES结构体,其中包含一个【类型+操作】的权限数组
    LUID luid;           //上述结构体中的类型值

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

    //获得本地进程name所代表的权限类型的局部唯一ID
    if (!LookupPrivilegeValue(NULL, name, &luid))
    {
       fprintf(stderr,"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))
    {
       fprintf(stderr,"AdjustTokenPrivileges error!\n");
       return -1;
    }

    return 0;

}

//函数说明开始
    //==================================================================================
    //  功能 : DLL注入程序的入口函数
    //  参数 : 
    //  返回 : 无
    //  主要思路 : 首先得到需要注入的dll的绝对路径,然后获取远程进程的调试权限(XP下有的
    //             进程写数据时需要调试权限),然后申请一块可读可写的内存,再将dll的绝对
    //             路径写到远程进程刚申请的进程空间里,获取远程进程的LoadLibraryA函数的
    //             地址,再开启一个远程线程,加载dll
    //  日期 : 2016年6月1日 18:35:34(注释日期)
    //==================================================================================
    //函数说明结束
int main()
{
    char lpDllName[260] = {0};         //保存dll绝对路径

    HANDLE hProcess = NULL;            //进程句柄
    HANDLE hNewRemoteThread = NULL;    //远程线程句柄

    LPVOID lpLoadDll = LoadLibraryA;   //LoadLibraryA的指针
    LPVOID lpRemoteBuf = NULL;         //远程进程存放dll绝对路径的控件地址指针

    DWORD dwSize = 0;                  //dll绝对路径长度
    DWORD dwNewThreadId = 0;           //远程线程PID
    DWORD dwWrite = 0;                 //实际写入远程进程空间的字节数

    int pid = 0;                       //远程进程PID

    GetCurrentDirectoryA(260, lpDllName);   //获取当前程序目录
    strcat(lpDllName, "\\dllDemo.dll");     //获取dll绝对路径

    if(EnableDebugPriv(SE_DEBUG_NAME))      //获取远程进程调试权限
    {
        fprintf(stderr, "Add Privilege Failed!!\n");
    }

    printf("请输入要注入的进程pid : ");
    scanf("%d", &pid);                      //输入远程进程PID

    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);   //打开远程进程句柄,获取全部权限
    if (NULL == hProcess)
    {
        fprintf(stderr, "\n获取进程句柄失败!\n,错误码 : %d", GetLastError());
        exit(1);
    }

    dwSize = strlen(lpDllName) + 1;         //得到dll路径长度+1,这个是开辟远程进程空间的大小
    lpRemoteBuf = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); //申请远程进程一段可读可写的空间

    if (WriteProcessMemory(hProcess, lpRemoteBuf, lpDllName, dwSize, &dwWrite))  //写入dll绝对路径
    {
        if (dwWrite != dwSize)             //如果没有将路径写完,则释放申请的空间并退出
        {
            VirtualFreeEx(hProcess, lpRemoteBuf, dwSize, MEM_COMMIT);
            CloseHandle(hProcess);
            exit(2);
        }
    }
    else                                  //如果写入失败则报出错代码并退出
    {
        fprintf(stderr, "\n写入远程进程内存出错\n出错码 : %d", GetLastError());
        CloseHandle(hProcess);
        exit(3);
    }

    //开启远程线程,加载dll
    hNewRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadDll, lpRemoteBuf, 0, &dwNewThreadId);
    if(NULL == hNewRemoteThread)  //如果开启线程失败,则报出错码并退出
    {
        fprintf(stderr, "\n建立远程线程失败\n错误码 : %d", GetLastError());
        CloseHandle(hProcess);
        exit(4);
    }

    //WaitForSingleObject(hNewRemoteThread, INFINITE);
    CloseHandle(hProcess);
    CloseHandle(hNewRemoteThread);

    return 0;

}
版权声明:本文为博主原创文章,未经博主允许不得转载。

《Windows核心编程》之“DLL注入”(一)

一、背景知识 1,Private Address Space         在Windows操作系统中,每个进程都有自己私有的地址空间(private address space)。各个进程的地址空...
  • Sagittarius_Warrior
  • Sagittarius_Warrior
  • 2016年08月09日 16:29
  • 1562

Dll注入经典方法完整版

 Pnig0s1992:算是复习了,最经典的教科书式的Dll注入。 总结一下基本的注入过程,分注入和卸载 注入Dll: 1,OpenProcess获得要注入进程的句柄 2,Virtu...
  • xumaojun
  • xumaojun
  • 2013年12月09日 20:58
  • 3133

(开源) Ring3下的DLL注入工具 x86&x64(NtCreateThreadEx + LdrLoadDll方式实现,可以注入系统进程)

工具介绍及使用请移步:http://blog.csdn.net/sunflover454/article/details/50441014 本文首发在零日安全论坛:http://www.jmpoep....
  • sunflover454
  • sunflover454
  • 2015年12月31日 13:40
  • 7787

API hook原理和实例快速入门(inline hook),以dll线程注入方式使用(win7-64bit)

一个完整的hook,如果hook程序是以dll形式生成的,是分两步:1.完成dll本身的设计和生成,2.完成dll注入程序的设计和生成 本文完成第一步。 第二步在http://blog.csdn....
  • wxdvc
  • wxdvc
  • 2012年10月26日 15:55
  • 5848

32位程序注入64位DLL到64位进程

向其他进程注入DLL通常的做法是通过调用CreateRemoteThread这个API在目标进程内创建一个远程线程,用这个线程来调用LoadLibraryA或LoadLibraryW(下文统称Load...
  • jiangqin115
  • jiangqin115
  • 2015年08月23日 17:58
  • 2880

通过Hook将DLL注入进程

首先,读这篇文章之前,默认已经掌握了进程地址空间,dll加载,windows Hook技术。 1. 为什么需要dll注入? 如果一个进程的程序是我们自己编写的,我们可以在程序中隐式或者显式地加载需...
  • frank_liuxing
  • frank_liuxing
  • 2013年10月18日 10:16
  • 2939

DLL劫持注入技术分析、过各种游戏保护!让你做你爱做的事情!

劫持DLL就是要制作一个“假”的DLL,但是功能又不能失真。 可执行文件在调用某函数时,要加载该函数所在的DLL。如果我们伪造一个DLL,让它包含所有被劫持DLL的导出函数。可执行文件会运行加...
  • chinazhd
  • chinazhd
  • 2013年09月04日 01:07
  • 10919

DLL的远程注入及卸载技术详解

DLL的远程注入技术是目前Win32病毒广泛使用的一种技术。使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运...
  • sky04
  • sky04
  • 2011年11月30日 13:27
  • 2255

利用CreateProcess实现程序未启动前的监视,并注入DLL!

一、DLL注入技术的用途 DLL注入技术的用途是很广泛的,这主要体现在: 1、假如你要操纵的对象涉及的数据不在进程内; 2、你想对目标进程中的函数进行拦截(甚至API函数,嘿嘿,由此...
  • a7082633
  • a7082633
  • 2016年03月05日 09:29
  • 688

Ring3下Dll注入方法整理汇总

1.dll劫持,粗略整理了下,可以劫持的dll有(持续更新): lpk.dll、usp10.dll、msimg32.dll、midimap.dll、ksuser.dll、comres.dll、ddr...
  • liujiayu2
  • liujiayu2
  • 2016年06月30日 11:08
  • 558
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DLL注入
举报原因:
原因补充:

(最多只允许输入30个字)