diff --git a/Makefile.defs b/Makefile.defs index 16d5ec9e5..48567214b 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -27,7 +27,7 @@ LD = g++ SH = sh BASH = bash PERL = perl -CCC =foo +SWIG = swig CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null|sed 's/\..*//') CC_VERSION := $(or $(strip $(CC_VERSION)),0) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index a70b9b953..806c63091 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1301,7 +1301,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) { // We need to listen to the high-frequency, peak-detected path. iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); - iso14a_set_timeout(201400); // 106 * 19ms default + iso14a_set_timeout(201400); // 106 * 19ms default *100? int len = 0; @@ -2903,9 +2903,11 @@ void ReaderIso14443a(PacketCommandNG *c) { goto OUT; } } - - if ((param & ISO14A_SET_TIMEOUT)) + uint32_t save_iso14a_timeout = 0; + if ((param & ISO14A_SET_TIMEOUT)) { + save_iso14a_timeout = iso14a_get_timeout(); iso14a_set_timeout(timeout); + } if ((param & ISO14A_APDU)) { uint8_t res; @@ -2969,6 +2971,10 @@ void ReaderIso14443a(PacketCommandNG *c) { if ((param & ISO14A_REQUEST_TRIGGER)) iso14a_set_trigger(false); + if ((param & ISO14A_SET_TIMEOUT)) { + iso14a_set_timeout(save_iso14a_timeout); + } + if ((param & ISO14A_NO_DISCONNECT)) return; diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 77181f8bf..92888a0fa 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -188,7 +188,6 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/emv/crypto.c ${PM3_ROOT}/client/src/emv/crypto_polarssl.c ${PM3_ROOT}/client/src/emv/dol.c - ${PM3_ROOT}/client/src/emv/dump.c ${PM3_ROOT}/client/src/emv/emv_pk.c ${PM3_ROOT}/client/src/emv/emv_pki.c ${PM3_ROOT}/client/src/emv/emv_pki_priv.c @@ -426,7 +425,7 @@ if (SKIPPYTHON EQUAL 1) else (SKIPPYTHON EQUAL 1) if (PYTHON3EMBED_FOUND) message(STATUS "Python3 library: Python3 embed found, enabled") - elseif (PYTHON_FOUND) + elseif (PYTHON3_FOUND) message(STATUS "Python3 library: Python3 found, enabled") else (PYTHON3EMBED_FOUND) message(STATUS "Python3 library: Python3 not found, disabled") @@ -456,6 +455,28 @@ else (SKIPWHEREAMISYSTEM EQUAL 1) message(STATUS "Whereami library: system library not found, using local library") endif (WHEREAMI_FOUND) endif (SKIPWHEREAMISYSTEM EQUAL 1) + +# Lua SWIG +if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) + set (TARGET_SOURCES + ${PM3_ROOT}/client/src/pm3_luawrap.c + ${TARGET_SOURCES}) + add_definitions(-DHAVE_LUA_SWIG) + message(STATUS "Lua SWIG: wrapper found") +endif (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) + +# Python SWIG +if (NOT SKIPPYTHON EQUAL 1) + if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) + if (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) + set (TARGET_SOURCES + ${PM3_ROOT}/client/src/pm3_pywrap.c + ${TARGET_SOURCES}) + add_definitions(-DHAVE_PYTHON_SWIG) + message(STATUS "Python SWIG: wrapper found") + endif (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) + endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) +endif (NOT SKIPPYTHON EQUAL 1) message(STATUS "===================================================================") add_executable(proxmark3 diff --git a/client/Makefile b/client/Makefile index 333cbad08..2f0899bc8 100644 --- a/client/Makefile +++ b/client/Makefile @@ -285,6 +285,19 @@ ifneq ($(SKIPREADLINE),1) READLINE_FOUND = 1 endif +######## +# SWIG # +######## + +ifneq ("$(wildcard src/pm3_luawrap.c)","") + SWIG_LUA_FOUND = 1 +endif +ifeq ($(PYTHON_FOUND),1) + ifneq ("$(wildcard src/pm3_pywrap.c)","") + SWIG_PYTHON_FOUND = 1 + endif +endif + ####################################################################################################### CFLAGS ?= $(DEFCFLAGS) # We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: @@ -315,6 +328,12 @@ ifeq ($(PYTHON_FOUND),1) PM3CFLAGS += -DHAVE_PYTHON endif +ifeq ($(SWIG_LUA_FOUND),1) + PM3CFLAGS += -DHAVE_LUA_SWIG +endif +ifeq ($(SWIG_PYTHON_FOUND),1) + PM3CFLAGS += -DHAVE_PYTHON_SWIG +endif CXXFLAGS ?= -Wall -Werror -O3 PM3CXXFLAGS = $(CXXFLAGS) @@ -414,6 +433,13 @@ else endif endif +ifeq ($(SWIG_LUA_FOUND),1) + $(info Lua SWIG: wrapper found) +endif +ifeq ($(SWIG_PYTHON_FOUND),1) + $(info Python SWIG: wrapper found) +endif + $(info compiler version: $(shell $(CC) --version|head -n 1)) $(info ===================================================================) @@ -506,7 +532,6 @@ SRCS = aiddesfire.c \ emv/crypto.c\ emv/crypto_polarssl.c\ emv/dol.c \ - emv/dump.c \ emv/emv_pk.c\ emv/emv_pki.c\ emv/emv_pki_priv.c\ @@ -573,6 +598,16 @@ SRCS += bucketsort.c \ parity.c \ util_posix.c +# swig + +SWIGSRCS = +ifeq ($(SWIG_LUA_FOUND),1) + SWIGSRCS += pm3_luawrap.c +endif +ifeq ($(SWIG_PYTHON_FOUND),1) + SWIGSRCS += pm3_pywrap.c +endif + # gui ifeq ($(QT_FOUND),1) CXXSRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp @@ -586,6 +621,7 @@ ifeq ($(platform),Darwin) endif OBJS = $(SRCS:%.c=$(OBJDIR)/%.o) +OBJS += $(SWIGSRCS:%.c=$(OBJDIR)/%.o) OBJS += $(CXXSRCS:%.cpp=$(OBJDIR)/%.o) OBJS += $(OBJCSRCS:%.m=$(OBJDIR)/%.o) @@ -650,6 +686,7 @@ endif ifneq (,$(INSTALLSHARE)) $(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) $(Q)$(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) + $(Q)$(CP) src/pm3.py $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)/pyscripts endif @true @@ -712,6 +749,18 @@ ifneq ($(WHEREAMI_FOUND),1) $(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) all endif +######## +# SWIG # +######## + +src/pm3_luawrap.c: pm3.i + $(info [=] GEN $@) + $(Q)$(SWIG) -lua -o $@ $< + +src/pm3_pywrap.c: pm3.i + $(info [=] GEN $@) + $(Q)$(SWIG) -python -o $@ $< + ######## # misc # ######## @@ -726,6 +775,14 @@ src/version.c: default_version.c # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) +# SWIG files emit a number of warnings, we've to ignore them +%wrap.o: %wrap.c +$(OBJDIR)/%wrap.o : %wrap.c $(OBJDIR)/%.d + $(info [-] CC $<) + $(Q)$(MKDIR) $(dir $@) + $(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -Wno-missing-prototypes -Wno-missing-declarations -Wno-missing-field-initializers -c -o $@ $< + $(Q)$(POSTCOMPILE) + %.o: %.c $(OBJDIR)/%.o : %.c $(OBJDIR)/%.d $(info [-] CC $<) @@ -748,6 +805,7 @@ $(OBJDIR)/%.o : %.m $(OBJDIR)/%.d $(Q)$(POSTCOMPILE) DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(SRCS)) \ + $(patsubst %wrap.c, $(OBJDIR)/%.d, $(SWIGSRCS)) \ $(patsubst %.cpp, $(OBJDIR)/%.d, $(CXXSRCS)) \ $(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) diff --git a/client/android/CMakeLists.txt b/client/android/CMakeLists.txt index 3df923c3c..f459748b2 100644 --- a/client/android/CMakeLists.txt +++ b/client/android/CMakeLists.txt @@ -66,7 +66,6 @@ add_library(pm3rrg_rdv4 SHARED ${PM3_ROOT}/client/src/emv/crypto.c ${PM3_ROOT}/client/src/emv/crypto_polarssl.c ${PM3_ROOT}/client/src/emv/dol.c - ${PM3_ROOT}/client/src/emv/dump.c ${PM3_ROOT}/client/src/emv/emv_pk.c ${PM3_ROOT}/client/src/emv/emv_pki.c ${PM3_ROOT}/client/src/emv/emv_pki_priv.c diff --git a/client/deps/cliparser/cliparser.c b/client/deps/cliparser/cliparser.c index f2d9fa8fd..f55b7a8f7 100644 --- a/client/deps/cliparser/cliparser.c +++ b/client/deps/cliparser/cliparser.c @@ -35,8 +35,7 @@ int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) { *ctx = malloc(sizeof(CLIParserContext)); if (!*ctx) { - printf("ERROR: Insufficient memory\n"); - fflush(stdout); + PrintAndLogEx(ERR, "ERROR: Insufficient memory\n"); return 2; } (*ctx)->argtable = NULL; @@ -220,16 +219,15 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int res = param_gethex_to_eol((char *)tmpstr, 0, data, maxdatalen, datalen); switch (res) { case 1: - printf("Parameter error: Invalid HEX value\n"); + PrintAndLogEx(ERR, "Parameter error: Invalid HEX value\n"); break; case 2: - printf("Parameter error: parameter too large\n"); + PrintAndLogEx(ERR, "Parameter error: parameter too large\n"); break; case 3: - printf("Parameter error: Hex string must have EVEN number of digits\n"); + PrintAndLogEx(ERR, "Parameter error: Hex string must have EVEN number of digits\n"); break; } - fflush(stdout); return res; } @@ -246,8 +244,7 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int int len = strlen(argstr->sval[i]); if (len > ((sizeof(tmpstr) / 2) - ibuf)) { - printf("Parameter error: string too long (%i chars), expect MAX %zu chars\n", len + ibuf, (sizeof(tmpstr) / 2)); - fflush(stdout); + PrintAndLogEx(ERR, "Parameter error: string too long (%i chars), expect MAX %zu chars\n", len + ibuf, (sizeof(tmpstr) / 2)); return 2; } @@ -263,8 +260,7 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int return 0; if (ibuf > maxdatalen) { - printf("Parameter error: string too long (%i chars), expected MAX %i chars\n", ibuf, maxdatalen); - fflush(stdout); + PrintAndLogEx(ERR, "Parameter error: string too long (%i chars), expected MAX %i chars\n", ibuf, maxdatalen); return 2; } diff --git a/client/experimental_client_with_swig/.gitignore b/client/experimental_client_with_swig/.gitignore deleted file mode 100644 index 567609b12..000000000 --- a/client/experimental_client_with_swig/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build/ diff --git a/client/experimental_client_with_swig/00make_swig.sh b/client/experimental_client_with_swig/00make_swig.sh index 6c752d024..626a87986 100755 --- a/client/experimental_client_with_swig/00make_swig.sh +++ b/client/experimental_client_with_swig/00make_swig.sh @@ -1,4 +1,5 @@ #!/bin/bash -swig -lua -o ../src/pm3_luawrap.c ../src/pm3.i -swig -python -o ../src/pm3_pywrap.c ../src/pm3.i +cd .. +make src/pm3_luawrap.c +make src/pm3_pywrap.c diff --git a/client/experimental_client_with_swig/01make_client.sh b/client/experimental_client_with_swig/01make_client_cmake.sh similarity index 92% rename from client/experimental_client_with_swig/01make_client.sh rename to client/experimental_client_with_swig/01make_client_cmake.sh index 667a6351e..48a5bd4f2 100755 --- a/client/experimental_client_with_swig/01make_client.sh +++ b/client/experimental_client_with_swig/01make_client_cmake.sh @@ -1,5 +1,6 @@ #!/bin/bash +cd .. rm -rf build mkdir build ( @@ -7,4 +8,3 @@ mkdir build cmake .. make -j ) - diff --git a/client/experimental_client_with_swig/01make_client_continue.sh b/client/experimental_client_with_swig/01make_client_cmake_continue.sh similarity index 86% rename from client/experimental_client_with_swig/01make_client_continue.sh rename to client/experimental_client_with_swig/01make_client_cmake_continue.sh index 4c85bb9dc..abd022c97 100755 --- a/client/experimental_client_with_swig/01make_client_continue.sh +++ b/client/experimental_client_with_swig/01make_client_cmake_continue.sh @@ -1,5 +1,6 @@ #!/bin/bash +cd .. ( cd build make -j diff --git a/client/experimental_client_with_swig/01make_client_makefile.sh b/client/experimental_client_with_swig/01make_client_makefile.sh new file mode 100755 index 000000000..93ab04ca2 --- /dev/null +++ b/client/experimental_client_with_swig/01make_client_makefile.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +cd .. +make -j diff --git a/client/experimental_client_with_swig/02a_run_test_lua.sh b/client/experimental_client_with_swig/02a_run_test_lua.sh index bca993a44..8e04b30f5 100755 --- a/client/experimental_client_with_swig/02a_run_test_lua.sh +++ b/client/experimental_client_with_swig/02a_run_test_lua.sh @@ -1,3 +1,3 @@ #!/bin/bash -build/proxmark3 /dev/ttyACM0 -c "script run testembedded.lua" +../../pm3 -c "script run testembedded.lua" diff --git a/client/experimental_client_with_swig/02b_run_test_py.sh b/client/experimental_client_with_swig/02b_run_test_py.sh index fcaf4c8f8..e613a6adf 100755 --- a/client/experimental_client_with_swig/02b_run_test_py.sh +++ b/client/experimental_client_with_swig/02b_run_test_py.sh @@ -1,7 +1,3 @@ #!/bin/bash -#/usr/local/lib/python3/dist-packages/pm3.py -#/usr/lib/python3/dist-packages/pm3.py - -# need access to pm3.py -PYTHONPATH=../src build/proxmark3 /dev/ttyACM0 -c "script run testembedded.py" +../../pm3 -c "script run testembedded.py" diff --git a/client/experimental_client_with_swig/02b_run_test_py_grabber.sh b/client/experimental_client_with_swig/02b_run_test_py_grabber.sh new file mode 100755 index 000000000..8aed5b8bb --- /dev/null +++ b/client/experimental_client_with_swig/02b_run_test_py_grabber.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +../../pm3 -c "script run testembedded_grab.py" -i diff --git a/client/experimental_client_with_swig/CMakeLists.txt b/client/experimental_client_with_swig/CMakeLists.txt deleted file mode 100644 index a871e528e..000000000 --- a/client/experimental_client_with_swig/CMakeLists.txt +++ /dev/null @@ -1,573 +0,0 @@ -# Usage: -# mkdir build -# cd build -# cmake .. (see below for options) -# make (VERBOSE=1 if needed) -# -# MINGW: -# On ProxSpace 3.4: -# cmake -G"MSYS Makefiles" .. -# On Proxspace 3.3 or less, you need to install cmake: -# pacman -S mingw-w64-x86_64-cmake -# /mingw64/bin/cmake -G"MSYS Makefiles" .. -# -# Android cross-compilation: (ANDROID_ABI=arm64-v8a for a 64b version) -# cmake \ -# -DCMAKE_TOOLCHAIN_FILE=/build/cmake/android.toolchain.cmake \ -# -DANDROID_ABI=armeabi-v7a \ -# -DANDROID_NATIVE_API_LEVEL=android-19 \ -# -DSKIPBT=1 -DSKIPPYTHON=1 -DSKIPPTHREAD=1 .. - -message(STATUS "CMake ${CMAKE_VERSION}") -cmake_minimum_required(VERSION 3.10) -project(proxmark3) -SET (PM3_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..) - -if(CMAKE_VERSION VERSION_LESS "3.7.0") - set(CMAKE_INCLUDE_CURRENT_DIR ON) -endif() - -find_package(PkgConfig) - -if (NOT SKIPQT EQUAL 1) - if(APPLE AND EXISTS /usr/local/opt/qt5) - # Homebrew installs Qt5 (up to at least 5.11.0) in - # /usr/local/qt5. Ensure that it can be found by CMake - # since it is not in the default /usr/local prefix. - # Add it to PATHS so that it doesn't override the - # CMAKE_PREFIX_PATH environment variable. - # QT_FIND_PACKAGE_OPTIONS should be passed to find_package, - # e.g. find_package(Qt5Core ${QT_FIND_PACKAGE_OPTIONS}) - list(APPEND QT_FIND_PACKAGE_OPTIONS PATHS /usr/local/opt/qt5) - endif(APPLE AND EXISTS /usr/local/opt/qt5) - set(QT_PACKAGELIST - Qt5Core - Qt5Widgets - Qt5Gui - ) - set(Qt5_FOUND ON) - foreach(_qt_package IN LISTS QT_PACKAGELIST) - find_package(${_qt_package} QUIET ${QT_FIND_PACKAGE_OPTIONS}) - set(Qt5_LIBRARIES ${${_qt_package}_LIBRARIES} ${Qt5_LIBRARIES}) - if(NOT ${_qt_package}_FOUND) - set(Qt5_FOUND OFF) - endif(NOT ${_qt_package}_FOUND) - endforeach() -endif (NOT SKIPQT EQUAL 1) - -if (NOT SKIPBT EQUAL 1) - pkg_search_module(BLUEZ QUIET bluez) -endif (NOT SKIPBT EQUAL 1) - -if (NOT SKIPPYTHON EQUAL 1) - pkg_search_module(PYTHON3 QUIET python3) - pkg_search_module(PYTHON3EMBED QUIET python3-embed) -endif (NOT SKIPPYTHON EQUAL 1) - -# If cross-compiled, we need to init source and build. -if (CMAKE_TOOLCHAIN_FILE) - set(CFLAGS_EXTERNAL_LIB "CFLAGS=--target=${CMAKE_C_COMPILER_TARGET} -w") - set(EMBED_READLINE ON) - set(EMBED_BZIP2 ON) -endif (CMAKE_TOOLCHAIN_FILE) - -if (EMBED_READLINE OR EMBED_BZIP2) - include(ExternalProject) -endif (EMBED_READLINE OR EMBED_BZIP2) - -if (NOT SKIPREADLINE EQUAL 1) - if (APPLE) - find_path(READLINE_INCLUDE_DIRS readline/readline.h /usr/local/opt/readline/include /opt/local/include /opt/include /usr/local/include /usr/include NO_DEFAULT_PATH) - find_library(READLINE_LIBRARIES readline /usr/local/opt/readline/lib /opt/local/lib /opt/lib /usr/local/lib /usr/lib NO_DEFAULT_PATH) - endif (APPLE) - if (EMBED_READLINE) - ExternalProject_Add(ncurses - URL http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz - PREFIX deps/ncurses - DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/ncurses - CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --disable-database --with-fallbacks=ansi-generic,ansi-mini,color_xterm,dtterm,dumb,Eterm,Eterm-256color,Eterm-88color,eterm-color,gnome,gnome-256color,guru,hurd,iTerm.app,konsole,konsole-16color,konsole-256color,konsole-base,konsole-linux,konsole-solaris,konsole-vt100,kterm,kterm-color,linux,linux-16color,linux-basic,mac,mlterm,mlterm-256color,mrxvt,mrxvt-256color,mterm,mterm-ansi,mvterm,nsterm,nsterm-16color,nsterm-256color,pty,putty,putty-256color,putty-vt100,rxvt,rxvt-16color,rxvt-256color,rxvt-88color,rxvt-basic,rxvt-color,screen,screen-16color,screen-256color,simpleterm,st-16color,st-256color,st52,st52-color,stv52,tt,tt52,unknown,vt100,vt102,vte,vte-256color,xterm,xterm-16color,xterm-256color,xterm-88color,xterm-basic,xterm-bold,xterm-color,xterm-utf8,xterm-vt220,xterm-vt52,xterm1,xtermc,xtermm --enable-termcap --without-ada --without-debug --without-dlsym --without-gpm --without-develop --without-tests --without-cxx-binding --with-termlib - BUILD_IN_SOURCE ON - BUILD_COMMAND make libs - INSTALL_COMMAND "" - LOG_DOWNLOAD ON - ) - ExternalProject_Add_StepTargets(ncurses configure build install) - - ExternalProject_Add(readline - URL ftp://ftp.gnu.org/gnu/readline/readline-7.0.tar.gz - PREFIX deps/readline - DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline - CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static - BUILD_IN_SOURCE ON - BUILD_COMMAND make - INSTALL_COMMAND "" - LOG_DOWNLOAD ON - ) - ExternalProject_Add_StepTargets(readline configure build install) - set(READLINE_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/) - set(READLINE_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/readline/src/readline/libreadline.a ${CMAKE_CURRENT_BINARY_DIR}/deps/ncurses/src/ncurses/lib/libtinfo.a) - else (EMBED_READLINE) - find_path(READLINE_INCLUDE_DIRS readline/readline.h) - find_library(READLINE_LIBRARIES readline) - endif (EMBED_READLINE) - if (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES) - set(READLINE_FOUND ON) - endif (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES) -endif (NOT SKIPREADLINE EQUAL 1) - -if (NOT SKIPJANSSONSYSTEM EQUAL 1) - pkg_check_modules(PC_JANSSON QUIET jansson) - find_path(JANSSON_INCLUDE_DIRS - NAMES jansson.h - HINTS ${PC_JANSSON_INCLUDEDIR} ${PC_JANSSON_INCLUDE_DIRS}) - find_library(JANSSON_LIBRARIES - NAMES jansson libjansson - HINTS ${PC_JANSSON_LIBDIR} ${PC_JANSSON_LIBRARY_DIRS}) - if (JANSSON_INCLUDE_DIRS AND JANSSON_LIBRARIES) - set(JANSSON_FOUND ON) - endif (JANSSON_INCLUDE_DIRS AND JANSSON_LIBRARIES) -endif (NOT SKIPJANSSONSYSTEM EQUAL 1) - -if(EMBED_BZIP2) - set(BZIP2_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2) - ExternalProject_Add(bzip2 - GIT_REPOSITORY https://android.googlesource.com/platform/external/bzip2 - GIT_TAG platform-tools-30.0.2 - PREFIX deps/bzip2 - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/bzip2 - CONFIGURE_COMMAND mkdir -p ${BZIP2_BUILD_DIR} && git archive --format tar HEAD | tar -C ${BZIP2_BUILD_DIR} -x - BUILD_IN_SOURCE ON - BUILD_COMMAND make -C ${BZIP2_BUILD_DIR} -j4 CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} libbz2.a - INSTALL_COMMAND "" - LOG_DOWNLOAD ON - ) - ExternalProject_Add_StepTargets(bzip2 configure build install) - set(BZIP2_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2) - set(BZIP2_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2/libbz2.a) - set(BZIP2_FOUND ON) -else(EMBED_BZIP2) - find_package (BZip2 REQUIRED) -endif(EMBED_BZIP2) - -if (NOT SKIPWHEREAMISYSTEM EQUAL 1) - find_path(WHEREAMI_INCLUDE_DIRS whereami.h) - find_library(WHEREAMI_LIBRARIES whereami) - if (WHEREAMI_INCLUDE_DIRS AND WHEREAMI_LIBRARIES) - set(WHEREAMI_FOUND ON) - endif (WHEREAMI_INCLUDE_DIRS AND WHEREAMI_LIBRARIES) -endif (NOT SKIPWHEREAMISYSTEM EQUAL 1) - -add_subdirectory(${PM3_ROOT}/client/deps deps) - -set (TARGET_SOURCES - ${PM3_ROOT}/common/commonutil.c - ${PM3_ROOT}/common/util_posix.c - ${PM3_ROOT}/common/parity.c - ${PM3_ROOT}/common/bucketsort.c - ${PM3_ROOT}/common/crapto1/crapto1.c - ${PM3_ROOT}/common/crapto1/crypto1.c - ${PM3_ROOT}/common/crc.c - ${PM3_ROOT}/common/crc16.c - ${PM3_ROOT}/common/crc32.c - ${PM3_ROOT}/common/crc64.c - ${PM3_ROOT}/common/lfdemod.c - ${PM3_ROOT}/common/legic_prng.c - ${PM3_ROOT}/common/iso15693tools.c - ${PM3_ROOT}/common/cardhelper.c - ${PM3_ROOT}/common/generator.c - ${PM3_ROOT}/client/src/crypto/asn1dump.c - ${PM3_ROOT}/client/src/crypto/asn1utils.c - ${PM3_ROOT}/client/src/crypto/libpcrypto.c - ${PM3_ROOT}/client/src/emv/test/cda_test.c - ${PM3_ROOT}/client/src/emv/test/crypto_test.c - ${PM3_ROOT}/client/src/emv/test/cryptotest.c - ${PM3_ROOT}/client/src/emv/test/dda_test.c - ${PM3_ROOT}/client/src/emv/test/sda_test.c - ${PM3_ROOT}/client/src/emv/apduinfo.c - ${PM3_ROOT}/client/src/emv/cmdemv.c - ${PM3_ROOT}/client/src/emv/crypto.c - ${PM3_ROOT}/client/src/emv/crypto_polarssl.c - ${PM3_ROOT}/client/src/emv/dol.c - ${PM3_ROOT}/client/src/emv/dump.c - ${PM3_ROOT}/client/src/emv/emv_pk.c - ${PM3_ROOT}/client/src/emv/emv_pki.c - ${PM3_ROOT}/client/src/emv/emv_pki_priv.c - ${PM3_ROOT}/client/src/emv/emv_roca.c - ${PM3_ROOT}/client/src/emv/emv_tags.c - ${PM3_ROOT}/client/src/emv/emvcore.c - ${PM3_ROOT}/client/src/emv/emvjson.c - ${PM3_ROOT}/client/src/emv/tlv.c - ${PM3_ROOT}/client/src/fido/additional_ca.c - ${PM3_ROOT}/client/src/fido/cbortools.c - ${PM3_ROOT}/client/src/fido/cose.c - ${PM3_ROOT}/client/src/fido/fidocore.c - ${PM3_ROOT}/client/src/loclass/cipher.c - ${PM3_ROOT}/client/src/loclass/cipherutils.c - ${PM3_ROOT}/client/src/loclass/elite_crack.c - ${PM3_ROOT}/client/src/loclass/hash1_brute.c - ${PM3_ROOT}/client/src/loclass/ikeys.c - ${PM3_ROOT}/client/src/mifare/mad.c - ${PM3_ROOT}/client/src/mifare/mfkey.c - ${PM3_ROOT}/client/src/mifare/mifare4.c - ${PM3_ROOT}/client/src/mifare/mifaredefault.c - ${PM3_ROOT}/client/src/mifare/mifarehost.c - ${PM3_ROOT}/client/src/mifare/ndef.c - ${PM3_ROOT}/client/src/mifare/desfire_crypto.c - ${PM3_ROOT}/client/src/uart/uart_posix.c - ${PM3_ROOT}/client/src/uart/uart_win32.c - ${PM3_ROOT}/client/src/ui/overlays.ui - ${PM3_ROOT}/client/src/aiddesfire.c - ${PM3_ROOT}/client/src/aidsearch.c - ${PM3_ROOT}/client/src/cmdanalyse.c - ${PM3_ROOT}/client/src/cmdcrc.c - ${PM3_ROOT}/client/src/cmddata.c - ${PM3_ROOT}/client/src/cmdflashmem.c - ${PM3_ROOT}/client/src/cmdflashmemspiffs.c - ${PM3_ROOT}/client/src/cmdhf.c - ${PM3_ROOT}/client/src/cmdhf14a.c - ${PM3_ROOT}/client/src/cmdhf14b.c - ${PM3_ROOT}/client/src/cmdhf15.c - ${PM3_ROOT}/client/src/cmdhfcryptorf.c - ${PM3_ROOT}/client/src/cmdhfepa.c - ${PM3_ROOT}/client/src/cmdhffelica.c - ${PM3_ROOT}/client/src/cmdhffido.c - ${PM3_ROOT}/client/src/cmdhficlass.c - ${PM3_ROOT}/client/src/cmdhflegic.c - ${PM3_ROOT}/client/src/cmdhflist.c - ${PM3_ROOT}/client/src/cmdhflto.c - ${PM3_ROOT}/client/src/cmdhfmf.c - ${PM3_ROOT}/client/src/cmdhfmfdes.c - ${PM3_ROOT}/client/src/cmdhfmfhard.c - ${PM3_ROOT}/client/src/cmdhfmfp.c - ${PM3_ROOT}/client/src/cmdhfmfu.c - ${PM3_ROOT}/client/src/cmdhfst.c - ${PM3_ROOT}/client/src/cmdhfthinfilm.c - ${PM3_ROOT}/client/src/cmdhftopaz.c - ${PM3_ROOT}/client/src/cmdhfwaveshare.c - ${PM3_ROOT}/client/src/cmdhw.c - ${PM3_ROOT}/client/src/cmdlf.c - ${PM3_ROOT}/client/src/cmdlfawid.c - ${PM3_ROOT}/client/src/cmdlfcotag.c - ${PM3_ROOT}/client/src/cmdlfdestron.c - ${PM3_ROOT}/client/src/cmdlfem4x.c - ${PM3_ROOT}/client/src/cmdlfem4x05.c - ${PM3_ROOT}/client/src/cmdlfem4x50.c - ${PM3_ROOT}/client/src/cmdlffdxb.c - ${PM3_ROOT}/client/src/cmdlfgallagher.c - ${PM3_ROOT}/client/src/cmdlfguard.c - ${PM3_ROOT}/client/src/cmdlfhid.c - ${PM3_ROOT}/client/src/cmdlfhitag.c - ${PM3_ROOT}/client/src/cmdlfidteck.c - ${PM3_ROOT}/client/src/cmdlfindala.c - ${PM3_ROOT}/client/src/cmdlfio.c - ${PM3_ROOT}/client/src/cmdlfjablotron.c - ${PM3_ROOT}/client/src/cmdlfkeri.c - ${PM3_ROOT}/client/src/cmdlfmotorola.c - ${PM3_ROOT}/client/src/cmdlfnedap.c - ${PM3_ROOT}/client/src/cmdlfnexwatch.c - ${PM3_ROOT}/client/src/cmdlfnoralsy.c - ${PM3_ROOT}/client/src/cmdlfpac.c - ${PM3_ROOT}/client/src/cmdlfparadox.c - ${PM3_ROOT}/client/src/cmdlfpcf7931.c - ${PM3_ROOT}/client/src/cmdlfpresco.c - ${PM3_ROOT}/client/src/cmdlfpyramid.c - ${PM3_ROOT}/client/src/cmdlfsecurakey.c - ${PM3_ROOT}/client/src/cmdlft55xx.c - ${PM3_ROOT}/client/src/cmdlfti.c - ${PM3_ROOT}/client/src/cmdlfviking.c - ${PM3_ROOT}/client/src/cmdlfvisa2000.c - ${PM3_ROOT}/client/src/cmdmain.c - ${PM3_ROOT}/client/src/cmdparser.c - ${PM3_ROOT}/client/src/cmdscript.c - ${PM3_ROOT}/client/src/cmdsmartcard.c - ${PM3_ROOT}/client/src/cmdtrace.c - ${PM3_ROOT}/client/src/cmdusart.c - ${PM3_ROOT}/client/src/cmdwiegand.c - ${PM3_ROOT}/client/src/comms.c - ${PM3_ROOT}/client/src/fileutils.c - ${PM3_ROOT}/client/src/flash.c - ${PM3_ROOT}/client/src/graph.c - ${PM3_ROOT}/client/src/jansson_path.c - ${PM3_ROOT}/client/src/preferences.c - ${PM3_ROOT}/client/src/pm3.c - ${PM3_ROOT}/client/src/pm3_binlib.c - ${PM3_ROOT}/client/src/pm3_bitlib.c - ${PM3_ROOT}/client/src/prng.c - ${PM3_ROOT}/client/src/scandir.c - ${PM3_ROOT}/client/src/scripting.c - ${PM3_ROOT}/client/src/tea.c - ${PM3_ROOT}/client/src/ui.c - ${PM3_ROOT}/client/src/util.c - ${PM3_ROOT}/client/src/wiegand_formats.c - ${PM3_ROOT}/client/src/wiegand_formatutils.c - ${CMAKE_BINARY_DIR}/version.c - ) - -add_custom_command( - OUTPUT ${CMAKE_BINARY_DIR}/version.c - COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version.c || perl ${PM3_ROOT}/tools/mkversion.pl > ${CMAKE_BINARY_DIR}/version.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version.c ${CMAKE_BINARY_DIR}/version.c - DEPENDS ${PM3_ROOT}/common/default_version.c -) - -set(ADDITIONAL_SRC "") -set(ADDITIONAL_LNK "") -set(ADDITIONAL_DIRS "") -set(ADDITIONAL_LNKDIRS "") -set(X86_CPUS x86 x86_64 i686) - -message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") - -if (APPLE) - message(STATUS "Apple device detected.") - set(ADDITIONAL_SRC ${PM3_ROOT}/client/src/util_darwin.h ${PM3_ROOT}/client/src/util_darwin.m ${ADDITIONAL_SRC}) - set(ADDITIONAL_LNK "-framework Foundation" "-framework AppKit") -endif (APPLE) - -if ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) - set(CMAKE_AUTOMOC ON) - set(CMAKE_AUTORCC ON) - set(CMAKE_AUTOUIC ON) - set (TARGET_SOURCES - ${PM3_ROOT}/client/src/proxgui.cpp - ${PM3_ROOT}/client/src/proxguiqt.cpp - ${TARGET_SOURCES}) - - add_definitions("-DHAVE_GUI") - set(ADDITIONAL_LNK ${Qt5_LIBRARIES} ${ADDITIONAL_LNK}) -else ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) - set(TARGET_SOURCES - ${PM3_ROOT}/client/src/guidummy.cpp - ${TARGET_SOURCES}) -endif ((NOT SKIPQT EQUAL 1) AND (Qt5_FOUND)) - -if (NOT SKIPBT EQUAL 1) - if (BLUEZ_FOUND) - add_definitions("-DHAVE_BLUEZ") - set(ADDITIONAL_LNK ${BLUEZ_LIBRARIES} ${ADDITIONAL_LNK}) - endif (BLUEZ_FOUND) -endif(NOT SKIPBT EQUAL 1) - -if (JANSSON_FOUND) - set(ADDITIONAL_DIRS ${JANSSON_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) - set(ADDITIONAL_LNK ${JANSSON_LIBRARIES} ${ADDITIONAL_LNK}) -endif (JANSSON_FOUND) - -if (NOT SKIPPYTHON EQUAL 1) - if (PYTHON3EMBED_FOUND) - add_definitions(-DHAVE_PYTHON) - set(ADDITIONAL_DIRS ${PYTHON3EMBED_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) - set(ADDITIONAL_LNK ${PYTHON3EMBED_LIBRARIES} ${ADDITIONAL_LNK}) - set(ADDITIONAL_LNKDIRS ${PYTHON3EMBED_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS}) - elseif (PYTHON3_FOUND) - add_definitions(-DHAVE_PYTHON) - set(ADDITIONAL_DIRS ${PYTHON3_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) - set(ADDITIONAL_LNK ${PYTHON3_LIBRARIES} ${ADDITIONAL_LNK}) - set(ADDITIONAL_LNKDIRS ${PYTHON3_LIBRARY_DIRS} ${ADDITIONAL_LNKDIRS}) - endif (PYTHON3EMBED_FOUND) -endif (NOT SKIPPYTHON EQUAL 1) - -if (NOT SKIPREADLINE EQUAL 1) - if (READLINE_FOUND) - add_definitions("-DHAVE_READLINE") - set(ADDITIONAL_DIRS ${READLINE_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) - set(ADDITIONAL_LNK ${READLINE_LIBRARIES} ${ADDITIONAL_LNK}) - endif (READLINE_FOUND) -endif(NOT SKIPREADLINE EQUAL 1) - -if (BZIP2_FOUND) - set(ADDITIONAL_DIRS ${BZIP2_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) - set(ADDITIONAL_LNK ${BZIP2_LIBRARIES} ${ADDITIONAL_LNK}) -endif (BZIP2_FOUND) - -if (WHEREAMI_FOUND) - set(ADDITIONAL_DIRS ${WHEREAMI_INCLUDE_DIRS} ${ADDITIONAL_DIRS}) - set(ADDITIONAL_LNK ${WHEREAMI_LIBRARIES} ${ADDITIONAL_LNK}) -endif (WHEREAMI_FOUND) - -message(STATUS "===================================================================") -if (SKIPQT EQUAL 1) - message(STATUS "GUI support: skipped") -else (SKIPQT EQUAL 1) - if (Qt5_FOUND) - message(STATUS "GUI support: QT5 found, enabled") - else (Qt5_FOUND) - message(STATUS "GUI support: QT5 not found, disabled") - endif (Qt5_FOUND) -endif (SKIPQT EQUAL 1) - -if (SKIPBT EQUAL 1) - message(STATUS "native BT support: skipped") -else (SKIPBT EQUAL 1) - if (BLUEZ_FOUND) - message(STATUS "native BT support: Bluez found, enabled") - else (BLUEZ_FOUND) - message(STATUS "native BT support: Bluez not found, disabled") - endif (BLUEZ_FOUND) -endif(SKIPBT EQUAL 1) - -if (EMBED_BZIP2) - message(STATUS "Bzip2 library: embedded") -else (EMBED_BZIP2) - message(STATUS "Bzip2 library: system library found") -endif (EMBED_BZIP2) - -if (SKIPJANSSONSYSTEM EQUAL 1) - message(STATUS "Jansson library: local library forced") -else (SKIPJANSSONSYSTEM EQUAL 1) - if (JANSSON_FOUND) - message(STATUS "Jansson library: system library found") - else (JANSSON_FOUND) - message(STATUS "Jansson library: system library not found, using local library") - endif (JANSSON_FOUND) -endif (SKIPJANSSONSYSTEM EQUAL 1) - -if (SKIPPYTHON EQUAL 1) - message(STATUS "Python3 library: skipped") -else (SKIPPYTHON EQUAL 1) - if (PYTHON3EMBED_FOUND) - message(STATUS "Python3 library: Python3 embed found, enabled") - elseif (PYTHON_FOUND) - message(STATUS "Python3 library: Python3 found, enabled") - else (PYTHON3EMBED_FOUND) - message(STATUS "Python3 library: Python3 not found, disabled") - endif (PYTHON3EMBED_FOUND) -endif(SKIPPYTHON EQUAL 1) - -if (SKIPREADLINE EQUAL 1) - message(STATUS "Readline library: skipped") -else (SKIPREADLINE EQUAL 1) - if (READLINE_FOUND) - if (EMBED_READLINE) - message(STATUS "Readline library: embedded") - else (EMBED_READLINE) - message(STATUS "Readline library: system library found") - endif (EMBED_READLINE) - else (READLINE_FOUND) - message(STATUS "Readline library: Readline not found, disabled") - endif (READLINE_FOUND) -endif(SKIPREADLINE EQUAL 1) - -if (SKIPWHEREAMISYSTEM EQUAL 1) - message(STATUS "Whereami library: local library forced") -else (SKIPWHEREAMISYSTEM EQUAL 1) - if (WHEREAMI_FOUND) - message(STATUS "Whereami library: system library found") - else (WHEREAMI_FOUND) - message(STATUS "Whereami library: system library not found, using local library") - endif (WHEREAMI_FOUND) -endif (SKIPWHEREAMISYSTEM EQUAL 1) -message(STATUS "===================================================================") - -# Lua SWIG -if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) - set (TARGET_SOURCES - ${PM3_ROOT}/client/src/pm3_luawrap.c - ${TARGET_SOURCES}) - add_definitions(-DHAVE_LUA_SWIG) - message("Lua SWIG wrapper found") -endif (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) - -# Python SWIG -if (NOT SKIPPYTHON EQUAL 1) - if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) - if (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) - set (TARGET_SOURCES - ${PM3_ROOT}/client/src/pm3_pywrap.c - ${TARGET_SOURCES}) - add_definitions(-DHAVE_PYTHON_SWIG) - message("Python SWIG wrapper found") - endif (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) - endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) -endif (NOT SKIPPYTHON EQUAL 1) - -add_executable(proxmark3 - ${PM3_ROOT}/client/src/proxmark3.c - ${TARGET_SOURCES} - ${ADDITIONAL_SRC} -) - -target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3) -if (EMBED_READLINE) - if (NOT SKIPREADLINE EQUAL 1) - add_dependencies(proxmark3 ncurses readline) - endif (NOT SKIPREADLINE EQUAL 1) -endif (EMBED_READLINE) -if (EMBED_BZIP2) - add_dependencies(proxmark3 bzip2) -endif (EMBED_BZIP2) - -if (MINGW) - # Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z) - # and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1 - # FTR __USE_MINGW_ANSI_STDIO seems deprecated in Mingw32 - # but not Mingw64 https://fr.osdn.net/projects/mingw/lists/archive/users/2019-January/000199.html - target_compile_definitions(proxmark3 PRIVATE _ISOC99_SOURCE) - - set(CMAKE_C_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_C_FLAGS}") - set(CMAKE_CXX_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_CXX_FLAGS}") -endif (MINGW) - -target_include_directories(proxmark3 PRIVATE - ${PM3_ROOT}/common - ${PM3_ROOT}/common_fpga - ${PM3_ROOT}/include - ${PM3_ROOT}/client/src - ${PM3_ROOT}/client/include - ${ADDITIONAL_DIRS} -) - -if (NOT APPLE) - # required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line. - set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed) -endif (NOT APPLE) - -if (NOT JANSSON_FOUND) - set(ADDITIONAL_LNK pm3rrg_rdv4_jansson ${ADDITIONAL_LNK}) -endif (NOT JANSSON_FOUND) -if (NOT WHEREAMI_FOUND) - set(ADDITIONAL_LNK pm3rrg_rdv4_whereami ${ADDITIONAL_LNK}) -endif (NOT WHEREAMI_FOUND) - -target_link_libraries(proxmark3 PRIVATE - m - pm3rrg_rdv4_mbedtls - pm3rrg_rdv4_cliparser - pm3rrg_rdv4_lua - pm3rrg_rdv4_tinycbor - pm3rrg_rdv4_amiibo - pm3rrg_rdv4_reveng - pm3rrg_rdv4_hardnested - ${ADDITIONAL_LNK}) - -if (NOT SKIPPTHREAD EQUAL 1) - target_link_libraries(proxmark3 PRIVATE pthread) -endif (NOT SKIPPTHREAD EQUAL 1) - -if (NOT SKIPPYTHON EQUAL 1) - # OSX have a hard time compiling python3 dependency with older cmake. - if (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) - if (NOT CMAKE_VERSION VERSION_LESS 3.13) - target_link_directories(proxmark3 PRIVATE ${ADDITIONAL_LNKDIRS}) - elseif (APPLE) - message( SEND_ERROR "Your CMAKE version is too old for Apple platform, please update to a version >=3.13" ) - endif (NOT CMAKE_VERSION VERSION_LESS 3.13) - endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) -endif (NOT SKIPPYTHON EQUAL 1) - -install(TARGETS proxmark3 DESTINATION "bin") -install(DIRECTORY cmdscripts lualibs luascripts pyscripts resources dictionaries DESTINATION "share/proxmark3") - -add_custom_command(OUTPUT lualibs/pm3_cmd.lua - COMMAND "awk -f pm3_cmd_h2lua.awk ../include/pm3_cmd.h > lualibs/pm3_cmd.lua" - COMMENT "Creating lualibs/pm3_cmd.lua" - ) - -add_custom_command(OUTPUT lualibs/mfc_default_keys.lua - COMMAND "awk -f default_keys_dic2lua.awk mfc_default_keys.dic > lualibs/mfc_default_keys.lua" - COMMENT "Creating lualibs/mfc_default_keys.lua" - ) - -#"make package" will trigger this -SET(CPACK_GENERATOR "DEB") -SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Iceman") -INCLUDE(CPack) diff --git a/client/experimental_client_with_swig/output_grabber.py b/client/experimental_client_with_swig/output_grabber.py new file mode 100755 index 000000000..ad405c9d9 --- /dev/null +++ b/client/experimental_client_with_swig/output_grabber.py @@ -0,0 +1,78 @@ +import os +import sys +import threading +import time + +# From https://stackoverflow.com/a/29834357 +class OutputGrabber(object): + """ + Class used to grab standard output or another stream. + """ + escape_char = "\b" + + def __init__(self, stream=None, threaded=False): + self.origstream = stream + self.threaded = threaded + if self.origstream is None: + self.origstream = sys.stdout + self.origstreamfd = self.origstream.fileno() + self.capturedtext = "" + # Create a pipe so the stream can be captured: + self.pipe_out, self.pipe_in = os.pipe() + + def __enter__(self): + self.start() + return self + + def __exit__(self, type, value, traceback): + self.stop() + + def start(self): + """ + Start capturing the stream data. + """ + self.capturedtext = "" + # Save a copy of the stream: + self.streamfd = os.dup(self.origstreamfd) + # Replace the original stream with our write pipe: + os.dup2(self.pipe_in, self.origstreamfd) + if self.threaded: + # Start thread that will read the stream: + self.workerThread = threading.Thread(target=self.readOutput) + self.workerThread.start() + # Make sure that the thread is running and os.read() has executed: + time.sleep(0.01) + + def stop(self): + """ + Stop capturing the stream data and save the text in `capturedtext`. + """ + # Print the escape character to make the readOutput method stop: + self.origstream.write(self.escape_char) + # Flush the stream to make sure all our data goes in before + # the escape character: + self.origstream.flush() + if self.threaded: + # wait until the thread finishes so we are sure that + # we have until the last character: + self.workerThread.join() + else: + self.readOutput() + # Close the pipe: + os.close(self.pipe_in) + os.close(self.pipe_out) + # Restore the original stream: + os.dup2(self.streamfd, self.origstreamfd) + # Close the duplicate stream: + os.close(self.streamfd) + + def readOutput(self): + """ + Read the stream data (one byte at a time) + and save the text in `capturedtext`. + """ + while True: + char = os.read(self.pipe_out,1).decode(self.origstream.encoding) + if not char or self.escape_char in char: + break + self.capturedtext += char diff --git a/client/experimental_client_with_swig/testembedded_grab.py b/client/experimental_client_with_swig/testembedded_grab.py new file mode 100755 index 000000000..caec75769 --- /dev/null +++ b/client/experimental_client_with_swig/testembedded_grab.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +import pm3 +from output_grabber import OutputGrabber + +out = OutputGrabber() +p=pm3.pm3() +print("Device:", p.name) +with out: + p.console("hw status") +for line in out.capturedtext.split('\n'): + if "Unique ID" in line: + print(line) diff --git a/client/experimental_lib/00make_swig.sh b/client/experimental_lib/00make_swig.sh index 6c752d024..626a87986 100755 --- a/client/experimental_lib/00make_swig.sh +++ b/client/experimental_lib/00make_swig.sh @@ -1,4 +1,5 @@ #!/bin/bash -swig -lua -o ../src/pm3_luawrap.c ../src/pm3.i -swig -python -o ../src/pm3_pywrap.c ../src/pm3.i +cd .. +make src/pm3_luawrap.c +make src/pm3_pywrap.c diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index 505d1ea1b..2bc02fd4b 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -188,7 +188,6 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/emv/crypto.c ${PM3_ROOT}/client/src/emv/crypto_polarssl.c ${PM3_ROOT}/client/src/emv/dol.c - ${PM3_ROOT}/client/src/emv/dump.c ${PM3_ROOT}/client/src/emv/emv_pk.c ${PM3_ROOT}/client/src/emv/emv_pki.c ${PM3_ROOT}/client/src/emv/emv_pki_priv.c @@ -456,7 +455,6 @@ else (SKIPWHEREAMISYSTEM EQUAL 1) message(STATUS "Whereami library: system library not found, using local library") endif (WHEREAMI_FOUND) endif (SKIPWHEREAMISYSTEM EQUAL 1) -message(STATUS "===================================================================") # Lua SWIG if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) @@ -464,7 +462,7 @@ if (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) ${PM3_ROOT}/client/src/pm3_luawrap.c ${TARGET_SOURCES}) add_definitions(-DHAVE_LUA_SWIG) - message("Lua SWIG wrapper found") + message(STATUS "Lua SWIG: wrapper found") endif (EXISTS ${PM3_ROOT}/client/src/pm3_luawrap.c) # Python SWIG @@ -475,10 +473,11 @@ if (NOT SKIPPYTHON EQUAL 1) ${PM3_ROOT}/client/src/pm3_pywrap.c ${TARGET_SOURCES}) add_definitions(-DHAVE_PYTHON_SWIG) - message("Python SWIG wrapper found") + message(STATUS "Python SWIG: wrapper found") endif (EXISTS ${PM3_ROOT}/client/src/pm3_pywrap.c) endif (PYTHON3EMBED_FOUND OR PYTHON3_FOUND) endif (NOT SKIPPYTHON EQUAL 1) +message(STATUS "===================================================================") add_library(pm3rrg_rdv4 SHARED ${PM3_ROOT}/client/src/proxmark3.c diff --git a/client/experimental_lib/example_py/02run_test_grab_interactive.sh b/client/experimental_lib/example_py/02run_test_grab_interactive.sh new file mode 100755 index 000000000..d7dd7dd16 --- /dev/null +++ b/client/experimental_lib/example_py/02run_test_grab_interactive.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +PYTHONPATH=../../src ipython3 -i ./test_grab.py diff --git a/client/experimental_lib/example_py/output_grabber.py b/client/experimental_lib/example_py/output_grabber.py new file mode 100755 index 000000000..ad405c9d9 --- /dev/null +++ b/client/experimental_lib/example_py/output_grabber.py @@ -0,0 +1,78 @@ +import os +import sys +import threading +import time + +# From https://stackoverflow.com/a/29834357 +class OutputGrabber(object): + """ + Class used to grab standard output or another stream. + """ + escape_char = "\b" + + def __init__(self, stream=None, threaded=False): + self.origstream = stream + self.threaded = threaded + if self.origstream is None: + self.origstream = sys.stdout + self.origstreamfd = self.origstream.fileno() + self.capturedtext = "" + # Create a pipe so the stream can be captured: + self.pipe_out, self.pipe_in = os.pipe() + + def __enter__(self): + self.start() + return self + + def __exit__(self, type, value, traceback): + self.stop() + + def start(self): + """ + Start capturing the stream data. + """ + self.capturedtext = "" + # Save a copy of the stream: + self.streamfd = os.dup(self.origstreamfd) + # Replace the original stream with our write pipe: + os.dup2(self.pipe_in, self.origstreamfd) + if self.threaded: + # Start thread that will read the stream: + self.workerThread = threading.Thread(target=self.readOutput) + self.workerThread.start() + # Make sure that the thread is running and os.read() has executed: + time.sleep(0.01) + + def stop(self): + """ + Stop capturing the stream data and save the text in `capturedtext`. + """ + # Print the escape character to make the readOutput method stop: + self.origstream.write(self.escape_char) + # Flush the stream to make sure all our data goes in before + # the escape character: + self.origstream.flush() + if self.threaded: + # wait until the thread finishes so we are sure that + # we have until the last character: + self.workerThread.join() + else: + self.readOutput() + # Close the pipe: + os.close(self.pipe_in) + os.close(self.pipe_out) + # Restore the original stream: + os.dup2(self.streamfd, self.origstreamfd) + # Close the duplicate stream: + os.close(self.streamfd) + + def readOutput(self): + """ + Read the stream data (one byte at a time) + and save the text in `capturedtext`. + """ + while True: + char = os.read(self.pipe_out,1).decode(self.origstream.encoding) + if not char or self.escape_char in char: + break + self.capturedtext += char diff --git a/client/experimental_lib/example_py/test_grab.py b/client/experimental_lib/example_py/test_grab.py new file mode 100755 index 000000000..7cec5a94f --- /dev/null +++ b/client/experimental_lib/example_py/test_grab.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +import pm3 +from output_grabber import OutputGrabber + +out = OutputGrabber() +p=pm3.pm3("/dev/ttyACM1") +print("Device:", p.name) +with out: + p.console("hw status") +for line in out.capturedtext.split('\n'): + if "Unique ID" in line: + print(line) diff --git a/client/lualibs/7816_error.lua b/client/lualibs/7816_error.lua index 15f4ef471..34f9847ce 100644 --- a/client/lualibs/7816_error.lua +++ b/client/lualibs/7816_error.lua @@ -68,10 +68,11 @@ end _errorcodes.tostring = function(command) if(type(command) == 'string') then - return ("%s (%d)"):format(_reverse_lookup[command] or "ERROR UNDEFINED!", command) + return ("%s (%s)"):format(_reverse_lookup[command] or "ERROR UNDEFINED!", command) end if(type(command) == 'number') then - return ("%s (%d)"):format(_reverse_lookup[ tostring(command)] or "ERROR UNDEFINED!", command) + local hx = ("%04X"):format(command) + return ("%s (0x%s)"):format(_reverse_lookup[hx] or "ERROR UNDEFINED!", hx) end return ("Error, numeric or string argument expected, got : %s"):format(tostring(command)) end diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 0cb6006d4..852aae3b8 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -29,12 +29,11 @@ #include "aidsearch.h" #include "cmdhf.h" // handle HF plot #include "protocols.h" // MAGIC_GEN_1A -#include "emv/dump.h" // dump_buffer bool APDUInFramingEnable = true; static int CmdHelp(const char *Cmd); -static int waitCmd(uint8_t iSelect, uint32_t timeout); +static int waitCmd(bool i_select, uint32_t timeout); static const manufactureName manufactureMapping[] = { // ID, "Vendor Country" @@ -246,20 +245,7 @@ static int usage_hf_14a_sniff(void) { PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a sniff c r")); return PM3_SUCCESS; } -static int usage_hf_14a_raw(void) { - PrintAndLogEx(NORMAL, "Usage: hf 14a raw [-h] [-r] [-c] [-k] [-a] [-T] [-t] [-b] <0A 0B 0C ... hex>"); - PrintAndLogEx(NORMAL, " -h this help"); - PrintAndLogEx(NORMAL, " -r do not read response"); - PrintAndLogEx(NORMAL, " -c calculate and append CRC"); - PrintAndLogEx(NORMAL, " -k keep signal field ON after receive"); - PrintAndLogEx(NORMAL, " -a active signal field ON without select"); - PrintAndLogEx(NORMAL, " -s active signal field ON with select"); - PrintAndLogEx(NORMAL, " -b number of bits to send. Useful for send partial byte"); - PrintAndLogEx(NORMAL, " -t timeout in ms"); - PrintAndLogEx(NORMAL, " -T use Topaz protocol to send command"); - PrintAndLogEx(NORMAL, " -3 ISO14443-3 select only (skip RATS)"); - return PM3_SUCCESS; -} + static int usage_hf_14a_reader(void) { PrintAndLogEx(NORMAL, "Usage: hf 14a reader [k|s|x] [3]"); PrintAndLogEx(NORMAL, " k keep the field active after command executed"); @@ -1118,14 +1104,14 @@ static int CmdHF14AAPDU(const char *Cmd) { CLIParserInit(&ctx, "hf 14a apdu", "Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL). works with all apdu types from ISO 7816-4:2013", "hf 14a apdu -st 00A404000E325041592E5359532E444446303100\n" - "hf 14a apdu -sd 00A404000E325041592E5359532E444446303100 -> decode apdu\n" - "hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 -> encode standard apdu\n" + "hf 14a apdu -sd 00A404000E325041592E5359532E444446303100 -> decode apdu\n" + "hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 -> encode standard apdu\n" "hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -el 65536 -> encode extended apdu\n"); void *argtable[] = { arg_param_begin, arg_lit0("s", "select", "activate field and select card"), - arg_lit0("k", "keep", "leave the signal field ON after receive response"), + arg_lit0("k", "keep", "keep signal field ON after receive"), arg_lit0("t", "tlv", "executes TLV decoder if it possible"), arg_lit0("d", "decapdu", "decode apdu request if it possible"), arg_str0("m", "make", "", "make apdu with head from this field and data from data field. Must be 4 bytes length: "), @@ -1225,97 +1211,54 @@ static int CmdHF14AAPDU(const char *Cmd) { } static int CmdHF14ACmdRaw(const char *Cmd) { - bool reply = 1; - bool crc = false; - bool keep_field_on = false; - bool active = false; - bool active_select = false; - bool no_rats = false; - uint16_t numbits = 0; - bool bTimeout = false; - uint32_t timeout = 0; - bool topazmode = false; - char buf[5] = ""; - int i = 0; + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a raw", + "Sends an raw bytes over ISO14443a. With option to use TOPAZ 14a mode.", + "hf 14a raw -sc 3000 -> select, crc, where 3000 == 'read block 00'\n" + "hf 14a raw -ak -b 7 40 -> send 7 bit byte 0x40\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0("a", NULL, "active signal field ON without select"), + arg_int0("b", NULL, "", "number of bits to send. Useful for send partial byte"), + arg_lit0("c", NULL, "calculate and append CRC"), + arg_lit0("k", NULL, "keep signal field ON after receive"), + arg_lit0("3", NULL, "ISO14443-3 select only (skip RATS)"), + arg_lit0("r", NULL, "do not read response"), + arg_lit0("s", NULL, "active signal field ON with select"), + arg_int0("t", "timeout", "", "timeout in milliseconds"), + arg_lit0(NULL, "topaz", "use Topaz protocol to send command"), + arg_strx1(NULL, NULL, "", "raw bytes to send"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + + bool active = arg_get_lit(ctx, 1); + uint16_t numbits = (uint16_t)arg_get_int_def(ctx, 2, 0); + bool crc = arg_get_lit(ctx, 3); + bool keep_field_on = arg_get_lit(ctx, 4); + bool no_rats = arg_get_lit(ctx, 5); + bool reply = (arg_get_lit(ctx, 6) == false); + bool active_select = arg_get_lit(ctx, 7); + uint32_t timeout = (uint32_t)arg_get_int_def(ctx, 8, 0); + bool topazmode = arg_get_lit(ctx, 9); + + int datalen = 0; uint8_t data[PM3_CMD_DATA_SIZE]; - uint16_t datalen = 0; - uint32_t temp; + CLIGetHexWithReturn(ctx, 10, data, &datalen); + CLIParserFree(ctx); - if (strlen(Cmd) < 2) return usage_hf_14a_raw(); + bool bTimeout = (timeout) ? true : false; - // strip - while (*Cmd == ' ' || *Cmd == '\t') Cmd++; - - while (Cmd[i] != '\0') { - if (Cmd[i] == ' ' || Cmd[i] == '\t') { i++; continue; } - if (Cmd[i] == '-') { - switch (Cmd[i + 1]) { - case 'H': - case 'h': - return usage_hf_14a_raw(); - case 'r': - reply = false; - break; - case 'c': - crc = true; - break; - case 'k': - keep_field_on = true; - break; - case 'a': - active = true; - break; - case 's': - active_select = true; - break; - case 'b': - sscanf(Cmd + i + 2, "%u", &temp); - numbits = temp & 0xFFFF; - i += 3; - while (Cmd[i] != ' ' && Cmd[i] != '\0') { i++; } - i -= 2; - break; - case 't': - bTimeout = true; - sscanf(Cmd + i + 2, "%u", &temp); - timeout = temp; - i += 3; - while (Cmd[i] != ' ' && Cmd[i] != '\0') { i++; } - i -= 2; - break; - case 'T': - topazmode = true; - break; - case '3': - no_rats = true; - break; - default: - return usage_hf_14a_raw(); - } - i += 2; - continue; + // ensure we can add 2byte crc to input data + if (datalen >= sizeof(data) + 2) { + if (crc) { + PrintAndLogEx(FAILED, "Buffer is full, we can't add CRC to your data"); + return PM3_EINVARG; } - if ((Cmd[i] >= '0' && Cmd[i] <= '9') || - (Cmd[i] >= 'a' && Cmd[i] <= 'f') || - (Cmd[i] >= 'A' && Cmd[i] <= 'F')) { - buf[strlen(buf) + 1] = 0; - buf[strlen(buf)] = Cmd[i]; - i++; - - if (strlen(buf) >= 2) { - sscanf(buf, "%x", &temp); - data[datalen] = (uint8_t)(temp & 0xff); - *buf = 0; - if (++datalen >= sizeof(data)) { - if (crc) - PrintAndLogEx(FAILED, "Buffer is full, we can't add CRC to your data"); - break; - } - } - continue; - } - PrintAndLogEx(FAILED, "Invalid char on input"); - return PM3_ESOFT; } if (crc && datalen > 0 && datalen < sizeof(data) - 2) { @@ -1371,19 +1314,19 @@ static int CmdHF14ACmdRaw(const char *Cmd) { if (reply) { int res = 0; if (active_select) - res = waitCmd(1, timeout); - if (!res && datalen > 0) - waitCmd(0, timeout); + res = waitCmd(true, timeout); + if (res == PM3_SUCCESS && datalen > 0) + waitCmd(false, timeout); } return PM3_SUCCESS; } -static int waitCmd(uint8_t iSelect, uint32_t timeout) { +static int waitCmd(bool i_select, uint32_t timeout) { PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, timeout + 1500)) { uint16_t len = (resp.oldarg[0] & 0xFFFF); - if (iSelect) { + if (i_select) { len = (resp.oldarg[1] & 0xFFFF); if (len) { PrintAndLogEx(SUCCESS, "Card selected. UID[%u]:", len); @@ -1395,28 +1338,30 @@ static int waitCmd(uint8_t iSelect, uint32_t timeout) { } if (!len) - return 1; + return PM3_ESOFT; uint8_t *data = resp.data.asBytes; - if (iSelect == 0 && len >= 3) { + if (i_select == false && len >= 3) { bool crc = check_crc(CRC_14443_A, data, len); + + char s[16]; + sprintf(s, + (crc) ? _GREEN_("%02X %02X") : _RED_("%02X %02X"), + data[len - 2], + data[len - 1] + ); - PrintAndLogEx(SUCCESS, "%s[%02X %02X] %s", - sprint_hex(data, len - 2), - data[len - 2], - data[len - 1], - (crc) ? _GREEN_("ok") : _RED_("fail") - ); + PrintAndLogEx(SUCCESS, "%s[ %s ]", sprint_hex(data, len - 2), s); } else { PrintAndLogEx(SUCCESS, "%s", sprint_hex(data, len)); } } else { PrintAndLogEx(WARNING, "timeout while waiting for reply."); - return 3; + return PM3_ETIMEOUT; } - return 0; + return PM3_SUCCESS; } static int CmdHF14AAntiFuzz(const char *Cmd) { diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 8754c7a05..593eaaece 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1326,7 +1326,7 @@ static int CmdHF15Dump(const char *Cmd) { if (fileNameLen < 1) { PrintAndLogEx(INFO, "Using UID as filename"); fptr += sprintf(fptr, "hf-15-"); - FillFileNameByUID(fptr, uid, "-dump", sizeof(uid)); + FillFileNameByUID(fptr, SwapEndian64(uid, sizeof(uid), 8), "-dump", sizeof(uid)); } // detect blocksize from card :) diff --git a/client/src/cmdhffido.c b/client/src/cmdhffido.c index 91c1a85b3..7535a5ef4 100644 --- a/client/src/cmdhffido.c +++ b/client/src/cmdhffido.c @@ -19,9 +19,7 @@ //----------------------------------------------------------------------------- #include "cmdhffido.h" - #include - #include "cmdparser.h" // command_t #include "commonutil.h" #include "comms.h" @@ -33,10 +31,10 @@ #include "crypto/libpcrypto.h" #include "fido/cbortools.h" #include "fido/fidocore.h" -#include "emv/dump.h" #include "ui.h" #include "cmdhf14a.h" #include "cmdtrace.h" +#include "util.h" static int CmdHelp(const char *Cmd); @@ -88,7 +86,7 @@ static int cmd_hf_fido_info(const char *cmd) { } else { PrintAndLogEx(INFO, "FIDO authenticator detected (not standard U2F)."); PrintAndLogEx(INFO, "Non U2F authenticator version:"); - dump_buffer((const unsigned char *)buf, len, NULL, 0); + print_buffer((const unsigned char *)buf, len, 1); } } else { PrintAndLogEx(INFO, "FIDO U2F authenticator detected. Version: %.*s", (int)len, buf); @@ -296,7 +294,7 @@ static int cmd_hf_fido_register(const char *cmd) { if (verbose2) { PrintAndLogEx(INFO, "------------ " _CYAN_("data") " ----------------------"); - dump_buffer((const unsigned char *)buf, len, NULL, 0); + print_buffer((const unsigned char *)buf, len, 1); PrintAndLogEx(INFO, "-------------" _CYAN_("data") " ----------------------"); } @@ -342,7 +340,7 @@ static int cmd_hf_fido_register(const char *cmd) { uint8_t rval[300] = {0}; uint8_t sval[300] = {0}; res = ecdsa_asn1_get_signature(&buf[hashp], len - hashp, rval, sval); - if (!res) { + if (res == PM3_SUCCESS) { if (verbose) { PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32)); PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32)); @@ -585,7 +583,7 @@ static int cmd_hf_fido_authenticate(const char *cmd) { uint8_t rval[300] = {0}; uint8_t sval[300] = {0}; res = ecdsa_asn1_get_signature(&buf[5], len - 5, rval, sval); - if (!res) { + if (res == PM3_SUCCESS) { if (verbose) { PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32)); PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32)); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index b6a1592bb..82fc8a1c4 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -16,7 +16,6 @@ #include "comms.h" // clearCommandBuffer #include "fileutils.h" #include "cmdtrace.h" -#include "emv/dump.h" #include "mifare/mifaredefault.h" // mifare default key array #include "cliparser.h" // argtable #include "hardnested_bf_core.h" // SetSIMDInstr @@ -5095,7 +5094,7 @@ static int CmdHFMFNDEF(const char *Cmd) { if (verbose2) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("MFC NDEF raw") " ----------------"); - dump_buffer(data, datalen, stdout, 1); + print_buffer(data, datalen, 1); } NDEFDecodeAndPrint(data, datalen, verbose); diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 871c9d115..3c5de933a 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -35,6 +35,7 @@ #include "mifare/mad.h" #include "generator.h" #include "aiddesfire.h" +#include "util.h" #define MAX_KEY_LEN 24 #define MAX_KEYS_LIST_LEN 1024 @@ -728,7 +729,6 @@ static int mfdes_get_info(mfdes_info_res_t *info) { return PM3_SUCCESS; } - static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rpayload) { // 3 different way to authenticate AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32) // 4 different crypto arg1 DES, 3DES, 3K3DES, AES @@ -777,9 +777,7 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp if (payload->kdfAlgo == MFDES_KDF_ALGO_AN10922) { mifare_kdf_an10922(key, payload->kdfInput, payload->kdfInputLen); - if (g_debugMode) { - PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); - } + PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); } else if (payload->kdfAlgo == MFDES_KDF_ALGO_GALLAGHER) { // We will overrite any provided KDF input since a gallagher specific KDF was requested. payload->kdfInputLen = 11; @@ -789,11 +787,9 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp } mifare_kdf_an10922(key, payload->kdfInput, payload->kdfInputLen); + PrintAndLogEx(DEBUG, " KDF Input: " _YELLOW_("%s"), sprint_hex(payload->kdfInput, payload->kdfInputLen)); + PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); - if (g_debugMode) { - PrintAndLogEx(INFO, " KDF Input: " _YELLOW_("%s"), sprint_hex(payload->kdfInput, payload->kdfInputLen)); - PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); - } } uint8_t subcommand = MFDES_AUTHENTICATE; @@ -866,8 +862,8 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp } if (g_debugMode > 1) { - PrintAndLogEx(INFO, "encRndB: %s", sprint_hex(encRndB, 8)); - PrintAndLogEx(INFO, "RndB: %s", sprint_hex(RndB, 8)); + PrintAndLogEx(DEBUG, "encRndB: %s", sprint_hex(encRndB, 8)); + PrintAndLogEx(DEBUG, "RndB: %s", sprint_hex(RndB, 8)); } // - Rotate RndB by 8 bits @@ -893,24 +889,24 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp memcpy(tmp, RndA, rndlen); memcpy(tmp + rndlen, rotRndB, rndlen); if (g_debugMode > 1) { - PrintAndLogEx(INFO, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(INFO, "Both: %s", sprint_hex(tmp, 16)); + PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); + PrintAndLogEx(DEBUG, "Both: %s", sprint_hex(tmp, 16)); } tdes_nxp_send(tmp, both, 16, key->data, IV, 2); if (g_debugMode > 1) { - PrintAndLogEx(INFO, "EncBoth: %s", sprint_hex(both, 16)); + PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 16)); } } else if (payload->algo == MFDES_ALGO_3K3DES) { uint8_t tmp[32] = {0x00}; memcpy(tmp, RndA, rndlen); memcpy(tmp + rndlen, rotRndB, rndlen); if (g_debugMode > 1) { - PrintAndLogEx(INFO, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(INFO, "Both3k3: %s", sprint_hex(tmp, 32)); + PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); + PrintAndLogEx(DEBUG, "Both3k3: %s", sprint_hex(tmp, 32)); } tdes_nxp_send(tmp, both, 32, key->data, IV, 3); if (g_debugMode > 1) { - PrintAndLogEx(INFO, "EncBoth: %s", sprint_hex(both, 32)); + PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 32)); } } } else if (payload->mode == MFDES_AUTH_AES) { @@ -918,8 +914,8 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp memcpy(tmp, RndA, rndlen); memcpy(tmp + rndlen, rotRndB, rndlen); if (g_debugMode > 1) { - PrintAndLogEx(INFO, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(INFO, "Both3k3: %s", sprint_hex(tmp, 32)); + PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); + PrintAndLogEx(DEBUG, "Both3k3: %s", sprint_hex(tmp, 32)); } if (payload->algo == MFDES_ALGO_AES) { if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) { @@ -927,7 +923,7 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp } mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, 32, IV, tmp, both); if (g_debugMode > 1) { - PrintAndLogEx(INFO, "EncBoth: %s", sprint_hex(both, 32)); + PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 32)); } } } @@ -996,8 +992,8 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp for (uint32_t x = 0; x < rndlen; x++) { if (RndA[x] != encRndA[x]) { if (g_debugMode > 1) { - PrintAndLogEx(INFO, "Expected_RndA : %s", sprint_hex(RndA, rndlen)); - PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(encRndA, rndlen)); + PrintAndLogEx(DEBUG, "Expected_RndA : %s", sprint_hex(RndA, rndlen)); + PrintAndLogEx(DEBUG, "Generated_RndA : %s", sprint_hex(encRndA, rndlen)); } return 11; } @@ -4769,7 +4765,7 @@ static int CmdHF14aDesNDEF(const char *Cmd) { if (verbose2) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("DESFire NDEF raw") " ----------------"); - dump_buffer(data, datalen, stdout, 1); + print_buffer(data, datalen, 1); } PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfdes ndef -vv`") " for more details"); diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 5ef2ac826..1f0d47ae5 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -15,12 +15,12 @@ #include "commonutil.h" // ARRAYLEN #include "comms.h" #include "ui.h" +#include "util.h" #include "cmdhf14a.h" #include "mifare/mifare4.h" #include "mifare/mad.h" #include "mifare/ndef.h" #include "cliparser.h" -#include "emv/dump.h" #include "mifare/mifaredefault.h" #include "util_posix.h" #include "fileutils.h" @@ -1551,7 +1551,7 @@ static int CmdHFMFPNDEF(const char *Cmd) { if (verbose2) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("MF Plus NDEF raw") " ----------------"); - dump_buffer(data, datalen, stdout, 1); + print_buffer(data, datalen, 1); } NDEFDecodeAndPrint(data, datalen, verbose); diff --git a/client/src/cmdhfwaveshare.c b/client/src/cmdhfwaveshare.c index 96547668f..932012f98 100644 --- a/client/src/cmdhfwaveshare.c +++ b/client/src/cmdhfwaveshare.c @@ -83,9 +83,9 @@ static model_t models[] = { {"2.9 inch e-paper", 16, 296, 128}, {"4.2 inch e-paper", 100, 400, 300}, // tested {"7.5 inch e-paper", 120, 800, 480}, - {"2.7 inch e-paper", 121, 276, 176}, - {"2.13 inch e-paper B (with red)", 106, 212, 104}, - {"1.54 inch e-paper B (with red)", 100, 200, 200}, + {"2.7 inch e-paper", 121, 176, 276}, // tested + {"2.13 inch e-paper B (with red)", 106, 104, 212}, // tested + {"1.54 inch e-paper B (with red)", 100, 200, 200}, // tested {"7.5 inch e-paper HD", 120, 880, 528}, }; @@ -563,7 +563,6 @@ static int transceive_blocking(uint8_t *txBuf, uint16_t txBufLen, uint8_t *rxBuf PacketResponseNG resp; SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT, txBufLen, 0, txBuf, txBufLen); rxBuf[0] = 1; - if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { if (resp.oldarg[0] > rxBufLen) { PrintAndLogEx(WARNING, "Received %"PRIu64 " bytes, rxBuf too small (%u)", resp.oldarg[0], rxBufLen); @@ -856,7 +855,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { } else if (model_nr == M2in13B) { //2.13inch B for (i = 0; i < 26; i++) { read_black(i, step8, model_nr, black); - ret = transceive_blocking(step8, 109, rx, 20, actrxlen, true); // cd 08 + ret = transceive_blocking(step8, 109, rx, 20, actrxlen, false); // cd 08 if (ret != PM3_SUCCESS) { return ret; } @@ -920,7 +919,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { for (i = 0; i < 26; i++) { read_red(i, step13, model_nr, red); //memset(&step13[3], 0xfE, 106); - ret = transceive_blocking(step13, 109, rx, 20, actrxlen, true); + ret = transceive_blocking(step13, 109, rx, 20, actrxlen, false); if (ret != PM3_SUCCESS) { return ret; } diff --git a/client/src/cmdlfem4x05.c b/client/src/cmdlfem4x05.c index e1f8e10ad..93078178d 100644 --- a/client/src/cmdlfem4x05.c +++ b/client/src/cmdlfem4x05.c @@ -1882,7 +1882,8 @@ uint32_t static em4x05_Sniff_GetBlock(char *bits, bool fwd) { if (parity != (bits[35] - '0')) parityerror = true; - if (parityerror) printf("parity error : "); + if (parityerror) + PrintAndLogEx(ERR, "parity error : "); if (!fwd) { uint32_t t1 = value; @@ -1997,10 +1998,10 @@ int CmdEM4x05Sniff(const char *Cmd) { ((strncmp(bits, "01010", 5) == 0) && (bitidx == 50))) { memmove(bits, &bits[1], bitidx - 1); bitidx--; - printf("Trim leading 0\n"); + PrintAndLogEx(INFO, "Trim leading 0"); } bits[bitidx] = 0; - // printf ("==> %s\n",bits); + // logon if ((strncmp(bits, "0011", 4) == 0) && (bitidx == 49)) { haveData = true; @@ -2017,8 +2018,9 @@ int CmdEM4x05Sniff(const char *Cmd) { sprintf(cmdText, "Write"); tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3); sprintf(blkAddr, "%d", tmpValue); - if (tmpValue == 2) + if (tmpValue == 2) { pwd = true; + } tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd); sprintf(dataText, "%08X", tmpValue); } @@ -2057,8 +2059,9 @@ int CmdEM4x05Sniff(const char *Cmd) { } else { i = (CycleWidth - ZeroWidth) / 28; bits[bitidx++] = '0'; - for (int ii = 0; ii < i; ii++) + for (int ii = 0; ii < i; ii++) { bits[bitidx++] = '1'; + } } } } @@ -2068,15 +2071,14 @@ int CmdEM4x05Sniff(const char *Cmd) { // Print results if (haveData) { //&& (minWidth > 1) && (maxWidth > minWidth)){ if (pwd) - PrintAndLogEx(SUCCESS, "%6zu | %-10s | "_YELLOW_("%8s")" | "_YELLOW_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits); + PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _YELLOW_("%8s")" | " _YELLOW_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits); else - PrintAndLogEx(SUCCESS, "%6zu | %-10s | "_GREEN_("%8s")" | "_GREEN_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits); + PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _GREEN_("%8s")" | " _GREEN_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits); } } // footer PrintAndLogEx(SUCCESS, "---------------------------------------------------------------------------------------------------"); PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; } diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index ae9d018d4..ddeece950 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -18,8 +18,8 @@ #include "comms.h" // getfromdevice #include "emv/emvcore.h" // decodeTVL #include "crypto/libpcrypto.h" // sha512hash -#include "emv/dump.h" #include "ui.h" +#include "util.h" #include "fileutils.h" #include "crc16.h" // crc @@ -316,7 +316,7 @@ static void PrintATR(uint8_t *atr, size_t atrlen) { if (K > 1) { PrintAndLogEx(INFO, "\tHistorical bytes"); - dump_buffer(&atr[2 + T1len + TD1len + TDilen], K, NULL, 1); + print_buffer(&atr[2 + T1len + TD1len + TDilen], K, 1); } } diff --git a/client/src/crypto/asn1dump.c b/client/src/crypto/asn1dump.c index 91b04216a..f1addb9e2 100644 --- a/client/src/crypto/asn1dump.c +++ b/client/src/crypto/asn1dump.c @@ -15,23 +15,17 @@ #include #include #include -#include #include #include #include #include #include "emv/emv_tags.h" -#include "emv/dump.h" #include "emv/emvjson.h" #include "util.h" #include "proxmark3.h" #include "fileutils.h" #include "pm3_cmd.h" -#ifndef PRINT_INDENT -# define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");} -#endif - enum asn1_tag_t { ASN1_TAG_GENERIC, ASN1_TAG_BOOLEAN, @@ -109,65 +103,62 @@ static const struct asn1_tag *asn1_get_tag(const struct tlv *tlv) { return tag ? tag : &asn1_tags[0]; } -static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level, bool longyear, bool *needdump) { +static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag *tag, int level, bool longyear, bool *needdump) { int len = tlv->len; *needdump = false; int startindx = longyear ? 4 : 2; if (len > 4) { - fprintf(f, "\tvalue: '"); + PrintAndLogEx(NORMAL, " value: '" NOLF); while (true) { // year - if (!longyear) - fprintf(f, "20"); - fwrite(tlv->value, 1, longyear ? 4 : 2, f); - fprintf(f, "-"); + if (longyear == false) + PrintAndLogEx(NORMAL, "20" NOLF); + + PrintAndLogEx(NORMAL, "%s-" NOLF, sprint_hex(tlv->value, startindx) ); + if (len < startindx + 2) break; + // month - fwrite(&tlv->value[startindx], 1, 2, f); - fprintf(f, "-"); + PrintAndLogEx(NORMAL, "%02x%02x-" NOLF, tlv->value[startindx], tlv->value[startindx + 1]); if (len < startindx + 4) break; + // day - fwrite(&tlv->value[startindx + 2], 1, 2, f); - fprintf(f, " "); + PrintAndLogEx(NORMAL, "%02x%02x " NOLF, tlv->value[startindx + 2], tlv->value[startindx + 3]); if (len < startindx + 6) break; // hour - fwrite(&tlv->value[startindx + 4], 1, 2, f); - fprintf(f, ":"); + PrintAndLogEx(NORMAL, "%02x%02x:" NOLF, tlv->value[startindx + 4], tlv->value[startindx + 5]); if (len < startindx + 8) break; // min - fwrite(&tlv->value[startindx + 6], 1, 2, f); - fprintf(f, ":"); + PrintAndLogEx(NORMAL, "%02x%02x:" NOLF, tlv->value[startindx + 6], tlv->value[startindx + 7]); if (len < startindx + 10) break; // sec - fwrite(&tlv->value[startindx + 8], 1, 2, f); + PrintAndLogEx(NORMAL, "%02x%02x" NOLF, tlv->value[startindx + 8], tlv->value[startindx + 9]); if (len < startindx + 11) break; // time zone - fprintf(f, " zone: %.*s", len - 10 - (longyear ? 4 : 2), &tlv->value[startindx + 10]); - + PrintAndLogEx(NORMAL, " zone: %.*s" NOLF, len - 10 - (longyear ? 4 : 2), &tlv->value[startindx + 10]); break; } - fprintf(f, "'\n"); + PrintAndLogEx(NORMAL, "'"); } else { - fprintf(f, "\n"); + PrintAndLogEx(NORMAL, ""); *needdump = true; } } -static void asn1_tag_dump_string(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level) { - fprintf(f, "\tvalue: '"); - fwrite(tlv->value, 1, tlv->len, f); - fprintf(f, "'\n"); +static void asn1_tag_dump_string(const struct tlv *tlv, const struct asn1_tag *tag, int level) { + PrintAndLogEx(NORMAL, " value: '" NOLF); + PrintAndLogEx(NORMAL, "%s'", sprint_hex(tlv->value, tlv->len)); } -static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level, bool *needdump) { +static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_tag *tag, int level, bool *needdump) { *needdump = false; for (size_t i = 0; i < tlv->len; i++) if (!isspace(tlv->value[i]) && !isprint(tlv->value[i])) { @@ -176,10 +167,10 @@ static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_ } if (*needdump) { - fprintf(f, "'\n"); + PrintAndLogEx(NORMAL, "'"); } else { - fprintf(f, "\t\t"); - asn1_tag_dump_string(tlv, tag, f, level); + PrintAndLogEx(NORMAL, " " NOLF); + asn1_tag_dump_string(tlv, tag, level); } } @@ -213,25 +204,26 @@ static unsigned long asn1_value_integer(const struct tlv *tlv, unsigned start, u return ret; } -static void asn1_tag_dump_boolean(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level) { - PRINT_INDENT(level); +static void asn1_tag_dump_boolean(const struct tlv *tlv, const struct asn1_tag *tag, int level) { + PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " "); if (tlv->len > 0) { - fprintf(f, "\tvalue: %s\n", tlv->value[0] ? "true" : "false"); + PrintAndLogEx(NORMAL, " value: %s", tlv->value[0] ? "true" : "false"); } else { - fprintf(f, "n/a\n"); + PrintAndLogEx(NORMAL, "n/a"); } } -static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level) { - PRINT_INDENT(level); +static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag *tag, int level) { + PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " "); if (tlv->len == 4) { int32_t val = 0; - for (size_t i = 0; i < tlv->len; i++) + for (size_t i = 0; i < tlv->len; i++) { val = (val << 8) + tlv->value[i]; - fprintf(f, "\tvalue4b: %d\n", val); + } + PrintAndLogEx(NORMAL, " value4b: %d", val); return; } - fprintf(f, "\tvalue: %lu\n", asn1_value_integer(tlv, 0, tlv->len * 2)); + PrintAndLogEx(NORMAL, " value: %lu", asn1_value_integer(tlv, 0, tlv->len * 2)); } static char *asn1_oid_description(const char *oid, bool with_group_desc) { @@ -277,77 +269,77 @@ error: return NULL; } -static void asn1_tag_dump_object_id(const struct tlv *tlv, const struct asn1_tag *tag, FILE *f, int level) { - PRINT_INDENT(level); +static void asn1_tag_dump_object_id(const struct tlv *tlv, const struct asn1_tag *tag, int level) { + mbedtls_asn1_buf asn1_buf; asn1_buf.len = tlv->len; asn1_buf.p = (uint8_t *)tlv->value; char pstr[300]; mbedtls_oid_get_numeric_string(pstr, sizeof(pstr), &asn1_buf); - fprintf(f, " %s", pstr); + + PrintAndLogEx(INFO, "%*s %s" NOLF, (level * 4), " ", pstr); char *jsondesc = asn1_oid_description(pstr, true); if (jsondesc) { - fprintf(f, " - %s", jsondesc); + PrintAndLogEx(NORMAL, " - %s" NOLF, jsondesc); } else { const char *ppstr; mbedtls_oid_get_attr_short_name(&asn1_buf, &ppstr); if (ppstr && strnlen(ppstr, 1)) { - fprintf(f, " (%s)\n", ppstr); + PrintAndLogEx(NORMAL, " (%s)", ppstr); return; } mbedtls_oid_get_sig_alg_desc(&asn1_buf, &ppstr); if (ppstr && strnlen(ppstr, 1)) { - fprintf(f, " (%s)\n", ppstr); + PrintAndLogEx(NORMAL, " (%s)", ppstr); return; } mbedtls_oid_get_extended_key_usage(&asn1_buf, &ppstr); if (ppstr && strnlen(ppstr, 1)) { - fprintf(f, " (%s)\n", ppstr); + PrintAndLogEx(NORMAL, " (%s)", ppstr); return; } } - fprintf(f, "\n"); + PrintAndLogEx(NORMAL, ""); } -bool asn1_tag_dump(const struct tlv *tlv, FILE *f, int level, bool *candump) { - if (!tlv) { - fprintf(f, "NULL\n"); +bool asn1_tag_dump(const struct tlv *tlv, int level, bool *candump) { + if (tlv == NULL) { + PrintAndLogEx(FAILED, "NULL\n"); return false; } const struct asn1_tag *tag = asn1_get_tag(tlv); - PRINT_INDENT(level); - fprintf(f, "--%2x[%02zx] '%s':", tlv->tag, tlv->len, tag->name); + PrintAndLogEx(INFO, "%*s--%2x[%02zx] '%s':" NOLF, (level * 4), " ", tlv->tag, tlv->len, tag->name); switch (tag->type) { case ASN1_TAG_GENERIC: - fprintf(f, "\n"); + PrintAndLogEx(NORMAL, ""); break; case ASN1_TAG_STRING: - asn1_tag_dump_string(tlv, tag, f, level); + asn1_tag_dump_string(tlv, tag, level); *candump = false; break; case ASN1_TAG_OCTET_STRING: - asn1_tag_dump_octet_string(tlv, tag, f, level, candump); + asn1_tag_dump_octet_string(tlv, tag, level, candump); break; case ASN1_TAG_BOOLEAN: - asn1_tag_dump_boolean(tlv, tag, f, level); + asn1_tag_dump_boolean(tlv, tag, level); *candump = false; break; case ASN1_TAG_INTEGER: - asn1_tag_dump_integer(tlv, tag, f, level); + asn1_tag_dump_integer(tlv, tag, level); *candump = false; break; case ASN1_TAG_UTC_TIME: - asn1_tag_dump_str_time(tlv, tag, f, level, false, candump); + asn1_tag_dump_str_time(tlv, tag, level, false, candump); break; case ASN1_TAG_STR_TIME: - asn1_tag_dump_str_time(tlv, tag, f, level, true, candump); + asn1_tag_dump_str_time(tlv, tag, level, true, candump); break; case ASN1_TAG_OBJECT_ID: - asn1_tag_dump_object_id(tlv, tag, f, level); + asn1_tag_dump_object_id(tlv, tag, level); *candump = false; break; }; diff --git a/client/src/crypto/asn1dump.h b/client/src/crypto/asn1dump.h index c7aef7e39..21caae36d 100644 --- a/client/src/crypto/asn1dump.h +++ b/client/src/crypto/asn1dump.h @@ -13,9 +13,8 @@ #include #include #include -#include #include "emv/tlv.h" -bool asn1_tag_dump(const struct tlv *tlv, FILE *f, int level, bool *candump); +bool asn1_tag_dump(const struct tlv *tlv, int level, bool *candump); #endif /* asn1utils.h */ diff --git a/client/src/crypto/asn1utils.c b/client/src/crypto/asn1utils.c index 9e5826712..a076f207d 100644 --- a/client/src/crypto/asn1utils.c +++ b/client/src/crypto/asn1utils.c @@ -12,19 +12,16 @@ #include #include #include - #include "ui.h" // Print... - #include "emv/tlv.h" -#include "emv/dump.h" #include "asn1dump.h" #include "util.h" int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *rval, uint8_t *sval) { if (!signature || !signaturelen || !rval || !sval) - return 1; + return PM3_EINVARG; - int res = 0; + int res = PM3_SUCCESS; unsigned char *p = signature; const unsigned char *end = p + signaturelen; size_t len; @@ -57,7 +54,7 @@ int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *r // check size if (end != p) - return 2; + return PM3_ESOFT; } exit: @@ -66,9 +63,9 @@ exit: static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) { bool candump = true; - asn1_tag_dump(tlv, stdout, level, &candump); + asn1_tag_dump(tlv, level, &candump); if (is_leaf && candump) { - dump_buffer(tlv->value, tlv->len, stdout, level); + print_buffer(tlv->value, tlv->len, level); } } @@ -80,10 +77,10 @@ int asn1_print(uint8_t *asn1buf, size_t asn1buflen, const char *indent) { tlvdb_free(t); } else { PrintAndLogEx(ERR, "Can't parse data as TLV tree"); - return 1; + return PM3_ESOFT; } - return 0; + return PM3_SUCCESS; } diff --git a/client/src/crypto/libpcrypto.c b/client/src/crypto/libpcrypto.c index 3d8e7ffc4..cb73b3f5c 100644 --- a/client/src/crypto/libpcrypto.c +++ b/client/src/crypto/libpcrypto.c @@ -418,7 +418,7 @@ int ecdsa_nist_test(bool verbose) { // make signature res = ecdsa_signature_create_test(curveid, T_PRIVATE_KEY, T_Q_X, T_Q_Y, T_K, input, length, signature, &siglen); // PrintAndLogEx(INFO, "res: %x signature[%x]: %s", (res < 0)? -res : res, siglen, sprint_hex(signature, siglen)); - if (res) + if (res != PM3_SUCCESS) goto exit; // check vectors @@ -483,7 +483,7 @@ int ecdsa_nist_test(bool verbose) { if (verbose) PrintAndLogEx(NORMAL, _GREEN_("passed\n")); - return 0; + return PM3_SUCCESS; exit: if (verbose) PrintAndLogEx(NORMAL, _RED_("failed\n")); diff --git a/client/src/emv/cmdemv.c b/client/src/emv/cmdemv.c index fa1e9618a..3e0fec872 100644 --- a/client/src/emv/cmdemv.c +++ b/client/src/emv/cmdemv.c @@ -1153,7 +1153,7 @@ static int CmdEMVExec(const char *Cmd) { // 9F27: Cryptogram Information Data (CID) const struct tlv *CID = tlvdb_get(tlvRoot, 0x9F27, NULL); if (CID) { - emv_tag_dump(CID, stdout, 0); + emv_tag_dump(CID, 1); PrintAndLogEx(NORMAL, "------------------------------"); if (CID->len > 0) { switch (CID->value[0] & EMVAC_AC_MASK) { @@ -1356,10 +1356,10 @@ static int CmdEMVExec(const char *Cmd) { // here must be AC2, but we dont make external authenticate ( /* // AC2 PRINT_INDENT(level); - if ((CID & EMVAC_AC2_MASK) == EMVAC_AAC2) fprintf(f, "\tAC2: AAC (Transaction declined)\n"); - if ((CID & EMVAC_AC2_MASK) == EMVAC_TC2) fprintf(f, "\tAC2: TC (Transaction approved)\n"); - if ((CID & EMVAC_AC2_MASK) == EMVAC_ARQC2) fprintf(f, "\tAC2: not requested (ARQC)\n"); - if ((CID & EMVAC_AC2_MASK) == EMVAC_AC2_MASK) fprintf(f, "\tAC2: RFU\n"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_AAC2) PrintAndLogEx(NORMAL, "\tAC2: AAC (Transaction declined)"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_TC2) PrintAndLogEx(NORMAL, "\tAC2: TC (Transaction approved)"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_ARQC2) PrintAndLogEx(NORMAL, "\tAC2: not requested (ARQC)"); + if ((CID & EMVAC_AC2_MASK) == EMVAC_AC2_MASK) PrintAndLogEx(NORMAL, "\tAC2: RFU"); */ } } diff --git a/client/src/emv/dump.c b/client/src/emv/dump.c deleted file mode 100644 index 137fc5bdb..000000000 --- a/client/src/emv/dump.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * libopenemv - a library to work with EMV family of smart cards - * Copyright (C) 2015 Dmitry Eremin-Solenikov - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "dump.h" - -#ifndef PRINT_INDENT -# define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");} -#endif - -void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level) { - int j; - - if (!f) - f = stdout; - - for (int i = 0; i < len; i += 16) { - PRINT_INDENT(level); - fprintf(f, "\t%02x:", i); - for (j = 0; j < 16; j++) { - if (i + j < len) - fprintf(f, " %02hhx", ptr[i + j]); - else - fprintf(f, " "); - } - fprintf(f, " |"); - for (j = 0; j < 16 && i + j < len; j++) { - fprintf(f, "%c", (ptr[i + j] >= 0x20 && ptr[i + j] < 0x7f) ? ptr[i + j] : '.'); - } - fprintf(f, "\n"); - } -} diff --git a/client/src/emv/dump.h b/client/src/emv/dump.h deleted file mode 100644 index 77cd489f3..000000000 --- a/client/src/emv/dump.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * libopenemv - a library to work with EMV family of smart cards - * Copyright (C) 2015 Dmitry Eremin-Solenikov - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ - -#ifndef DUMP_H -#define DUMP_H - -#include "common.h" - -#include // FILE - -void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level); - -#endif diff --git a/client/src/emv/emv_pki.c b/client/src/emv/emv_pki.c index 0afcfe775..f06a5ea69 100644 --- a/client/src/emv/emv_pki.c +++ b/client/src/emv/emv_pki.c @@ -24,7 +24,6 @@ #include #include "crypto.h" -#include "dump.h" #include "util.h" #include "ui.h" @@ -73,7 +72,7 @@ static unsigned char *emv_pki_decode_message(const struct emv_pk *enc_pk, /* if (true){ PrintAndLogEx(SUCCESS, "Recovered data:\n"); - dump_buffer(data, data_len, stdout, 0); + print_buffer(data, data_len, 1); }*/ if (data[data_len - 1] != 0xbc || data[0] != 0x6a || data[1] != msgtype) { @@ -200,7 +199,7 @@ static struct emv_pk *emv_pki_decode_key_ex(const struct emv_pk *enc_pk, if (showData) { PrintAndLogEx(SUCCESS, "Recovered data:"); - dump_buffer(data, data_len, stdout, 0); + print_buffer(data, data_len, 1); } /* Perform the rest of checks here */ @@ -375,7 +374,7 @@ struct tlvdb *emv_pki_recover_dac_ex(const struct emv_pk *enc_pk, const struct t if (showData) { PrintAndLogEx(SUCCESS, "Recovered data:"); - dump_buffer(data, data_len, stdout, 0); + print_buffer(data, data_len, 1); } struct tlvdb *dac_db = tlvdb_fixed(0x9f45, 2, data + 3); @@ -409,7 +408,7 @@ struct tlvdb *emv_pki_recover_idn_ex(const struct emv_pk *enc_pk, const struct t if (showData) { PrintAndLogEx(SUCCESS, "Recovered data:"); - dump_buffer(data, data_len, stdout, 0); + print_buffer(data, data_len, 1); } size_t idn_len = data[4]; @@ -445,7 +444,7 @@ struct tlvdb *emv_pki_recover_atc_ex(const struct emv_pk *enc_pk, const struct t if (showData) { PrintAndLogEx(SUCCESS, "Recovered data:"); - dump_buffer(data, data_len, stdout, 0); + print_buffer(data, data_len, 1); } size_t idn_len = data[4]; @@ -511,7 +510,7 @@ struct tlvdb *emv_pki_perform_cda_ex(const struct emv_pk *enc_pk, const struct t if (showData) { PrintAndLogEx(SUCCESS, "Recovered data:"); - dump_buffer(data, data_len, stdout, 0); + print_buffer(data, data_len, 1); } if (data[3] < 30 || data[3] > data_len - 4) { diff --git a/client/src/emv/emv_tags.c b/client/src/emv/emv_tags.c index 296dcdf82..661df0e5e 100644 --- a/client/src/emv/emv_tags.c +++ b/client/src/emv/emv_tags.c @@ -18,15 +18,10 @@ #endif #include "emv_tags.h" - #include #include - #include "commonutil.h" - -#ifndef PRINT_INDENT -# define PRINT_INDENT(level) {for (int myi = 0; myi < (level); myi++) fprintf(f, " ");} -#endif +#include "ui.h" enum emv_tag_t { EMV_TAG_GENERIC, @@ -455,19 +450,21 @@ static const char *bitstrings[] = { "1.......", }; -static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { +static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *tag, int level) { const struct emv_tag_bit *bits = tag->data; unsigned bit, byte; for (byte = 1; byte <= tlv->len; byte ++) { unsigned char val = tlv->value[byte - 1]; - PRINT_INDENT(level); - fprintf(f, "\tByte %u (%02x)\n", byte, val); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Byte %u (%02x)", byte, val); for (bit = 8; bit > 0; bit--, val <<= 1) { if (val & 0x80) { - PRINT_INDENT(level); - fprintf(f, "\t\t%s - '%s'\n", bitstrings[bit - 1], - bits->bit == EMV_BIT(byte, bit) ? bits->name : "Unknown"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " %s - '%s'", + bitstrings[bit - 1], + (bits->bit == EMV_BIT(byte, bit)) ? bits->name : "Unknown" + ); } if (bits->bit == EMV_BIT(byte, bit)) bits ++; @@ -475,7 +472,7 @@ static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *ta } } -static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { +static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, int level) { const unsigned char *buf = tlv->value; size_t left = tlv->len; @@ -484,22 +481,20 @@ static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, F const struct emv_tag *doltag; if (!tlv_parse_tl(&buf, &left, &doltlv)) { - PRINT_INDENT(level); - fprintf(f, "Invalid Tag-Len\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, "Invalid Tag-Len"); continue; } doltag = emv_get_tag(&doltlv); - PRINT_INDENT(level); - fprintf(f, "\tTag %4x len %02zx ('%s')\n", doltlv.tag, doltlv.len, doltag->name); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Tag %4x len %02zx ('%s')", doltlv.tag, doltlv.len, doltag->name); } } -static void emv_tag_dump_string(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - fprintf(f, "\tString value '"); - fwrite(tlv->value, 1, tlv->len, f); - fprintf(f, "'\n"); +static void emv_tag_dump_string(const struct tlv *tlv, const struct emv_tag *tag, int level) { + PrintAndLogEx(NORMAL, " String value '%s'", sprint_hex_inrow(tlv->value, tlv->len)); } static unsigned long emv_value_numeric(const struct tlv *tlv, unsigned start, unsigned end) { @@ -532,17 +527,18 @@ static unsigned long emv_value_numeric(const struct tlv *tlv, unsigned start, un return ret; } -static void emv_tag_dump_numeric(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - PRINT_INDENT(level); - fprintf(f, "\tNumeric value %lu\n", emv_value_numeric(tlv, 0, tlv->len * 2)); +static void emv_tag_dump_numeric(const struct tlv *tlv, const struct emv_tag *tag, int level) { + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Numeric value %lu", emv_value_numeric(tlv, 0, tlv->len * 2)); } -static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - PRINT_INDENT(level); - fprintf(f, "\tDate: 20%02lu.%lu.%lu\n", +static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, int level) { + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Date: 20%02lu.%lu.%lu", emv_value_numeric(tlv, 0, 2), emv_value_numeric(tlv, 2, 4), - emv_value_numeric(tlv, 4, 6)); + emv_value_numeric(tlv, 4, 6) + ); } static uint32_t emv_get_binary(const unsigned char *S) { @@ -550,44 +546,44 @@ static uint32_t emv_get_binary(const unsigned char *S) { } // https://github.com/binaryfoo/emv-bertlv/blob/master/src/main/resources/fields/visa-cvr.txt -static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - if (!tlv || tlv->len < 1) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID!\n"); +static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, int level) { + if (tlv == NULL || tlv->len < 1) { + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID length!"); return; } if (tlv->len != tlv->value[0] + 1) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID length!\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID length!"); return; } if (tlv->len >= 2) { // AC1 - PRINT_INDENT(level); - if ((tlv->value[1] & 0xC0) == 0x00) fprintf(f, "\tAC1: AAC (Transaction declined)\n"); - if ((tlv->value[1] & 0xC0) == 0x40) fprintf(f, "\tAC1: TC (Transaction approved)\n"); - if ((tlv->value[1] & 0xC0) == 0x80) fprintf(f, "\tAC1: ARQC (Online authorisation requested)\n"); - if ((tlv->value[1] & 0xC0) == 0xC0) fprintf(f, "\tAC1: RFU\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + if ((tlv->value[1] & 0xC0) == 0x00) PrintAndLogEx(NORMAL, " AC1: AAC (Transaction declined)"); + if ((tlv->value[1] & 0xC0) == 0x40) PrintAndLogEx(NORMAL, " AC1: TC (Transaction approved)"); + if ((tlv->value[1] & 0xC0) == 0x80) PrintAndLogEx(NORMAL, " AC1: ARQC (Online authorisation requested)"); + if ((tlv->value[1] & 0xC0) == 0xC0) PrintAndLogEx(NORMAL, " AC1: RFU"); // AC2 - PRINT_INDENT(level); - if ((tlv->value[1] & 0x30) == 0x00) fprintf(f, "\tAC2: AAC (Transaction declined)\n"); - if ((tlv->value[1] & 0x30) == 0x10) fprintf(f, "\tAC2: TC (Transaction approved)\n"); - if ((tlv->value[1] & 0x30) == 0x20) fprintf(f, "\tAC2: not requested (ARQC)\n"); - if ((tlv->value[1] & 0x30) == 0x30) fprintf(f, "\tAC2: RFU\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + if ((tlv->value[1] & 0x30) == 0x00) PrintAndLogEx(NORMAL, " AC2: AAC (Transaction declined)"); + if ((tlv->value[1] & 0x30) == 0x10) PrintAndLogEx(NORMAL, " AC2: TC (Transaction approved)"); + if ((tlv->value[1] & 0x30) == 0x20) PrintAndLogEx(NORMAL, " AC2: not requested (ARQC)"); + if ((tlv->value[1] & 0x30) == 0x30) PrintAndLogEx(NORMAL, " AC2: RFU"); } if (tlv->len >= 3 && (tlv->value[2] >> 4)) { - PRINT_INDENT(level); - fprintf(f, "\tPIN try: %x\n", tlv->value[2] >> 4); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " PIN try: %x", tlv->value[2] >> 4); } if (tlv->len >= 4 && (tlv->value[3] & 0x0F)) { - PRINT_INDENT(level); - fprintf(f, "\tIssuer discretionary bits: %x\n", tlv->value[3] & 0x0F); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Issuer discretionary bits: %x", tlv->value[3] & 0x0F); } if (tlv->len >= 5 && (tlv->value[4] >> 4)) { - PRINT_INDENT(level); - fprintf(f, "\tSuccessfully processed issuer script commands: %x\n", tlv->value[4] >> 4); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Successfully processed issuer script commands: %x", tlv->value[4] >> 4); } // mask 0F 0F F0 0F @@ -610,68 +606,73 @@ static void emv_tag_dump_cvr(const struct tlv *tlv, const struct emv_tag *tag, F }; if (data[0] || data[1] || data[2] || data[3]) - emv_tag_dump_bitmask(&bit_tlv, &bit_tag, f, level); + emv_tag_dump_bitmask(&bit_tlv, &bit_tag, level); } // EMV Book 3 -static void emv_tag_dump_cid(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { - if (!tlv || tlv->len < 1) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID!\n"); +static void emv_tag_dump_cid(const struct tlv *tlv, const struct emv_tag *tag, int level) { + if (tlv == NULL || tlv->len < 1) { + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID!"); return; } - PRINT_INDENT(level); - if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AAC) fprintf(f, "\tAC1: AAC (Transaction declined)\n"); - if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_TC) fprintf(f, "\tAC1: TC (Transaction approved)\n"); - if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_ARQC) fprintf(f, "\tAC1: ARQC (Online authorisation requested)\n"); - if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AC_MASK) fprintf(f, "\tAC1: RFU\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + + if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AAC) + PrintAndLogEx(NORMAL, " AC1: AAC (Transaction declined)"); + if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_TC) + PrintAndLogEx(NORMAL, " AC1: TC (Transaction approved)"); + if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_ARQC) + PrintAndLogEx(NORMAL, " AC1: ARQC (Online authorisation requested)"); + if ((tlv->value[0] & EMVAC_AC_MASK) == EMVAC_AC_MASK) + PrintAndLogEx(NORMAL, " AC1: RFU"); if (tlv->value[0] & EMVCID_ADVICE) { - PRINT_INDENT(level); - fprintf(f, "\tAdvice required!\n"); + PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Advice required!"); } if (tlv->value[0] & EMVCID_REASON_MASK) { - PRINT_INDENT(level); - fprintf(f, "\tReason/advice/referral code: "); + PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Reason/advice/referral code: " NOLF); switch ((tlv->value[0] & EMVCID_REASON_MASK)) { case 0: - fprintf(f, "No information given\n"); + PrintAndLogEx(NORMAL, "No information given"); break; case 1: - fprintf(f, "Service not allowed\n"); + PrintAndLogEx(NORMAL, "Service not allowed"); break; case 2: - fprintf(f, "PIN Try Limit exceeded\n"); + PrintAndLogEx(NORMAL, "PIN Try Limit exceeded"); break; case 3: - fprintf(f, "Issuer authentication failed\n"); + PrintAndLogEx(NORMAL, "Issuer authentication failed"); break; default: - fprintf(f, "\tRFU: %2x\n", (tlv->value[0] & EMVCID_REASON_MASK)); + PrintAndLogEx(NORMAL, " RFU: %2x", (tlv->value[0] & EMVCID_REASON_MASK)); break; } } } -static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { +static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *tag, int level) { uint32_t X, Y; int i; if (tlv->len < 10 || tlv->len % 2) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID!\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID!"); return; } X = emv_get_binary(tlv->value); Y = emv_get_binary(tlv->value + 4); - PRINT_INDENT(level); - fprintf(f, "\tX: %u\n", X); - PRINT_INDENT(level); - fprintf(f, "\tY: %u\n", Y); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " X: %u", X); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " Y: %u", Y); for (i = 8; i < tlv->len; i += 2) { const char *method; @@ -746,73 +747,76 @@ static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *t break; } - PRINT_INDENT(level); - fprintf(f, "\t%02x %02x: '%s' '%s' and '%s' if this CVM is unsuccessful\n", - tlv->value[i], tlv->value[i + 1], - method, condition, (tlv->value[i] & 0x40) ? "continue" : "fail"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " %02x %02x: '%s' '%s' and '%s' if this CVM is unsuccessful", + tlv->value[i], + tlv->value[i + 1], + method, + condition, + (tlv->value[i] & 0x40) ? "continue" : "fail" + ); } } -static void emv_tag_dump_afl(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level) { +static void emv_tag_dump_afl(const struct tlv *tlv, const struct emv_tag *tag, int level) { if (tlv->len < 4 || tlv->len % 4) { - PRINT_INDENT(level); - fprintf(f, "\tINVALID!\n"); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, " INVALID!"); return; } for (int i = 0; i < tlv->len / 4; i++) { - PRINT_INDENT(level); - fprintf(f, "SFI[%02x] start:%02x end:%02x offline:%02x\n", tlv->value[i * 4 + 0] >> 3, tlv->value[i * 4 + 1], tlv->value[i * 4 + 2], tlv->value[i * 4 + 3]); + PrintAndLogEx(INFO, "%*s" NOLF, (level * 4), " "); + PrintAndLogEx(NORMAL, "SFI[%02x] start:%02x end:%02x offline:%02x", tlv->value[i * 4 + 0] >> 3, tlv->value[i * 4 + 1], tlv->value[i * 4 + 2], tlv->value[i * 4 + 3]); } } -bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level) { - if (!tlv) { - fprintf(f, "NULL\n"); +bool emv_tag_dump(const struct tlv *tlv, int level) { + if (tlv == NULL) { + PrintAndLogEx(FAILED, "NULL"); return false; } const struct emv_tag *tag = emv_get_tag(tlv); - PRINT_INDENT(level); - fprintf(f, "--%2x[%02zx] '%s':", tlv->tag, tlv->len, tag->name); + PrintAndLogEx(INFO, "%*s--%2x[%02zx] '%s':" NOLF, (level * 4), " ", tlv->tag, tlv->len, tag->name); switch (tag->type) { case EMV_TAG_GENERIC: - fprintf(f, "\n"); + PrintAndLogEx(NORMAL, ""); break; case EMV_TAG_BITMASK: - fprintf(f, "\n"); - emv_tag_dump_bitmask(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_bitmask(tlv, tag, level); break; case EMV_TAG_DOL: - fprintf(f, "\n"); - emv_tag_dump_dol(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_dol(tlv, tag, level); break; case EMV_TAG_CVM_LIST: - fprintf(f, "\n"); - emv_tag_dump_cvm_list(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_cvm_list(tlv, tag, level); break; case EMV_TAG_AFL: - fprintf(f, "\n"); - emv_tag_dump_afl(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_afl(tlv, tag, level); break; case EMV_TAG_STRING: - emv_tag_dump_string(tlv, tag, f, level); + emv_tag_dump_string(tlv, tag, level); break; case EMV_TAG_NUMERIC: - emv_tag_dump_numeric(tlv, tag, f, level); + emv_tag_dump_numeric(tlv, tag, level); break; case EMV_TAG_YYMMDD: - emv_tag_dump_yymmdd(tlv, tag, f, level); + emv_tag_dump_yymmdd(tlv, tag, level); break; case EMV_TAG_CVR: - fprintf(f, "\n"); - emv_tag_dump_cvr(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_cvr(tlv, tag, level); break; case EMV_TAG_CID: - fprintf(f, "\n"); - emv_tag_dump_cid(tlv, tag, f, level); + PrintAndLogEx(NORMAL, ""); + emv_tag_dump_cid(tlv, tag, level); break; }; diff --git a/client/src/emv/emv_tags.h b/client/src/emv/emv_tags.h index 235048b20..2da2cd2ef 100644 --- a/client/src/emv/emv_tags.h +++ b/client/src/emv/emv_tags.h @@ -17,7 +17,6 @@ #define TAGS_H #include "tlv.h" -#include // FILE // AC # define EMVAC_AC_MASK 0xC0 @@ -34,7 +33,7 @@ # define EMVCID_ADVICE 0x08 # define EMVCID_REASON_MASK 0x07 -bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level); +bool emv_tag_dump(const struct tlv *tlv, int level); const char *emv_get_tag_name(const struct tlv *tlv); #endif diff --git a/client/src/emv/emvcore.c b/client/src/emv/emvcore.c index 23de78c7d..913316725 100644 --- a/client/src/emv/emvcore.c +++ b/client/src/emv/emvcore.c @@ -19,7 +19,6 @@ #include "ui.h" #include "cmdhf14a.h" #include "dol.h" -#include "dump.h" #include "emv_tags.h" #include "emvjson.h" #include "util_posix.h" @@ -158,9 +157,9 @@ enum CardPSVendor GetCardPSVendor(uint8_t *AID, size_t AIDlen) { } static void print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) { - emv_tag_dump(tlv, stdout, level); + emv_tag_dump(tlv, level); if (is_leaf) { - dump_buffer(tlv->value, tlv->len, stdout, level); + print_buffer(tlv->value, tlv->len, level); } } @@ -805,6 +804,7 @@ int trDDA(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { emv_pk_free(pk); emv_pk_free(issuer_pk); emv_pk_free(icc_pk); + atc_db = NULL; return 9; } } else { diff --git a/client/src/emv/test/cda_test.c b/client/src/emv/test/cda_test.c index acdde8bb4..b5a87952c 100644 --- a/client/src/emv/test/cda_test.c +++ b/client/src/emv/test/cda_test.c @@ -23,10 +23,10 @@ #include "../emv_pk.h" #include "../crypto.h" -#include "../dump.h" #include "../tlv.h" #include "../emv_pki.h" #include "ui.h" // printandlog +#include "util.h" // print_buffer struct emv_pk c_mchip_05 = { .rid = { 0xa0, 0x00, 0x00, 0x00, 0x04, }, @@ -172,7 +172,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "issuer cert:"); - dump_buffer(ipk_data, ipk_data_len, stdout, 0); + print_buffer(ipk_data, ipk_data_len, 1); } size_t ipk_pk_len = ipk_data[13]; @@ -202,7 +202,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash:"); - dump_buffer(h, 20, stdout, 0); + print_buffer(h, 20, 1); } if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) { @@ -231,7 +231,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "icc cert:"); - dump_buffer(iccpk_data, iccpk_data_len, stdout, 0); + print_buffer(iccpk_data, iccpk_data_len, 1); } size_t iccpk_pk_len = iccpk_data[19]; @@ -260,7 +260,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash1.1:"); - dump_buffer(h, 20, stdout, 0); + print_buffer(h, 20, 1); } if (memcmp(iccpk_data + iccpk_data_len - 21, h, 20)) { @@ -287,7 +287,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "SDAD:"); - dump_buffer(sdad, sdad_len, stdout, 0); + print_buffer(sdad, sdad_len, 1); } ch = crypto_hash_open(HASH_SHA_1); @@ -308,7 +308,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash2:"); - dump_buffer(h2, 20, stdout, 0); + print_buffer(h2, 20, 1); } crypto_hash_close(ch); @@ -331,7 +331,7 @@ static int cda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash2.1:"); - dump_buffer(h, 20, stdout, 0); + print_buffer(h, 20, 1); } if (memcmp(sdad + 5 + 8 + 1 + 8, h, 20)) { @@ -408,7 +408,7 @@ static int cda_test_pk(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "IDN:"); - dump_buffer(idn->value, idn->len, stdout, 0); + print_buffer(idn->value, idn->len, 1); } tlvdb_free(idndb); diff --git a/client/src/emv/test/crypto_test.c b/client/src/emv/test/crypto_test.c index e3b8124f0..987a672da 100644 --- a/client/src/emv/test/crypto_test.c +++ b/client/src/emv/test/crypto_test.c @@ -24,7 +24,6 @@ #include "commonutil.h" // ARRAYLEN #include "../crypto.h" -#include "../dump.h" #include "util_posix.h" #include "ui.h" // printandlog diff --git a/client/src/emv/test/dda_test.c b/client/src/emv/test/dda_test.c index 7bf6d4975..c36af108d 100644 --- a/client/src/emv/test/dda_test.c +++ b/client/src/emv/test/dda_test.c @@ -23,11 +23,10 @@ #include "dda_test.h" #include "../emv_pk.h" #include "../crypto.h" -#include "../dump.h" #include "../tlv.h" #include "../emv_pki.h" #include "ui.h" // printandlog - +#include "util.h" // print_buffer struct emv_pk mchip_05 = { .rid = { 0xa0, 0x00, 0x00, 0x00, 0x04, }, @@ -161,7 +160,7 @@ static int dda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "issuer cert:"); - dump_buffer(ipk_data, ipk_data_len, stdout, 0); + print_buffer(ipk_data, ipk_data_len, 1); } size_t ipk_pk_len = ipk_data[13]; @@ -191,7 +190,7 @@ static int dda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash:"); - dump_buffer(h, 20, stdout, 0); + print_buffer(h, 20, 1); } if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) { @@ -220,7 +219,7 @@ static int dda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "icc cert:"); - dump_buffer(iccpk_data, iccpk_data_len, stdout, 0); + print_buffer(iccpk_data, iccpk_data_len, 1); } size_t iccpk_pk_len = iccpk_data[19]; @@ -249,7 +248,7 @@ static int dda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash1.1:"); - dump_buffer(h, 20, stdout, 0); + print_buffer(h, 20, 1); } if (memcmp(iccpk_data + iccpk_data_len - 21, h, 20)) { @@ -276,7 +275,7 @@ static int dda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "sdad:"); - dump_buffer(sdad, sdad_len, stdout, 0); + print_buffer(sdad, sdad_len, 1); } ch = crypto_hash_open(HASH_SHA_1); @@ -297,7 +296,7 @@ static int dda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash2:"); - dump_buffer(h2, 20, stdout, 0); + print_buffer(h2, 20, 1); } crypto_hash_close(ch); @@ -356,7 +355,7 @@ static int dda_test_pk(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "IDN:"); - dump_buffer(idn->value, idn->len, stdout, 0); + print_buffer(idn->value, idn->len, 1); } tlvdb_free(idndb); diff --git a/client/src/emv/test/sda_test.c b/client/src/emv/test/sda_test.c index 04f3b70ae..731adb563 100644 --- a/client/src/emv/test/sda_test.c +++ b/client/src/emv/test/sda_test.c @@ -23,10 +23,10 @@ #include "../emv_pk.h" #include "../crypto.h" -#include "../dump.h" #include "../tlv.h" #include "../emv_pki.h" #include "ui.h" // printandlog +#include "util.h" // print_buffer #include "sda_test.h" struct emv_pk vsdc_01 = { @@ -122,7 +122,7 @@ static int sda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "issuer cert:"); - dump_buffer(ipk_data, ipk_data_len, stdout, 0); + print_buffer(ipk_data, ipk_data_len, 1); } size_t ipk_pk_len = ipk_data[13]; @@ -152,7 +152,7 @@ static int sda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash:"); - dump_buffer(h, 20, stdout, 0); + print_buffer(h, 20, 1); } if (memcmp(ipk_data + ipk_data_len - 21, h, 20)) { @@ -179,7 +179,7 @@ static int sda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "ssad:"); - dump_buffer(ssad, ssad_len, stdout, 0); + print_buffer(ssad, ssad_len, 1); } ch = crypto_hash_open(HASH_SHA_1); @@ -200,7 +200,7 @@ static int sda_test_raw(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "crypto hash2:"); - dump_buffer(h2, 20, stdout, 0); + print_buffer(h2, 20, 1); } crypto_hash_close(ch); @@ -245,7 +245,7 @@ static int sda_test_pk(bool verbose) { if (verbose) { PrintAndLogEx(INFO, "dac:"); - dump_buffer(dac->value, dac->len, stdout, 0); + print_buffer(dac->value, dac->len, 1); } tlvdb_free(dacdb); diff --git a/client/src/fido/fidocore.c b/client/src/fido/fidocore.c index 26fa30dc4..abe3f28ce 100644 --- a/client/src/fido/fidocore.c +++ b/client/src/fido/fidocore.c @@ -22,7 +22,6 @@ #include "crypto/libpcrypto.h" #include "additional_ca.h" #include "cose.h" -#include "emv/dump.h" #include "ui.h" #include "util.h" @@ -364,7 +363,7 @@ static int FIDO2CheckSignature(json_t *root, uint8_t *publickey, uint8_t *sign, uint8_t sval[300] = {0}; int res = ecdsa_asn1_get_signature(sign, signLen, rval, sval); - if (!res) { + if (res == PM3_SUCCESS) { if (verbose) { PrintAndLogEx(INFO, " r: %s", sprint_hex(rval, 32)); PrintAndLogEx(INFO, " s: %s", sprint_hex(sval, 32)); diff --git a/client/src/mifare/ndef.c b/client/src/mifare/ndef.c index 785b822db..bd1109e80 100644 --- a/client/src/mifare/ndef.c +++ b/client/src/mifare/ndef.c @@ -14,7 +14,6 @@ #include "ui.h" #include "util.h" // sprint_hex... -#include "emv/dump.h" #include "crypto/asn1utils.h" #include "pm3_cmd.h" @@ -181,7 +180,7 @@ static int ndefDecodeSig1(uint8_t *sig, size_t siglen) { uint8_t rval[300] = {0}; uint8_t sval[300] = {0}; int res = ecdsa_asn1_get_signature(&sig[indx], intsiglen, rval, sval); - if (!res) { + if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\t\tr: %s", sprint_hex(rval + 32 - slen, slen)); PrintAndLogEx(SUCCESS, "\t\ts: %s", sprint_hex(sval + 32 - slen, slen)); } @@ -375,15 +374,15 @@ static int ndefRecordDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { if (NDEFHeader.TypeLen) { PrintAndLogEx(INFO, "Type data:"); - dump_buffer(NDEFHeader.Type, NDEFHeader.TypeLen, stdout, 1); + print_buffer(NDEFHeader.Type, NDEFHeader.TypeLen, 1); } if (NDEFHeader.IDLen) { PrintAndLogEx(INFO, "ID data:"); - dump_buffer(NDEFHeader.ID, NDEFHeader.IDLen, stdout, 1); + print_buffer(NDEFHeader.ID, NDEFHeader.IDLen, 1); } if (NDEFHeader.PayloadLen) { PrintAndLogEx(INFO, "Payload data:"); - dump_buffer(NDEFHeader.Payload, NDEFHeader.PayloadLen, stdout, 1); + print_buffer(NDEFHeader.Payload, NDEFHeader.PayloadLen, 1); if (NDEFHeader.TypeLen) ndefDecodePayload(&NDEFHeader); } diff --git a/client/src/pm3.i b/client/src/pm3.i index 5b4a1fb47..dc47563b2 100644 --- a/client/src/pm3.i +++ b/client/src/pm3.i @@ -11,22 +11,22 @@ typedef struct { %extend { pm3() { - printf("SWIG pm3 constructor, get current pm3\n"); +// printf("SWIG pm3 constructor, get current pm3\n"); pm3_device * p = pm3_get_current_dev(); p->script_embedded = 1; return p; } pm3(char *port) { - printf("SWIG pm3 constructor with port, open pm3\n"); +// printf("SWIG pm3 constructor with port, open pm3\n"); pm3_device * p = pm3_open(port); p->script_embedded = 0; return p; } ~pm3() { if ($self->script_embedded) { - printf("SWIG pm3 destructor, nothing to do\n"); +// printf("SWIG pm3 destructor, nothing to do\n"); } else { - printf("SWIG pm3 destructor, close pm3\n"); +// printf("SWIG pm3 destructor, close pm3\n"); pm3_close($self); } } diff --git a/client/src/pm3_luawrap.c b/client/src/pm3_luawrap.c index 2dc4a8dc0..cc8ca7dcf 100644 --- a/client/src/pm3_luawrap.c +++ b/client/src/pm3_luawrap.c @@ -2687,7 +2687,7 @@ static swig_module_info swig_module = {swig_types, 1, 0, 0, 0, 0}; #include "comms.h" SWIGINTERN pm3 *new_pm3__SWIG_0(void){ - printf("SWIG pm3 constructor, get current pm3\n"); +// printf("SWIG pm3 constructor, get current pm3\n"); pm3_device * p = pm3_get_current_dev(); p->script_embedded = 1; return p; @@ -2701,16 +2701,16 @@ SWIGINTERN int SWIG_lua_isnilstring(lua_State *L, int idx) { } SWIGINTERN pm3 *new_pm3__SWIG_1(char *port){ - printf("SWIG pm3 constructor with port, open pm3\n"); +// printf("SWIG pm3 constructor with port, open pm3\n"); pm3_device * p = pm3_open(port); p->script_embedded = 0; return p; } SWIGINTERN void delete_pm3(pm3 *self){ if (self->script_embedded) { - printf("SWIG pm3 destructor, nothing to do\n"); +// printf("SWIG pm3 destructor, nothing to do\n"); } else { - printf("SWIG pm3 destructor, close pm3\n"); +// printf("SWIG pm3 destructor, close pm3\n"); pm3_close(self); } } diff --git a/client/src/pm3_pywrap.c b/client/src/pm3_pywrap.c index a3a5812ff..03a584e48 100644 --- a/client/src/pm3_pywrap.c +++ b/client/src/pm3_pywrap.c @@ -2672,7 +2672,7 @@ static swig_module_info swig_module = {swig_types, 2, 0, 0, 0, 0}; #include "comms.h" SWIGINTERN pm3 *new_pm3__SWIG_0(void){ - printf("SWIG pm3 constructor, get current pm3\n"); +// printf("SWIG pm3 constructor, get current pm3\n"); pm3_device * p = pm3_get_current_dev(); p->script_embedded = 1; return p; @@ -2801,16 +2801,16 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) SWIGINTERN pm3 *new_pm3__SWIG_1(char *port){ - printf("SWIG pm3 constructor with port, open pm3\n"); +// printf("SWIG pm3 constructor with port, open pm3\n"); pm3_device * p = pm3_open(port); p->script_embedded = 0; return p; } SWIGINTERN void delete_pm3(pm3 *self){ if (self->script_embedded) { - printf("SWIG pm3 destructor, nothing to do\n"); +// printf("SWIG pm3 destructor, nothing to do\n"); } else { - printf("SWIG pm3 destructor, close pm3\n"); +// printf("SWIG pm3 destructor, close pm3\n"); pm3_close(self); } } diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 113da7248..539b7a20b 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -898,7 +898,7 @@ int main(int argc, char *argv[]) { // execute pm3 command file if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--script-file") == 0) { - if (i + 1 == argc) { + if (i + 1 == argc || strlen(argv[i + 1]) == 0) { PrintAndLogEx(ERR, _RED_("ERROR:") " missing script file specification after -s\n"); show_help(false, exec_name); return 1; @@ -910,7 +910,7 @@ int main(int argc, char *argv[]) { // execute lua script if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "--lua") == 0) { addLuaExec = true; - if (i + 1 == argc) { + if (i + 1 == argc || strlen(argv[i + 1]) == 0) { PrintAndLogEx(ERR, _RED_("ERROR:") " missing lua script specification after -l\n"); show_help(false, exec_name); return 1; diff --git a/client/src/util.c b/client/src/util.c index 6a49a27dd..2e1cfb0bd 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -200,6 +200,52 @@ void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) { PrintAndLogEx(NORMAL, ""); } +void print_buffer(const uint8_t *data, const size_t len, int level) { + + if (len < 1) + return; + + char buf[UTIL_BUFFER_SIZE_SPRINT + 3]; + int i; + for (i = 0; i < len; i += 16) { + + // (16 * 3) + (16) + + 1 + memset(buf, 0, sizeof(buf)); + sprintf(buf, "%*s%02x: ", (level * 4), " ", i); + + hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, 16, (sizeof(buf) - strlen(buf) - 1), 0, 1, true); + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, 16)); + PrintAndLogEx(INFO, "%s", buf); + } + + // the last odd bytes + uint8_t mod = len % 16; + + if (mod) { + memset(buf, 0, sizeof(buf)); + sprintf(buf, "%*s%02x: ", (level * 4), " ", i); + hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, mod, (sizeof(buf) - strlen(buf) - 1), 0, 1, true); + + // add the spaces... + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%*s", ((16 - mod) * 3) , " "); + + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, mod)); + PrintAndLogEx(INFO, "%s", buf); + } +} + +void print_blocks(uint32_t *data, size_t len) { + PrintAndLogEx(SUCCESS, "Blk | Data "); + PrintAndLogEx(SUCCESS, "----+------------"); + + if (!data) { + PrintAndLogEx(ERR, "..empty data"); + } else { + for (uint8_t i = 0; i < len; i++) + PrintAndLogEx(SUCCESS, " %02d | %08X", i, data[i]); + } +} + char *sprint_hex(const uint8_t *data, const size_t len) { static char buf[UTIL_BUFFER_SIZE_SPRINT - 3] = {0}; hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, 1, true); @@ -344,18 +390,6 @@ char *sprint_ascii(const uint8_t *data, const size_t len) { return sprint_ascii_ex(data, len, 0); } -void print_blocks(uint32_t *data, size_t len) { - PrintAndLogEx(SUCCESS, "Blk | Data "); - PrintAndLogEx(SUCCESS, "----+------------"); - - if (!data) { - PrintAndLogEx(ERR, "..empty data"); - } else { - for (uint8_t i = 0; i < len; i++) - PrintAndLogEx(SUCCESS, " %02d | %08X", i, data[i]); - } -} - int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen) { char buf[4] = {0}; int indx = 0; diff --git a/client/src/util.h b/client/src/util.h index f65c94622..51100731e 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -50,6 +50,7 @@ char *sprint_hex_ascii(const uint8_t *data, const size_t len); char *sprint_ascii(const uint8_t *data, const size_t len); char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len); +void print_buffer(const uint8_t *data, const size_t len, int level); void print_blocks(uint32_t *data, size_t len); int hex_to_bytes(const char *hexValue, uint8_t *bytesValue, size_t maxBytesValueLen); diff --git a/pm3 b/pm3 index 4349ed643..27e992b11 100755 --- a/pm3 +++ b/pm3 @@ -11,22 +11,36 @@ FINDBTRFCOMM=true FINDBTDIRECT=true PM3PATH=$(dirname "$0") +EVALENV="" FULLIMAGE="fullimage.elf" BOOTIMAGE="bootrom.elf" # try pm3 dirs in current repo workdir if [ -d "$PM3PATH/client/" ]; then - CLIENT="$PM3PATH/client/proxmark3" + if [ -x "$PM3PATH/client/proxmark3" ]; then + CLIENT="$PM3PATH/client/proxmark3" + elif [ -x "$PM3PATH/client/build/proxmark3" ]; then + CLIENT="$PM3PATH/client/build/proxmark3" + else + echo >&2 "[!!] In devel workdir but no executable found, did you compile it?" + exit 1 + fi + # Devel mode: point to workdir pm3.py module + EVALENV+=" PYTHONPATH=$PM3PATH/client/src" # try install dir elif [ -x "$PM3PATH/proxmark3" ]; then CLIENT="$PM3PATH/proxmark3" + EVALENV+=" PYTHONPATH=$PM3PATH/../share/proxmark3/pyscripts/" + # or /usr/[local/]lib/python3/dist-packages/pm3.py ? else -# hope it's installed somehow, still not sure where fw images are... +# hope it's installed somehow, still not sure where fw images and pm3.py are... CLIENT="proxmark3" fi -EVALENV="" # LeakSanitizer suppressions if [ -e .lsan_suppressions ]; then - EVALENV="export LSAN_OPTIONS=suppressions=.lsan_suppressions" + EVALENV+=" LSAN_OPTIONS=suppressions=.lsan_suppressions" +fi +if [ "$EVALENV" != "" ]; then + EVALENV="export $EVALENV" fi PM3LIST=() SHOWLIST=false