Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

analysis: add some misc analyses/analysis work #821

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/analysis/pass/filter-xed-nop/filter-xed-nop
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# filter-xed-nop: find and remove cohorts that XED thinks are NOPs.

require "json"

# TODO(ww): Remove this.
XED_SO = "./src/worker/xed/xed.so"

warn "[+] pass: filter-xed-nop"

count = 0
$stdin.each_line do |line|
result = JSON.parse line, symbolize_names: true

xed = result[:outputs].find { |o| o[:worker_so] == XED_SO }

# `addr32 nop ...` and `nop ...` both occur
if xed[:result].include?("nop ")
count += 1
next
end

$stdout.puts result.to_json
end

warn "[+] pass: filter-xed-nop done: #{count} filtered"
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# filter-zydis-find-overaccept: find inputs that Zydis potentially overaccepts
# (i.e., inputs the other high-quality decoders think are invalid)

require "json"

# TODO(ww): Remove this.
BDDISASM_SO = "./src/worker/bddisasm/bddisasm.so"
XED_SO = "./src/worker/xed/xed.so"
ZYDIS_SO = "./src/worker/zydis/zydis.so"
ICED_SO = "./src/worker/iced/iced.so"

def success?(decoder)
decoder[:status][:value] == 1
end

def failure?(decoder)
!success?(decoder)
end

def failure_by_consensus?(*decoders)
nfailures = decoders.select { |d| failure?(d) }.size

(nfailures / decoders.size.to_f) > 0.50
end

warn "[+] pass: filter-zydis-find-overaccept"

count = 0
$stdin.each_line do |line|
result = JSON.parse line, symbolize_names: true

bddisasm = result[:outputs].find { |o| o[:worker_so] == BDDISASM_SO }
xed = result[:outputs].find { |o| o[:worker_so] == XED_SO }
zydis = result[:outputs].find { |o| o[:worker_so] == ZYDIS_SO }
iced = result[:outputs].find { |o| o[:worker_so] == ICED_SO }

# If Zydis reports success when other high-quality decoders don't, keep it.
if success?(zydis) && failure_by_consensus?(bddisasm, xed, iced)
$stdout.puts result.to_json
end

count += 1
end

warn "[+] pass: filter-zydis-find-overaccept done: #{count} filtered"
3 changes: 3 additions & 0 deletions src/analysis/pass/filter-zydis-find-overaccept/spec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: filter-zydis-find-overaccept
desc: Find results that Zydis potentially overaccepts
run: filter-zydis-find-overaccept
23 changes: 23 additions & 0 deletions src/analysis/pass/find-small-inputs/find-small-inputs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# find-small-inputs: find cohorts whose inputs are relatively small.

require "json"

warn "[+] pass: find-small-inputs"

count = 0
$stdin.each_line do |line|
result = JSON.parse line, symbolize_names: true

# input is a hex string, so 8 bytes * 2 bytes per hex char
if result[:input].size <= 16
count += 1
next
end

$stdout.puts result.to_json
end

warn "[+] pass: find-small-inputs done: #{count} filtered"
3 changes: 3 additions & 0 deletions src/analysis/pass/find-small-inputs/spec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: find-small-inputs
desc: Find results whose inputs are relatively small (<= 8 bytes)
run: find-small-inputs
20 changes: 20 additions & 0 deletions src/analysis/pass/prune-capstone/prune-capstone
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# prune-capstone: remove Capstone results from each cohort, if present

require "json"

# TODO(ww): Remove this.
CAPSTONE_SO = "./src/worker/capstone/capstone.so"

warn "[+] pass: prune-capstone"

$stdin.each_line do |line|
result = JSON.parse line, symbolize_names: true
result[:outputs].reject! { |o| o[:worker_so] == CAPSTONE_SO }

$stdout.puts result.to_json
end

warn "[+] pass: prune-capstone done"
3 changes: 3 additions & 0 deletions src/analysis/pass/prune-capstone/spec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: prune-capstone
desc: Remove all Capstone results
run: prune-capstone
20 changes: 20 additions & 0 deletions src/analysis/pass/prune-libopcodes/prune-libopcodes
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# prune-libopcodes: remove libopcodes results from each cohort, if present

require "json"

# TODO(ww): Remove this.
LIBOPCODES_SO = "./src/worker/bfd/bfd.so"

warn "[+] pass: prune-libopcodes"

$stdin.each_line do |line|
result = JSON.parse line, symbolize_names: true
result[:outputs].reject! { |o| o[:worker_so] == LIBOPCODES_SO }

$stdout.puts result.to_json
end

warn "[+] pass: prune-libopcodes done"
3 changes: 3 additions & 0 deletions src/analysis/pass/prune-libopcodes/spec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: prune-libopcodes
desc: Remove all libopcodes (BFD) results
run: prune-libopcodes
13 changes: 13 additions & 0 deletions src/analysis/passes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,16 @@ xed-underaccept:
- filter-xed-find-underaccept
- minimize-input
- normalize

# Find relatively small (<= 8 byte) inputs.
# This should be run after an analysis that does `minimize-input`
small-inputs:
- find-small-inputs

# Remove all libopcodes results.
remove-libopcodes:
- prune-libopcodes

# Remove all capstone results.
remove-capstone:
- prune-capstone