[记录点滴]授人以渔,从Tensorflow找不到dll扩展到如何排查问题

[记录点滴]授人以渔,从Tensorflow找不到dll扩展到如何排查问题

0x00 摘要

本文将通过一个经典的 “tensorflow找不到dll” 问题来入手,给大家一个如何找到缺失dll的办法,进而再分享一个windows上排查问题的好工具(因为大多开发者在windows上开发&在linux上部署,windows还是绕不过)。

0x01 引言

很多朋友在windows上安装tensorflow之后,第一次运行会遇到如下错误:

ImportError: DLL load failed: 找不到指定的模块。

大家第一反应就是去网上搜索,比如常见的解决办法是:

  • 运行环境不全,安装vc_redist.x64.exe即可,比如在tensorflow官方的release note中有提示。
  • 安装visual studio2017。
  • 由于tensorflow 2.1.0 版本较高,需要安装 CUDA、cuDNN神经网络加速库等,直接降版本。
  • ......

很多朋友解决了这个问题就继续运行tensorflow了,没有继续思考这个问题。

其实,绝大多数问题原因是:tensorflow运行环境缺少库, msvcp140_1.dll, 或者 VCRUNTIME140_1.dll,而vc_redist.x64.exe就是安装了这个库,visual studio2017则刚好有运行tensorflow必须的运行时环境。

但是从而有几个新问题:

  • 如何知道缺少哪个dll?因为我实验了两台电脑,一台提示缺少msvcp140_1.dll,一台没有任何提示,最后发现是缺少VCRUNTIME140_1.dll。
  • 如果新版本tensorflow又缺少其他的dll怎么办?
  • 如果其他软件缺少dll怎么办?
  • 如果在windows上遇到其他古怪的问题怎么办?

所以我们的终极目标是:

  • 如果某个软件也出现缺少dll的情况,我们应该有办法知道缺少哪个dll
  • 如果在windows上遇到其他古怪问题,我们应该知道有什么工具来帮我们解决。

下面就让我们解答这两个问题。

0x02 如何找到缺失的dll

面对缺失的dll,我们的办法是:祭出 Process Monitor 大招

Process Monitor是一款 Windows 系统和应用程序监视工具,总体来说,Process Monitor相当于Filemon+Regmon,其中的Filemon专门用来监视系统 中的任何文件操作过程,而Regmon用来监视注册表的读写操作过程。

有了Process Monitor,使用者就可以对系统中的任何文件和 注册表操作同时进行监视和记录,通过注册表和文件读写的变化, 对于帮助诊断系统故障或是发现恶意软件、病毒或木马来说,非常有用。

Process Monitor 由优秀的 Sysinternals 开发,并且目前已并入微软旗下,可靠性自不用说。

2.1 Process Monitor可以捕获哪些事件?

Process Monitor 虽然可以捕获 Windows 操作系统中的大多数操作数据,但并非抓取每条信息。它所做的只是获得特定类型的 I/O(输入/输出)操作,其中就包括:文件系统、网络通讯和注册表。当然它还会额外跟踪其它比较有限几种事件,例如:

  • 注册表:监控注册表的创建、读取、删除或查询操作。
  • 文件系统:监控本地磁盘或网络驱动器中文件的创建、写入、删除等操作。
  • 网络:监控进程的 TCP/UDP 源和目标及流量。
  • 进程:可以被动监控进程和线程的活动,包括线程的启动或退出等。不过通常情况下我们都使用 Process Explorer 来监控进程。
  • 性能分析:Process Monitor 还可以捕获进程的 CPU 时间和内存使用,通常情况下这些信息我们也主要依赖 Process Explorer 来监控分析。

总的来说,Process Monitor 可以捕获和监控 Windows 中的 I/O 操作,虽然它不记录实际对注册表、文件系统或网络传输中的数据,但我们可以监控到进程的所有操作事件

2.2 Process Monitor默认列

Process Monitor 的默认列中显示了微软认为对用户最为有用的常用信息,其中从左到右分别为:

  • Time:此列对应每行,显示该事件发生的精确时间
  • Process Name:此列显示的为生成该事件的进程名称,默认该列只显示进程所对应的 exe 文件名称,如果将鼠标指向某个进程名则会悬浮显示该 exe 在磁盘中的具体路径。
  • PID:这个不用多说吧,就是进程 ID
  • Operation:该列记录的是该事件中所执行的操作名称,主要匹配对注册表、文件、网络和进程的操作。
  • Path:此列记录的是此事件操作路径,非进程的路径。例如:WriteFile 事件在此路径中记录的是操作的文件或文件夹路径,如果是注册表事件则会记录所操作的注册路径。
  • Result:此列记录的为该事件操作结果,主要状态有SUCCESS(成功)或ACCESS DENIED(访问拒绝)等。
  • Detail:此列记录一些事件操作的额外细节信息,通常不对排错起太大意义。

当然,以上这些列只为 Process Monitor 提供的默认列,如果你觉得不够的话可以在列名上右键 — 选择 Select Columns 来自定义选择所需的列。

2.3 排查过程

下文的实验环境是缺少msvcp140_1.dll,我们假设没有提示dll文件名字。因为因为我实验了两台电脑都安装同样版本tensorflow,一台提示缺少msvcp140_1.dll,一台没有任何提示,最后发现是缺少VCRUNTIME140_1.dll。

2.3.1 实验代码

import tensorflow as tf
print(tf.version)

错误如下:

File "C:\Users\xxx\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\platform\self_check.py", line 61, in preload_check
    % " or ".join(missing))
ImportError: Could not find the DLL(s) 'msvcp140_1.dll'. TensorFlow requires that these DLLs be installed in a directory that is named in your %PATH% environment variable. You may install these DLLs by downloading "Microsoft C++ Redistributable for Visual Studio 2015, 2017 and 2019" for your platform from this URL: https://support.microsoft.com/help/2977003/the-latest-supported-visual-c-downloads

2.3.2 初步上手

打开 Process Monitor,我们可以看到有很多python.exe的事件

2.3.3 筛选Process Monitor数据

我们可以用非常颗粒化的过滤器来筛选 Process Monitor 所捕获的事件,这非常有利于我们对单个进程所生成的事件进行分析。例如当我们只关心 python.exe 所生成的事件时,只需将其过滤出来即可。

当我们选择 include ‘python.exe’ 之后,界面中则会只筛选出 python.exe 进行的相关事件。

我们这时候发现,现在事件分为两种:

  • 对注册表的操作。
  • 对文件系统的操作。

对于我们这个例子来说,注册表操作没啥意义,所以我们只关心对文件系统的操作。但是这样事件也太多了,所以我们只筛选出没有找到文件的数据,即Result 是 NAME NOT FOUND的事件

2.3.4 Filter

于是我们建立两个Filter来筛选事件。

一个是指定进程名字是python.exe。

一个是指定Result是NAME NOT FOUND。

建立的filter如下:

结果可以看出来,python.exe 在很多目录下查找 msvcp140_1.dll。这就是python在path中所有路径下查找这个文件

2.3.5 查看单个事件

我们可以双击 Process Monitor 中的任意一条事件来查看其详细信息。

双击打开 Event(事件) 标签,其中将列出该事件的详细时间、事件类型、事件所执行的操作、操作路径及事件的执行结果等内容。

当我们切换到 Process(进程) 选项卡之后,则可以看到生成该事件的进程的大量相关信息。

而在 Stack(堆栈) 标签中,我们可以查看到该事件进程的堆栈,通过该选项卡我们可以检查任何不正常的模块。举个例子,假设某个进程不断尝试查询或访问不存在的文件,但我们不知道为什么会发生这种情况。此时,便可以通过查看 Stack(堆栈) 标签来查看是否有任何不正常的模块。

2.3.6 总结

现在我们知道是python.exe 在很多目录下查找 msvcp140_1.dll。我们就可以去网上搜索这个dll,直接拷贝到系统目录下即可。

同时我们也初步了解了如何通过 Process Monitor 来查找一个缺失的dll。

0x03 Linux下怎么办?

3.1 Linux 版本

可能有人会问,在windows下有process monitor可以监控各种事件,那么在linux下如果有类似需求,我应该如何处理?

微软贴心的提供了一个Linux版本,而且开源了 https://github.com/Microsoft/Procmon-for-Linux

其简介是:

Process Monitor (Procmon) is a Linux reimagining of the classic Procmon tool from the Sysinternals suite of tools for Windows. Procmon provides a convenient and efficient way for Linux developers to trace the syscall activity on the system.

但是这个就不是绿色版本了,而是需要自己编译安装。

3.2 用法举例

具体用法举例如下:

  • 跟踪系统所有进程和系统调用
sudo procmon
  • 跟踪进程号10和20的进程
sudo procmon -p 10,20
  • 只跟踪进程号为20的进程的如下系统调用: read, write and openat
sudo procmon -p 20 -e read,write,openat
  • 跟踪进程35,并且把所有事件输出到procmon.db
sudo procmon -p 35 -c procmon.db

3.3 屏幕示例

具体屏幕示例如下:

目前为止,我们知道了如何排查dll缺失。但是在windows上如果遇到了其他古怪问题,我们应该怎么处理呢?下面我们继续了解一个排查神器。

0x04 一个给力的排查神器

下面文字几乎都摘录 SysInternals系列:什么是SysInternals工具集 这个系列。

4.1 SysInternals

我们之前提到Process Monitor 属于SysInternals,那么我们下面为大家推荐的排查神器就是SysInternals套件

SysInternals 工具集最早由大牛 Mark Russinovich 开发,它是一套完全免费的 Windows 工具套件,其官方网站为 www.SysInternals.com 。由于已经于 2006 年被微软收购,Mark 也已经出任 Aazure CTO,访问网址时会直接跳转到 Technet 的 SysInternals 主页。

该工具集在平常的维护和排错工作中经常都会用到,微软的 Troubleshooting 团队也会经常使用该工具集中的工具。正是由于其强大的功能和便利性,被微软收购也不足为奇了。SysInternals 工具集的工具有很多,大概涵盖了如下的几个类型:

  • 文件和磁盘工具
  • 网络工具
  • 进程工具
  • 安全工具
  • 系统信息工具
  • 其它类型工具

Sysinternals 套件可以免费从微软 Technet 网站下载,而且都是绿色版无需安装,大家可以放到 U 盘中随身携带,非常方便。

4.2 功能简介

因为大家不是专业的windows运维,所以只要快速浏览,大概知道此神器有哪些功能,遇到问题时候知道搜索什么关键字即可。最重要的是知道有这个神器,知道搜索什么内容

4.2.1 Process Explorer

Process Explorer 是一个类似于任务管理器和资源监视器的应用,它自 2001 年首次发布以来历经了 Windows 9x 至支持 Windows 10 的各种 Windows 版本,目前微软还在不断的更新和改进,是我们日常处理故障和排错的必备利器。

下面列举了 Process Explorer 一些常用功能及特性清单,有许多非常有用的功能都掩藏在其不起眼的界面之下,很多时候一个很小的功能和特性就能够帮我们在排错时少走弯路和节约时间,大家一定要用心去发觉。

  • 它默认以进程树的方式显示进程及子进程之间的关系(可开关)且以颜色进行区分让人一目了然
  • 非常精确的 CPU 占用显示
  • 提供替代任务管理器的选项,在 Windows XP/7/Vista/8/10 中都非常有用
  • 可以任务栏托盘图标的方式监视 CPU、磁盘、GPU 和 网络等的使用情况
  • 查看进程加载了哪些 DLL
  • 查看进程打开或锁定了哪些文件或文件夹
  • 查看任何进程的完整信息,包括:线程、内存占用、句柄、对象和其它几乎任何你想知道的内容
  • 可以直接 Kill 掉整个进程树
  • 可以将进程挂起(暂停),冻结其所有线程
  • 强大到可以查看线程的CPU使用率
  • 从 v16 版本开始集成了VirusTotal,可以快速验证是否是病毒

4.2.2 PsTools

PsTools 可以帮助我们在命令行中执行相当多的管理任务,更主要的是可以将其写成脚本来执行周期性重复任务或在管理大批量服务器时提高效率。

作为 Sysinternals 工具包中的一个子集,PsTools 本身就有十来个命令行小工具,下面我们会逐个为大家进行介绍:

  • PsExec – 在远程计算机执行命令
  • PsFile – 查看打开的网络文件
  • PsGetSid – 获取 Machine SID
  • PsInfo – 查看简要系统信息
  • PsKill – 按进程名或PID杀掉进程
  • PsList – 列出进程信息
  • PsLoggedOn – 显示已登的会话
  • PsLogList – 命令行获取 event log
  • PsPasswd – 更改用户密码
  • PsPing – 简单的tcp/udp连接测试工具
  • PsService – Windows 服务管理命令
  • PsShutdown – 关机、注销命令
  • PsSuspend – 暂停或恢复某个进程

以上所有命令都可以直接在本地计算机上使用。

4.2.3 TCPView

TCPView 是用于查看当前 Windows 应用程序和服务连网状态的绝佳工具,通过它我们可以在图形界面中查看到类似使用 netstat 命令输出的大部分信息。

4.2.4 ListDlls

与 Process Explorer 的功能类似,ListDlls 主要用于显示进程载入的 DLL 文件,当然 Process Explorer 更直观易用。

4.2.5 RamMap

RamMap 工具主要用于分析物理内存的使用情况,它以可视化的图形界面进行输出显示。在 RamMap 界面中,你可以查看到非常详细的内存用量,例如:空闲内存、页面缓冲池、非页面缓冲池、已提交和已缓存等条目的详细情况,比任务管理器中的内存显示强大多了。

4.2.6 Handle

Handle 命令行工具的功能其实在 Process Explorer 中也有,使用它可以快速找出进程所打开的资源句柄。

4.2.7 Autologon

Autologon 就是可快速实现 Windows 自动登录的第三种工具。

4.2.8 RegJump

RegJump 命令行工具可以很快在注册表树状条目中进行定位(完全支持简写)

4.2.9 ShellRunAs

ShellRunAs 命令行工具其实是一个 Shell 扩展应用,它可以让我们快速以不同用户身份来执行应用。

4.2.10 AccessEnum

AccessEnum 是在做文件夹权限排错时最常用的一个工具,在我们对某个文件夹进行过复杂的权限配置后,AccessEnum 工具可以非常容易帮助我们理清文件夹或注册表的最终访问控制列表。

4.2.11 Streams:查看和显示隐藏的NTFS流

大多数用户都不了解,Windows 其实会隐藏部分存储在文件系统中的数据,被称为「备用数据流」,只有在文件名末尾追加冒号和独特的密钥才能与之进行交互。

Streams可以帮助大家查看指定文件已有的全部「备用数据流」

4.2.12 SigCheck:分析未经数字签名的文件(如恶意软件)

SigCheck 也是可以帮助我们分析文件是否拥有数字签名的一个命令行工具。它还可以从 VirusTotal 进行检查,以方便我们找出恶意软件。

4.2.13 SDelete:安全删除文件

大家都知道,在 Windows 中删除文件都不是直接清除,而是在硬盘中标记为已删除,SDelete 命令行工具可以帮助我们将硬盘中已经删除文件部分填充无意义数据以达到抹除的目的。

4.2.14 Contig:整理一个或多个文件

如果你想只对 Windows 中的一个或几个文件进行磁盘碎片整理,可以使用 Contig 命令行工具

4.2.15 du:查看磁盘用量

相信大家最常用 Windows 资源管理器来查看磁盘空间和文件夹大小,而 du 是 Sysinternals 套件中的命令行磁盘和文件夹大小查看工具。

4.2.16 Junction:创建符号链接

Windows 与 Linux 一样支持文件和文件夹的符号链接,Sysinternals 工具包中的 Junction 命令也可用于创建和删除符号链接。

4.2.17 DiskView:显示磁盘结构

DiskView 小工具可以让你以图形界面的方式查看详细的磁盘驱动器结构并可以放大和缩小显示区块,甚至可以选择某个文件之后查看其在磁盘中存储的位置。

4.2.18 MoveFiles:重启时移动系统文件

大家有没想过为什么在 Windows Update 之后或安装某些应用程序之后会要求重启系统?因为在 Windows 运行时,有些文件(特别是系统文件)是不能随便被移来移去功随意替换掉的。movefile 命令行小工具可以调用 Windows 自身的功能帮助我们在 Windows 下次重启时移动、删除或重命名文件或目录

4.2.19 FindLinks:查找硬链接文件

前面既然提到了 Junction 创建符号链接,就不得不提一个 findlinks 这个 Sysinternals 是用于查看文件硬链接的命令行工具。如果有多个硬链接指向同一文件,在删除最后一个硬链接时就会将文件直接删除,因此大家可用 findlinks 工具进行查看和关注。

4.2.20 Disk2vhd:物理磁盘转换VHD虚拟磁盘

Disk2vhd 小工具可将正在运行计算机的磁盘克隆成 VHD 虚拟磁盘文件,因此它也成为不少虚拟化项目中的 P2V 转换工具。

0xFF 参考

病毒分析(三)-利用Process Monitor对熊猫烧香病毒进行行为分析

利用Process Monitor软件解决无法加载DLL文件的问题

SysInternals系列:什么是SysInternals工具集

SysInternals系列:使用Sysmon将监控事件写入系统日志

SysInternals系列:其它常用工具介绍

SysInternals系列:使用PsTools工具执行本地/远程PC管理任务

SysInternals系列:分析管理文件、文件夹和驱动器

SysInternals系列:Windows启动项管理利器Autoruns

Process Explorer:Windows进程管理及排错利器(上)

Process Explorer:Windows进程管理利器常用功能(中)

Process Explorer:诊断和排错实例(下)

Process Monitor:Windows事件监控利器简介(上)

Process Monitor:Windows事件监控常用功能(中)

Process Monitor:Windows事件监控实例(下)

Process Monitor(简称Procmon)发布Linux版,附使用方法

https://github.com/microsoft/ProcMon-for-Linux

posted @ 2020-09-17 21:04  罗西的思考  阅读(1182)  评论(1编辑  收藏  举报