主頁 >  其他 > angr_ctf——從0學習angr(一):angr簡介與核心概念

angr_ctf——從0學習angr(一):angr簡介與核心概念

2022-11-30 07:17:41 其他

我在學習angr時,先是閱讀了開發者發布在IEEE上的論文IEEE Xplore Full-Text PDF:該文章講述了自動化漏洞挖掘的背景和方法,并對angr的架構和核心模塊進行了介紹,非常經典值得一讀,

而后,我閱讀了angr官方檔案和API檔案,對angr有了總體的、暈暈乎乎的了解,最后,我發現了github上的專案angr_ctf,并使用該專案在解題程序中不斷補充、修正我對angr的了解,以下是涉及的相關連接,你可能用得上:

angr官方檔案README - angr Documentation

angr的API檔案angr API documentation — angr 9.2.26 documentation

angr_ctf專案GitHub - jakespringer/angr_ctf

本系列教程是angr的入門教程,將通過做angr_ctf中的題目的形式來介紹angr,在每篇開頭會先介紹該篇所寫題目時要用到的知識,并且盡量進行詳細的補充和擴展,以便于你了解angr是一個多么偉大的專案,觀點均來自作者的論文、angr官方檔案以及本人在實踐時的思考,

angr和angr_ctf簡介

angr是一個支持多處理架構的用于二進制檔案分析的工具包,它提供了動態符號執行的能力以及多種靜態分析的能力,專案創建的初衷,是為了整合此前多種二進制分析方式的優點,并開發一個平臺,以供二進制分析人員比較不同二進制分析方式的優劣,并根據自身需要開發新的二進制分析系統和方式,

也正是因為angr是一個二進制檔案分析的工具包,因此它可以被使用者擴展,用于自動化逆向工程、漏洞挖掘等多個方面,

 

angr_ctf則是一個專門針對angr的專案,里面有17個angr相關的題目,這些題目只有一個唯一的要求:你需要找出能夠使程式輸出“Good Job”的輸入,這也是符號執行常見的應用場景,

專案中序號開頭的檔案夾里面是題目的原始碼和題解,

dist中保存了各個題目編譯后的可執行檔案,均是ELF-32bit

solutions中集合了所有題目的題解,也是所有序號開頭檔案夾的合集,題解檔案solve包含完整題解,而scaffold則是待填充的題解,需要使用者根據程式在“???”處填入合適的內容,

 

angr核心概念

頂層介面

Project類是angr的主類,也是angr的開始,通過初始化該類的物件,可以將你想要分析的二進制檔案加載進來,就像這樣:

import angr
p = angr.Project('/bin/true')

引數為待分析的檔案路徑,它是唯一必須傳入的引數,此外還有一個比較常用的引數load-options,它指明加載的方式,如下:

名稱  描述 傳入引數
auto_load_libs   是否自動加載程式的依賴 布爾
skip_libs 希望避免加載的庫 庫名
except_missing_libs 無法決議庫時是否拋出例外 布爾
force_load_libs 強制加載的庫 庫名
ld_path 共享庫的優先搜索路徑 路徑名

使用angr時最重要的就是效率問題,少加載一些無關結果的庫能夠提升angr的效率,如下:

import angr
p = angr.Project('/bin/true', auto_load_libs=False)

任何附加的引數都會被傳遞到angr的加載器,即CLE.loader中(CLE 即 CLE Loads Everything的縮寫)

Project類中有許多方法和屬性,例如加載的檔案名、架構、程式入口點、大小端等等:

>>> print(p.arch, hex(p.entry), p.filename, p.arch.bits, p.arch.memory_endness )
<Arch AMD64 (LE)> 0x4023c0 /bin/true 64 Iend_LE

 

狀態State

Project實際上只是將二進制檔案加載進來了,要執行它,實際上是對SimState物件進行操作,它是程式的狀態,用docker來比喻,Project相當于開發環境,State則是使用開發環境制作的鏡像,

要創建狀態,需要使用Project物件中的factory,它還可以用于創建模擬管理器和基本塊(后面提到),如下:

init_state = p.factory.entry_state()

預設狀態有四種方式如下:

預設狀態方式 描述
entry_state 初始化狀態為程式運行到程式入口點處的狀態
blank_state(addr=) 大多數資料都沒有初始化,狀態中下一條指令為addr處的指令
full_init_state 共享庫和預定義內容已經加載完畢,例如剛加載完共享庫
call_state 準備呼叫函式的狀態

狀態包含了程式運行時的一切資訊,暫存器、記憶體的值、檔案系統以及符號變數等,這些資訊的使用等用到時再進一步說明,

entry_state和blank_state是常用的兩種方式,后者通常用于跳過一些極大降低angr效率的指令,它們間的對比如下:

>>> state = p.factory.entry_state()
>>> print(state.regs.rax, state.regs.rip)
<BV64 0x1c> <BV64 0x4023c0>
>>> state = p.factory.blank_state(addr=0x4023c0)
>>> print(state.regs.rax, state.regs.rip)
<BV64 reg_rax_42_64{UNINITIALIZED}> <BV64 0x4023c0>

在blank_state方式中,我們仍將地址設定為程式的入口點,然而rax中的值由于沒有初始化,它現在是一個名字,也即符號變數,這是符號執行的基礎,后續在細說,

此外,可以看到暫存器中的資料型別并不是int,而是BV64,它是一個位向量(Bit Vector),有關位向量的細節之后再說,

 

模擬管理器(Simulation Manager)

上述方式只是預設了程式開始分析時的狀態,我們要分析程式就必須要讓它到達下一個狀態,這就需要模擬管理器的幫助(簡稱SM).

使用以下指令能創建一個SM,它需要傳入一個state或者state的串列作為引數:

simgr  = p.factory.simgr(state)

SM中有許多串列,這些串列被稱為stash,它保存了處于某種狀態的state,stash有如下幾種:

stash 描述
active 保存接下來可以執行并且將要執行的狀態
deadended 由于某些原因不能繼續執行的狀態,例如沒有合法指令,或者有非法指標
pruned 與solve的策略有關,當發現一個不可解的節點后,其后面所有的節點都優化掉放在pruned里
unconstrained 如果創建SM時啟用了save_unconstrained,則沒有約束條件的state會放在這里
unsat 如果創建SM時啟用了save_unsat,則被認為不可滿足的state會放在這里

默認情況下,state會被存放在active中,

stash中的state可以通過move()方法來轉移,將fulter_func篩選出來的state從from_stash轉移到to_stash

simgr.move(from_stash='deadended', to_stash='more_then_50', filter_func=lambda s: '100' in s.posix.dumps(1))

stash是一個串列,可以使用python支持的方式去遍歷其中的元素,也可以使用常見的串列操作,但angr提供了一種更高級的方式,在stash名字前加上one_,可以得到stash中的第一個狀態,加上mp_,可以得到一個mulpyplexed版本的stash

此外,稍微解釋一下上面代碼中的posix.dumps:

  • state.posix.dumps(0):表示到達當前狀態所對應的程式輸入
  • state.posix.dumps(1):表示到達當前狀態所對應的程式輸出

上述代碼就是將deadended中輸出的字串包含'100'的state轉移到more_then_50這個stash中,

 

可以通過step()方法來讓處于active的state執行一個基本塊,這種操作不會改變state本身:

>>> state = p.factory.entry_state()
>>> simgr = p.factory.simgr(state)
>>> print(state.regs.rax, state.regs.rip)
<BV64 0x1c> <BV64 0x4023c0>

>>> print(simgr.one_active)
<SimState @ 0x4023c0>

>>> simgr.step()
<SimulationManager with 1 active>
>>> print(simgr.one_active)
<SimState @ 0x529240>

>>> print(state.regs.rax, state.regs.rip)
<BV64 0x1c> <BV64 0x4023c0>

 

最后也是SM最常用的技術:探索技術(explorer techniques)

可以使用explorer方法去執行某個狀態,直到找到目標指令或者active中沒有狀態為止,它有如下引數:

  • find:傳入目標指令的地址或地址串列,或者一個用于判斷的函式,函式以state為形參,回傳布林值
  • avoid:傳入要避免的指令的地址或地址串列,或者一個用于判斷的函式,用于減少路徑

此外還有一些搜索策略,之后會集中講解,默認使用DFS(深度優先搜索),

explorer找到的符合find的狀態會被保存在simgr.found這個串列當中,可以遍歷其中元素獲取狀態,

 符號執行

angr作為一個二進制分析的工具包,但它通常作為符號執行工具更為出名,

符號執行就是給程式傳遞一個符號而不是具體的值,讓這個符號伴隨程式運行,當碰見分支時,符號會進入哪個分支呢?

angr的回答是全都進入!angr會保存所有分支,以及分支后的所有分支,并且在分支時,保存進入該分支時的判斷條件,通常這些判斷條件時對符號的約束,

當angr運行到目標狀態時,就可以呼叫求解器對一路上收集到的約束進行求解,最終得到某個符號能夠到達當前狀態的值,

例如,程式接收一個int型別的輸入,當這個輸入大于0小于5時,就會執行某條保存在該程式中,我們希望執行的指令(例如一個后門函式backdoor),具體而言如下圖所示:

angr會沿著分支按照某種策略(默認DFS)進行狀態搜索,當達到目標狀態(也就是backdoor能夠執行的狀態),此時angr已經收集了兩個約束(x>0 以及x<=5),那么angr就通過這兩個約束對x進行求解,解出來的x值就是能夠讓程式執行backdoor的輸入,

在復雜的程式當中,從一個符號到backdoor的路徑可能十分復雜,甚至包含一些加密解密的程序,這時就是angr大顯身手的時候了,

 

實戰 00_angr_find

使用angr一般分為如下步驟:

  1. 創建Project,預設state
  2. 創建位向量和符號變數,保存在記憶體/暫存器/檔案或其他地方
  3. 將state添加到SM中
  4. 運行,探索滿足條件的路徑
  5. 約束求解獲取執行結果

先逆向查看邏輯

程式接收一個8位元組的輸入,對它使用complex_function函式進行轉換,比較轉換后的字串是否等于JACEJGCS,現在我們要找出能夠讓程式執行puts("Good Job.")的輸入,

以下是能夠獲取結果的angr腳本:

import angr

#加載檔案,預設狀態,執行狀態
p = angr.Project('./dist/00_angr_find', auto_load_libs=False)
init_state = p.factory.entry_state()
simgr = p.factory.simgr(init_state)
 
#puts Good的指令地址
target = 0x08048678

#搜索能夠執行目標指令的狀態
simgr.explore(find = target)

if simgr.found:
    solution_state = simgr.found[0]
   #列印出符號條件的狀態的輸入    
    print(solution_state.posix.dumps(0))

由于該題比較簡單,因此跳過了第2和第5步,

執行結果如下:

┌──(venv)─(kali?kali)-[~/angrfile]
└─$ python 00.py                                                                                                          148 ? 2 ?
WARNING | 2022-11-27 22:37:44,598 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing register with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-11-27 22:37:44,598 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-11-27 22:37:44,598 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-11-27 22:37:44,598 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-11-27 22:37:44,598 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-11-27 22:37:44,598 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x80486b1 (__libc_csu_init+0x1 in 00_angr_find (0x80486b1))
WARNING | 2022-11-27 22:37:44,601 | angr.storage.memory_mixins.default_filler_mixin | Filling register ebx with 4 unconstrained bytes referenced from 0x80486b3 (__libc_csu_init+0x3 in 00_angr_find (0x80486b3))
WARNING | 2022-11-27 22:37:46,904 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x7ffeff50 with 4 unconstrained bytes referenced from 0x8100000 (strcmp+0x0 in extern-address space (0x0))
b'JXWVXRKX'

事實上,上述腳本能夠解決一切有關"為了執行某條目標陳述句,我應該用怎樣的輸入”這樣的問題,是一個萬能腳本,區別在于由于程式的復雜程度和邏輯不同,耗費的時間不同,因此在解決這類問題上,撰寫angr腳本的本質是在使用angr提供的各種二進制分析方法去優化路徑,提高它的運行效率,

實戰 01_angr_avoid

這個題使用IDA打開時就很慢,在對main進行反匯編時會提示函式過大,因此直接shift+F12查找呼叫了Good的指令,發現是函式maybe_good

此外查看函式avoid_me的交叉參考

可以發現該函式被main函式呼叫了多次,應該是導致main函式過大的原因,因此要對它進行避免,也就是使用explorer的avoid的引數,

整個angr腳本如下:

import angr

p = angr.Project('./dist/01_angr_avoid')
init_state = p.factory.entry_state()
simgr = p.factory.simgr(init_state)

good = 0x080485e5
#avoid_me的函式起始的位置(并非呼叫該函式的位置,因為呼叫該函式的地方太多了) bad = 0x080485a8 simgr.explore(find= good,avoid = bad) if simgr.found: solution = simgr.found[0] print(solution.posix.dumps(0))else: raise Exception("Could not find solution")

運行結果如下:

┌──(venv)─(kali?kali)-[~/angr]
└─$ python 01.py                                                                                                            1 ? 2 ?
WARNING | 2022-11-27 22:54:49,287 | angr.storage.memory_mixins.default_filler_mixin | The program is accessing register with an unspecified value. This could indicate unwanted behavior.
WARNING | 2022-11-27 22:54:49,287 | angr.storage.memory_mixins.default_filler_mixin | angr will cope with this by generating an unconstrained symbolic variable and continuing. You can resolve this by:
WARNING | 2022-11-27 22:54:49,287 | angr.storage.memory_mixins.default_filler_mixin | 1) setting a value to the initial state
WARNING | 2022-11-27 22:54:49,287 | angr.storage.memory_mixins.default_filler_mixin | 2) adding the state option ZERO_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to make unknown regions hold null
WARNING | 2022-11-27 22:54:49,287 | angr.storage.memory_mixins.default_filler_mixin | 3) adding the state option SYMBOL_FILL_UNCONSTRAINED_{MEMORY,REGISTERS}, to suppress these messages.
WARNING | 2022-11-27 22:54:49,288 | angr.storage.memory_mixins.default_filler_mixin | Filling register edi with 4 unconstrained bytes referenced from 0x80d4591 (__libc_csu_init+0x1 in 01_angr_avoid (0x80d4591))
WARNING | 2022-11-27 22:54:49,293 | angr.storage.memory_mixins.default_filler_mixin | Filling register ebx with 4 unconstrained bytes referenced from 0x80d4593 (__libc_csu_init+0x3 in 01_angr_avoid (0x80d4593))
WARNING | 2022-11-27 22:54:55,575 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x7ffeff2d with 11 unconstrained bytes referenced from 0x8197e20 (strncmp+0x0 in libc.so.6 (0x97e20))
WARNING | 2022-11-27 22:54:55,576 | angr.storage.memory_mixins.default_filler_mixin | Filling memory at 0x7ffeff50 with 4 unconstrained bytes referenced from 0x8197e20 (strncmp+0x0 in libc.so.6 (0x97e20))
b'HUJOZMYS'

 

實戰:02_angr_find_condition

該題邏輯和前兩題差不多,區別在于此時使用了字串“Good Job”和字串“Try again”的指令多了很多,因此需要考慮給find和avoid引數傳入函式來篩選出所有這些使用了這兩個字串的指令,

對前兩題的腳本進行如下修改:

def good(state):
    tag = b'Good' in state.posix.dumps(1)
    return True if tag else False

def bad(state):
    tag = b'Try' in state.posix.dumps(1)
    return True if tag else False
    
simgr.explore(find=good, avoid=bad)

上述函式使用state作為形參,在函式內部進行判斷后回傳布林值,當值為true時觸發相應的操作(find或者avoid),這樣就能篩選出所有能夠列印出字串“Good Job”和字串“Try again的狀態了,

 

其他說明:路徑搜索——avoid為何能提高效率

angr在模擬執行指令時,對于遇到的分支和跳轉,會全部進行保留,并且記錄用于判斷分支的條件(即約束),如下圖所示

 

之前說過,這些狀態都是程式運行到某些階段時的資訊,包括了記憶體、暫存器、檔案系統等多個方面,這些狀態中有滿足條件的狀態,就會被放入到found串列當中,

而在路徑搜索時,對于滿足avoid條件的狀態,則會被丟棄,也就是說,該狀態及該狀態的后續路徑都不會被進行搜索,因此簡化了angr的搜索路徑,從而提高效率,

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/538711.html

標籤:其他

上一篇:淺談CVE-2022-22965漏洞成因(六)

下一篇:angr_ctf——從0學習angr(二):狀態操作和約束求解

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more