我正在尝试对易受缓冲区溢出影响的库函数代码进行逆向工程,以正确确定原因和与之相关的风险,但有一种行为我不确定是否完全理解。
场景如下:
- Windows 8.1 上的 W64 应用程序,它实例化一个 COM 对象(一个库)。
- 该库容易因用户控制的输入而导致缓冲区溢出。没有 EIP 被覆盖,因为库是使用 MS Visual Studio /GS 选项编译的(堆栈金丝雀保护)
- 旧版本库的私有符号可用,因此我可以强制它们使用 .reload /i 加载
- 在调用 ProcessMessage 函数后,一个 1023 字节的输出缓冲区被用户控制的输入填充,例如一个 2048 字节的字符串。
- 从该函数 ProcessMessage 返回后,使用调试器单步执行会引发“无法在 .... 处读取动态函数表条目”类型的消息。
这是违规的调用代码:
lea r9,[rsp+78h] ;* _EVENT_DATA_DESCRIPTOR
lea rdx,[rsp+40h] ; format string in data section (.... %s)
mov r8d,1 ; # of _EVENT_DATA_DESCRIPTORs
mov dword ptr [rbp-80h],eax ;stringLen of data in _EVENT_DATA_DESCRIPTOR
mov dword ptr [rbp-7Ch],esi
call qword ptr [Library!ADVAPI32_NULL_THUNK_DATA] ;call to EtwEventWrite
call qword ptr [Library!_imp_PeekNamedPipe ;calls GetCommandLineW
lea rdx,[Library!$xdatasym+0x70] ;format string in data section (.... %s)
lea rcx,[rbp-60h] ;output buffer which will store result of ProcessMessage and will get overrun
mov r8,rax ;result of _imp_PeekNamedPipe. Will used together with format string in rdx to form a string and store it in output buffer in rcx
call Library!`VulnerableClass::ProcessMessage'::`1'::catch$0+0x38
在调用 ProcessMessage 之后,使用 Windbg 进行调试时会出现以下消息:
0:013> p
Unable to read dynamic function table entry at 00007ff801642c90
Unable to read dynamic function table entry at 00007ff801642cd0
0:013> p
Unable to read dynamic function table entry at 00007ff801642c50
Unable to read dynamic function table entry at 00007ff801642c90
这些消息是否意味着我们溢出的缓冲区已经覆盖了堆栈中具有虚拟方法的对象的 vtable 指针?如果是这样,是否有可能知道这些地址属于哪个对象或函数?在这些地址上执行 au 或 dd 没有结果。
如果有帮助,除了当前堆栈帧之外,声明的异常处理程序也被用户输入覆盖(如下所示的 mona.py 模式),不知道它是否必须对有关的消息执行任何操作动态函数表:
0:013> !exchain
31 stack frames, scanning for handlers...
Frame 0x00: Library!VulnerableClass::SetValue+0x88b
ehandler Library!`operator new'::`6'::`dynamic atexit destructor for 'nomem''+0x6490
Frame 0x01: error getting module for 3462413362413262
Frame 0x02: error getting module for 307a5a6241356241
Frame 0x03: error getting module for 7a5a327a5a317a5a
非常感谢您的回答。