首页
社区
课程
招聘
[求助]ring0 中 ntkrnlpa.exe 的 IAT 定位问题,请教大侠了
发表于: 2010-5-16 08:27 10487

[求助]ring0 中 ntkrnlpa.exe 的 IAT 定位问题,请教大侠了

2010-5-16 08:27
10487
#define ibaseDD *(PDWORD)&ibase
BOOL GetHeaders(PUCHAR ibase,
                PIMAGE_FILE_HEADER *pfh,
                PIMAGE_OPTIONAL_HEADER *poh,
                PIMAGE_SECTION_HEADER *psh)
{
        PIMAGE_DOS_HEADER mzhead=(PIMAGE_DOS_HEADER)ibase;
        if    ((mzhead->e_magic!=IMAGE_DOS_SIGNATURE) ||        
                (ibaseDD[mzhead->e_lfanew]!=IMAGE_NT_SIGNATURE))
                return FALSE;
        *pfh=(PIMAGE_FILE_HEADER)&ibase[mzhead->e_lfanew];
        if (((PIMAGE_NT_HEADERS)*pfh)->Signature!=IMAGE_NT_SIGNATURE)
                return FALSE;
        *pfh=(PIMAGE_FILE_HEADER)((PBYTE)*pfh+sizeof(IMAGE_NT_SIGNATURE));
        *poh=(PIMAGE_OPTIONAL_HEADER)((PBYTE)*pfh+sizeof(IMAGE_FILE_HEADER));
        if ((*poh)->Magic!=IMAGE_NT_OPTIONAL_HDR32_MAGIC)
                return FALSE;
        *psh=(PIMAGE_SECTION_HEADER)((PBYTE)*poh+sizeof(IMAGE_OPTIONAL_HEADER));
        return TRUE;
}
void GetKernelModuleList()
{
PVOID base_addr
PIMAGE_FILE_HEADER pFileHeader;
PIMAGE_OPTIONAL_HEADER pOptHeader;
PIMAGE_SECTION_HEADER pSecHeader;
ULONG vaImportDir;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
USHORT i, sectionCount;
PCHAR moduleName;

KdVersionBlock = (PDBGKD_GET_VERSION64)(*(ULONG *)(0xffdff000 + 0x34));
base_addr = (PULONG)(ULONG)(KdVersionBlock->KernBase);

if (!GetHeaders(base_addr, &pFileHeader, &pOptHeader, &pSecHeader))
        return;
sectionCount = pFileHeader->NumberOfSections;
vaImportDir = pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
for (i = 0; i < sectionCount; i++, pSecHeader++)
{
        if (DirVirtualAddress >= pSecHeader->VirtualAddress &&
                DirVirtualAddress < pSecHeader->VirtualAddress + pSecHeader->SizeOfRawData)
                break;
}
//以上代码,调试其中跟踪都正常
//pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)base_addr + vaImportDir); //直接基址+VirtualAddress和下面的方法得到的pImportDesc都是无效地址,Why?
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)base_addr + vaImportDir - pSecHeader->VirtualAddress + pSecHeader->PointerToRawData);
        if (pImportDesc == NULL)
        {
                return;
        }
        if(!MmIsAddressValid(pImportDesc))
        {
//程序运行到此,调试显示pImportDesc地址无效,why?
                return;
        }
        for (; pImportDesc->Name; pImportDesc++)
        {
                moduleName = (PCHAR)(base_addr + pImportDesc->Name);
                //...
        }
}
网上看到两种方法获取IAT:
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)base_addr + vaImportDir);
OR
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)base_addr + vaImportDir - pSecHeader->VirtualAddress + pSecHeader->PointerToRawData);
得到的pImportDesc都是无效地址,Why?
还有为什么会有两种方法啊,有什么区别,什么时候改用哪种方法?迷糊!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (18)
雪    币: 75
活跃值: (828)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
pe文件加载到内存后的空间布局与它在磁盘上的布局不一样
2010-5-16 11:38
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
3
PE文件加载到内存时有两种不同的加载方法:
一、按PE的节对齐格式Map到内存中(通常可执行文件加载时是这种方式),此时内存中和硬盘上的不一样,内存中的PE映像因为对齐关系在节与节之间会有空隙
二、直接将整个文件按数据文件Map到内存中,此时内存中和硬盘上的布局是一样的

如果是按第一种方法加载的,那么(ULONG)base_addr + vaImportDir就是正确的
如果是按第二种方法加载的,那么就是:
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)base_addr + vaImportDir - pSecHeader->VirtualAddress + pSecHeader->PointerToRawData);
但是,这个PSecHeader并不是第一个节的节头,而应该是输入表所在的那个节的节头(这就不一定是第一个节了)。

具体如何取输入表地址,取决于你的加载方式,对于已经按正常方式加载的PE文件,当然是按第一种取了。
但是ntoskrnl不是一般的exe,比较特殊,在内核初始化阶段,输入表所在的节是有效的,但是当内核初始化完成后,该节所在内存会被释放掉,所以在内核初始化之后,这个地址可能就无效了,就算有效也可能并不是你想要的内容。
比如在我的系统上,ntoskrnl的PE头中部分内容如下:
  18B200 [    B50A] address [size] of Export Directory
  [COLOR="Red"]1D4D04[/COLOR] [      50] address [size] of Import Directory
  1D5680 [   105CC] address [size] of Resource Directory
       0 [       0] address [size] of Exception Directory
       0 [       0] address [size] of Security Directory
  1E5C80 [    FC78] address [size] of Base Relocation Directory
     760 [      1C] address [size] of Debug Directory
       0 [       0] address [size] of Description Directory
       0 [       0] address [size] of Special Directory
       0 [       0] address [size] of Thread Storage Directory
    94C0 [      40] address [size] of Load Configuration Directory
       0 [       0] address [size] of Bound Import Directory
     600 [     154] address [size] of Import Address Table Directory
       0 [       0] address [size] of Delay Import Directory
       0 [       0] address [size] of COR20 Header Directory
       0 [       0] address [size] of Reserved Directory

可以看到,输入表的VA是1D4D04,正处于下面这个节的范围之内(如果直接Map文件来取IAT的话,就应该取这个节,具体哪个节可以判断IAT的VA在哪个节的VA范围之内)。而这个节就是INIT,在内核初始化完成之后就会被释放。
SECTION HEADER #17
    INIT name
   2A986 virtual size
  1AAC80 virtual address
   2AA00 size of raw data
  1AAC80 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
E2000020 flags
         Code
         Discardable
         (no align specified)
         Execute Read Write


当然了,对于一个普通的Win32程序来说,是不存在这个问题的。
2010-5-16 12:39
0
雪    币: 75
活跃值: (828)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4

我这边看到的导入表相对地址:001EA41C,COOL,多谢教主
上传的附件:
2010-5-16 13:14
0
雪    币: 202
活跃值: (57)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
多谢了,说的很详细,知道错误原因了,我这里也是INIT节包含IAT。不过如果我要hook 内存中的ntoskrnl 的某个IAT函数应该用什么办法呢;比如ntoskrnl  的KDCOM.DLL的 KdSendPacket函数被IAT HOOK了,使windbg无法进行调试,我想再给IAT HOOK回来, 要怎么办啊?还请大侠再帮帮
2010-5-16 17:03
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
6
难道是TesSafe??
2010-5-16 17:25
0
雪    币: 202
活跃值: (57)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
嗯,主要是想了解一下内核的IAT布局问题,暂无他意。
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)base_addr + vaImportDir - pSecHeader->VirtualAddress + pSecHeader->PointerToRawData); 中匹配的就是INIT节,不过算出来的pImportDesc的内存地址,是个无效地址,应该就是 “当内核初始化完成后,该节所在内存会被释放掉”吧,应该还有其他办法访问内核的IAT吧。
2010-5-16 22:46
0
雪    币: 202
活跃值: (57)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
希望大神能给点提示
2010-5-16 22:47
0
雪    币: 6082
活跃值: (804)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
9
应该是。。。不过解决办法好象不是那样的。。。
2010-5-17 10:43
0
雪    币: 233
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
RING0 IAT???? 没R3有R0么。。汗。。。“服务对象”搞错了。。兄弟们。。

我说实话而已。。见谅。。

操作系统又不是WINDOWS光棍的拉   搞个新的多好玩。。摆脱那些传统的R0模式
2010-5-17 10:52
0
雪    币: 233
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
暂时考虑要不要爆猛料中的猛料。。。。看情况吧

情况合适1个月内 颠覆传统技术新局面即将到来。。。可能有些大牛已经知道了 玩腻的牛牛们估计也快爆料了。。
2010-5-17 10:55
0
雪    币: 202
活跃值: (57)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
各位老大别光顾着聊天,顺便给点提示啊
2010-5-17 22:56
0
雪    币: 441
活跃值: (1002)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
13
那个可以直接修改他的 MyKdSendPacket 代码跳回真正的函数去~~无视之~~~~~~~
2010-5-18 14:40
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
14


人家的代码可是有校验的,敢改?它马上死给你看~~
2010-5-18 15:27
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
连看雪都没有人能解决这个问题啊?看来楼主遇到的问题真的有难度。。。
2010-5-19 11:57
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
碰到同样问题 楼主搞好没
2010-11-18 22:21
0
雪    币: 105
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
ASDSADA
2010-11-19 21:33
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
18
想把TesSafe玩得彻底,还是要搞定代码校验滴~~~
2010-11-20 06:34
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
从文件映射出来 看重定位表 定位到函数位子 nt里面的sendpacket 他调用顺序是jmp [xxxx] 把他的xxxx改成我们的aaaa [aaaa]中包含原始kdcom的sendpacket地址 试试看
2010-11-26 11:05
0
游客
登录 | 注册 方可回帖
返回
//