之前有介绍过HOOK的方式注入,这次介绍以其它方式注入,而无须HOOK,要知道在Windows这个浩荡的海洋里,API就是宝藏,找到足够多的宝藏那么你就是海贼王~!

实现思路如下:

首先打开一个进程的地址空间,然后开辟一块空间将动态库copy进去,然后找到动态库要调用的函数首地址,在调用此函数!

首先给大家介绍几个dll注入的方法:

1.通过调用Kernel32动态库里的LoadLibraryW函数来加载dll到指定进程下,然后在创建远线程!

这是最常用的一个方法,但是很遗憾这种方法可用性并不大,因为在Win8和Win10以上你会发现可以创建远线程的进程没有几个,Windows内核里已经放弃这个API了,因为这个API本身就不是ring0级别的代码,Windows代代更新内核之后就已经不在支持这个API了!

那么来介绍一下实现这个方法的API:

有些API的原型我在其他文章里已经介绍过,这里就不重复介绍,有兴趣的可以去翻一下:

1.首先第一步使用FindWindow得到窗口句柄,

2.在使用OpenProcess打开窗口进程,但是需要获取窗口的PID,

3.所以要先使用GetWindowThreadProcessId获取PID,

4.在使用VirtualAllocEx开辟内存,开辟内存大小是要注入dll绝对路径的长度,

5.然后在使用WriteProcessMemory函数写入路径字符,

6.在使用GetProcAddress获取Kernel32里的LoadLibraryW函数地址!

7.在使用CreateRemoteThread函数将LoadLibraryW加载到指定进程下,然后调用传递参数

在此之前需要给大家介绍一下CreateRemoteThread,GetProcAddress以及GetModuleHandle这三个API:

1.CreateRemoteThread

HANDLE WINAPI CreateRemoteThread(
__in HANDLE hProcess,
__in LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out LPDWORD lpThreadId
);

参数介绍:

hProcess [in]
线程所属进程的进程句柄.
该句柄必须具有 PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE,和PROCESS_VM_READ 访问权限.
lpThreadAttributes [in]
一个指向 SECURITY_ATTRIBUTES 结构的指针, 该结构指定了线程的安全属性.
dwStackSize [in]
线程初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小.
lpStartAddress [in]
在远程进程的地址空间中,该线程的线程函数的起始地址.
lpParameter [in]
传给线程函数的参数.
dwCreationFlags [in]
线程的创建标志.
值   含义
0   线程创建后立即运行
CREATE_SUSPENDED    线程创建后先将线程挂起,直到 ResumeThread 被调用.
0x00000004
STACK_SIZE_PARAM_IS_A_RESERVATION   dwStackSize 参数指定为线程栈预订大小,如果STACK_SIZE_PARAM_IS_A_RESERVATION没有被指定,dwStackSize 参数指定为线程栈分配大小.
0x00010000
lpThreadId [out]
用来存放创建线程后的线程ID,如果线程创建成功,那么线程ID会被存放到这个变量里,一般不需要给NULL,如果创建失败则给NULL!
返回值:
成功返回非0否则可以使用GetLastError获取错误码

2.GetProcAddress

FARPROC GetProcAddress(
HMODULE hModule, // DLL模块句柄
LPCSTR lpProcName // 函数名
);
返回值:
如果函数调用成功,返回值是DLL中的输出函数地址。
如果函数调用失败,返回值是NULL。得到进一步的错误信息,调用函数GetLastError。

3.GetModuleHandle

HMODULE WINAPI GetModuleHandle(
_In_opt_LPCTSTR lpModuleName
);
lpModuleName String,指定模块名,这通常是与模块的文件名相同的一个名字。例如,NOTEPAD.EXE程序的模块文件名就叫作NOTEPAD。
返回值:
HMODULE,如执行成功成功,则返回模块句柄。零表示失败。获取错误信息,请调用
GetLastError。

其次可以使用

LoadLibrary

来映射指定模块

实现代码如下:
#include "windows.h"
int main()
{//程序的窗口句柄HWND hWnd = FindWindow(NULL, "123");if (hWnd == NULL) {MessageBox(NULL, "无法打开指定进程", "Error", 0);}//根据窗口句柄获取进程PIDDWORD Process_ID = (DWORD)0;GetWindowThreadProcessId(hWnd, &Process_ID);    //PID这里传址if (Process_ID == (DWORD)0) {    //判断是否与原值相同MessageBox(NULL, "无法获取进程PID", "Error", 0);}//打开进程HANDLE hPro = OpenProcess(PROCESS_CREATE_THREAD | //允许远程创建线程PROCESS_VM_OPERATION | //允许远程VM操作PROCESS_VM_WRITE,//允许远程VM写FALSE, Process_ID);if (hPro == NULL) {MessageBox(NULL, "无法打开进程空间", "Error", 0);}// 在远程进程中为路径名称分配空间char str[256] = { 0 };strcpy_s(str,"d:\\3.dll"); //你的dll路径int dwSize = (lstrlenA(str)+1);  //路径大小+1是因为\0//开辟空间LPVOID pszLibFileRemote = (PWSTR)VirtualAllocEx(hPro, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);if (pszLibFileRemote == NULL) {MessageBox(NULL, "无法开辟内存!", "Error", 0);return -1;}//写入数据DWORD  dwWritten; //写入字节数DWORD n = WriteProcessMemory(hPro, (LPTHREAD_START_ROUTINE)pszLibFileRemote, "d:\\4.dll", dwSize, &dwWritten);if (n == NULL) {MessageBox(NULL, "无法写入内存!", "Error", 0);return -1;}//Kernel32模块已经被包含在依赖库里自动加载进来了,所以我们可以直接获取PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA");if (pfnThreadRtn == NULL) {MessageBox(NULL, "无法获取dll库函数", "Error", 0);return -1;}//创建远线程DWORD dwID = NULL;HANDLE hThread = CreateRemoteThread(hPro, 0, 0, pfnThreadRtn, pszLibFileRemote, 0, &dwID);if (hThread == NULL) {MessageBox(NULL, "无法创建远线程!", "Error", 0);printf("%d", GetLastError());}//等待线程结束WaitForSingleObject(hThread, INFINITE);return 0;
}

这里有个程序博主已经写好的了:

dll代码:

#include <windows.h>
BOOL APIENTRY DllMain(HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved
)
{MessageBox(NULL, "wed", "wed", 0);return TRUE;
}

运行结果:

可以看到已经成功注入到指定窗口下了,而且信息框也是在指定窗口下弹出的!

这里有几个加载问题给大家解释一下:

GetProcAddress是获取当前模块下指定函数的地址,注意是当前进程下的,那么为什么CreateRemoteThread

是创建远程函数应该给远程函数的地址才对,为什么是本地下的?

答:

这是Windows的一套机制,在Windows上运行的话会附加一系列的依赖库,这些依赖库在加载到内存中会被存放在

进程的空间下,但不是乱放的,是有序加载的,而且是通过模块表来记录每个模块的内存位置,而这些顺序在不同的操作系统下可能不同(xp以下是在注册表里的,可以通过修改注册表的方式来加载自己的dll,但在xp以上就不可行了

xp注册表装载dll方式:

打开

HKEY_LOCAL_MACHINE\SoftWare\MicroSoft\Windows NT\CurrentVersion\Windows\

找到:

AppInit_Dlls健值,在里面添加上你的dll绝对路径,用“,”号分开

但是GetProcAddress可以很好的帮我们从模块表里找到我们需要的地址,然后返回给我们,然后我们在给它偏移量,最后CreateRemoteThread

在创建的时候会根据句柄找到对应的段地址,在GDT表-LRT表里找到对应的物理地址在偏移量相加即成为每个程序的模块函数地址!

这样的方法仅在win7以下有效,win7以上需要提权!但Win10以后的系统程序无法注入dll!

并且调用LoadLibraryW函数会注册你的dll模块到程序中的模块表里,所以可以被第三方查询出来是否有可疑dll注入!

当然注入方法不止这一种你可以调用其它的创建线程函数来创建远线程!

Windows核心编程_远线程方式实现Dll注入相关推荐

  1. Windows核心编程_设置Windows开机自动登录

    设置自动登录的方法在Windows中已经给出了非常方便的方法,当Windows内核进入登入界面时会检查HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ ...

  2. Windows核心编程_获取鼠标指定位置的RGB颜色值

    Windows核心编程_获取鼠标指定位置的RGB颜色值 大家平常会见到很多屏幕取色工具,其原理都是获取鼠标位置的屏幕像素点颜色! 一般思路都是:获取鼠标位置,然后取出鼠标指向的屏幕像素点颜色! Get ...

  3. Windows核心编程_提权

    在Windows下编程有些涉及到硬件或者跨内存的API会发现失效了,原因是因为权限问题,这也是Windows出于安全的保护,但是事物都有两面性的,Windows又为我们提供了提权的API! 1.Adj ...

  4. Windows核心编程_实现QQ好友来消息时任务栏头像闪烁功能

    当QQ好友来消息时,任务栏会发出通知,如: 实现方法: FlashWindow 函数原型: BOOL WINAPI FlashWindow(__in HWND hWnd, //要闪烁的窗口的句柄,该窗 ...

  5. Windows核心编程 第八章 用户方式中线程的同步(下)

    8.4 关键代码段 关键代码段是指一个小代码段,在代码能够执行前,它必须独占对某些共享资源的访问权.这是让若干行代码能够"以原子操作方式"来使用资源的一种方法.所谓原子操作方式,是 ...

  6. Windows核心编程 第八章 用户方式中线程的同步(上)

    第8章 用户方式中线程的同步 当所有的线程在互相之间不需要进行通信的情况下就能够顺利地运行时, M i c r o s o f t Wi n d o w s的运行性能最好.但是,线程很少能够在所有的时 ...

  7. Windows核心编程 第九章 线程与内核对象的同步(下)

    9.4 等待定时器内核对象 等待定时器是在某个时间或按规定的间隔时间发出自己的信号通知的内核对象.它们通常用来在某个时间执行某个操作. 若要创建等待定时器,只需要调用C r e a t e Wa i ...

  8. Windows核心编程_修改其它进程里的内存值+示例:修改游戏分数

    最近一直忙于Opencv图像处理方面的学习,以及工作,没有更新C/C++专栏方面的博客了,所以今天就给大家写个应用层方面的编程代码,可用于参考学习,本篇博客将运用WindowsSDK库所提供的API来 ...

  9. Windows核心编程 第九章 线程与内核对象的同步(上)

    第9章 线程与内核对象的同步 上一章介绍了如何使用允许线程保留在用户方式中的机制来实现线程同步的方法.用户方式同步的优点是它的同步速度非常快.如果强调线程的运行速度,那么首先应该确定用户方式的线程同步 ...

最新文章

  1. 100万年薪只是起步价!跨境AI人才遭疯抢后最终去了哪儿?
  2. 华云数字实名认证图片_华云数据与安宁完成产品兼容互认证 携手推出安宁安全邮件系统联合解决方案...
  3. Ubuntu触摸板使用
  4. 【Google Play】Android 应用隐私政策 ( 生成隐私政策 | HTML 隐私政策模板 | Markdown 隐私政策模板 )
  5. Alpha 冲刺 —— 十分之八
  6. webstorm2018破解方法
  7. ITK:计算Sigmoid
  8. 漫游飞行_手机“飞行模式”为何没被淘汰?内行人坦言:其实是你不会用!
  9. vue插槽面试题_VUE面试题解析,半年出一篇,建议收藏!
  10. python 数据库接口_Python3笔记050 - 11.1 数据库接口
  11. Django:新手入门学习资料汇总
  12. 上海服务器虚拟机系统,服务器虚拟机系统重装系统
  13. mysql正则mybatis中用法_SQL 正则表达式及mybatis中使用正则表达式
  14. 【数据可视化应用】绘制风玫瑰图(附Python代码)
  15. 改oracle sockets,安装GI最后检查时出现warning - Domain Sockets,PRVG-11750
  16. ios 开发控件中心点_iosapp开发控件大盘点
  17. Linux - 微软无线鼠标滚动过快问题
  18. 图像的二值化原理和实现
  19. webInspect SprinBoot2.x安全整改
  20. 沃尔玛中国前CEO陈文渊将出任百事亚太区CEO;山姆再次下调近百种畅销单品价格 | 美通企业日报...

热门文章

  1. 内存颗粒和闪存颗粒的区别_颠覆你的常识,这内存上面混搭了四个厂家的颗粒...
  2. python修复不了_python-如何修复cm.spectral(模块“ matplotlib.cm”...
  3. Linux用scp实现无密码传输文件和目录(使用密钥)
  4. 如何用C++从文件读取学生成绩再求出平均成绩送回文件中
  5. java的equals什么作用_java当中equals函数的作用小结
  6. python read函数参数_最新Pandas.read_excel()全参数详解(案例实操,如何利用python导入excel)...
  7. 10年老电脑如何提速_2020年10月和双十一轻薄本/轻薄型笔记本电脑如何挑选?内含轻薄本/轻薄型笔记本电脑推荐!...
  8. 错误: 编码GBK的不可映射字符 - Android Studio 生成javadoc文档时报错
  9. winform界面嵌入dwg图纸_完美解决窗体中预览DWG图形(C#版)
  10. 在html中使用css的主要方式有,html中使用css的方法有哪几种