- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
缩小这个问题的范围真的很难,但我们开始吧。
我处于加载到主机 (TstCon.exe
) 的 32 位 ActiveX 控件的上下文中。卸载并重新加载控件后,我从 NtMapViewOfSection
收到一连串错误,第一个错误发生在 odbc32.dll
使用 LoadLibraryExW
加载时C:\Windows\system32\odbcint.dll
。那时,SEH 异常从 NtMapViewOfSection
内部某处发出,代码为 0xC0000023
(根据调试器也称为 STATUS_BUFFER_TOO_SMALL
)。
这是调试器拦截异常时调用堆栈的样子:
ntdll.dll!_NtMapViewOfSection@40()
KernelBase.dll!BasepLoadLibraryAsDataFileInternal()
KernelBase.dll!BasepLoadLibraryAsDataFile()
KernelBase.dll!LoadLibraryExW()
odbc32.dll!_InitializeDll@0()
odbc32.dll!_SQLAllocEnv@4()
<OurDll>.dll!<OurFunction>()
...
那时,我已经使用非常理智的技术来检索调用NtMapViewOfSection
的参数,方法是遵循this documentation。 :
*(void**)(ESP + 4 + 0) /*SectionHandle*/ 0x000003b0 void *
*(void**)(ESP + 4 + 4) /*ProcessHandle*/ 0xffffffff void *
*(void**)(ESP + 4 + 8) /*BaseAddress*/ 0x00daae30 void *
*(unsigned long*)(ESP + 4 + 12) /*ZeroBits*/ 0x00000000 unsigned long
*(unsigned long*)(ESP + 4 + 16) /*CommitSize*/ 0x00000000 unsigned long
*(long long**)(ESP + 4 + 20) /*SectionOffset*/ 0x00000000 {???} __int64 *
*(unsigned long**)(ESP + 4 + 24) /*ViewSize*/ 0x00daae28 {0x00000000} unsigned long *
*(int*)(ESP + 4 + 28) /*InheritDisposition*/ 0x00000001 int
*(unsigned long*)(ESP + 4 + 32) /*AllocationType*/ 0x00800000 unsigned long
*(unsigned long*)(ESP + 4 + 36) /*Protect*/ 0x00000002 unsigned long
我最初是通过在 VS 的调试器中启用 break-on-throw 来捕获异常的,然后我就能够查明第一个失败的调用并在前面放置一个断点。这是我在反汇编内部进行调试时可以看到的内容(>
标记当前指令):
_NtMapViewOfSection@40:
76F2EF60 mov eax,28h
76F2EF65 mov edx,offset _Wow64SystemServiceCall@0 (76F43430h)
> 76F2EF6A call edx
76F2EF6C ret 28h
76F2EF6F nop
...进入:
_Wow64SystemServiceCall@0:
> 76F43430 jmp dword ptr [_Wow64Transition (76FD2218h)]
...进入:
> 74A37000 jmp 0033:74A37009
74A37007 add byte ptr [eax],al
74A37009 inc ecx
74A3700A jmp dword ptr [edi+0F8h]
...进入:
_NtQueryObject@20:
76F2EDC0 mov eax,10h
76F2EDC5 mov edx,offset _Wow64SystemServiceCall@0 (76F43430h)
76F2EDCA call edx
> 76F2EDCC ret 14h
76F2EDCF nop
下一个进入会触发异常。
对程序环境的干扰,例如:
/base
链接器标志强制 OCX 的基地址;drstrace.exe
监控系统调用;... 更改对 NtMapViewOfSection
的调用将成功或失败,似乎是随机的:并非所有调用都失败,但有相当一部分会失败。事实上,错误的第一次出现可能并不能说明问题的实际来源,因为我很少能够使它更早地崩溃(在卸载控件时),甚至在 none 的情况下发生崩溃 我们的代码在调用堆栈上(通过直接退出 TstCon.exe
)。
我找不到任何文档(官方或其他)提及 STATUS_BUFFER_TOO_SMALL
或在此上下文中的 0xC0000023
代码。我一直无法在失败的调用中找到模式,并且在 Dr. Memory 运行中没有看到相关的访问错误。
那么......这个过程中可能发生了什么导致出现这种症状?
最佳答案
在长时间检查 ActiveX 控件的执行后,使用调试器跳过特定的代码部分,我将错误的可能位置缩小到单个函数。事实证明,问题的根源几乎无法猜测。
有一天,有人希望能够为线程命名。为此,他们使用了记录在案的 0x406D1388
技术(事实上,代码几乎是从链接文档中复制粘贴的)。这本身就很好。但是后来他们想要(或者我收集到)以编程方式检索名称,自定义异常方法不支持。这一切都是在 SetThreadDescription
/GetThreadDescription
存在之前发生的,所以他们寻找另一种方法。 男人他们有创造力。
除了对抛出自定义异常的函数的调用之外,还有以下几行:
// Grab the TIB.
P_T_TIB pTib = GetTIB();
if (pTib == NULL)
return false;
// If someone has already written to the arbitrary field, I don't
// want to be overwriting it.
if (pTib->pvArbitrary == NULL)
{
// Nothing's there. Set the name.
pTib->pvArbitrary = (void *)pszName;
}
有什么,当然绝对不是“无”。 GetTIB
定义如下:
// A static function to get the TIB.
static P_T_TIB GetTIB()
{
P_T_TIB pTib = NULL;
_asm
{
MOV EAX, FS:[18h]
MOV pTib, EAX
}
return pTib;
}
据我所知,这段高度可疑的程序集检索了一个指向 Thread Information Block 的指针。当前线程的。 T_TIB
的定义遵循该页面上的描述,并允许线程命名函数将指向名称的指针存储到任意数据槽中。在名称获取函数中使用了相同的技术来检索指针并返回名称。
当然,难点在于“任意”并不代表“用户数据”,NtMapViewOfSection
和小伙伴们都是依赖字段来存储信息的,字段上放置的数据断点就是明证被 LdrpMapViewOfSection
等击中。在他们路径的某个地方,遇到具有异常非零值(即我们的名称指针)的字段导致他们执行一些非常错误的操作,最终触发了那个奇怪的异常。
出于好奇,我完全删除了所有这些,因为它没有在其他任何地方使用,并且只是使用了一个 thread_local
变量来存储名称。结案了!
关于c++ - `LoadLibraryExW` 从 `0xC0000023` 触发异常 `NtMapViewOfSection`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53767707/
当尝试通过 LoadLibraryExW 加载 C:\Windows\System32\user32.dll 时,它失败并显示最后一个错误 ERROR_INVALID_IMAGE_HASH。 这是它的
客户正在使用我们的 dll,该 dll 正在创建一个使用开源库的子进程,最终由于调用 LoadLibraryExW() 而失败,返回的最后一个错误是 ERROR_MOD_NOT_FOUND。这发生在
我正在尝试获取 DLL LoadLibraryExW 中函数的地址。但是,当我尝试获取此函数的地址时,我实际上获取了 LoadLibraryExWStub 的地址。 #include #includ
缩小这个问题的范围真的很难,但我们开始吧。 上下文 我处于加载到主机 (TstCon.exe) 的 32 位 ActiveX 控件的上下文中。卸载并重新加载控件后,我从 NtMapViewOfSect
在使用 PyInstaller(开发版本 4.0.dev0+8196c57ab)时,产生了 OSError: [WinError 2] 'The system cannot find the file
我是一名优秀的程序员,十分优秀!