吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 20656|回复: 56
收起左侧

[C&C++ 原创] 【C语言】编写的DLL注入工具

  [复制链接]
bubbletea 发表于 2018-2-15 00:51
本帖最后由 wushaominkk 于 2018-4-26 11:11 编辑

现已更新附件,之前的代码有个地方有问题,EjectDll.c中第77行return 1;之前加上一句
((PFFREELIBRARY)pParam->pFunc[5])(hModule);
再编译生成一下,否则不执行用户输入的卸载时执行函数就无法卸载DLL。
最近学习了几种DLL注入的方式,这里分享一个我写的DLL注入工具(ring3),编译平台是windows7 32位+VS2013,含32位和64位,win10上测试了一下也能运行。

1.png
注入方式使用的是代码注入,参考了《逆向工程核心原理》中的相关代码。代码注入占用内存少并难以查找痕迹,在代码量小的时候比较合适。

不过这边有一个问题就是在执行用户选择的启动函数时我选择让目标进程使用CreateThread来调用dll的导出函数,这样做是否合适?测试了一些暂时还没发现什么问题

[C] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
// 参数类型
typedef struct _INJECTTHREAD_PARAM
{
        FARPROC pFunc[3];
        char szBuf[2][128];
} INJECTTHREAD_PARAM, *PINJECTTHREAD_PARAM;
 
// 此函数以代码形式注入目标进程
DWORD WINAPI InjectThreadProc(LPVOID param)
{
        PINJECTTHREAD_PARAM pParam = (PINJECTTHREAD_PARAM)param;
        HMODULE hModule;
        FARPROC pFunc;
        HANDLE hThread;
 
        // 注入的代码里不能直接调用API函数
        // LoadLibraryA(szDllPath)
        hModule = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]);
        if (!hModule)
        {
                return 1;
        }
 
        // GetProcAddress(hModule, szFunc)
        pFunc = ((PFGETPROCADDRESS)pParam->pFunc[1])(hModule, pParam->szBuf[1]);
        if (!pFunc)
        {
                return 1;
        }
 
        // CreateThread()执行加载时要运行的函数, 不知道使用这种方式合不合适
        hThread = ((PFCREATETHREAD)pParam->pFunc[2])(NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, NULL, 0, NULL);
 
        return 0;
}
 
BOOL InjectDll(DWORD dwPID, LPCSTR szDllPath, LPCSTR szFunc)
{
        HMODULE hModule;
        INJECTTHREAD_PARAM param;
        HANDLE hProcess;
        HANDLE hThread;
        LPVOID pRemoteBuf[2];
        DWORD dwSize;
 
        hModule = GetModuleHandleW(L"kernel32.dll");
        memset(¶m, 0, sizeof(INJECTTHREAD_PARAM));
        // 要进行代码注入, 就必需要把要调用参数先写入目标进程
        param.pFunc[0] = GetProcAddress(hModule, "LoadLibraryA");
        param.pFunc[1] = GetProcAddress(hModule, "GetProcAddress");
        param.pFunc[2] = GetProcAddress(hModule, "CreateThread");
        strcpy_s(param.szBuf[0], strlen(szDllPath) + 1, szDllPath);
        strcpy_s(param.szBuf[1], strlen(szFunc) + 1, szFunc);
 
        if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
        {
                return FALSE;
        }
 
        // 判断环境
        if (Is64BitProcess(GetCurrentProcess()) != Is64BitProcess(hProcess))
        {
                MessageBox(NULL, TEXT("打开动态链接库文件失败"), TEXT("提示"), MB_ICONERROR | MB_OK);
                CloseHandle(hProcess);
                return FALSE;
        }
 
        dwSize = sizeof(INJECTTHREAD_PARAM);
        if (!(pRemoteBuf[0] = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE)))
        {
                return FALSE;
        }
        // 将全部的参数作为结构体整个写入
        if (!WriteProcessMemory(hProcess, pRemoteBuf[0], (LPVOID)¶m, dwSize, NULL))
        {
                return FALSE;
        }
 
        dwSize = (DWORD)InjectDll - (DWORD)InjectThreadProc;
        if (!(pRemoteBuf[1] = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE)))
        {
                return FALSE;
        }
        // 再将InjectThreadProc的函数代码写入目标进程
        if (!WriteProcessMemory(hProcess, pRemoteBuf[1], (LPVOID)InjectThreadProc, dwSize, NULL))
        {
                return FALSE;
        }
 
        // pRemoteBuf[1]就是InjectThreadProc在目标进程中的起始地址, 已经被写入, pRemoteBuf[0]则是写入的参数地址
        if (!(hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteBuf[1], pRemoteBuf[0], 0, NULL)))
        {
                return FALSE;
        }
 
        WaitForSingleObject(hThread, INFINITE);
 
        VirtualFreeEx(hProcess, pRemoteBuf[0], 0, MEM_RELEASE);
        VirtualFreeEx(hProcess, pRemoteBuf[1], 0, MEM_RELEASE);
 
        CloseHandle(hThread);
        CloseHandle(hProcess);
 
        return TRUE;
[align=left]
}

DLL Injector.zip

435.86 KB, 下载次数: 2014, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 14吾爱币 +14 热心值 +11 收起 理由
smile1110 + 1 热心回复!
1154h + 1 高手啊,学习学习
zldtb19931116 + 1 + 1 谢谢@Thanks!
ok199793 + 1 + 1 谢谢@Thanks!
hjm666 + 1 谢谢@Thanks!
qin1980k + 1 + 1 谢谢@Thanks!
wangbingbing + 1 用心讨论,共获提升!
wushaominkk + 3 + 1 鼓励新人贴,吾爱因你更精彩!
yaojia100 + 1 + 1 谢谢@Thanks!
龟仔龟龟 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ZiPP + 1 + 1 谢谢@Thanks!
BY丶显示 + 2 + 1 谢谢@Thanks!
锋霜 + 1 + 1 热心回复!
帅到被排挤 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| bubbletea 发表于 2018-5-14 20:52
AIDONG 发表于 2018-5-14 00:11
加载时执行函数 要怎么填 。。。。。。

填你编写的DLL里的导出函数名字来执行你的函数代码,没有就不填了
yangchunlang 发表于 2019-1-8 08:53
个问题就是在执行用户选择的启动函数时我选择让目标进程使用CreateThread来调用dll的导出函数,这样做是否
帅到被排挤 发表于 2018-2-15 00:59
绝美之城 发表于 2018-2-15 01:00
感谢楼主热心分享。
BY丶显示 发表于 2018-2-15 01:26
下载学习一下,谢谢楼主分享。
xiaoyima 发表于 2018-2-15 01:48
明天试试,注入能检测到不
djswzw 发表于 2018-2-15 02:10
谢谢分享 学习学习
peter_king 发表于 2018-2-15 02:12
感谢无私的分享!!
大虾米的爱情 发表于 2018-2-15 02:31
感谢分享源码
xie83544109 发表于 2018-2-15 09:41

多谢楼主分享哟
follower 发表于 2018-2-15 09:56 来自手机
小白来学习了。谢谢代码。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-1 20:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表