我有一个调用 GetOpenFileNameA 和 GetSaveFileNameA 的旧应用程序。 两次调用都是错误的。应用程序崩溃! 我已经使用 OllyDbg 和 API Monitor 来读取存储在 OPENFILENAME 结构中的大小。 该结构的大小为 76 字节(使用 Windows 7 x64 进行测试)。 调用 GetOpenFileNameA 或 GetSaveFileNameA 时出现访问冲突异常。 我假设在运行时窗口试图读取 88 字节而不是 76 字节。 看看这个: http://dotnetbutchering.blogspot.de/2007/10/vc-60-getting-0xc0000005-access.html 还有这个 http://www.asmcommunity.net/board/index.php?topic=5768.15
我做了一些研究,同时我发现了以下行为: 运行 Microsoft Spy++ 时应用程序不会崩溃!! 我单步调试调试器,发现访问冲突异常仍然发生,但异常被吞没了。 该应用程序工作正常!我可以加载和保存文件。
我有以下想法。你觉得他们怎么样?
写某事。就像 Loader.exe 一样,它的功能与 Spy++ 相同。 在调用两个 API 时吞下访问冲突异常。
使用 DLL 注入(inject)和 API Hook 。 我可以将 GetOpenFileName 和 GetSaveFileName 与自定义 DLL 中的自定义实现 Hook 。我的实现将修复该结构并将更正后的结构传递给原始 API 调用。
使用 SetWindowsHook Hook 窗口消息 ?!?!?!
修补二进制文件。是否可以通过使用 HEX 编辑器进行修补来解决此结构大小问题?
哪一个会起作用? 你有更好的办法解决这个问题吗?
我无法获得这个旧应用程序的源代码。 我必须使用现有的二进制文件修复它。 我的解决方案必须至少适用于 Windows XP 和 Windows 7(x86、x64)
工具 PEiD 向我显示了有关旧应用程序的以下信息: 链接器信息:2.55 MS Visual C++ 4.0
最佳答案
The size of the struct is 76 Bytes (testing with Windows 7 x64). I get an access violation exception while GetOpenFileNameA or GetSaveFileNameA is called. I assume that at runtime windows tries to read 88 Bytes instead of 76 Bytes.
如果您查看 OPENFILENAME struct,您会注意到:
#if (_WIN32_WINNT >= 0x0500)
void * pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
#endif // (_WIN32_WINNT >= 0x0500)
在 32 位程序中(VC++ 4 不支持 64 位目标)转换为恰好 12 字节的差异。只要调用者正确设置了 lStructSize,这根本就不是问题。可能值得使用 Microsoft/Sysinternals 的 procdump 来获取确切状态的小型转储(或附加调试器并进行调查)。您遇到的异常不一定是由于 struct 大小造成的。如果是的话,微软很可能在向后兼容这个功能时失手了。显然 OPENFILENAME::lStructSize 用于对 struct 进行版本控制,并确保不会发生您遇到的情况。但是,我们谈论的是使用 Windows 2000 之前的编译器/链接器构建的程序。
write sth. like a Loader.exe which does the same like Spy++. Swallowing the access violation exception when both APIs are called. It's a fair point. If you would insert exception handling at the top level you could do things you want, but it may cause side-effects depending on what exactly caused the exception (i.e. which exact memory was overwritten).
Use DLL Injection and API Hooking. I could hook GetOpenFileName and GetSaveFileName with a custom implementation in a custom DLL. My implementation would fix the struct and pass the corrected struct to the original API calls. This is pretty much related to the first one. I think it will be easiest and safest in all, because this way you can correct the behavior without too much intrusion. Please read further below. Also, check out NInjectLib.
Use SetWindowsHook to hook a window message ?!?!?! I don't see how that helps other than facilitating the injection of a DLL (for 1. and 2.).
Patch the binary file. Is it possible to fix this struct size issue by patching using a HEX Editor? This may be the trickiest, depending on whether the
OPENFILENAMEis inside the binary (initialized data) or on stack or whether it gets allocated on the heap (easy then).
1. 和 2. 的一种可能的混合方法是:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options 以您正在执行的程序命名(例如 foo.exe) Debugger 的 REG_SZ 值,并将该值设置为我现在将尝试简要描述的程序。这有效地为您的这个旧应用程序设置了一个调试器,这意味着我们要编写的调试器将接收您的应用程序的命令行作为参数。它很方便,因为它对最终用户是透明的,您可以根据自己的需要进行调整。
您需要编写一个调试器。这个任务并不像最初看起来那么难,因为您可以使用 Win32 提供的调试助手。要点在调试器循环中。通常,您可以使用 CreateProcess 传递适当的标志来自行创建目标进程,以便能够对其进行调试。使用 WaitForDebugEvent 和 ContinueDebugEvent 来控制执行。出于所有实际目的,您甚至可能根本不需要调试器循环,因为您可以创建目标应用程序的主线程挂起(将 CREATE_SUSPENDED 传递给 CreateProcess)然后指向最开始将主线程的CONTEXT设置为自己的代码,然后调用ResumeThread(pi.hThread)。这样你就可以在主线程启动之前完成。但是,由于 kernel32.dll 的 CreateThread 工作方式(它涉及向 Win32 子系统又名 csrss.exe<>)。因此,最好在内存或类似的东西中修补目标的 IAT。毕竟您只对两个功能感兴趣。
我个人更喜欢基于来自 PaiMei 的 PyDbg 编写我的调试器,但我承认我没有尝试在 Image File Execution Options 中使用这样一个基于 Python 的调试器。
关于c++ - 替换或修改外部应用程序中的 API 调用(GetOpenFileName、GetSaveFileName),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10739312/
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server