内核中通过给线程插apc注入dll
2014-03-03 17:53
387 查看
void ApcLoadDll(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2); void ApcLoadDllEnd(); PMDL pMdl = NULL; void ApcKernelRoutine( IN struct _KAPC *Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2 ) { if (Apc) ExFreePool(Apc); if(pMdl) { MmUnlockPages(pMdl); IoFreeMdl (pMdl); pMdl = NULL; } DbgPrint("ApcKernelRoutine called. Memory freed."); } VOID AddApcIngectDll(LPSTR DllFullPath, PETHREAD Thread,ULONG pTargetProcess,void *LoadLibraryWAddr) { PRKAPC pApc = NULL; PVOID pMappedAddress = NULL; ULONG dwSize = 0; KAPC_STATE ApcState; int *p=NULL; NTSTATUS Status = STATUS_UNSUCCESSFUL; if ( MmIsAddressValid((PVOID)Thread) == TRUE) { pApc = ExAllocatePool(NonPagedPool, sizeof(KAPC)); if (!pApc) { DbgPrint("Failed to allocate memory for the APC structure"); return ; } dwSize = 386;//这个长度是我们写的大片的nop pMdl = IoAllocateMdl (ApcLoadDll, dwSize, FALSE,FALSE,NULL); if (!pMdl) { DbgPrint(" Failed to allocate MDL"); ExFreePool (pApc); return STATUS_INSUFFICIENT_RESOURCES; } __try { MmProbeAndLockPages (pMdl,KernelMode,IoWriteAccess); } __except (EXCEPTION_EXECUTE_HANDLER) { DbgPrint("Exception during MmProbeAndLockPages"); IoFreeMdl (pMdl); ExFreePool (pApc); return STATUS_UNSUCCESSFUL; } KeStackAttachProcess((ULONG *)pTargetProcess,&ApcState);//进入目标进程的上下文 pMappedAddress = MmMapLockedPagesSpecifyCache (pMdl,UserMode,MmCached,NULL,FALSE,NormalPagePriority);//把分配好的内存映射进目标进程里面 if (!pMappedAddress) { DbgPrint("Cannot map address"); KeUnstackDetachProcess (&ApcState); IoFreeMdl (pMdl); ExFreePool (pApc); return STATUS_UNSUCCESSFUL; } else DbgPrint("UserMode memory at address: 0x%p",pMappedAddress); wcscpy ((unsigned char*)pMappedAddress + 0x16, DllFullPath);//将dll路径拷贝到目标进程空间 p=(int*)((unsigned char*)pMappedAddress+6); *p=(int)((unsigned char*)pMappedAddress + 0x16); p=(int*)((unsigned char*)pMappedAddress+1); *p=LoadLibraryWAddr; KeUnstackDetachProcess (&ApcState); //恢复咱原来的上下文 //初始化APC,插APC KeInitializeApc(pApc, (PETHREAD)Thread, OriginalApcEnvironment, &ApcKernelRoutine, NULL, (PKNORMAL_ROUTINE)pMappedAddress, UserMode, (PVOID) NULL); if (!KeInsertQueueApc(pApc,0,NULL,0)) { DbgPrint("KernelExec -> Failed to insert APC"); MmUnlockPages(pMdl); IoFreeMdl (pMdl); ExFreePool (pApc); return STATUS_UNSUCCESSFUL; } else { DbgPrint("APC delivered"); } //使线程处于警告状态,注意不同操作系统的ETHREAD if(!*(char *)((char *)Thread+0x4a)) { *(char *)((char *)Thread+0x4a) = TRUE; } } } //枚举指定进程的线程 NTSTATUS IngectDll(PEPROCESS Process,LPSTR DllFullPath,void *LoadLibraryWAddr) { ULONG i; PETHREAD txtd; PEPROCESS txps; NTSTATUS st = STATUS_UNSUCCESSFUL; for (i=8;i<=65536;i=i+4) { st = PsLookupThreadByThreadId(i,&txtd); if ( NT_SUCCESS(st) ) { txps=IoThreadToProcess(txtd); if ( txps == Process ) { AddApcIngectDll(DllFullPath, txtd,Process,LoadLibraryWAddr); return STATUS_SUCCESS; //只需要枚举一个线程就够了。因为我们注入dll只需要调用一次 } } } return STATUS_SUCCESS; } __declspec(naked) void ApcLoadDll(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2) { __asm { mov eax,0xabcdef //LoadLibraryW的地址这是是需要复制到目标进程空间之后再赋值的 push 0xabcdef //这是是需要复制到目标进程空间之后再赋值的 call eax jmp end nop //分配内存 nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop end: ret 0x0c } }
相关文章推荐
- 通过修改Mach-O中Load Commands进行全局进程劫持
- NDK下,是否有可能禁止编译器自动链接C++的运行时库
- JAVA基础必备(二)——数据类型
- HDU 2586—— How far away ?
- IBM 官方datastage文档链接
- Javascript中的Array数组对象详谈
- Oracle相同用户相同库Copy表结构
- AIX中不小心删除了inittab文件
- VC6 MFC里怎么使用TTS朗读中文?
- 杭电-动态分配
- photoshop的页面制作练习1
- Activity生命周期
- SQLServer运维
- (31)5个数求最值
- 3月3号笔记
- GridView RowCommand事件获取事件行例子
- CSS 基础整理1
- Linux_C目录扫描程序
- Android如何防止apk程序被反编译
- ubuntu中设置xampp开机启动