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位进程的更多相关文章

  1. Wow64(32位进程)注入DLL到64位进程

    转载自: https://blog.poxiao.me/p/wow64-process-inject-dll-into-x64-process/ 向其他进程注入DLL通常的做法是通过调用CreateR ...

  2. 实现远程线程DLL注入

    ### 32位:远程线程注入 远程线程注入是最常用的一种注入技术,该技术利用的核心API是 `CreateRemoteThread()` 这个API可以运行远程线程,其次通过创建的线程调用 `Load ...

  3. 【windows核心编程】远程线程DLL注入

    15.1 DLL注入 目前公开的DLL注入技巧共有以下几种: 1.注入表注入 2.ComRes注入 3.APC注入 4.消息钩子注入 5.远线程注入 6.依赖可信进程注入 7.劫持进程创建注入 8.输 ...

  4. 使用远程线程来注入DLL

    使用远程线程来注入DLL DLL注入技术要求我们目标进程中的一个线程调用LoadLibrary来载入我们想要的DLL (1)用OpenProcess函数打开目标进程(2)用VirtualAllocEx ...

  5. 《windows核心编程系列》十九谈谈使用远程线程来注入DLL。

    windows内的各个进程有各自的地址空间.它们相互独立互不干扰保证了系统的安全性.但是windows也为调试器或是其他工具设计了一些函数,这些函数可以让一个进程对另一个进程进行操作.虽然他们是为调试 ...

  6. Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储

    在VS2013中调试Silverlight项目时,提示:无法附加.Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储.请改用64位版本. ...

  7. 64位进程调用32位dll的解决方法 / 程序64位化带来的问题和思考

    最近做在Windows XP X64,VS2005环境下做32位程序编译为64位程序的工作,遇到了一些64位编程中可能遇到的问题:如内联汇编(解决方法改为C/C++代码),long类型的变化,最关键的 ...

  8. 64位进程调用32位dll的解决方法

    64位进程调用32位dll的解决方法   最近做在Windows XP X64,VS2005环境下做32位程序编译为64位程序的工作,遇到了一些64位编程中可能遇到的问题:如内联汇编(解决方法改为C/ ...

  9. Dll注入:X86/X64 远程线程CreateRemoteThread 注入

    远线程注入原理是利用Windows 系统中CreateRemoteThread()这个API,其中第4个参数是准备运行的线程,我们可以将LoadLibrary()填入其中,这样就可以执行远程进程中的L ...

随机推荐

  1. 函数动态参数实现format

    变量赋值一种是字符串格式化,一种是通过format的方式 1.字符串格式化 s="i am %s,age %d"%('Jasper',23)print(s) 打印输出:i am J ...

  2. 从零开始学习Android(二)从架构开始说起

    我们刚开始学新东西的时候,往往希望能从一个实例进行入手学习.接下来的系列连载文章也主要是围绕这个实例进行.这个实例原形是从电子书<Android应用开发详解>得到的,我们在这里对其进行详细 ...

  3. 【前端】JavaScript获取指定范围内的随机整数

    function getRandomIntNumber(min, max) { var span = max - min + 1; var result = Math.floor(Math.rando ...

  4. Oracle客户端配置

    1.  打开开发生产数据库系统,点击下载Oracle_12C_Client32,并且解压缩. 2.  找到文件下的setup.exe文件,并且执行. 3.  等待数秒,在如下界面中选择第二项,管理员, ...

  5. 后缀数组:倍增法和DC3的简单理解

    一些定义:设字符串S的长度为n,S[0~n-1]. 子串:设0<=i<=j<=n-1,那么由S的第i到第j个字符组成的串为它的子串S[i,j]. 后缀:设0<=i<=n- ...

  6. Sublime Text 3 提高工作效率的使用技巧

    Sublime Text 3对于Sublime Text 2压倒性的优势就是秒启动,启动非常非常快,所以从2012年到2016年我一直用Sublime Text 2,但是安装了3并且启动试用后,我再也 ...

  7. iOS - Share 分享/第三方登录

    1.系统方式创建分享 按照下图在 Info.plist 文件中将 Localization native development region 的值改为 China.如果不设置此项弹出的分享页面中显示 ...

  8. Java开发基础

    天数 课程 01 Java基础回顾 集合 泛型 IO流 多线程 Junit Properties   HTML   JavaScript   JavaScript   BOM编程   XML基础   ...

  9. Keil软件常见的警告和错误含义。——Arvin

    1. warning:  #767-D: conversion from pointer to smaller integer 解释:将指针转换为较小的整数 影响:可能造成的影响:容易引起数据截断,造 ...

  10. Mysql主从同步遇到的一些问题

    为提供更快的访问速度,在不同的地区增加了一台只供访问的从服务器.因此要将主服务器的数据全部备份过去,并且设置主从同步 假设: 主服务器IP:192.168.1.10 从服务器IP:192.168.1. ...