首页 > 其他分享 >使用 IDA 和 windbg 调试 LNK1123 转换到 COFF 期间失败:文件无效或损坏(中)

使用 IDA 和 windbg 调试 LNK1123 转换到 COFF 期间失败:文件无效或损坏(中)

时间:2022-12-13 11:01:23浏览次数:71  
标签:__ file windbg res piob dx LNK1123 COFF

使用 IDA 和 windbg 调试 LNK1123 转换到 COFF 期间失败:文件无效或损坏(中)

原总结排错process monitorvsIDAwindbg调试rcCVT1101LNK1123

前言

在 ​​上一篇文章​​​ 中,我们总结了使用 ​​windbg​​ 和 ​​IDA​​ 找出 ​​cvtres.exe​

几个值得深究的问题

  1. 为什么链接的时候需要调用 cvtres.exe 呢?
    ​​​微软官方描述​​ 摘录如下:

You can specify a .res file when linking a program. The .res file is created by the resource compiler (RC). LINK automatically converts .res files to COFF. The CVTRES.exe tool must be in the same directory as LINK.exe or in a directory specified in the PATH environment variable.

  1. ​stackoverflow​​ 上有一个更加详细的描述,摘录如下:

Input files must have the Common Object File Format (COFF) format. If an input file is not COFF, the linker automatically tries to convert 32-bit OMF objects to COFF, or runs CVTRES.EXE to convert resource files. This message indicates that the linker could not convert the file. This can also occur when using an incompatible version of CVTRES.EXE from another installation of Visual Studio, the Windows Development Kit, or .NET Framework.

  1. 有没有更好的设置条件断点的方式?目前的语法实在是太难用了。
    可以使用

​dx​

  1. 提供的语法来设置条件断点。先定义一个辅助函数

​@$get_wfs_open_file_param​

  1. 用来获取

​file​

dx @$get_wfs_open_file_param = (esp_value => ((wchar_t*)*((int*)esp_value+1)).ToDisplayString("sub"))

设置条件断点

bp /w "@$get_wfs_open_file_param(@esp).EndsWith(\"510.res\")" MSVCR120!_wfsopen

是不是比传统的方式好理解的多?如果不想定义辅助函数,可以直接像下面这样设置条件断点。

bp /w "((wchar_t*)*((int*)@esp+1)).ToDisplayString(\"sub\").EndsWith(\"510.res\")" MSVCR120!_wfsopen

有什么简单的办法可以查看 __piob

  1. 在前一篇文章中,只是通过逻辑推理确定了当尝试打开

​510.res​

  1. 时,

​__piob​

  1. 数组中的每个元素都被占用了。并没有实际查看其内容。其实,可以通过

​dx​

  1. 命令非常方便的查看想要查看的内容。比如,可以只查看那些可用的记录项(值为

​NULL​

  1. 或者不满足

​inuse()​

​str_locked()​

  1. 为了让代码更容易理解,定义了几个辅助变量及函数。
$$ 以下变量定义在 VC\crt\src\stdio.h 中
dx @$ioReadFlag = 0x1
dx @$ioWriteFlag = 0x2
dx @$ioRWFlag = 0x80
dx @$ioLockedFlag = 0x8000

$$ inuse() 和 str_locked() 定义在 VC\crt\src\file2.h 中
dx -r0 @$IsInUse = (f => f->_flag & (@$ioReadFlag | @$ioWriteFlag | @$ioRWFlag))
dx -r0 @$IsLocked = (f => f->_flag & @$ioLockedFlag)

$$ 使用自定义变量 my_piob 指向 __piob
dx -r0 @$my_piob = (FILE*[512])MSVCR120!__piob

$$ 找到所有可用的记录的数量
dx @$my_piob.Where(f => f == 0 || (@$IsInUse(f) && @$IsLocked(f) ) ).Count()

$$ 找到所有不可用的记录的数量
dx @$my_piob.Where(f => !(f == 0 || (@$IsInUse(f) && @$IsLocked(f) ) ) ).Count()

当打开 ​​510.res​

使用 IDA 和 windbg 调试 LNK1123 转换到 COFF 期间失败:文件无效或损坏(中)_初始化

为什么在打开 510.res

  1. 猜测应该是已经打开了一些文件。为了验证这个猜测,再次调试。

​cvtres.exe​

  1. 中断到

​windbg​

  1. 后,执行

​x MSVCR120!__piob​

  1. 查看

​__piob​


可以看到此时 ​​__piob​​ 的地址是 ​​0x6250fe00​​ ,值是 ​​0​​。说明此时还没被赋值。通过 ​​ba w4 0x6250fe00​​ 设置内存写断点设置好后,执行 ​​g​​ 命令恢复运行。几乎立刻中断到 ​​windbg​

使用 IDA 和 windbg 调试 LNK1123 转换到 COFF 期间失败:文件无效或损坏(中)_初始化_02

可以看到 ​​__piob​​ 会在 ​​__initstdio()​​ 函数中被初始化。而且前 ​​_IOB_ENTRIES​​ 项(值为 ​​20​​)的值会被 ​​_iob​​ 中对应的值赋值。而 ​​_iob​

使用 IDA 和 windbg 调试 LNK1123 转换到 COFF 期间失败:文件无效或损坏(中)_赋值_03

所以,​​cvtres.exe​​ 最多只能通过 ​​_wfsopen()​​ 函数打开 ​​512-3 = 509​​ 个文件。也就是说,只能打开 ​​1.res ~ 509.res​​,打开 ​​510.res​

注意: _iob 的前三项分别指向了 stdin, stdout, stderror。我是怎么知道的?看代码呗。

使用 IDA 和 windbg 调试 LNK1123 转换到 COFF 期间失败:文件无效或损坏(中)_条件断点_04

除了通过

_iob

初始化代码的注释可以看出来前三项的意义,也可以通过

stdio.h

使用 IDA 和 windbg 调试 LNK1123 转换到 COFF 期间失败:文件无效或损坏(中)_初始化_05

More

还有一个小问题没解决 —— 为什么设置 ​​PATH​​ 环境变量后,直接通过文件名启动程序,​​windbg​

总结

  • 命令行程序默认会打开三个文件

​stdin、stdout、stderror​

  • 。所以,

​crt​

  • 默认能同时打开的文件数是

​509​​​​dx​

参考资料

​https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/setting-a-conditional-breakpoint​

​https://docs.microsoft.com/en-us/cpp/build/reference/dot-res-files-as-linker-input?view=msvc-170​

​https://stackoverflow.com/questions/61581826/visual-studio-2019-cvt1101-lnk1123-fatal-error​

​vs2013​​ 自带的 ​​crt​

欢迎各位小伙伴指出不足,提出建议!感谢关注我的博客:)

作 者:​​编程难​​

码云博客:​​https://bianchengnan.gitee.io​

github博客:​​https://bianchengnan.github.io​

版权所有,转载请保留原文链接:)



标签:__,file,windbg,res,piob,dx,LNK1123,COFF
From: https://blog.51cto.com/u_15469822/5933161

相关文章

  • 使用Windbg找出程序CPU高问题
    使用Windbg找出程序CPU高问题ReggieDing系统架构师​关注 1人赞同了该文章背景本人在把应用程序部署到服务器上运行,观察一段时间后运行平稳,CPU......
  • Windbg提示:*** WARNING: Unable to verify checksum for 的处理
    当我们用windbg调试时,经常会遇到“***WARNING:Unabletoverifychecksumforxxx.dll”这样的提示,他的意思时不能校验某某模块的校验和。这一般都是我们的动态库或exe的......
  • windbg preview下载及其历史版本下载
    WinDBG是专门针对WindowsNT系列操作系统而设计的调试器。WinDBG的最初版本是微软公司在开发最初WindowsNT操作系统(NT3.1)期间推出的,它是当时NT团队内部开发和调试NT操作系......
  • windbg 分析 32 位进程的 64 位转储文件
    场景:x86的项目在x64的windows机器上运行时出现未响应的情况,使用任务管理器创建该进程的转储文件因为项目是32位的,所以使用x86的windbg来调试dmp文件,使用kn......
  • Windbg命令大全
    Windbg是在windows平台下,强大的用户态和内核态调试工具。相比较于VisualStudio,它是一个轻量级的调试工具,所谓轻量级指的是它的安装文件大小较小,但是其调试功能,却比VS更为......
  • WinDBG详解进程初始化dll是如何加载的
    一:背景1.讲故事有朋友咨询个问题,他每次在调试WinDbg的时候,进程初始化断点之前都会有一些dll加载到进程中,比如下面这样:Microsoft(R)WindowsDebuggerVersion10.0.252......
  • windbg调试kvm windows虚机
    参考:http://m.blog.chinaunix.net/uid-22954220-id-4733247.html准备2台虚机,一台target目标机,用于运行要调试的windows系统(调试内核),一台debug调试机,用于运行windbg,配置......
  • windbg下看系统非分页内存
       这篇文章实在是闲的无聊才写的,因为快过年了...文章基于xpsp3   先看看和非分页内存相关的全局变量,也好有个大局观:kd>xnt!MmNonPaged*805517d8nt!Mm......
  • 用windbg为无效页面建立页面映射
       前几天和同事扯淡,说调试驱动时访问无效内存会蓝屏,好麻烦,应该让windbg自动建立一个有效的页面,这样就不用蓝屏重启了。虽然说这是扯淡,但仔细想想貌似也不是不可能实现......
  • windbg调试服务程序
       相比通过输出日志来跟踪程序运行状态,我更倾向使用调试器。虽然我早知调试服务很麻烦,总不会比调试驱动还麻烦吧?基于这个想法,我尝试了在win7上使用windbg调试服务并记......