scapy 사용시에는 반드시 IDA를 관리자 권한으로 실행할 것


오류 발견

처음 오류는

WinPcap을 설치하지 않았다고 해서 설치하려는데 다음과 같은 오류 발생

 

 

이를 찾아보니까 Windows 10부터 지원하지 않는다고 공식 사이트에서 나와있어서 최신 Npcap을 설치 하고 실행해보니 다음과 같이 오류 발생

 

 

이 오류는 winpcap이 설치되어 있지 않다고 나와 있는데 (winpcap is not installed) Npcap이 제대로 설치가 안되었거나 무슨 문제가 있는 것이 분명하다고 생각했고 천천히 와이어샤크 Windows ARM 버전용으로 설치를 진행하였다. (MAC OS apple silicon, windows 11)

Npcap의 최신 버전인 1.79버전이 아닌 1.78이 자동으로 설치되도록 나와있어서 1.78로 설치를 진행함

 

이후에도 같은 에러가 나타남


문제 원인

문제의 원인은 IDA와 NPCAP이 아닌 Python에 문제가 있었다.

https://bugs.python.org/issue41100

 

Issue 41100: Support macOS 11 and Apple Silicon Macs - Python tracker

Issue41100 Created on 2020-06-24 11:51 by ronaldoussoren, last changed 2022-04-11 14:59 by admin. This issue is now closed. File name Uploaded Description Edit build.log harlantc, 2021-04-15 15:38 build log for ARM M1 Big Sur URL Status Linked Edit PR 2111

bugs.python.org

위 사이트에서 해당 오류를 확인해 볼 수 있는데 요약하자면

애플 실리콘 아키텍처에서 3.10, 3.9, 3.8 버전의 파이썬을 사용하면 라이브러리를 제대로 가져오지 못하는 문제가 발생(컴파일 오류 였다.)

즉 파이썬을 3.11 이상인 최신버전을 이용하면 해결이 되는 문제였다.

따로 윈도우 데스크탑에서 똑같은 환경으로 테스트 해보니 정상 작동이 되었다.

 

그럼 애플 실리콘 윈도우에선 안되는 걸까?

 


해결 방법

IDA Pro 7.6버전은 공식적으로 3.9.0~1 버전까지만 지원된다.

1. IDA Pro 7.6은 3.9.1까지만 지원하여 파이썬 버전을 올릴 수 없으니 IDA Pro 버전을 올리면 된다. IDA Pro 올리면 자연스레 Python도 최신 버전을 설치하게 된다.

2. 그냥 인텔 아키텍처 사용 -> 너무 간단하지만 확실하다

3. 공유? 라이브러리 설정 <- 이부분은 저도 잘 모르겠습니다. 1번과 2번으로 원만한 합의 보시길..

 

 

 

 

 

 

 

추가적으로 해결 방법이 존재하신다면 피드백 주시면 감사하겠습니다.

 

 

 

 

 

1. 간단한 인터프리터 예제

2. 간단한 실제 사용 예제

 

 

1. 간단한 인터프리터 예제

1.1 현재 위치 주소

1.2 최소 최대 주소

 

1.1 here() : 현재 위치의 주소를 리턴한다.(현재 커서에 있는 위치)

hex(here())
here()

 

1.2 idc.get_inf_attr(idc.INF_최대,최소_EA) : IDA 데이터 베이스에서 바이너리의 전체 범위에 대한 최대와 최소 주소값 반환

idc.get_inf_attr(idc.INF_MIN_EA)
idc.get_inf_attr(idc.INF_MAX_EA)

 

 

2. 간단한 실제 사용 예제

2.1 세그먼트별 주소 출력 예제

2.2 함수 목록 출력 예제

2.3 전체 명령어 추출 스크립트 예제

2.4 전체 주석 추출 스크립트 예제

2.5 IP 주소와 도메인 이름 추출 예제

 

2.1 세그먼트별 주소 출력 예제

# 세그먼트의 개수와 세부 정보를 출력
for n in range(idaapi.get_segm_qty()):
    seg = idaapi.getnseg(n)  # n번째 세그먼트 정보를 가져옴
    if seg:
            # 세그먼트 이름, 시작 주소, 끝 주소를 가져와서 출력
        segname = idc.get_segm_name(seg.start_ea)
        start_address = seg.start_ea
        end_address = seg.end_ea
        print(f"Segment Name: {segname}, Start: {hex(start_address)}, End:{hex(end_address)}")

 

2.2 함수 목록 출력 예제

import idautils

def print_functions():
    # 모든 함수들을 순회
    for func in idautils.Functions():
        # 함수의 시작 주소를 가져옴
        start_address = func
        # 함수의 이름을 가져옴
        func_name = ida_funcs.get_func_name(start_address)
        
        # 함수의 시작 주소와 이름을 출력
        print(f"Function Name: {func_name}, Start Address: {hex(start_address)}")

if __name__ == "__main__":
    print_functions()

 

 

2.3 전체 명령어 추출 스크립트 예제

import idautils
import idc

def find_instructions_with_comments(keyword):
    """
    전체 바이너리에서 특정 명령어를 포함하는 코드를 찾아 그 코드의 주소, 명령어, 주석을 출력합니다.
    :param keyword: 검색할 명령어 키워드
    """
    print(f"Searching for instructions containing '{keyword}':")
    print("-" * 50)
    for seg in idautils.Segments():
        for head in idautils.Heads(idc.get_segm_start(seg), idc.get_segm_end(seg)):
            disasm = idc.GetDisasm(head)
            if keyword in disasm:
                # 명령어에 키워드가 포함되어 있는 경우
                comment = idc.get_cmt(head, 0)  # 일반 주석
                rcomment = idc.get_cmt(head, 1) # 반복 주석
                print(f"Address: {hex(head)} - Instruction: {disasm}")
                if comment:
                    print(f"  Comment: {comment}")
                if rcomment:
                    print(f"  Repeatable Comment: {rcomment}")
                print("-" * 40)

if __name__ == "__main__":
    # 예를 들어, 'call' 명령어를 포함하는 코드를 찾으려면
    find_instructions_with_comments("call")

 

 

2.4 전체 주석 추출 스크립트 예제

import idautils
import idc

def extract_all_comments():
    print("Extracting all comments from the binary:")
    print("-" * 50)
    for seg in idautils.Segments():
        for head in idautils.Heads(idc.get_segm_start(seg), idc.get_segm_end(seg)):
            # 주석 가져오기
            comment = idc.get_cmt(head, 0)  # 일반 주석
            rcomment = idc.get_cmt(head, 1) # 반복 주석
            if comment or rcomment:
                print(f"Address: {hex(head)}")
                if comment:
                    print(f"  Comment: {comment}")
                if rcomment:
                    print(f"  Repeatable Comment: {rcomment}")
                print("-" * 40)

if __name__ == "__main__":
    extract_all_comments()

 

2.5 IP 주소와 도메인 이름 추출 예제

import idautils
import idc
import re

def find_network_iocs():
    """
    전체 바이너리에서 네트워크 관련 IOC를 찾아 출력합니다. 이에는 IP 주소와 도메인 이름이 포함됩니다.
    """
    ip_pattern = re.compile(r'\b(?:\d{1,3}\.){3}\d{1,3}\b')
    domain_pattern = re.compile(r'\b(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}\b')
    print("Searching for Network IOCs (IP Addresses and Domain Names):")
    print("-" * 60)
    for seg in idautils.Segments():
        for head in idautils.Heads(idc.get_segm_start(seg), idc.get_segm_end(seg)):
            disasm = idc.GetDisasm(head)
            comments = idc.get_cmt(head, 0)  # 일반 주석
            rcomments = idc.get_cmt(head, 1) # 반복 주석
            strings = idc.get_strlit_contents(head)
            search_text = f"{disasm} {comments if comments else ''} {rcomments if rcomments else ''} {strings if strings else ''}"

            ip_matches = ip_pattern.findall(search_text)
            domain_matches = domain_pattern.findall(search_text)
            if ip_matches or domain_matches:
                print(f"Address: {hex(head)}")
                if ip_matches:
                    print(f"  IP Addresses: {', '.join(ip_matches)}")
                if domain_matches:
                    print(f"  Domain Names: {', '.join(domain_matches)}")
                print("-" * 60)

if __name__ == "__main__":
    find_network_iocs()

유의미한 정보 추출

 

 

 

 

 

 

 

 

 

 

 

+ Recent posts