Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 读取ntdll.dll+;偏移量导致访问冲突_C_Windows_Winapi_Windbg_Ntdll - Fatal编程技术网

C 读取ntdll.dll+;偏移量导致访问冲突

C 读取ntdll.dll+;偏移量导致访问冲突,c,windows,winapi,windbg,ntdll,C,Windows,Winapi,Windbg,Ntdll,我试图逐字节读取加载在可执行文件中的ntdll.dll内存。 可执行文件在我的x64 windows 7计算机上编译为x32可执行文件 我编写了一个名为FindPattern的函数,它接收一个特定的字节数组,并在ntdll.dll模块中查找这个字节数组 我已经在其他模块上检查了此功能,我确信它工作正常 现在,当我在我的ntdll模块上使用此函数时,它在读取内存ntdll+0x1000时崩溃 我在windbg上检查了这个,windbg也无法读取内存: 0:000> db ntdll + FF

我试图逐字节读取加载在可执行文件中的
ntdll.dll
内存。 可执行文件在我的x64 windows 7计算机上编译为x32可执行文件

我编写了一个名为
FindPattern
的函数,它接收一个特定的字节数组,并在ntdll.dll模块中查找这个字节数组

我已经在其他模块上检查了此功能,我确信它工作正常

现在,当我在我的ntdll模块上使用此函数时,它在读取内存ntdll+0x1000时崩溃

我在windbg上检查了这个,windbg也无法读取内存:

0:000> db ntdll + FF0 L20
77df0ff0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
77df1000  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
我不知道为什么会发生这种情况,但它包含0x9000字节

0:000> db ntdll + FFF0 L20
77dffff0  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
77e00000  8b 44 24 04 cc c2 04 00-cc 90 c3 90 cc c3 90 90  .D$.............
这在我检查的任何其他DLL中都没有发生。。使用
ReadProcessMemory
可以绕过该问题,但我想了解是什么导致了它

跑步!卫生署命令结果:

0:000> !dh ntdll

File Type: DLL
FILE HEADER VALUES
     14C machine (i386)
       5 number of sections
55636317 time date stamp Mon May 25 20:59:51 2015

       0 file pointer to symbol table
       0 number of symbols
      E0 size of optional header
    2102 characteristics
            Executable
            32 bit word machine
            DLL

OPTIONAL HEADER VALUES
     10B magic #
    9.00 linker version
   D6400 size of code
   67400 size of initialized data
       0 size of uninitialized data
       0 address of entry point
   10000 base of code
         ----- new -----
77df0000 image base
   10000 section alignment
     200 file alignment
       3 subsystem (Windows CUI)
    6.01 operating system version
    6.01 image version
    6.01 subsystem version
  180000 size of image
     400 size of headers
  14C3B3 checksum
00040000 size of stack reserve
00001000 size of stack commit
00100000 size of heap reserve
00001000 size of heap commit
     140  DLL characteristics
            Dynamic base
            NX compatible
   10218 [    F6D2] address [size] of Export Directory
       0 [       0] address [size] of Import Directory
  110000 [   5A028] address [size] of Resource Directory
       0 [       0] address [size] of Exception Directory
  13C600 [    3A18] address [size] of Security Directory
  170000 [    4D30] address [size] of Base Relocation Directory
   E60F4 [      38] 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
   71C80 [      40] address [size] of Load Configuration Directory
       0 [       0] address [size] of Bound Import Directory
       0 [       0] 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


SECTION HEADER #1
   .text name
   D6153 virtual size
   10000 virtual address
   D6200 size of raw data
     400 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
60000020 flags
         Code
         (no align specified)
         Execute Read


Debug Directories(2)
    Type       Size     Address  Pointer
    cv           23       e6130    d6530    Format: RSDS, guid, 2, wntdll.pdb
    (    10)       4       e612c    d652c

SECTION HEADER #2
      RT name
     1C9 virtual size
   F0000 virtual address
     200 size of raw data
   D6600 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
60000020 flags
         Code
         (no align specified)
         Execute Read

SECTION HEADER #3
   .data name
    82A8 virtual size
  100000 virtual address
    6E00 size of raw data
   D6800 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
C0000040 flags
         Initialized Data
         (no align specified)
         Read Write

SECTION HEADER #4
   .rsrc name
   5A028 virtual size
  110000 virtual address
   5A200 size of raw data
   DD600 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
40000040 flags
         Initialized Data
         (no align specified)
         Read Only

SECTION HEADER #5
  .reloc name
    4D30 virtual size
  170000 virtual address
    4E00 size of raw data
  137800 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
42000040 flags
         Initialized Data
         Discardable
         (no align specified)
         Read Only
为什么这
10000段对齐
10000段基本对齐
似乎都包含了避免崩溃和访问冲突所需的正确值


原因是什么?为什么它只发生在ntdll中?

加载的映像中存在间隙,如转储中所示。文件头在0x77df0000处加载,然后.text节在0x77e00000处加载64k字节。这是你在文章中提到的64k部分对齐的结果。我不知道是否有任何不寻常的部分对齐的原因,除了明显的原因,他们希望一些缓冲区或其他元素分配与64k对齐。这可能与以下事实有关:

您可以使用VirtualQuery来确定哪些页面是有效的。每次“for循环”进入新页面时,请调用VirtualQuery。如果
State
值为MEM\u COMMIT,并且
AllocationProtect
值具有PAGE\u EXECUTE\u READWRITE、PAGE\u READONLY或PAGE\u READWRITE位集中的一个,并且
AllocationProtect
值未设置PAGE\u GUARD位,则您知道页面存在且可读。如果没有,则可以使用
RegionSize
值跳过该页,以及该页之后具有相同状态的每一页


您还可以在0x77df0000处解析PECOFF头,以确定节的加载位置,但这要复杂一些。

我猜Windows是在保护
ntdll.dll
不让人们因为安全原因而弄乱其内部结构。由于节对齐为64 KiB,因此存在间隙<代码>!地址ntdll+1000显示此地址启动0xf000字节的保留(未提交)区域。至于为什么节对齐是64kib,我只知道它必须是文件对齐(通常是512字节)和页面大小(x86上是4kib)的倍数,而x86和x64上的默认值是4kib。@RemyLebeau,这听起来很奇怪,很离谱。这将提供什么样的保护@埃里克森,我不太明白。。。是否存在其他可能发生这种情况的dll?看起来它保留了10页(
0x10*sizeof(PAGE)
),这听起来像是一个要保留的随机数。@RE初学者这不是一个随机数,它是加载64k对齐的.text部分所必需的数字。为什么部分有64k对齐是一个谜,但是考虑到它们有64k对齐,填充和预期一样。文件对齐是512字节,因此只有一个只读页面(4096字节)必须提交给文件头。请注意,所有截面(例如,文本)均以截面对齐的倍数开始。不过这都是一个分配,所以任何未提交的页面都将是
MEM\u RESERVE
。user32是相同的。与内核32相比,内核32使用0x10000进行文件和节对齐,因此只读头提交16页,其中15页都是0。还有advapi32,它使用默认的节对齐方式,因此它的.text节从
advapi32+0x1000
开始。那么,您建议如何准确地处理实际代码中的问题呢?假设我对整个模块内存地址有一个
For循环
。我需要自己读取每个字节。@作为初学者,我已经更新了我的答案,并解释了如何使用VirtualQuery。作为任何试图在这里重新填充内容的人的补充说明,关于ntdll.dll的许多内容都与pecoff规范相违背。Thar be dragons。