連發程序exe(讓你的RX470 570 秒變 580。教你打磨顯卡二 讓你的礦卡跑分20W)
連發程序exe文章列表:
- 1、讓你的RX470 570 秒變 580。教你打磨顯卡二 讓你的礦卡跑分20W
- 2、今天 你黑屏了嗎?解決全屏切換黑屏問題
- 3、Python Apex Legends 武器自動識別與壓槍
- 4、植物大戰僵尸β版更新日志
- 5、談談Office Moniker類漏洞和公式編輯器類漏洞
讓你的RX470 570 秒變 580。教你打磨顯卡二 讓你的礦卡跑分20W
本文主要補充之前的發文,以及回答條友的疑問。
還是那張200元的574黑狼
首先直接上干貨。刷新教程:
第一步:下載AMDWINFLASH最新2.93版本
地址為:https://www.techpowerup.com/download/ati-atiflash/
第二步:選擇適合你的顯卡BIOS
地址為:https://www.techpowerup.com/vgabios/
第三步:了解刷新命令
直接再命令提示符下運行amdvbflash回車即可得到所有命令以及解釋
常用的命令例子 amdvbflashWin -p -f 0 XXX.rom
其中P為刷新 F為強制 0為顯卡1 如果是顯卡2則用1 XXX.ROM為BIOS。
另外帶WIN的則為WIN下的EXE,不帶的為DOS下的。
了解了如何刷新,那么我們來做一下準備工作:
首先了解一下供電,用自己的顯卡拍了張圖給大家:
雙6PIN=225W
單8PIN=225W
8 6PIN=300W
其次了解一下自己的顯存以及SP
然后根據情況選擇自己的BIOS,并查看是否對應。
需要注意的是,2048SP的580 BIOS目前比較少,而2048的470 570只有刷入2048SP版本呢的BIOS才能變身成功,2304則不行。
來個案例,比如我們想刷入藍寶石的1411頻率的584的BIOS,那么先來看一下參數
可以看到,這個BIOS為藍寶石的是2304SP的584,現存為自動檢測,可以是爾必達也可以是海力士,我們的XFX 574是爾必達,所以可以刷。
那么在再看!不同顯存的錯誤例子:
這個BIOS和上面那個一樣,但!顯存是三星的,則不能刷。
了解了這些之后,我們來對比下幾個BIOS的表現:
首先我們來刷入藍寶石2048SP 584的BIOS:
直接BAT搞起:
刷新成功。
GPU-Z FURMARK 魯大師3連發:(AMD從POWERTUNE之后FURMARK已經不滿載了,學精了)
總結:完美的BIOS調教,風扇1100RPM也很安靜。功耗噪音與性能的綜合首選。
然后我們來刷入XFX 574的原版BIOS(之前有備份):
慣例3連發:
總結:性能版BIOS,溫度高,轉速高,功耗高,原版BIOS的溫度墻為90度,原裝散熱不僅僅直升機而已直接撞墻,即使更換更強大的風扇和7921硅脂也依然無法拯救噪音,吃雞的時候壓力更高,長時間仍然有撞墻的危險。
貼下以前原版BIOS原版散熱的吃雞圖:(平均溫度82 83就是因為反復撞墻,如果一直FURMARK則永遠停留再89)
最后我們倆刷入藍寶石574 1411版功耗實際增加幾乎100W的版本,甚至偶爾極限情況還會因為過流保護直接自動重啟的版本:
老套路三連發:
總結:最高性能版BIOS,默認即可跑分18W,甚至偶爾吃雞的時候會直接超過供電極限而自動重啟,(只有過一次,應該是主板75W供電保護,因為我這里PCI-E不僅僅接了顯卡)。畢竟吃雞的壓力更大,功耗也更高,FURMARK 的時候230W,吃雞用這個BIOS經常過300.
本文測試都是基于PCI-E 3.0 8X的結果。
因為本文只是回應群友和條友的教程,不是極限OC測試,所以默認跑個魯大師就溜了。不沖擊20W 了。
文章到這里就結束了。祝群友和條友能找到適合自己的BIOS。
而我。。。。也要去刷回584 2048SP的變身BIOS了。長夜漫漫。。
漫漫。。
漫漫。。
沒有了拖拉機。。
依然。。
無心睡眠。
今天 你黑屏了嗎?解決全屏切換黑屏問題
很多玩家在登錄過久以后 切屏會出現失敗的情況
還有的玩家 全屏后 不小心彈回桌面就切不回去了 (如下圖)
其實這都是騰訊自己的插件 Cross搞的鬼 由于該插件 隨DNF啟動 當DNF變化時 這插件跟不上變化 因此DNF黑屏無法切換
下面上教程!
首先找到 地下城與勇士startCrossCoreStable 文件夾 CrossProxy.exe文件
四項禁止以后 確定上游戲即可 隨意切換無卡頓 無黑屏
而且不會再出現直播框了
但是wegame換裝和連發可能會失靈
建議還是用WEgame 登錄 連發就用盒子之類的
換裝已經死了 沒啥猴戲了 就不用了
來自掌游寶投稿—藍幻冰峰
Python Apex Legends 武器自動識別與壓槍
文章目錄
環境準備
操縱鍵鼠
驅動安裝 鏈接庫加載 代碼準備和游戲外測試
toolkit.py
游戲內測試
鍵鼠監聽
武器識別
如何簡單且高效判斷是否在游戲內
如何簡單且高效判斷背包狀態 無武器/1號武器/2號武器
如何簡單且高效判斷武器子彈類別
如何簡單且高效判斷武器名稱
如何簡單且高效判斷武器模式 全自動/連發/單發
何時觸發識別
壓槍思路
組織數據
第一階段實現 能自動識別出所有武器
cfg.py
toolkit.py
apex.py
第二階段實現 能自動識別出所有武器并采用對應壓槍參數執行壓槍
第三階段實現 放棄抖槍術 轉常規后座抵消法
本文為下面參考文章的學習與實踐
[原文] FPS游戲自動槍械識別 壓槍(以PUBG為例)
環境準備
Python Windows 開發環境搭建
說明
基礎環境
從 python 官網下載安裝包并安裝, 配置環境變量后, 在命令行內可以執行 python 命令
包管理工具
pip: 一個現代的,通用的 Python 包管理工具。提供了對 Python 包的查找、下載、安裝、卸載的功能。注:pip 已內置于 Python 3.4 和 2.7 及以上版本,其他版本需另行安裝。
虛擬環境
python 基礎環境下, 不同的依賴只能存在一個版本, 而不同的項目可能依賴了同一個包的不同版本, 這樣的項目就可能無法在同一個 python 基礎環境下運行. 基于基礎環境創建的虛擬環境是相互隔離的, 第三方依賴包可根據項目要求自行下載, 不同項目運行在不同的虛擬環境幾下就可以避免以來沖突等問題
虛擬環境只能基于本地存在的基礎環境來創建, 會繼承基礎環境自帶的庫, 可以選擇是否繼承基礎環境的已安裝的第三方包
我覺得可以借鑒學習 java maven 的依賴管理理念, 告別虛擬環境
虛擬環境管理工具
virtualenv: virtualenv可以為每個項目創建一套隔離的Python環境, 再使用pip進行包管理
venv: python 3.3 起自帶的虛擬環境管理工具
pipenv:
virtualenvwrapper:
virtualenvwrapper-win:
virtualenv-burrito:
autoenv:
pyvenv:
pyenv:
CONDA
Conda
Conda
Miniconda
Anaconda
Conda 是一個開源的 環境和包管理系統, 它可以創建并管理完全隔離的不同版本的 python 環境, 也可以創建并管理某 python 版本的完全隔離的虛擬環境, 用了它就不必再安裝基礎環境了
默認配置下, Conda 可以安裝和管理由 Anaconda? 構建、審查和維護的數千個包。版本通常低于最新版
Anaconda: Anaconda是一個打包的集合,里面預裝好了 Conda、Python、眾多數據科學和機器學習相關的包、科學計算工具等等,所以也稱為Python的一種發行版。
Miniconda: Miniconda 是一個免費的 conda 最小安裝程序。 它是 Anaconda 的一個小型引導版本,僅包含 Conda、Python、它們所依賴的包以及少量其他有用的包,包括 pip、zlib 和其他一些包。
Anaconda Navigator: Anaconda 的 GUI 管理工具
基礎環境搭建
Python 官網
Python Windows 下載
到官網找到 Windows 最新版下載并安裝
pip 是 Python 包管理工具,該工具提供了對Python 包的查找、下載、安裝、卸載的功能。
什么是 Python Launcher?
python 安裝程序會自動在 path 環境變量中添加這兩條目錄
目錄結構說明
vc dll 結構體_python的安裝目錄結構
python.exe: python 解釋器, 運行時會彈出控制臺窗口
pythonw.exe: 無窗口的python可執行程序, 代碼在后臺運行
DLLs: 包含 python 的 *.pyd(Python動態模塊)文件與幾個Windows的 *.dll(動態鏈接庫)文件
pyd 文件是由 D 語言編寫的一種 dll 文件, 可以保護 python 文件的源碼不被暴露
Doc: 幫助文檔
include: python 的 C 語言接口頭文件(.h結尾), 當在 C 程序中集成 python 時, 會用到這個目錄下的頭文件
C語言中, 后綴為 .h 的文件是頭文件, 內含函數聲明、宏定義、結構體定義等內容。 后綴為 .c 的文件是源文件, 內含函數實現,變量定義等內容。 為什么要有頭文件? C/C 編譯的時候先掃描整個文件有沒有語法錯誤, 然后將C語句轉化為匯編, 當碰到不認識的變量、類、函數、對象的命名時, 首先查找它有沒有聲明, 如果沒有聲明直接報錯, 如果有,則根據對應的定義空出一定的存儲空間并進行相關的指令轉化。
Lib: python 自帶的標準庫/包/測試套件等
Lib/site-packages: 存放安裝的第三方庫, pip install 安裝的第三方庫就放在這里
libs: python 的 C 語言接口庫文件
Scripts: 腳本文件, 如 pip.exe 包管理器等
TCL: python 與 TCL 的結合
Tools: 一些工具
Miniconda 環境搭建
Miniconda
紅字提示, 不推薦勾選添加環境變量, 因為可能會導致因路徑被添加到靠前的位置而造成問題. 如果是首次安裝 python 相關環境, 可以選擇添加到環境變量選項, 如果已經有在用的其他配置了 PATH 的 Conda 或者 Python 則不建議
確實在用戶環境變量 PATH 里加了很多目錄, 查看這些目錄下都有哪些 exe, 根目錄下有 python.exe
使用方式
安裝完成后, 從開始菜單中找到并打開 [Anaconda Prompt], 運行 [conda list] 命令, 如果正確安裝, 則會出現已安裝的包列表
常用命令
Command reference
conda常用命令:安裝,更新,創建,激活,關閉,查看,卸載,刪除,清理,重命名,換源,問題
Anaconda /Miniconda 常用命令CONDA集合
查看幫助
conda -hconda --helpconda install -hconda install --helpconda env -h12345
查看信息
conda info # 包含 conda, python, pip 等, 還有當前在 conda 命令行中激活的環境1
列出環境
conda env listconda info -e12
新安裝的 Conda 只有 base 基礎環境, 沒有虛擬環境
配置源
windows環境下conda更換為國內清華鏡像源
編輯用戶目錄下的 .condarc 文件即可更換 conda 默認源。
# Windows 用戶無法直接創建名為 .condarc 的文件,需要先執行如下命令,生成該文件后再修改。C:Users用戶名.condarc# 設置搜索時顯示通道地址conda config --set show_channel_urls yes123
修改文件內容
channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/menpo/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/ - defaultsshow_channel_urls: true12345678910
運行 conda clean -i 清除索引緩存,保證用的是鏡像站提供的索引。
運行 conda config --show 確認源信息
虛擬環境
# 創建虛擬環境conda create -hconda create -n testenvconda create -n testenv2 python=3.8conda create -n testenv3 python=3.10.7 # 貌似不能下 Anaconda 庫中沒有的 python 版本, 表現就是轉圈很久conda create -p C:mrathenadevelopworkspacepycharmyolov5-6.2venv# 查看環境包conda list # 查看當前激活環境的包, 默認激活的是 base 基礎環境conda list -n testenv # 查看指定虛擬環境的包# 激活虛擬環境conda activate testenvconda activate C:mrathenadevelopworkspacePyCharmyolov5-6.2venv# 反激活conda deactivate # 退出虛擬環境, 重新激活 base 基礎環境# 刪除虛擬環境conda remove -n testenv --allconda remove -p C:mrathenadevelopworkspacepycharmyolov5-6.2venv --all1234567891011121314151617
如果報錯如下, 檢查是否有開代理工具, 關閉代理, 重開工具就可以了
CondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/win-64/current_repodata.json>1
創建虛擬環境的注意點
創建虛擬環境時, 一定要指定一個不同于 base python 版本的 python 版本
不然的話, 新的虛擬環境基本等同于沒有創建, 使用的仍然是 base 環境, 執行 pip install 會污染 base 環境, 真是惡心
創建了一個不同于 base python 版本的虛擬環境后, 在虛擬環境中會實打實包含類似 base 的目錄結構, 也包含對應的 pip.exe, 這時候再執行 pip install 就不會影響到 base 環境了
IDE pycharm
pycharm的virtualenv、pipenv、conda詳解
下載最新版如 pycharm-professional-2021.2.3.exe
以下選項自選
Create Desktop Shortcut, 64-bit launcher, 創建64位啟動器的桌面快捷方式, 非常建議
Update context menu, Add “Open Folder as Project”, 在上下文菜單(文件夾右鍵)添加"以項目的方式打開該文件夾"選項, 可選
Create Associations, .py, 創建 .py 文件的關聯, 默認使用 PyCharm 打開 .py 文件, 非常建議
Download and install JRE x86 by JetBrains, 下載 JRE? 不確定做什么, 不選
Update PATH variable(restart needed), Add “bin” folder to the PATH, 更新 PATH 環境變量, 將啟動器目錄添加到 PATH, 不選
創建工程時, 建議每個工程都創建新的虛擬環境, 通過 Conda
測試
在 conda 命令行中也能看到 pycharm 中創建的虛擬環境, 但是沒有名字
插件
Chinese (Simplified) Language Pack / 中文語言包
尋找文檔
Pypi
在官網輸入包名, 找到包, 點進去, 里面一般都會有項目說明, GitHub, 文檔等內容
conda create -n apex python=3.91
操縱鍵鼠
由于絕地求生屏蔽了硬件驅動外的其他鼠標輸入,因此我們無法直接通過py腳本來控制游戲內鼠標操作。為了實現游戲內的鼠標下移,我使用了羅技鼠標的驅動(ghub),而py通過調用ghub的鏈接庫文件,將指令操作傳遞給ghub,最終實現使用硬件驅動的鼠標指令輸入給游戲,從而繞過游戲的鼠標輸入限制。值得一提的是,我們只是通過py代碼調用鏈接庫的接口將指令傳遞給羅技驅動的,跟實際使用的是何種鼠標沒有關系,所以即便用戶使用的是雷蛇、卓威、雙飛燕等鼠標,對下面的代碼并無任何影響。
驅動安裝 鏈接庫加載 代碼準備和游戲外測試
羅技驅動使用 LGS_9.02.65_X64(請自行找資源安裝,官網新版羅技驅動沒找到對應的鏈接庫文件),鏈接庫文件在項目鏈接里面可以找到。下面是載入鏈接庫的代碼。
羅技驅動分LGS(老)和GHub(新), 必須裝指定版本的LGS驅動(如已安裝GHub可能需要卸載), 不然要么報未安裝, 要么初始化成功但調用無效
LGS_9.02.65_x64_Logitech.exe, 網盤下載
其他地址1
其他地址2
try: gm = CDLL(r'./ghub_device.dll') gmok = gm.device_open() == 1 if not gmok: print('未安裝ghub或者lgs驅動!!!') else: print('初始化成功!')except FileNotFoundError: print('缺少文件')123456789
裝了該驅動后, 無需重啟電腦, 當下就生效了. 遺憾的是, 沒有對應的文檔, 只能猜測參數了
toolkit.py
import timefrom ctypes import CDLLimport win32api # conda install pywin32try: driver = CDLL(r'mouse.device.lgs.dll') # 在Python的string前面加上‘r’, 是為了告訴編譯器這個string是個raw string(原始字符串),不要轉義backslash(反斜杠) '' ok = driver.device_open() == 1 if not ok: print('初始化失敗, 未安裝lgs/ghub驅動')except FileNotFoundError: print('初始化失敗, 缺少文件')class Mouse: @staticmethod def move(x, y, absolute=False): if ok: mx, my = x, y if absolute: ox, oy = win32api.GetCursorPos() mx = x - ox my = y - oy driver.moveR(mx, my, True) @staticmethod def down(code): if ok: driver.mouse_down(code) @staticmethod def up(code): if ok: driver.mouse_up(code) @staticmethod def click(code): """ :param code: 1:左鍵, 2:中鍵, 3:右鍵, 4:側下鍵, 5:側上鍵, 6:DPI鍵 :return: """ if ok: driver.mouse_down(code) driver.mouse_up(code)class Keyboard: @staticmethod def press(code): if ok: driver.key_down(code) @staticmethod def release(code): if ok: driver.key_up(code) @staticmethod def click(code): """ :param code: 'a'-'z':A鍵-Z鍵, '0'-'9':0-9, 其他的沒猜出來 :return: """ if ok: driver.key_down(code) driver.key_up(code)12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
游戲內測試
在游戲里面試過后, 管用, 但是不準, 猜測可能和游戲內鼠標靈敏度/FOV等有關系
from toolkit import Mouseimport pynput # conda install pynputdef onClick(x, y, button, pressed): if not pressed: if pynput.mouse.Button.x2 == button: Mouse.move(100, 100)mouseListener = pynput.mouse.Listener(on_click=onClick)mouseListener.start()mouseListener.join()123456789101112
鍵鼠監聽
前面說到,要實現壓槍就要對各種配件、狀態做出識別。那么在寫識別的函數之前,我們先要解決的是何時識別的問題。如果識別使用多線程多進程的一直持續檢測,無疑是一種巨大的開銷,因此就需要對鍵盤、鼠標的狀態進行監聽。只有按下特定按鍵時,才觸發特定相應的識別請求。
這里我使用的鉤子是Pynput,其他可使用的庫還有Pyhook3
Pynput 說明
def onClick(x, y, button, pressed): print(f'button {button} {"pressed" if pressed else "released"} at ({x},{y})') if pynput.mouse.Button.left == button: return False # 正常不要返回False, 這樣會結束監聽并停止監聽線程, 在關閉程序前返回False就好了listener = pynput.mouse.Listener(on_click=onClick)listener.start()def onRelease(key): print(f'{key} released') if key == pynput.keyboard.Key.end: return False # 正常不要返回False, 這樣會結束監聽并停止監聽線程, 在關閉程序前返回False就好了listener = pynput.keyboard.Listener(on_release=onRelease)listener.start()1234567891011121314
Listener中綁定on_press和on_release的函數( on_key_press、on_key_release),它們返回False的時候是結束監聽,下文鼠標監聽的函數同理,所以不要隨便返回False
鍵盤的特殊按鍵采用keyboard.Key.tab這種寫法,普通按鍵用keyboard.KeyCode.from_char(‘c’)這種寫法
這里有一點非常坑,on_press和on_release的參數只能有一個key,這個key就是對應鍵盤按下的哪顆按鍵。但這是不足以滿足我們的需求的,因為我們應該在鉤子函數內部,在按下指定按鍵時對信號量做出修改,但因為參數的限制,我們無法把信號量傳進函數內部,這里我也是想了很久,最后才想到用嵌套函數的寫法解決這個問題。
另外,鉤子函數本身是阻塞的。也就是說鉤子函數在執行的過程中,用戶正常的鍵盤/鼠標操作是無法輸入的。所以在鉤子函數里面必須寫成有限的操作(即O(1)時間復雜度的代碼),也就是說像背包內配件及槍械識別,還有下文會講到的鼠標壓槍這類時間開銷比較大或者持續時間長的操作,都不適合寫在鉤子函數里面。這也解釋了為什么在檢測到Tab(打開背包)、鼠標左鍵按下時,為什么只是改變信號量,然后把這些任務丟給別的進程去做的原因。
武器識別
如何簡單且高效判斷是否在游戲內
找幾個特征點取色判斷, 血條左上角和生存物品框左下角
一般能用于取色的點, 它的顏色RGB都是相同的, 這種點的顏色非常穩定
我原本以為屏幕點取色應該不會超過1ms的耗時, 結果萬萬沒想到, 取個色居然要1-10ms, 效率奇低, 暫無其他優雅方法
如何簡單且高效判斷背包狀態 無武器/1號武器/2號武器
看武器邊框上紅色圈住的部分顏色, 灰色說明沒有武器, 上下不同色, 說明使用2號武器, 上下同色說明使用1號武器
如何簡單且高效判斷武器子彈類別
可以和上面的放在一起, 同一個點直接判斷出背包狀態和武器子彈類別
如何簡單且高效判斷武器名稱
在分類后的基礎上, 通過 背包狀態 確定要檢查顏色的位置(1號位/2號位), 通過 武器子彈類別 縮小判斷范圍, 在每個武器的名字上找一個純白色的點, 確保這個點只有這把武器是純白色, 然后逐個對比
如何簡單且高效判斷武器模式 全自動/連發/單發
需要壓槍的只有全自動和半自動兩種模式的武器, 單發不需要壓槍(后面有可能做自動單發, 到時候在考慮), 噴子和狙不需要壓槍
所以需要找一個能區分三種模式的點(不同模式這個點的顏色不同但是穩定), 且這個點不能受和平和三重的特殊標記影響
收起武器, 部分武器可以通過[V]標判斷, 放棄
何時觸發識別
鍵盤 1/2/3/E/V 釋放, 鼠標 右鍵 按下, 這個如果不影響開槍就這個了, 影響的話就改成側下鍵. 鍵位和鍵在游戲內的功能不沖突的
壓槍思路
apex 的壓槍有兩個思路, 因為 apex 不同武器的彈道貌似是固定的, 其他游戲也是??
左右抖動抵消水平后坐力, 下拉抵消垂直后坐力. 這種方法簡單, 但是畫面會抖動, 效果也不是很好
根據武器配件等測試不同情況下的武器后坐力數據, 然后做反向抵消.
可以通過取巧的方式, 只做無配件狀態下的反向抵消, 還省了找配件的麻煩
這種方法太難太麻煩了, 但是做的好的話, 基本一條線, 強的離譜
我先試試 抖槍大法
組織數據
武器數據, 通過子彈類型分組, 組里的每個成員指定序號, 名稱, 壓槍參數等信息
配置數據, 按分辨率分組, 再按是否在游戲中, 是否有武器, 武器位置, 武器子彈類型, 武器索引等信息分類
信號數據, 程序運行時, 進程線程間通訊
第一階段實現 能自動識別出所有武器
目前測試下來, 一波識別大概六七十毫秒的樣子, 最多也不超過一百毫秒, 主要耗時在取色函數(1-10ms), 性能已經夠用了
cfg.py
mode = 'mode'name = 'name'game = 'game'data = 'data'pack = 'pack' # 背包color = 'color'point = 'point'index = 'index'bullet = 'bullet' # 子彈differ = 'differ'positive = 'positive' # 肯定的negative = 'negative' # 否定的# 檢測數據detect = { "3440:1440": { game: [ # 判斷是否在游戲中 { point: (236, 1344), # 點的坐標, 血條左上角 color: 0x00FFFFFF # 點的顏色, 255, 255, 255 }, { point: (2692, 1372), # 生存物品右下角 color: 0x959595 # 149, 149, 149 } ], pack: { # 背包狀態, 有無武器, 選擇的武器 point: (2900, 1372), # 兩把武器時, 1號武器上面邊框分界線的上半部分, y 1 就是1號武器上面邊框分界線的下半部分 color: 0x808080, # 無武器時, 灰色, 128, 128, 128 '0x447bb4': 1, # 輕型彈藥武器, 子彈類型: 1/2/3/4/5/6/None(無武器) '0x839b54': 2, # 重型彈藥武器 '0x3da084': 3, # 能量彈藥武器 '0xce5f6e': 4, # 狙擊彈藥武器 '0xf339b': 5, # 霰彈槍彈藥武器 '0x5302ff': 6, # 空投武器 }, mode: { # 武器模式, 全自動/半自動/單發/其他 point: (3148, 1349), '0xf8f8f8': 1, # 全自動 '0xfefefe': 2 # 半自動 }, name: { # 武器名稱判斷 color: 0x00FFFFFF, '1': { # 1號武器 '1': [ # 輕型彈藥武器 (2959, 1386), # 1: RE-45 自動手槍 (2970, 1385), # 2: 轉換者沖鋒槍 (2972, 1386), # 3: R-301 卡賓槍 (2976, 1386), # 4: R-99 沖鋒槍 (2980, 1386), # 5: P2020 手槍 (2980, 1384), # 6: 噴火輕機槍 (2987, 1387), # 7: G7 偵查槍 (3015, 1386), # 8: CAR (輕型彈藥) ], '2': [ # 重型彈藥武器 (2957, 1385), # 1: 赫姆洛克突擊步槍 (2982, 1385), # 2: 獵獸沖鋒槍 (2990, 1393), # 3: 平行步槍 (3004, 1386), # 4: 30-30 (3015, 1386), # 5: CAR (重型彈藥) ], '3': [ # 能量彈藥武器 (2955, 1386), # 1: L-STAR能量機槍 (2970, 1384), # 2: 三重式狙擊槍 (2981, 1385), # 3: 電能沖鋒槍 (2986, 1384), # 4: 專注輕機槍 (2980, 1384), # 5: 哈沃克步槍 ], '4': [ # 狙擊彈藥武器 (2969, 1395), # 1: 哨兵狙擊步槍 (2999, 1382), # 2: 充能步槍 (2992, 1385), # 3: 輔助手槍 (3016, 1383), # 4: 長弓 ], '5': [ # 霰彈槍彈藥武器 (2957, 1384), # 1: 和平捍衛者霰彈槍 (2995, 1382), # 2: 莫桑比克 (3005, 1386), # 3: EVA-8 ], '6': [ # 空投武器 (2958, 1384), # 1: 克雷貝爾狙擊槍 (2983, 1384), # 2: 敖犬霰彈槍 (3003, 1383), # 3: 波塞克 (3014, 1383), # 4: 暴走 ] }, '2': { differ: 195 } } }, "2560:1440": { }, "2560:1080": { }, "1920:1080": { }}# 武器數據weapon = { '1': { # 輕型彈藥武器 '1': { name: 'RE-45 自動手槍', }, '2': { name: '轉換者沖鋒槍', }, '3': { name: 'R-301 卡賓槍', }, '4': { name: 'R-99 沖鋒槍', }, '5': { name: 'P2020 手槍', }, '6': { name: '噴火輕機槍', }, '7': { name: 'G7 偵查槍', }, '8': { name: 'CAR (輕型彈藥)', } }, '2': { # 重型彈藥武器 '1': { name: '赫姆洛克突擊步槍', }, '2': { name: '獵獸沖鋒槍', }, '3': { name: '平行步槍', }, '4': { name: '30-30', }, '5': { name: 'CAR (重型彈藥)', } }, '3': { # 能量彈藥武器 '1': { name: 'L-STAR能量機槍', }, '2': { name: '三重式狙擊槍', }, '3': { name: '電能沖鋒槍', }, '4': { name: '專注輕機槍', }, '5': { name: '哈沃克步槍', }, }, '4': { # 狙擊彈藥武器 '1': { name: '哨兵狙擊步槍', }, '2': { name: '充能步槍', }, '3': { name: '輔助手槍', }, '4': { name: '長弓', }, }, '5': { # 霰彈彈藥武器 '1': { name: '和平捍衛者霰彈槍', }, '2': { name: '莫桑比克', }, '3': { name: 'EVA-8', }, }, '6': { # 空投武器 '1': { name: '克雷貝爾狙擊槍', }, '2': { name: '敖犬霰彈槍', }, '3': { name: '波塞克', }, '4': { name: '暴走', }, }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
toolkit.py
import mss # pip install mssimport ctypesfrom ctypes import CDLLimport cfgfrom cfg import detect, weapon# 全局 dlluser32 = ctypes.windll.user32gdi32 = ctypes.windll.gdi32hdc = user32.GetDC(None)try: driver = CDLL(r'mouse.device.lgs.dll') # 在Python的string前面加上‘r’, 是為了告訴編譯器這個string是個raw string(原始字符串),不要轉義backslash(反斜杠) '' ok = driver.device_open() == 1 if not ok: print('初始化失敗, 未安裝lgs/ghub驅動')except FileNotFoundError: print('初始化失敗, 缺少文件')class Mouse: @staticmethod def point(): return user32.GetCursorPos() @staticmethod def move(x, y, absolute=False): if ok: mx, my = x, y if absolute: ox, oy = user32.GetCursorPos() mx = x - ox my = y - oy driver.moveR(mx, my, True) @staticmethod def moveHumanoid(x, y, absolute=False): """ 仿真移動(還沒做好) """ if ok: ox, oy = user32.GetCursorPos() # 原鼠標位置 mx, my = x, y # 相對移動距離 if absolute: mx = x - ox my = y - oy tx, ty = ox mx, oy my print(f'({ox},{oy}), ({tx},{ty}), x:{mx},y:{my}') # 以絕對位置方式移動(防止相對位置丟失精度) adx, ady = abs(mx), abs(my) if adx <= ady: # 水平方向移動的距離短 for i in range(1, adx): ix = i if mx > 0 else -i temp = int(ady / adx * abs(ix)) iy = temp if my > 0 else -temp Mouse.move(ox ix, oy iy, absolute=True) # time.sleep(0.001) else: # 垂直方向移動的距離短 for i in range(1, ady): iy = i if my > 0 else -i temp = int(adx / ady * abs(iy)) ix = temp if mx > 0 else -temp Mouse.move(ox ix, oy iy, absolute=True) # time.sleep(0.001) @staticmethod def down(code): if ok: driver.mouse_down(code) @staticmethod def up(code): if ok: driver.mouse_up(code) @staticmethod def click(code): """ :param code: 1:左鍵, 2:中鍵, 3:右鍵, 4:側下鍵, 5:側上鍵, 6:DPI鍵 :return: """ if ok: driver.mouse_down(code) driver.mouse_up(code)class Keyboard: @staticmethod def press(code): if ok: driver.key_down(code) @staticmethod def release(code): if ok: driver.key_up(code) @staticmethod def click(code): """ 鍵盤按鍵函數中,傳入的參數采用的是鍵盤按鍵對應的鍵碼 :param code: 'a'-'z':A鍵-Z鍵, '0'-'9':0-9, 其他的沒猜出來 :return: """ if ok: driver.key_down(code) driver.key_up(code)class Monitor: """ 顯示器 """ sct = mss.mss() @staticmethod def grab(region): """ region: tuple, (left, top, width, height) pip install mss """ left, top, width, height = region return Monitor.sct.grab(monitor={'left': left, 'top': top, 'width': width, 'height': height}) @staticmethod def pixel(x, y): """ 效率很低且不穩定, 單點檢測都要耗時1-10ms 獲取顏色, COLORREF 格式, 0x00FFFFFF 結果是int, 可以通過 print(hex(color)) 查看十六進制值 可以通過 print(color == 0x00FFFFFF) 進行顏色判斷 """ # hdc = user32.GetDC(None) return gdi32.GetPixel(hdc, x, y) class Resolution: """ 分辨率 """ @staticmethod def display(): """ 顯示分辨率 """ w = user32.GetSystemMetrics(0) h = user32.GetSystemMetrics(1) return w, h @staticmethod def virtual(): """ 多屏幕組合的虛擬顯示器分辨率 """ w = user32.GetSystemMetrics(78) h = user32.GetSystemMetrics(79) return w, h @staticmethod def physical(): """ 物理分辨率 """ # hdc = user32.GetDC(None) w = gdi32.GetDeviceCaps(hdc, 118) h = gdi32.GetDeviceCaps(hdc, 117) return w, hclass Game: """ 游戲工具 """ @staticmethod def game(): """ 是否在游戲內 太耗時了, 所以不能調的多了 """ w, h = Monitor.Resolution.display() data = detect.get(f'{w}:{h}').get(cfg.game) for item in data: x, y = item.get(cfg.point) if Monitor.pixel(x, y) != item.get(cfg.color): return False return True @staticmethod def index(): """ 武器索引和子彈類型索引 :return: 武器位索引, 1:1號位, 2:2號位, None:無武器, 拳頭(這個暫時無法判斷) 子彈類型索引, 1:輕型, 2:重型, 3:能量, 4:狙擊, 5:霰彈, 6:空投, None:無武器 """ w, h = Monitor.Resolution.display() data = detect.get(f'{w}:{h}').get(cfg.pack) x, y = data.get(cfg.point) color = Monitor.pixel(x, y) if data.get(cfg.color) == color: return None, None else: bullet = data.get(hex(color)) return (1, bullet) if color == Monitor.pixel(x, y 1) else (2, bullet) @staticmethod def weapon(index, bullet): """ 通過武器位和子彈類型識別武器, 參考:config.detect.name :param index: 武器位, 1:1號位, 2:2號位 :param bullet: 子彈類型, 1:輕型, 2:重型, 3:能量, 4:狙擊, 5:霰彈, 6:空投 :return: """ w, h = Monitor.Resolution.display() data = detect.get(f'{w}:{h}').get(cfg.name) color = data.get(cfg.color) if index == 1: lst = data.get(str(index)).get(str(bullet)) for i in range(len(lst)): x, y = lst[i] if color == Monitor.pixel(x, y): return i 1 elif index == 2: differ = data.get(str(index)).get(cfg.differ) lst = data.get(str(1)).get(str(bullet)) for i in range(len(lst)): x, y = lst[i] if color == Monitor.pixel(x differ, y): return i 1 return None @staticmethod def mode(): """ 武器模式 :return: 1:全自動, 2:半自動, None:其他 """ w, h = Monitor.Resolution.display() data = detect.get(f'{w}:{h}').get(cfg.mode) x, y = data.get(cfg.point) color = Monitor.pixel(x, y) return data.get(hex(color)) @staticmethod def detect(): """ 決策是否需要壓槍, 向信號量寫數據 """ if Game.game() is False: print('not in game') return index, bullet = Game.index() if (index is None) | (bullet is None): print('no weapon') return if Game.mode() is None: print('not in full auto or semi auto mode') return arms = Game.weapon(index, bullet) if arms is None: print('detect weapon failure') return # 檢測通過, 需要壓槍 print(weapon.get(str(bullet)).get(str(arms)).get(cfg.name)) return weapon.get(str(bullet)).get(str(arms)).get(cfg.name)123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
apex.py
import timeimport pynput # conda install pynputimport toolkitExitFlag = Falsedef down(x, y, button, pressed): global ExitFlag if ExitFlag: print(ExitFlag) return False # 結束監聽線程 if pressed: # 按下 if pynput.mouse.Button.right == button: toolkit.Game.detect()mouseListener = pynput.mouse.Listener(on_click=down)mouseListener.start()def release(key): if key == pynput.keyboard.Key.end: print('end') global ExitFlag ExitFlag = True return False if key == pynput.keyboard.KeyCode.from_char('1'): toolkit.Game.detect() elif key == pynput.keyboard.KeyCode.from_char('2'): toolkit.Game.detect() elif key == pynput.keyboard.KeyCode.from_char('3'): toolkit.Game.detect() elif key == pynput.keyboard.KeyCode.from_char('e'): toolkit.Game.detect() elif key == pynput.keyboard.KeyCode.from_char('v'): toolkit.Game.detect()keyboardListener = pynput.keyboard.Listener(on_release=release)keyboardListener.start()keyboardListener.join()123456789101112131415161718192021222324252627282930313233343536373839404142434445
第二階段實現 能自動識別出所有武器并采用對應壓槍參數執行壓槍
第三階段實現 放棄抖槍術 轉常規后座抵消法
1
植物大戰僵尸β版更新日志
更新日志
β6.20.3 (2021-05-12)
(需要補充)
β6.20.2 (2021-05-08)
(需要補充)
β6.20.1 (2021-05-03)
(需要補充)
β6.20 (2021-05-03)
(需要補充)
β6.15-1 (2020-10-01)
更新內容:染色
β6.15 (2020-10-01)
更新內容:
添加9個隱藏關卡 添加隱藏關卡:卡槽危機添加隱藏關卡:風雪大戰(關閉3d加速可以不看雪)添加隱藏關卡:嚇與天2添加隱藏關卡:園藝大師添加隱藏關卡:周二圍三添加隱藏關卡:求生2添加隱藏關卡:無盡辣火添加隱藏關卡:僵群[煩人的小僵]添加隱藏關卡:卡片保齡球
優化了隱藏關卡進入方式
添加了部分提示彈窗
修復了若干個bug
β6.10-1 (2020-07-08)
更新內容:修復礦工bug
β6.10 (2020-07-06)
更新內容:
添加了7個隱藏關卡
修改寶石迷陣ex豌豆不飛了(避免崩潰)
修改需要wsad的關卡暫停時無法輸入wsad而可以輸入其他指令
修改求生hardQQ時精英蹦極存在10s后消失
添加指令break來取消窗口標題的持續修改(給一些用腳本的人用的)
為第5頁部分關卡添加提醒
優化選卡中蹦極的位置(以后點禮物盒不會再被這玩意擋了)
ex模式進迷你關卡會有提示
現在可以查看冷卻中的植物還要多久才完成冷卻
打開同文件目錄下的 betainstall.ini,將 KO=0 的值改為 1 即可不彈出啟動窗口,直接進入游戲
β6.05-1 (2020-05-31)
更新內容:調整巨人之怒平衡性
β6.05 (2020-05-31)
更新內容:
關卡類:
添加隱藏關“森然巨化,WSAD,上帝正在看你打僵尸,魔術時間,寶石迷陣:現世,手操保齡球,嚇與天,視覺失調3,手操保齡球 2,真實之霧,巨人之怒”
調整辣個窩瓜不出精英撐桿
修改砸罐關卡不出現幽靈小丑
EXmode僵尸無盡調整
增強盒子僵尸的復仇(消失次數由15?>8)
修改套僵尸中推車路障和精英鐵桶無效果
修改黃油爆米花中持槍僵尸無效果
植物/僵尸類:
修改僵尸無視ex三葉草
增強雪人頭保齡球(僵尸傷害判定增加,不能被僵尸啃食)
修改魔術豆不出模仿者
植物僵尸卡牌顯示
游戲體驗改善:
ex模式的存檔分隔開,避免存檔混亂導致奇奇怪怪的bug
添加一部分視覺上的效果
播放自定義bgm,方法:在關卡游戲中輸入song,然后仔細看彈出的注意事項
關卡內輸入turn開啟陣型保存和讀取(具體看輸入后的注意事項)
實裝難度顯示(僅隱藏關卡,不同難度的關卡關卡名字就不一樣顏色)
現在僵尸可魅惑 只有開sun才可以勾選了
移除萌新彈窗
優化開頭進入β版的選擇界面
bug 修復:
修復ex機槍往旁邊兩路發射的子彈無法擊中僵尸的bug
修復ex模式打開寶石迷陣旋風會崩潰的bug
優化某個全屏的問題
修復7-10可能崩潰的bug
修復水池不動的bug
修復ex豌豆和雪人頭保齡球可能崩潰的bug
β6.00 (2020-05-03)
更新內容:
關卡類:
添加5個隱藏關卡(禁止失車,不滅之星,視覺失調 2,光標危機,盒子僵尸的復仇)
關卡自定義中添加自定義關卡名的途徑:切換特性模式,右鍵陽光菇顯示文本輸入框,輸入完后左鍵陽光菇進行確認
關卡自定義特性模式中鍵陽光菇可以全部清空已經做過的修改
關卡自定義禮物盒不消失
削弱雷厲風行(冰車→鐵桶)
修改7-x蹦極為堅果頭
修改無盡礦工不聰明
修改選卡界面打開禮物盒時隱藏無用卡片按鈕
植物類:
削弱模仿膽小菇(0.75s→0.9s)
削弱寒冰射手(10連發后的連射改成15連發后連射)
優化玉米加農炮的發射
bug 修復:
修復關卡自定義點擊菜單到選關界面會崩潰的bug
修復地刺 地刺王 仙人掌擊退僵王錯位bug
修復黃油/冰凍僵尸后僵尸會鬼畜的bug
修復大炮天會崩潰的bug
其他:
替換鼠標以及圖標
添加了大量彩蛋,當然現在無法觸發,要到比較特別的時候才會觸發
添加hide指令:開啟/取消右鍵顯示僵尸血量標簽
修復大炮天會崩潰的bug
添加冒險模式跳關的途徑:通關冒險模式2次以上時,對主菜單冒險模式進行右鍵操作,并注意彈出窗口說明的相關事項,就可以進行冒險模式跳關了
現在右擊全屏按鈕可以控制窗口的大小,并針對全屏不會瘋狂閃(需要先alt tab切出) (注意:非800*600情況下,1234567890選卡將不可用或者錯位)
修改cheat模式下可以隨意放置植物
EX mode:
ex模式打開方式:在幫助或紙條界面右鍵下方按鈕即可開啟(或者把exconfig.txt的第一個值改成1),ex植物特性若要開啟請自行將植物對應的0改成1,若要關閉將對應的1改成0
ex模式僵尸精英機制:僵尸將有概率生成特殊的僵尸,特殊的僵尸將擁有特殊的能力
添加HardQQ指令,該指令只能在ex mode使用 作用:使幾乎所有的僵尸變成精英(除了一些特殊僵尸有特殊判定以外)
β5.85 (2020-04-10)
更新內容:
選卡界面添加選擇隱藏卡片的按鈕(條件:購買所有紫卡 模仿者)
修復打贏過一些隱藏關莫名其妙獲得紫卡,花園物品,智慧樹突然變高等的bug
優化選卡界面的禮物盒按鈕(并添加右鍵清空選卡)
優化選關界面(你可以在正常的選關界面玩到松鼠了),并添加隱藏關卡選擇界面,方法:鼠標右鍵長按“第3頁”這個按鈕
現在,右鍵按住僵尸可以看僵尸血量(當然在7-5就不要這樣子做了)
點擊獎杯可以考慮是否開啟7-x(無論金銀)
添加5個隱藏關卡
修復了隨機砸罐最后抽到禮盒無法過關的bug
火炬樹被啃食會被扣血,但是會解除僵尸的冰凍狀態(反彈樹同理,不過反彈樹被啃食扣血會更多)
增加新植物,雙生櫻桃,在額外卡槽選擇后可以使用(迷你櫻桃禁止被攜帶因此價格昂貴,且冷卻巨高)
添加了一些有趣的東西
修改開頭萌新彈窗出現方式
一些植物的調整(冰豆不能凍結僵王,紅色和紫色火球濺射傷害調成原來的)
從該版本開始,存檔的機制會發生變化(僅影響游戲存檔,不影響用戶存檔)做此更改是避免β版的存檔會影響到原版
從此版本開始,游戲將可以多開
大鍵盤 1234567890 變成卡槽選擇,1左邊的點換成鏟子(必須英文輸入法)
自定義關卡添加存檔讀檔功能,在關卡自定義這關對右下角的圖鑒/商店按鈕進行右鍵操作來存檔和讀檔,文件和exe在同一目錄,名字為 beta.pvzdiy
注意事項:
選擇非隱藏卡的植物后按鈕會消失,且選擇的隱藏卡片在當前選卡界面不能收回(這是特性)
因為火炬樹樁的火焰極其不穩定,因此,僵尸吃火炬死亡被冰凍乃特性
β版存檔位于 C:ProgramDataPopCap GamesPlantsVsZombiesbetasavesavex_x
β5.80 (2020-03-20)
更新內容:
三葉草現在可以驅逐僵尸豌豆
現在僵尸豌豆如果用豌豆擊殺堅果會直接引爆堅果(包括兩個隱藏堅果,不包括高堅果)
雙發機槍改成10%概率紫火豌豆(80傷害),10%概率火豌豆(40傷害)
寒冰射手連射時往上下兩行發射凍結(1.5s)冰豆(改成每隔10發子彈連射3次,但只往上下發射1次)
修改普通火焰子彈(傷害40)穿過火炬樹樁變成紅色火焰子彈(傷害60)
現在,當豌豆僵尸(包括機槍),被減速時,攻擊間隔增加(150→300)
1437攻擊間隔200→180
添加隱藏植物,冰凍巧克力,輸入冰激凌的同僚食物進入
削弱豌豆僵尸的子彈速度(3→2)
優化自動收集(不撿卡片等)
重做堅果保齡球,并且添加一旗(保齡球2也是)
削弱拉霸
開局出怪密度從2恢復為4個
圖鑒會變得更有趣
加了點彩蛋
自定義關卡特性更新(事先選玉米加農炮切換選擇模式):土豆雷:左鍵:僵尸無視植物,中鍵:The World,右鍵:大蒜天模式寒冰射手:左鍵:黃油爆米花,中鍵:擊彈模式,右鍵:LS模式(誰笑到最后)大嘴花:左鍵:波數 1,中鍵:波數改成100,右鍵:波數-1雙發射手:左鍵:僵尸速度 1倍,中鍵:還原僵尸速度 ,右鍵:僵尸速度-1倍小噴菇:左鍵:出怪密度 1倍,中鍵:還原出怪密度 ,右鍵:出怪密度-1倍
隱藏關卡:凍次打次提示:僵尸快跑的僵尸很“ ** ”(6個字母),在這關輸入指令進入隱藏關凍次打次
隱藏關卡:快樂的小**,提示:植物僵尸2,名字(與PVZ一棵植物有關)
隱藏關卡:瓜分天下,在跳跳舞會輸入。提示:倭瓜很*(英文5個字母)
隱藏關卡:辣個窩瓜,在植物僵尸輸入會使人產生痛覺的植物的英文進入
修復 bug
β5.75 (2020-03-08)
更新內容:
添加雪人的頭(保齡球),同堅果保齡球
修復保齡球場景bug: 可在六路地圖中正常運轉,種在屋頂有奇效 指令提示:某個僵尸的英文(條件:關卡游玩中卡槽內存在無用紫卡)
添加唱片機介紹:美妙的音樂可以吸引周圍的僵尸,并讓一些僵尸脫下自己的防具/或者忘記自己所做的事情指令提示:唱,跳,RAP,籃球,——(條件:關卡游玩中卡槽內存在無用紫卡)
添加植物窩窩瓜:陽光125,冷卻30s,種下后立即消失,并使周圍十字植物變窩瓜指令提示:窩瓜經常被?(6個字母)
添加植物魔術豆(某咕咕黑的創意):陽光0,冷卻50s,可以種在很多植物上,并使這些植物立即消失變成卡片,指令提示:這個植物真“神奇”
冰葉草對蹦極的buff從無限冰凍改成直接秒殺
三葉草傷害降低(60→40→50),但對氣球僵尸提高(60→100),冷卻略微提升(7.5s→10s),不過在小僵尸不麻煩有特判(60傷害,能一下吹死小僵尸)
膽小菇冷卻不變(15s→20s→15s),模仿者膽小菇攻擊間隔縮短(1.5s→0.9s→0.75s),但無法白嫖陽光
1437攻擊間隔略微提高(1.5s→2s)
蘿卜傘反彈豌豆和機槍僵尸子彈(但不能攻擊僵尸),但若套上南瓜頭,或者離上述僵尸太近,則不能觸發此效果,冷卻提高(7.5s→15s)
路燈花冷卻提高(30s→50s),但能使場上的撐桿僵尸棄桿(不過會使撐桿攻擊判定增大),并移除僵尸頭上的路障
冰焰豌豆減速時間翻倍(1s→2s)
大噴噴射特效修改(把方塊改為一行噴霧)
西瓜冰瓜消耗陽光修改(西瓜300→225,冰瓜200→175)
修改仙人掌,有概率(=本行僵尸數 * 40/1000(總概率為1))暴擊(子彈傷害(20) * 2=40) 擊退僵尸(對于氣球擊退3格)
僵尸菇調整:變成一次性植物,種植后消失并生產3張魅惑僵尸卡
大蒜中毒僵尸變綠
地刺和地刺王可以種在屋頂右4列(克制冰車);屋頂,月夜選卡不黑
全是一個波數降低(60→50)
植物僵尸1修改:豌豆帶破爛鐵門,小丑不會炸傷植物,被魅惑爆炸改為凍結僵尸等,修改了此關卡很多僵尸的特性,現在植物僵尸變成了全新的關卡(注意:跳跳僵尸未進行修改)
降低了開局僵尸的出怪密度(÷2)
自定義關卡模式:基本方式:進入upsell關卡,點擊模仿者,開啟關卡自定義模式選擇對應植物卡片,修改出怪,波數,場景出怪:豌豆~卷心菜投手按順序設置波數:香蒲~地刺王按順序設置(1旗,2旗,3旗,4旗)場景:玉米投手~憂郁蘑菇按順序設置花盆:清空出怪玉米加農炮:切換選擇模式(未來可以添加新的關卡特性,但現在暫時沒加)中途退出關卡存檔過后可以進入關卡選擇界面的“禪境花園”再次進入自定義關卡存檔傳送帶模式:在關卡自定義模式點擊模仿者,切換傳送帶選擇模式選擇選卡界面的植物,點擊右下角的圖鑒和商店調整卡片權重(顯示在陽光那里)調整完后點擊模仿者,切換為原來的關卡自定義模式若想清空傳送帶殘留存檔,在關卡自定義模式選玉米加農炮后選擇豌豆射手進行清空特性自定義:(注:以下內容均要先點擊玉米加農炮切換選擇模式)初始陽光自定義:點擊向日葵,鼠標中鍵清空或者還原初始陽光,左鍵初始陽光 25,右鍵初始陽光-25(初始陽光范圍0~9990)調用冰凍關卡名稱(方便修改文本):鼠標左鍵點擊櫻桃炸彈極限出怪模式:鼠標右鍵點擊櫻桃炸彈狂捶模式:鼠標中鍵點擊櫻桃炸彈(目前有bug,不能過關,輸入win就行)雷厲風行模式:鼠標左鍵點擊堅果墻小僵尸模式:鼠標右鍵點擊堅果墻柱子模式:鼠標中鍵點擊堅果墻
魅惑巨人捶擊傷害提高5倍(50→100→500)
sun value開啟字幕 開sun陽光顏色修改
防止多帶同一張隱藏卡片
hardH:大睡天(生產植物等特殊植物不睡)
β5.70 (2020-02-24)
更新內容:
修復7-x僵尸飾品不顯示的bug
調整關卡瓜瓜樂(生產植物生產間隔提高)
修復路燈花在睡覺時超模的bug
修LS無盡bug
玉米加農炮炸梯范圍減小到櫻桃
冒險6-10和7-10bgm改成僵王BGM
輸入隱藏植物指令時取消該植物冷卻(減少等待時間)
求生開頭戴夫說話
修復了魅惑僵尸造成的bug
修復了無用紫卡植物有時候不能變成隱藏植物的bug
西瓜和冰西瓜可以打氣球僵尸了
墓碑吞噬者和咖啡豆可以戰術型配合使用了
添加新植物(目前開啟新植物均為同火炬豌豆的方式):僵尸菇 種下之后具有神奇的功能,即每一個僵尸卡片都有魅惑的效果。 指令提示:陽光菇pak中某一圖片名字中的6個字母
添加新植物:小盆菇 ≈小噴菇,但是能直接種在**(指令提示)上,自然消失后必定掉小陽光
吸金磁吸的錢翻倍,陽光略微增加
添加新植物:冰葉草 ≈颶風甘藍,但是有一些(其實是很多)變動 指令提示:三葉草某部位的英文
添加新植物:反彈樹樁 =櫻桃反彈布丁 指令提示:反彈樹樁的作用?
加強了裂莢射手(相當于1轉水管)
隱藏關卡:雷厲風行 提示:在僵尸快跑輸入某個動物的英文(4個字母)即可進入
添加指令stop:暫停出怪
β5.65 (2020-02-12)
更新內容:
增強磁力菇:每當磁鐵吸夠5次鐵具后,會對全屏范圍內進行5秒的鐵具消除,注意在進行鐵具消除的時候的鐵具也會被算入吸鐵次數。當技能期間再吸滿8次將會重置鐵具消除的時間(5s) 磁力菇的陽光價格將改為125
實裝手套指令,并修復了關于手套的諸多bug,提示:5個字母,無多余提示
替換大噴的噴射特效(適配將來的pak)
更改辣椒的顯示特效
實裝hardG指令:迷霧模式(可以通過指令ctrlfog來調節濃霧大小)
路燈花功能修改:種下去讓僵尸眩暈(停留)3s
實裝顯示/隱藏卡槽指令,提示:6個字母,無多余提示
幼苗現在對大噴,1437也有效了,且修復憂郁菇bug
增強寒冰菇:現在寒冰菇凍住小丑和辣椒會使其在寒冰菇賦予的冰凍時間里不會爆炸,除非是小丑的特殊爆炸
添加隱藏關卡:有果有因 進入方法,在花園輸入另一個和死有關的東西
添加隱藏關卡:樂 指令提示:在植物僵尸2輸入pvz中最慘植物的英文即可進入關卡樂
小黃的騷話更多了
β5.60 (2020-02-04)
溫馨提示:從這個版本開始,為了修復一些莫名其妙的崩潰問題及加入開頭彈窗,一些殺毒軟件可能會報毒(但其實無毒,而且那些崩潰問題也有效解決了) 更新內容:
實裝隨機砸罐彩蛋:進入方法提示—— 15P 10Z=?小丑√ 堅果×t[I]me [T]ime [T]ime
優化部分關卡文本(指的陽光無限制,cheat模式下也會顯示)
小黃(主菜單左下角的文字,可以告訴你一些奇怪的東西)裝上了
(7-10BOSS)彩蛋關實裝(進入方法就是打敗boss的同時且XXXX)
增強巨人(7-10BOSS)的分身
開啟陽光鏟(指令類似僵尸掉陽光,5個字母)
實裝ip(我是植物)模式,關卡進入提示: 植物max隨機砸罐無聊
Ls添加無盡選項(誰笑到最后)
冒險模式削弱了豌豆僵尸的出怪比重(1→2),就是現在豌豆的出怪比重和路障的一樣。(也就是6-6之類的存在豌豆僵尸的冒險關卡變簡單了)
按1呼出鏟子有聲音了
β5.55 (2020-01-22)
更新了兩個隱藏植物的特性,加強隱藏植物的兩個堅果,橄欖球啃咬了也會爆炸
修復隱藏關卡某文本
card 現在更加美觀了
關卡 7-6 7-7 的災難目前可以正常發生,發生在第 29 輪,大幅度削弱 7-6 7-7
添加了萌新提醒
按 1 呼出鏟子(非小鍵盤)
移除7-10的紅
關卡 7-8 7-9 災禍實裝
關卡 7-10 的 boss 目前已經實裝了
7-x開啟隱藏植物
地刺擊退恢復特效 修改地刺擊退代碼
現在,如果僵尸出現在不對的地方會直接死亡
修復傳送帶 bug
加強部分弱勢植物(數值調整) 機槍射速 150→100豌豆射手、雙發射手、裂莢射手射速 150→125
7-8,7-9災禍效果: 滿溢之災禍,陽光迅速不斷增加,但是陽光過多時刷怪極大加快
修復bug
(施工中)
談談Office Moniker類漏洞和公式編輯器類漏洞
在近幾年出現的諸多office漏洞中,有兩類漏洞是很值得談談的,第一類是Moniker導致的邏輯漏洞,第二類是公式編輯器漏洞。
對于第一類漏洞,其重點在于攻擊者和微軟安全團隊之間的攻防過程,了解這類漏洞攻防過程對威脅追蹤與研究較有益處:
第一回合:CVE-2017-0199,用URL Moniker加載遠程HTA文件實現遠程代碼執行;
第二回合:CVE-2017-8570,用compositeMoniker、FileMoniker、NewMoniker、scriptletfile實現遠程代碼執行;
第三回合:CVE-2017-8759,用office文檔加載.Net組件漏洞,實現遠程代碼執行;
第四回合:CVE-2018-8174,用office文檔加載IE VBScript組件漏洞,實現遠程代碼執行;
第五回合:CVE-2020-0674,用office文檔加載IE JavaScript組件漏洞,實現遠程代碼執行。
對于第二類漏洞,其難點在于對相似漏洞之間的區分。從CVE-2017-11882開始,到CVE-2018-0802,再到CVE-2018-0798,三個都是非常相似的漏洞,在靜態層面不容易區分,本文將分享一個在動態層面區分它們的方法。
下面跟隨筆者一起來看一下這兩類漏洞。
Moniker類漏洞
第一回合:CVE-2017-0199
2017年4月7日,著名office漏洞研究員李海飛發布了一篇在野0day攻擊預警,首度披露了CVE-2017-0199漏洞的在野攻擊。隨后,2017年4月11日和12日,FireEye連發兩篇文章,披露了他們捕獲到的CVE-2017-0199漏洞樣本細節。后續的披露表明這幾篇文章中披露的漏洞是一種借助URL Moniker特性加載遠程hta文件的新型漏洞,這是一個由于開發者對office文件加載機制設計不合理導致的邏輯漏洞,且要求觸發環境安裝IE10/IE11。漏洞觸發過程不需要用戶交互,但在觸發的過程中會彈出一個對話框,不點擊或者點擊任意該對話框的按鈕都不影響執行過程,對話框樣式如下:
該漏洞的發現者之一李海飛曾經在Syscan360 2017會議上做過題為《Moniker Magic: Running Scripts Directly in Microsoft Office》的演講,里面詳細介紹了CVE-2017-0199的細節,包括:
微軟在CVE-2017-0199的補丁中修復了兩個漏洞,分別是被在野利用的RTF URL Moniker加載遠程HTA文件的遠程代碼執行漏洞,和李海飛獨立發現的PPSX Script Moniker遠程代碼執行漏洞;
office安全團隊在這兩個漏洞的基礎上設計了一類針對Moniker的黑名單機制,禁用了一些他們覺得不安全的Moniker。
Moniker本身是office的一個特性,可以用來鏈接一些本地或遠程對象,其本身不屬于漏洞,漏洞發生在office軟件對遠程鏈接的文件的執行策略上。譬如,如果遠程加載的是一個Excel文件,直接打開沒問題;但如果加載的是HTA文件和Script這類腳本文件時,直接執行就存在問題了,導致了漏洞。
第二回合:CVE-2017-8570
在對CVE-2017-0199補丁的研究過程中,李海飛發現(上面也已經提到):
office安全團隊在這CVE-2017-0199的補丁中設計了一類針對Moniker的黑名單機制,禁用了一些他們覺得不安全的Moniker。
于是他開始尋找那些還沒有被禁用的Moniker,嘗試用那些沒有被禁用的Moniker構造出另一個邏輯漏洞,結果確實找到一個,即CVE-2017-8570。
在CVE-2017-0199中,用到的Moniker是下面這兩個:
3050F4D8-98B5-11CF-BB82-00AA00BDCE0B // htafile06290BD3-48AA-11D2-8432-006008C3FBFC // scriptlet(or ScriptMoniker)
而在CVE-2017-8570中,用到的Moniker是下面這幾個:
00000309-0000-0000-C000-000000000046 // CompositeMoniker00000303-0000-0000-C000-000000000046 // FileMonikerECABAFC6-7F19-11D2-978E-0000F8757E2A // NewMoniker06290BD2-48AA-11D2-8432-006008C3FBFC // scriptletfile(or ScripletFactory)
可以看到CVE-2017-8570利用未被加入黑名單的Moniker繞過了CVE-2017-0199的補丁。
不過,許多分析過CVE-2017-8570的讀者可能會觀察到一個奇怪的現象:漏洞中觸發時script腳本中的代碼會被執行兩次。這是為什么呢?原來,在這個漏洞的觸發邏輯中,會涉及到wwlib.dll庫中的一個函數調用,該函數內部會順序調用ole32!CDefLink::BindToSource和ole32!CDefLink::Update兩個函數,如下(以office 2010為例):
而這兩個函數最終都會調用kernel32!CreateProcessW創建進程,所以script腳本中的代碼會被執行兩次。其中ole32!CDefLink::BindToSource創建進程的棧回溯如下:
0:000> k 50ChildEBP RetAddr 0013a5b4 729cd2f5 kernel32!CreateProcessW0013a63c 729cd5f7 wshom!CreateNewProcessW 0x6f0013a69c 76da3e75 wshom!CWshShell::Exec 0x19a0013a6bc 76da3cef OLEAUT32!DispCallFunc 0x1650013a74c 729d0267 OLEAUT32!CTypeInfo2::Invoke 0x23f...cut...0013ae9c 7705b5dc comsvcs!CNewMoniker::BindToObject 0x14f0013aed0 770c3cc6 ole32!CCompositeMoniker::BindToObject 0x105 [d:w7rtmcomole32commoniker2ccompmon.cxx @ 1104]0013af3c 68ee87ce ole32!CDefLink::BindToSource 0x1bf [d:w7rtmcomole32ole232stdimpldeflink.cpp @ 4637]0013af80 68a61429 wwlib!wdGetApplicationObject 0x69230 // 第一處調用0013b010 68a23b2c wwlib!DllGetLCID 0x4753b3...cut...
而ole32!CDefLink::Update創建進程的棧回溯如下:
0:000> k 50ChildEBP RetAddr 0013a57c 729cd2f5 kernel32!CreateProcessW0013a604 729cd5f7 wshom!CreateNewProcessW 0x6f0013a664 76da3e75 wshom!CWshShell::Exec 0x19a0013a684 76da3cef OLEAUT32!DispCallFunc 0x1650013a714 729d0267 OLEAUT32!CTypeInfo2::Invoke 0x23f...cut...0013ae68 7705b5dc comsvcs!CNewMoniker::BindToObject 0x14f0013ae9c 770c3c55 ole32!CCompositeMoniker::BindToObject 0x105 [d:w7rtmcomole32commoniker2ccompmon.cxx @ 1104]0013af08 7710f7ee ole32!CDefLink::BindToSource 0x14e [d:w7rtmcomole32ole232stdimpldeflink.cpp @ 4611]0013af30 7710f42a ole32!CDefLink::Update 0x62 [d:w7rtmcomole32ole232stdimpldeflink.cpp @ 5347]0013af44 68ee8830 ole32!CDefLink::Update 0x33 [d:w7rtmcomole32ole232stdimpldeflink.cpp @ 2695]0013af80 68a61429 wwlib!wdGetApplicationObject 0x69292 // 第二處調用 0013b010 68a23b2c wwlib!DllGetLCID 0x4753b3...cut...
第三回合:CVE-2017-8759
在CVE-2017-8570漏洞被修復后,累計有如下這些Moniker被加入黑名單:
3050F4D8-98B5-11CF-BB82-00AA00BDCE0B // htafile06290BD3-48AA-11D2-8432-006008C3FBFC // scriptlet(or ScriptMoniker)00000309-0000-0000-C000-000000000046 // CompositeMoniker00000303-0000-0000-C000-000000000046 // FileMonikerECABAFC6-7F19-11D2-978E-0000F8757E2A // NewMoniker06290BD2-48AA-11D2-8432-006008C3FBFC // scriptletfile(or ScripletFactory)
在前面幾個Moniker不能使用之后,攻擊者又注意到了下面這個Moniker:
ecabb0c7-7f19-11d2-978e-0000f8757e2a // SOAPMoniker
SOAP Moniker可以用來加載一個遠程的SOAP配置文件,當Word進程遠程加載這個配置文件時,.Net組件會被加載用來解析對應的配置文件,并按照配置自動生成一個C#文件,再自動將該C#文件編譯得到一個動態鏈接庫并執行。攻擊者借助.Net SOAP WSDL模塊中的一個代碼注入漏洞(CVE-2015-8759),將惡意腳本代碼注入到了待編譯的C#文件中,從而讓編譯得到的動態鏈接庫包含惡意代碼并自動執行。
從CVE-2017-8759開始,攻擊者開始借助office組件與其他Windows組件之間的交互進行攻擊。.Net的漏洞本身不屬于office的范圍,卻可以借助office文檔進行觸發,這種攻擊方式當時給筆者留下了深刻的印象。
第四回合:CVE-2018-8174
CVE-2017-8759被修復后,Moniker黑名單又得到了更新:
3050F4D8-98B5-11CF-BB82-00AA00BDCE0B // htafile06290BD3-48AA-11D2-8432-006008C3FBFC // scriptlet(or ScriptMoniker)00000309-0000-0000-C000-000000000046 // CompositeMoniker00000303-0000-0000-C000-000000000046 // FileMonikerECABAFC6-7F19-11D2-978E-0000F8757E2A // NewMoniker06290BD2-48AA-11D2-8432-006008C3FBFC // scriptletfile(or ScripletFactory)ecabb0c7-7f19-11d2-978e-0000f8757e2a // SOAPMoniker
在上面這些Moniker都不可用之后,攻擊者又想出了一種新的攻擊方式:借助URL Moniker去加載遠程html文件,這樣就可以借助office加載IE漏洞。攻擊者首先用URL Moniker CVE-2014-6332的組合試了一下該方案的可行性,筆者追溯到的這方面的最早樣本為2018年1月17日的下面這個文件(以及相關文件):
// CVE-2014-6332Document MD5: A9D3F7A1ACD624DE705CF27EC699B6B6URL Moniker: hxxp://s.dropcanvas[.]com/1000000/940000/939574/akw.htmlakw.html MD5: C40A128AE7AEFFA3C1720A516A99BBDF
到了2018年4月,攻擊者終于按捺不住了,借助URL Moniker IE VBScript 0day的方式對特定目標進行了攻擊,這次攻擊所用漏洞就是著名的CVE-2018-8174,相關樣本如下:
// CVE-2018-8174Document MD5: b48ddad351dd16e4b24f3909c53c8901URL Moniker: hxxp://autosoundcheckers[.]com/s2/search[.]php?who=7search.htm MD5: 15eafc24416cbf4cfe323e9c271e71e7
CVE-2018-8174出現后,微軟安全團隊并未直接將office加載VBScript腳本的功能進行限制。隨后,在2018年7月,攻擊者又借助另一個IE VBScript 0day(CVE-2018-8173),用相同的方式實施了攻擊。
這下微軟不淡定了,趕緊對Office加載VBScript腳本進行了限制。
第五回合:CVE-2020-0674
故事到這里就結束了嗎?當然沒有。此時,微軟依然沒有限制office加載JavaScript腳本,所以IE瀏覽器的兩個JavaScript引擎:JScript和JScript9依然可以通過此種方式進行攻擊。
其一,據筆者所知,在2018年的天府杯上,針對office項目的攻擊采用了URL Moniker IE JScript9 0day的組合。
其二,2019年-2020年,由于幾個JScript漏洞被相繼披露,陸續有APT攻擊組織使用URL Moniker JScript 1day的方式實施攻擊,相關樣本如下:
// CVE-2020-0674Document MD5: 90403dfafa3c573c49aa52c5fe511169URL Moniker: hxxp://tsinghua.gov-mil[.]cn/images/A96961AA/36604/1836/65449576/ab8feeeab8feee MD5: 1892D293030E81D0D1D777CB79A0FDBE// CVE-2020-0968Document MD5: 60981545a5007e5c28c8275d5f51d8f0URL Moniker: hxxp://94.156.174[.]7/up/a1a.htma1a.htm MD5: 293916af3a30b3d7a0dc2949115859a6
于是微軟在高版本office中(office2016及以上版本)也加入了對JScript9腳本和JScript腳本的加載限制。
至此,攻擊者針對Moniker的所有嘗試都被微軟進行了封堵,此后未觀察到針對Moniker的新攻擊方式。
公式編輯器漏洞
2017年11月補丁日,國外安全公司_embedi發表了一篇《SKELETON IN THE CLOSET: MS Office vulnerability you didn’t know about》詳細描述了他們發現office公式編輯器漏洞CVE-2017-11882的整個過程(筆者發現這家公司的官網已經掛了…)。
屬于office公式編輯器漏洞的時代至此開啟。
由于組件源碼的丟失,微軟的補丁開發人員花了較長時間來修復這一漏洞,并且以一種近乎炫技的方式,直接在二進制層面對程序作了修補,在沒有重新編譯源碼的情況下修復了漏洞,并添加了ASLR支持。
然而,一時激起千層浪,CVE-2017-11882出現后,廣大安全研究員蜂擁而至,都開始關注office公式編輯器這一組件,這直接導致微軟在2018年1月的更新中砍掉了公式編輯器組件。
在第二次修復的諸多office公式編輯器漏洞中,有兩個漏洞比較值得注意,這兩個漏洞分別為CVE-2018-0802和CVE-2018-0798,三個漏洞并稱為office公式編輯器漏洞領域的“三駕馬車”,
由于筆者經常看到分析人員對這三個漏洞的樣本進行誤判,所以這里分享一種在動態層面區分這三個漏洞的方法。
首先跟隨筆者來了解一下這三個漏洞的具體成因,下文中的匯編代碼基于以下公式編輯器組件:
eqnedt32.exe 2000.11.9.0
在office中,公式編輯器的數據被存儲在一個OLE文件的“Equation Native”流中,三個公式編輯器漏洞都是在處理這個流的數據時出現的問題。
CVE-2017-11882
首先來看一下CVE-2017-11882。
該漏洞的成因為:在讀入“Equation Native”流中的Font Name Record數據時,在將Name拷貝到某個局部變量的時候沒有對Name的長度做校驗,從而造成棧緩沖區溢出,漏洞發生點如下圖所示:
從下圖可以看出,函數給SrcStr變量分配的大小是0x24個字節,Name長度超過該大小就會造成棧溢出。
CVE-2017-11882的觸發邏輯如下所示:
CVE-2018-0802
再來看一下CVE-2018-0802。
該漏洞的成因為:在將“Equation Native”流中的Font Name Record數據拷貝到一個LOGFONT結構體(位于棧上)內的lfFaceName成員(它是一個以空結尾的char型字符串,最大長度為0x20,其中包含終止符NULL),沒有對Name的長度做校驗,從而造成棧緩沖區溢出,漏洞發生點如下圖所示:
CVE-2018-0802漏洞的觸發路徑和CVE-2017-11882有很大的重疊,下圖可以做一個直觀的比對:
由于某些限制,CVE-2018-0802在未打CVE-2017-11882補丁的版本上只會造成crash,但在打了補丁的版本上可以實現遠程代碼執行。
CVE-2018-0798
最后看一下CVE-2018-0798。
該漏洞的成因為:在讀入“Equation Native”流中的Matrix Record數據時,存在一處while循環內的數據讀取操作,由于未對Matrix的行和列兩個參數進行校驗,從而使攻擊者可以控制由此計算得到的拷貝長度,導致棧緩沖區溢出:
上述匯編片段描述了一個while循環,反匯編成偽代碼如下,攻擊者可以控制偽碼中v2的大小,從而導致了數據讀寫越界:
上述代碼位于sub_443F6C函數內,所以理論上只要調用sub_443F6C函數的地方均存在CVE-2018-0798漏洞。作為與之前兩個漏洞的對比,在之前兩個漏洞的基礎上加入CVE-2018-0798的觸發路徑如下:
動態區分三個公式編輯器漏洞
以上筆者已經介紹了三個公式編輯器漏洞的成因,借助上述知識,很容易在調試器中確認特定樣本使用的漏洞,判定方式如下:
// CVE-2017-11882.text:00411655 C1 E9 02 shr ecx, 2 // 獲取此偏移處的ecx值,若ecx的值位于(0x20, 0x94]區間,即為CVE-2017-11882.text:00411658 F3 A5 rep movsd.text:0041165A 8B C8 mov ecx, eax.text:0041165C 83 E1 03 and ecx, 3// CVE-2018-0802.text:00421E5B C1 E9 02 shr ecx, 2 // 獲取此偏移處的ecx值,若ecx的值大于0x94,即為CVE-2018-0802.text:00421E5E F3 A5 rep movsd.text:00421E60 8B C8 mov ecx, eax.text:00421E62 83 E1 03 and ecx, 3.text:00421E65 F3 A4 rep movsb// CVE-2018-0798.text:00443F79 8D 04 45 02 00 00 00 lea eax, ds:2[eax*2].text:00443F80 83 C0 07 add eax, 7.text:00443F83 C1 F8 03 sar eax, 3.text:00443F86 66 89 45 08 mov [ebp arg_0], ax // 獲取此偏移處的eax值,若eax的值大于4,即為CVE-2018-0798
有些樣本會同時滿足上述兩個或三個條件,因為這些樣本中內嵌多個公式編輯器漏洞利用。
延伸
細心的讀者會發現2020年極棒大賽上使用的某國產軟件公式編輯器漏洞和CVE-2018-0798基本一樣,有興趣的讀者可以自行對比研究。
參考鏈接
https://www.mcafee.com/blogs/other-blogs/mcafee-labs/critical-office-zero-day-attacks-detected-wild/
https://www.fireeye.com/blog/threat-research/2017/04/cve-2017-0199-hta-handler.html
https://www.fireeye.com/blog/threat-research/2017/04/cve-2017-0199_useda.html
https://0b3dcaf9-a-62cb3a1a-s-sites.googlegroups.com/site/zerodayresearch/Moniker_Magic_final.pdf
http://justhaifei1.blogspot.com/2017/07/bypassing-microsofts-cve-2017-0199-patch.html
https://www.fireeye.com/blog/threat-research/2017/09/zero-day-used-to-distribute-finspy.html
https://securelist.com/root-cause-analysis-of-cve-2018-8174/85486/
https://ti.dbappsecurity.com.cn/blog/index.php/2020/07/13/sidewinder-new-attack-target-cn/
https://ti.dbappsecurity.com.cn/blog/index.php/2020/09/18/operation-domino/
https://support.microsoft.com/en-us/help/4058123/security-settings-for-com-objects-in-office
https://www.anquanke.com/post/id/87311
https://www.anquanke.com/post/id/94210
https://www.freebuf.com/vuls/160409.html