1. 程式人生 > >系統級程式設計結課實驗-第一部分

系統級程式設計結課實驗-第一部分

實驗要求是老師口述的,參考論文Towards security defect prediction with AI,使用記憶網路對資料集進行訓練,使之能完成程式碼漏洞的檢測,並且!新增新的漏洞型別(原論文提供的資料集只有兩種漏洞型別)進行檢查!

這一部分先講一下使用機器學習進行漏洞檢查的原理以及配置訓練環境的一些情況。

為什麼要用機器學習檢查漏洞

  因為靜態分析工具很難找完或者準確找到程式碼中的漏洞,即使是最先進的靜態分析工具在Juliet Test Suite(一個程式碼集合,用以測試漏洞檢查工具的效能)上表現也不佳。因為靜態分析工具需要制定一些規則,來判斷程式碼是否存在漏洞,而有的漏洞往往難以想到,但是數量又眾多,所以可以嘗試機器學習,給模型喂資料,模型不需要理解程式碼的邏輯就可以判斷程式碼是否存在漏洞。這只是個人理解,詳細可以看上面的論文

訓練的原理

  個人不是很懂機器學習,只能講一個簡單的大概,就是將c程式碼貼上標籤(行位放個特殊的註釋),然後用clang等工具將c程式碼轉為token檔案,然後餵給記憶網路。記憶網路會用position encoding,即位置編碼,詳見End-to-end memory networks. InAdvances in Neural Information Processing Systems,對所有程式碼進行編碼變成一個矩陣,然後放入記憶網路用一定的演算法(看的不太懂...上面給的論文都有詳細介紹這個演算法)進行訓練,最後得出一個模型,通過這個模型就可以對程式碼進行預測。對於本次實驗,並不需要了解記憶網路工作原理和訓練原理(畢竟是系統級程式設計,不是機器學習課程)。

配置訓練環境

這次實驗用到https://github.com/cmu-sei/sa-bAbI的檔案,cmu大佬寫的程式碼,說明裡面雖然有教怎麼使用,但是還是有些問題需要解決一下。

1.docker的安裝,可能我這邊網比較差,裝最新的docker總是裝不上,最後用的apt方法來獲取docker.io才裝上

2.docker-compose build應該更正為sudo docker-compose,不然會提示沒有許可權,後面生成資料集以及測試也需要用sudo先獲取許可權。

3.enviroment.yml檔案似乎有些問題,需要修改。將檔案中的

替換為

# - libgfortran=3.0.1=h93005f0_2
# - libopenblas=0.3.3=hdc02c5d_3
# - mkl=2019.0=118
# - numpy=1.15.2=py36h6a91979_0
# - numpy-base=1.15.2=py36h8a80b8c_0
# - scikit-learn=0.20.0=py36h4f467ca_1
# - scipy=1.1.0=py36h28f7352_1
- pip:
#- libgfortran==3.0.1=h93005f0_2
#- libopenblas==0.3.3=hdc02c5d_3
#- scipy==1.1.0=py36h28f7352_1
#- scikit-learn==0.20.0=py36h4f467ca_1
#- numpy-base==1.15.2=py36h8a80b8c_0
#- numpy==1.15.2=py36h6a91979_0
- numpy==1.15.2
- scipy==1.1.0
- scikit-learn==0.20.0
#- numpy-base==1.15.2

即可。然後按照github上的方法,一直到訓練為止都不會有問題,到了python validate.py這一步會出問題,提示資料夾不存在,這個是validate.py中的一個小疏忽。修改方法如下:

將evaluate_oneoff函式下的程式碼

if not os.path.exists(path):
if models is None:
models = get_models(models_dir)
predic = models[predic_num].predict(
[val_instances_mat, val_queries_mat])
np.save(path, predic)

  修改為:

if not os.path.exists(path):
    if models is None:
        models = get_models(models_dir)
    predic = models[predic_num].predict(
        [val_instances_mat, val_queries_mat])
    if not os.path.exists(os.path.dirname(path)):
        os.makedirs(os.path.dirname(path))
    np.save(path, predic)

即可。