Asm2Vec: Boosting Static Representation Robustness for Binary Clone Search against Code Obfuscation (Type IV)
four types of clones:
Type I: literally identical
Type II: syntactically equivalent
Type III: slightly modified
Type IV: semantically similar (assembly functions may appear syntactically different, but share similar functional logic in their source
code)
Introduction
However, designing an effective search engine is difficult, due to varieties of compiler optimizations and obfuscation techniques that make logically similar assembly functions appear to be dramatically different.
It is challenging to identify these semantically similar, but structurally and syntactically different assembly functions as clones.
Two problems
P1: Existing state-of-the-art static approaches fail to consider the relationships among features. (没有考虑特征之间的关系)
e.g.,
A fclose libc function call is related to other file-related libc calls such as fopen.
A strcpy libc call can be replaced with memcpy.
To address this problem, we propose to incorporate lexical semantic relationship into the feature engineering process. (将词汇语义关系纳入特征工程过程)Asm2V ec explores co-occurrence relationships among tokens and discovers rich lexical semantic relationships among tokens.
P2: The existing static approaches assume that features are equally important or require a mapping of equivalent assembly functions to learn the weights.
Inspired by recent development in representation learning, we propose to train a neural network model to read many assembly code data and let the model identify the best representation that distinguishes one function from the rest.
Problem Definition
Overall Workflow![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/1e0089c4892174babebe75aa0178e69d.png#pic_center)
Step 1: Given a repository of assembly functions, we first build a neural network model for these functions.
给定一个函数库,首先为这些函数建立一个神经网络模型。
Step 2: After the training phase, the model produces a vector representation for each repository function.
在训练阶段之后,模型为每个函数生成一个向量表示
Step 3: Given a target function
f
t
f_t
ft that was not trained with this model, we use the model to estimate its vector representation.
给定一个未经过该模型训练的目标函数
f
t
f_t
ft ,我们使用该模型估计其向量表示。
Step 4: We compare the vector of
f
t
f_t
ft against the other vectors in the repository by using cosine similarity to retrieve the top-
k
k
k ranked candidates as results.
将
f
t
f_t
ft向量与库中其他向量进行比较,利用余弦相似度检索排名前k的候选向量作为结果。
The training process is a one-time effort and is efficient to learn representation for queries. If a new assembly function is added to the repository, we follow the same procedure in Step 3 to estimate its vector representation. The model can be retrained periodically to guarantee the vectors’ quality.
(该训练过程是一次性的,可以有效地学习查询的表示。如果向存储库中添加了一个新的汇编函数,我们将按照步骤3中的相同过程来估计它的向量表示。该模型可以周期性地进行再训练,以保证矢量的质量。)
Assembly Code Representation Learning(based on the PV-DM model)
Preliminaries (PV-DM model)
给定一个包含多个句子的文本段落,PV-DM在每个句子上应用一个滑动窗口。滑动窗口从句首开始,每一步向前移动一个单词。
e.g.,
Figure 4. 滑动窗口是5
- 第一步,滑动窗口包含五个单词“the”,“cat”,“sit”,“on”和“a”。
- 中间的单词“sat”被当作目标,周围的单词被当作上下文。
- 第二步,窗口向前移动一个单词,其中包含“cat”、“sit”、“on”、“a”和“mat”,其中“on”是目标单词。
在每一步,PV-DM模型执行一个多类预测任务。它将当前段落映射为基于段落ID的向量,并将上下文中的每个单词映射为基于单词ID的向量。该模型对这些向量进行平均,并通过softmax分类从词汇表中预测目标词。利用反向传播的分类误差来更新这些向量。
给定一个文本语料库
T
T
T, 包括一个段落列表
p
∈
T
p \in T
p∈T, 每一个段落包含一个句子列表
s
∈
p
s \in p
s∈p, 并且每一个句子包含一个单词序列
w
t
∈
s
w_t \in s
wt∈s, 单词数目为
∣
s
∣
|s|
∣s∣.
PV-DM maximizes the log probability:
(1) ∑ p T ∑ s p ∑ t = k ∣ s ∣ − k l o g P ( w t ∣ p , w t − k , . . . , w t + k ) \sum_{p}^{T}\sum_{s}^{p}\sum_{t=k}^{|s|-k}logP(w_t|p,w_{t-k},...,w_{t+k}) ∑pT∑sp∑t=k∣s∣−klogP(wt∣p,wt−k,...,wt+k)
滑动窗口大小为2k + 1。段落向量捕捉上下文中缺失的信息来预测目标。 它被解释为主题。PV-DM是为按顺序排列的文本数据设计的。
The Asm2Vec Model
PV-DM是为按顺序排列的文本数据设计的。但是,汇编代码比纯文本具有更丰富的语法。它包含与纯文本在结构上不同的操作、操作数和控制流。
一个汇编函数可以被表示为控制流图(CFG)。我们将控制流图建模为多个序列。每个序列都对应于一个潜在的执行轨迹,该轨迹包含线性排列的汇编指令。
这个步骤对应于Step1, Step2. 通过这两个步骤, 我们训练出一个表示模型, 为每一个函数库中的函数
f
s
∈
R
P
f_s\in RP
fs∈RP 生成一个数值向量。
首先,我们将每个函数 f s f_s fs 映射为一个向量 θ → f s ∈ R 2 × d {\mathop{\theta} \limits ^{\rightarrow}}_{f_s}\in\mathbb{R}^{2\times d} θ→fs∈R2×d.
- θ → f s {\mathop{\theta} \limits ^{\rightarrow}}_{f_s} θ→fs 是函数 f s f_s fs的需要在训练中学习的表示向量。
- d d d是用户选择的参数。
类似地,我们手机在存储库 R P RP RP 中所有独特的token,我们将汇编代码的操作数和操作符视为token。我们将每一个token t t t 映射为一个数值向量 v t → ∈ R d {\mathop{v_t} \limits ^{\rightarrow}}\in\mathbb{R}^{d} vt→∈Rd 和另一个数值向量 v t ′ → ∈ R 2 × d {\mathop{v'_t} \limits ^{\rightarrow}}\in\mathbb{R}^{2\times d} vt′→∈R2×d 。
- v t → \mathop{v_t} \limits ^{\rightarrow} vt→ 是 token t t t 的向量表示。训练后, 它代表了token的词汇语义。 向量 v t → \mathop{v_t} \limits ^{\rightarrow} vt→ 用来可视化token之间的关系。
- v t ′ → \mathop{v'_t} \limits ^{\rightarrow} vt′→ 被用作token的预测。
所有的
θ
→
f
s
{\mathop{\theta} \limits ^{\rightarrow}}_{f_s}
θ→fs 和
v
t
→
\mathop{v_t} \limits ^{\rightarrow}
vt→ 被初始化为 0 附近的小随机值。
所有的
v
t
′
→
\mathop{v'_t} \limits ^{\rightarrow}
vt′→ 被初始化为 0 。
对于
f
s
f_s
fs ,我们是用
2
×
d
2\times d
2×d, 因为我们连接操作符的向量和操作数的向量来表示一条指令。
我们将存储库
R
P
RP
RP 中的每一个函数
f
s
∈
R
P
f_s \in RP
fs∈RP 看做一个多序列
S
(
f
s
)
=
s
e
q
[
1
:
i
]
\mathcal{S}(f_s) = seq[1:i]
S(fs)=seq[1:i], 其中
s
e
q
i
seq_i
seqi 是其中的一条。我们假设序列的顺序是随机的。
一个序列被表示为一个指令列表
I
(
s
e
q
i
)
=
i
n
[
1
:
j
]
\mathcal{I}(seq_i) = in[1:j]
I(seqi)=in[1:j],其中
i
n
j
in_j
inj是其中的一个指令。
一条指令
i
n
j
in_j
inj 包含了多个操作数
A
(
i
n
j
)
\mathcal{A}(in_j)
A(inj) 和一个操作符
P
(
i
n
j
)
\mathcal{P}(in_j)
P(inj) 。它们的连接被表示为它的 token
T
(
i
n
j
)
=
P
(
i
n
j
)
∣
∣
A
(
i
n
j
)
\mathcal{T}(in_j) = \mathcal{P}(in_j) || \mathcal{A}(in_j)
T(inj)=P(inj)∣∣A(inj), 其中
∣
∣
||
∣∣ 表示连接. 常量 token 被规范化为十六进制形式。
对于函数
f
s
f_s
fs 中的每一条序列
s
e
q
i
seq_i
seqi ,神经网络从序列的开始遍历指令。
我们收集当前的指令
i
n
j
in_j
inj,它的前一条指令
i
n
j
−
1
in_{j-1}
inj−1, 以及它的下一条指令
i
n
j
+
1
in_{j+1}
inj+1 。我们忽视那些越界的指令。
提出的模型试图最大化 存储库 R P RP RP 的 l o g log log 概率:
(2) ∑ f s R P ∑ s e q i S f s ∑ i n j I ( s e q i ) ∑ t c T ( i n j ) l o g P ( t c ∣ f s , i n j − 1 , i n j + 1 ) \sum_{f_s}^{RP}\sum_{seq_i}^{\mathcal{S_{f_s}} }\sum_{in_j}^{\mathcal{I(seq_i)}}\sum_{t_c}^{\mathcal{T(in_j})}log \mathbf P(t_c|f_s,in_{j-1},in_{j+1}) ∑fsRP∑seqiSfs∑injI(seqi)∑tcT(inj)logP(tc∣fs,inj−1,inj+1)
如果给定当前的汇编函数 f s f_s fs 和她的邻居指令,这个公式用来最大化当前指令的token t c t_c tc 的 l o g log log 概率。是使用当前函数的向量和相邻指令提供的上下文来预测当前指令。相邻指令提供的向量捕获词汇语义关系。函数的向量记住了在给定的上下文下不能预测的东西。它模拟指令,以区分当前函数与其他函数。
对于一个给定函数
f
s
f_s
fs, 我们首先通过预先建好的字典寻找它的向量表示
θ
→
f
s
{\mathop{\theta} \limits ^{\rightarrow}}_{f_s}
θ→fs 。 为了将一个邻居指令
i
n
in
in 建模为
C
T
(
i
n
)
∈
R
2
×
d
\mathcal{CT} (in) \in \mathbb{R}^{2\times d}
CT(in)∈R2×d, 我们对它的操作数的向量
(
∈
R
d
)
(\in \mathbb{R}^d)
(∈Rd)进行平均, 并将其与操作符的平均向量表示
(
∈
R
d
)
(\in \mathbb{R}^d)
(∈Rd) 相连接。
可以表示为:
(3)
C
T
(
i
n
)
=
v
→
P
∣
∣
1
A
(
i
n
)
∑
t
A
(
i
n
)
v
→
t
b
\mathcal{CT}(in)= {\mathop{v} \limits ^{\rightarrow} }_\mathcal{P}||\frac{1}{\mathcal{A}(in)}\sum_{t}^{\mathcal{A}(in)} {\mathop{v} \limits ^{\rightarrow}}_{t_b}
CT(in)=v→P∣∣A(in)1∑tA(in)v→tb
P
(
∗
)
\mathcal{P}(*)
P(∗) 表示一个操作符并且它是一个单独的 token 。
通过用
C
T
(
i
n
j
−
1
)
\mathcal{CT}(in_j -1)
CT(inj−1) 和
C
T
(
i
n
j
+
1
)
\mathcal{CT}(in_j +1)
CT(inj+1) 平均
f
s
f_s
fs ,
δ
(
i
n
,
f
s
)
\delta(in, f_s)
δ(in,fs) 对相邻指令的联合内存进行建模:
(4) δ ( i n , f s ) = 1 3 ( θ → f s + C T ( i n j − 1 ) + C T ( i n j + 1 ) ) \delta(in, f_s) = \frac{1}{3}({\mathop{\theta} \limits ^{\rightarrow}}_{f_s} + \mathcal{CT}(in_{j-1})+\mathcal{CT}(in_{j+1})) δ(in,fs)=31(θ→fs+CT(inj−1)+CT(inj+1))
例:
考虑一个简单的汇编函数
f
s
f_s
fs 和它的其中一条序列, 如图5所示
用第三条指令举例,
j
=
3
j = 3
j=3,
T
(
i
n
3
)
=
{
′
p
u
s
h
′
,
′
r
b
x
′
}
\mathcal{T}(in_3) = \{'push', 'rbx'\}
T(in3)={′push′,′rbx′} 。
A
(
i
n
3
−
1
)
=
{
′
r
b
p
′
,
′
r
s
p
}
\mathcal{A}(in_{3-1}) =\{'rbp', 'rsp\}
A(in3−1)={′rbp′,′rsp} .
P
(
i
n
3
−
1
)
=
{
′
m
o
v
′
}
\mathcal{P}(in_{3-1}) = \{'mov' \}
P(in3−1)={′mov′}.
我们收集它们各自的向量 :
v
→
r
b
p
{\mathop{v} \limits ^{\rightarrow}}_{rbp}
v→rbp,
v
→
r
s
p
{\mathop{v} \limits ^{\rightarrow}}_{rsp}
v→rsp,
v
→
m
o
v
{\mathop{v} \limits ^{\rightarrow}}_{mov}
v→mov, 并且计算
C
T
(
i
n
3
−
1
)
=
v
→
m
o
v
∣
∣
(
v
→
r
b
p
+
v
→
r
s
p
)
/
2
\mathcal{CT}(in_{3-1}) = {\mathop{v} \limits ^{\rightarrow}}_{mov}|| ({\mathop{v} \limits ^{\rightarrow}}_{rbp}+{\mathop{v} \limits ^{\rightarrow}}_{rsp})/2
CT(in3−1)=v→mov∣∣(v→rbp+v→rsp)/2 。
使用同样的步骤, 计算
C
T
(
i
n
3
+
1
)
\mathcal{CT}(in_{3+1})
CT(in3+1) .
使用公式(4), 可以得到
δ
(
i
n
3
,
f
s
)
\delta(in_3, f_s)
δ(in3,fs)
给定
δ
(
i
n
,
f
s
)
\delta(in, f_s)
δ(in,fs), 公式 (2)中词的概率可以被写作:
(5)
P
(
t
c
∣
f
s
,
i
n
j
−
1
,
i
n
j
+
1
)
=
P
(
t
c
∣
δ
(
i
n
j
,
f
s
)
)
\mathbf{P}(t_c|f_s, in_{j-1}, in_{j+1}) = \mathbf{P}(t_c|\delta(in_j, f_s))
P(tc∣fs,inj−1,inj+1)=P(tc∣δ(inj,fs))
我们将每一个 token 映射为两个向量
v
→
{\mathop{v} \limits ^{\rightarrow}}
v→,
v
′
→
{\mathop{v'} \limits ^{\rightarrow}}
v′→。
对于每一个 token
t
c
∈
T
(
i
n
j
)
t_c \in \mathcal{T}(in_j)
tc∈T(inj),属于当前的指令, 我们寻找它的输出向量
v
′
→
t
c
{\mathop{v'} \limits ^{\rightarrow}}_{t_c}
v′→tc。
公式(5)的概率可以被建模为一个 softmax 多类回归录像:
- D D D 表示在存储库 R P RP RP 上构建的整个词汇表。
- U h ( ⋅ ) Uh(\cdot) Uh(⋅) 表示一个应用在向量中每一个值的 sigmoid 函数
- 对于softmax 要布局的每一遍, 要估计的参数总数是
(
∣
D
∣
+
1
)
×
2
×
d
(|D|+1)\times2\times d
(∣D∣+1)×2×d 。
∣ D ∣ |D| ∣D∣ 对于softmax分类来说太大了。
我们使用 k k k negative sampling 方法去近似 log 概率:
是一个 identity 函数 。 如果这个函数内的表达式被计算为真,那么它输出1;否则为0.
例如:
negative sampling 算法区分出正确的猜测
t
c
t_c
tc 用
k
k
k 个随机选择的 negative samples
{
t
d
∣
t
d
≠
t
c
}
\{t_d|t_d \neq t_c\}
{td∣td=tc} 使用
k
+
1
k+1
k+1 logistic 回归.。
E t d ∼ P t c \mathbb E_{t_d \sim P {t_c}} Etd∼Ptc 是一个采样函数, 从词汇表 D D D 中采样 t d t_d td 根据 从 D D D 中构建的噪声分布 P n ( t c ) P_n(t_c) Pn(tc) 。
通过导数, 分别对于 v ′ → t {\mathop{v'} \limits ^{\rightarrow}}_t v′→t, θ → f s {\mathop{\theta} \limits ^{\rightarrow}}_{f_s} θ→fs 计算梯度如下:
通过导数, 分别对于
v
′
→
P
(
i
n
j
+
1
)
{\mathop{v'} \limits ^{\rightarrow}}_{\mathcal P(in_{j+1})}
v′→P(inj+1),
{
v
→
t
b
∣
t
b
∈
A
(
i
n
j
+
1
)
}
\{{\mathop{v} \limits ^{\rightarrow}}_{t_b}|t_b \in \mathcal A(in_{j+1})\}
{v→tb∣tb∈A(inj+1)}, 计算梯度如下:
之后,我们使用反向传播来更新所涉及向量的值。具体来说, 我们更新
θ
→
f
s
{\mathop{\theta} \limits ^{\rightarrow}}_{f_s}
θ→fs,所有涉及到的
v
→
t
{\mathop{v} \limits ^{\rightarrow}}_t
v→t 和
v
′
→
t
{\mathop{v'} \limits ^{\rightarrow}}_t
v′→t 根据它们的梯度, 使用一个学习率。
例:
继续示例1,其中目标 token 为
′
p
u
s
h
′
' push '
′push′。接下来,我们使用 negative sampling (方程A)计算
P
(
v
′
→
p
u
s
h
∣
δ
(
i
n
j
,
f
s
)
)
\mathbf P ({\mathop{v'} \limits ^{\rightarrow}}_{push} |\delta(in_j, f_s))
P(v′→push∣δ(inj,fs))。之后,我们使用公式7和8计算梯度。我们更新这两个例子中所有涉及的向量,根据它们各自的梯度,以学习速率。