Skip to content

Commit

Permalink
Demangle rust symbols (#97)
Browse files Browse the repository at this point in the history
* demangle more symbols using symbolic

Signed-off-by: Prabhu Subramanian <[email protected]>

* Bump version

Signed-off-by: Prabhu Subramanian <[email protected]>

* pyinstaller bug fix

Signed-off-by: Prabhu Subramanian <[email protected]>

---------

Signed-off-by: Prabhu Subramanian <[email protected]>
  • Loading branch information
prabhu authored May 5, 2024
1 parent 4e56ade commit a3d65e5
Show file tree
Hide file tree
Showing 11 changed files with 322 additions and 158 deletions.
2 changes: 1 addition & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[flake8]
ignore = E203, E266, E501, W503, W605
ignore = E203, E266, E501, W503, W605, F401
exclude = blint/cyclonedx/spec.py
max-line-length = 99
max-complexity = 18
Expand Down
28 changes: 21 additions & 7 deletions .github/workflows/bintests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ concurrency:
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.10', '3.11', '3.12']
fail-fast: false
steps:
Expand All @@ -27,21 +28,34 @@ jobs:
poetry install
- name: Test binaries
run: |
mkdir -p bintests gobintests
mkdir -p bintests gobintests rusttests
cd bintests
wget -q https://github.com/owasp-dep-scan/dosai/releases/download/v0.1.1/Dosai.exe
wget -q https://github.com/owasp-dep-scan/dosai/releases/download/v0.1.1/Dosai
wget -q https://github.com/owasp-dep-scan/dosai/releases/download/v0.1.1/Dosai-osx-arm64
curl -LO https://github.com/owasp-dep-scan/dosai/releases/download/v0.1.1/Dosai.exe
curl -LO https://github.com/owasp-dep-scan/dosai/releases/download/v0.1.1/Dosai
curl -LO https://github.com/owasp-dep-scan/dosai/releases/download/v0.1.1/Dosai-osx-arm64
cd ..
cd gobintests
wget -q https://github.com/containerd/containerd/releases/download/v1.7.14/containerd-1.7.14-linux-amd64.tar.gz
wget -q https://github.com/containerd/nerdctl/releases/download/v1.7.4/nerdctl-1.7.4-windows-amd64.tar.gz
curl -LO https://github.com/containerd/containerd/releases/download/v1.7.14/containerd-1.7.14-linux-amd64.tar.gz
curl -LO https://github.com/containerd/nerdctl/releases/download/v1.7.4/nerdctl-1.7.4-windows-amd64.tar.gz
tar -xvf containerd-1.7.14-linux-amd64.tar.gz
tar -xvf nerdctl-1.7.4-windows-amd64.tar.gz
rm containerd-1.7.14-linux-amd64.tar.gz
rm nerdctl-1.7.4-windows-amd64.tar.gz
cd ..
cd rusttests
curl -LO https://github.com/BurntSushi/ripgrep/releases/download/14.1.0/ripgrep-14.1.0-x86_64-unknown-linux-musl.tar.gz
curl -LO https://github.com/BurntSushi/ripgrep/releases/download/14.1.0/ripgrep-14.1.0-x86_64-apple-darwin.tar.gz
curl -LO https://github.com/BurntSushi/ripgrep/releases/download/14.1.0/ripgrep-14.1.0-x86_64-pc-windows-gnu.zip
tar -xvf ripgrep-14.1.0-x86_64-unknown-linux-musl.tar.gz
rm ripgrep-14.1.0-x86_64-unknown-linux-musl.tar.gz
tar -xvf ripgrep-14.1.0-x86_64-apple-darwin.tar.gz
rm ripgrep-14.1.0-x86_64-apple-darwin.tar.gz
unzip ripgrep-14.1.0-x86_64-pc-windows-gnu.zip
rm ripgrep-14.1.0-x86_64-pc-windows-gnu.zip
cd ..
poetry run blint sbom -i bintests -o reports/bom.json --deep
poetry run blint sbom -i gobintests -o reports/bom.json --deep
poetry run blint sbom -i rusttests -o reports/bom.json --deep
env:
SCAN_DEBUG_MODE: "debug"
shell: bash
3 changes: 3 additions & 0 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: Build Linux Binaries

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

Expand Down Expand Up @@ -37,6 +39,7 @@ jobs:
--add-data="blint/data:blint/data" \
--add-data="blint/data/annotations:blint/data/annotations" \
--collect-submodules blint \
--collect-submodules symbolic \
--noupx
./dist/blint -i dist/blint -o /tmp/reports
sha256sum ./dist/blint > ./dist/blint.sha256
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/pytests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ name: Python matrix CI
on:
push:
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/win.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: Build Windows Binaries

on:
push:
branches:
- main
workflow_dispatch:
pull_request:

Expand Down
2 changes: 2 additions & 0 deletions blint/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from rich.terminal_theme import MONOKAI

from blint.binary import parse
# pylint: disable-next=unused-import
from blint.checks import (check_nx, check_pie,
check_relro, check_canary, check_rpath,
check_virtual_size, check_authenticode,
Expand Down Expand Up @@ -300,6 +301,7 @@ def print_reviews_table(reviews, files):


def json_serializer(obj):
"""JSON serializer to help serialize problematic types such as bytes"""
if isinstance(obj, bytes):
return obj.decode('utf-8')

Expand Down
39 changes: 34 additions & 5 deletions blint/binary.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
# pylint: disable=too-many-lines,consider-using-f-string
import codecs
import contextlib
import orjson
import sys
from typing import Tuple
import zlib
import orjson

import lief

from blint.logger import DEBUG, LOG
from blint.utils import calculate_entropy, check_secret, cleanup_dict_lief_errors, decode_base64

SYMBOLIC_FOUND = True
try:
from symbolic._lowlevel import ffi, lib
from symbolic.utils import encode_str, decode_str, rustcall
except OSError:
SYMBOLIC_FOUND = False

MIN_ENTROPY = 0.39
MIN_LENGTH = 80

Expand All @@ -21,6 +28,21 @@
ADDRESS_FMT = "0x{:<10x}"


def demangle_symbolic_name(symbol, lang=None, no_args=False):
"""Demangles a symbol."""
if not SYMBOLIC_FOUND:
return symbol
try:
func = lib.symbolic_demangle_no_args if no_args else lib.symbolic_demangle
lang_str = encode_str(lang) if lang else ffi.NULL

demangled = rustcall(func, encode_str(symbol), lang_str)
demangled_symbol = decode_str(demangled, free=True)
return demangled_symbol.strip()
except AttributeError:
return symbol


def is_shared_library(parsed_obj):
"""
Checks if the given parsed binary object represents a shared library.
Expand Down Expand Up @@ -243,7 +265,9 @@ def parse_symbols(symbols):
is_exported = True
symbol_name = symbol.demangled_name
if isinstance(symbol_name, lief.lief_errors):
symbol_name = symbol.name
symbol_name = demangle_symbolic_name(symbol.name)
else:
symbol_name = demangle_symbolic_name(symbol_name)
exe_type = guess_exe_type(symbol_name)
symbols_list.append(
{
Expand Down Expand Up @@ -497,12 +521,14 @@ def parse_pe_symbols(symbols):
symbols_list = []
exe_type = ""
for symbol in symbols:
if not symbol:
continue
try:
if symbol.section_number <= 0:
section_nb_str = str(lief.PE.SYMBOL_SECTION_NUMBER(symbol.section_number)).rsplit(
".", maxsplit=1
)[-1]
elif symbol.section.name:
elif symbol.section and symbol.section.name:
section_nb_str = symbol.section.name
else:
section_nb_str = "section<{:d}>".format(symbol.section_number)
Expand All @@ -525,6 +551,8 @@ def parse_pe_symbols(symbols):
)
except (IndexError, AttributeError, ValueError) as e:
LOG.debug(f"Caught {type(e)}: {e} while parsing {symbol}.")
except RuntimeError:
pass
return symbols_list, exe_type


Expand Down Expand Up @@ -637,8 +665,9 @@ def parse_macho_symbols(symbols):
)
symbol_name = symbol.demangled_name
if not symbol_name or isinstance(symbol_name, lief.lief_errors):
symbol_name = symbol.name
symbol_name = symbol_name.replace("..", "::")
symbol_name = demangle_symbolic_name(symbol.name)
else:
symbol_name = demangle_symbolic_name(symbol_name)
if not exe_type:
exe_type = guess_exe_type(symbol_name)
symbols_list.append(
Expand Down
1 change: 1 addition & 0 deletions blint/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,5 +505,6 @@ def create_component_evidence(method_value: str, confidence: float) -> Component


def camel_to_snake(name: str) -> str:
"""Convert camelCase to snake_case"""
name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower()
Loading

0 comments on commit a3d65e5

Please sign in to comment.