通常,当我具有Vista应用程序时,它会从kernel32.dll升级很少的功能,而大多数情况是InitializeCriticalSection-> InitializeCriticalSectionEx

是否可以反向移植?除了更改链接器OSVersion之外。

编辑:只是很冗长,下面是示例br />

#1 楼

一种方法是创建具有相似名称的“ shim” DLL,以便易于识别。可以逐步使用此技术(即,对于具有类似要求的其他程序,可以随时将附加功能添加到DLL中,而不是每次都使用全新的DLL)。由于需要附加的参数,因此不能简单地替换函数名称(即CriticalSectionEx-> CriticalSection)。 exe文件,例如从“ kernel32.dll”到“ kernel31.dll”(以保留名称的长度并保持数据对齐)。然后,创建一个“ kernel31.dll”,该文件与exe文件放在同一目录中。此“ kernel31.dll”文件的内容将是导出表,导入表和某些功能的包装器。

要创建导入表,您需要另一个程序来读取导入表。原始exe文件,并在每个条目上执行GetProcAddress。对于每个返回有效地址的条目,“ kernel31.dll”导出表将直接添加该条目,并将指向“ kernel31.dll”导入表,以便将该导入名称转发至原始DLL。此函数没有兼容性问题。

对于每个返回零地址的条目,“ kernel31.dll”导出表将指向“ kernel31.dll”内部的包装器,您必须写你自己。

对原始exe中的每个DLL重复此过程(因此,“ ntdll.dll”可能变为“ ntdl1.​​dll”,“ user32.dll”可能变为“ user31.dll”等)。

但是,有两种特殊情况:LoadLibrary及其变体(及其在ntdll.dll中的等效项)和GetModuleHandle及其变体(及其在ntdll.dll中的等效项)。它们需要在“ kernel31.dll”中包装,因为它们可能会尝试动态访问也会存在兼容性问题的DLL或函数。不幸的是,您不能通过静态分析真正确定这一点。这两个包装器将调用kernel32.dll(或ntdll.dll)中的原始函数,然后检查结果。如果DLL不存在,则是在Windows的更高版本中引入它的情况下,自己创建该DLL的情况;如果DLL是真正可选的,则返回此结果。如果该函数不存在,那就是找到对该DLL的引用并重命名它,然后为该DLL的新版本编写函数包装的情况。可能确实很难实现,但是需要详细信息。

评论


只是好奇在种子上可以使用这种垫片吗?太糟糕了XP有SFC,否则XP会有kernelEx

–科尔·埃默特(Kohl Emmert)
16年1月1日在18:00

在msvcp140.dll redist(仍支持XP)中,我可以找到所有缺少的* Ex函数,但名称为__crt [function] Ex。我可以重定向到这些吗?

–科尔·埃默特(Kohl Emmert)
16年1月3日,18:03

此外,msvcp140随附的其他dll(这些UCRT)中也提供了所有缺少的secureapi。

–科尔·埃默特(Kohl Emmert)
16年1月3日,18:15

是的,这些功能应该起作用。

–彼得·弗里
16年1月3日在20:53

#2 楼

这不是一个简单的修复,但是您可以修补导入表,以用InitializeCriticalSectionEx替换InitializeCriticalSection(只需用一个空字节替换E字符),然后修补所有最初对InitializeCriticalSectionEx的调用,以仅传递lpCriticalSection参数而不是dwSpinCountFlags参数。如果对该函数的其他调用不依赖于静态导入,则需要做一些额外的工作。但我不建议您使用这条路线。

也许其他人可以想到一个更简单的解决方案...?

评论


我尝试了一下,但是由于内存分配错误而崩溃了。除了更改导入表外,我在十六进制转储中将00 00更改为56 56

–科尔·埃默特(Kohl Emmert)
16年1月1日在18:04

将56 56更改为00 00与我上面给出的建议不符。

–詹森·格夫纳(Jason Geffner)
16年1月1日在23:15

啊,对不起,你是对的

–科尔·埃默特(Kohl Emmert)
16年1月3日,17:32

#3 楼

这很容易做。

                33 F6 56 56 51 FF 15 F0 C1 4A 00 85 C0
changed into -> 33 F6 90 90 51 FF 15 F0 C1 4A 00 85 C0
                      ^^ ^^


并在导入表中更改字符串

49 6E 69 74 69 61 6C 69 7A 65 43 72 69 74 69 63 61 6C 53 65 63 74 69 6F 6E 45 78 00 // InitializeCriticalSectionEx
49 6E 69 74 69 61 6C 69 7A 65 43 72 69 74 69 63 61 6C 53 65 63 74 69 6F 6E 00 00 00  // InitializeCriticalSection 
                                                                           ^^ ^^