邪恶八进制信息安全团队技术讨论组's Archiver

eros412 2008-5-9 22:07

[原创]逆向工程之检查隐藏驱动(更新)

文章作者:Eros412
信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])
文章备注:逆向MJ0011的drvdet,通过暴力搜索内存寻找隐藏的驱动[code]//By:Eros412

#include<ntddk.h>
typedef ULONG DWORD;
typedef void * PVOID ;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef struct _SYSTEM_MODULE_INFORMATION {
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;            
CHAR ImageName[255];  
ULONG reserved[2];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

typedef struct
{
DWORD dwUnknown1;
ULONG uKeMaximumIncrement;
ULONG uPageSize;
ULONG uMmNumberOfPhysicalPages;
ULONG uMmLowestPhysicalPage;
ULONG uMmHighestPhysicalPage;
ULONG uAllocationGranularity;
PVOID pLowestUserAddress;
PVOID pMmHighestUserAddress;
ULONG uKeActiveProcessors;
BYTE bKeNumberProcessors;
BYTE bUnknown2;
WORD wUnknown3;
} SYSTEM_BASIC_INFORMATION,*PSYSTEM_BASIC_INFORMATION;

NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
  ULONG num,
  PVOID SystemInformation,
  ULONG SystemInformationLength,
  PULONG ReturnLength
);

PSYSTEM_MODULE_INFORMATION moduleinfo;
DWORD ReturnLength,count,status;
PVOID memory;
ULONG n,j;

int address_check(ULONG addr_in){

count=0;
j=0;

        ZwQuerySystemInformation(11,&n,0x0A,&ReturnLength);
        memory=(PSYSTEM_MODULE_INFORMATION)ExAllocatePoolWithTag(0,ReturnLength,0x206B6444);
        if(memory==NULL)
          return 0;

                status=ZwQuerySystemInformation(11,memory,ReturnLength,&ReturnLength);
                n=*(DWORD*)memory;
                if(status||!n)
                {
                        ExFreePool(memory);
                        return 0;
                }

       

        moduleinfo = (PSYSTEM_MODULE_INFORMATION)((PULONG )memory + 3 );
        while(1)
    {
         if(addr_in>(ULONG)moduleinfo[j].Base&&addr_in<(ULONG)moduleinfo[j].Base+moduleinfo[j].Size)      
         return 1;
                 
                 j++;
                 count++;

                 if(count>n)
                                         {
                        ExFreePool(memory);
                        return 0;
                 }
                 
                 }
         
}

NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    ){

        PHYSICAL_ADDRESS physical_address;
        PSYSTEM_BASIC_INFORMATION systeminfo;
        DWORD pagesize,physicalpage;
        ULONG addr,limit,check,inloop,tmp,sizeofimage,MZminustwo,i,searchaddr,searchagain,startrange;
        BOOLEAN bol;
                LARGE_INTEGER largeint;
        char imagename[255];

systeminfo=(PSYSTEM_BASIC_INFORMATION)ExAllocatePool(NonPagedPool,sizeof(SYSTEM_BASIC_INFORMATION)+1);
ZwQuerySystemInformation(0,systeminfo,0x2C,&ReturnLength);

physicalpage=systeminfo->uMmNumberOfPhysicalPages;
pagesize=systeminfo->uPageSize;
largeint.QuadPart=physicalpage*pagesize;
startrange=*(ULONG*)MmSystemRangeStart;
for(addr=startrange,limit=addr+0x140;limit<0xFFFF0140;limit+=0x1000,addr+=0x1000){

if(!MmIsAddressValid((PVOID)addr))
continue;
physical_address=MmGetPhysicalAddress((PVOID)addr);

if(physical_address.HighPart>largeint.HighPart)
continue;
if(physical_address.HighPart==largeint.HighPart&&physical_address.LowPart>largeint.LowPart)
continue;

tmp=(DWORD)MmGetVirtualForPhysical(physical_address);

check=limit-0x100;
for(inloop=check;inloop<limit;inloop++){
      
if(*(BYTE*)inloop==0x44&&
   *(BYTE*)(inloop+1)==0x4f&&
   *(BYTE*)(inloop+2)==0x53&&
   *(BYTE*)(inloop+3)==0x20&&
   *(BYTE*)(inloop+4)==0x6d&&
   *(BYTE*)(inloop+5)==0x6f&&
   *(BYTE*)(inloop+6)==0x64&&
   *(BYTE*)(inloop+7)==0x65 //寻找"DOS mode"字符串
   )
if(*(DWORD*)(limit-0x104)<0x1000)//比较PE offset
if(*(BYTE*)(addr+*(DWORD*)(limit-0x104)+0x5C)==1)//subsystem,1=驱动程序
{
        sizeofimage=*(DWORD*)(addr+*(DWORD*)(limit-0x104)+0x50);
        MZminustwo=limit-0x13E;
        if(!address_check(MZminustwo))//找到隐藏驱动
        {
                bol=0;
               if(addr>=addr+sizeofimage)
                           {
                                   goto printout;

                           continue;
                           }
                           searchaddr=addr;
                           do{
                                   if(MmIsAddressValid((PVOID)searchaddr)){
                                           if(*(DWORD*)searchaddr==0x6264702E){//寻找".pdb"字符串
                                                   searchagain=searchaddr;

                                                   while(1)
                                                   {
                                                           if(MmIsAddressValid((PVOID)searchagain))
                                                           {
                                                                   if(!*(BYTE*)searchagain)
                                                           goto printout2;

                                                                   if(*(BYTE*)searchagain==92)
                                                                           break;
                               
                                                           }
                                                            searchagain--;
                                                           if(searchagain<searchaddr-256)
                                                                   goto here;
                                                   }
printout2:
DbgPrint("Find Hidden Module:%s , ImageBase = %08x ImageSize = %08x",searchagain+1, addr, sizeofimage);
                           bol=1;
                                           }
                                   }
here:
                                           searchaddr++;
                           }while(searchaddr<addr+sizeofimage);
                           if(!bol)
printout:
              DbgPrint("Find Hidden Module:Unknow Image Name , ImageBase = %08x ImageSize = %08x", addr, sizeofimage);
                }
}

}

}
return STATUS_SUCCESS;
}
[/code]

[[i] 本帖最后由 eros412 于 2008-5-13 15:21 编辑 [/i]]

洋洋洒洒 2008-5-10 00:00

地毯式 [s:307]
又简单又实用啊
弱弱.,,.这代码没什么好逆的,....

zshoucheng 2008-5-10 00:05

搜索。。。太慢了

sudami 2008-5-10 07:08

哈哈.顶下.

驱动才3K. 看下IAT就大概知道怎么回事了.然后直接F5~~:smile:

疯狂奴隶 2008-5-11 18:41

逆得和原始的差太远了

楼上真是超级大牛啊,看IAT就知道了啊

sudami 2008-5-11 19:45

LS的难道是马甲?

看下IAT。和几个重要函数,再按下F5本来就差不多了。

难道我说错了呀?:lol:

eros412 2008-5-11 19:45

回复 地板 疯狂奴隶 的帖子

MJ用win2003的ntddk来编译,一部分代码可以省略,只是改了最后寻找驱动名的那部分

[[i] 本帖最后由 eros412 于 2008-5-12 14:13 编辑 [/i]]

疯狂奴隶 2008-5-11 20:29

[quote]原帖由 [i]eros412[/i] 于 2008-5-11 19:45 发表 [url=https://forum.eviloctal.com/redirect.php?goto=findpost&pid=142570&ptid=33044][img]images/common/back.gif[/img][/url]
MJ用win2003的ntddk来编译,一部分代码可以省略,只是改了最后寻找驱动名的那部分,还有,逆向是一个练习,不是只是一味看它使用了什么API函数,了解数据结构才是最重要 ... [/quote]
我说的就是代码
你逆的代码和我原本的代码在很多地方无论是逻辑还是结构都有不少不同
逆向不是你这么个逆法的
而且你这个驱动编译出来,会比我原来的驱动少检测出很多类隐藏ROOTKIT驱动~哈

eros412 2008-5-11 20:42

回复 8楼 疯狂奴隶 的帖子

谢谢提醒,已修改

[[i] 本帖最后由 eros412 于 2008-5-13 15:22 编辑 [/i]]

页: [1]
© 1999-2008 EvilOctal Security Team