[記錄點滴]授人以漁,從Tensorflow找不到dll擴展到如何排查問題
- [記錄點滴]授人以漁,從Tensorflow找不到dll擴展到如何排查問題
- 0x00 摘要
- 0x01 引言
- 0x02 如何找到缺失的dll
- 0x03 Linux下怎么辦?
- 0x04 一個給力的排查神器
- 4.1 SysInternals
- 4.2 功能簡介
- 4.2.1 Process Explorer
- 4.2.2 PsTools
- 4.2.3 TCPView
- 4.2.4 ListDlls
- 4.2.5 RamMap
- 4.2.6 Handle
- 4.2.7 Autologon
- 4.2.8 RegJump
- 4.2.9 ShellRunAs
- 4.2.10 AccessEnum
- 4.2.11 Streams:查看和顯示隱藏的NTFS流
- 4.2.12 SigCheck:分析未經數字簽名的文件(如惡意軟件)
- 4.2.13 SDelete:安全刪除文件
- 4.2.14 Contig:整理一個或多個文件
- 4.2.15 du:查看磁盤用量
- 4.2.16 Junction:創建符號鏈接
- 4.2.17 DiskView:顯示磁盤結構
- 4.2.18 MoveFiles:重啟時移動系統文件
- 4.2.19 FindLinks:查找硬鏈接文件
- 4.2.20 Disk2vhd:物理磁盤轉換VHD虛擬磁盤
- 0xFF 參考
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系列:使用PsTools工具執行本地/遠程PC管理任務
SysInternals系列:Windows啟動項管理利器Autoruns
Process Explorer:Windows進程管理及排錯利器(上)
Process Explorer:Windows進程管理利器常用功能(中)
Process Monitor:Windows事件監控利器簡介(上)
Process Monitor:Windows事件監控常用功能(中)
Process Monitor:Windows事件監控實例(下)