远程线程DLL注入64位进程
int main()
{
BOOL bFlag = FALSE; char *szDllName = "MSGDLL.dll";
//bFlag = EnablePrivilege(SE_DEBUG_NAME); //返回值为1时代表成功 //得到目标进程句柄
HANDLE hDestProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ); LPTHREAD_START_ROUTINE dwAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA"); //在目标进程的地址空间内分配一个内存块
LPVOID pRemoteSpace = VirtualAllocEx(hDestProcess, NULL, strlen(szDllName) + , MEM_COMMIT,
PAGE_READWRITE); //向上一步的内存块中写入数据,就是要加载的DLL名字
bFlag = WriteProcessMemory(hDestProcess, pRemoteSpace, szDllName, strlen(szDllName) + , ); //在目标进程内创建线程,线程的入口函数就是LoadLibraryA, 参数就是Dll名字
HANDLE hThread = CreateRemoteThread(hDestProcess, NULL, , dwAddr, pRemoteSpace,
NULL,
); //前面都是成功的,就到了这一步,返回的错误是5,Access denied,权限不够
//本来以为我的VS是以管理员权限启动的,那么我这个进程应该权限就都够了,
//看来不行,必须程序提权
//我提权了之后,发现还是不行,之后上网查了
//发现是32位注入到64位中会有问题,所以我换了个x64,然后显然线程运行成功了,
//但是现在远程进程却崩溃了,估计是DLL是32的,我换个DLL编译方式再试试
//我编译了64位的DLL,然后还是崩溃的,之后我发现了应该是我函数地址传的有问题
//因为32位的LoadLibraryA地址是DWORD,但64位却是ULONGLONG,所以仅仅改变编译方式还不够
//必须用一个足够容纳8个字节地址的类型来保存,这样就够了 //另外一个需要注意的问题就是,为什么我在我这个进程中得到的LoadLibrary在远程进程中也可以用
//答案就是,系统DLL在各个进程中的映射地址都是一样的,不过具体情况具体分析,至少这个函数看来是一样的。 //在我完成了之后,我把EnablePrivileges这行注释掉了,但仍然注入成功,看来我用管理员权限运行VS2015之后就够了 //然后我又发现了一个问题,就是对同一个进程,加载dll只能一次,第二次就不会弹了
//原因,我目测是,DLL已经被加载了,所以第二次就不加载了,也就不执行DllMain那个函数了
//除非我创建一个线程再UnLoad那个LIB,之后再LOAD,这样应该就可以了
//也可以换个Dll名字,再LOAD, 反正方法很多。 DWORD dwErr = GetLastError(); return ;
}
//DLL的代码,用DLL方式生成一下,拉到前面EXE目录,或者系统目录都行,跟前面代码中DLL名字有没有加绝对路径有关
//这代码是书上的代码,直接复制了
/* ************************************
*《精通Windows API》
* 示例代码
* msg.c
* 6.5 动态链接库
**************************************/
/* 头文件 */
#include <Windows.h>
#include <Psapi.h>
/* 链接 */
#pragma comment (lib, "Psapi.lib")
/* 函数声明 */ // 使用__declspec(dllexport)声明导出函数
__declspec(dllexport) DWORD ExportExample(LPSTR szMsg, DWORD dwCode); /*************************************
* DllMain
**************************************/
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // DLL模块的句柄
DWORD fdwReason, // 调用的情况
LPVOID lpReserved) // reserved
{
// 在不同的情况下都会调用DllMain函数,分别处理
switch (fdwReason)
{
// 加载Dll
case DLL_PROCESS_ATTACH:
{
CHAR lpMainMoudleName[MAX_PATH];
CHAR lpMessage[MAX_PATH + ];
// 获取PID 和主模块名,将弹出消息框
DWORD dwPID = GetCurrentProcessId();
GetModuleBaseName(GetCurrentProcess(), NULL, lpMainMoudleName, MAX_PATH);
wsprintf(lpMessage, "Process name: %s, PID: %u ", lpMainMoudleName, dwPID);
MessageBox(NULL, lpMessage, "msg.dll", MB_OK);
break;
}
// 新建线程
case DLL_THREAD_ATTACH:
break;
// 线程退出
case DLL_THREAD_DETACH:
break;
// 释放Dll
case DLL_PROCESS_DETACH: break;
}
return TRUE;
} /*************************************
* DWORD ExportExample(LPSTR szMsg, DWORD dwCode)
* 功能 导出函数,显示消息
*
* 参数 LPSTR szMsg 字符串; DWORD dwCode 整形
**************************************/
DWORD ExportExample(LPSTR szMsg, DWORD dwCode)
{
LPVOID lpShowOut = HeapAlloc(GetProcessHeap(), , lstrlen(szMsg) + );
wsprintf((LPSTR)lpShowOut, "%s,%d", szMsg, dwCode);
MessageBox(NULL, (LPSTR)lpShowOut, "由导出函数弹出的消息!", MB_OK);
HeapFree(GetProcessHeap(), , lpShowOut);
return ;
}
需要注意的点都在那一大串注释中
64位进程,就得用64位的EXE来CreateRemoteThread, 另外DLL也应该是64位
32位进程,就得用32位的EXE来CreateRemoteThread, 另外DLL也应该是32位
把CreateRemoteThread的入口点函数设为LoadLibraryA(W),线程的那个参数设为DLL路径指针(在目标进程中,所以得把DLL路径拷到目标进程 中, 用VirtualAllocEx在目标进程中分配块空间,然后WriteProcessMemory).
这样可行的原因:
线程的函数原型DWORD ThreadProc(LPVOID lpParam)
LoadLibrary的函数原型HMODULE LoadLibrary(LPCTSTR lpFileName);
其实是一样的,指针都是同样大小,都只有一个参数,返回值无所谓..
另外在目标进程和本进程中LoadLibraryA(W)的虚拟地址是一样的..
远程线程DLL注入64位进程的更多相关文章
- Wow64(32位进程)注入DLL到64位进程
转载自: https://blog.poxiao.me/p/wow64-process-inject-dll-into-x64-process/ 向其他进程注入DLL通常的做法是通过调用CreateR ...
- 实现远程线程DLL注入
### 32位:远程线程注入 远程线程注入是最常用的一种注入技术,该技术利用的核心API是 `CreateRemoteThread()` 这个API可以运行远程线程,其次通过创建的线程调用 `Load ...
- 【windows核心编程】远程线程DLL注入
15.1 DLL注入 目前公开的DLL注入技巧共有以下几种: 1.注入表注入 2.ComRes注入 3.APC注入 4.消息钩子注入 5.远线程注入 6.依赖可信进程注入 7.劫持进程创建注入 8.输 ...
- 使用远程线程来注入DLL
使用远程线程来注入DLL DLL注入技术要求我们目标进程中的一个线程调用LoadLibrary来载入我们想要的DLL (1)用OpenProcess函数打开目标进程(2)用VirtualAllocEx ...
- 《windows核心编程系列》十九谈谈使用远程线程来注入DLL。
windows内的各个进程有各自的地址空间.它们相互独立互不干扰保证了系统的安全性.但是windows也为调试器或是其他工具设计了一些函数,这些函数可以让一个进程对另一个进程进行操作.虽然他们是为调试 ...
- Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储
在VS2013中调试Silverlight项目时,提示:无法附加.Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储.请改用64位版本. ...
- 64位进程调用32位dll的解决方法 / 程序64位化带来的问题和思考
最近做在Windows XP X64,VS2005环境下做32位程序编译为64位程序的工作,遇到了一些64位编程中可能遇到的问题:如内联汇编(解决方法改为C/C++代码),long类型的变化,最关键的 ...
- 64位进程调用32位dll的解决方法
64位进程调用32位dll的解决方法 最近做在Windows XP X64,VS2005环境下做32位程序编译为64位程序的工作,遇到了一些64位编程中可能遇到的问题:如内联汇编(解决方法改为C/ ...
- Dll注入:X86/X64 远程线程CreateRemoteThread 注入
远线程注入原理是利用Windows 系统中CreateRemoteThread()这个API,其中第4个参数是准备运行的线程,我们可以将LoadLibrary()填入其中,这样就可以执行远程进程中的L ...
随机推荐
- Android动态方式破解apk进阶篇(IDA调试so源码)
一.前言 今天我们继续来看破解apk的相关知识,在前一篇:Eclipse动态调试smali源码破解apk 我们今天主要来看如何使用IDA来调试Android中的native源码,因为现在一些app,为 ...
- build/envsetup.sh 生成的命令详解表
参考: https://wiki.cyanogenmod.org/w/Envsetup_help 它是一个.sh文件,用source后就生成android编译相关函数,具体如下. 速查 Invokin ...
- EF常用命令行
启用迁移:指定迁移的目录和数据库上下文名称Enable-Migrations -MigrationsDirectory "MigrationsHis" -ContextTypeNa ...
- Extjs MVC学习随笔01
Extjs Mvc模式下的整个MVC框架体系即下图: 包含了Controller(实现方法层),Store(数据来源管理层),View(页面布局层).之所以用MVC我想是因为减轻针对某一页面的单一的J ...
- phprpc的简单使用
PHPRPC 是一个轻型的.安全的.跨网际的.跨语言的.跨平台的.跨环境的.跨域的.支持复杂对象传输的.支持引用参数传递的.支持内容输出重定向的.支持分级错误处理的.支持会话的.面向服务的高性能远程过 ...
- php : 收集整理的非常有用的函数
项目中经常会需要一些让人头疼的函数,作为开发者应该整理一个自己的函数库,在需要之时复制过来即可.以下是收集整理数十个PHP项目中常用的函数 1.PHP加密解密 PHP加密和解密函数可以用来加密一些有用 ...
- U盘修复
方法一: 1.点开始-运行-输入cmd-format f: /fs: FAT32 (这里f:是指U盘所在盘符) 2.打开控制面板-管理工具-计算机管理-磁盘管理-找到U盘的所在的盘符--点右键--删除 ...
- HTML中使背景图片自适应浏览器大小
由于<body>标签的图片不能够拉伸, 解决办法: 1.图片不够大,又background属性不能拉伸图片: 2.只能用个div,把其z-index值设为负,并使这个div大小为整个bod ...
- Java多线程同步 synchronized 关键字的使用
代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A, ...
- Struts2配置Result(Struts2_result)
一.概要 二.常用四种类型的配置 Struts.xml <?xml version="1.0" encoding="UTF-8" ?> <!D ...