feat: migrate sim framework from worktree to master

Migrates all 43 sim modules and 23 test files (~7.8k LOC, 686 tests)
from .worktrees/sim-framework/ into pm3py/sim/. Import fixes:
- 4 files: ..protocol/..transport → ..core.protocol/..core.transport
- trace_fmt.py: pm3py.hf_15 → pm3py.trace.ndef
- test_sim_pm3medium.py: flat imports → core.*
- test_sim_trace_fmt.py: flat imports → core.*
- Added sim Cmd entries to core/protocol.py (EML_SETMEM, SIM_TABLE_*)

751 tests passing (686 sim + 65 core).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
michael
2026-03-18 20:04:55 -07:00
parent 7fc2470b01
commit 668170457e
68 changed files with 16951 additions and 1 deletions

105
tests/test_sim_implants.py Normal file
View File

@@ -0,0 +1,105 @@
"""Tests for implant preset profiles."""
import asyncio
import pytest
from pm3py.sim.medium import SoftwareMedium
from pm3py.sim.implants import (
xEM, xNT, xM1, FlexDF, NExT,
MagicMifareClassicTag,
)
from pm3py.sim.em4100 import EM4100Reader
from pm3py.sim.iso14443a import Reader14443A, _compute_bcc
def run(coro):
return asyncio.get_event_loop().run_until_complete(coro)
class TestXEM:
def test_creates_t5577_configured_as_em4100(self):
tag = xEM(tag_id=0x1122334455)
assert tag.blocks[0] != 0 # config block set
def test_readable_as_em4100(self):
medium = SoftwareMedium()
tag = xEM(tag_id=0x1122334455)
run(medium.attach(tag))
reader = EM4100Reader(medium)
result = run(reader.read_id())
assert result is not None
assert result["tag_id"] == 0x1122334455
class TestXNT:
def test_creates_ntag216_like(self):
tag = xNT()
assert tag._total_pages >= 45 # NTAG213+ size
def test_is_type2_tag(self):
from pm3py.sim.ndef import NfcType2Tag
tag = xNT()
assert isinstance(tag, NfcType2Tag)
def test_has_7byte_uid(self):
tag = xNT()
assert len(tag._uid) == 7
class TestXM1:
def test_creates_mifare_classic_1k(self):
tag = xM1()
assert tag._size == "1k"
assert len(tag._data) == 1024
def test_default_keys_ff(self):
tag = xM1()
assert tag._keys_a[0] == b"\xFF" * 6
class TestMagicMifareClassic:
def test_gen1a_backdoor_write_block0(self):
"""Magic gen1a allows direct write to block 0."""
tag = MagicMifareClassicTag(uid=b"\x01\x02\x03\x04",
magic_type="gen1a")
run(tag.power_on())
# gen1a responds to special WUPA sequence for backdoor
assert tag.magic_type == "gen1a"
# Direct block 0 write should work
new_data = b"\xDE\xAD\xBE\xEF" + b"\x00" * 12
tag.write_block_raw(0, new_data)
assert tag.read_block_raw(0) == new_data
def test_gen2_cuid(self):
tag = MagicMifareClassicTag(uid=b"\x01\x02\x03\x04",
magic_type="gen2")
assert tag.magic_type == "gen2"
class TestFlexDF:
def test_creates_desfire(self):
from pm3py.sim.desfire import DesfireTag
tag = FlexDF()
assert isinstance(tag, DesfireTag)
def test_has_7byte_uid(self):
tag = FlexDF()
assert len(tag._uid) == 7
class TestNExT:
def test_creates_dual_frequency(self):
lf, hf = NExT(tag_id=0x1122334455)
# LF side is T5577 configured as EM4100
assert lf.blocks[0] != 0
# HF side is NfcType2Tag (xNT)
from pm3py.sim.ndef import NfcType2Tag
assert isinstance(hf, NfcType2Tag)
def test_both_sides_work(self):
lf, hf = NExT(tag_id=0xAABBCCDDEE)
# LF
lf_medium = SoftwareMedium()
run(lf_medium.attach(lf))
reader = EM4100Reader(lf_medium)
result = run(reader.read_id())
assert result["tag_id"] == 0xAABBCCDDEE