注入 - Ring3 APC注入
系统产生一个软中断,当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数,利用QueueUserAPC()这个API,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,
1.根据进程名称得进程ID
2.枚举该进程中的线程
3.将自己的函数插入到每个线程的APC队列中
1 // APCInject(Ring3).cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <windows.h>
#include <TlHelp32.h>
#include <ntstatus.h>
#include <vector>
#include <iostream> using namespace std;
/*
Win7下成功 Win10不一定成功(编译对应的位数,管理员身份运行)
Win7要将倒着插入!!
要将DLL拷到.cpp的文件夹中
尽量选择线程多的exe 另外没有提供删除APC队列中函数的方法,所以不能反复注入。
*/ WCHAR __DllFullPath[MAX_PATH] = { };
PVOID __DllFullPathBufferData = NULL;
UINT_PTR __LoadLibraryWAddress = ; //typedef void(*pfnSub_110)(); BOOL GetProcessIDByProcessImageName(IN PWCHAR ProcessImageName, OUT PUINT32 ProcessID);
BOOL GetThreadIDByProcessID(IN UINT32 ProcessID, OUT vector<UINT32>& ThreadIDVector);
BOOL InjectDllByApc(IN UINT32 ProcessID, OUT UINT32 ThreadID);
BOOL DebugPrivilege(WCHAR * DebugName, BOOL bEnable); int main()
{
if (DebugPrivilege(SE_DEBUG_NAME, TRUE)==FALSE)
{
printf("DebugPrivilege Error\r\n");
} GetCurrentDirectory(MAX_PATH, __DllFullPath); wcscat(__DllFullPath, L"\\Dll.dll"); UINT ProcessID = ; if (GetProcessIDByProcessImageName(
L"taskmgr.exe", &ProcessID) == FALSE)
{ return ;
} vector<UINT32> ThreadIDVector; if (GetThreadIDByProcessID(ProcessID, ThreadIDVector) == FALSE)
{
return ;
} size_t ThreadCount = ThreadIDVector.size();
//每一个线程
/*
win7下得倒着注入
*/
for (INT_PTR i = ThreadCount - ; i >= ; i--)
{
UINT32 ThreadID = ThreadIDVector[i];
InjectDllByApc(ProcessID, ThreadID);
} printf("Input Any Key to Exit\r\n");
getchar();
getchar(); return ;
} BOOL InjectDllByApc(IN UINT32 ProcessID, OUT UINT32 ThreadID)
{
HANDLE ThreadHandle = NULL;
HANDLE ProcessHandle = OpenProcess(
PROCESS_ALL_ACCESS, FALSE, ProcessID); SIZE_T DllFullPathLength = ((wcslen(__DllFullPath) + )); SIZE_T ReturnLength = ;
BOOL IsOk = FALSE; // 申请一次内存
if (__DllFullPathBufferData == NULL)
{
__DllFullPathBufferData =
VirtualAllocEx(
ProcessHandle,
NULL,
DllFullPathLength * ,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE
); if (__DllFullPathBufferData == NULL)
{
CloseHandle(ProcessHandle);
ProcessHandle = NULL;
return FALSE;
} IsOk = WriteProcessMemory(
ProcessHandle,
__DllFullPathBufferData,
__DllFullPath,
DllFullPathLength * ,
&ReturnLength
); if (IsOk == FALSE)
{ VirtualFree(__DllFullPathBufferData,
DllFullPathLength * , MEM_RELEASE); CloseHandle(ProcessHandle);
ProcessHandle = NULL;
return FALSE;
}
} __LoadLibraryWAddress =
(UINT_PTR)GetProcAddress(
GetModuleHandle(L"Kernel32.dll"),
"LoadLibraryW"
); if (__LoadLibraryWAddress == NULL)
{
VirtualFree(
__DllFullPathBufferData,
DllFullPathLength * , MEM_RELEASE);
CloseHandle(ProcessHandle);
ProcessHandle = NULL;
return FALSE;
} __try
{
ThreadHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, ThreadID);
DWORD v1 = QueueUserAPC(
(PAPCFUNC)__LoadLibraryWAddress,
ThreadHandle,
(UINT_PTR)__DllFullPathBufferData
); //LoadLibraryWAddress("DllFullPathBufferData")
if (v1 == )
{
printf("FAIL %d\r\n", GetLastError());
}
else if (v1 != )
{
printf("Success\r\n");
}
} __except (EXCEPTION_CONTINUE_EXECUTION)
{ } CloseHandle(ProcessHandle);
CloseHandle(ThreadHandle); return TRUE;
} BOOL GetThreadIDByProcessID(IN UINT32 ProcessID, OUT vector<UINT32>& ThreadIDVector)
{
HANDLE ThreadSnapshotHandle = NULL;
THREADENTRY32 ThreadEntry32 = { }; ThreadEntry32.dwSize = sizeof(THREADENTRY32); ThreadSnapshotHandle = CreateToolhelp32Snapshot(
TH32CS_SNAPTHREAD, );
if (ThreadSnapshotHandle == INVALID_HANDLE_VALUE)
{
return FALSE;
} BOOL IsOk = Thread32First(
ThreadSnapshotHandle, &ThreadEntry32); if (IsOk)
{
do
{
if (
ThreadEntry32.th32OwnerProcessID
== ProcessID)
{
ThreadIDVector.emplace_back(
ThreadEntry32.th32ThreadID); // 把该进程的所有线程id压入模板
}
} while (Thread32Next(
ThreadSnapshotHandle, &ThreadEntry32)
); } CloseHandle(ThreadSnapshotHandle);
ThreadSnapshotHandle = NULL; return TRUE;
} BOOL GetProcessIDByProcessImageName(IN PWCHAR ProcessImageName, OUT PUINT32 ProcessID)
{
HANDLE ProcessSnapshotHandle = NULL;
ProcessSnapshotHandle =
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, ); if (ProcessSnapshotHandle == INVALID_HANDLE_VALUE)
{
return FALSE;
} PROCESSENTRY32 ProcessEntry32 = { };
ProcessEntry32.dwSize = sizeof(PROCESSENTRY32); BOOL IsOk = Process32First(
ProcessSnapshotHandle,
&ProcessEntry32
); if (IsOk)
{
do
{
if (
lstrcmpi(ProcessEntry32.szExeFile,
ProcessImageName)==
)
{
*ProcessID = ProcessEntry32.th32ProcessID;
break;
}
} while (Process32Next(
ProcessSnapshotHandle,
&ProcessEntry32
)
);
} if (*ProcessID==)
{
printf("Get ProcessID FAIL! 请打开任务管理器.\r\n");
return FALSE;
} CloseHandle(ProcessSnapshotHandle);
ProcessSnapshotHandle = NULL; return TRUE;
} BOOL DebugPrivilege(WCHAR * DebugName, BOOL bEnable)
{
BOOL bRet = TRUE;
HANDLE TokenHandle;
TOKEN_PRIVILEGES TokenPrivileges; //进程 Token 令牌
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &TokenHandle))
{
bRet = FALSE;
return bRet;
}
TokenPrivileges.PrivilegeCount = ;
TokenPrivileges.Privileges[].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : ; LookupPrivilegeValue(NULL, DebugName, &TokenPrivileges.Privileges[].Luid);
AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
if (GetLastError() != ERROR_SUCCESS)
{
bRet = FALSE;
} CloseHandle(TokenHandle);
return bRet; }
注入 - Ring3 APC注入的更多相关文章
- Dll注入:Ring3 层 APC注入
APC,即Asynchronous procedure call,异步程序调用APC注入的原理是:在一个进程中,当一个执行到SleepEx()或者WaitForSingleObjectEx()时,系统 ...
- Windows x86/ x64 Ring3层注入Dll总结
欢迎转载,转载请注明出处:http://www.cnblogs.com/uAreKongqi/p/6012353.html 0x00.前言 提到Dll的注入,立马能够想到的方法就有很多,比如利用远程线 ...
- 分析恶意驱动(进程启动apc注入dll)
一.前言 用IDA也有好些时间了,以前就只会用F5功能玩无壳无保护的裸驱动,感觉太坑了,这两天就开始看网上大牛的逆向. 今天记录一下sudami曾经逆向过的fuck.sys.第一遍自己走的时候漏掉了 ...
- APC注入
0X01 注入原理 当线程被唤醒时APC中的注册函数会被执行的机制,并依此去调用我们的DLL加载代码,进而完成注入的目的 具体的流程: 1 当EXE里的某个线程执行到sleepEX(),或者waitF ...
- 常见注入手法第二讲,APC注入
常见注入手法第二讲,APC注入 转载注明出处 首先,我们要了解下什么是APC APC 是一个简称,具体名字叫做异步过程调用,我们看下MSDN中的解释,异步过程调用,属于是同步对象中的函数,所以去同步对 ...
- 注入理解之APC注入
近期学习做了一个各种注入的MFC程序,把一些心得和体会每天分享一些 APC(Asynchronous procedure call)异步程序调用,在NT中,有两种类型的APCs:用户模式和内核模式.用 ...
- Dll注入技术之APC注入
APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下: 1)当EXE里某个线程执行到SleepEx( ...
- windows:shellcode 代码远程APC注入和加载
https://www.cnblogs.com/theseventhson/p/13197776.html 上一章介绍了通用的shellcode加载器,这个加载器自己调用virtualAlloc分配 ...
- DLL注入-APC注入
APC注入 APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下: 1)当EXE里某个线程执行到Sl ...
随机推荐
- 学习笔记TF014:卷积层、激活函数、池化层、归一化层、高级层
CNN神经网络架构至少包含一个卷积层 (tf.nn.conv2d).单层CNN检测边缘.图像识别分类,使用不同层类型支持卷积层,减少过拟合,加速训练过程,降低内存占用率. TensorFlow加速所有 ...
- nginx-port-Permission-denied
nginx use 9000 port Permission denied other port ok 新架构下web服务需要使用反向代理,将不同的请求转发到不同的service,对应不同的端口. ...
- php 页面调转导致session丢失解决方法
例如在a页面设置了会话,然后打印会话值,可以成功打印,但是调转到b页面后,会话丢失了. 原因有不少,一个原因就是没有在页面开头加入session_start();当然你也可以直接配置php.ini文件 ...
- linux(kali,centos)安装vm及其提示缺少c头文件解决方法
我电脑系统是kali最新版 首先去官网下一个vm安装包,给个直达网址 http://www.vmware.com/cn/products/workstation/workstation-evaluat ...
- day 55 jQuery 之事件 绑定等
属性选择器: [attribute] [attribute=value]// 属性等于 列入 $("input[value='male']").prop('chekced') 注意 ...
- GitLab Shell如何通过SSH工作
转自:https://wayjam.me/post/how-gitlab-shell-works-with-ssh.md GitLab访问Git仓库 首先回顾GitLab的Git仓库四种访问方式: g ...
- 线性代数及其应用 (David C.Lay, Steven R.Lay 著)
第1章 线性代数中的线性方程组 (已看) 介绍性实例 经济学与工程中的线性模型 1.1 线性方程组 1.2 行化简与阶梯形矩阵 1.3 向量方程 1.4 矩阵方程Ax=b 1.5 线性方程组的解集 1 ...
- laya的UI编辑器
//加载一个图集 Laya.loader.load("res/atlas/comp.json",Handler.create(this,this.onLoaderComp), Ha ...
- MySQL 出现 Host is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
MySQL 出现 Host is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts' 一大 ...
- dev 域名与 Chrome
前几天在相开发时使用什么的样域名比较好呢? 之前使用到 localhost,但只是本地开发,使用 test.com 感觉又不专业. 后来发现了一些指向 127.0.0.1 的域名,比如 localte ...