首页
社区
课程
招聘
[求助]driver里如何获取NtReadVirtualMemory的地址?
发表于: 2009-7-21 18:30 12478

[求助]driver里如何获取NtReadVirtualMemory的地址?

2009-7-21 18:30
12478
方便hook用,我听说直接声明原型好像对公开函数管用,那么他是公开函数么,他的原型是什么呢?这些问题就是困扰我的问题

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (22)
雪    币: 1505
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
2
http://undocumented.ntinternals.net/
2009-7-21 18:32
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
3
ntdll.dll 导出函数
NTSYSAPI
NTSTATUS
NTAPI
NtReadVirtualMemory(

  IN HANDLE               ProcessHandle,
  IN PVOID                BaseAddress,
  OUT PVOID               Buffer,
  IN ULONG                NumberOfBytesToRead,
  OUT PULONG              NumberOfBytesReaded OPTIONAL );
2009-7-22 10:12
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
4
g_nReadIndex      = GetFunctionIndex("NtReadVirtualMemory");
g_NtReadVirtualMemory    = KeServiceDescriptorTable->ServiceTableBase[g_nReadIndex];
2009-7-22 11:36
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
5
GetFunctionIndex
GetFunctionAdd

函数看到忘记在哪了
2009-7-22 11:42
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
6
ULONG GetFunctionAddr( IN PCWSTR FunctionName)
{
UNICODE_STRING UniCodeFunctionName;
RtlInitUnicodeString( &UniCodeFunctionName, FunctionName );
return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName ); 
}
2009-7-22 11:50
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
7
GetFunctionIndex
函数没找到
2009-7-22 11:55
0
雪    币: 246
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
获取到的是0x0000000
2009-7-22 18:59
0
雪    币: 246
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
[QUOTE=竹君;659423]g_nReadIndex      = GetFunctionIndex("NtReadVirtualMemory");
g_NtReadVirtualMemory    = KeServiceDescriptorTable->ServiceTableBase[g_nReadIndex];...[/QUOTE]

这个说没有定义的函数!
2009-7-22 18:59
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
10
ZwReadVirtualMemory和NtReadVirtualMemory在ntoskrnl.exe中都没有导出,如果要调用,需要直接找SSDT,相关系统服务号可以硬编码,也可以在ntdll.dll的同名函数中获取。
2009-7-22 19:05
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
11
ntdll.dll导出函数啊
2009-7-22 20:55
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
12
MmGetSystemRoutineAddress只能获取NT内核(ntoskrnl.exe)和Hal.dll中的导出函数地址,ntdll.dll或PsLoadedModuleList上其他驱动的获取不了……
2009-7-22 22:26
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
13
Google一下你就知道~
2009-7-23 02:29
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
14
自己实现GetProcAddress,ring0/ring3通吃~
2009-7-23 08:48
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
15
恩。所以先获取序号,

g_nIndex      = GetFunctionIndex("NtReadVirtualMemory");
KeServiceDescriptorTable->ServiceTableBase[g_Index];
2009-7-23 10:28
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
16
服务号  0xBA

不知道GetFunctionIndex函数咋实现取服务号?
2009-7-23 10:30
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
17
对于ntoskrnl.exe有导出Zw*系列的函数的,可能直接跟ntdll.dll中取服务号一样的取法(不同的是取的是ntoskrnl.exe中的函数内容),对于ntoskrnl.exe未导出Zw*系列的函数的,就不清楚了。
2009-7-23 10:40
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
18
明白
2009-7-23 11:09
0
雪    币: 44
活跃值: (133)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
ntoskrnl.exe中导出的Zw*开头不都是mov eax,XXX,这里XXX就是服务号
2009-7-24 11:41
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
20
Attach到非System进程,然后从ntdll中取任意服务的服务号
2009-7-24 11:52
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
21
解析ntdll文件
2009-8-12 23:23
0
雪    币: 76
活跃值: (45)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
22
bool CSysInfo::GetOSKernelName()
{
        ULONG Size;       
        CHAR szFileName[MAX_FN_LEN];
        NTSTATUS ntstatus;
        PSYSTEM_MODULE_INFORMATION pModInfo,p;
        ntstatus = ZwQuerySystemInformation( SystemModuleInformation,NULL,0,&Size);
        if(ntstatus != STATUS_INFO_LENGTH_MISMATCH || Size==0)       
                return false;
        p = (PSYSTEM_MODULE_INFORMATION) new BYTE[Size];
        if(p==NULL)
                return false;
        ntstatus = ZwQuerySystemInformation( SystemModuleInformation,p,Size,0);
        if(!NT_SUCCESS(ntstatus))
        {
                delete p;
                return false;
        }
        pModInfo = p;
        for(ULONG n=0; n<p->dCount; n++)
        {
                TStrCpyLimit(szFileName,(PCSTR)pModInfo->aSM[n].abName+pModInfo->aSM[n].wNameOffset,MAX_FN_LEN);
                for(int i =0 ;m_gNtoskrnlName[i];i++)
                {
                        if(TStrICmp(szFileName,m_gNtoskrnlName[i])==0)
                        {
                                TStrCpyLimit(szFileName,(PCSTR)pModInfo->aSM[n].abName,MAX_FN_LEN);
                                if(ConvertFileName(szFileName)==false)
                                {
                                        TStrCpy(szFileName,"\\??\\");
                                        TStrCpyLimit(szFileName,(PCSTR)pModInfo->aSM[n].abName,MAX_FN_LEN-sizeof("\\??\\"));
                                }
                                m_OSKernlBase = *(DWORD*)&pModInfo->aSM[n].pAddress;
                               
                                TStrCpy(m_OSKernelName,szFileName);
                                ::DbgPrint("Syser : Windows kernel name '%s' base=%08x\n",(PCSTR)pModInfo->aSM[n].abName+pModInfo->aSM[n].wNameOffset,m_OSKernlBase);
                                delete p;
                                return true;
                        }
                }                               
        }       
        delete p;
        return false;       
}

bool CSysInfo::NtcallInit()
{
        CPEFile PEFile;
        char FileName[MAX_FN_LEN];
        CHAR*Name=NULL;
        CSymbolModule* pSymbolModule;       
        BYTE CodeBuffer[MAX_INSTR_LEN];
        int n;
        ULONGLONG zwFunc[4]={0,0,0,0};
        ULSIZE ReadLen;
        DWORD ServiceNum;
        ULONGLONG llData;
        TNtcallMap::IT Iter;
        CDbgModule* pDbgModule;

        TStrCpy(FileName,m_szSystem32A);
        TStrCat(FileName,"ntdll.dll");
        PEFile.m_OpenMode|=PE_OPEN_NO_IMPORT;
        if(PEFile.Open(FileName)==false)
        {
                ::DbgPrint("Syser : Ntcall initialize failed to load PE file symbol %s\n",FileName);
                return false;
        }
        for(n=0;n<PEFile.m_ExportFuncCount;n++)
        {
                if(_GET_WORD(PEFile.m_ExportFunc[n].FuncName)=='tN')
                {
                        ReadLen = PEFile.ReadImageMemory(PEFile.m_ExportFunc[n].Address,CodeBuffer,sizeof(CodeBuffer));
                        if(ReadLen!=sizeof(CodeBuffer))continue;
                        if((CodeBuffer[0]==0xb8&&CodeBuffer[5]==0x8d&&CodeBuffer[0x9]==0xcd)||//2k
                                (CodeBuffer[0]==0xb8&&CodeBuffer[5]==0xba&&CodeBuffer[0xa]==0xff&&CodeBuffer[0xb]==0x12)||//xp vista windows7
                                (CodeBuffer[0]==0xb8&&CodeBuffer[5]==0xba&&CodeBuffer[0xa]==0xff&&CodeBuffer[0xb]==0xd2)//2003
                                )
                        {
                                ServiceNum = *(DWORD*)&CodeBuffer[1];
                                llData = PEFile.m_ExportFunc[n].Address-PEFile.m_ImageBase;
                                llData <<= 32;
                                llData |= ServiceNum;
                                Iter = m_NtcallMap.InsertUnique(PEFile.m_ExportFunc[n].FuncName,llData);
                                if(Iter==m_NtcallMap.End())continue;
                        }
                }
        }
        Iter = m_NtcallMap.Find("NtQueryVirtualMemory");
        if(Iter!=m_NtcallMap.End())
                zwFunc[3]=*Iter;
        PEFile.Close();
        if(m_OSKernelName[0])
                Name = m_OSKernelName;
        if(Name==NULL)
        {
                if(gpSyser->m_pSysDebugger==NULL)
                        return true;               
                pDbgModule = gpSyser->m_pSysDebugger->GetModule((ULPOS)KeSetEvent);
                if(pDbgModule==NULL)
                        return true;
                Name = (char*)pDbgModule->m_ModuleFullName;
        }
        PEFile.m_OpenMode|=PE_OPEN_NO_IMPORT;       
        if(PEFile.Open(Name)==false)
        {
                ::DbgPrint("Syser : Ntcall initialize failed to load PE file symbol %s\n",(char*)Name);
                return true;
        }
        for(n=0;n<PEFile.m_ExportFuncCount;n++)
        {
                if(_GET_WORD(PEFile.m_ExportFunc[n].FuncName)=='wZ')
                {
                        ReadLen = PEFile.ReadImageMemory(PEFile.m_ExportFunc[n].Address,CodeBuffer,sizeof(CodeBuffer));
                        if(ReadLen==sizeof(CodeBuffer))
                        {
                                if(CodeBuffer[0]==0xb8||CodeBuffer[5]==0x8d||CodeBuffer[0x9]==0x9c||CodeBuffer[0xa]==0x6a)
                                {
                                        ServiceNum = *(DWORD*)&CodeBuffer[1];
                                        llData = PEFile.m_ExportFunc[n].Address-PEFile.m_ImageBase;
                                        llData <<= 32;
                                        llData |= ServiceNum;
                                        Iter = m_NtcallMap.InsertUnique(PEFile.m_ExportFunc[n].FuncName,llData);
                                        if(zwFunc[0]==0)
                                                zwFunc[0]=llData;
                                        else if(zwFunc[1]==0)
                                                zwFunc[1]=llData;
                                        else if(zwFunc[2]==0)
                                                zwFunc[2]=llData;
                                }
                        }
                }
        }
        if(zwFunc[0] && zwFunc[1]&&zwFunc[2]&&zwFunc[3])
        {
                ULONGLONG first,second,addr1,addr2,len1,len2,len3;
                if((zwFunc[0] & 0xffffffff)>(zwFunc[1] & 0xffffffff))
                {
                        first = zwFunc[0] & 0xffffffff;
                        addr1 = (zwFunc[0]>>32) & 0xffffffff;
                        second = zwFunc[1] & 0xffffffff;
                        addr2 = (zwFunc[1]>>32) & 0xffffffff;
                }
                else
                {
                        first=zwFunc[1] & 0xffffffff;
                        addr1 = (zwFunc[1]>>32) & 0xffffffff;
                        second=zwFunc[0] & 0xffffffff;
                        addr2 = (zwFunc[0]>>32) & 0xffffffff;
                }
                len1= (addr1-addr2) / (first-second);
                if((zwFunc[1] & 0xffffffff)>(zwFunc[2] & 0xffffffff))
                {
                        first = zwFunc[1] & 0xffffffff;
                        addr1 = (zwFunc[1]>>32) & 0xffffffff;
                        second = zwFunc[2] & 0xffffffff;
                        addr2 = (zwFunc[2]>>32) & 0xffffffff;
                }
                else
                {
                        first=zwFunc[2] & 0xffffffff;
                        addr1 = (zwFunc[2]>>32) & 0xffffffff;
                        second=zwFunc[1] & 0xffffffff;
                        addr2 = (zwFunc[1]>>32) & 0xffffffff;
                }
                len2= (addr1-addr2) / (first-second);
                if((zwFunc[0] & 0xffffffff)>(zwFunc[2] & 0xffffffff))
                {
                        first = zwFunc[0] & 0xffffffff;
                        addr1 = (zwFunc[0]>>32) & 0xffffffff;
                        second = zwFunc[2] & 0xffffffff;
                        addr2 = (zwFunc[2]>>32) & 0xffffffff;
                }
                else
                {
                        first=zwFunc[2] & 0xffffffff;
                        addr1 = (zwFunc[2]>>32) & 0xffffffff;
                        second=zwFunc[0] & 0xffffffff;
                        addr2 = (zwFunc[0]>>32) & 0xffffffff;
                }
                len3= (addr1-addr2) / (first-second);
                addr2=0;
                if(len2 == len1 || len2 == len3)
                {
                        if((zwFunc[0] & 0xffffffff)>(zwFunc[3] & 0xffffffff))
                        {
                                first = zwFunc[0] & 0xffffffff;                       
                                second = zwFunc[3] & 0xffffffff;
                                addr1 = (zwFunc[0] >> 32) & 0xffffffff;
                                addr2 = addr1 -(first - second)*len1;
                        }
                        else
                        {
                                first = zwFunc[3] & 0xffffffff;                       
                                second = zwFunc[0] & 0xffffffff;
                                addr1 = (zwFunc[0] >> 32) & 0xffffffff;
                                addr2 = addr1 + (first - second)*len1;
                        }
                }
                if(m_OSKernlBase)
                {
                        addr2+=m_OSKernlBase;
                        m_pZwQueryVirtualMemory = *(ZWQUERYVIRTUALMEMORY*)&addr2;
                        DbgPrint("Syser : Find ZwQueryVirtualMemory address %08x\n",m_pZwQueryVirtualMemory);
                }

        }
        PEFile.Close();
        return true;
}
2009-8-14 07:46
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
System 进程中貌似也有ntdll
2009-8-15 17:38
0
游客
登录 | 注册 方可回帖
返回
//