Articles of LoadLibrary

LoadLibrary冻结

我已经编译了一个JNI dll,我想使用System.loadLibrary加载到我的Java应用程序中。 这在Windows XP上使用MSVC ++ 2008 Express编译的dll非常好。 但是,在Windows 7上,我使用MSVC ++ 2010 Express编译dll(相同的选项,相同的处理器架构,相同的Java版本,只是不同的操作系统和编译器),应用程序将冻结loadLibrary调用。 没有错误信息,根本没有反应。 当我尝试jstack冻结过程时,它也冻结(没有输出,不终止)。 以pipe理员身份运行应用程序不能解决此问题。 该DLL及其所有依赖项都位于java.library.path 。 事实上,当我删除它们时,Java应用程序会告诉我它们错过了,所以这个DLL必须已经被正确地初始化了,而其他的东西却没有成功。 然而,debuggingcertificate,实际上loadLibrary冻结的,之后什么也不做。 有人可以告诉我可能会发生什么吗? 更新 : 正如我在下面的评论中所说的,这个问题似乎越来越深入。 使用一个简单的C程序加载DLL的依赖关系之一已经使冻结发生,所以这一定是Windows API的某种问题,以及MSVC ++如何链接DLL(该依赖关系也由MSVC ++ 2010 Express链接) 。

从文件中的偏移量LoadLibrary

我写了一个脚本化的游戏引擎,为此我有大量的类执行各种任务。 引擎的大小正在迅速增长,所以我想把大的可执行文件分解成dll模块,以便只包含游戏编写器实际使用的组件。 当用户编译他们的游戏(也就是说他们的脚本)时,我希望正确的dll是最终可执行文件的一部分。 我已经有相当多的覆盖数据,所以我想我可能能够存储DLL作为这个块的一部分。 我的问题归结为: 是否有可能欺骗LoadLibrary开始读取文件在一个特定的偏移量? 这将使我不必将DLL提取到一个不干净的临时文件中,或者把dll的自动包含完全废除,并简单地指示我的用户将DLL与游戏一起打包。 起初,我想到的是“从内存中加载DLL”的方法,但由于可移植性而拒绝它,只是因为它看起来像一个可怕的黑客攻击。 有什么想法吗? 亲切的问候, 菲利普·本尼弗

与其他“dll”扩展名的文件的LoadLibrary

是否有可能加载一个dll文件,没有“dll”扩展名? 谢谢

Win32应用程序是否自动链接到ntdll.dll?

我只是偶然发现,执行此GetModuleHandle("ntdll.dll")没有以前调用LoadLibrary("ntdll.dll") 。 这意味着ntdll.dll已经加载在我的过程中。 假设ntdll.dll将永远在Win32应用程序中加载是否安全,因此不需要调用LoadLibrary ?

从多个目录加载Win32模块

我有一个程序,在多个目录中存储插件,如下所示: root/ core/bin/ app.exe core.dll plugin.dll support.dll a/bin/ a.dll a_support.dll 在这个例子中, a.dll导入core.dll , support.dll和a_support.dll (它们按照导入表中的顺序)。 a_support.dll导入support.dll 。 我可以改变所有的支持模块,那些是第三方库的redist。 我的代码调用LoadLibraryEx(name, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)加载每个插件。 对于core.dll和plugin.dll ,这工作正常。 当我尝试加载a.dll ,它失败, 说没有finda_support.dll 。 没有关于core.dll或support.dll错误,也许是因为它们已经在内存中。 我的怀疑是,当加载a_support.dll , support.dll无法find,但这似乎是不寻常的,因为a.dll似乎在a_support.dll之前导入support.dll 。 这是模块的布局甚至可能使用? 系统能够使用已经加载的支持DLL,还是会去search它们并失败? 有没有办法通过体现来处理这个问题? 有没有办法使这个工作,或者我将不得不将所有模块重新放置到一个单一的目录? 编辑:在阿德里安·麦卡锡的build议,我运行加载序列与进程监视器跟踪,似乎当我调用LoadLibrary("root/a/bin/a.dll", …) ,它开始search根目录,然后系统目录,然后通过path。 出于某种原因,它从不searcha/bin/ ,它非常应该。 我仔细检查path,并注意到我的调用加载plugin.dll在哪里使用错误的path(根,而不是根/核心/斌)。 无论哪种方式, core.dll加载正确。 修复后,我再次尝试,这次a.dll确实finda_support.dll ,似乎加载。 但是,这绝对没有意义,除非加载程序成功地使用support.dll从某处。 该procmon日志不显示它甚至试图加载support.dll再次,所以我不完全确定在这一点上,如果实际上有一个问题(除了加载器的行为没有任何意义)。

是否有可能加载到地址空间而不是从文件系统文件的DLL?

我必须创build一个包装器DLL,导出一些符号(函数)。 它的资源中包含另一个实际完成这个工作的encryption DLL。 包装器DLL初始化后,它将解密原始文件,将其保存在文件中,并通过LoadLibrary将其加载到地址空间中。 不过,我想避免将这个DLL保存在一个文件中。 我知道这并不保证防弹保护,但实际上可能会转储虚拟内存并在那里看到它。 我也知道可以用FILE_FLAG_DELETE_ON_CLOSE属性创build一个文件,这个文件可以确保这个文件一旦被终止,就会被删除。 但是,我仍然想知道是否有一个选项来加载DLL“不是从一个文件”。 到目前为止,我想到了以下几点: 分配具有适当保护的虚拟内存块( PAGE_EXECUTE_READ或PAGE_EXECUTE_READWRITE )。 最好在图像的首选基地址。 在那里提取/解密DLL图像。 如果图像基地址不是其首选地址 – 请手动重新定位。 即 – 分析重新定位表并在原地修补图像。 处理图像导入。 加载它的依赖DLL并填​​充符号地址。 调用它的初始化函数( DllMain )。 也就是说,我可以做装载机的工作。 但不幸的是,有一些地区,由上述技巧加载的DLL会有不同的performance,因为从操作系统的angular度来看,它不是一个正确加载的DLL。 这包括以下内容: DllMain需要DLL“模块句柄”,这只是它的基地址。 它可以在调用各种AP​​I函数(如LoadResource使用此LoadResource 。 这些电话可能会失败。 exception处理会有问题。 操作系统将不会看到DLL的SAFESEH部分,因此它的内部exception处理代码将不会被调用(这是一个64位的DLL,意味着SAFESEH对于exception处理是强制性的)。 这是我的问题:是否有一个API正确加载到进程地址空间的DLL,而不需要在文件中? LoadLibrary一个替代变体,例如,在文件映射而不是文件系统文件上工作? 提前致谢。

CTYPES中的函数名称parsing如何工作?

我正在使用Windows API,其函数名称以32位dll(例如_FunctionName)中的下划线开头,但不是64位版本(例如FunctionName)。 我使用类似于此的代码来加载和调用64位版本的函数: dll = windll.LoadLibrary('library.dll') dll['FunctionName']() 但是,我发现我也可以使用相同的代码来调用32位函数,即使它们以下划线开头。 我甚至可以用除了下划线以外的东西来使用函数名,它仍然可以parsing。 如果我完全更改名称,则不会按预期解决问题。 我想避免有不同的方式来调用64位和32位平台的function,这似乎工作。 但是,我无法find有关此行为的任何文档。 任何人都可以确认行为或提供文件吗?

一个进程可以加载两个完全相同名字的DLL吗?

帮助解释MSDN : dynamic链接库search顺序 … 如果具有相同模块名称的DLL 已经加载到内存中,那么在parsing到加载的DLL之前,系统只检查redirect和清单,而不pipe它在哪个目录中。 系统不search该DLL 。 注意:具有相同名称的多个DLL基本上是一个坏主意,这只是为了得到一个更好的图片。 考虑: …\x\foo.exe …\x\a\bar.dll ~ no further dependencies …\x\b\bar.dll ~ no further dependencies 是否有可能通过显式的加载库调用将这两个bar.dll到foo.exe ? 以及在哪里/如何logging和支持(否则我只是试试。) 也就是说,以下可靠工作在Windows7 +上: // Load using full path: HANDLE a_mod = LoadLibrary(L"…\x\a\bar.dll"); HANDLE b_mod = LoadLibrary(L"…\x\b\bar.dll"); // now use moth DLLs …

什么是“不能设置分配”错误,谁发出它,我能做些什么呢?

几年来,我们一直困扰着客户,关于在我们的应用程序启动时出现的一个非描述性错误消息“无法设置分配”。 到目前为止,我们从来没有能够在我们自己的testing环境中重现这个问题。 我现在已经没有想法试图追踪这个问题了。 以下是一段时间内积累的观测数据: 错误消息文本显示“无法设置分配”(注意缺less标点符号)。 窗口标题只是读取“错误”(或等效的本地化)。 不pipe操作系统区域设置如何,“无法设置分配”文本总是英文。 到目前为止,我还没有find包含消息文本的DLL或EXE。 谷歌充满了各种不同产品的这种错误报告 – 但没有解决scheme。 到目前为止,我所能做出的受影响产品之间唯一的统一方面是,它们似乎都是以加载到第三方进程的DLL的forms出现的(例如Visual Studio或Windows资源pipe理器shell扩展的插件)。 我们的应用程序实际上是一个用Delphi编写的用于MS Outlook的共享软件COM插件(即本机代码 – 无.NET)。 在我们的案例中主要的嫌疑犯是我们正在使用的第三方许可包装,它们将我们的DLL解密和解压缩到内存中。 显然,我不能简单地给我们的应用程序的受保护的版本给受影响的客户来validation这个怀疑。 也许其他已经报道过的厂商正在使用类似的产品。 由授权供应商提供给我们的保护包装器的debugging版本没有得到任何结果:日志文件看起来与没有发生错误的会话完全相同。 显然,“内部”DLL得到解密和解压缩,但由于某种原因,仍然无法由主机进程加载。 通过创build一个不受保护的“加载程序”DLL,我们已经能够精确定位LoadLibrary调用后面的错误,这个调用应该将我们的DLL加载到内存中。 在我们自己的代码(无保护的加载程序和受保护的“核心”-DLL)中,广泛的日志logging和全局exception挂钩根本没有任何结果。 这个错误显然是在别的地方引起的。 前面这个问题所描述的问题很可能是由同一个问题引起的。 这是在我们创build未受保护的装载程序存根之前。 这个错误只发生在我们客户的1-2%左右,而通常所有受影响客户现场的安装都受到相同的影响。 有时错误会在我们发布新版本后消失,但经常会在几周或几个月后再次出现。 一旦错误发生在机器上,就会一直如此。 当通过远程访问(例如VNC,RDP,TeamViewer等)连接到受影响的机器时,从未发生错误,并且所有受影响的客户都不在我们的行驶距离内,所以我们只需要logging文件和“目击者报告“。 有一个客户报告说,错误消息对话框显然是非模态的,也就是说,他能够简单地将对话框移到一边,继续使用应用程序(减去我们DLL提供的function)。 不知道这在所有其他事件中是否也是普遍存在的。 在某些情况下,客户可以通过禁用或卸载其他供应商提供的与我们自己的产品共享主机应用程序的其他插件,从而永久消除错误。 到目前为止,在Windows XP,Vista和7上都出现了这个错误。 在过去的几周里,我们从Outlook 2003 / Windows 7用户那里得到了大量的报告。 最近的Windows / Office更新会让情况变得更糟吗? 有没有人有任何经验,这个错误呢? 还是有更多的想法来调查这个?

LoadLibrary采取LPCTSTR

我想用LoadLibrary开发一个插件系统。 我的问题是:我想我的函数采取一个const char*和LoadLibrary需要一个LPCTSTR 。 我有明确的想法做(LPCSTR)path不断给我一个模块找不到错误。 当前的代码如下。 如果我取消注释widepath = L..线,它工作正常。 我已经阅读使用MFC的解决scheme,但我不想使用MFC。 当前代码: bool PluginLoader::Load(char *path) { path = "Release\\ExamplePlugin.dll"; LPCTSTR widepath = (LPCTSTR)path; //widepath = L"Release\\ExamplePlugin.dll"; HMODULE handle = LoadLibrary(widepath); if (handle == 0) { printf("Path: %s\n",widepath ); printf("Error code: %d\n", GetLastError()); return false; } int (*load_callback)() = (int (*)()) GetProcAddress(handle, "_plugin_start@0"); if (load_callback == 0) […]