extractors: ida: move os extraction to global module

This commit is contained in:
William Ballenthin
2021-08-17 08:57:27 -06:00
parent 98c00bd8b1
commit 0065876702
2 changed files with 46 additions and 24 deletions

View File

@@ -5,10 +5,7 @@
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and limitations under the License.
import contextlib
import idaapi
import ida_loader
import capa.ida.helpers
import capa.features.extractors.elf
@@ -17,26 +14,9 @@ import capa.features.extractors.ida.insn
import capa.features.extractors.ida.global_
import capa.features.extractors.ida.function
import capa.features.extractors.ida.basicblock
from capa.features.common import OS, OS_WINDOWS
from capa.features.extractors.base_extractor import FeatureExtractor
def extract_os():
format_name = ida_loader.get_file_type_name()
if "PE" in format_name:
yield OS(OS_WINDOWS), 0x0
elif "ELF" in format_name:
with contextlib.closing(capa.ida.helpers.IDAIO()) as f:
os = capa.features.extractors.elf.detect_elf_os(f)
yield OS(os), 0x0
else:
raise NotImplementedError("file format: %s", format_name)
class FunctionHandle:
"""this acts like an idaapi.func_t but with __int__()"""
@@ -80,7 +60,7 @@ class IdaFeatureExtractor(FeatureExtractor):
def __init__(self):
super(IdaFeatureExtractor, self).__init__()
self.global_features = []
self.global_features.extend(extract_os())
self.global_features.extend(capa.features.extractors.ida.global_.extract_os())
self.global_features.extend(capa.features.extractors.ida.global_.extract_arch())
def get_base_address(self):

View File

@@ -1,7 +1,43 @@
import idaapi
import logging
import contextlib
import idaapi
import ida_loader
import capa.ida.helpers
import capa.features.extractors.elf
from capa.features.common import OS, OS_WINDOWS
from capa.features.common import ARCH_I386, ARCH_AMD64, Arch
logger = logging.getLogger(__name__)
def extract_os():
format_name = ida_loader.get_file_type_name()
if "PE" in format_name:
yield OS(OS_WINDOWS), 0x0
elif "ELF" in format_name:
with contextlib.closing(capa.ida.helpers.IDAIO()) as f:
os = capa.features.extractors.elf.detect_elf_os(f)
yield OS(os), 0x0
else:
# we likely end up here:
# 1. handling shellcode, or
# 2. handling a new file format (e.g. macho)
#
# for (1) we can't do much - its shellcode and all bets are off.
# we could maybe accept a futher CLI argument to specify the OS,
# but i think this would be rarely used.
# rules that rely on OS conditions will fail to match on shellcode.
#
# for (2), this logic will need to be updated as the format is implemented.
logger.debug("unsupported file format: %s, will not guess OS", format_name)
return
def extract_arch():
info = idaapi.get_inf_structure()
@@ -10,6 +46,12 @@ def extract_arch():
elif info.procName == "metapc" and info.is_32bit():
yield Arch(ARCH_I386), 0x0
elif info.procName == "metapc":
raise NotImplementedError("unsupported architecture: non-32-bit nor non-64-bit intel")
logger.debug("unsupported architecture: non-32-bit nor non-64-bit intel")
return
else:
raise NotImplementedError("unsupported architecture: %s" % (info.procName))
# we likely end up here:
# 1. handling a new architecture (e.g. aarch64)
#
# for (1), this logic will need to be updated as the format is implemented.
logger.debug("unsupported architecture: %s", info.procName)
return