使用CreateRemoteThread注入DLL
DLL:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h> INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) {
/* open file */
FILE *file;
fopen_s(&file, "D:\\Case Folders\\2019-11-27\\CreateRemoteThread\\temp.txt", "a+"); switch (Reason) {
case DLL_PROCESS_ATTACH:
fprintf(file, "DLL attach function called.\n");
break;
case DLL_PROCESS_DETACH:
fprintf(file, "DLL detach function called.\n");
break;
case DLL_THREAD_ATTACH:
fprintf(file, "DLL thread attach function called.\n");
break;
case DLL_THREAD_DETACH:
fprintf(file, "DLL thread detach function called.\n");
break;
} /* close file */
fclose(file); return TRUE;
}
CreateRemoteThread program:
#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <TlHelp32.h>
#include <tchar.h> bool Inject(DWORD pId, const char *dllName)
{
HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, false, pId);
if (h)
{
LPVOID LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
LPVOID dereercomp = VirtualAllocEx(h, NULL, strlen(dllName), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(h, dereercomp, dllName, strlen(dllName), NULL);
HANDLE asdc = CreateRemoteThread(h, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, dereercomp, , NULL);
if (asdc == NULL) {
printf("Error: the remote thread could not be created.\n");
}
else {
printf("Success: the remote thread was successfully created.\n");
}
WaitForSingleObject(asdc, INFINITE);
VirtualFreeEx(h, dereercomp, strlen(dllName), MEM_RELEASE);
CloseHandle(asdc);
CloseHandle(h);
return true;
}
return false;
}
int _tmain(int argc, _TCHAR* argv[]) {
const char* buffer = "D:\\Case Folders\\2019-11-27\\CreateRemoteThread\\inject\\Debug\\inject.dll"; /*
* Get process handle passing in the process ID.
*/
int procID = ;
Inject(, "D:\\Case Folders\\2019-11-27\\CreateRemoteThread\\inject\\Debug\\inject.dll");
//HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
//if (process == NULL) {
// printf("Error: the specified process couldn't be found.\n");
//} ///*
//* Get address of the LoadLibrary function.
//*/
//LPVOID addr = (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
//if (addr == NULL) {
// printf("Error: the LoadLibraryA function was not found inside kernel32.dll library.\n");
//} ///*
//* Allocate new memory region inside the process's address space.
//*/
//LPVOID arg = (LPVOID)VirtualAllocEx(process, NULL, strlen(buffer), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
//if (arg == NULL) {
// printf("Error: the memory could not be allocated inside the chosen process.\n");
//} ///*
//* Write the argument to LoadLibraryA to the process's newly allocated memory region.
//*/
//int n = WriteProcessMemory(process, arg, buffer, strlen(buffer), NULL);
//if (n == 0) {
// printf("Error: there was no bytes written to the process's address space.\n");
//} ///*
//* Inject our DLL into the process's address space.
//*/
//HANDLE threadID = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)addr, arg, NULL, NULL);
//int err = GetLastError();
//if (threadID == NULL) {
// printf("Error: the remote thread could not be created.\n");
//}
//else {
// printf("Success: the remote thread was successfully created.\n");
//} /*
* Close the handle to the process, becuase we've already injected the DLL.
*/
//CloseHandle(process);
getchar(); return ;
}
检查被插入的进程是否包含inject.dll
#include <windows.h>
#include <Tlhelp32.h>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef basic_string<TCHAR, char_traits<TCHAR>, allocator<TCHAR> > tstring; int ProcessModule(DWORD);
int CheckProcessModule(DWORD pid);
BOOL IsModuleValid(tstring szModuleName);
int dwCount = ;
vector<tstring> patch;
vector<tstring> checkpatch; int main(void)
{ //进程创建完毕后的模块快照
ProcessModule();
cout << "******************当前模块*****************" << endl;
for (int i = ; i < patch.size(); i++)
{
cout << patch[i].c_str() << endl;
}
cout << endl << endl; LoadLibrary(TEXT("user32.dll"));//加载user32.dll测试 HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN | FOREGROUND_INTENSITY); //检测是否存在不同的模块
// CheckProcessModule(GetCurrentProcessId());
cout << "******************检测模块*****************" << endl;
for (int j = ; j < checkpatch.size(); j++)
{
cout << checkpatch[j].c_str() << endl;;
}
cout << endl << endl;
if (patch.size() == checkpatch.size())
{
cout << "没有检测到注入模块" << endl;
} return ;
} //获取进程模块
int ProcessModule(DWORD pid)
{ HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
if (hProcessSnap)
{
MODULEENTRY32 me32;
me32.dwSize = sizeof(MODULEENTRY32);
Module32First(hProcessSnap, &me32);//获取进程第一个模块信息
do
{
patch.push_back(me32.szModule);
//printf("模块路径:%s\n",me32.szExePath);
//printf("模块名:%s\n",me32.szModule);
//printf("模块基址:0x%08X\n",(DWORD)me32.modBaseAddr); } while (Module32Next(hProcessSnap, &me32));
CloseHandle(hProcessSnap);
return ;
}
else
{
cout << "获取进程快照失败" << endl;;
return ;
}
return ;
} int CheckProcessModule(DWORD pid)
{ HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
if (hProcessSnap)
{
MODULEENTRY32 me32;
me32.dwSize = sizeof(MODULEENTRY32);
Module32First(hProcessSnap, &me32);//获取进程第一个模块信息
do
{
checkpatch.push_back(me32.szModule);
if (!IsModuleValid(me32.szModule))
{
cout << "[可疑模块]:" << me32.szExePath << endl;
dwCount++;
} //printf("模块路径:%s\n",me32.szExePath);
//printf("模块名:%s\n",me32.szModule);
//printf("模块基址:0x%08X\n",(DWORD)me32.modBaseAddr); } while (Module32Next(hProcessSnap, &me32));
CloseHandle(hProcessSnap);
if (dwCount)
{
cout << "可疑模块数:" << dwCount << endl;
}
return ;
}
else
{
cout << "获取进程快照失败" << endl;
return ;
}
return ;
} BOOL IsModuleValid(tstring szModuleName)
{
// 遍历起始状态的模块列表
for (int i = ; i < patch.size(); i++)
{
if (patch[i] == szModuleName)
return TRUE;
}
return FALSE; }
部分解释:
介绍将用于将DLL注入到进程的地址空间中的整个过程。为了清楚地表明我们将要执行的操作,请看下面的图片,在该图片中,我们将向其中注入DLL的过程标有紫色,并命名为受害者。但是,我们需要澄清另外两个难题。首先,我们需要确定如果要将DLL注入到某个进程中,则必须首先拥有要注入的DLL。DLL以绿色呈现,并具有名称inject.dll。但是我们还必须有一个程序,该程序会将DLL注入受害者的地址空间。该程序以蓝色显示,名称为program.exe。
为了能够将DLL注入受害者的地址空间,program.exe必须顺序调用提供的函数。首先,它必须调用OpenProcess来获取受害者进程的句柄。之后,它必须调用GetProcAddress函数来获取kernel32.dll库中LoadLibraryA函数的地址。在这里,我们可以运行任何我们喜欢的函数,但是它必须存在于DLL中,该DLL已经加载在进程的地址空间中。我们知道每个程序都使用kernel32.dll库,因此将DLL注入到进程的地址空间中的最佳方法是查找LoadLibraryA函数并调用它。为了加载DLL,我们必须将DLL路径传递给LoadLibraryA函数,但是该名称需要存储在进程地址空间内的某个位置。明显,DLL的路径已经不太可能出现在进程的地址空间中,这就是为什么我们需要接下来的两个函数:VirtualAllocEx和WriteProcessMemory。第一个函数在进程的地址空间内分配一个新的内存范围。该内存区域的大小仅需要大到适合其内部DLL的名称即可;通常将大小四舍五入以占据至少一页。WriteProcessMemory是实际上将DLL的路径写入受害者的地址空间的函数。最后,调用CreateRemoteThread,该调用在受害者的地址空间内调用LoadLibraryA函数以向其中注入DLL。
更多信息请参考:https://resources.infosecinstitute.com/using-createremotethread-for-dll-injection-on-windows/#gref
使用CreateRemoteThread注入DLL的更多相关文章
- CreateRemoteThread注入DLL
DLL注入的常用方式之一远程线程注入,实现代码如下 // CreateRemoteThread.cpp : Defines the entry point for the application.// ...
- N种内核注入DLL的思路及实现
内核注入,技术古老但很实用.现在部分RK趋向无进程,玩的是SYS+DLL,有的无文件,全部存在于内存中.可能有部分人会说:"都进内核了.什么不能干?".是啊,要是内核中可以做包括R ...
- [转]N种内核注入DLL的思路及实现
内核注入,技术古老但很实用.现在部分RK趋向无进程,玩的是SYS+DLL,有的无文件,全部存在于内存中.可能有部分人会说:“都进内核了.什么不能干?”.是啊,要是内核中可以做包括R3上所有能做的事,软 ...
- Windows x86/ x64 Ring3层注入Dll总结
欢迎转载,转载请注明出处:http://www.cnblogs.com/uAreKongqi/p/6012353.html 0x00.前言 提到Dll的注入,立马能够想到的方法就有很多,比如利用远程线 ...
- 【windows核心编程】使用远程线程注入DLL
前言 该技术是指通过在[目标进程]中创建一个[远程线程]来达到注入的目的. 创建的[远程线程]函数为LoadLibrary, 线程函数的参数为DLL名字, 想要做的工作在DLL中编写. 示意图如下: ...
- [C#] - 注入DLL
原文:http://xyzlht.blog.163.com/blog/static/69301417200882834211787/ ) { MessageBox.Show("创建远程线程失 ...
- Wow64(32位进程)注入DLL到64位进程
转载自: https://blog.poxiao.me/p/wow64-process-inject-dll-into-x64-process/ 向其他进程注入DLL通常的做法是通过调用CreateR ...
- 详细解读:远程线程注入DLL到PC版微信
一.远程线程注入的原理 1.其基础是在 Windows 系统中,每个 .exe 文件在双击打开时都会加载 kernel32.dll 这个系统模块,该模块中有一个 LoadLibrary() 函数,可以 ...
- 使用远程线程来注入DLL
使用远程线程来注入DLL DLL注入技术要求我们目标进程中的一个线程调用LoadLibrary来载入我们想要的DLL (1)用OpenProcess函数打开目标进程(2)用VirtualAllocEx ...
随机推荐
- HNU_团队项目_数据库设计感想_个人感想
数据库设计感想 个人的一点心得体会 最重要的放在最前面——讨论开会时的123经验 开会前对会议目的及方式要有所考虑: 不要随意无目的开会: 遵守时间,控制会议时间长度: 会议主持人要维持会议只需,有 ...
- jvm的学习笔记:二、类的初始化,代码实战(4)
当接口被初始化的时候,不要求其父类被初始化 System.out.println(MyChild5.c); 输出: MyChild5 1 依据:new Random().nextInt(3)并非编译区 ...
- web学习(2019-10)
@“fuzz一下”:所有注入爆破题/其他题,必fuzz 在安全测试中,模糊测试(fuzz testing)是一种介于完全的手工渗透测试与完全的自动化测试之间的安全性测试类型 模糊测试(fuzz tes ...
- C语言 俄罗斯方块的实现1 全局变量
目录 全局变量 程序的模块化之MVC 关于俄罗斯方块的代码实现要点 使用数组表示背景和方块 方块表示及其初始化 要让游戏动起来 方块自动下落 全局变量 简而言之,定义在函数外的变量,就是全局变量. 所 ...
- 将对象以json格式写入到文件中
将 list 对象以json格式写入到文件中 try { ObjectMapper mapper = new ObjectMapper(); String value = mapper.writeVa ...
- 【Linux-驱动】简单字符设备驱动结构和初始化
(1)在编写简单字符设备驱动的时候,首先要申请一个设备结构struct cdev: struct cdev { struct kobject kobj; struct module *owner; / ...
- MVVM 和 VUE三要素:响应式、模板引擎、渲染
MVVM 和 VUE三要素:响应式.模板引擎.渲染:https://blog.csdn.net/weixin_37644989/article/details/94409430
- 深入理解Java中的Clone与深拷贝和浅拷贝
1.Java对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象. ...
- [BZOJ 3117] [NOI1999]内存分配(STL)
[BZOJ 3117] [NOI1999]内存分配(STL) 题面 内存是计算机重要的资源之一,程序运行的过程中必须对内存进行分配. 经典的内存分配过程是这样进行的: 1.内存以内存单元为基本单位,每 ...
- unittest之三:字符串与列表的相互转换与分离数据时的应用
一.分离数据时,需读取文档中存储的数据,但TXT文件的数据读取出来的类型为列表,而测试用例中断言的时候验证的是字符串,所以需要将列表转为字符串 #1字符串————>列表 str1='hello ...