Merge branch 'master' into allin

update 201114
This commit is contained in:
tharexde 2020-11-14 19:56:02 +01:00
commit 79e1159eaf
56 changed files with 713 additions and 1114 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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

View file

@ -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))

View file

@ -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

View file

@ -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;
}

View file

@ -1 +0,0 @@
build/

View file

@ -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

View file

@ -1,5 +1,6 @@
#!/bin/bash
cd ..
rm -rf build
mkdir build
(
@ -7,4 +8,3 @@ mkdir build
cmake ..
make -j
)

View file

@ -0,0 +1,4 @@
#!/bin/bash
cd ..
make -j

View file

@ -1,3 +1,3 @@
#!/bin/bash
build/proxmark3 /dev/ttyACM0 -c "script run testembedded.lua"
../../pm3 -c "script run testembedded.lua"

View file

@ -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"

View file

@ -0,0 +1,3 @@
#!/bin/bash
../../pm3 -c "script run testembedded_grab.py" -i

View file

@ -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=<path-to-your-android-ndk>/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)

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,3 @@
#!/bin/bash
PYTHONPATH=../../src ipython3 -i ./test_grab.py

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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] <milliseconds> [-b] <number of bits> <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");
@ -1125,7 +1111,7 @@ static int CmdHF14AAPDU(const char *Cmd) {
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", "<head (CLA INS P1 P2) hex>", "make apdu with head from this field and data from data field. Must be 4 bytes length: <CLA INS P1 P2>"),
@ -1225,98 +1211,55 @@ 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, "<dec>", "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", "<ms>", "timeout in milliseconds"),
arg_lit0(NULL, "topaz", "use Topaz protocol to send command"),
arg_strx1(NULL, NULL, "<hex>", "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;
}
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)
// 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");
break;
return PM3_EINVARG;
}
}
continue;
}
PrintAndLogEx(FAILED, "Invalid char on input");
return PM3_ESOFT;
}
if (crc && datalen > 0 && datalen < sizeof(data) - 2) {
uint8_t first, second;
@ -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);
PrintAndLogEx(SUCCESS, "%s[%02X %02X] %s",
sprint_hex(data, len - 2),
char s[16];
sprintf(s,
(crc) ? _GREEN_("%02X %02X") : _RED_("%02X %02X"),
data[len - 2],
data[len - 1],
(crc) ? _GREEN_("ok") : _RED_("fail")
data[len - 1]
);
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) {

View file

@ -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 :)

View file

@ -19,9 +19,7 @@
//-----------------------------------------------------------------------------
#include "cmdhffido.h"
#include <unistd.h>
#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));

View file

@ -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);

View file

@ -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");

View file

@ -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);

View file

@ -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;
}

View file

@ -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,26 +2059,26 @@ 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';
}
}
}
}
}
idx++;
// 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;
}

View file

@ -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);
}
}

View file

@ -15,23 +15,17 @@
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <jansson.h>
#include <mbedtls/asn1.h>
#include <mbedtls/oid.h>
#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;
};

View file

@ -13,9 +13,8 @@
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#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 */

View file

@ -12,19 +12,16 @@
#include <ctype.h>
#include <stdlib.h>
#include <mbedtls/asn1.h>
#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;
}

View file

@ -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"));

View file

@ -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");
*/
}
}

View file

@ -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 <config.h>
#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");
}
}

View file

@ -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 <stdio.h> // FILE
void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level);
#endif

View file

@ -24,7 +24,6 @@
#include <stdarg.h>
#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) {

View file

@ -18,15 +18,10 @@
#endif
#include "emv_tags.h"
#include <stdlib.h>
#include <string.h>
#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;
};

View file

@ -17,7 +17,6 @@
#define TAGS_H
#include "tlv.h"
#include <stdio.h> // 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

View file

@ -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 {

View file

@ -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);

View file

@ -24,7 +24,6 @@
#include "commonutil.h" // ARRAYLEN
#include "../crypto.h"
#include "../dump.h"
#include "util_posix.h"
#include "ui.h" // printandlog

View file

@ -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);

View file

@ -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);

View file

@ -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));

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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);

20
pm3
View file

@ -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
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