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

update identify.py #908

Merged
merged 15 commits into from
Nov 16, 2023
65 changes: 50 additions & 15 deletions floss/language/identify.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import floss.logging_
from floss.results import StaticString
from floss.language.utils import get_rdata_section
from floss.rust_version_database import rust_commit_hash

logger = floss.logging_.getLogger(__name__)
Expand Down Expand Up @@ -89,22 +90,30 @@ def get_if_go_and_version(pe: pefile.PE) -> Tuple[bool, str]:
b"\xfa\xff\xff\xff\x00\x00",
b"\xf1\xff\xff\xff\x00\x00",
]

go_functions = [
b"runtime.main",
b"main.main",
b"runtime.gcWork",
b"runtime.morestack",
b"runtime.morestack_noctxt",
b"runtime.newproc",
b"runtime.gcWriteBarrier",
b"runtime.Gosched",
]
# look for the .rdata section first
for section in pe.sections:
try:
section_name = section.Name.partition(b"\x00")[0].decode("utf-8")
except UnicodeDecodeError:
continue
if ".rdata" == section_name:
section_va = section.VirtualAddress
section_size = section.SizeOfRawData
section_data = section.get_data(section_va, section_size)
for magic in go_magic:
if magic in section_data:
pclntab_va = section_data.index(magic) + section_va
if verify_pclntab(section, pclntab_va):
return True, get_go_version(magic)
try:
section = get_rdata_section(pe)
mr-tz marked this conversation as resolved.
Show resolved Hide resolved
except ValueError:
logger.debug(".rdata section not found")
else:
section_va = section.VirtualAddress
section_size = section.SizeOfRawData
section_data = section.get_data(section_va, section_size)
for magic in go_magic:
if magic in section_data:
pclntab_va = section_data.index(magic) + section_va
if verify_pclntab(section, pclntab_va):
return True, get_go_version(magic)

# if not found, search in all the available sections
for magic in go_magic:
Expand All @@ -116,6 +125,32 @@ def get_if_go_and_version(pe: pefile.PE) -> Tuple[bool, str]:
pclntab_va = section_data.index(magic) + section_va
if verify_pclntab(section, pclntab_va):
return True, get_go_version(magic)

# if not found, the magic bytes may have been patched, search for common Go functions present in all Go samples including obfuscated files
# look for the .rdata section first
mr-tz marked this conversation as resolved.
Show resolved Hide resolved
try:
section = get_rdata_section(pe)
except ValueError:
logger.debug(".rdata section not found")
else:
section_va = section.VirtualAddress
section_size = section.SizeOfRawData
section_data = section.get_data(section_va, section_size)
for go_function in go_functions:
if go_function in section_data:
logger.info("Go binary found, function name %s", go_function)
return True, VERSION_UNKNOWN_OR_NA

# if not found, search in all the available sections
for section in pe.sections:
section_va = section.VirtualAddress
section_size = section.SizeOfRawData
section_data = section.get_data(section_va, section_size)
for go_function in go_functions:
if go_function in section_data:
logger.info("Go binary found, function name %s", go_function)
return True, VERSION_UNKNOWN_OR_NA

return False, VERSION_UNKNOWN_OR_NA


Expand Down
16 changes: 7 additions & 9 deletions floss/language/rust/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,19 @@
import binary2strings as b2s

from floss.results import StaticString, StringEncoding
from floss.language.utils import find_lea_xrefs, find_mov_xrefs, find_push_xrefs, get_struct_string_candidates
from floss.language.utils import (
find_lea_xrefs,
find_mov_xrefs,
find_push_xrefs,
get_rdata_section,
get_struct_string_candidates,
)

logger = logging.getLogger(__name__)

MIN_STR_LEN = 4


def get_rdata_section(pe: pefile.PE) -> pefile.SectionStructure:
mr-tz marked this conversation as resolved.
Show resolved Hide resolved
for section in pe.sections:
if section.Name.startswith(b".rdata\x00"):
return section

raise ValueError("no .rdata section found")


def fix_b2s_wide_strings(
strings: List[Tuple[str, str, Tuple[int, int], bool]], min_length: int, buffer: bytes
) -> List[Tuple[str, str, Tuple[int, int], bool]]:
Expand Down
8 changes: 8 additions & 0 deletions floss/language/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ class StructString:
length: int


def get_rdata_section(pe: pefile.PE) -> pefile.SectionStructure:
mr-tz marked this conversation as resolved.
Show resolved Hide resolved
for section in pe.sections:
if section.Name.startswith(b".rdata\x00"):
return section

raise ValueError("no .rdata section found")


def get_image_range(pe: pefile.PE) -> Tuple[VA, VA]:
"""return the range of the image in memory."""
image_base = pe.OPTIONAL_HEADER.ImageBase
Expand Down