实现生成木马的自动变异

步骤说明:
1)        用NtQuerySystemInformation取得内核模块ntkrnlpa.exe或ntoskrnl.exe的基址 KernelBase, 获取内核模块的文件名称,到底是 ntkrnlpa.exe 还是ntoskrnl.exe.
2)        读取ntkrnlpa.exe或ntoskrnl.exe的映象基址ImageBase,和.Text节中虚拟偏移Virtual Offset,实际偏移Real Offset.
3)        从ntkrnlpa.exe或ntoskrnl.exe读出正确的SSDT: 正确SSDT在ntkrnlpa.exe或ntoskrnl.exe文件中偏移 = *(PULONG) KeServiceDescriptorTable - KernelBase Virtual Offset + Real Offset. 读取长度 = KeServiceDescriptorTable->NumberOfService * 4.
4)        这里读出的内容每4字节就是一个调用的地址,但这样读出的内容还不是SSDT. 计算出正确的SSDT: 每4个字节 - ImageBase + KernelBase.
5)        禁用中断 -> memcpy写SSDT -> 启用中断.
以下是代码了,需要用到我前篇文章写的IrpFile.h,去复制就OK啦.


#include "IrpFile.h"
#define SystemModuleInformation 11

typedef struct _SYSTEM_MODULE_INFORMATION

{

     ULONG    Reserved[2];

     PVOID    Base;

     ULONG    Size;

     ULONG    Flags;

     USHORT   Index;

     USHORT   Unknown;

     USHORT   LoadCount;

     USHORT   ModuleNameOffset;

     CHAR ImageName[256];

} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

 

typedef struct

{

     ULONG                            NumberOfModules;

     SYSTEM_MODULE_INFORMATION   smi;

} MODULES, *PMODULES;

 

NTSYSAPI

NTSTATUS

NTAPI

NtQuerySystemInformation(

     IN ULONG SysInfoClass,

     IN OUT PVOID SystemInformation,

     IN ULONG SystemInformationLength,

     OUT PULONG RetLen

     );

 

typedef struct _NEED_INFO

{

     ULONG    ImageBase;

     UCHAR    UseLess1[204];

     ULONG    VOffset;

     ULONG    UseLess2;

     ULONG    ROffset;

} NEED_INFO, *PNEED_INFO;

 

typedef struct _SERVICE_DESCRIPTOR_TABLE

{

     PVOID    ServiceTableBase;

     PULONG   ServiceCounterTableBase;

     ULONG    NumberOfService;

     ULONG    ParamTableBase;

} SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;

extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;

 

 

VOID InterruptEnable()

{

     __asm

     {

         MOV EAX, CR0

         OR EAX, 10000H

         MOV CR0, EAX

         STI

     }

}

 

VOID InterruptDisable()

{

     __asm

     {

         CLI

         MOV EAX, CR0

         AND EAX, NOT 10000H

         MOV CR0, EAX

     }

}

 

NTSTATUS RestoreServiceDescriptorTable()

{

     NTSTATUS rc;

     ULONG NeededSize;

     PMODULES pModules;

     ULONG KernelBase;

 

     ULONG ActualLength;

     HANDLE LinkHandle;

     WCHAR NameBuffer[128];

     OBJECT_ATTRIBUTES ObjectAttributes;

     UNICODE_STRING LinkString, NameString;

 

     PFILE_OBJECT FileObject;

     ANSI_STRING AnsiImageName;

     UNICODE_STRING UniImageName, UniModuleName;

    IO_STATUS_BLOCK IoStatusBlock;

 

     LARGE_INTEGER CurrentOffset;

     ULONG Elfnew, Index, *Address;

     NEED_INFO NeedInfo;

 

     PVOID Buffer;

 

     pModules = (PMODULES)&pModules;

     rc = NtQuerySystemInformation(SystemModuleInformation, pModules, 4, &NeededSize);

     if(rc == STATUS_INFO_LENGTH_MISMATCH)

     {

         pModules = (PMODULES)ExAllocatePool(PagedPool, NeededSize);

         if(!pModules)

              return STATUS_INSUFFICIENT_RESOURCES;

 

         rc = NtQuerySystemInformation(SystemModuleInformation, pModules, NeededSize, NULL);

         if(!NT_SUCCESS(rc))

         {

              ExFreePool(pModules);

              return rc;

         }

     }

     if(!NT_SUCCESS(rc))

     {

         return rc;

     }

 

     KernelBase = (ULONG)pModules->smi.Base;

 

     LinkString.Buffer = NameBuffer;

     LinkString.MaximumLength = sizeof(NameBuffer);

     RtlZeroMemory(NameBuffer, sizeof(NameBuffer));

     RtlInitUnicodeString(&NameString, L"//KnownDlls//KnownDllPath");

     InitializeObjectAttributes(&ObjectAttributes, &NameString, OBJ_KERNEL_HANDLE, NULL, NULL);

     ZwOpenSymbolicLinkObject(&LinkHandle, SYMBOLIC_LINK_QUERY, &ObjectAttributes);

     ZwQuerySymbolicLinkObject(LinkHandle, &LinkString, &ActualLength);

     ZwClose(LinkHandle);

 

     RtlInitAnsiString(&AnsiImageName, pModules->smi.ImageName + pModules->smi.ModuleNameOffset - 1);

     RtlAnsiStringToUnicodeString(&UniModuleName, &AnsiImageName, TRUE);

     wcscat(NameBuffer, UniModuleName.Buffer);

     RtlInitUnicodeString(&UniImageName, NameBuffer);

     RtlFreeUnicodeString(&UniModuleName);

 

     ExFreePool(pModules);

 

     rc = IrpCreateFile(&FileObject, FILE_READ_ATTRIBUTES|SYNCHRONIZE, &UniImageName,

                          &IoStatusBlock, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE,

                          FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);

     if(NT_SUCCESS(rc))

     {

         CurrentOffset.QuadPart = 60;

         rc = IrpReadFile(FileObject, &IoStatusBlock, &Elfnew, sizeof(ULONG), &CurrentOffset);

         if(NT_SUCCESS(rc))

         {

              CurrentOffset.QuadPart = Elfnew + 52;

              rc = IrpReadFile(FileObject, &IoStatusBlock, &NeedInfo, sizeof(NEED_INFO), &CurrentOffset);

              if(NT_SUCCESS(rc))

              {

                   Buffer = ExAllocatePoolWithTag(NonPagedPool, KeServiceDescriptorTable->NumberOfService * 4, 'TDSS');

                   if (!Buffer)

                       rc = STATUS_INSUFFICIENT_RESOURCES;

                   else

                   {

                       CurrentOffset.QuadPart = *(PULONG)KeServiceDescriptorTable - KernelBase - (NeedInfo.VOffset - NeedInfo.ROffset);

                       rc = IrpReadFile(FileObject, &IoStatusBlock, Buffer, KeServiceDescriptorTable->NumberOfService * 4, &CurrentOffset);

                       if(NT_SUCCESS(rc))

                       {

                            for(Index = 0;Index < KeServiceDescriptorTable->NumberOfService;Index++)

                            {

                                 Address = (PULONG)Buffer + Index;

                                 *Address = *Address - NeedInfo.ImageBase + KernelBase;

                            }

                            InterruptDisable();

                            memcpy((unsigned char *)KeServiceDescriptorTable->ServiceTableBase, Buffer, KeServiceDescriptorTable->NumberOfService * 4);

                            InterruptEnable();

                       }

                       ExFreePoolWithTag(Buffer, 'TDSS');

                   }

              }

         }

         IrpClose(FileObject);

     }

 

     return rc;

}

 

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )

{

     RestoreServiceDescriptorTable();

     return STATUS_UNSUCCESSFUL;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值