diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c05fdec..93f553f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -154,6 +154,7 @@ jobs: - name: Configure run: | + xmake lua private.xrepo clean xmake f ${{ matrix.plat.extra-configure-flags }} -a ${{ matrix.plat.arch }} -m ${{ matrix.mode }} -p ${{ matrix.plat.os }} --toolchain=${{ matrix.plat.toolchain }} -vD -y - name: Build diff --git a/src/tools/nfc-staticnested/main.cpp b/src/tools/nfc-staticnested/main.cpp index f87b9f2..48cca2b 100644 --- a/src/tools/nfc-staticnested/main.cpp +++ b/src/tools/nfc-staticnested/main.cpp @@ -12,6 +12,8 @@ #include "pwn_host.h" +#include "utility.h" + using namespace nfcpp; using namespace nfcpp::mifare; @@ -20,6 +22,10 @@ auto load_args(int argc, char* argv[]) { InputArguments args; + program.add_argument("-c", "--connstring") + .default_value("") + .store_into(args.connstring) + .help("Specify the device's connstring."); program.add_argument("-m", "--mifare-classic") .default_value("1k") .choices("mini", "1k", "2k", "4k") @@ -98,10 +104,39 @@ int main(int argc, char* argv[]) CPPTRACE_TRY { // Start libnfc lifecycle NfcContext context; - auto device = context.open_device(); + auto hack_ctx = reinterpret_cast(context.get()); + + // We do not want to scan for new devices in nfc_open. + hack_ctx->allow_autoscan = false; + + auto device = context.open_device(args.connstring); + if (!device && args.connstring.empty()) { + std::println("Scanning device..."); + + // Re-enable it. + hack_ctx->allow_autoscan = true; + hack_ctx->allow_intrusive_scan = true; + + auto connstrings = context.list_devices(); + if (connstrings.empty()) { + throw std::runtime_error("No device found."); + } + // TODO: Libc++ does not yet support C++23 std::views::enumerate + for (auto i : std::views::iota(0uz, connstrings.size())) { + std::println("{} {}", i == 0 ? "*" : "-", connstrings[i]); + } + args.connstring = connstrings[0]; + std::println( + "You can use '--connstring \"{}\"' or add it to libnfc.conf to " + "avoid duplicated scanning.", + args.connstring + ); + device = context.open_device(args.connstring); + } if (!device) { - throw std::runtime_error("No device found."); + throw std::runtime_error("Failed to open device!"); } + std::println("NFC device opened: {}", device->get_name()); auto initiator = device->as_initiator(); diff --git a/src/tools/nfc-staticnested/pwn_host.h b/src/tools/nfc-staticnested/pwn_host.h index 37dc74f..5c5c7a8 100644 --- a/src/tools/nfc-staticnested/pwn_host.h +++ b/src/tools/nfc-staticnested/pwn_host.h @@ -16,6 +16,7 @@ namespace nfcpp { struct InputArguments { + std::string connstring; mifare::MifareCard type; bool force_detect_distance; std::string dump_keys; diff --git a/src/utility.h b/src/utility.h index 842b856..2b19f08 100644 --- a/src/utility.h +++ b/src/utility.h @@ -85,4 +85,24 @@ constexpr auto start_block_sequence(MifareCard type) { } // namespace mifare +namespace libhack { + +typedef char nfc_connstring[1024]; + +struct nfc_user_defined_device { + char name[256]; + nfc_connstring connstring; + bool optional; +}; + +struct nfc_context { + bool allow_autoscan; + bool allow_intrusive_scan; + uint32_t log_level; + struct nfc_user_defined_device user_defined_devices[4]; + unsigned int user_defined_device_count; +}; + +} // namespace libhack + } // namespace nfcpp