Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

修正在低版本系统上如果用户已经加载了一个用户目录下的指定名称的模块时,之后try_get_module函数并不能加载到系统目录下的该名称的模块的问题 #123

Closed

Conversation

sonyps5201314
Copy link
Contributor

@sonyps5201314 sonyps5201314 commented Oct 12, 2024

使用类似下面的示例:
image
先加载一个程序目录下的version.dll(如群文件中我提供的远程调试器压缩包中的versiXP.dll改名为version.dll),
然后调用YY-Thunks中实现的GetFileVersionInfosizeEx函数,会触发到try_get_module函数被调用,而在低版本系统上(如Windows2003),会导致触发到下图的代码:
image
即LdrLoadDll被调用,而目前代码会导致获取到的模块句柄是程序目录下的version.dll的(如上图中new_handle中值所示)
这并非程序所预期,因此算是个问题。

我这里的延申问题:
因为这里这个问题,在我Win2K3-New分支上,由于有下面这段代码:

    void* new_fp = try_get_proc_address_from_first_available_module(_ProcInfo);
    if (new_fp)
    {
        PIMAGE_DOS_HEADER pImageBase = &__ImageBase;
        PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((PBYTE)pImageBase + pImageBase->e_lfanew);
        if ((ULONG_PTR)new_fp >= (ULONG_PTR)pImageBase &&
            (ULONG_PTR)new_fp < (ULONG_PTR)pImageBase + pNtHeaders->OptionalHeader.SizeOfImage)
        {
            new_fp = nullptr;
        }
    }

会进行API函数指针返回值判断,如果函数是本模块中的就认为该系统下不存在该API,这里因为LdrLoadDll返回了用户目录下的version.dll中的实现(没直接指向本模块KernelEx.dll(YY-Thunks的容器)中的实现,本Windows2003系统目录下的version.dll已经修改,导出了GetFileVersionInfoSizeExW=KernelEx.GetFileVersionInfoSizeExW这个函数,即指向了KernelEx),因此被误认为该系统存在这个API了,因此出现了如下图的无限递归而崩溃的问题。
image

@mingkuang-Chuyu
Copy link
Collaborator

mingkuang-Chuyu commented Oct 14, 2024

暂时不太赞同这类更改,其实现在的行为符合我最初的设计(如果当前进程已经有了一个version.dll,那么就会使用它,它应该正确处理系统version的能力)

现在的使用场景再YY-Thunks设计时最初没有考虑,目前的解决方案我也存在很多疑虑。

如果这样更改,我暂时可以下面几个问题。

  1. 某些DLL程序就想要使用程序下的新版本DLL,比如说DbgHelper相关,如果强制从System32加载,这类能力就可能会出现问题。

    • 我不知道我应该真的使用程序跟目录的,还是System32的,如果我直接使用System32的,那么想要使用程序目录DbgHelper的用户就会有异议。
    • 有些环境也可能自己实现了一份API实现,现在的行为可以正确回落到对应大多数用户预期的实现里。
  2. 另外现在这个行为其实还有更加极端的情况,比如说,用户自己用YY-thunks编译了一个bcrypt.dll,并且放在了XP系统的System32目录。就算程序显式从System32加载,问题任然无法避免。

    • 使用者可能会理所应当的认为XP没有bcrypt.dll,我自己编译一个放系统目录,给大家使用是合理的。

@mingkuang-Chuyu
Copy link
Collaborator

此PR我存在一些疑虑,因此暂不考虑合入。

不过私下讨论后,感觉提供自定义加载能力比较合理,而且似乎也能满足需求。

5306e8d

@mingkuang-Chuyu mingkuang-Chuyu removed the 进度:需要更多信息 Further information is requested label Oct 19, 2024
@sonyps5201314 sonyps5201314 deleted the fix_LdrLoadDll branch October 22, 2024 02:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants