Merge pull request #5 from RfidResearchGroup/master

Update fork
This commit is contained in:
mwalker33 2019-09-13 18:17:07 +10:00 committed by GitHub
commit a901d386b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
602 changed files with 10111 additions and 7852 deletions

12
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: iceman1001
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

5
.gitignore vendored
View file

@ -35,9 +35,11 @@ Makefile.platform
!client/hardnested/*.bin
!client/hardnested/tables/*.z
client/ui/ui_overlays.h
client/reveng/bmptst
hardnested_stats.txt
proxmark3
proxmark3-flasher
flasher
!flasher/
lua
@ -71,8 +73,9 @@ tools/jtag_openocd/openocd_configuration
ppls patches/*
*- Copy.*
client/lualibs/mf_default_keys.lua
client/lualibs/mfc_default_keys.lua
client/lualibs/pm3_cmd.lua
# recompiled
fpga_version_info.c
.proxmark3/*

View file

@ -15,9 +15,18 @@ matrix:
include:
- os: osx
osx_image: xcode11
env: MAKE_PARAMS='PLATFORM_EXTRAS='
- os: osx
osx_image: xcode11
env: MAKE_PARAMS='PLATFORM_EXTRAS=BTADDON'
- os: linux
dist: xenial
sudo: required
env: MAKE_PARAMS='PLATFORM_EXTRAS='
- os: linux
dist: xenial
sudo: required
env: MAKE_PARAMS='PLATFORM_EXTRAS=BTADDON'
addons:
apt:
@ -27,27 +36,23 @@ addons:
homebrew:
packages:
- readline
- p7zip
- libusb-compat
- perl
- qt5
- wget
- RfidResearchGroup/proxmark3/arm-none-eabi-gcc
taps: RfidResearchGroup/proxmark3
install:
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
brew info proxmark3;
brew options proxmark3;
brew install --HEAD proxmark3;
elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
make all;
if ! arm-none-eabi-gcc -v; then
echo "arm-none-eabi-gcc [ERROR]";
travis_terminate 1;
fi
make clean;
make all V=1 "$MAKE_PARAMS";
script:
## start and run a test script
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
proxmark3 -h ;
./pm3test.sh;
elif [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
./client/proxmark3 -h ;
./pm3test.sh;
fi

4
.vscode/tasks.json vendored
View file

@ -14,13 +14,13 @@
{
"label": "flash fullimage",
"type": "shell",
"command": "./flash-fullimage.sh",
"command": "sudo ./pm3-flash-fullimage",
"problemMatcher": []
},
{
"label": "FLASH BOOTROM",
"type": "shell",
"command": "./flash-bootrom.sh",
"command": "sudo ./pm3-flash-bootrom",
"problemMatcher": []
}
]

View file

@ -3,14 +3,38 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Chg proxmark3-flasher is now merged into proxmark3 client. Add pm3-flash (@doegox)
- Chg `hf iclass clone\dump\rdbl\wrbl` - now uses NG (@iceman1001)
- Fix `hf iclass clone` - last block always fails (@iceman1001)
- Chg `hf iclass clone` - retries ten times, less output (honor verbose) (@iceman1001)
- Chg `hf iclass dump` - retries ten times, less output (honor verbose) (@iceman1001)
- Rename `hf iclass writeblk` -> `hf iclass wrbl` to match hf mf wrbl (@iceman1001)
- Rename `hf iclass readblk` -> `hf iclass rdbl` to match hf mf rdbl (@iceman1001)
- Add cmdscript example and show usage with shebang (@doegox)
- Add instructions for Fedora (@doegox)
- Chg reduce the list of requirements to the minimum and move to QT5 (@doegox)
- Add `make install` and reorganize/rename stuffs accordingly (@doegox)
- Add searchFile for several types of files (@doegox / @iceman1001)
- Chg posix sh version of mkversion (@doegox)
- Chg remove entirely ncurses, not needed nowadays (@doegox)
- Chg remove deprecated termcap, use ncurses instead (@ZeroChaos-)
- Chg `hf iclass encrypt` - now takes transport key as param. (@iceman1001)
- Chg `hf iclass decrypt` - now takes transport key as param. (@iceman1001)
- Chg `hf mf fchk m` - now secretly dumps card to emul, if all keys are found (@iceman1001)
- Chg history and logfile are now saved into $HOME/.proxmark3/ (@doegox)
- Chg optimization of iclass mac calculations on deviceside (@pwpiwi)
- Add `hf mf autopwn` - Autopwn function for Mifare Classic, extract all keys and dump card memory (@matthiaskonrath)
- Add Lua paths: look for scripts also in ~/.proxmark/lua{scripts,libs} and /usr/local/share/proxmark3/lua{scripts,libs} (@doegox)
- Change Lua directory scripts/ to luascript/ (@doegox)
- Change non-rdv4 PLATFORM must now use the generic PM3OTHER, simpler (@doegox)
- Fix reveng integration for all platforms else than WIN32 (@doegox)
- Add cheat sheet for easy operations of the Proxmark3 (scund00r)
- Chg commands are now in green in the helptext list (@iceman1001)
- Fix 'script run ndefdump' - better exit messages when failing (@iceman1001)
- Fix 'hf iclass dump' - now also saves in EML format (@iceman1001)
- Fix 'hf iclass sim 3' - now works on legacy readers and legacy SE readers (@iceman1001)
- Fix `script run ndefdump` - better exit messages when failing (@iceman1001)
- Fix `hf iclass dump` - now also saves in EML format (@iceman1001)
- Fix `hf iclass sim 3` - now works on legacy readers and legacy SE readers (@iceman1001)
- Rework hitag2 read/write help (@ViRb3)
- Add 'lf nedap' - encoding / decoding (anon)
- Add `lf nedap` - encoding / decoding (anon)
- Add client option `-i` to stay in interactive mode after a script or command (@DidierStevens/@doegox)
- Add VSCode tasks (@ViRb3)
- Better warn user of hardcoded hitag info (@ViRb3)
@ -18,10 +42,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Fix hitag password write offset by 1 (@ViRb3)
- Fix momentarily flash read/write of dicts (@doegox/@cjbrigato)
- Add some more default keys (@anon)
- Add 'hf thinfilm sim' simulating Thinfilm NFC barcode tags (@doegox)
- Add 'hf thinfilm list' specific trace decoding (Thinfilm NFC barcode tags) (@doegox)
- Fix 'hf topaz reader' - don't crash when trying to read a Thinfilm tag (@iceman1001)
- Add 'hf thinfilm info' - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001)
- Add `hf thinfilm sim` simulating Thinfilm NFC barcode tags (@doegox)
- Add `hf thinfilm list` specific trace decoding (Thinfilm NFC barcode tags) (@doegox)
- Fix `hf topaz reader` - don't crash when trying to read a Thinfilm tag (@iceman1001)
- Add `hf thinfilm info` - read / decode Kovio Thinfilm NFC barcode tags (@iceman1001)
- Add FPGA LF adc path (@anon)
- Add ECC support / check for NID_secp128r1 (@pwpiwi)
- Add some more default keys (ollibolli)

View file

@ -1,131 +1,2 @@
The project compiles on Linux, Mac OS X and Windows (MinGW/MSYS).
it requires:
- gcc >= 4.8
- libpthread
- libreadline
- libusb
- perl
- an ARM cross-compiler to compile the firmware
- libncurses5-dev
and optionally QT for the GUI
To compile, just run "make".
===========
= Windows =
===========
Rather than download and install every one of these packages, a new ProxSpace
environment archive file will be made available for download on the project
page at @Gator96100's repo
Afterwards just clone the iceman repo or download someone elses. Read instructions on @Gator96100 repo page. (https://github.com/Gator96100/ProxSpace/)
Download the ProxSpace environment archive and extract it to C:\
Links
https://github.com/Gator96100/ProxSpace/archive/master.zip
============
= Mac OS X =
============
Installing from HomeBrew tap
---------------------------
This method is recommended and tested on macOS Sierra 10.12.3
1. Install homebrew if you haven't yet already done so: http://brew.sh/
2. Tap proxmark repo:
brew tap iceman1001/proxmark3
3. Install Proxmark3:
Stable release
brew install proxmark3
Latest non-stable from GitHub (use this if previous command fails)
brew install --HEAD proxmark3
For more information go to https://github.com/iceman1001/homebrew-proxmark3
Upgrading HomeBrew tap formula
-----------------------------
*This method is useful for those looking to run bleeding-edge versions of iceman's client. Keep this in mind when attempting to update your HomeBrew tap formula as this procedure could easily cause a build to break if an update is unstable on macOS.*
Tested on macOS Sierra 10.12.6
*Note: This assumes you have already installed iceman's fork from HomeBrew as mentioned above*
1. Force HomeBrew to pull the latest source from github
`brew upgrade --fetch-HEAD iceman1001/proxmark3/proxmark3`
2. Flash the bootloader
* With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark 3 as you plug it into a USB port. After about 5 seconds let go of the button and run this command
`$ sudo proxmark3-flasher /dev/tty.usbmodem881 /usr/local/Cellar/proxmark3/HEAD-ccfdd60/share/firmware/fullimage.elf`
* After the bootloader finishes flashing, unplug your Proxmark3 from your machine
3. Flash fullimage.elf
* Press and hold the button on your Proxmark 3 and keep it held as you plug the Proxmark 3 back into the USB port; continue to hold the button until after this step is complete and the `proxmark3-flasher` command outputs "Have a nice day!"*
`$ sudo proxmark3-flasher /dev/tty.usbmodem881 /usr/local/Cellar/proxmark3/HEAD-ccfdd60/share/firmware/fullimage.elf`
4. Enjoy the update
Compilling from source manually (Legacy)
---------------------------
Tested on OSX 10.10 Yosemite
1 - Install Xcode and Xcode Command Line Tools
2 - Install Homebrew and dependencies
brew install readline libusb p7zip libusb-compat wget qt5 pkgconfig
3 - Download DevKitARM for OSX
http://sourceforge.net/projects/devkitpro/files/devkitARM/devkitARM_r44/
Unpack devkitARM_r44-osx.tar.bz2 to proxmark3 directory.
4 - Edit proxmark3/client/Makefile adding path to readline and qt5
LDLIBS = -L/usr/local/opt/readline/lib -L/usr/local/opt/qt5/lib -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm
CFLAGS = -std=c99 -I/usr/local/opt/qt5/include -I/usr/local/opt/readline/include -I. -I../include -I../common -I../zlib -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
If your old brew intallation use /usr/local/Cellar/ path replace /usr/local/opt/readline/lib with your actuall readline and qt5 path. See homebrew manuals.
5 - Set Environment
export DEVKITPRO=$HOME/proxmark3/
export DEVKITARM=$DEVKITPRO/devkitARM
export PATH=${PATH}:${DEVKITARM}/bin
============
= Linux =
============
1 - Download
A precompiled DevKitARM cross compiler tool chain package can be found at
http://sourceforge.net/projects/devkitpro/files/devkitARM
Select the one you need (32bit or 64bit) and unpack to a convinient place, eg
$HOME/proxmark3/. It will create a devkitARM/ subdirectory.
You will also need a general compiling environment on your computer for
the client and the libusb headers. In most distributions you will get all you
need with the lsb-package (Linux Standard Base). In debian/ubuntu you simply
call `aptitude install lsb libusb-dev libreadline-dev libreadline6`.
For the graphical plot view, you might need the qtlibs (debian/ubuntu:
libqt4-dev), too.
2 - Set Environment
export DEVKITPRO=$HOME/proxmark3/
export DEVKITARM=$DEVKITPRO/devkitARM
export PATH=${PATH}:${DEVKITARM}/bin
Refer to doc/md/Installation_Instructions/ for up-to-date intructions for various platforms.

176
Makefile
View file

@ -1,86 +1,131 @@
# Hide full compilation line:
ifneq ($(V),1)
Q?=@
endif
# To see full command lines, use make V=1
GZIP=gzip
# Windows' echo echos its input verbatim, on Posix there is some
# amount of shell command line parsing going on. echo "" on
# Windows yields literal "", on Linux yields an empty line
ifeq ($(shell echo ""),)
# This is probably a proper system, so we can use uname
DELETE=rm -rf
FLASH_TOOL=client/flasher
platform=$(shell uname)
ifneq (,$(findstring MINGW,$(platform)))
FLASH_PORT=com3
PATHSEP=\\#
else
FLASH_PORT=/dev/ttyACM0
PATHSEP=/
endif
else
# Assume that we are running on native Windows
DELETE=del /q
FLASH_TOOL=client/flasher.exe
platform=Windows
FLASH_PORT=com3
PATHSEP=\\#
endif
include Makefile.defs
-include Makefile.platform
-include .Makefile.options.cache
include common_arm/Makefile.hal
all clean: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/%
# preserve relative DESTDIR path for subdir makes
ifneq (,$(DESTDIR))
# realpath needs the directory to exist
$(shell $(MKDIR) $(DESTDIR))
MYDESTDIR:=$(realpath $(DESTDIR))
ifeq (,$(MYDESTDIR))
$(error Can't create $(DESTDIR))
endif
endif
all clean install uninstall: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% fpga_compress/%
INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py findbits.py rfidtest.pl xorcheck.py
INSTALLSIMFW=sim011.bin sim011.sha512.txt
INSTALLSCRIPTS=pm3 pm3-flash pm3-flash-all pm3-flash-bootrom pm3-flash-fullimage
INSTALLSHARES=tools/jtag_openocd traces
INSTALLDOCS=doc/*.md doc/md
install: all common/install
common/install:
$(info [@] Installing common resources to $(MYDESTDIR)$(PREFIX)...)
ifneq (,$(INSTALLSCRIPTS))
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)
$(Q)$(CP) $(INSTALLSCRIPTS) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)
endif
ifneq (,$(INSTALLSHARES))
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
$(Q)$(CP) $(INSTALLSHARES) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
endif
ifneq (,$(INSTALLDOCS))
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)
$(Q)$(CP) $(INSTALLDOCS) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)
endif
ifneq (,$(INSTALLTOOLS))
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)
$(Q)$(CP) $(foreach tool,$(INSTALLTOOLS),tools/$(tool)) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)
endif
ifneq (,$(INSTALLSIMFW))
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
$(Q)$(CP) $(foreach fw,$(INSTALLSIMFW),tools/simmodule/$(fw)) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
endif
ifeq ($(platform),Linux)
$(Q)$(MKDIR) $(DESTDIR)$(UDEV_PREFIX)
$(Q)$(CP) driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules
endif
uninstall: common/uninstall
common/uninstall:
$(info [@] Uninstalling common resources from $(MYDESTDIR)$(PREFIX)...)
ifneq (,$(INSTALLSCRIPTS))
$(Q)$(RM) $(foreach script,$(INSTALLSCRIPTS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)$(PATHSEP)$(notdir $(script)))
endif
ifneq (,$(INSTALLSHARES))
$(Q)$(RMDIR) $(foreach share,$(INSTALLSHARES),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)$(PATHSEP)$(notdir $(share)))
endif
ifneq (,$(INSTALLDOCS))
$(Q)$(RMDIR) $(foreach doc,$(INSTALLDOCS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)$(PATHSEP)$(notdir $(doc)))
$(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)
endif
ifneq (,$(INSTALLTOOLS))
$(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)$(PATHSEP)$(notdir $(tool)))
endif
$(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)
ifneq (,$(INSTALLSIMFW))
$(Q)$(RM) $(foreach fw,$(INSTALLSIMFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw)))
endif
$(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
ifeq ($(platform),Linux)
$(Q)$(RM) $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules
endif
$(Q)$(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
mfkey/%: FORCE
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@)
$(Q)$(MAKE) --no-print-directory -C tools/mfkey $(patsubst mfkey/%,%,$@) DESTDIR=$(MYDESTDIR)
nonce2key/%: FORCE
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@)
$(Q)$(MAKE) --no-print-directory -C tools/nonce2key $(patsubst nonce2key/%,%,$@) DESTDIR=$(MYDESTDIR)
fpga_compress/%: FORCE
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@)
$(Q)$(MAKE) --no-print-directory -C tools/fpga_compress $(patsubst fpga_compress/%,%,$@) DESTDIR=$(MYDESTDIR)
bootrom/%: FORCE cleanifplatformchanged
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C bootrom $(patsubst bootrom/%,%,$@)
$(Q)$(MAKE) --no-print-directory -C bootrom $(patsubst bootrom/%,%,$@) DESTDIR=$(MYDESTDIR)
armsrc/%: FORCE cleanifplatformchanged fpga_compress/%
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C armsrc $(patsubst armsrc/%,%,$@)
$(Q)$(MAKE) --no-print-directory -C armsrc $(patsubst armsrc/%,%,$@) DESTDIR=$(MYDESTDIR)
client/%: FORCE
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C client $(patsubst client/%,%,$@)
recovery/%: FORCE cleanifplatformchanged bootrom/% armsrc/%
$(Q)$(MAKE) --no-print-directory -C client $(patsubst client/%,%,$@) DESTDIR=$(MYDESTDIR)
recovery/all: bootrom/all armsrc/all
recovery/install: bootrom/all armsrc/all
recovery/%: FORCE cleanifplatformchanged
$(info [*] MAKE $@)
$(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@)
$(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) DESTDIR=$(MYDESTDIR)
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
.PHONY: all clean help _test bootrom flash-bootrom os flash-os flash-all recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged
.PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key style checks FORCE udev accessrights cleanifplatformchanged
help:
@echo "Multi-OS Makefile"
@echo
@echo "Possible targets:"
@echo "+ all - Make all targets: bootrom, armsrc and OS-specific host tools"
@echo "+ clean - Clean in all targets"
@echo "+ all - Make all targets: bootrom, fullimage and OS-specific host tools"
@echo "+ clean - Clean in all targets"
@echo "+ .../clean - Clean in specified target and its deps, e.g. bootrom/clean"
@echo "+ (un)install - Install/uninstall Proxmark files in the system, default to /usr/local/share,
@echo " else provide a PREFIX. See Maintainers.md for more options"
@echo
@echo "+ bootrom - Make bootrom"
@echo "+ os - Make armsrc (includes fpga)"
@echo "+ flash-bootrom - Make bootrom and flash it"
@echo "+ flash-os - Make armsrc and flash os image (includes fpga)"
@echo "+ flash-all - Make bootrom and armsrc and flash bootrom and os image"
@echo "+ recovery - Make bootrom and armsrc images for JTAG flashing"
@echo "+ bootrom - Make bootrom"
@echo "+ fullimage - Make armsrc fullimage (includes fpga)"
@echo "+ recovery - Make bootrom and fullimage files for JTAG flashing"
@echo
@echo "+ client - Make only the OS-specific host client"
@echo "+ mfkey - Make tools/mfkey"
@echo "+ nonce2key - Make tools/nonce2key"
@echo "+ fpga_compress - Make tools/fpga_compress"
@echo "+ client - Make only the OS-specific host client"
@echo "+ mfkey - Make tools/mfkey"
@echo "+ nonce2key - Make tools/nonce2key"
@echo "+ fpga_compress - Make tools/fpga_compress"
@echo
@echo "+ style - Apply some automated source code formatting rules"
@echo "+ checks - Detect various encoding issues in source code"
@echo "+ style - Apply some automated source code formatting rules"
@echo "+ checks - Detect various encoding issues in source code"
@echo
@echo "Possible platforms: try \"make PLATFORM=\" for more info, default is PM3RDV4"
@echo "To activate verbose mode, use make V=1"
@ -89,7 +134,17 @@ client: client/all
bootrom: bootrom/all
os: armsrc/all
# aliases fullimage = armsrc
fullimage: armsrc/all
fullimage/all: armsrc/all
fullimage/clean: armsrc/clean
fullimage/install: armsrc/install
fullimage/uninstall: armsrc/uninstall
recovery: recovery/all
@ -99,17 +154,8 @@ nonce2key: nonce2key/all
fpga_compress: fpga_compress/all
flash-bootrom: bootrom/obj/bootrom.elf $(FLASH_TOOL)
$(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$<)
flash-os: armsrc/obj/fullimage.elf $(FLASH_TOOL)
$(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$<)
flash-all: bootrom/obj/bootrom.elf armsrc/obj/fullimage.elf $(FLASH_TOOL)
$(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$(filter-out $(FLASH_TOOL),$^))
newtarbin:
$(DELETE) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz
$(RM) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz
@touch proxmark3-$(platform)-bin.tar
tarbin: newtarbin client/tarbin armsrc/tarbin bootrom/tarbin

46
Makefile.defs Normal file
View file

@ -0,0 +1,46 @@
# Hide full compilation line:
ifneq ($(V),1)
Q?=@
endif
# To see full command lines, use make V=1
# been here
DEFSBEENHERE = true
CP = cp -a
GZIP = gzip
MKDIR = mkdir -p
RM = rm -f
RMDIR = rm -rf
# rmdir only if dir is empty, tolerate failure
RMDIR_SOFT = -rmdir
MV = mv
TOUCH = touch
FALSE = false
TAR = tar
TARFLAGS ?= -v --ignore-failed-read -r
TARFLAGS += -C .. -f
CROSS ?= arm-none-eabi-
CC = gcc
CXX = g++
LD = g++
PATHSEP=/
PREFIX ?= /usr/local
UDEV_PREFIX ?= /etc/udev/rules.d
INSTALLBINRELPATH ?= bin
INSTALLSHARERELPATH ?= share/proxmark3
INSTALLFWRELPATH ?= share/proxmark3/firmware
INSTALLTOOLSRELPATH ?= share/proxmark3/tools
INSTALLDOCSRELPATH ?= share/doc/proxmark3
platform = $(shell uname)
DETECTED_OS=$(platform)
ifeq ($(platform),Darwin)
AR= /usr/bin/ar rcs
RANLIB= /usr/bin/ranlib
else
AR= ar rcs
RANLIB= ranlib
endif

76
Makefile.host Normal file
View file

@ -0,0 +1,76 @@
# This Makefile might have been called from various subdirs, trying to find our Makefile.defs
ifeq ($(DEFSBEENHERE),)
-include Makefile.defs
endif
ifeq ($(DEFSBEENHERE),)
-include ../Makefile.defs
endif
ifeq ($(DEFSBEENHERE),)
-include ../../Makefile.defs
endif
ifeq ($(DEFSBEENHERE),)
$(error Can't find Makefile.defs)
endif
CFLAGS ?= -Wall -Werror -O3
CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES)
vpath %.c $(MYSRCPATHS)
# Flags to generate temporary dependency files
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
# make temporary to final dependency files after successful compilation
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@
BINDIR := .
OBJDIR := obj
MYOBJS = $(MYSRCS:%.c=$(OBJDIR)/%.o)
CLEAN = $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin))
all: $(foreach bin,$(MYLIBS) $(BINS) $(LIB_A),$(BINDIR)/$(bin))
clean:
$(Q)$(RM) $(CLEAN)
$(Q)$(RMDIR) $(OBJDIR)
install: all
ifneq (,$(INSTALLTOOLS))
$(info [@] Installing $(BINS) to $(DESTDIR)$(PREFIX)...)
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)
$(Q)$(CP) $(INSTALLTOOLS) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)
endif
@true
uninstall:
ifneq (,$(INSTALLTOOLS))
$(info [@] Uninstalling $(BINS) from $(DESTDIR)$(PREFIX)...)
$(Q)$(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)$(PATHSEP)$(notdir $(tool)))
endif
@true
.PHONY: all clean install uninstall
$(BINDIR)/$(LIB_A): $(MYOBJS)
$(info [=] AR $(notdir $@))
$(Q)$(AR) $@ $(MYOBJS)
$(Q)$(RANLIB) $@
$(BINDIR)/% : $(OBJDIR)/%.o $(MYOBJS) $(MYLIBS)
$(info [=] LD $(notdir $@))
$(Q)$(LD) $(LDFLAGS) $(MYOBJS) $< -o $@ $(MYLIBS)
$(OBJDIR)/%.o : %.c | $(OBJDIR)
$(info [-] CC $<)
$(Q)$(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $<
$(Q)$(POSTCOMPILE)
$(OBJDIR):
$(Q)$(MKDIR) $(OBJDIR)
DEPENDENCY_FILES = $(MYOBJS:%.o=%.d) $(BINS:%=$(OBJDIR)/%.d)
$(DEPENDENCY_FILES): ;
.PRECIOUS: $(DEPENDENCY_FILES)
-include $(DEPENDENCY_FILES)

View file

@ -1,8 +1,8 @@
# RRG / Iceman repo, dedicated to Proxmark3 RDV4.0
# RRG / Iceman repo - Proxmark3
This repo is based on iceman fork for Proxmark3. It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design.
This repo is based on iceman fork for Proxmark3. It supports other Proxmark3 platforms as well.
_Note that it also supports other Proxmark3 platforms as well!_
It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design.
| Releases | Linux & OSX CI | Windows CI |
@ -17,16 +17,23 @@ _Note that it also supports other Proxmark3 platforms as well!_
| ------------------- |:-------------------:| -------------------:|
|[What has changed?](#what-has-changed) | [Setup and build for Linux](/doc/md/Installation_Instructions/Linux-Installation-Instructions.md) | [Compilation Instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md)|
|[Development](#development) | [Important notes on ModemManager for Linux users](/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md) | [Validating proxmark client functionality](/doc/md/Use_of_Proxmark/1_Validation.md) |
|[Why didn't you base it on official PM3 Master?](#why-didnt-you-base-it-on-official-pm3-master)| [Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)|
|[PM3 GUI](#pm3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)|
|[Why didn't you base it on official Proxmark3 Master?](#why-didnt-you-base-it-on-official-proxmark3-master)| [Homebrew (Mac OS X) & Upgrading HomeBrew Tap Formula](/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md) | [First Use and Verification](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md)|
|[Proxmark3 GUI](#proxmark3-gui)|[Setup and build for Windows](/doc/md/Installation_Instructions/Windows-Installation-Instructions.md)|[Commands & Features](/doc/md/Use_of_Proxmark/3_Commands-and-Features.md)|
|[Issues](#issues)|[Blue shark manual](/doc/bt_manual_v10.md) |[Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)|
|[Notes on UART](/doc/uart_notes.md)||[Command Cheat sheet](/doc/cheatsheet.md)|
|[Notes on Frame format](/doc/new_frame_format.md)|||
|[Notes on external flash](/doc/ext_flash_notes.md)|||
|[Notes on Termux / Android](/doc/termux_notes.md)|||
|[Notes on UART](/doc/uart_notes.md)|[Maintainers](/doc/md/Development/Maintainers.md)|[Command Cheat sheet](/doc/cheatsheet.md)|
|[Notes on frame format](/doc/new_frame_format.md)||[More cheat sheets](https://github.com/RfidResearchGroup/proxmark3/wiki/More-cheat-sheets)|
|[Notes on external flash](/doc/ext_flash_notes.md)||[EMV](/doc/emv_notes.md)|
|[Notes on Termux / Android](/doc/termux_notes.md)||[Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md)|
|[Notes on wireshark / tracedata](/doc/trace_wireshark_notes.md)||[JTAG](/doc/jtag_notes.md)|
|[Notes on loclass](/doc/loclass_notes.md)|||
|[Notes on paths](/doc/path_notes.md)|||
|[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode) ||
|[Donations](#Donations)|||
## Support on other Proxmark3 platforms
In order to build this repo for other Proxmark3 platforms we urge you to read [Advanced compilation parameters](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md)
## What has changed?
On the hardware side:
@ -38,11 +45,13 @@ On the hardware side:
On the software side: quite a lot, see the [Changelog file](CHANGELOG.md).
## Development
This fork now compiles just fine on
This repo now compiles just fine on
- Proxspace v3.2
- Windows/mingw environment with Qt5.6.1 & GCC 4.8
- Ubuntu 1404, 1510, 1604, 1804, 1904
- Mac OS X / Homebrew
- ParrotOS, Gentoo, Pentoo
- ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora
- WSL, WSL2 (Windows subsystem linux) on Windows 10
- Docker container
@ -54,15 +63,26 @@ If you intend to contribute to the code, please read the [coding style notes](HA
- Internal notes on [external flash](/doc/ext_flash_notes.md)
- Internal notes on [standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)
- Internal notes on [Termux / Android](/doc/termux_notes.md)
- Internal notes on [Wireshark / tracedata](/doc/trace_wireshark_notes.md)
- Internal notes on [loclass](/doc/loclass_notes.md)
- Internal notes on [EMV](/doc/emv_notes.md)
- Internal notes on [Paths](/doc/path_notes.md)
## Cheat sheet
Thanks to Alex Dibs, you can enjoy a [command cheat sheet](/doc/cheatsheet.md)
## Maintainers ( package, distro )
To all distro, package maintainers, we tried to make your life easier. `make install` is now available and if you want to know more.
- [Maintainers](/doc/md/Development/Maintainers.md)
## Why didn't you base it on official Proxmark3 Master?
The separation from official Proxmark3 repo gives us a lot of freedom to create a firmware/client that suits the RDV40 features. We don't want to mess up the official Proxmark3 repo with RDV40 specific code.
## Proxmark3 GUI
The official PM3-GUI from Gaucho will not work.
The new universal GUI will work. [Proxmark3 Universal GUI](https://github.com/burma69/PM3UniversalGUI) Almost, change needed in order to show helptext when client isn't connected to a device.
@ -78,6 +98,7 @@ It's needed to have a good USB cable to connect Proxmark3 to USB. If you have st
- updated Feb 2019 [@5w0rdfish](https://mobile.twitter.com/5w0rdFish)
# Donations
Nothing says thank you as much as a donation. So if you feel the love, do feel free to become a iceman patron. For some tiers it comes with rewards.
https://www.patreon.com/iceman1001

View file

@ -73,13 +73,76 @@ clone_script:
Write-Host "[ OK ]" -ForegroundColor Green
Write-Host "Update msys2 packages..." -NoNewLine
Write-Host "Update msys2 packages..."
$env:Path = "C:\ProxSpace\msys2\usr\bin;C:\ProxSpace\msys2\mingw32\bin;C:\ProxSpace\gcc-arm-none-eabi\bin;$env:Path"
C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null 1> msys1.txt 2>&1
Function ExecUpdate($Name, $Cmd, $ErrorLine) {
C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null 1> msys1.txt 2>&1
Write-Host "Exec [$Name]... " -NoNewLine
#--- begin Job
$Job = Start-Job -Name "$Name" -ScriptBlock {
$env:Path = "C:\ProxSpace\msys\bin;$env:Path"
Set-Location $using:PWD
$sb=[scriptblock]::Create("$using:Cmd")
#execute scriptblock
$Cond=&$sb
return $Cond
}
#--- end Job
$JobTime=[System.Environment]::TickCount
while($true) {
Try {
$Res = Receive-Job -Job $Job -Keep 2>&1 6>&1
}
Catch {
$Res = ""
Write-host "error in Receive-Job"
}
if ($Res -is "String" -and $Res -like "*$ErrorLine*"){
Write-host "Exit by stop phrase" -ForegroundColor Green
break
}
if ($Res -is [Object]){
[bool]$needexit = $false
ForEach($line in $Res){
if ($line -like "*$ErrorLine*"){
Write-host "Exit by stop phrase [obj]" -ForegroundColor Green
$needexit = $true
break
}
}
if ($needexit) {
break
}
}
if(Wait-Job $Job -Timeout 5){
Write-host "Exit by end job" -ForegroundColor Green
break
}
if ([System.Environment]::TickCount-$JobTime -gt 1000000) {
Write-host "Exit by timeout" -ForegroundColor Yellow
break
}
}
Remove-Job -Force $Job
}
ExecUpdate "update1" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2"
ExecUpdate "update2" "C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null" "terminate?MSYS2"
Write-Host "Update " -NoNewLine
Write-Host "[ OK ]" -ForegroundColor Green
install:
@ -130,54 +193,38 @@ build_script:
}
if(!(Test-Path C:\ProxSpace\pm3\client\hardnested\tables\*.bin.z)){
if(!(Test-Path C:\ProxSpace\pm3\client\resources\hardnested_tables\*.bin.z)){
throw "Files in hardnested\tables not exists."
throw "Files in client\resources\hardnested_tables is not exists."
}
#copy
#install
Write-Host "Copy release files..." -NoNewLine -ForegroundColor Yellow
Write-Host "Installing..." -NoNewLine -ForegroundColor Yellow
New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release
New-Item -ItemType Directory -Force -Path C:\ProxSpace\pm3\Release\bin
Copy-Item C:\ProxSpace\pm3\client\*.exe C:\ProxSpace\Release
New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\arm
Copy-Item C:\ProxSpace\pm3\armsrc\obj\*.elf C:\ProxSpace\Release\arm
Copy-Item C:\ProxSpace\pm3\bootrom\obj\*.elf C:\ProxSpace\Release\arm
New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\scripts
Copy-Item C:\ProxSpace\pm3\client\scripts\*.lua C:\ProxSpace\Release\scripts
New-Item -ItemType Directory -Force -Path C:\ProxSpace\Release\hardnested\tables
Copy-Item C:\ProxSpace\pm3\client\hardnested\*.bin C:\ProxSpace\Release\hardnested
Copy-Item C:\ProxSpace\pm3\client\hardnested\tables\*.bin.z C:\ProxSpace\Release\hardnested\tables
bash -c -i 'make install DESTDIR=Release PREFIX='
# dll files
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libgcc_s_dw2-1.dll C:\ProxSpace\Release
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libgcc_s_dw2-1.dll C:\ProxSpace\pm3\Release\bin
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libstdc++-6.dll C:\ProxSpace\Release
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libstdc++-6.dll C:\ProxSpace\pm3\Release\bin
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libwinpthread-1.dll C:\ProxSpace\Release
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libwinpthread-1.dll C:\ProxSpace\pm3\Release\bin
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Core.dll C:\ProxSpace\Release
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Core.dll C:\ProxSpace\pm3\Release\bin
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Gui.dll C:\ProxSpace\Release
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Gui.dll C:\ProxSpace\pm3\Release\bin
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Widgets.dll C:\ProxSpace\Release
Copy-Item C:\ProxSpace\msys2\mingw32\bin\Qt5Widgets.dll C:\ProxSpace\pm3\Release\bin
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libreadline*.dll C:\ProxSpace\Release
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libreadline*.dll C:\ProxSpace\pm3\Release\bin
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libtermcap-0.dll C:\ProxSpace\Release
Copy-Item C:\ProxSpace\msys2\mingw32\bin\libtermcap-0.dll C:\ProxSpace\pm3\Release\bin
Write-Host "[ OK ]" -ForegroundColor Green
@ -199,7 +246,7 @@ build_script:
cd C:\ProxSpace
7z a release.zip C:\ProxSpace\Release
7z a release.zip C:\ProxSpace\pm3\Release
Push-AppveyorArtifact release.zip -DeploymentName "$releasename"
@ -256,6 +303,13 @@ test_script:
if ($Cond -is "String" -and $Cond -like "*true*"){
$res= $true
}
ForEach($line in $Cond){
if ($line -like "*passed*"){
$res = $true
$Cond = $line
break
}
}
} Else {
$res=$Cond
}
@ -287,6 +341,7 @@ test_script:
Remove-Job -Force $Job
if(!$res){
Write-host "--------------------- tests fail" -ForegroundColor Red
$global:TestsPassed=$false
}
}
@ -297,30 +352,34 @@ test_script:
#file test
ExecTest "proxmark3 exists" "proxmark3.exe" {Test-Path C:\ProxSpace\Release\proxmark3.exe}
ExecTest "proxmark3 exists" "proxmark3.exe" {Test-Path C:\ProxSpace\pm3\Release\bin\proxmark3.exe}
ExecTest "arm image exists" "\arm\fullimage1.elf" {Test-Path C:\ProxSpace\Release\arm\fullimage.elf}
ExecTest "arm bootrom exists" "bootrom.elf" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\bootrom.elf}
ExecTest "bootrom exists" "bootrom.elf" {Test-Path C:\ProxSpace\Release\arm\bootrom.elf}
ExecTest "arm image exists" "fullimage.elf" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\fullimage.elf}
ExecTest "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\Release\hardnested\tables\*.z}
ExecTest "arm recovery image exists" "proxmark3_recovery.bin" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\firmware\proxmark3_recovery.bin}
ExecTest "hardnested tables exists" "hardnested" {Test-Path C:\ProxSpace\pm3\Release\share\proxmark3\resources\hardnested_tables\*.z}
ExecTest "release exists" "release.zip" {Test-Path C:\ProxSpace\release.zip}
#proxmark logic tests
ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h | grep -q wait && echo Passed || echo Failed'}
ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h 2>&1 | grep -q wait && echo passed || echo failed'}
ExecTest "proxmark help text ISO7816" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q ISO7816 && echo Passed || echo Failed'}
ExecTest "proxmark help text ISO7816" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q ISO7816 && echo passed || echo failed'}
ExecTest "proxmark help text hardnested" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q hardnested && echo Passed || echo Failed'}
ExecTest "proxmark help text hardnested" "proxmark3 -t" {bash -lc 'cd ~/client;./proxmark3 -t 2>&1 | grep -q hardnested && echo passed || echo failed'}
ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf'"} "at_enc"
ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 -c 'hf mf hardnested t 1 000000000000'"} "found:"
ExecTest "hf mf iclass" "hf mf iclass" {bash -lc "cd ~/client;./proxmark3 -c 'hf iclass loclass t'"} "verified ok"
#proxmark crypto tests

View file

@ -134,6 +134,13 @@ include ../common_arm/Makefile.common
COMMON_FLAGS = -Os
INSTALLFW = $(OBJDIR)/fullimage.elf
ifneq (,$(FWTAG))
INSTALLFWTAG = $(notdir $(INSTALLFW:%.elf=%-$(FWTAG).elf))
else
INSTALLFWTAG = $(notdir $(INSTALLFW))
endif
OBJS = $(OBJDIR)/fullimage.s19
FPGA_COMPRESSOR = ../tools/fpga_compress/fpga_compress
@ -144,7 +151,7 @@ all: $(OBJS)
# version.c should be remade on every time fullimage.stage1.elf should be remade
version.c: default_version.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ)
$(info [-] GEN $@)
$(Q)perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@
$(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@
fpga_version_info.c: $(FPGA_BITSTREAMS) | $(FPGA_COMPRESSOR)
$(info [-] GEN $@)
@ -203,17 +210,26 @@ tarbin: $(OBJS)
$(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(OBJS:%=armsrc/%) $(OBJS:%.s19=armsrc/%.elf)
clean:
$(Q)$(DELETE) $(DEPENDENCY_FILES)
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.o
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.elf
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.s19
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.map
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.d
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.z
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.bin
$(Q)$(DELETE) version.c
$(Q)$(RM) $(DEPENDENCY_FILES)
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.elf
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.s19
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.map
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.d
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.z
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.bin
$(Q)$(RM) version.c
.PHONY: all clean help
install: all
$(info [@] Installing fullimage to $(DESTDIR)$(PREFIX)...)
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
$(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG)
uninstall:
$(info [@] Uninstalling fullimage from $(DESTDIR)$(PREFIX)...)
$(Q)$(RM) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG)
.PHONY: all clean help install uninstall
help:
@echo Multi-OS Makefile, you are running on $(DETECTED_OS)
@echo Possible targets:

View file

@ -1,6 +1,6 @@
# Default standalone if no standalone specified
DEFAULT_STANDALONE=LF_SAMYRUN
HELP_EXAMPLE_STANDALONE=HF_COLIN
HELP_EXAMPLE_STANDALONE=HF_YOUNG
# (you can set explicitly STANDALONE= to disable standalone modes)
STANDALONE?=$(DEFAULT_STANDALONE)
STANDALONE_REQ_DEFS=

View file

@ -229,7 +229,7 @@ void RAMFUNC SniffAndStore(uint8_t param) {
if (DBGLEVEL > 1)
Dbprintf("[!] Wrote %u Authentification attempts into logfile", auth_attempts);
SpinErr(0, 200, 5); // blink led A
SpinErr(LED_A, 200, 5);
SpinDelay(100);
}

View file

@ -518,7 +518,7 @@ failtag:
if (cjcuid == 0) {
cjSetCursLeft();
DbprintfEx(FLAG_NEWLINE, "%s>>%s BUG: 0000_CJCUID! Retrying...", _XRED_, _XWHITE_);
SpinErr(0, 100, 8);
SpinErr(LED_A, 100, 8);
goto failtag;
}
@ -636,7 +636,7 @@ failtag:
cjTabulize();
DbprintfEx(FLAG_NEWLINE, "%s[ FAIL ]%s\r\n->did not found all the keys :'(", _XRED_, _XWHITE_);
cjSetCursLeft();
SpinErr(1, 100, 8);
SpinErr(LED_B, 100, 8);
SpinOff(100);
return;
}
@ -672,7 +672,7 @@ failtag:
cjSetCursLeft();
DbprintfEx(FLAG_NEWLINE, "FATAL:EML_FALLBACKFILL_B");
SpinErr(2, 100, 8);
SpinErr(LED_C, 100, 8);
SpinOff(100);
return;
}
@ -778,7 +778,7 @@ readysim:
DbprintfEx(FLAG_NEWLINE, "- [ LA FIN ] -\r\n%s`-> You can take shell back :) ...", _XWHITE_);
cjSetCursLeft();
vtsend_set_attribute(NULL, 0);
SpinErr(3, 100, 16);
SpinErr(LED_D, 100, 16);
SpinDown(75);
SpinOff(100);
return;

View file

@ -24,131 +24,112 @@ void ModInfo(void) {
}
// samy's sniff and repeat routine for LF
// LEDS.
// A , B == which bank (recording)
// FLASHING A, B = clone bank
// C = playing bank A
// D = playing bank B
void RunMod() {
StandAloneMode();
Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<");
uint32_t high[OPTS], low[OPTS];
int selected = 0;
int playing = 0;
int cardRead = 0;
bool gotCard;
// Turn on selected LED
LED(selected + 1, 0);
#define STATE_READ 0
#define STATE_SIM 1
#define STATE_CLONE 2
uint8_t state = STATE_READ;
for (;;) {
WDT_HIT();
// exit from SamyRun, send a usbcommand.
if (data_available()) break;
// Was our button held down or pressed?
int button_pressed = BUTTON_HELD(1000);
int button_pressed = BUTTON_HELD(280);
if ( button_pressed != BUTTON_HOLD )
continue;
/*
#define BUTTON_NO_CLICK 0
#define BUTTON_SINGLE_CLICK -1
#define BUTTON_DOUBLE_CLICK -2
*/
Dbprintf("button %d", button_pressed);
SpinDelay(300);
if ( state == STATE_READ ) {
// Button was held for a second, begin recording
if (button_pressed > 0 && cardRead == 0) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_D, 0);
if (selected == 0) {
LED_A_ON();
LED_B_OFF();
} else {
LED_B_ON();
LED_A_OFF();
}
LED_C_OFF();
LED_D_OFF();
WAIT_BUTTON_RELEASED();
// record
DbpString("[=] starting recording");
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
// findone, high, low, no ledcontrol (A)
uint32_t hi = 0, lo = 0;
CmdHIDdemodFSK(1, &hi, &lo, 0);
high[selected] = hi;
low[selected] = lo;
/* need this delay to prevent catching some weird data */
SpinDelay(500);
Dbprintf("[=] recorded bank %x | %x%08x", selected, high[selected], low[selected]);
CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
Dbprintf("[=] recorded bank %x | %x %08x", selected, high[selected], low[selected]);
LEDsoff();
LED(selected + 1, 0);
// Finished recording
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 1;
gotCard = true;
} else if (button_pressed > 0 && cardRead == 1) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_A, 0);
// record
Dbprintf("[=] cloning %x %x %08x", selected, high[selected], low[selected]);
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
/* need this delay to prevent catching some weird data */
SpinDelay(500);
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
Dbprintf("[=] cloned %x %x %08x", selected, high[selected], low[selected]);
LEDsoff();
LED(selected + 1, 0);
// Finished recording
// If we were previously playing, set playing off
// so next button push begins playing what we recorded
playing = 0;
cardRead = 0;
}
// Change where to record (or begin playing)
else if (button_pressed && gotCard) {
// Next option if we were previously playing
if (playing)
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
// Begin transmitting
if (playing) {
LED(LED_B, 0);
DbpString("[=] playing");
// wait for button to be released
while (BUTTON_PRESS())
WDT_HIT();
Dbprintf("[=] %x %x %08x", selected, high[selected], low[selected]);
CmdHIDsimTAG(high[selected], low[selected], false);
DbpString("[=] done playing");
if (BUTTON_HELD(1000) > 0)
goto out;
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
// when done, we're done playing, move to next option
selected = (selected + 1) % OPTS;
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
} else {
while (BUTTON_PRESS())
WDT_HIT();
// got nothing. blink and loop.
if ( hi == 0 && lo == 0 ) {
SpinErr( (selected == 0) ? LED_A : LED_B, 100, 12);
Dbprintf("[=] recorded nothing, looping");
continue;
}
SpinErr( (select==0) ? LED_A : LED_B, 250, 2);
state = STATE_SIM;
continue;
} else if ( state == STATE_SIM ) {
LED_C_ON(); // Simulate
LED_D_OFF();
WAIT_BUTTON_RELEASED();
Dbprintf("[=] simulating %x | %x%08x", selected, high[selected], low[selected]);
// high, low, no led control(A) no time limit
CmdHIDsimTAGEx(high[selected], low[selected], false, -1);
SpinErr( LED_C, 250, 2);
state = STATE_CLONE;
continue;
} else if ( state == STATE_CLONE ) {
LED_C_OFF();
LED_D_ON(); // clone
WAIT_BUTTON_RELEASED();
Dbprintf("[=] cloning %x | %x%08x", selected, high[selected], low[selected]);
// high2, high, low, no longFMT
CopyHIDtoT55x7(0, high[selected], low[selected], 0);
state = STATE_READ;
SpinErr( LED_D, 250, 2);
selected = (selected + 1) % OPTS;
LEDsoff();
}
}
out:
DbpString("[=] exiting");
DbpString("[=] exiting samyrun");
LEDsoff();
}

View file

@ -447,15 +447,12 @@ void SendCapabilities(void) {
// Show some leds in a pattern to identify StandAlone mod is running
void StandAloneMode(void) {
DbpString("Stand-alone mode! No PC necessary.");
DbpString("Stand-alone mode, no computer necessary");
SpinDown(50);
SpinOff(50);
SpinDelay(50);
SpinUp(50);
SpinOff(50);
SpinDelay(50);
SpinDown(50);
SpinDelay(500);
}
/*
@ -800,7 +797,12 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_LF_T55XX_WAKEUP: {
T55xxWakeUp(packet->oldarg[0], packet->oldarg[1]);
struct p {
uint32_t password;
uint8_t flags;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
T55xxWakeUp(payload->password, payload->flags);
break;
}
case CMD_LF_T55XX_RESET_READ: {
@ -1134,7 +1136,8 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_MIFARE_EML_LOAD: {
MifareECardLoad(packet->oldarg[0], packet->oldarg[1]);
mfc_eload_t *payload = (mfc_eload_t *) packet->data.asBytes;
MifareECardLoadExt(payload->sectorcnt, payload->keytype);
break;
}
// Work with "magic Chinese" card
@ -1228,18 +1231,36 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_ICLASS_WRITEBL: {
iClass_WriteBlock(packet->oldarg[0], packet->data.asBytes);
struct p {
uint8_t blockno;
uint8_t data[12];
} PACKED;
struct p *payload = (struct p *)packet->data.asBytes;
iClass_WriteBlock(payload->blockno, payload->data);
break;
}
// iceman2019, unused?
case CMD_HF_ICLASS_READCHECK: { // auth step 1
iClass_ReadCheck(packet->oldarg[0], packet->oldarg[1]);
break;
}
case CMD_HF_ICLASS_READBL: {
iClass_ReadBlk(packet->oldarg[0]);
/*
struct p {
uint8_t blockno;
} PACKED;
struct p *payload = (struct p *)packet->data.asBytes;
*/
iClass_ReadBlk( packet->data.asBytes[0] );
break;
}
case CMD_HF_ICLASS_AUTH: { //check
/*
struct p {
uint8_t mac[4];
} PACKED;
struct p *payload = (struct p *)packet->data.asBytes;
*/
iClass_Authentication(packet->data.asBytes);
break;
}
@ -1252,7 +1273,13 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_ICLASS_CLONE: {
iClass_Clone(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
struct p {
uint8_t startblock;
uint8_t endblock;
uint8_t data[];
} PACKED;
struct p *payload = (struct p *)packet->data.asBytes;
iClass_Clone(payload->startblock, payload->endblock, payload->data);
break;
}
#endif

View file

@ -44,7 +44,7 @@
int cs_win_snprintf(char *str, size_t size, const char *format, ...);
int cs_win_vsnprintf(char *str, size_t size, const char *format, va_list ap);
#if _MSC_VER >= 1700
#include <stdint.h>
#include "stdint.h"
#else
typedef _int64 int64_t;
typedef unsigned _int64 uint64_t;

View file

@ -55,7 +55,11 @@
#include "protocols.h"
#include "ticks.h"
static int timeout = 4096;
static int g_wait = 290;
static int timeout = 5000;
static uint32_t time_rdr = 0;
static uint32_t time_response = 0;
static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay);
int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf);
@ -151,7 +155,7 @@ typedef struct {
static tUartIc Uart;
static void OnError(uint8_t reason) {
reply_old(CMD_ACK, 0, reason, 0, 0, 0);
reply_mix(CMD_ACK, 0, reason, 0, 0, 0);
switch_off();
}
@ -160,10 +164,12 @@ static void uart_reset(void) {
Uart.synced = false;
Uart.frame = false;
}
static void uart_init(uint8_t *data) {
Uart.buf = data;
uart_reset();
}
static void uart_bit(uint8_t bit) {
static uint8_t buf = 0xff;
static uint8_t n_buf;
@ -890,8 +896,6 @@ void RAMFUNC SniffIClass(void) {
// time ZERO, the point from which it all is calculated.
time_0 = GetCountSspClk();
int divi = 0;
uint8_t tag_byte = 0, foo = 0;
// loop and listen
// every sample (1byte in data),
// contains HIGH nibble = reader data
@ -902,12 +906,11 @@ void RAMFUNC SniffIClass(void) {
for (;;) {
WDT_HIT();
if (checked == 1000) {
if (checked == 2000) {
if (BUTTON_PRESS() || data_available()) break;
checked = 0;
} else {
checked++;
}
checked++;
previous_data <<= 8;
previous_data |= *data;
@ -921,14 +924,6 @@ void RAMFUNC SniffIClass(void) {
AT91C_BASE_PDC_SSC->PDC_RNCR = ICLASS_DMA_BUFFER_SIZE;
}
if (*data & 0xF) {
//tag_byte <<= 1;
tag_byte ^= (1 << 4);
foo ^= (1 << (3 - divi));
Dbprintf(" %d|%x == %d|%x", tag_byte, tag_byte, foo, foo);
}
divi++;
// every odd sample
if (sniffCounter & 0x01) {
// no need to try decoding reader data if the tag is sending
@ -958,8 +953,6 @@ void RAMFUNC SniffIClass(void) {
LED_C_INV();
// LOW nibble is always tag data.
/*
uint32_t tag_byte =
((previous_data & 0x0F000000) >> 8 ) |
((previous_data & 0x000F0000) >> 4 ) |
@ -969,8 +962,8 @@ void RAMFUNC SniffIClass(void) {
*/
//uint8_t tag_byte = ((previous_data & 0xF) << 4 ) | (*data & 0xF);
if (ManchesterDecoding_iclass(foo)) {
uint8_t tag_byte = ((previous_data & 0xF) << 4 ) | (*data & 0xF);
if (ManchesterDecoding_iclass(tag_byte)) {
time_stop = GetCountSspClk() - time_0;
LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false);
DemodIcReset();
@ -980,17 +973,15 @@ void RAMFUNC SniffIClass(void) {
}
TagIsActive = (Demod.state != DEMOD_IC_UNSYNCD);
}
tag_byte = 0;
foo = 0;
divi = 0;
}
} // end main loop
/*
if (DBGLEVEL >= 1) {
DbpString("[+] Sniff statistics:");
Dbhexdump(ICLASS_DMA_BUFFER_SIZE, data, false);
}
*/
switch_off();
}
@ -1023,12 +1014,11 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen)
WDT_HIT();
if (checked == 1000) {
if (checked == 2000) {
if (BUTTON_PRESS() || data_available()) return false;
checked = 0;
} else {
checked++;
}
checked++;
// keep tx buffer in a defined state anyway.
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))
@ -1048,6 +1038,7 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen)
return false;
}
/*
static uint8_t encode4Bits(const uint8_t b) {
// OTA, the least significant bits first
// Manchester encoding added
@ -1094,6 +1085,9 @@ static uint8_t encode4Bits(const uint8_t b) {
return 0xaa; // 0000 -> 0000 -> 10101010 -> 0xaa
}
}
*/
static uint8_t lut_enc[] = { 0xAA, 0x6A, 0x9A, 0x5A, 0xA6, 0x66, 0x96, 0x56, 0xA9, 0x69, 0x99, 0x59, 0xA5, 0x65, 0x95, 0x55 };
//-----------------------------------------------------------------------------
// Prepare tag messages
@ -1140,8 +1134,8 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) {
int i;
for (i = 0; i < len; i++) {
uint8_t b = cmd[i];
ToSend[++ToSendMax] = encode4Bits(b & 0xF); // least significant half
ToSend[++ToSendMax] = encode4Bits((b >> 4) & 0xF); // most significant half
ToSend[++ToSendMax] = lut_enc[b & 0xF]; // least significant half
ToSend[++ToSendMax] = lut_enc[(b >> 4) & 0xF]; // most significant half
}
// Send EOF
@ -1427,9 +1421,9 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
uint32_t time_0 = GetCountSspClk();
uint32_t t2r_stime = 0, t2r_etime = 0;
uint32_t r2t_stime, r2t_etime = 0;
LED_A_ON();
bool buttonPressed = false;
uint8_t cmd, options, block;
while (!exitLoop) {
WDT_HIT();
@ -1450,7 +1444,11 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
LED_C_ON(); //Signal tracer
if (receivedCmd[0] == ICLASS_CMD_ACTALL) { // 0x0A
cmd = receivedCmd[0] & 0xF;
options = (receivedCmd[0] >> 4) & 0xFF;
block = receivedCmd[1];
if (cmd == ICLASS_CMD_ACTALL) { // 0x0A
// Reader in anticollission phase
modulated_response = resp_sof;
modulated_response_size = resp_sof_Len; //order = 1;
@ -1458,7 +1456,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
trace_data_size = sizeof(sof_data);
// adjusted for 330 + (160*num of slot)
goto send;
} else if (receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C
} else if (cmd == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C
if (len == 1) {
// Reader asks for anticollission CSN
modulated_response = resp_anticoll;
@ -1470,7 +1468,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
if (len == 4) {
// block0,1,2,5 is always readable.
switch (receivedCmd[1]) {
switch (block) {
case 0: // csn (0c 00)
modulated_response = resp_csn;
modulated_response_size = resp_csn_len;
@ -1503,7 +1501,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
if (simulationMode == MODE_FULLSIM) { // 0x0C
//Read block
//Take the data...
memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8);
memcpy(data_generic_trace, emulator + (block << 3), 8);
AddCrc(data_generic_trace, 8);
trace_data = data_generic_trace;
trace_data_size = 10;
@ -1516,7 +1514,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
}
}//swith
}// if 4
} else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81
} else if (cmd == ICLASS_CMD_SELECT) { // 0x81
// Reader selects anticollission CSN.
// Tag sends the corresponding real CSN
modulated_response = resp_csn;
@ -1524,23 +1522,15 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
trace_data = csn_data;
trace_data_size = sizeof(csn_data);
goto send;
} else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KD) { // 0x88
// Read e-purse (88 02)
} else if (cmd == ICLASS_CMD_READCHECK ) { // 0x88
// Read e-purse KD (88 02) KC (18 02)
modulated_response = resp_cc;
modulated_response_size = resp_cc_len; //order = 4;
trace_data = card_challenge_data;
trace_data_size = sizeof(card_challenge_data);
LED_B_ON();
goto send;
} else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KC) { // 0x18
// Read e-purse (18 02)
modulated_response = resp_cc;
modulated_response_size = resp_cc_len; //order = 4;
trace_data = card_challenge_data;
trace_data_size = sizeof(card_challenge_data);
LED_B_ON();
goto send;
} else if (receivedCmd[0] == ICLASS_CMD_CHECK) { // 0x05
} else if (cmd == ICLASS_CMD_CHECK) { // 0x05
// Reader random and reader MAC!!!
if (simulationMode == MODE_FULLSIM) {
// NR, from reader, is in receivedCmd +1
@ -1578,17 +1568,17 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
}
}
goto send;
} else if (receivedCmd[0] == ICLASS_CMD_HALT && len == 1) {
} else if (cmd == ICLASS_CMD_HALT && options == 0 && len == 1) {
// Reader ends the session
modulated_response = resp_sof;
modulated_response_size = 0; //order = 0;
trace_data = NULL;
trace_data_size = 0;
goto send;
} else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ4 && len == 4) { // 0x06
} else if (simulationMode == MODE_FULLSIM && cmd == ICLASS_CMD_READ4 && len == 4) { // 0x06
//Read block
//Take the data...
memcpy(data_generic_trace, emulator + (receivedCmd[1] << 3), 8 * 4);
memcpy(data_generic_trace, emulator + (block << 3), 8 * 4);
AddCrc(data_generic_trace, 8 * 4);
trace_data = data_generic_trace;
trace_data_size = 34;
@ -1596,7 +1586,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) {
memcpy(modulated_response, ToSend, ToSendMax);
modulated_response_size = ToSendMax;
goto send;
} else if (simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_UPDATE) {
} else if (simulationMode == MODE_FULLSIM && cmd == ICLASS_CMD_UPDATE) {
//Probably the reader wants to update the nonce. Let's just ignore that for now.
// OBS! If this is implemented, don't forget to regenerate the cipher_state
@ -1640,7 +1630,7 @@ send:
A legit tag has about 330us delay between reader EOT and tag SOF.
**/
if (modulated_response_size > 0) {
t2r_stime = (GetCountSspClk() - time_0) << 4;
t2r_stime = GetCountSspClkDelta(time_0) << 4;
SendIClassAnswer(modulated_response, modulated_response_size, 0);
t2r_etime = ((GetCountSspClk() - time_0) << 4) - t2r_stime;
}
@ -1676,12 +1666,12 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) {
uint16_t checked = 0;
for (;;) {
if (checked == 1000) {
if (checked == 2000) {
if (BUTTON_PRESS() || data_available()) return 0;
checked = 0;
} else {
checked++;
}
checked++;
// Prevent rx holding register from overflowing
if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {
b = AT91C_BASE_SSC->SSC_RHR;
@ -1710,14 +1700,16 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) {
//-----------------------------------------------------------------------------
// Transmit the command (to the tag) that was placed in ToSend[].
//-----------------------------------------------------------------------------
static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait) {
static void TransmitIClassCommand(const uint8_t *cmd, int len, int *wait) {
int c = 0;
volatile uint32_t b;
bool firstpart = true;
uint8_t sendbyte;
time_rdr = 0;
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
AT91C_BASE_SSC->SSC_THR = 0x00;
// make sure we timeout previous comms.
@ -1747,20 +1739,9 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int
if (c >= len) break;
}
// Prevent rx holding register from overflowing
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
b = AT91C_BASE_SSC->SSC_RHR;
(void)b;
}
}
if (samples) {
if (wait)
*samples = (c + *wait) << 3;
else
*samples = c << 3;
}
time_rdr = GetCountSspClk();
}
//-----------------------------------------------------------------------------
@ -1804,17 +1785,12 @@ void CodeIClassCommand(const uint8_t *cmd, int len) {
void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait) {
int samples = 0;
// This is tied to other size changes
CodeIClassCommand(frame, len);
// Select the card
TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait);
if (trigger)
LED_A_ON();
rsamples += samples;
TransmitIClassCommand(ToSend, ToSendMax, &wait);
LED_A_ON();
LogTrace(frame, len, rsamples, rsamples, NULL, true);
}
@ -1827,22 +1803,20 @@ void ReaderTransmitIClass(uint8_t *frame, int len) {
// If a response is captured return TRUE
// If it takes too long return FALSE
//-----------------------------------------------------------------------------
static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed) {
static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *wait) {
// buffer needs to be 512 bytes
// maxLen is not used...
int c = 0;
bool skip = false;
LED_D_ON();
// Set FPGA mode to "reader listen mode", no modulation (listen
// only, since we are receiving, not transmitting).
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);
// Setup UART/DEMOD to receive
DemodIcInit(receivedResponse);
if (elapsed) *elapsed = 0;
// Set FPGA mode to "reader listen mode", no modulation (listen
// only, since we are receiving, not transmitting).
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);
SpinDelayUs(320); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments.
SpinDelayUs(g_wait); //310 Tout= 330us (iso15603-2) (330/21.3) take consideration for clock increments.
// clear RXRDY:
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
@ -1850,38 +1824,28 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples,
uint16_t checked = 0;
uint32_t card_start = GetCountSspClk();
for (;;) {
WDT_HIT();
if (checked == 1000) {
if (checked == 2000) {
if (BUTTON_PRESS() || data_available()) return false;
checked = 0;
} else {
checked++;
}
// keep tx buffer in a defined state anyway.
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x00;
// To make use of exact timing of next command from reader!!
if (elapsed)(*elapsed)++;
}
checked++;
// Wait for byte be become available in rx holding register
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
if (c >= timeout) return false;
c++;
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
skip = !skip;
if (skip) continue;
if (ManchesterDecoding_iclass(b & 0x0f)) {
if (samples)
*samples = c << 3;
time_response = GetCountSspClk() - card_start;
return true;
} else if (GetCountSspClkDelta(card_start) > timeout && Demod.state == DEMOD_IC_UNSYNCD) {
return false;
}
}
}
@ -1889,18 +1853,11 @@ static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples,
}
int ReaderReceiveIClass(uint8_t *receivedAnswer) {
int samples = 0;
if (!GetIClassAnswer(receivedAnswer, 0, &samples, NULL))
return false;
rsamples += samples;
if (GetIClassAnswer(receivedAnswer, 0, NULL) == false)
return 0;
LogTrace(receivedAnswer, Demod.len, rsamples, rsamples, NULL, false);
if (samples == 0)
return false;
return Demod.len;
}
@ -1924,25 +1881,34 @@ void setupIclassReader() {
// Now give it time to spin up.
// Signal field is on with the appropriate LED
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
SpinDelay(300);
SpinDelay(500);
StartCountSspClk();
LED_A_ON();
}
bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, uint8_t retries) {
bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, int8_t retries) {
while (retries-- > 0) {
ReaderTransmitIClass(command, cmdsize);
//iceman - if received size is bigger than expected, we smash the stack here
// since its called with fixed sized arrays
// update/write command takes 4ms to 15ms before responding
int old_wait = g_wait;
if ( (command[0] & 0xF) == ICLASS_CMD_UPDATE)
g_wait = 3900;
uint8_t got_n = ReaderReceiveIClass(resp);
g_wait = old_wait;
// 0xBB is the internal debug separator byte..
if (expected_size != got_n || (resp[0] == 0xBB || resp[7] == 0xBB || resp[2] == 0xBB)) {
//try again
// SpinDelayUs(360);
continue;
}
@ -1964,26 +1930,30 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) {
// act_all...
static uint8_t act_all[] = { ICLASS_CMD_ACTALL };
static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 };
static uint8_t select[] = { ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK_KD, 0x02 };
static uint8_t select[] = { 0x80 | ICLASS_CMD_SELECT, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 };
// Bit 4: K.If this bit equals to one, the READCHECK will use the Credit Key (Kc); if equals to zero, Debit Key (Kd) willbe used
// bit 7: parity.
if (use_credit_key)
readcheck_cc[0] = ICLASS_CMD_READCHECK_KC;
readcheck_cc[0] = 0x10 | ICLASS_CMD_READCHECK;
uint8_t resp[ICLASS_BUFFER_SIZE] = {0};
uint8_t read_status = 0;
// Send act_all
ReaderTransmitIClass_ext(act_all, 1, 330 + 160);
// Send act_all ( 330 timeout + 160 timeslot);
ReaderTransmitIClass_ext(act_all, 1, 330 + 180);
// Card present?
if (!ReaderReceiveIClass(resp)) return read_status;//Fail
if (ReaderReceiveIClass(resp) == 0)
return 0;
//Send Identify
ReaderTransmitIClass(identify, 1);
//We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC
uint8_t len = ReaderReceiveIClass(resp);
if (len != 10) return read_status;//Fail
if ( ReaderReceiveIClass(resp) != 10 )
return 0;
//Copy the Anti-collision CSN to our select-packet
memcpy(&select[1], resp, 8);
@ -1992,17 +1962,10 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) {
ReaderTransmitIClass(select, sizeof(select));
//We expect a 10-byte response here, 8 byte CSN and 2 byte CRC
len = ReaderReceiveIClass(resp);
if (len != 10) return read_status;//Fail
if ( ReaderReceiveIClass(resp) != 10)
return 0;
//Success - level 1, we got CSN
//Save CSN in response data
memcpy(card_data, resp, 8);
//Flag that we got to at least stage 1, read CSN
read_status = 1;
// Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
// Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
// ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
// if (ReaderReceiveIClass(resp) == 8) {
// //Save CC (e-purse) in response data
@ -2010,13 +1973,22 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) {
// read_status++;
// }
bool isOK = sendCmdGetResponseWithRetries(readcheck_cc, sizeof(readcheck_cc), resp, 8, 3);
if (!isOK) return read_status;
//Success - level 1, we got CSN
//Save CSN in response data
memcpy(card_data, resp, 8);
bool isBlk_2 = sendCmdGetResponseWithRetries(readcheck_cc, sizeof(readcheck_cc), resp, 8, 3);
//Flag that we got to at least stage 1, read CSN
if ( isBlk_2 == false) {
return 1;
}
//Save CC (e-purse) in response data
memcpy(card_data + 8, resp, 8);
read_status++;
return read_status;
// we got all data;
return 2;
}
uint8_t handshakeIclassTag(uint8_t *card_data) {
return handshakeIclassTag_ext(card_data, false);
@ -2057,7 +2029,7 @@ void ReaderIClass(uint8_t arg0) {
WDT_HIT();
// if only looking for one card try 2 times if we missed it the first time
if (try_once && tryCnt > 2) {
if (try_once && tryCnt > 10) {
if (DBGLEVEL > 1) DbpString("Failed to find a tag");
break;
}
@ -2140,7 +2112,7 @@ void ReaderIClass(uint8_t arg0) {
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("SEND %c", send ? 'y' : 'n');
if (send) {
reply_old(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data));
reply_mix(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data));
if (abort_after_read) {
LED_B_OFF();
return;
@ -2151,19 +2123,18 @@ void ReaderIClass(uint8_t arg0) {
}
LED_B_OFF();
if (checked == 1000) {
if (checked == 2000) {
userCancelled = BUTTON_PRESS() || data_available();
checked = 0;
} else {
checked++;
}
checked++;
}
if (userCancelled) {
reply_old(CMD_ACK, 0xFF, 0, 0, card_data, 0);
reply_mix(CMD_ACK, 0xFF, 0, 0, card_data, 0);
switch_off();
} else {
reply_old(CMD_ACK, 0, 0, 0, card_data, 0);
reply_mix(CMD_ACK, 0, 0, 0, card_data, 0);
}
}
@ -2311,8 +2282,8 @@ void iClass_Authentication(uint8_t *mac) {
//memcpy(check+5, mac, 4);
// 6 retries
bool isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6);
reply_mix(CMD_ACK, isOK, 0, 0, 0, 0);
uint8_t isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6);
reply_ng(CMD_HF_ICLASS_AUTH, PM3_SUCCESS, (uint8_t*)&isOK ,sizeof(uint8_t));
}
typedef struct iclass_premac {
@ -2333,10 +2304,10 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
uint8_t keyCount = arg1 & 0xFF;
uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t resp[ICLASS_BUFFER_SIZE];
uint8_t readcheck_cc[] = { ICLASS_CMD_READCHECK_KD, 0x02 };
uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 };
if (use_credit_key)
readcheck_cc[0] = ICLASS_CMD_READCHECK_KC;
readcheck_cc[0] = 0x10 | ICLASS_CMD_READCHECK;
// select card / e-purse
uint8_t card_data[6 * 8] = {0};
@ -2355,12 +2326,11 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
uint8_t startup_limit = 10;
while (read_status != 2) {
if (checked == 1000) {
if (checked == 2000) {
if (BUTTON_PRESS() || !data_available()) goto out;
checked = 0;
} else {
checked++;
}
checked++;
read_status = handshakeIclassTag_ext(card_data, use_credit_key);
if (startup_limit-- == 0) {
@ -2371,16 +2341,17 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
};
// since handshakeIclassTag_ext call sends s readcheck, we start with sending first response.
checked = 0;
// Keychunk loop
for (i = 0; i < keyCount; i++) {
// Allow button press / usb cmd to interrupt device
if (checked == 1000) {
if (checked == 2000) {
if (BUTTON_PRESS() || !data_available()) goto out;
checked = 0;
} else {
checked++;
}
checked++;
WDT_HIT();
LED_B_ON();
@ -2396,8 +2367,6 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
if (isOK)
goto out;
SpinDelayUs(400); //iClass (iso15693-2) should timeout after 330us.
// Auth Sequence MUST begin with reading e-purse. (block2)
// Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
@ -2433,10 +2402,14 @@ bool iClass_ReadBlock(uint8_t blockno, uint8_t *data, uint8_t len) {
// turn off afterwards
// readblock 8 + 2. only want 8.
void iClass_ReadBlk(uint8_t blockno) {
uint8_t data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
bool isOK = iClass_ReadBlock(blockno, data, sizeof(data));
reply_mix(CMD_ACK, isOK, 0, 0, data, sizeof(data));
struct p {
bool isOK;
uint8_t blockdata[8];
} PACKED result;
result.isOK = iClass_ReadBlock(blockno, result.blockdata, sizeof(result.blockdata));
switch_off();
reply_ng(CMD_HF_ICLASS_READBL, PM3_SUCCESS, (uint8_t *)&result, sizeof(result));
}
// turn off afterwards
@ -2448,7 +2421,7 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) {
BigBuf_free();
uint8_t *dataout = BigBuf_malloc(255 * 8);
if (dataout == NULL) {
DbpString("[!] out of memory");
DbpString("[!] fail to allocate memory");
OnError(1);
return;
}
@ -2468,39 +2441,26 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) {
}
memcpy(dataout + (blkCnt * 8), blockdata, 8);
}
switch_off();
//return pointer to dump memory in arg3
reply_mix(CMD_ACK, isOK, blkCnt, BigBuf_max_traceLen(), 0, 0);
switch_off();
BigBuf_free();
}
bool iClass_WriteBlock_ext(uint8_t blockno, uint8_t *data) {
uint8_t resp[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t write[] = { ICLASS_CMD_UPDATE, blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t write[] = { 0x80 | ICLASS_CMD_UPDATE, blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
memcpy(write + 2, data, 12); // data + mac
AddCrc(write + 1, 13);
bool isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5);
if (isOK) { //if reader responded correctly
//if response is not equal to write values
if (memcmp(write + 2, resp, 8)) {
//if not programming key areas (note key blocks don't get programmed with actual key data it is xor data)
if (blockno != 3 && blockno != 4) {
isOK = sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5);
}
}
}
return isOK;
return sendCmdGetResponseWithRetries(write, sizeof(write), resp, sizeof(resp), 5);
}
// turn off afterwards
void iClass_WriteBlock(uint8_t blockno, uint8_t *data) {
bool isOK = iClass_WriteBlock_ext(blockno, data);
reply_mix(CMD_ACK, isOK, 0, 0, 0, 0);
uint8_t isOK = iClass_WriteBlock_ext(blockno, data);
switch_off();
reply_ng(CMD_HF_ICLASS_WRITEBL, PM3_SUCCESS, (uint8_t*)&isOK, sizeof(uint8_t));
}
// turn off afterwards
@ -2509,23 +2469,19 @@ void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) {
int total_block = (endblock - startblock) + 1;
for (i = 0; i < total_block; i++) {
// block number
if (iClass_WriteBlock_ext(i + startblock, data + (i * 12))) {
Dbprintf("Write block [%02x] successful", i + startblock);
if (iClass_WriteBlock_ext(startblock + i, data + (i * 12))) {
Dbprintf("Write block [%02x] successful", startblock + i);
written++;
} else {
if (iClass_WriteBlock_ext(i + startblock, data + (i * 12))) {
Dbprintf("Write block [%02x] successful", i + startblock);
written++;
} else {
Dbprintf("Write block [%02x] failed", i + startblock);
}
Dbprintf("Write block [%02x] failed", startblock + i);
}
}
if (written == total_block)
DbpString("Clone complete");
else
DbpString("Clone incomplete");
reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
switch_off();
uint8_t isOK = 0;
if (written == total_block)
isOK = 1;
reply_ng(CMD_HF_ICLASS_CLONE, PM3_SUCCESS, (uint8_t *)&isOK, sizeof(uint8_t));
}

View file

@ -1672,26 +1672,11 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
// clear TXRDY
AT91C_BASE_SSC->SSC_THR = SEC_Y;
volatile uint8_t b;
uint16_t c = 0;
uint32_t sendtimer = GetTickCount();
uint32_t cntr = 0;
while (c < len) {
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = cmd[c++];
cntr = 0;
} else {
if (cntr++ > 1000) {
cntr = 0;
if (GetTickCount() - sendtimer > 100)
break;
}
}
//iceman test
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
(void)b;
AT91C_BASE_SSC->SSC_THR = cmd[c];
c++;
}
}

View file

@ -941,7 +941,7 @@ static void fcSTT(int *n) {
}
// compose fc/X fc/Y waveform (FSKx)
static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) {
static uint8_t fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) {
uint8_t *dest = BigBuf_get_addr();
uint8_t halfFC = fc >> 1;
uint8_t wavesPerClock = clock / fc;
@ -966,12 +966,15 @@ static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) {
*n += fc;
}
}
/* This code interfers with FSK2 and I don't see any example of FSK1 simulation in the code...
if (!modAdjOk) { //fsk1
memset(dest + (*n), 0, mod - (mod >> 1));
memset(dest + (*n) + (mod - (mod >> 1)), 1, mod >> 1);
*n += mod;
}
*/
}
return mod;
}
// prepare a waveform pattern in the buffer based on the ID given then
@ -1059,17 +1062,17 @@ void CmdFSKsimTAG(uint8_t fchigh, uint8_t fclow, uint8_t separator, uint8_t clk,
int n = 0, i = 0;
uint16_t modCnt = 0;
uint8_t mod = 0;
if (separator) {
//int fsktype = ( fchigh == 8 && fclow == 5) ? 1 : 2;
//fcSTT(&n);
}
for (i = 0; i < bitslen; i++) {
if (bits[i])
fcAll(fclow, &n, clk, &modCnt);
mod = fcAll(fchigh, &n, clk+mod, &modCnt);
else
fcAll(fchigh, &n, clk, &modCnt);
mod = fcAll(fclow, &n, clk+mod, &modCnt);
}
WDT_HIT();
@ -1306,7 +1309,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
hi2 = hi = lo = idx = 0;
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
DbpString("Stopped");
DbpString("HID fsk demod stopped");
if (ledcontrol) LED_A_OFF();
}
@ -2060,6 +2063,7 @@ void T55xxWakeUp(uint32_t pwd, uint8_t flags) {
//-- Turn and leave field on to let the begin repeating transmission
TurnReadLFOn(20 * 1000);
reply_ng(CMD_LF_T55XX_WAKEUP, PM3_SUCCESS, NULL, 0);
}

View file

@ -1342,8 +1342,6 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
for (uint16_t i = s_point; i < keyCount; ++i) {
//if ( i % 100 == 0) Dbprintf("ChkKeys_fast: sector %d | checking %d | %d found | s_point %d", s, i, foundkeys, s_point);
// Allow button press / usb cmd to interrupt device
if (BUTTON_PRESS() && !data_available()) {
goto OUT;
@ -1525,6 +1523,33 @@ OUT:
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
BigBuf_free();
BigBuf_Clear_ext(false);
// special trick ecfill
if (use_flashmem && foundkeys == allkeys) {
uint8_t block[16] = {0};
for (int i = 0; i < sectorcnt; i++) {
uint8_t blockno;
if (i < 32) {
blockno = (i * 4) ^ 0x3;
} else {
blockno = (32 * 4 + (i - 32) * 16) ^ 0xF;
}
// get ST
emlGetMem(block, blockno, 1);
memcpy(block, k_sector[i].keyA, 6);
memcpy(block + 10, k_sector[i].keyB, 6);
emlSetMem_xt(block, blockno, 1, sizeof(block));
}
int oldbg = DBGLEVEL;
DBGLEVEL = DBG_NONE;
MifareECardLoad(sectorcnt, 0);
MifareECardLoad(sectorcnt, 1);
DBGLEVEL = oldbg;
}
} else {
// partial/none keys found
reply_mix(CMD_ACK, foundkeys, 0, 0, 0, 0);
@ -1669,10 +1694,15 @@ void MifareEMemGet(uint8_t blockno, uint8_t blockcnt) {
// Load a card into the emulator memory
//
//-----------------------------------------------------------------------------
int MifareECardLoad(uint32_t arg0, uint32_t arg1) {
int MifareECardLoadExt(uint8_t numSectors, uint8_t keyType) {
int retval = MifareECardLoad(numSectors, keyType);
reply_ng(CMD_HF_MIFARE_EML_LOAD, retval, NULL, 0);
return retval;
}
int MifareECardLoad(uint8_t numSectors, uint8_t keyType) {
uint32_t cuid = 0;
uint8_t numSectors = arg0;
uint8_t keyType = arg1;
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
@ -1683,68 +1713,63 @@ int MifareECardLoad(uint32_t arg0, uint32_t arg1) {
uint8_t uid[10] = {0x00};
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
clear_trace();
set_tracing(true);
bool isOK = true;
int retval;
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
isOK = false;
if (DBGLEVEL >= 1) Dbprintf("Can't select card");
retval = PM3_ESOFT;
if (DBGLEVEL > DBG_ERROR) Dbprintf("Can't select card");
goto out;
}
for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) {
for (uint8_t sectorNo = 0; sectorNo < numSectors; sectorNo++) {
uint64_t ui64Key = emlGetKey(sectorNo, keyType);
if (sectorNo == 0) {
if (isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {
if (DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth error", sectorNo);
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {
if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo);
break;
}
} else {
if (isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) {
isOK = false;
if (DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth nested error", sectorNo);
break;
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) {
retval = PM3_ESOFT;
if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth nested error", sectorNo);
goto out;
}
}
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
if (isOK && mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {
isOK = false;
if (DBGLEVEL >= 1) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo);
for (uint8_t blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
if (mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {
retval = PM3_ESOFT;
if (DBGLEVEL > DBG_ERROR) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo);
break;
}
if (isOK) {
if (blockNo < NumBlocksPerSector(sectorNo) - 1) {
emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1);
} else { // sector trailer, keep the keys, set only the AC
emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
}
if (blockNo < NumBlocksPerSector(sectorNo) - 1) {
emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1);
} else { // sector trailer, keep the keys, set only the AC
emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
}
}
}
if (mifare_classic_halt(pcs, cuid))
if (DBGLEVEL >= 1)
if (mifare_classic_halt(pcs, cuid)) {
if (DBGLEVEL > DBG_ERROR)
Dbprintf("Halt error");
}
// ----------------------------- crypto1 destroy
if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished");
out:
crypto1_destroy(pcs);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
if (DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED");
set_tracing(false);
return (isOK) ? PM3_SUCCESS : PM3_EUNDEF;
return retval;
}
@ -1955,6 +1980,8 @@ void MifareCIdent() {
#define GEN_1A 1
#define GEN_1B 2
#define GEN_2 4
#define GEN_UNFUSED 5
// variables
uint8_t isGen = 0;
uint8_t rec[1] = {0x00};
@ -1970,19 +1997,19 @@ void MifareCIdent() {
// Generation 1 test
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) {
goto TEST2;
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) {
isGen = GEN_1B;
goto OUT;
};
isGen = GEN_1A;
goto OUT;
if (ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) {
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if (!ReaderReceive(rec, recpar) || (rec[0] != 0x0a)) {
isGen = GEN_1B;
goto OUT;
};
isGen = GEN_1A;
goto OUT;
}
TEST2:
// reset card
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(100);
@ -1990,6 +2017,12 @@ TEST2:
int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res == 2) {
Dbprintf("cident AA55C396 == %08X", cuid);
if (cuid == 0xAA55C396) {
isGen = GEN_UNFUSED;
goto OUT;
}
ReaderTransmit(rats, sizeof(rats), NULL);
res = ReaderReceive(buf, par);
if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10\xF0\x05", 11) == 0) {

View file

@ -31,7 +31,8 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
void MifareEMemClr(void);
void MifareEMemSet(uint8_t blockno, uint8_t blockcnt, uint8_t blockwidth, uint8_t *datain);
void MifareEMemGet(uint8_t blockno, uint8_t blockcnt);
int MifareECardLoad(uint32_t arg0, uint32_t arg1);
int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype);
int MifareECardLoadExt(uint8_t numSectors, uint8_t keyType);
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain);

View file

@ -60,11 +60,59 @@
-- MHS 2015
**/
/**
The runtime of opt_doTagMAC_2() with the MHS optimized version was 403 microseconds on Proxmark3.
This was still to slow for some newer readers which didn't want to wait that long.
Further optimizations to speedup the MAC calculations:
* Optimized opt_Tt logic
* Look up table for opt_select
* Removing many unnecessary bit maskings (& 0x1)
* updating state in place instead of alternating use of a second state structure
* remove the necessity to reverse bits of input and output bytes
opt_doTagMAC_2() now completes in 270 microseconds.
-- piwi 2019
**/
#include "optimized_cipher.h"
#define opt_T(s) (0x1 & ((s->t >> 15) ^ (s->t >> 14)^ (s->t >> 10)^ (s->t >> 8)^ (s->t >> 5)^ (s->t >> 4)^ (s->t >> 1)^ s->t))
static const uint8_t opt_select_LUT[256] = {
00, 03, 02, 01, 02, 03, 00, 01, 04, 07, 07, 04, 06, 07, 05, 04,
01, 02, 03, 00, 02, 03, 00, 01, 05, 06, 06, 05, 06, 07, 05, 04,
06, 05, 04, 07, 04, 05, 06, 07, 06, 05, 05, 06, 04, 05, 07, 06,
07, 04, 05, 06, 04, 05, 06, 07, 07, 04, 04, 07, 04, 05, 07, 06,
06, 05, 04, 07, 04, 05, 06, 07, 02, 01, 01, 02, 00, 01, 03, 02,
03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06,
00, 03, 02, 01, 02, 03, 00, 01, 00, 03, 03, 00, 02, 03, 01, 00,
05, 06, 07, 04, 06, 07, 04, 05, 05, 06, 06, 05, 06, 07, 05, 04,
02, 01, 00, 03, 00, 01, 02, 03, 06, 05, 05, 06, 04, 05, 07, 06,
03, 00, 01, 02, 00, 01, 02, 03, 07, 04, 04, 07, 04, 05, 07, 06,
02, 01, 00, 03, 00, 01, 02, 03, 02, 01, 01, 02, 00, 01, 03, 02,
03, 00, 01, 02, 00, 01, 02, 03, 03, 00, 00, 03, 00, 01, 03, 02,
04, 07, 06, 05, 06, 07, 04, 05, 00, 03, 03, 00, 02, 03, 01, 00,
01, 02, 03, 00, 02, 03, 00, 01, 05, 06, 06, 05, 06, 07, 05, 04,
04, 07, 06, 05, 06, 07, 04, 05, 04, 07, 07, 04, 06, 07, 05, 04,
01, 02, 03, 00, 02, 03, 00, 01, 01, 02, 02, 01, 02, 03, 01, 00
};
#define opt_B(s) (((s->b >> 6) ^ (s->b >> 5) ^ (s->b >> 4) ^ (s->b)) & 0x1)
/********************** the table above has been generated with this code: ********
#include "util.h"
static void init_opt_select_LUT(void) {
for (int r = 0; r < 256; r++) {
uint8_t r_ls2 = r << 2;
uint8_t r_and_ls2 = r & r_ls2;
uint8_t r_or_ls2 = r | r_ls2;
uint8_t z0 = (r_and_ls2 >> 5) ^ ((r & ~r_ls2) >> 4) ^ ( r_or_ls2 >> 3);
uint8_t z1 = (r_or_ls2 >> 6) ^ ( r_or_ls2 >> 1) ^ (r >> 5) ^ r;
uint8_t z2 = ((r & ~r_ls2) >> 4) ^ (r_and_ls2 >> 3) ^ r;
opt_select_LUT[r] = (z0 & 4) | (z1 & 2) | (z2 & 1);
}
print_result("", opt_select_LUT, 256);
}
***********************************************************************************/
#define opt__select(x,y,r) (4 & (((r & (r << 2)) >> 5) ^ ((r & ~(r << 2)) >> 4) ^ ( (r | r << 2) >> 3)))\
|(2 & (((r | r << 2) >> 6) ^ ( (r | r << 2) >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1)))\
@ -74,9 +122,6 @@
* Some background on the expression above can be found here...
uint8_t xopt__select(bool x, bool y, uint8_t r)
{
uint8_t r_ls2 = r << 2;
uint8_t r_and_ls2 = r & r_ls2;
uint8_t r_or_ls2 = r | r_ls2;
//r: r0 r1 r2 r3 r4 r5 r6 r7
//r_ls2: r2 r3 r4 r5 r6 r7 0 0
@ -96,82 +141,95 @@ uint8_t xopt__select(bool x, bool y, uint8_t r)
}
*/
void opt_successor(const uint8_t *k, State *s, bool y, State *successor) {
uint8_t Tt = 1 & opt_T(s);
static void opt_successor(const uint8_t *k, State *s, uint8_t y) {
// #define opt_T(s) (0x1 & ((s->t >> 15) ^ (s->t >> 14) ^ (s->t >> 10) ^ (s->t >> 8) ^ (s->t >> 5) ^ (s->t >> 4)^ (s->t >> 1) ^ s->t))
// uint8_t Tt = opt_T(s);
uint16_t Tt = s->t & 0xc533;
Tt = Tt ^ (Tt >> 1);
Tt = Tt ^ (Tt >> 4);
Tt = Tt ^ (Tt >> 10);
Tt = Tt ^ (Tt >> 8);
successor->t = (s->t >> 1);
successor->t |= (Tt ^ (s->r >> 7 & 0x1) ^ (s->r >> 3 & 0x1)) << 15;
s->t = (s->t >> 1);
s->t |= (Tt ^ (s->r >> 7) ^ (s->r >> 3)) << 15;
successor->b = s->b >> 1;
successor->b |= (opt_B(s) ^ (s->r & 0x1)) << 7;
uint8_t opt_B = s->b;
opt_B ^= s->b >> 6;
opt_B ^= s->b >> 5;
opt_B ^= s->b >> 4;
successor->r = (k[opt__select(Tt, y, s->r)] ^ successor->b) + s->l ;
successor->l = successor->r + s->r;
s->b = s->b >> 1;
s->b |= (opt_B ^ s->r) << 7;
uint8_t opt_select = opt_select_LUT[s->r] & 0x04;
opt_select |= (opt_select_LUT[s->r] ^ ((Tt ^ y) << 1)) & 0x02;
opt_select |= (opt_select_LUT[s->r] ^ Tt) & 0x01;
uint8_t r = s->r;
s->r = (k[opt_select] ^ s->b) + s->l ;
s->l = s->r + r;
}
void opt_suc(const uint8_t *k, State *s, uint8_t *in, uint8_t length, bool add32Zeroes) {
State x2;
static void opt_suc(const uint8_t *k, State *s, uint8_t *in, uint8_t length, bool add32Zeroes) {
for (int i = 0; i < length; i++) {
uint8_t head;
head = 1 & (in[i] >> 7);
opt_successor(k, s, head, &x2);
head = in[i];
opt_successor(k, s, head);
head = 1 & (in[i] >> 6);
opt_successor(k, &x2, head, s);
head >>= 1;
opt_successor(k, s, head);
head = 1 & (in[i] >> 5);
opt_successor(k, s, head, &x2);
head >>= 1;
opt_successor(k, s, head);
head = 1 & (in[i] >> 4);
opt_successor(k, &x2, head, s);
head >>= 1;
opt_successor(k, s, head);
head = 1 & (in[i] >> 3);
opt_successor(k, s, head, &x2);
head >>= 1;
opt_successor(k, s, head);
head = 1 & (in[i] >> 2);
opt_successor(k, &x2, head, s);
head >>= 1;
opt_successor(k, s, head);
head = 1 & (in[i] >> 1);
opt_successor(k, s, head, &x2);
head >>= 1;
opt_successor(k, s, head);
head = 1 & in[i];
opt_successor(k, &x2, head, s);
head >>= 1;
opt_successor(k, s, head);
}
//For tag MAC, an additional 32 zeroes
if (add32Zeroes) {
for (int i = 0; i < 16; i++) {
opt_successor(k, s, 0, &x2);
opt_successor(k, &x2, 0, s);
opt_successor(k, s, 0);
opt_successor(k, s, 0);
}
}
}
void opt_output(const uint8_t *k, State *s, uint8_t *buffer) {
State temp = {0, 0, 0, 0};
static void opt_output(const uint8_t *k, State *s, uint8_t *buffer) {
for (uint8_t times = 0; times < 4; times++) {
uint8_t bout = 0;
bout |= (s->r & 0x4) << 5;
opt_successor(k, s, 0, &temp);
bout |= (temp.r & 0x4) << 4;
opt_successor(k, &temp, 0, s);
bout |= (s->r & 0x4) << 3;
opt_successor(k, s, 0, &temp);
bout |= (temp.r & 0x4) << 2;
opt_successor(k, &temp, 0, s);
bout |= (s->r & 0x4) << 1;
opt_successor(k, s, 0, &temp);
bout |= (temp.r & 0x4) ;
opt_successor(k, &temp, 0, s);
bout |= (s->r & 0x4) >> 2;
opt_successor(k, s, 0);
bout |= (s->r & 0x4) >> 1;
opt_successor(k, s, 0, &temp);
bout |= (temp.r & 0x4) >> 2;
opt_successor(k, &temp, 0, s);
opt_successor(k, s, 0);
bout |= (s->r & 0x4);
opt_successor(k, s, 0);
bout |= (s->r & 0x4) << 1;
opt_successor(k, s, 0);
bout |= (s->r & 0x4) << 2;
opt_successor(k, s, 0);
bout |= (s->r & 0x4) << 3;
opt_successor(k, s, 0);
bout |= (s->r & 0x4) << 4;
opt_successor(k, s, 0);
bout |= (s->r & 0x4) << 5;
opt_successor(k, s, 0);
buffer[times] = bout;
}
}
void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) {
static void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) {
State _init = {
((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l
((k[0] ^ 0x4c) + 0x21) & 0xFF,// r
@ -183,45 +241,25 @@ void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out) {
opt_output(k, &_init, out);
}
uint8_t rev_byte(uint8_t b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
void opt_reverse_arraybytecpy(uint8_t *dest, uint8_t *src, size_t len) {
uint8_t i;
for (i = 0; i < len ; i++)
dest[i] = rev_byte(src[i]);
}
void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) {
static uint8_t cc_nr[12];
opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12);
uint8_t dest [] = {0, 0, 0, 0, 0, 0, 0, 0};
opt_MAC(div_key_p, cc_nr, dest);
//The output MAC must also be reversed
opt_reverse_arraybytecpy(mac, dest, 4);
opt_MAC(div_key_p, cc_nr_p, dest);
memcpy(mac, dest, 4);
return;
}
void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) {
static uint8_t cc_nr[8 + 4 + 4];
opt_reverse_arraybytecpy(cc_nr, cc_p, 12);
State _init = {
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
0x4c, // b
0xE012 // t
};
opt_suc(div_key_p, &_init, cc_nr, 12, true);
uint8_t dest [] = {0, 0, 0, 0};
opt_output(div_key_p, &_init, dest);
//The output MAC must also be reversed
opt_reverse_arraybytecpy(mac, dest, 4);
opt_suc(div_key_p, &_init, cc_p, 12, true);
opt_output(div_key_p, &_init, mac);
return;
}
/**
* The tag MAC can be divided (both can, but no point in dividing the reader mac) into
* two functions, since the first 8 bytes are known, we can pre-calculate the state
@ -231,17 +269,16 @@ void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) {
* @return the cipher state
*/
State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) {
static uint8_t cc_nr[8];
opt_reverse_arraybytecpy(cc_nr, cc_p, 8);
State _init = {
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
0x4c, // b
0xE012 // t
};
opt_suc(div_key_p, &_init, cc_nr, 8, false);
opt_suc(div_key_p, &_init, cc_p, 8, false);
return _init;
}
/**
* The second part of the tag MAC calculation, since the CC is already calculated into the state,
* this function is fed only the NR, and internally feeds the remaining 32 0-bits to generate the tag
@ -252,13 +289,7 @@ State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) {
* @param div_key_p - the key to use
*/
void opt_doTagMAC_2(State _init, uint8_t *nr, uint8_t mac[4], const uint8_t *div_key_p) {
static uint8_t _nr[4];
opt_reverse_arraybytecpy(_nr, nr, 4);
opt_suc(div_key_p, &_init, _nr, 4, true);
uint8_t dest [] = {0, 0, 0, 0};
opt_output(div_key_p, &_init, dest);
//The output MAC must also be reversed
opt_reverse_arraybytecpy(mac, dest, 4);
opt_suc(div_key_p, &_init, nr, 4, true);
opt_output(div_key_p, &_init, mac);
return;
}

View file

@ -2,7 +2,7 @@
#define OPTIMIZED_CIPHER_H
#include "common.h"
#include "string.h"
/**
* Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2
* consisting of the following four components:

View file

@ -94,7 +94,10 @@ size_t DemodPCF7931(uint8_t **outBlocks) {
} else {
// Error
if (++warnings > 10) {
Dbprintf("Error: too many detection errors, aborting.");
if ( DBGLEVEL >= DBG_EXTENDED )
Dbprintf("Error: too many detection errors, aborting.");
return 0;
}
}
@ -135,27 +138,38 @@ bool IsBlock0PCF7931(uint8_t *block) {
// assuming all RFU bits are set to 0
// if PAC is enabled password is set to 0
if (block[7] == 0x01) {
if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) && !memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7))
if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7)
&& !memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) {
return true;
}
} else if (block[7] == 0x00) {
if (!memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7))
if (!memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) {
return true;
}
}
return false;
}
bool IsBlock1PCF7931(uint8_t *block) {
// assuming all RFU bits are set to 0
if (block[10] == 0
&& block[11] == 0
&& block[12] == 0
&& block[13] == 0) {
if ((block[14] & 0x7f) <= 9
&& block[15] <= 9) {
uint8_t rb1 = block[14] & 0x80;
uint8_t rfb = block[14] & 0x7f;
uint8_t rlb = block[15];
if (block[10] == 0
&& block[11] == 0
&& block[12] == 0
&& block[13] == 0) {
// block 1 is sent only if (RLB >= 1 && RFB <= 1) or RB1 enabled
if (rfb <= rlb
&& rfb <= 9
&& rlb <= 9
&& ((rfb <= 1 && rlb >= 1) || rb1)) {
return true;
}
}
return false;
}
@ -188,21 +202,28 @@ void ReadPCF7931() {
// exit if no block is received
if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) {
Dbprintf("Error, no tag or bad tag");
if ( DBGLEVEL >= DBG_INFO )
Dbprintf("[!!] Error, no tag or bad tag");
return;
}
// exit if too many errors during reading
if (tries > 50 && (2 * errors > tries)) {
Dbprintf("Error reading the tag");
Dbprintf("Here is the partial content");
if ( DBGLEVEL >= DBG_INFO )
Dbprintf("[!!] Error reading the tag, only partial content");
goto end;
}
// our logic breaks if we don't get at least two blocks
if (n < 2) {
// skip if all 0s block or no blocks
if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16))
continue;
// add block to single blocks list
if (single_blocks_cnt < max_blocks) {
for (i = 0; i < single_blocks_cnt; ++i) {
if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) {
@ -212,6 +233,7 @@ void ReadPCF7931() {
}
if (j != 1) {
memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16);
print_result("got single block", single_blocks[single_blocks_cnt], 16);
single_blocks_cnt++;
}
j = 0;
@ -220,7 +242,12 @@ void ReadPCF7931() {
continue;
}
Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors);
if ( DBGLEVEL >= DBG_EXTENDED )
Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors);
for (i = 0; i < n; ++i) {
print_result("got consecutive blocks", tmp_blocks[i], 16);
}
i = 0;
if (!found_0_1) {
@ -279,10 +306,12 @@ void ReadPCF7931() {
}
++tries;
if (BUTTON_PRESS()) {
Dbprintf("Button pressed, stopping.");
if ( DBGLEVEL >= DBG_EXTENDED)
Dbprintf("Button pressed, stopping.");
goto end;
}
} while (found_blocks != max_blocks);
} while (found_blocks < max_blocks);
end:
Dbprintf("-----------------------------------------");
@ -305,7 +334,7 @@ end:
Dbprintf("-----------------------------------------");
}
reply_old(CMD_ACK, 0, 0, 0, 0, 0);
reply_mix(CMD_ACK, 0, 0, 0, 0, 0);
}
static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) {
@ -391,8 +420,12 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3
@param data : data to write
*/
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) {
Dbprintf("Initialization delay : %d us", init_delay);
Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p);
if ( DBGLEVEL >= DBG_INFO ) {
Dbprintf("Initialization delay : %d us", init_delay);
Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p);
}
Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7);
Dbprintf("Block address : %02x", address);
Dbprintf("Byte address : %02x", byte);
@ -411,7 +444,9 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui
void SendCmdPCF7931(uint32_t *tab) {
uint16_t u = 0, tempo = 0;
Dbprintf("Sending data frame...");
if ( DBGLEVEL >= DBG_INFO ) {
Dbprintf("Sending data frame...");
}
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
@ -454,7 +489,6 @@ void SendCmdPCF7931(uint32_t *tab) {
SpinDelay(200);
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
LED(0xFFFF, 1000);
}
@ -468,13 +502,13 @@ bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p) {
uint32_t u;
for (u = 0; u < 8; ++u) {
if (byte & (1 << u)) { //bit is 1
if (AddBitPCF7931(1, tab, l, p) == 1) return 1;
if (AddBitPCF7931(1, tab, l, p) == 1) return true;
} else { //bit is 0
if (AddBitPCF7931(0, tab, l, p) == 1) return 1;
if (AddBitPCF7931(0, tab, l, p) == 1) return true;
}
}
return 0;
return false;
}
/* Add a bits for building the data frame of PCF7931 tags
@ -487,7 +521,7 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) {
uint8_t u = 0;
//we put the cursor at the last value of the array
for (u = 0; tab[u] != 0; u += 3) { }
for (u = 0; tab[u] != 0; u += 3) { };
if (b == 1) { //add a bit 1
if (u == 0)
@ -497,7 +531,7 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) {
tab[u + 1] = 6 * T0_PCF + tab[u] + l;
tab[u + 2] = 88 * T0_PCF + tab[u + 1] - l - p;
return 0;
return false;
} else { //add a bit 0
if (u == 0)
@ -507,9 +541,9 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p) {
tab[u + 1] = 6 * T0_PCF + tab[u] + l;
tab[u + 2] = 24 * T0_PCF + tab[u + 1] - l - p;
return 0;
return false;
}
return 1;
return true;
}
/* Add a custom pattern in the data frame
@ -526,5 +560,5 @@ bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t *tab) {
tab[u + 1] = b + tab[u];
tab[u + 2] = c + tab[u + 1];
return 0;
return true;
}

View file

@ -96,9 +96,9 @@ static s32_t rdv40_spiffs_llerase(u32_t addr, u32_t size) {
////////////////////////////////////////////////////////////////////////////////
////// SPIFFS LOW LEVEL OPERATIONS /////////////////////////////////////////////
static u8_t spiffs_work_buf[RDV40_SPIFFS_WORKBUF_SZ];
static u8_t spiffs_fds[RDV40_SPIFFS_FDBUF_SZ];
static u8_t spiffs_cache_buf[RDV40_SPIFFS_CACHE_SZ];
static u8_t spiffs_work_buf[RDV40_SPIFFS_WORKBUF_SZ] __attribute__((aligned));
static u8_t spiffs_fds[RDV40_SPIFFS_FDBUF_SZ] __attribute__((aligned));
static u8_t spiffs_cache_buf[RDV40_SPIFFS_CACHE_SZ] __attribute__((aligned));
static spiffs fs;

View file

@ -185,6 +185,13 @@ uint32_t RAMFUNC GetCountSspClk(void) {
return tmp_count;
}
uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start) {
uint32_t stop = GetCountSspClk();
if ( stop >= start )
return stop - start;
return (UINT32_MAX - start) + stop;
}
// -------------------------------------------------------------------------
// Timer for bitbanging, or LF stuff when you need a very precis timer
// 1us = 1.5ticks

View file

@ -33,6 +33,7 @@ void SpinDelayCountUs(uint32_t us);
void StartCountSspClk();
void ResetSspClk(void);
uint32_t RAMFUNC GetCountSspClk();
uint32_t RAMFUNC GetCountSspClkDelta();
void StartTicks(void);
uint32_t GetTicks(void);

View file

@ -90,6 +90,7 @@ void LEDsoff() {
LED_D_OFF();
}
//ICEMAN: LED went from 1,2,3,4 -> 1,2,4,8
void LED(int led, int ms) {
if (led & LED_A) // Proxmark3 historical mapping: LED_ORANGE
LED_A_ON();
@ -123,26 +124,27 @@ void SpinOff(uint32_t pause) {
SpinDelay(pause);
}
// 0=A, 1=B, 2=C, 3=D
// Blinks..
// A = 1, B = 2, C = 4, D = 8
void SpinErr(uint8_t led, uint32_t speed, uint8_t times) {
SpinOff(speed);
NTIME(times) {
switch (led) {
case 0:
LED_A_INV();
break;
case 1:
LED_B_INV();
break;
case 2:
LED_C_INV();
break;
case 3:
LED_D_INV();
break;
}
if (led & LED_A) // Proxmark3 historical mapping: LED_ORANGE
LED_A_INV();
if (led & LED_B) // Proxmark3 historical mapping: LED_GREEN
LED_B_INV();
if (led & LED_C) // Proxmark3 historical mapping: LED_RED
LED_C_INV();
if (led & LED_D) // Proxmark3 historical mapping: LED_RED2
LED_D_INV();
SpinDelay(speed);
}
LED_A_OFF();
LED_B_OFF();
LED_C_OFF();
LED_D_OFF();
}
void SpinDown(uint32_t speed) {

View file

@ -31,12 +31,14 @@ APP_CFLAGS += -fno-stack-protector -fno-pie
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
include ../common_arm/Makefile.common
INSTALLFW = $(OBJDIR)/bootrom.elf
OBJS = $(OBJDIR)/bootrom.s19
# version.c should be remade on every compilation
version.c: default_version.c
$(info [=] GEN $@)
$(Q)perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@
$(Q)sh ../tools/mkversion.sh > $@ || perl ../tools/mkversion.pl > $@ || $(CP) $^ $@
all: $(OBJS)
@ -49,14 +51,23 @@ $(OBJDIR)/bootrom.elf: $(VERSIONOBJ) $(ASMOBJ) $(ARMOBJ) $(THUMBOBJ)
$(Q)$(CC) $(LDFLAGS) -Wl,-T,ldscript-flash,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
clean:
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.o
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.elf
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.s19
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.map
$(Q)$(DELETE) $(OBJDIR)$(PATHSEP)*.d
$(Q)$(DELETE) version.c
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.o
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.elf
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.s19
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.map
$(Q)$(RM) $(OBJDIR)$(PATHSEP)*.d
$(Q)$(RM) version.c
.PHONY: all clean help
install: all
$(info [@] Installing bootrom to $(DESTDIR)$(PREFIX)...)
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
$(Q)$(CP) $(INSTALLFW) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)
uninstall:
$(info [@] Uninstalling bootrom from $(DESTDIR)$(PREFIX)...)
$(Q)$(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw)))
.PHONY: all clean help install
help:
@echo Multi-OS Makefile, you are running on $(DETECTED_OS)
@echo Possible targets:

View file

@ -9,35 +9,20 @@
# Add -DNOFORCE to disable the -F switch
# Add -DPRESETS to compile with preset models (edit config.h)
# Hide full compilation line:
ifneq ($(V),1)
Q?=@
endif
# To see full command lines, use make V=1
# Must be called before any Makefile include
ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
CC = gcc
CXX = g++
LD = g++
TAR = tar
TARFLAGS = -C .. --ignore-failed-read -rvf
RM = rm -f
MV = mv
TOUCH = touch
FALSE = false
include ../Makefile.defs
ENV_LDFLAGS := $(LDFLAGS)
ENV_CFLAGS := $(CFLAGS)
INSTALLBIN = proxmark3
INSTALLSHARE = cmdscripts lualibs luascripts resources dictionaries
platform = $(shell uname)
VPATH = ../common ../common/zlib uart
VPATH = ../common uart
vpath %.dic dictionaries
OBJDIR = obj
LDLIBS =
ifneq ($(platform),Darwin)
LDLIBS += -L/opt/local/lib
endif
LDLIBS += -L/usr/local/lib -lreadline -lpthread -lm
LDLIBS ?= -L/usr/local/lib
LDLIBS += -lreadline -lpthread -lm
# RPi Zero gcc requires -latomic
# but MacOSX /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
@ -46,23 +31,35 @@ ifneq ($(platform),Darwin)
LDLIBS += -Wl,--as-needed -latomic -Wl,--no-as-needed
endif
# local libraries
LUALIBPATH = ./liblua
LUALIB = $(LUALIBPATH)/liblua.a
JANSSONLIBPATH = ./jansson
JANSSONLIB = $(JANSSONLIBPATH)/libjansson.a
MBEDTLSLIBPATH = ../common/mbedtls
MBEDTLSLIB = $(MBEDTLSLIBPATH)/libmbedtls.a
CBORLIBPATH = ./tinycbor
CBORLIB = $(CBORLIBPATH)/tinycbor.a
REVENGFLAGS = -DPRESETS
LIBS = -I../common/zlib -Iuart -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH)
INCLUDES_CLIENT = -I. -I../include -I../common -I/opt/local/include $(LIBS)
LDFLAGS = $(ENV_LDFLAGS)
CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE $(REVENGFLAGS) $(INCLUDES_CLIENT) -Wall -Werror -g -O3
REVENGPATH = ./reveng
REVENGLIB = $(REVENGPATH)/libreveng.a
AMIIBOLIBPATH = ./amiitool
AMIIBOLIB = $(AMIIBOLIBPATH)/libamiibo.a
# common libraries
MBEDTLSLIBPATH = ../common/mbedtls
MBEDTLSLIB = $(OBJDIR)/libmbedtls.a
ZLIBPATH = ../common/zlib
ZLIB = $(OBJDIR)/libz.a
LIBS = -I$(LUALIBPATH) -I$(MBEDTLSLIBPATH) -I$(JANSSONLIBPATH) -I$(CBORLIBPATH) -I$(ZLIBPATH) -I$(REVENGPATH) -I$(AMIIBOLIBPATH)
INCLUDES_CLIENT = -I. -I../include -I../common -Iuart $(LIBS)
CFLAGS ?= -Wall -Werror -g -O3
# We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env:
PM3CFLAGS = $(CFLAGS) -std=c99 -D_ISOC99_SOURCE $(INCLUDES_CLIENT)
PREFIX ?= /usr/local
ifneq (,$(findstring MINGW,$(platform)))
CFLAGS += -mno-ms-bitfields
PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850
endif
CXXFLAGS = -I../include -Wall -O3
CXXFLAGS ?= -Wall -Werror -O3
PM3CXXFLAGS = $(CXXFLAGS) -I../include
LUAPLATFORM = generic
ifneq (,$(findstring MINGW,$(platform)))
@ -76,7 +73,6 @@ else
LIBS := -I/usr/local/opt/readline/include $(LIBS)
else
LUALIB += -ldl
LDLIBS += -ltermcap -lncurses
LUAPLATFORM = linux
endif
endif
@ -93,7 +89,7 @@ ifeq ($(QTINCLUDES), )
MOC = $(shell pkg-config --variable=moc_location QtCore)
UIC = $(shell pkg-config --variable=uic_location QtCore)
else
CXXFLAGS += -std=c++11 -fPIC
PM3CXXFLAGS += -std=c++11 -fPIC
endif
ifeq ($(QTINCLUDES), )
# if both pkg-config commands failed, search in common places
@ -103,7 +99,7 @@ ifeq ($(QTINCLUDES), )
ifneq ($(wildcard $(QTDIR)/include/QtWidgets),)
QTINCLUDES += -I$(QTDIR)/include/QtWidgets
QTLDLIBS = -L$(QTDIR)/lib -lQt5Widgets -lQt5Gui -lQt5Core
CXXFLAGS += -std=c++11 -fPIC
PM3CXXFLAGS += -std=c++11 -fPIC
endif
MOC = $(QTDIR)/bin/moc
UIC = $(QTDIR)/bin/uic
@ -113,7 +109,7 @@ endif
ifneq ($(QTLDLIBS),)
QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o
CFLAGS += -DHAVE_GUI
PM3CFLAGS += -DHAVE_GUI
else
QTGUIOBJS = $(OBJDIR)/guidummy.o
endif
@ -121,7 +117,7 @@ endif
# Flags to generate temporary dependency files
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
# make temporary to final dependency files after successful compilation
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@
CORESRCS = uart_posix.c \
uart_win32.c \
@ -150,7 +146,7 @@ CMDSRCS = crapto1/crapto1.c \
loclass/cipherutils.c \
loclass/ikeys.c \
loclass/elite_crack.c \
loclass/fileutils.c \
fileutils.c \
whereami.c \
mifare/mifarehost.c \
parity.c \
@ -241,7 +237,8 @@ CMDSRCS = crapto1/crapto1.c \
cmdscript.c \
pm3_bitlib.c \
cmdcrc.c \
bucketsort.c
bucketsort.c \
flash.c
cpu_arch = $(shell uname -m)
ifneq ($(findstring 86, $(cpu_arch)), )
@ -254,24 +251,11 @@ ifeq ($(MULTIARCHSRCS), )
CMDSRCS += hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c
endif
ZLIBSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c
ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
#-DDEBUG -Dverbose=1
REVENGSRCS = reveng/preset.c \
reveng/reveng.c \
reveng/cli.c \
reveng/bmpbit.c \
reveng/model.c \
reveng/poly.c
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
OBJCOBJS = $(OBJCSRCS:%.m=$(OBJDIR)/%.o)
ZLIBOBJS = $(ZLIBSRCS:%.c=$(OBJDIR)/%.o)
REVENGOBJS = $(REVENGSRCS:%.c=$(OBJDIR)/%.o)
MULTIARCHOBJS = $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_NOSIMD.o) \
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_MMX.o) \
$(MULTIARCHSRCS:%.c=$(OBJDIR)/%_SSE2.o) \
@ -295,23 +279,21 @@ ifeq "$(SUPPORTS_AVX512)" "True"
MULTIARCHOBJS += $(MULTIARCHSRCS:%.c=$(OBJDIR)/%_AVX512.o)
endif
BINS = proxmark3 flasher
CLEAN = $(BINS) $(DEPENDENCY_FILES) $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(ZLIBOBJS) $(REVENGOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(OBJDIR)/*.o *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua reveng/bmptst
BINS = proxmark3
CLEAN = $(BINS) *.moc.cpp ui/ui_overlays.h lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
# transition: make sure old flasher is gone too
CLEAN += flasher
# need to assign dependancies to build these first...
all: lua_build jansson_build mbedtls_build cbor_build $(BINS)
all: $(BINS)
all-static: LDLIBS:=-static $(LDLIBS)
all-static: $(BINS)
proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(QTLDLIBS)
proxmark3: reveng/bmptst $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(REVENGOBJS) lualibs/pm3_cmd.lua lualibs/mf_default_keys.lua
proxmark3: LDLIBS+=$(LUALIB) $(JANSSONLIB) $(MBEDTLSLIB) $(CBORLIB) $(ZLIB) $(REVENGLIB) $(AMIIBOLIB) $(QTLDLIBS)
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LUALIB) $(JANSSONLIB) $(CBORLIB) $(REVENGLIB) $(MBEDTLSLIB) $(ZLIB) $(AMIIBOLIB) lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua
$(info [=] LD $@)
$(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(REVENGOBJS) $(LDLIBS) -o $@
flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS) $(OBJCOBJS)
$(info [=] LD $@)
$(Q)$(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@
$(Q)$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(OBJCOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LDLIBS) -o $@
proxgui.cpp: ui/ui_overlays.h
@ -327,115 +309,144 @@ lualibs/pm3_cmd.lua: ../include/pm3_cmd.h
$(info [=] GEN $@)
$(Q)awk -f pm3_cmd_h2lua.awk $^ > $@
lualibs/mf_default_keys.lua : default_keys.dic
lualibs/mfc_default_keys.lua : mfc_default_keys.dic
$(info [=] GEN $@)
$(Q)awk -f default_keys_dic2lua.awk $^ > $@
clean:
$(Q)$(RM) $(CLEAN)
$(Q)$(RMDIR) $(OBJDIR)
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) clean
$(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) clean
install: all
$(info [@] Installing client to $(DESTDIR)$(PREFIX)...)
ifneq (,$(INSTALLBIN))
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)
$(Q)$(CP) $(INSTALLBIN) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)
endif
ifneq (,$(INSTALLSHARE))
$(Q)$(MKDIR) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
$(Q)$(CP) $(INSTALLSHARE) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)
endif
@true
uninstall:
$(info [@] Uninstalling client from $(DESTDIR)$(PREFIX)...)
ifneq (,$(INSTALLBIN))
$(Q)$(RM) $(foreach tool,$(INSTALLBIN),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)$(PATHSEP)$(notdir $(tool)))
endif
ifneq (,$(INSTALLSHARE))
$(Q)$(RMDIR) $(foreach tool,$(INSTALLSHARE),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)$(PATHSEP)$(notdir $(tool)))
endif
@true
tarbin: $(BINS)
$(info [=] TAR ../proxmark3-$(platform)-bin.tar)
$(Q)$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%)
lua_build:
# local libraries:
$(LUALIB):
$(info [*] MAKE liblua for $(LUAPLATFORM))
$(Q)$(MAKE) --no-print-directory -C $(LUALIBPATH) $(LUAPLATFORM)
jansson_build:
$(JANSSONLIB):
$(info [*] MAKE jansson)
$(Q)$(MAKE) --no-print-directory -C $(JANSSONLIBPATH) all
mbedtls_build:
$(info [*] MAKE mbedtls)
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) all
cbor_build:
$(CBORLIB):
$(info [*] MAKE tinycbor)
$(Q)$(MAKE) --no-print-directory -C $(CBORLIBPATH) all
$(REVENGLIB):
$(info [*] MAKE reveng)
$(Q)$(MAKE) --no-print-directory -C $(REVENGPATH) all
reveng/bmptst: reveng/bmpbit.c reveng/config.h reveng/reveng.h
$(CC) $(CFLAGS) $(REVENGFLAGS) -DBMPTST -o $@ $<
( ./$@ && $(TOUCH) $@ ) || ( $(RM) $@ && $(FALSE) )
$(AMIIBOLIB):
$(info [*] MAKE amiibo)
$(Q)$(MAKE) --no-print-directory -C $(AMIIBOLIBPATH) all
.PHONY: all clean
# common libraries:
$(MBEDTLSLIB):
$(info [*] MAKE mbedtls)
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all
$(ZLIB):
$(info [*] MAKE zlib)
$(Q)$(MAKE) --no-print-directory -C $(ZLIBPATH) OBJDIR=$(ROOT_DIR)$(OBJDIR) BINDIR=$(ROOT_DIR)$(OBJDIR) all
.PHONY: all clean install uninstall
# easy printing of MAKE VARIABLES
print-%: ; @echo $* = $($*)
$(OBJDIR)/%_NOSIMD.o : %.c $(OBJDIR)/%_NOSIMD.d
$(info [-] CC(NOSIMD) $<)
$(Q)$(CC) $(DEPFLAGS:%.Td=%_NOSIMD.Td) $(CFLAGS) $(HARD_SWITCH_NOSIMD) -c -o $@ $<
$(Q)$(MV) -f $(OBJDIR)/$*_NOSIMD.Td $(OBJDIR)/$*_NOSIMD.d
$(Q)$(MKDIR) $(dir $@)
$(Q)$(CC) $(DEPFLAGS:%.Td=%_NOSIMD.Td) $(PM3CFLAGS) $(HARD_SWITCH_NOSIMD) -c -o $@ $<
$(Q)$(MV) -f $(OBJDIR)/$*_NOSIMD.Td $(OBJDIR)/$*_NOSIMD.d && $(TOUCH) $@
$(OBJDIR)/%_MMX.o : %.c $(OBJDIR)/%_MMX.d
$(info [-] CC(MMX) $<)
$(Q)$(CC) $(DEPFLAGS:%.Td=%_MMX.Td) $(CFLAGS) $(HARD_SWITCH_MMX) -c -o $@ $<
$(Q)$(MV) -f $(OBJDIR)/$*_MMX.Td $(OBJDIR)/$*_MMX.d
$(Q)$(MKDIR) $(dir $@)
$(Q)$(CC) $(DEPFLAGS:%.Td=%_MMX.Td) $(PM3CFLAGS) $(HARD_SWITCH_MMX) -c -o $@ $<
$(Q)$(MV) -f $(OBJDIR)/$*_MMX.Td $(OBJDIR)/$*_MMX.d && $(TOUCH) $@
$(OBJDIR)/%_SSE2.o : %.c $(OBJDIR)/%_SSE2.d
$(info [-] CC(SSE2) $<)
$(Q)$(CC) $(DEPFLAGS:%.Td=%_SSE2.Td) $(CFLAGS) $(HARD_SWITCH_SSE2) -c -o $@ $<
$(Q)$(MV) -f $(OBJDIR)/$*_SSE2.Td $(OBJDIR)/$*_SSE2.d
$(Q)$(MKDIR) $(dir $@)
$(Q)$(CC) $(DEPFLAGS:%.Td=%_SSE2.Td) $(PM3CFLAGS) $(HARD_SWITCH_SSE2) -c -o $@ $<
$(Q)$(MV) -f $(OBJDIR)/$*_SSE2.Td $(OBJDIR)/$*_SSE2.d && $(TOUCH) $@
$(OBJDIR)/%_AVX.o : %.c $(OBJDIR)/%_AVX.d
$(info [-] CC(AVX) $<)
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX.Td) $(CFLAGS) $(HARD_SWITCH_AVX) -c -o $@ $<
$(Q)$(MV) -f $(OBJDIR)/$*_AVX.Td $(OBJDIR)/$*_AVX.d
$(Q)$(MKDIR) $(dir $@)
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX) -c -o $@ $<
$(Q)$(MV) -f $(OBJDIR)/$*_AVX.Td $(OBJDIR)/$*_AVX.d && $(TOUCH) $@
$(OBJDIR)/%_AVX2.o : %.c $(OBJDIR)/%_AVX2.d
$(info [-] CC(AVX2) $<)
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX2.Td) $(CFLAGS) $(HARD_SWITCH_AVX2) -c -o $@ $<
$(Q)$(MV) -f $(OBJDIR)/$*_AVX2.Td $(OBJDIR)/$*_AVX2.d
$(Q)$(MKDIR) $(dir $@)
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX2.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX2) -c -o $@ $<
$(Q)$(MV) -f $(OBJDIR)/$*_AVX2.Td $(OBJDIR)/$*_AVX2.d && $(TOUCH) $@
$(OBJDIR)/%_AVX512.o : %.c $(OBJDIR)/%_AVX512.d
$(info [-] CC(AVX512) $<)
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX512.Td) $(CFLAGS) $(HARD_SWITCH_AVX512) -c -o $@ $<
$(Q)$(MV) -f $(OBJDIR)/$*_AVX512.Td $(OBJDIR)/$*_AVX512.d
$(Q)$(MKDIR) $(dir $@)
$(Q)$(CC) $(DEPFLAGS:%.Td=%_AVX512.Td) $(PM3CFLAGS) $(HARD_SWITCH_AVX512) -c -o $@ $<
$(Q)$(MV) -f $(OBJDIR)/$*_AVX512.Td $(OBJDIR)/$*_AVX512.d && $(TOUCH) $@
%.o: %.c
$(OBJDIR)/%.o : %.c $(OBJDIR)/%.d
$(info [-] CC $<)
$(Q)$(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $<
$(Q)$(MKDIR) $(dir $@)
$(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $<
$(Q)$(POSTCOMPILE)
%.o: %.cpp
$(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d
$(info [-] CXX $<)
$(Q)$(CXX) $(DEPFLAGS) $(CXXFLAGS) $(QTINCLUDES) -c -o $@ $<
$(Q)$(MKDIR) $(dir $@)
$(Q)$(CXX) $(DEPFLAGS) $(PM3CXXFLAGS) $(QTINCLUDES) -c -o $@ $<
$(Q)$(POSTCOMPILE)
%.o: %.m
$(OBJDIR)/%.o : %.m $(OBJDIR)/%.d
$(info [-] CC $<)
$(Q)$(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $<
$(Q)$(MKDIR) $(dir $@)
$(Q)$(CC) $(DEPFLAGS) $(PM3CFLAGS) -c -o $@ $<
$(Q)$(POSTCOMPILE)
#$(CMDOBJS) $(COREOBJS): $(notdir $(%.c)) %.d
# $(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $<
# $(POSTCOMPILE)
#$(ZLIBOBJS): $(notdir $(%.c)) %.d
# $(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $<
# $(POSTCOMPILE)
#$(QTGUIOBJS): $(notdir $(%.cpp)) %.d
# $(CXX) $(DEPFLAGS) $(CXXFLAGS) -c -o $@ $<
# $(POSTCOMPILE)
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(ZLIBSRCS) $(REVENGSRCS)) \
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(REVENGSRCS)) \
$(patsubst %.o, %.d, $(MULTIARCHOBJS)) \
$(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \
$(patsubst %.m, $(OBJDIR)/%.d, $(OBJCSRCS)) \
$(OBJDIR)/proxmark3.d $(OBJDIR)/flash.d $(OBJDIR)/flasher.d
$(OBJDIR)/proxmark3.d
$(DEPENDENCY_FILES): ;
.PRECIOUS: $(DEPENDENCY_FILES)
-include $(DEPENDENCY_FILES)

19
client/amiitool/Makefile Normal file
View file

@ -0,0 +1,19 @@
MYSRCPATHS =
MYINCLUDES = -I. -I.. -I../jansson -I../../common/ -I../../include/
MYCFLAGS = -std=c99 -D_ISOC99_SOURCE
MYDEFS =
MYSRCS = \
amiibo.c \
drbg.c \
keygen.c
LIB_A = libamiibo.a
include ../../Makefile.host
# just for testing amiitool before complete migration into a lib:
amiitool:
gcc $(CFLAGS) \
amiitool.c $(MYSRCS) ../../common/commonutil.c ../ui.c -lreadline -lm ../../common/mbedtls/libmbedtls.a \
-o amiitool

View file

@ -8,6 +8,7 @@
#include "amiibo.h"
#include "mbedtls/md.h"
#include "mbedtls/aes.h"
#include "commonutil.h"
#define HMAC_POS_DATA 0x008
#define HMAC_POS_TAG 0x1B4

View file

@ -13,7 +13,6 @@
#include <string.h>
#include <stdio.h>
#include "keygen.h"
#include "util.h"
#define NFC3D_AMIIBO_SIZE 520

View file

@ -5,10 +5,11 @@
* SPDX-License-Identifier: MIT
*/
#include <amiibo.h>
#include <stdio.h>
#include <string.h>
#include "../loclass/fileutils.h"
#include "fileutils.h"
#include "amiibo.h"
#include "getopt.h"
#define NTAG215_SIZE 540
@ -16,7 +17,7 @@ static char *self;
void amiitool_usage() {
fprintf(stderr,
"amiitool build %i (commit %s-%08x)\n"
/*"amiitool build %i (commit %s-%08x)\n"*/
"by Marcos Del Sol Vives <marcos@dracon.es>\n"
"\n"
"Usage: %s (-e|-d|-c) -k keyfile [-i input] [-s input2] [-o output]\n"
@ -28,7 +29,7 @@ void amiitool_usage() {
" -s input save file, save from this file will replace input file ones.\n"
" -o output file. If not specified, stdout will be used.\n"
" -l decrypt files with invalid signatures.\n",
, self
self
);
}
@ -62,6 +63,9 @@ int main(int argc, char **argv) {
case 'i':
infile = optarg;
break;
case 'k':
keyfile = optarg;
break;
case 's':
savefile = optarg;
break;
@ -83,7 +87,8 @@ int main(int argc, char **argv) {
}
nfc3d_amiibo_keys amiiboKeys;
if (! LoadAmiikey(amiiboKeys, keyfile))
return 5;
uint8_t original[NTAG215_SIZE];
uint8_t modified[NFC3D_AMIIBO_SIZE];

View file

@ -8,7 +8,7 @@
#include "drbg.h"
#include <assert.h>
#include <string.h>
#include <mbedtls/md.h>
#include "mbedtls/md.h"
void nfc3d_drbg_init(nfc3d_drbg_ctx *ctx, const uint8_t *hmacKey, size_t hmacKeySize, const uint8_t *seed, size_t seedSize) {
assert(ctx != NULL);

View file

@ -19,7 +19,7 @@ void nfc3d_keygen_prepare_seed(const nfc3d_keygen_masterkeys *baseKeys, const ui
uint8_t *start = output;
// 1: Copy whole type string
output = memccpy(output, baseKeys->typeString, '\0', sizeof(baseKeys->typeString));
output = (uint8_t *)strcpy((char *)output, baseKeys->typeString);
// 2: Append (16 - magicBytesSize) from the input seed
size_t leadingSeedBytes = 16 - baseKeys->magicBytesSize;

View file

@ -23,6 +23,7 @@
#include "lfdemod.h" // for demod code
#include "loclass/cipherutils.h" // for decimating samples in getsamples
#include "cmdlfem4x.h" // askem410xdecode
#include "fileutils.h" // searchFile
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
size_t DemodBufferLen = 0;
@ -38,6 +39,7 @@ static int usage_data_printdemodbuf(void) {
PrintAndLogEx(NORMAL, " x output in hex (omit for binary output)");
PrintAndLogEx(NORMAL, " o <offset> enter offset in # of bits");
PrintAndLogEx(NORMAL, " l <length> enter length to print in # of bits or hex characters respectively");
PrintAndLogEx(NORMAL, " s strip leading zeroes, i.e. set offset to first bit equal to one");
return PM3_SUCCESS;
}
static int usage_data_manrawdecode(void) {
@ -401,6 +403,7 @@ void printDemodBuff(void) {
int CmdPrintDemodBuff(const char *Cmd) {
bool hexMode = false;
bool errors = false;
bool lstrip = false;
uint32_t offset = 0;
uint32_t length = 512;
char cmdp = 0;
@ -422,6 +425,10 @@ int CmdPrintDemodBuff(const char *Cmd) {
if (!length) errors = true;
cmdp += 2;
break;
case 's':
lstrip = true;
cmdp ++;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
@ -435,6 +442,15 @@ int CmdPrintDemodBuff(const char *Cmd) {
PrintAndLogEx(NORMAL, "Demodbuffer is empty");
return PM3_ESOFT;
}
if (lstrip) {
char *buf = (char *)(DemodBuffer + offset);
length = (length > (DemodBufferLen - offset)) ? DemodBufferLen - offset : length;
uint32_t i;
for (i = 0; i < length; i++) {
if (buf[i] == 1) break;
}
offset += i;
}
length = (length > (DemodBufferLen - offset)) ? DemodBufferLen - offset : length;
if (hexMode) {
@ -1646,11 +1662,20 @@ static int CmdLoad(const char *Cmd) {
if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
memcpy(filename, Cmd, len);
FILE *f = fopen(filename, "r");
char *path;
if (searchFile(&path, TRACES_SUBDIR, filename, ".pm3", true) != PM3_SUCCESS) {
if (searchFile(&path, TRACES_SUBDIR, filename, "", false) != PM3_SUCCESS) {
return PM3_EFILE;
}
}
FILE *f = fopen(path, "r");
if (!f) {
PrintAndLogEx(WARNING, "couldn't open '%s'", filename);
PrintAndLogEx(WARNING, "couldn't open '%s'", path);
free(path);
return PM3_EFILE;
}
free(path);
GraphTraceLen = 0;
char line[80];

View file

@ -14,7 +14,7 @@
#include "cmdparser.h" // command_t
#include "pmflash.h"
#include "loclass/fileutils.h" //saveFile
#include "fileutils.h" //saveFile
#include "comms.h" //getfromdevice
#include "cmdflashmemspiffs.h" // spiffs commands
@ -59,9 +59,9 @@ static int usage_flashmem_load(void) {
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " mem load f myfile"); // upload file myfile at default offset 0
PrintAndLogEx(NORMAL, " mem load f myfile o 1024"); // upload file myfile at offset 1024
PrintAndLogEx(NORMAL, " mem load f default_keys m");
PrintAndLogEx(NORMAL, " mem load f default_pwd t");
PrintAndLogEx(NORMAL, " mem load f default_iclass_keys i");
PrintAndLogEx(NORMAL, " mem load f mfc_default_keys m");
PrintAndLogEx(NORMAL, " mem load f t55xx_default_pwds t");
PrintAndLogEx(NORMAL, " mem load f iclass_default_keys i");
return PM3_SUCCESS;
}
static int usage_flashmem_dump(void) {
@ -209,9 +209,8 @@ static int CmdFlashMemLoad(const char *Cmd) {
datalen += 2;
break;
case DICTIONARY_NONE:
res = loadFile(filename, ".bin", data, FLASH_MEM_MAX_SIZE, &datalen);
//int res = loadFileEML( filename, data, &datalen);
if (res) {
res = loadFile_safe(filename, ".bin", (void **)&data, &datalen);
if (res != PM3_SUCCESS) {
free(data);
return PM3_EFILE;
}
@ -223,7 +222,7 @@ static int CmdFlashMemLoad(const char *Cmd) {
}
break;
}
// not needed when we transite to loadxxxx_safe methods.(iceman)
uint8_t *newdata = realloc(data, datalen);
if (newdata == NULL) {
free(data);

View file

@ -13,7 +13,7 @@
#include "cmdparser.h" // command_t
#include "pmflash.h"
#include "loclass/fileutils.h" //saveFile
#include "fileutils.h" //saveFile
#include "comms.h" //getfromdevice
static int CmdHelp(const char *Cmd);
@ -330,12 +330,15 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) {
if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) {
PrintAndLogEx(FAILED, "Filename too long");
errors = true;
break;
}
cmdp += 2;
break;
case 'o':
param_getstr(Cmd, cmdp + 1, destfilename, 32);
if (strlen(destfilename) == 0) {
PrintAndLogEx(FAILED, "Destination Filename missing or invalid");
errors = true;
}
cmdp += 2;
break;
default:
@ -345,42 +348,20 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) {
}
}
if (destfilename[0] == '\0') {
PrintAndLogEx(FAILED, "Destination Filename missing or invalid");
errors = true;
}
// Validations
if (errors || cmdp == 0) {
usage_flashmemspiffs_load();
return PM3_EINVARG;
}
if (errors || cmdp == 0)
return usage_flashmemspiffs_load();
size_t datalen = 0;
int res = 0;
uint8_t *data = calloc(FLASH_MEM_MAX_SIZE, sizeof(uint8_t));
uint8_t *data = NULL;
res = loadFile(filename, "", data, FLASH_MEM_MAX_SIZE, &datalen);
int res = loadFile_safe(filename, "", (void **)&data, &datalen);
// int res = loadFileEML( filename, data, &datalen);
if (res) {
if (res != PM3_SUCCESS) {
free(data);
return PM3_EFILE;
}
if (datalen > FLASH_MEM_MAX_SIZE) {
PrintAndLogEx(ERR, "error, filesize is larger than available memory");
free(data);
return PM3_EOVFLOW;
}
uint8_t *newdata = realloc(data, datalen);
if (newdata == NULL) {
free(data);
return PM3_EMALLOC;
} else {
data = newdata;
}
// We want to mount before multiple operation so the lazy writes/append will not
// trigger a mount + umount each loop iteration (lazy ops device side)
SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0);
@ -425,6 +406,7 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) {
if (!isok) {
conn.block_after_ACK = false;
PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent);
free(data);
return PM3_EFLASH;
}
}

View file

@ -76,18 +76,23 @@ int CmdHFSearch(const char *Cmd) {
PrintAndLogEx(INFO, "Checking for known tags...\n");
PrintAndLogEx(INPLACE, "Searching for ThinFilm tag...");
if (IfPm3NfcBarcode()) {
if (infoThinFilm(false) == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Thinfilm tag") " found\n");
return PM3_SUCCESS;
}
}
PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag...");
if (IfPm3Iso14443a()) {
if (infoHF14A(false, false) > 0) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-A tag") " found\n");
return PM3_SUCCESS;
}
}
PrintAndLogEx(INPLACE, "Searching for ISO15693 tag...");
if (IfPm3Iso15693()) {
if (readHF15Uid(false) == 1) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO15693 tag") " found\n");
@ -97,25 +102,33 @@ int CmdHFSearch(const char *Cmd) {
// until refactoring of ISO15693 cmds, this is needed.
DropField();
}
PrintAndLogEx(INPLACE, "Searching for LEGIC tag...");
if (IfPm3Legicrf()) {
if (readLegicUid(false) == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LEGIC tag") " found\n");
return PM3_SUCCESS;
}
}
PrintAndLogEx(INPLACE, "Searching for Topaz tag...");
if (IfPm3Iso14443a()) {
if (readTopazUid() == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n");
return PM3_SUCCESS;
}
}
// 14b and iclass is the longest test (put last)
PrintAndLogEx(INPLACE, "Searching for ISO14443-B tag...");
if (IfPm3Iso14443a()) {
if (readHF14B(false) == 1) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("ISO14443-B tag") " found\n");
return PM3_SUCCESS;
}
}
PrintAndLogEx(INPLACE, "Searching for iClass / PicoPass tag...");
if (IfPm3Iclass()) {
if (readIclass(false, false) == 1) {
PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iClass tag / PicoPass tag") " found\n");
@ -133,7 +146,7 @@ int CmdHFSearch(const char *Cmd) {
//}
PrintAndLogEx(FAILED, "\nno known/supported 13.56 MHz tags found\n");
PrintAndLogEx(FAILED, "\nNo known/supported 13.56 MHz tags found\n");
return PM3_ESOFT;
}
@ -208,7 +221,7 @@ static command_t CommandTable[] = {
{"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"},
{"list", CmdTraceList, AlwaysAvailable, "List protocol data in trace buffer"},
{"tune", CmdHFTune, IfPm3Present, "Continuously measure HF antenna tuning"},
{"search", CmdHFSearch, AlwaysAvailable, "Search for known HF tags [preliminary]"},
{"search", CmdHFSearch, AlwaysAvailable, "Search for known HF tags"},
{"sniff", CmdHFSniff, IfPm3Hfsniff, "<samples to skip (10000)> <triggers to skip (1)> Generic HF Sniff"},
{NULL, NULL, NULL, NULL}
};

View file

@ -133,7 +133,7 @@ static const manufactureName manufactureMapping[] = {
{ 0x61, "Wearlinks Technology Inc. China" },
{ 0x62, "Userstar Information Systems Co., Ltd Taiwan" },
{ 0x63, "Pragmatic Printing Ltd. UK" },
{ 0x64, "Associacao do Laboratorio de Sistemas Integraveis Tecnologico LSI-TEC Brazil" },
{ 0x64, "Associacao do Laboratorio de Sistemas Integraveis Tecnologico - LSI-TEC Brazil" },
{ 0x65, "Tendyron Corporation China" },
{ 0x66, "MUTO Smart Co., Ltd. Korea" },
{ 0x67, "ON Semiconductor USA" },

View file

@ -12,7 +12,7 @@
#include "cmdhf14b.h"
#include <ctype.h>
#include "loclass/fileutils.h"
#include "fileutils.h"
#include "cmdparser.h" // command_t
#include "comms.h" // clearCommandBuffer

View file

@ -35,7 +35,7 @@
#include "graph.h"
#include "crc16.h" // iso15 crc
#include "cmddata.h" // getsamples
#include "loclass/fileutils.h" // savefileEML
#include "fileutils.h" // savefileEML
#define FrameSOF Iso15693FrameSOF
#define Logic0 Iso15693Logic0

View file

@ -44,7 +44,7 @@ static int CmdHelp(const char *Cmd);
static int CmdHFFidoInfo(const char *cmd) {
if (cmd && strlen(cmd) > 0)
PrintAndLogEx(WARNING, "WARNING: command don't have any parameters.\n");
PrintAndLogEx(WARNING, "WARNING: command doesn't have any parameters.\n");
// info about 14a part
infoHF14A(false, false);
@ -75,14 +75,14 @@ static int CmdHFFidoInfo(const char *cmd) {
if (!strncmp((char *)buf, "U2F_V2", 7)) {
if (!strncmp((char *)buf, "FIDO_2_0", 8)) {
PrintAndLogEx(INFO, "FIDO2 authenricator detected. Version: %.*s", len, buf);
PrintAndLogEx(INFO, "FIDO2 authenticator detected. Version: %.*s", len, buf);
} else {
PrintAndLogEx(INFO, "FIDO authenricator detected (not standard U2F).");
PrintAndLogEx(INFO, "FIDO authenticator detected (not standard U2F).");
PrintAndLogEx(INFO, "Non U2F authenticator version:");
dump_buffer((const unsigned char *)buf, len, NULL, 0);
}
} else {
PrintAndLogEx(INFO, "FIDO U2F authenricator detected. Version: %.*s", len, buf);
PrintAndLogEx(INFO, "FIDO U2F authenticator detected. Version: %.*s", len, buf);
}
res = FIDO2GetInfo(buf, sizeof(buf), &len, &sw);
@ -91,13 +91,13 @@ static int CmdHFFidoInfo(const char *cmd) {
return res;
}
if (sw != 0x9000) {
PrintAndLogEx(ERR, "FIDO2 version not exists (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
PrintAndLogEx(ERR, "FIDO2 version doesn't exist (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
return 0;
}
if (buf[0]) {
PrintAndLogEx(ERR, "FIDO2 ger version error: %d - %s", buf[0], fido2GetCmdErrorDescription(buf[0]));
PrintAndLogEx(ERR, "FIDO2 get version error: %d - %s", buf[0], fido2GetCmdErrorDescription(buf[0]));
return 0;
}
@ -163,14 +163,14 @@ static int CmdHFFidoRegister(const char *cmd) {
json_t *root = NULL;
CLIParserInit("hf fido reg",
"Initiate a U2F token registration. Needs two 32-byte hash number. \nchallenge parameter (32b) and application parameter (32b).",
"Initiate a U2F token registration. Needs two 32-byte hash numbers. \nchallenge parameter (32b) and application parameter (32b).",
"Usage:\n\thf fido reg -> execute command with 2 parameters, filled 0x00\n"
"\thf fido reg 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters"
"\thf fido reg -p s0 s1 -> execute command with plain parameters");
void *argtable[] = {
arg_param_begin,
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("aA", "apdu", "show APDU requests and responses"),
arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
arg_lit0("pP", "plain", "send plain ASCII to challenge and application parameters instead of HEX"),
arg_lit0("tT", "tlv", "Show DER certificate contents in TLV representation"),
@ -393,7 +393,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
json_t *root = NULL;
CLIParserInit("hf fido auth",
"Initiate a U2F token authentication. Needs key handle and two 32-byte hash number. \nkey handle(var 0..255), challenge parameter (32b) and application parameter (32b).",
"Initiate a U2F token authentication. Needs key handle and two 32-byte hash numbers. \nkey handle(var 0..255), challenge parameter (32b) and application parameter (32b).",
"Usage:\n\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with 2 parameters, filled 0x00 and key handle\n"
"\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f "
"000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters");
@ -640,8 +640,8 @@ static int CmdHFFido2MakeCredential(const char *cmd) {
char fname[300] = {0};
CLIParserInit("hf fido make",
"Execute a FIDO2 Make Credentional command. Needs json file with parameters. Sample file `fido2.json`. File can be placed in proxmark directory or in `proxmark/fido` directory.",
"Usage:\n\thf fido make -> execute command default parameters file `fido2.json`\n"
"Execute a FIDO2 Make Credential command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.",
"Usage:\n\thf fido make -> execute command with default parameters file `fido2.json`\n"
"\thf fido make test.json -> execute command with parameters file `text.json`");
void *argtable[] = {
@ -713,7 +713,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) {
return res;
if (showCBOR) {
PrintAndLogEx(INFO, "CBOR make credentional request:");
PrintAndLogEx(INFO, "CBOR make credential request:");
PrintAndLogEx(NORMAL, "---------------- CBOR ------------------");
TinyCborPrintFIDOPackage(fido2CmdMakeCredential, false, data, datalen);
PrintAndLogEx(NORMAL, "---------------- CBOR ------------------");
@ -738,7 +738,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) {
PrintAndLogEx(SUCCESS, "MakeCredential result (%d b) OK.", len);
if (showCBOR) {
PrintAndLogEx(SUCCESS, "CBOR make credentional response:");
PrintAndLogEx(SUCCESS, "CBOR make credential response:");
PrintAndLogEx(NORMAL, "---------------- CBOR ------------------");
TinyCborPrintFIDOPackage(fido2CmdMakeCredential, true, &buf[1], len - 1);
PrintAndLogEx(NORMAL, "---------------- CBOR ------------------");
@ -766,8 +766,8 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
char fname[300] = {0};
CLIParserInit("hf fido assert",
"Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") ". File can be placed in proxmark directory or in `proxmark/fido` directory.",
"Usage:\n\thf fido assert -> execute command default parameters file `fido2.json`\n"
"Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.",
"Usage:\n\thf fido assert -> execute command with default parameters file `fido2.json`\n"
"\thf fido assert test.json -l -> execute command with parameters file `text.json` and add to request CredentialId");
void *argtable[] = {
@ -775,7 +775,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
arg_lit0("cC", "cbor", "show CBOR decoded data"),
arg_lit0("lL", "list", "add CredentialId from json to allowList. Needs if `rk` option is `false` (authenticator don't store credential to its memory)"),
arg_lit0("lL", "list", "add CredentialId from json to allowList. Needs if `rk` option is `false` (authenticator doesn't store credential to its memory)"),
arg_str0(NULL, NULL, "<json file name>", "JSON input / output file name for parameters. Default `fido2.json`"),
arg_param_end
};
@ -801,7 +801,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
SetAPDULogging(APDULogging);
int res = GetExistsFileNameJson("fido", "fido2", fname);
int res = GetExistsFileNameJson("fido", cjsonname, fname);
if (res) {
PrintAndLogEx(ERR, "ERROR: Can't found the json file.");
return res;

File diff suppressed because it is too large Load diff

View file

@ -12,6 +12,7 @@
#define CMDHFICLASS_H__
#include "common.h"
#include "fileutils.h"
typedef struct iclass_block {
uint8_t d[8];
@ -32,9 +33,8 @@ int readIclass(bool loop, bool verbose);
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize);
void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite);
int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt);
int GenerateMacFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list);
int GenerateFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list);
void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list);
void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list);
void PrintPreCalcMac(uint8_t *keys, int keycnt, iclass_premac_t *pre_list);
void PrintPreCalc(iclass_prekey_t *list, int itemcnt);
#endif

View file

@ -17,7 +17,7 @@
#include "cmdtrace.h"
#include "crc.h"
#include "crc16.h"
#include "loclass/fileutils.h" //saveFile
#include "fileutils.h" //saveFile
static int CmdHelp(const char *Cmd);

View file

@ -323,10 +323,31 @@ void annotateIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
}
void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
switch (cmd[0]) {
uint8_t c = cmd[0] & 0x0F;
uint8_t parity = 0;
for ( uint8_t i=0; i<7; i++) {
parity ^= (cmd[0] >> i) & 1;
}
switch (c) {
case ICLASS_CMD_HALT:
snprintf(exp, size, "HALT");
break;
case ICLASS_CMD_SELECT:
snprintf(exp, size, "SELECT");
break;
case ICLASS_CMD_ACTALL:
snprintf(exp, size, "ACTALL");
break;
case ICLASS_CMD_DETECT:
snprintf(exp, size, "DETECT");
break;
case ICLASS_CMD_CHECK:
snprintf(exp, size, "CHECK");
break;
case ICLASS_CMD_READ4:
snprintf(exp, size, "READ4(%d)", cmd[1]);
break;
case ICLASS_CMD_READ_OR_IDENTIFY: {
if (cmdsize > 1) {
snprintf(exp, size, "READ(%d)", cmd[1]);
@ -335,36 +356,22 @@ void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
}
break;
}
case ICLASS_CMD_SELECT:
snprintf(exp, size, "SELECT");
break;
case ICLASS_CMD_PAGESEL:
snprintf(exp, size, "PAGESEL(%d)", cmd[1]);
break;
case ICLASS_CMD_READCHECK_KC:
snprintf(exp, size, "READCHECK[Kc](%d)", cmd[1]);
break;
case ICLASS_CMD_READCHECK_KD:
snprintf(exp, size, "READCHECK[Kd](%d)", cmd[1]);
break;
case ICLASS_CMD_CHECK:
snprintf(exp, size, "CHECK");
break;
case ICLASS_CMD_DETECT:
snprintf(exp, size, "DETECT");
break;
case ICLASS_CMD_HALT:
snprintf(exp, size, "HALT");
break;
case ICLASS_CMD_UPDATE:
snprintf(exp, size, "UPDATE(%d)", cmd[1]);
break;
case ICLASS_CMD_READCHECK:
if ( ICLASS_CREDIT(c) ) {
snprintf(exp, size, "READCHECK[Kc](%d)", cmd[1]);
} else {
snprintf(exp, size, "READCHECK[Kd](%d)", cmd[1]);
}
break;
case ICLASS_CMD_ACT:
snprintf(exp, size, "ACT");
break;
case ICLASS_CMD_READ4:
snprintf(exp, size, "READ4(%d)", cmd[1]);
break;
default:
snprintf(exp, size, "?");
break;

File diff suppressed because it is too large Load diff

View file

@ -36,13 +36,14 @@
#include "hardnested/hardnested_bf_core.h"
#include "hardnested/hardnested_bitarray_core.h"
#include "zlib.h"
#include "fileutils.h"
#define NUM_CHECK_BITFLIPS_THREADS (num_CPUs())
#define NUM_REDUCTION_WORKING_THREADS (num_CPUs())
#define IGNORE_BITFLIP_THRESHOLD 0.99 // ignore bitflip arrays which have nearly only valid states
#define STATE_FILES_DIRECTORY "hardnested/tables/"
#define STATE_FILES_DIRECTORY "hardnested_tables/"
#define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin.z"
#define DEBUG_KEY_ELIMINATION
@ -248,10 +249,15 @@ static void init_bitflip_bitarrays(void) {
bitflip_bitarrays[odd_even][bitflip] = NULL;
count_bitflip_bitarrays[odd_even][bitflip] = 1 << 24;
sprintf(state_file_name, STATE_FILE_TEMPLATE, odd_even, bitflip);
strcpy(state_files_path, get_my_executable_directory());
strcat(state_files_path, STATE_FILES_DIRECTORY);
strcpy(state_files_path, STATE_FILES_DIRECTORY);
strcat(state_files_path, state_file_name);
FILE *statesfile = fopen(state_files_path, "rb");
char *path;
if (searchFile(&path, RESOURCES_SUBDIR, state_files_path, "", true) != PM3_SUCCESS) {
continue;
}
FILE *statesfile = fopen(path, "rb");
free(path);
if (statesfile == NULL) {
continue;
} else {

View file

@ -86,7 +86,7 @@ static int CmdHFMFPInfo(const char *cmd) {
// check SL0
uint8_t data[250] = {0};
int datalen = 0;
// https://github.com/Proxmark/proxmark3/blob/master/client/scripts/mifarePlus.lua#L161
// https://github.com/Proxmark/proxmark3/blob/master/client/luascripts/mifarePlus.lua#L161
uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00};
int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen);
if (!res && datalen > 1 && data[0] == 0x09) {

View file

@ -18,7 +18,7 @@
#include "cmdhfmf.h"
#include "cmdhf14a.h"
#include "comms.h"
#include "loclass/fileutils.h"
#include "fileutils.h"
#include "protocols.h"
#define MAX_UL_BLOCKS 0x0F
@ -2191,7 +2191,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
// convert old format to new format, if need
int res = convertOldMfuDump(&dump, &bytes_read);
if (res) {
if (res != PM3_SUCCESS) {
PrintAndLogEx(WARNING, "Failed convert on load to new Ultralight/NTAG format");
free(dump);
return res;
@ -2519,7 +2519,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
if (param_gethex(Cmd, 0, uid, 14)) {
PrintAndLogEx(WARNING, "UID must include 14 HEX symbols");
return 1;
return PM3_EINVARG;
}
// read block2.
@ -2527,7 +2527,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
SendCommandMIX(CMD_HF_MIFAREU_READBL, 2, 0, 0, NULL, 0);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
PrintAndLogEx(WARNING, "Command execute timeout");
return 2;
return PM3_ETIMEOUT;
}
// save old block2.
@ -2544,7 +2544,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 0, 0, 0, data, sizeof(data));
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
PrintAndLogEx(WARNING, "Command execute timeout");
return 3;
return PM3_ETIMEOUT;
}
// block 1.
@ -2556,7 +2556,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 1, 0, 0, data, sizeof(data));
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
PrintAndLogEx(WARNING, "Command execute timeout");
return 4;
return PM3_ETIMEOUT;
}
// block 2.
@ -2568,9 +2568,9 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
SendCommandOLD(CMD_HF_MIFAREU_WRITEBL, 2, 0, 0, data, sizeof(data));
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
PrintAndLogEx(WARNING, "Command execute timeout");
return 5;
return PM3_ETIMEOUT;
}
return 0;
return PM3_SUCCESS;
}
static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) {
@ -2681,8 +2681,9 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) {
PrintAndLogEx(NORMAL, "Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey)));
PrintAndLogEx(NORMAL, "Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd)));
mbedtls_des3_free(&ctx);
// next. from the diversify_key method.
return 0;
return PM3_SUCCESS;
}
static int CmdHF14AMfUPwdGen(const char *Cmd) {
@ -2709,11 +2710,11 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) {
// 3: proprietary Anticollision
if (select_status == 0) {
PrintAndLogEx(WARNING, "iso14443a card select failed");
return 1;
return PM3_ESOFT;
}
if (card.uidlen != 7) {
PrintAndLogEx(WARNING, "Wrong sized UID, expected 7bytes got %d", card.uidlen);
return 1;
return PM3_ESOFT;
}
memcpy(uid, card.uid, sizeof(uid));
} else {
@ -2732,7 +2733,7 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) {
PrintAndLogEx(NORMAL, "------+----------+-----");
PrintAndLogEx(NORMAL, " Vingcard algo");
PrintAndLogEx(NORMAL, "--------------------");
return 0;
return PM3_SUCCESS;
}
//------------------------------------
// Menu Stuff
@ -2757,7 +2758,7 @@ static command_t CommandTable[] = {
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return 0;
return PM3_SUCCESS;
}
int CmdHFMFUltra(const char *Cmd) {

View file

@ -60,10 +60,11 @@ static int print_barcode(uint8_t *barcode, const size_t barcode_len, bool verbos
compute_crc(CRC_14443_A, barcode, barcode_len - 2, &b1, &b2);
bool isok = (barcode[barcode_len - 1] == b1 && barcode[barcode_len - 2] == b2);
PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail"));
PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("%02X %02X")"- %s", b2, b1, (isok) ? _GREEN_("OK") : _RED_("fail"));
} else {
PrintAndLogEx(SUCCESS, " checksum : "_YELLOW_("too few data for checksum")"- " _RED_("fail"));
PrintAndLogEx(SUCCESS, " Checksum : "_YELLOW_("too few data for checksum")"- " _RED_("fail"));
}
PrintAndLogEx(SUCCESS, " Data len (bits) : "_YELLOW_("%i")"- %s", barcode_len*8, (barcode_len==16||barcode_len==32) ? _GREEN_("OK") : _YELLOW_("warning"));
PrintAndLogEx(SUCCESS, " Raw data : "_YELLOW_("%s"), sprint_hex(barcode, barcode_len));
if (barcode_len < 4) // too few to go to next decoding stages
return PM3_ESOFT;

View file

@ -493,7 +493,7 @@ static int CmdTune(const char *Cmd) {
static int CmdVersion(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
pm3_version(true);
pm3_version(true, false);
return PM3_SUCCESS;
}
@ -617,7 +617,66 @@ int CmdHW(const char *Cmd) {
return CmdsParse(CommandTable, Cmd);
}
void pm3_version(bool verbose) {
void pm3_version(bool verbose, bool oneliner) {
#if defined(__MINGW64__)
# define PM3CLIENTCOMPILER "MinGW-w64 "
#elif defined(__MINGW32__)
# define PM3CLIENTCOMPILER "MinGW "
#elif defined(__clang__)
# define PM3CLIENTCOMPILER "Clang/LLVM "
#elif defined(__GNUC__) || defined(__GNUG__)
# define PM3CLIENTCOMPILER "GCC "
#else
# define PM3CLIENTCOMPILER "unknown compiler "
#endif
#if defined(__APPLE__) || defined(__MACH__)
# define PM3HOSTOS " OS:OSX"
#elif defined(__ANDROID__) || defined(ANDROID)
// must be tested before __linux__
# define PM3HOSTOS " OS:Android"
#elif defined(__linux__)
# define PM3HOSTOS " OS:Linux"
#elif defined(__FreeBSD__)
# define PM3HOSTOS " OS:FreeBSD"
#elif defined(__NetBSD__)
# define PM3HOSTOS " OS:NetBSD"
#elif defined(__OpenBSD__)
# define PM3HOSTOS " OS:OpenBSD"
#elif defined(__CYGWIN__)
# define PM3HOSTOS " OS:Cygwin"
#elif defined(_WIN64) | defined(__WIN64__)
// must be tested before _WIN32
# define PM3HOSTOS " OS:Windows (64b)"
#elif defined(_WIN32) | defined(__WIN32__)
# define PM3HOSTOS " OS:Windows (32b)"
#else
# define PM3HOSTOS " OS:unknown"
#endif
#if defined(__x86_64__)
# define PM3HOSTARCH " ARCH:x86_64"
#elif defined(__i386__)
# define PM3HOSTARCH " ARCH:x86"
#elif defined(__aarch64__)
# define PM3HOSTARCH " ARCH:aarch64"
#elif defined(__arm__)
# define PM3HOSTARCH " ARCH:arm"
#elif defined(__powerpc64__)
# define PM3HOSTARCH " ARCH:powerpc64"
#elif defined(__mips__)
# define PM3HOSTARCH " ARCH:mips"
#else
# define PM3HOSTARCH " ARCH:unknown"
#endif
if (oneliner) {
// For "proxmark3 -v", simple printf, avoid logging
printf("Client: RRG/Iceman compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH "\n");
return;
}
if (!verbose)
return;
@ -630,11 +689,7 @@ void pm3_version(bool verbose) {
PrintAndLogEx(NORMAL, "\n" _BLUE_(" [ Proxmark3 RFID instrument ]") "\n");
PrintAndLogEx(NORMAL, "\n [ CLIENT ]");
PrintAndLogEx(NORMAL, " client: RRG/Iceman"); // TODO version info?
#if defined(__clang__)
PrintAndLogEx(NORMAL, " compiled with Clang/LLVM "__VERSION__);
#elif defined(__GNUC__) || defined(__GNUG__)
PrintAndLogEx(NORMAL, " compiled with GCC "__VERSION__);
#endif
PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH);
PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]");
PrintAndLogEx(NORMAL, " external flash: %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent"));
PrintAndLogEx(NORMAL, " smartcard reader: %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent"));

View file

@ -15,6 +15,6 @@
int CmdHW(const char *Cmd);
void pm3_version(bool verbose);
void pm3_version(bool verbose, bool oneliner);
#endif

View file

@ -58,7 +58,7 @@ static int usage_lf_awid_sim(void) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf awid sim 26 224 1337");
PrintAndLogEx(NORMAL, " lf awid sim 50 2001 deadc0de");
PrintAndLogEx(NORMAL, " lf awid sim 50 2001 13371337");
return PM3_SUCCESS;
}

View file

@ -15,7 +15,7 @@
#include "cmdtrace.h"
#include "commonutil.h"
#include "hitag.h"
#include "loclass/fileutils.h" // savefile
#include "fileutils.h" // savefile
static int CmdHelp(const char *Cmd);

View file

@ -22,7 +22,7 @@
#include "cmdlf.h"
#include "lfdemod.h"
static int CmdHelp(const char *Cmd);
/*
static int usage_lf_paradox_sim(void) {
PrintAndLogEx(NORMAL, "Enables simulation of Paradox card with specified card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
@ -38,6 +38,7 @@ static int usage_lf_paradox_sim(void) {
PrintAndLogEx(NORMAL, " lf paradox sim 123 11223");
return PM3_SUCCESS;
}
*/
//by marshmellow
//Paradox Prox demod - FSK2a RF/50 with preamble of 00001111 (then manchester encoded)
@ -111,8 +112,12 @@ static int CmdParadoxRead(const char *Cmd) {
return CmdParadoxDemod(Cmd);
}
static int CmdParadoxSim(const char *Cmd) {
static int CmdParadoxSim(const char *Cmd) {
PrintAndLogEx(INFO," To be implemented, feel free to contribute!");
return PM3_SUCCESS;
}
/*
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_paradox_sim();
@ -155,7 +160,7 @@ static int CmdParadoxSim(const char *Cmd) {
return resp.status;
return PM3_SUCCESS;
}
*/
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdParadoxDemod, AlwaysAvailable, "Demodulate a Paradox FSK tag from the GraphBuffer"},

View file

@ -25,7 +25,7 @@
#include "cmddata.h"
#include "lfdemod.h"
#include "cmdhf14a.h" // for getTagInfo
#include "loclass/fileutils.h" // loadDictionary
#include "fileutils.h" // loadDictionary
#include "util_posix.h"
@ -91,6 +91,17 @@ static int usage_t55xx_read() {
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int usage_t55xx_resetread() {
PrintAndLogEx(NORMAL, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)");
PrintAndLogEx(NORMAL, "Usage: lf t55xx resetread [r <mode>]");
PrintAndLogEx(NORMAL, "Options:");
print_usage_t55xx_downloadlink();
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf t55xx resetread");
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int usage_t55xx_write() {
PrintAndLogEx(NORMAL, "Usage: lf t55xx write [r <mode>] b <block> d <data> [p <password>] [1] [t]");
PrintAndLogEx(NORMAL, "Options:");
@ -108,26 +119,26 @@ static int usage_t55xx_write() {
return PM3_SUCCESS;
}
static int usage_t55xx_trace() {
PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [r mode]");
PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [1] [r mode]");
PrintAndLogEx(NORMAL, "Options:");
print_usage_t55xx_downloadlink();
// Command did not seem to support the 1 option (yet) so have removed the help lines
// PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag.");
PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag.");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf t55xx trace");
// PrintAndLogEx(NORMAL, " lf t55xx trace 1");
PrintAndLogEx(NORMAL, " lf t55xx trace 1");
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int usage_t55xx_info() {
PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1] [r <mode>] [d <data> [q]]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " (default) - read data from tag.");
PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag.");
PrintAndLogEx(NORMAL, " d <data> - 4 bytes of data (8 hex characters)");
PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag.");
PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config.");
PrintAndLogEx(NORMAL, " (default) - read data from tag.");
PrintAndLogEx(NORMAL, " p <password> - OPTIONAL password 4bytes (8 hex symbols)");
PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag.");
PrintAndLogEx(NORMAL, " d <data> - 4 bytes of data (8 hex characters)");
PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag.");
PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config.");
print_usage_t55xx_downloadlink();
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
@ -135,19 +146,20 @@ static int usage_t55xx_info() {
PrintAndLogEx(NORMAL, " lf t55xx info 1");
PrintAndLogEx(NORMAL, " lf t55xx info d 00083040");
PrintAndLogEx(NORMAL, " lf t55xx info d 6001805A q");
PrintAndLogEx(NORMAL, " lf t55xx info p 11223344");
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int usage_t55xx_dump() {
PrintAndLogEx(NORMAL, "Usage: lf t55xx dump [r <mode>] [<password> [o]]");
PrintAndLogEx(NORMAL, "Usage: lf t55xx dump [r <mode>] [p <password> [o]]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " <password> - OPTIONAL password 4bytes (8 hex symbols)");
PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card");
PrintAndLogEx(NORMAL, " p <password> - OPTIONAL password 4bytes (8 hex symbols)");
PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card");
print_usage_t55xx_downloadlink();
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf t55xx dump");
PrintAndLogEx(NORMAL, " lf t55xx dump feedbeef o");
PrintAndLogEx(NORMAL, " lf t55xx dump p feedbeef o");
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
@ -206,7 +218,7 @@ static int usage_t55xx_chk() {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf t55xx chk m");
PrintAndLogEx(NORMAL, " lf t55xx chk i default_pwd.dic");
PrintAndLogEx(NORMAL, " lf t55xx chk i t55xx_default_pwds");
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
@ -215,16 +227,16 @@ static int usage_t55xx_bruteforce() {
PrintAndLogEx(NORMAL, "press " _YELLOW_("'enter'") " to cancel the command");
PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!");
PrintAndLogEx(NORMAL, "Try reading block 7 before\n");
PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] [r <mode>] <start password> <end password>");
PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] [r <mode>] [s <start password>] [e <end password>]");
PrintAndLogEx(NORMAL, " password must be 4 bytes (8 hex symbols)");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - this help");
print_usage_t55xx_downloadlink();
PrintAndLogEx(NORMAL, " <start_pwd> - 4 byte hex value to start pwd search at");
PrintAndLogEx(NORMAL, " <end_pwd> - 4 byte hex value to end pwd search at");
PrintAndLogEx(NORMAL, " s <start_pwd> - 4 byte hex value to start pwd search at");
PrintAndLogEx(NORMAL, " e <end_pwd> - 4 byte hex value to end pwd search at");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf t55xx bruteforce r 2 aaaaaa77 aaaaaa99");
PrintAndLogEx(NORMAL, " lf t55xx bruteforce r 2 s aaaaaa77 e aaaaaa99");
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
@ -248,15 +260,15 @@ static int usage_t55xx_recoverpw() {
return PM3_SUCCESS;
}
static int usage_t55xx_wipe() {
PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5]");
PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5] [p <password>]");
PrintAndLogEx(NORMAL, "This commands wipes a tag, fills blocks 1-7 with zeros and a default configuration block");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - this help");
PrintAndLogEx(NORMAL, " Q5 - indicates to use the T5555 (Q5) default configuration block");
PrintAndLogEx(NORMAL, " q - indicates to use the T5555 (Q5) default configuration block");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf t55xx wipe - wipes a t55x7 tag, config block 0x000880E0");
PrintAndLogEx(NORMAL, " lf t55xx wipe Q5 - wipes a t5555 Q5 tag, config block 0x6001F004");
PrintAndLogEx(NORMAL, " lf t55xx wipe - wipes a t55x7 tag, config block 0x000880E0");
PrintAndLogEx(NORMAL, " lf t55xx wipe q - wipes a t5555 Q5 tag, config block 0x6001F004");
return PM3_SUCCESS;
}
static int usage_lf_deviceconfig() {
@ -292,6 +304,9 @@ void printT5xxHeader(uint8_t page) {
static int CmdT55xxSetConfig(const char *Cmd) {
// No args
if (strlen(Cmd) == 0) return printConfiguration(config);
uint8_t offset = 0, bitRate = 0;
char modulation[6] = {0x00};
uint8_t rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0};
@ -395,9 +410,6 @@ static int CmdT55xxSetConfig(const char *Cmd) {
}
}
// No args
if (cmdp == 0) return printConfiguration(config);
//Validations
if (errors) return usage_t55xx_config();
@ -409,41 +421,42 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uin
//Password mode
if (usepwd) {
// try reading the config block and verify that PWD bit is set before doing this!
if (!override) {
if (override == 0) {
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, downlink_mode)) return PM3_ESOFT;
if (!tryDetectModulation()) {
PrintAndLogEx(NORMAL, "Safety Check: Could not detect if PWD bit is set in config block. Exits.");
return 0;
return PM3_ESOFT;
} else {
PrintAndLogEx(NORMAL, "Safety Check: PWD bit is NOT set in config block. Reading without password...");
usepwd = false;
page1 = false;
page1 = false; // ??
}
} else {
} else if (override == 1) {
// Show only if first for command i.e. override = 1 (override and display) override = 2 (override and dont display)
if ((override & 2) != 2)
PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk");
PrintAndLogEx(NORMAL, "Safety Check Overriden - proceeding despite risk");
}
}
if (!AquireData(page1, block, usepwd, password, downlink_mode))
return PM3_ESOFT;
if (!AquireData(page1, block, usepwd, password, downlink_mode)) return PM3_ESOFT;
if (!DecodeT55xxBlock()) return PM3_ESOFT;
if (!DecodeT55xxBlock())
return PM3_ESOFT;
printT55xxBlock(block);
return PM3_SUCCESS;
}
static int CmdT55xxReadBlock(const char *Cmd) {
uint8_t block = REGULAR_READ_MODE_BLOCK;
uint32_t password = 0; //default to blank Block 7
bool usepwd = false;
bool override = false;
bool page1 = false;
bool errors = false;
uint8_t cmdp = 0;
uint8_t downlink_mode = 0;
uint8_t block = REGULAR_READ_MODE_BLOCK;
uint8_t override = 0;
uint8_t cmdp = 0;
uint8_t downlink_mode = 0;
uint32_t password = 0; //default to blank Block 7
bool usepwd = false;
bool page1 = false;
bool errors = false;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
@ -454,7 +467,7 @@ static int CmdT55xxReadBlock(const char *Cmd) {
cmdp += 2;
break;
case 'o':
override = true;
override = 1;
cmdp++;
break;
case 'p':
@ -467,9 +480,10 @@ static int CmdT55xxReadBlock(const char *Cmd) {
cmdp++;
break;
case 'r':
case 'R':
downlink_mode = param_getchar(Cmd, cmdp + 1) - '0';
if (downlink_mode > 3) downlink_mode = 0;
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode > 3)
downlink_mode = 0;
cmdp += 2;
break;
@ -479,7 +493,7 @@ static int CmdT55xxReadBlock(const char *Cmd) {
break;
}
}
if (errors) return usage_t55xx_read();
if (errors || cmdp == 0) return usage_t55xx_read();
if (block > 7 && block != REGULAR_READ_MODE_BLOCK) {
PrintAndLogEx(NORMAL, "Block must be between 0 and 7");
@ -593,15 +607,13 @@ void T55xx_Print_DownlinkMode(uint8_t downlink_mode) {
//
static int CmdT55xxDetect(const char *Cmd) {
bool errors = false;
bool useGB = false;
bool usepwd = false;
bool try_all_dl_modes = false;
bool found = false;
uint32_t password = 0;
uint8_t cmdp = 0;
uint8_t downlink_mode = 0;
uint8_t dl_mode = 0;
bool errors = false;
bool useGB = false;
bool usepwd = false;
bool try_all_dl_modes = false;
uint32_t password = 0;
uint8_t cmdp = 0;
uint8_t downlink_mode = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
@ -613,14 +625,15 @@ static int CmdT55xxDetect(const char *Cmd) {
cmdp += 2;
break;
case '1':
// use Graphbuffer data
useGB = true;
cmdp++;
break;
case 'r':
downlink_mode = param_getchar(Cmd, cmdp + 1) - '0';
if (downlink_mode == 4) try_all_dl_modes = true;
if (downlink_mode > 3) downlink_mode = 0;
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode >= 4) {
try_all_dl_modes = true;
downlink_mode = 4;
}
cmdp += 2;
break;
default:
@ -632,48 +645,32 @@ static int CmdT55xxDetect(const char *Cmd) {
if (errors) return usage_t55xx_detect();
// sanity check.
if (SanityOfflineCheck(useGB) != PM3_SUCCESS) return PM3_ENODATA;
if (SanityOfflineCheck(useGB) != PM3_SUCCESS)
return PM3_ESOFT;
if (!useGB) {
for (dl_mode = downlink_mode; dl_mode < 4; dl_mode++) {
found = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, dl_mode);
if (useGB == false) {
if ( try_all_dl_modes ) {
for (uint8_t mode = 0; mode < 4; mode++) {
// found = false if password is supplied but wrong d/l mode
// so keep trying other modes (if requested)
/*
if (!found) {
printf ("Aquire not found");
return PM3_ENODATA;
if ( AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, mode) == false ) {
continue;
}
if (tryDetectModulation()) {
T55xx_Print_DownlinkMode(mode);
return PM3_SUCCESS;
}
}
*/
if (tryDetectModulation()) {
T55xx_Print_DownlinkMode(dl_mode);
dl_mode = 4;
found = true;
} else found = false;
if (!try_all_dl_modes) dl_mode = 4;
return PM3_ESOFT;
} else {
if ( AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode) == false )
return PM3_ENODATA;
}
}
if (useGB) found = tryDetectModulation();
if (!found)
if (tryDetectModulation() == false)
PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'"));
/*
if (!useGB) {
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password,downlink_mode))
return PM3_ENODATA;
}
if (!tryDetectModulation())
PrintAndLogEx(WARNING, "Could not detect modulation automatically. Try setting it manually with " _YELLOW_("\'lf t55xx config\'"));
else
T55xx_Print_DownlinkMode (downlink_mode);
*/
return PM3_SUCCESS;
}
// detect configuration?
@ -1107,24 +1104,23 @@ int special(const char *Cmd) {
}
int printConfiguration(t55xx_conf_block_t b) {
PrintAndLogEx(NORMAL, "Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7");
PrintAndLogEx(NORMAL, "Modulation : %s", GetSelectedModulationStr(b.modulation));
PrintAndLogEx(NORMAL, "Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9))));
PrintAndLogEx(NORMAL, "Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No");
PrintAndLogEx(NORMAL, "Offset : %d", b.offset);
PrintAndLogEx(NORMAL, "Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No");
PrintAndLogEx(NORMAL, "Block0 : 0x%08X", b.block0);
PrintAndLogEx(NORMAL, " Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7");
PrintAndLogEx(NORMAL, " Modulation : %s", GetSelectedModulationStr(b.modulation));
PrintAndLogEx(NORMAL, " Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9))));
PrintAndLogEx(NORMAL, " Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No");
PrintAndLogEx(NORMAL, " Offset : %d", b.offset);
PrintAndLogEx(NORMAL, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No");
PrintAndLogEx(NORMAL, " Block0 : 0x%08X", b.block0);
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int CmdT55xxWakeUp(const char *Cmd) {
uint32_t password = 0;
uint8_t cmdp = 0;
bool errors = false;
uint8_t downlink_mode = 0;
uint8_t flags = 0;
uint32_t password = 0;
uint8_t cmdp = 0;
bool errors = false;
uint8_t downlink_mode = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
@ -1133,11 +1129,12 @@ static int CmdT55xxWakeUp(const char *Cmd) {
case 'p':
password = param_get32ex(Cmd, cmdp + 1, 0, 16);
cmdp += 2;
errors = false;
break;
case 'r':
downlink_mode = param_getchar(Cmd, cmdp + 1) - '0';
if (downlink_mode > 3) downlink_mode = 0;
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode > 3)
downlink_mode = 0;
cmdp += 2;
break;
default:
@ -1149,24 +1146,35 @@ static int CmdT55xxWakeUp(const char *Cmd) {
if (errors) return usage_t55xx_wakup();
flags = (downlink_mode & 3) << 3;
clearCommandBuffer();
SendCommandMIX(CMD_LF_T55XX_WAKEUP, password, flags, 0, NULL, 0);
PrintAndLogEx(SUCCESS, "Wake up command sent. Try read now");
struct p {
uint32_t password;
uint8_t flags;
} PACKED payload;
payload.password = password;
payload.flags = (downlink_mode & 3) << 3;
clearCommandBuffer();
SendCommandNG(CMD_LF_T55XX_WAKEUP, (uint8_t *)&payload, sizeof(payload));
if (!WaitForResponseTimeout(CMD_LF_T55XX_WAKEUP, NULL, 1000)) {
PrintAndLogEx(WARNING, "command execution time out");
return PM3_ETIMEOUT;
}
PrintAndLogEx(SUCCESS, "Wake up command sent. Try read now");
return PM3_SUCCESS;
}
static int CmdT55xxWriteBlock(const char *Cmd) {
uint8_t block = 0xFF; //default to invalid block
uint32_t data = 0; //default to blank Block
uint32_t password = 0; //default to blank Block 7
bool usepwd = false;
bool page1 = false;
bool gotdata = false;
bool testMode = false;
bool errors = false;
uint8_t cmdp = 0;
uint8_t block = 0xFF; // default to invalid block
uint32_t data = 0; // default to blank Block
uint32_t password = 0; // default to blank Block 7
bool usepwd = false;
bool page1 = false;
bool gotdata = false;
bool testMode = false;
bool errors = false;
uint8_t cmdp = 0;
uint32_t downlink_mode = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
@ -1201,8 +1209,10 @@ static int CmdT55xxWriteBlock(const char *Cmd) {
cmdp++;
break;
case 'r':
downlink_mode = param_getchar(Cmd, cmdp + 1) - '0';
if (downlink_mode > 3) downlink_mode = 0;
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode > 3)
downlink_mode = 0;
cmdp += 2;
break;
default:
@ -1252,25 +1262,43 @@ static int CmdT55xxWriteBlock(const char *Cmd) {
}
static int CmdT55xxReadTrace(const char *Cmd) {
uint8_t cmd_len = 0;
bool frombuff = false;
uint8_t downlink_mode = 0;
uint8_t cmdp = 0;
bool errors = false;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_t55xx_trace();
case 'r':
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode > 3)
downlink_mode = 0;
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'r') {
downlink_mode = param_getchar(Cmd, 1) - '0';
if (downlink_mode > 3) downlink_mode = 0;
cmd_len = 3;
cmdp += 2;
break;
case '1':
frombuff = true;
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if ((strlen(Cmd) != cmd_len) || (cmdp == 'h')) return usage_t55xx_trace();
if (strlen(Cmd) == cmd_len) {
if (errors) return usage_t55xx_trace();
if (!frombuff) {
// sanity check.
if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ENODATA;
bool pwdmode = false;
uint32_t password = 0;
// REGULAR_READ_MODE_BLOCK - yeilds correct Page 1 Block 2 data i.e. + 32 bit offset.
// if (!AquireData(T55x7_PAGE1, T55x7_TRACE_BLOCK1, pwdmode, password,downlink_mode))
// REGULAR_READ_MODE_BLOCK - yeilds correct Page 1 Block 2 data i.e. + 32 bit offset.
if (!AquireData(T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password, downlink_mode))
return PM3_ENODATA;
}
@ -1467,7 +1495,7 @@ static void printT5x7KnownBlock0(uint32_t b0) {
snprintf(s + strlen(s), sizeof(s) - strlen(s), "FDXB ");
break;
case T55X7_HID_26_CONFIG_BLOCK:
snprintf(s + strlen(s), sizeof(s) - strlen(s), "HID 26b ");
snprintf(s + strlen(s), sizeof(s) - strlen(s), "HID 26b (ProxCard) ");
break;
case T55X7_PYRAMID_CONFIG_BLOCK:
snprintf(s + strlen(s), sizeof(s) - strlen(s), "Pyramid ");
@ -1513,10 +1541,10 @@ static int CmdT55xxInfo(const char *Cmd) {
Normal mode
Extended mode
*/
bool frombuff = false, gotdata = false, dataasq5 = false;
uint8_t cmdp = 0;
uint8_t downlink_mode = 0;
uint32_t block0 = 0;
bool frombuff = false, gotdata = false, dataasq5 = false, usepwd = false;
uint8_t cmdp = 0;
uint8_t downlink_mode = 0;
uint32_t block0 = 0, password = 0;
while (param_getchar(Cmd, cmdp) != 0x00) {
switch (tolower(param_getchar(Cmd, cmdp))) {
@ -1527,6 +1555,11 @@ static int CmdT55xxInfo(const char *Cmd) {
gotdata = true;
cmdp += 2;
break;
case 'p':
password = param_get32ex(Cmd, cmdp + 1, 0, 16);
usepwd = true;
cmdp += 2;
break;
case '1':
frombuff = true;
cmdp += 2;
@ -1536,8 +1569,10 @@ static int CmdT55xxInfo(const char *Cmd) {
cmdp += 2;
break;
case 'r':
downlink_mode = param_getchar(Cmd, cmdp + 1) - '0';
if (downlink_mode > 3) downlink_mode = 0;
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode > 3)
downlink_mode = 0;
cmdp += 2;
break;
default:
@ -1556,11 +1591,10 @@ static int CmdT55xxInfo(const char *Cmd) {
// sanity check.
if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ENODATA;
bool pwdmode = false;
uint32_t password = 0;
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password, downlink_mode))
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode))
return PM3_ENODATA;
}
if (!gotdata) {
if (!DecodeT55xxBlock()) return PM3_ESOFT;
@ -1653,34 +1687,47 @@ static int CmdT55xxInfo(const char *Cmd) {
static int CmdT55xxDump(const char *Cmd) {
uint32_t password = 0;
uint8_t override = false;
uint8_t cmd_opt_idx = 0;
uint8_t downlink_mode = 0;
uint8_t pwd_offset = 0;
char cmdp = tolower(param_getchar(Cmd, 0));
uint32_t password = 0;
uint8_t override = 0;
uint8_t downlink_mode = 0;
bool usepwd = false;
bool errors = false;
uint8_t cmdp = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_t55xx_dump();
case 'r':
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode > 3)
downlink_mode = 0;
if (cmdp == 'h') return usage_t55xx_dump();
if (cmdp == 'r') {
cmd_opt_idx++;
downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0';
if (downlink_mode > 3) downlink_mode = 0;
pwd_offset = 3;
}
bool usepwd = (strlen(Cmd) > pwd_offset);
if (usepwd) {
password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16);
if (param_getchar(Cmd, cmd_opt_idx++) == 'o')
override = true;
cmdp += 2;
break;
case 'p':
password = param_get32ex(Cmd, cmdp + 1, 0, 16);
usepwd = true;
cmdp += 2;
break;
case 'o':
override = 1;
cmdp++;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (errors) return usage_t55xx_dump();
printT5xxHeader(0);
for (uint8_t i = 0; i < 8; ++i) {
T55xxReadBlock(i, 0, usepwd, override, password, downlink_mode);
// idea for better user experience and display.
// only show override warning on the first block read
if (override) override |= 2; // flag not to show safty for 2nd and on.
if (override == 1) override++; // flag not to show safty for 2nd and on.
}
printT5xxHeader(1);
for (uint8_t i = 0; i < 4; i++)
@ -1970,16 +2017,34 @@ static void t55x7_create_config_block(int tagtype) {
static int CmdResetRead(const char *Cmd) {
uint8_t downlink_mode = 0;
uint8_t flags = 0;
uint8_t flags = 0;
uint8_t cmdp = 0;
bool errors = false;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_t55xx_resetread();
case 'r':
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode > 3)
downlink_mode = 0;
if (strlen(Cmd) == 3)
downlink_mode = param_getchar(Cmd, 1) - '0';
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (downlink_mode > 3) downlink_mode = 0;
if (errors) return usage_t55xx_resetread();
PrintAndLogEx(INFO, "DL : %d\n", downlink_mode);
printf("DL : %d\n", downlink_mode);
flags = downlink_mode << 3;
clearCommandBuffer();
SendCommandNG(CMD_LF_T55XX_RESET_READ, &flags, sizeof(flags));
if (!WaitForResponseTimeout(CMD_ACK, NULL, 2500)) {
@ -1997,29 +2062,62 @@ static int CmdResetRead(const char *Cmd) {
}
static int CmdT55xxWipe(const char *Cmd) {
char writeData[20] = {0};
char writeData[36] = {0};
char *ptrData = writeData;
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_t55xx_wipe();
uint32_t password = 0;
bool usepwd = false;
bool Q5 = false;
uint8_t cmdp = 0;
bool errors = false;
bool Q5 = (cmdp == 'q');
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_t55xx_wipe();
case 'p':
// password used by handheld cloners
password = param_get32ex(Cmd, cmdp + 1, 0x51243648, 16);
usepwd = true;
cmdp += 2;
break;
case 'q':
Q5 = true;
cmdp++;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (errors) return usage_t55xx_wipe();
// Try with the default password to reset block 0
// With a pwd should work even if pwd bit not set
PrintAndLogEx(INFO, "\nBeginning Wipe of a T55xx tag (assuming the tag is not password protected)\n");
if (Q5)
snprintf(ptrData, sizeof(writeData), "b 0 d 6001F004 p 0");
else
snprintf(ptrData, sizeof(writeData), "b 0 d 000880E0 p 0");
if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk 0");
if (usepwd) {
snprintf(ptrData, sizeof(writeData), "b 0 p %08x ", password);
} else {
snprintf(ptrData, sizeof(writeData), "b 0 ");
}
if (Q5)
snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d 6001F004");
else
snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d 000880E0");
if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS)
PrintAndLogEx(WARNING, "Warning: error writing blk 0");
for (uint8_t blk = 1; blk < 8; blk++) {
snprintf(ptrData, sizeof(writeData), "b %d d 0", blk);
if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk %d", blk);
if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS)
PrintAndLogEx(WARNING, "Warning: error writing blk %d", blk);
memset(writeData, 0x00, sizeof(writeData));
}
@ -2037,44 +2135,50 @@ static bool IsCancelled(void) {
// load a default pwd file.
static int CmdT55xxChkPwds(const char *Cmd) {
char filename[FILE_PATH_SIZE] = {0};
bool found = false;
char filename[FILE_PATH_SIZE] = {0};
bool found = false;
uint8_t timeout = 0;
uint8_t *keyBlock = NULL;
bool from_flash = false;
bool try_all_dl_modes = false;
bool from_flash = false;
bool try_all_dl_modes = false;
uint8_t downlink_mode = 0;
int len;
char cmdp;
bool use_pwd_file = false;
int dl_mode; // to try each downlink mode for each password
bool use_pwd_file = false;
int dl_mode; // to try each downlink mode for each password
uint8_t cmdp = 0;
bool errors = false;
cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_t55xx_chk();
if (cmdp == 'm') {
from_flash = true;
Cmd += 2;
cmdp = tolower(param_getchar(Cmd, 0));
}
if (cmdp == 'r') {
Cmd += 2;
downlink_mode = param_getchar(Cmd, 0) - '0'; // get 2nd option, as this is fixed order.
if (downlink_mode == 4) try_all_dl_modes = true;
if (downlink_mode > 3) downlink_mode = 0;
Cmd += 2;
cmdp = param_getchar(Cmd, 0);
}
if (cmdp == 'i') {
Cmd += 2;
len = strlen(Cmd);
if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
memcpy(filename, Cmd, len);
use_pwd_file = true;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_t55xx_chk();
case 'r':
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode >= 4) {
try_all_dl_modes = true;
downlink_mode = 4;
}
cmdp += 2;
break;
case 'm':
from_flash = true;
cmdp++;
break;
case 'i':
if ( param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) == 0 ) {
PrintAndLogEx(ERR, "Error, no filename after 'f' was found");
errors = true;
}
use_pwd_file = true;
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (errors) return usage_t55xx_chk();
/*
// block 7, page1 = false, usepwd = false, override = false, pwd = 00000000
@ -2127,19 +2231,13 @@ static int CmdT55xxChkPwds(const char *Cmd) {
if (use_pwd_file) {
uint16_t keycount = 0;
size_t datalen = 0;
// TODO, a way of reallocating memory if file was larger
keyBlock = calloc(4 * 200, sizeof(uint8_t));
if (keyBlock == NULL) {
PrintAndLogEx(ERR, "error, cannot allocate memory ");
return PM3_ESOFT;
}
int res = loadFileDICTIONARY(filename, keyBlock, &datalen, 4, &keycount);
if (res || keycount == 0) {
int res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 4, &keycount);
if (res != PM3_SUCCESS || keycount == 0 || keyBlock == NULL) {
PrintAndLogEx(WARNING, "No keys found in file");
free(keyBlock);
if (keyBlock != NULL)
free(keyBlock);
return PM3_ESOFT;
}
@ -2194,33 +2292,48 @@ out:
static int CmdT55xxBruteForce(const char *Cmd) {
uint32_t start_password = 0x00000000; //start password
uint32_t end_password = 0xFFFFFFFF; //end password
uint32_t curr = 0;
uint8_t downlink_mode = 0;
uint8_t cmd_opt_idx = 0;
uint8_t found = 0; // > 0 if found xx1 xx downlink needed, 1 found
uint32_t end_password = 0xFFFFFFFF; //end password
uint32_t curr = 0;
uint8_t downlink_mode = 0;
uint8_t found = 0; // > 0 if found xx1 xx downlink needed, 1 found
uint8_t cmdp = 0;
bool errors = false;
char cmdp = tolower(param_getchar(Cmd, cmd_opt_idx));
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_t55xx_bruteforce();
case 'r':
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode > 4)
downlink_mode = 0;
if (cmdp == 'h') return usage_t55xx_bruteforce();
if (cmdp == 'r') { // downlink mode supplied
cmd_opt_idx++; // skip over 'r'
downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0';
if (downlink_mode > 4) downlink_mode = 0;
cmdp += 2;
break;
case 's':
start_password = param_get32ex(Cmd, cmdp + 1, 0, 16);
cmdp += 2;
break;
case 'e':
end_password = param_get32ex(Cmd, cmdp + 1, 0, 16);
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
uint64_t t1 = msclock();
start_password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16);
end_password = param_get32ex(Cmd, cmd_opt_idx++, 0, 16);
curr = start_password;
if (start_password >= end_password) {
return usage_t55xx_bruteforce();
}
if (errors) return usage_t55xx_bruteforce();
uint64_t t1 = msclock();
curr = start_password;
PrintAndLogEx(INFO, "Search password range [%08X -> %08X]", start_password, end_password);
while (found == 0) {
@ -2281,25 +2394,41 @@ uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode) {
}
static int CmdT55xxRecoverPW(const char *Cmd) {
int bit = 0;
int bit = 0;
uint32_t orig_password = 0x0;
uint32_t curr_password = 0x0;
uint32_t prev_password = 0xffffffff;
uint32_t mask = 0x0;
uint8_t downlink_mode = 0;
uint8_t found = 0;
uint8_t cmd_opt_idx = 0;
uint32_t mask = 0x0;
uint8_t downlink_mode = 0;
uint8_t found = 0;
uint8_t cmdp = 0;
bool errors = false;
char cmdp = tolower(param_getchar(Cmd, cmd_opt_idx));
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_t55xx_recoverpw();
case 'p':
// password used by handheld cloners
orig_password = param_get32ex(Cmd, cmdp + 1, 0x51243648, 16);
cmdp += 2;
break;
case 'r':
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode > 4)
downlink_mode = 0;
if (cmdp == 'h') return usage_t55xx_recoverpw();
if (cmdp == 'r') { // downlink mode supplied
cmd_opt_idx++; // skip over 'r'
downlink_mode = param_getchar(Cmd, cmd_opt_idx++) - '0';
if (downlink_mode > 4) downlink_mode = 0;
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
orig_password = param_get32ex(Cmd, cmd_opt_idx++, 0x51243648, 16); //password used by handheld cloners
if (errors) return usage_t55xx_recoverpw();
// first try fliping each bit in the expected password
while (bit < 32) {
@ -2514,9 +2643,13 @@ static int CmdT55xxDetectPage1(const char *Cmd) {
cmdp++;
break;
case 'r':
downlink_mode = param_getchar(Cmd, cmdp + 1) - '0';
if (downlink_mode == 4) try_all_dl_modes = true;
if (downlink_mode > 3) downlink_mode = 0;
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode == 4)
try_all_dl_modes = true;
if (downlink_mode > 3)
downlink_mode = 0;
cmdp += 2;
break;
default:
@ -2592,8 +2725,10 @@ static int CmdT55xxSetDeviceConfig(const char *Cmd) {
cmdp += 2;
break;
case 'r':
downlink_mode = param_getchar(Cmd, cmdp + 1) - '0';
if (downlink_mode > 3) downlink_mode = 0;
downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (downlink_mode > 3)
downlink_mode = 0;
cmdp += 2;
break;
case 'p':

View file

@ -176,6 +176,9 @@ int CmdsParse(const command_t Commands[], const char *Cmd) {
memset(cmd_name, 0, sizeof(cmd_name));
sscanf(Cmd, "%127s%n", cmd_name, &len);
str_lower(cmd_name);
// Comment
if (cmd_name[0] == '#')
return PM3_SUCCESS;
int i = 0;
while (Commands[i].Name) {
if (0 == strcmp(Commands[i].Name, cmd_name)) {

View file

@ -8,10 +8,6 @@
// Some lua scripting glue to proxmark core.
//-----------------------------------------------------------------------------
// this define is needed for scandir/alphasort to work
#define _GNU_SOURCE
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
@ -26,36 +22,10 @@
#include "lauxlib.h"
#include "proxmark3.h"
#include "ui.h"
#ifdef _WIN32
#include "scandir.h"
#endif
#include "fileutils.h"
static int CmdHelp(const char *Cmd);
static int str_ends_with(const char *str, const char *suffix) {
if (str == NULL || suffix == NULL)
return 0;
size_t str_len = strlen(str);
size_t suffix_len = strlen(suffix);
if (suffix_len > str_len)
return 0;
return 0 == strncmp(str + str_len - suffix_len, suffix, suffix_len);
}
/**
* Utility to check the ending of a string (used to check file suffix)
*/
static bool endsWith(const char *base, const char *str) {
int blen = strlen(base);
int slen = strlen(str);
return (blen >= slen) && (0 == strcmp(base + blen - slen, str));
}
/**
* Generate a sorted list of available commands, what it does is
* generate a file listing of the script-directory for files
@ -63,31 +33,10 @@ static bool endsWith(const char *base, const char *str) {
*/
static int CmdScriptList(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
char const *exedir = get_my_executable_directory();
if (exedir == NULL)
return 0;
char script_directory_path[strlen(exedir) + strlen(LUA_SCRIPTS_DIRECTORY) + 1];
strcpy(script_directory_path, exedir);
strcpy(script_directory_path, get_my_executable_directory());
strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY);
struct dirent **namelist;
int n;
n = scandir(script_directory_path, &namelist, NULL, alphasort);
if (n == -1) {
PrintAndLogEx(FAILED, "Couldn't open the scripts-directory");
return 1;
}
for (uint16_t i = 0; i < n; i++) {
if (str_ends_with(namelist[i]->d_name, ".lua"))
PrintAndLogEx(NORMAL, "%-21s", namelist[i]->d_name);
free(namelist[i]);
}
free(namelist);
return 0;
int ret = searchAndList(LUA_SCRIPTS_SUBDIR, ".lua");
if (ret != PM3_SUCCESS)
return ret;
return searchAndList(CMD_SCRIPTS_SUBDIR, ".cmd");
}
/**
@ -97,67 +46,81 @@ static int CmdScriptList(const char *Cmd) {
* @return
*/
static int CmdScriptRun(const char *Cmd) {
// create new Lua state
lua_State *lua_state;
lua_state = luaL_newstate();
// load Lua libraries
luaL_openlibs(lua_state);
//Sets the pm3 core libraries, that go a bit 'under the hood'
set_pm3_libraries(lua_state);
//Add the 'bin' library
set_bin_library(lua_state);
//Add the 'bit' library
set_bit_library(lua_state);
char script_name[128] = {0};
char preferredName[128] = {0};
char arguments[256] = {0};
int name_len = 0;
int arg_len = 0;
sscanf(Cmd, "%127s%n %255[^\n\r]%n", script_name, &name_len, arguments, &arg_len);
static uint8_t luascriptfile_idx = 0;
sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len);
const char *suffix = "";
if (!endsWith(script_name, ".lua")) {
suffix = ".lua";
char *script_path;
if ((!str_endswith(preferredName, ".cmd")) && (searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", true) == PM3_SUCCESS)) {
int error;
if (luascriptfile_idx == MAX_NESTED_LUASCRIPT) {
PrintAndLogEx(ERR, "Too many nested scripts, skipping %s\n", script_path);
return PM3_EMALLOC;
}
PrintAndLogEx(SUCCESS, "Executing Lua script: %s, args '%s'\n", script_path, arguments);
luascriptfile_idx++;
// create new Lua state
lua_State *lua_state;
lua_state = luaL_newstate();
// load Lua libraries
luaL_openlibs(lua_state);
//Sets the pm3 core libraries, that go a bit 'under the hood'
set_pm3_libraries(lua_state);
//Add the 'bin' library
set_bin_library(lua_state);
//Add the 'bit' library
set_bit_library(lua_state);
error = luaL_loadfile(lua_state, script_path);
free(script_path);
if (!error) {
lua_pushstring(lua_state, arguments);
lua_setglobal(lua_state, "args");
//Call it with 0 arguments
error = lua_pcall(lua_state, 0, LUA_MULTRET, 0); // once again, returns non-0 on error,
}
if (error) { // if non-0, then an error
// the top of the stack should be the error string
if (!lua_isstring(lua_state, lua_gettop(lua_state)))
PrintAndLogEx(FAILED, "Error - but no error (?!)");
// get the top of the stack as the error and pop it off
const char *str = lua_tostring(lua_state, lua_gettop(lua_state));
lua_pop(lua_state, 1);
puts(str);
}
//luaL_dofile(lua_state, buf);
// close the Lua state
lua_close(lua_state);
luascriptfile_idx--;
PrintAndLogEx(SUCCESS, "\nFinished %s\n", preferredName);
return PM3_SUCCESS;
}
char script_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1];
strcpy(script_path, get_my_executable_directory());
strcat(script_path, LUA_SCRIPTS_DIRECTORY);
strcat(script_path, script_name);
strcat(script_path, suffix);
PrintAndLogEx(SUCCESS, "Executing: %s%s, args '%s'\n", script_name, suffix, arguments);
// run the Lua script
int error = luaL_loadfile(lua_state, script_path);
if (!error) {
lua_pushstring(lua_state, arguments);
lua_setglobal(lua_state, "args");
//Call it with 0 arguments
error = lua_pcall(lua_state, 0, LUA_MULTRET, 0); // once again, returns non-0 on error,
if ((!str_endswith(preferredName, ".lua")) && (searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", true) == PM3_SUCCESS)) {
PrintAndLogEx(SUCCESS, "Executing Cmd script: %s, args '%s'\n", script_path, arguments);
int ret = push_cmdscriptfile(script_path, true);
if (ret != PM3_SUCCESS)
PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", script_path);
free(script_path);
return ret;
}
if (error) { // if non-0, then an error
// the top of the stack should be the error string
if (!lua_isstring(lua_state, lua_gettop(lua_state)))
PrintAndLogEx(FAILED, "Error - but no error (?!)");
// get the top of the stack as the error and pop it off
const char *str = lua_tostring(lua_state, lua_gettop(lua_state));
lua_pop(lua_state, 1);
puts(str);
}
//luaL_dofile(lua_state, buf);
// close the Lua state
lua_close(lua_state);
PrintAndLogEx(SUCCESS, "\nFinished\n");
return 0;
// file not found, let's search again to display the error messages
int ret = PM3_EUNDEF;
if (!str_endswith(preferredName, ".cmd")) ret = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false);
if (!str_endswith(preferredName, ".lua")) ret = searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", false);
return ret;
}
static command_t CommandTable[] = {
@ -175,7 +138,7 @@ static command_t CommandTable[] = {
*/
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
PrintAndLogEx(NORMAL, "This is a feature to run Lua-scripts. You can place lua-scripts within the scripts/-folder. ");
PrintAndLogEx(NORMAL, "This is a feature to run Lua-scripts. You can place Lua-scripts within the luascripts/-folder. ");
return 0;
}

View file

@ -0,0 +1,6 @@
#!/usr/bin/env -S pm3 -s
mem load f mfc_default_keys m
mem load f t55xx_default_pwds t
mem load f iclass_default_keys i
lf t55xx deviceconfig z p

View file

@ -22,6 +22,7 @@
#include "crypto/libpcrypto.h" // sha512hash
#include "emv/dump.h"
#include "ui.h"
#include "fileutils.h"
static int CmdHelp(const char *Cmd);
@ -68,7 +69,7 @@ static int usage_sm_upgrade(void) {
PrintAndLogEx(NORMAL, " f <filename> : firmware file name");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " sc upgrade f ../tools/simmodule/SIM011.BIN");
PrintAndLogEx(NORMAL, " sc upgrade f ../tools/simmodule/sim011.bin");
return 0;
}
static int usage_sm_setclock(void) {
@ -92,33 +93,35 @@ static int usage_sm_brute(void) {
return 0;
}
static int smart_loadjson(const char *preferredName, const char *suffix, json_t **root) {
static int smart_loadjson(const char *preferredName, json_t **root) {
json_error_t error;
if (preferredName == NULL) return 1;
if (suffix == NULL) return 1;
int retval = 0;
int size = sizeof(char) * (strlen(get_my_executable_directory()) + strlen(preferredName) + strlen(suffix) + 10);
char *fileName = calloc(size, sizeof(char));
sprintf(fileName, "%s%s.%s", get_my_executable_directory(), preferredName, suffix);
*root = json_load_file(fileName, 0, &error);
char *path;
int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, ".json", false);
if (res != PM3_SUCCESS) {
return PM3_EFILE;
}
int retval = PM3_SUCCESS;
*root = json_load_file(path, 0, &error);
if (!*root) {
PrintAndLogEx(ERR, "json (%s) error on line %d: %s", fileName, error.line, error.text);
retval = 2;
PrintAndLogEx(ERR, "json (%s) error on line %d: %s", path, error.line, error.text);
retval = PM3_ESOFT;
goto out;
}
if (!json_is_array(*root)) {
PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", fileName);
retval = 3;
PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", path);
retval = PM3_ESOFT;
goto out;
}
PrintAndLogEx(SUCCESS, "Loaded file (%s) OK.", fileName);
PrintAndLogEx(SUCCESS, "Loaded file (%s) OK.", path);
out:
free(fileName);
free(path);
return retval;
}
@ -1035,7 +1038,7 @@ static int CmdSmartBruteforceSFI(const char *Cmd) {
PrintAndLogEx(INFO, "Importing AID list");
json_t *root = NULL;
smart_loadjson("aidlist", "json", &root);
smart_loadjson("aidlist", &root);
uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
if (!buf)

View file

@ -16,7 +16,7 @@
#include "parity.h" // oddparity
#include "cmdhflist.h" // annotations
#include "comms.h" // for sending cmds to device. GetFromBigBuf
#include "loclass/fileutils.h" // for saveFile
#include "fileutils.h" // for saveFile
static int CmdHelp(const char *Cmd);
@ -294,6 +294,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
uint8_t parityBits = parityBytes[j >> 3];
if (protocol != LEGIC
&& protocol != ISO_14443B
&& protocol != ISO_15693
&& protocol != ICLASS
&& protocol != ISO_7816_4
&& protocol != PROTO_HITAG
&& protocol != THINFILM
@ -301,7 +303,18 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
&& (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) {
snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]);
} else {
} else if ( protocol == ICLASS && isResponse == false) {
uint8_t parity = 0;
for (int i=0; i<6; i++) {
parity ^= ((frame[0] >> i) & 1);
}
if ( parity == ((frame[0] >> 7) & 1)) {
snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]);
} else {
snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x! ", frame[j]);
}
} else {
snprintf(line[j / 18] + ((j % 18) * 4), 110, "%02x ", frame[j]);
}

View file

@ -763,8 +763,8 @@ static int CmdUsartRXhex(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"btpin", CmdUsartBtPin, IfPm3FpcUsartHostFromUsb, "Change BT add-on PIN"},
{"btfactory", CmdUsartBtFactory, IfPm3FpcUsartHostFromUsb, "Reset BT add-on to factory settings"},
{"btpin", CmdUsartBtPin, IfPm3FpcUsartFromUsb, "Change BT add-on PIN"},
{"btfactory", CmdUsartBtFactory, IfPm3FpcUsartFromUsb, "Reset BT add-on to factory settings"},
{"tx", CmdUsartTX, IfPm3FpcUsartDevFromUsb, "Send string over USART"},
{"rx", CmdUsartRX, IfPm3FpcUsartDevFromUsb, "Receive string over USART"},
{"txrx", CmdUsartTXRX, IfPm3FpcUsartDevFromUsb, "Send string over USART and wait for response"},

View file

@ -25,6 +25,8 @@
#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, " ");}
@ -235,25 +237,17 @@ static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag *
static char *asn1_oid_description(const char *oid, bool with_group_desc) {
json_error_t error;
json_t *root = NULL;
char fname[300] = {0};
static char res[300];
memset(res, 0x00, sizeof(res));
size_t len = strlen(get_my_executable_directory());
if (len >= 300) len = 299;
strncpy(fname, get_my_executable_directory(), len);
strcat(fname, "crypto/oids.json");
if (access(fname, F_OK) < 0) {
strncpy(fname, get_my_executable_directory(), len);
strcat(fname, "oids.json");
if (access(fname, F_OK) < 0) {
goto error; // file not found
}
char *path;
if (searchFile(&path, RESOURCES_SUBDIR, "oids", ".json", false) != PM3_SUCCESS) {
return NULL;
}
// load `oids.json`
root = json_load_file(fname, 0, &error);
root = json_load_file(path, 0, &error);
free(path);
if (!root || !json_is_object(root)) {
goto error;

View file

@ -1,11 +0,0 @@
#
# iClass Default Keys
# -- iceman fork version --
# -- contribute to this list, sharing is caring --
AEA684A6DAB23278 -- AA1
7665544332211000 -- key1/Kc from PicoPass 2k documentation
0123456789ABCDEF -- SAGEM
5b7c62c491c11b39 -- from loclass demo file.
F0E1D2C3B4A59687 -- Kd from PicoPass 2k documentation
5CBCF1DA45D5FB4F -- PicoPass Default Exchange Key
31ad7ebd2f282168 -- From HID multiclassSE reader

View file

@ -1,966 +0,0 @@
#
# Mifare Default Keys
# -- iceman fork version --
# -- contribute to this list, sharing is caring --
#
ffffffffffff,//Defaultkey(firstkeyusedbyprogramifnouserdefinedkey)
000000000000,//Blankkey
a0a1a2a3a4a5,//NFCForumMADkey
b0b1b2b3b4b5,
c0c1c2c3c4c5,
d0d1d2d3d4d5,
aabbccddeeff,
4d3a99c351dd,
1a982c7e459a,
d3f7d3f7d3f7,// key A Wien
5a1b85fce20a,// key B Wien
714c5c886e97,
587ee5f9350f,
a0478cc39091,
533cb6c723f6,
8fd0a4f256e9,
#
d2ece8b9395e, //lib
#
# more Keys from mf_default_keys.lua
000000000001,
000000000002,
00000000000a,
00000000000b,
00000ffe2488,--VästtrafikenKeyB
010203040506,
0123456789ab,
0297927c0f77,--VästtrafikenKeyA
100000000000,
111111111111,
123456789abc,
12f2ee3478c1,
14d446e33363,
1999a3554a55,
200000000000,
222222222222,
26940b21ff5d,--RKFSLKeyA
27dd91f1fcf1,
2BA9621E0A36,--DirectoryandeventlogKeyB
333333333333,
33f974b42769,
34d1df9934c5,
434f4d4d4f41,--RKFJOJOGROUPKeyA
434f4d4d4f42,--RKFJOJOGROUPKeyB
43ab19ef5c31,
444444444444,
47524f555041,--RKFJOJOGROUPKeyA
47524f555042,--RKFJOJOGROUPKeyB
4AF9D7ADEBE4,--DirectoryandeventlogKeyA
4b0b20107ccb,--TNP3xxx
505249564141,--RKFJOJOPRIVAKeyA
505249564142,--RKFJOJOPRIVAKeyB
505249565441,
505249565442,
54726176656c,--VästtrafikenKeyA
555555555555,
55f5a5dd38c9,
569369c5a0e5,--kiev
5c598c9c58b5,--RKFSLKeyB
632193be1c3c,--kiev
644672bd4afe,--kiev
666666666666,
722bfcc5375f,--RKFRejskortDanmarkKeyA
776974687573,--VästtrafikenKeyB
777777777777,
888888888888,
8fe644038790,--kiev
999999999999,
99c636334433,
9de89e070277,--kiev
a00000000000,
a053a292a4af,
a64598a77478,--RKFSLKeyA
a94133013401,
aaaaaaaaaaaa,
abcdef123456,--Keyfromladyada.net
b00000000000,
b127c6f41436,
b5ff67cba951,--kiev
bbbbbbbbbbbb,
bd493a3962b6,
c934fe34d934,
cccccccccccc,
dddddddddddd,
e4d2770a89be,--RKFSLKeyB
ee0042f88840,--VästtrafikenKeyB
eeeeeeeeeeee,
eff603e1efe9,--kiev
f14ee7cae863,--kiev
f1a97341a9fc,
f1d83f964314,--RKFRejskortDanmarkKeyB
fc00018778f7,--VästtrafikenKeyA, RKFÖstgötaTrafikenKeyA
44ab09010845,-- hotel system
85fed980ea5a,-- hotel system
314B49474956 --VIGIK1 A
564c505f4d41 --VIGIK1 B
ba5b895da162 --VIGIK1 B
# Vigik mystery Keys Mifare 1k EV1 (S50)
5c8ff9990da2, 16 A
75ccb59c9bed, 17 A
d01afeeb890a, 16 B
4b791bea7bcc, 17 B
#
4143414F5250,
a9b43414F585,--Tehran Railway
1FB235AC1388,--Tehran Railway
#
# Data from: http://irq5.io/2013/04/13/decoding-bcard-conference-badges/
f4a9ef2afc6d,--BCARD KeyB
#
# Data from: ...
89eac97f8c2a // S0 B
43c7600dee6b // S4 A
0120bf672a64 // S6 A
fb0b20df1f34 // S6 B
#
a9f953def0a3,
#
# Here be BIP keys...
3A42F33AF429,
1FC235AC1309,
6338A371C0ED,
243F160918D1,
F124C2578AD0,
9AFC42372AF1,
32AC3B90AC13,
682D401ABB09,
4AD1E273EAF1,
067DB45454A9,
E2C42591368A,
15FC4C7613FE,
2A3C347A1200,
68D30288910A,
16F3D5AB1139,
F59A36A2546D,
937A4FFF3011,
64E3C10394C2,
35C3D2CAEE88,
B736412614AF,
693143F10368,
324F5DF65310,
A3F97428DD01,
643FB6DE2217,
63F17A449AF0,
82F435DEDF01,
C4652C54261C,
0263DE1278F3,
D49E2826664F,
51284C3686A6,
3DF14C8000A1,
6A470D54127C,
#
# Data from: http://pastebin.com/AK9Bftpw
48ffe71294a0, -- Länstrafiken i Västerbotten
e3429281efc1, -- Länstrafiken i Västerbotten
16f21a82ec84, -- Länstrafiken i Västerbotten
460722122510, -- Länstrafiken i Västerbotten
#
# 3dprinter
AAFB06045877, --EPI Envisionte# 3dprinter
#
# gym
3e65e4fb65b3, --Fysiken A
25094df6f148, --Fysiken B
a05dbd98e0fc, -- CleverFit
#
d3b595e9dd63, -- Hotel KeyCard
afbecd121004, -- Hotel KeyCard
6471a5ef2d1a, -- SimonsVoss
#
# 24-7
D21762B2DE3B,
0E83A374B513,
1F1FFE000000,
A10F303FC879,
1322285230b8,
0C71BCFB7E72,
C3C88C6340B8,
F101622750B7,
1F107328DC8D,
710732200D34,
7C335FB121B5,
B39AE17435DC,
#
#
454841585443, -- key A
#
# Data from: http://pastebin.com/gQ6nk38G
D39BB83F5297,
85675B200017,
528C9DFFE28C,
C82EC29E3235,
3E3554AF0E12,
491CDCFB7752,
22C1BAE1AACD,
5F146716E373,
740E9A4F9AAF,
AC0E24C75527,
97184D136233,
E444D53D359F,
17758856B182,
A8966C7CC54B,
C6AD00254562,
AE3FF4EEA0DB,
5EB8F884C8D1,
FEE470A4CB58,
75D8690F21B6,
871B8C085997,
97D1101F18B0,
75EDE6A84460,
DF27A8F1CB8E,
B0C9DD55DD4D,
#
# Data from: http://bit.ly/1bdSbJl
A0B0C0D0E0F0,
A1B1C1D1E1F1,
#
# Data from: msk social
2735fc181807,
2aba9519f574,
84fd7f7a12b6,
186d8c4b93f9,
3a4bba8adaf0,
8765b17968a2,
40ead80721ce,
0db5e6523f7c,
51119dae5216,
83e3549ce42d,
136bdb246cac,
7de02a7f6025,
bf23a53c1f63,
cb9a1f2d7368,
c7c0adb3284f,
9f131d8c2057,
67362d90f973,
6202a38f69e2,
100533b89331,
653a87594079,
d8a274b2e026,
b20b83cb145c,
9afa6cb4fc3d,
#
# Data from http://pastebin.com/RRJUEDCM
0d258fe90296,
e55a3ca71826,
a4f204203f56,
eeb420209d0c,
911e52fd7ce4,
752fbb5b7b45,
66b03aca6ee9,
48734389edc3,
17193709adf4,
1acc3189578c,
c2b7ec7d4eb1,
369a4663acd2,
#
# Data from https://github.com/zhangjingye03/zxcardumper
# zxcard Key A/B
668770666644,
003003003003,
#
# Data from: http://phreakerclub.com/forum/showthread.php?p=41266
26973ea74321,
71f3a315ad26,
51044efb5aab,
ac70ca327a04,
eb0a8ff88ade,
#
# Data from: https://github.com/RadioWar/NFCGUI
44dd5a385aaf,
21a600056cb0,
b1aca33180a5,
dd61eb6bce22,
1565a172770f,
3e84d2612e2a,
f23442436765,
79674f96c771,
87df99d496cb,
c5132c8980bc,
a21680c27773,
f26e21edcee2,
675557ecc92e,
f4396e468114,
6db17c16b35b,
4186562a5bb2,
2feae851c199,
db1a3338b2eb,
157b10d84c6b,
a643f952ea57,
df37dcb6afb3,
4c32baf326e0,
91ce16c07ac5,
3c5d1c2bcd18,
c3f19ec592a2,
f72a29005459,
185fa3438949,
321a695bd266,
d327083a60a7,
45635ef66ef3,
5481986d2d62,
cba6ae869ad5,
645a166b1eeb,
a7abbc77cc9e,
f792c4c76a5c,
bfb6796a11db,
#
# Data from Salto A/B
6A1987C40A21,
7F33625BC129,
#
# Data from forum
2338b4913111,
#
# Data from stoye
cb779c50e1bd,
a27d3804c259,
003cc420001a,
f9861526130f,
381ece050fbd,
a57186bdd2b9,
48c739e21a04,
36abf5874ed7,
649d2abbbd20,
bbe8fffcf363,
ab4e7045e97d,
340e40f81cd8,
e4f65c0ef32c,
d2a597d76936,
a920f32fe93a,
86afd95200f7,
9b832a9881ff,
26643965b16e,
0c669993c776,
b468d1991af9,
d9a37831dce5,
2fc1f32f51b1,
0ffbf65b5a14,
c5cfe06d9ea3,
c0dece673829,
#
a56c2df9a26d,
#
# Data from: https://pastebin.com/vbwast74
#
68d3f7307c89,
568c9083f71c,--Smart Rider. Western Australian Public Transport Cards
# Vigik Keys
# Various sources :
# * https://github.com/DumpDos/Vigik
# * http://newffr.com/viewtopic.php?&forum=235&topic=11559
# * Own dumps
021209197591, // BTCINO UNDETERMINED SPREAKD 0x01->0x13 key
2ef720f2af76,
414c41524f4e,
424c41524f4e,
4a6352684677,
bf1f4424af76,
536653644c65,
#
# Intratone Cogelec
# Data from http://bouzdeck.com/rfid/32-cloning-a-mifare-classic-1k-tag.html
484558414354,
a22ae129c013,
49fae4e3849f,
38fcf33072e0,
8ad5517b4b18,
509359f131b1,
6c78928e1317,
aa0720018738,
a6cac2886412,
62d0c424ed8e,
e64a986a5d94,
8fa1d601d0a2,
89347350bd36,
66d2b7dc39ef,
6bc1e1ae547d,
22729a9bd40f,
#
# Data from https://dfir.lu/blog/cloning-a-mifare-classic-1k-tag.html
925b158f796f,
fad63ecb5891,
bba840ba1c57,
cc6b3b3cd263,
6245e47352e6,
8ed41e8b8056,
2dd39a54e1f3,
6d4c5b3658d2,
1877ed29435a,
52264716efde,
961c0db4a7ed,
703140fd6d86,
157c9a513fa5,
e2a5dc8e066f,
#
# Data from a oyster card
374bf468607f,
bfc8e353af63,
15cafd6159f6,
62efd80ab715,
987a7f7f1a35,
c4104fa3c526,
4c961f23e6be,
67546972bc69,
f4cd5d4c13ff,
94414c1a07dc,
16551d52fd20,
9cb290282f7d,
77a84170b574,
ed646c83a4f3,
e703589db50b,
513c85d06cde,
95093f0b2e22,
543b01b27a95,
c6d375b99972,
ee4cc572b40e,
5106ca7e4a69,
c96bd1ce607f,
167a1be102e0,
a8d0d850a606,
a2abb693ce34,
7b296c40c486,
91f93a5564c9,
e10623e7a016,
b725f9cbf183,
#
# Data from FDi tag
8829da9daf76,
#
# Data from GitHub issue
0A7932DC7E65,
11428B5BCE06,
11428B5BCE07,
11428B5BCE08,
11428B5BCE09,
11428B5BCE0A,
11428B5BCE0F,
18971D893494,
25D60050BF6E,
3FA7217EC575,
44F0B5FBE344,
7B296F353C6B,
8553263F4FF0,
8E5D33A6ED51,
9F42971E8322,
C620318EF179,
D4FE03CE5B06,
D4FE03CE5B07,
D4FE03CE5B08,
D4FE03CE5B09,
D4FE03CE5B0A,
D4FE03CE5B0F,
E241E8AFCBAF,
#
# Data from forum post
123F8888F322,
050908080008,
#
# Data from hoist
4f9f59c9c875,
#
# Data from pastebin
66f3ed00fed7,
f7a39753d018,
#
# Data from https://pastebin.com/Z7pEeZif
386B4D634A65,
666E564F4A44,
564777315276,
476242304C53,
6A696B646631,
4D3248735131,
425A73484166,
57784A533069,
345547514B4D,
4C6B69723461,
4E4175623670,
4D5076656D58,
686A736A356E,
484A57696F4A,
6F4B6D644178,
744E326B3441,
70564650584F,
584F66326877,
6D4E334B6C48,
6A676C315142,
77494C526339,
623055724556,
356D46474348,
4E32336C6E38,
57734F6F6974,
436A46587552,
5544564E6E67,
6F506F493353,
31646241686C,
77646B633657,
#
# Data from TransPert
2031d1e57a3b,
53c11f90822a,
9189449ea24e,
#
# data from Github
410b9b40b872,
2cb1a90071c8,
#
# data from
8697389ACA26,
1AB23CD45EF6,
013889343891,
#
#
0000000018de,
16ddcb6b3f24,
#
# Data from https://pastebin.com/vwDRZW7d
EC0A9B1A9E06,--Vingcard Mifare 4k Staff card
6C94E1CED026,--Vingcard Mifare 4k Staff card
0F230695923F,--Vingcard Mifare 4k Staff card
0000014B5C31,--Vingcard Mifare 4k Staff card
#
BEDB604CC9D1,
B8A1F613CF3D,
B578F38A5C61,
B66AC040203A
6D0B6A2A0003
2E641D99AD5B
AD4FB33388BF,
69FB7B7CD8EE,
2A6D9205E7CA,
2a2c13cc242a,
27FBC86A00D0,
01FA3FC68349,
#
6D44B5AAF464,--Smart Rider. Western Australian Public Transport Cards
1717E34A7A8A,--Smart Rider. Western Australian Public Transport Cards
#
6B6579737472,--RFIDeas
#
484944204953,--HID MIFARE Classic 1k Key
204752454154,--HID MIFARE Classic 1k Key
3B7E4FD575AD,--HID MIFARE SO
11496F97752A,--HID MIFARE SO
#
415A54454B4D,--Luxeo/Aztek cashless vending
#
321958042333,--BQT
#
160A91D29A9C,--Aperio KEY_A Sector 1, 12, 13, 14, 15 Data Start 0 Length 48
#
b7bf0c13066e,--Gallagher
#
# Boston, MA, USA Transit - MBTA Charlie Card
3060206f5b0a,-- charlie
5ec39b022f2b,-- charlie
3a09594c8587,-- charlie
f1b9f5669cc8,-- charlie
f662248e7e89,-- charlie
62387b8d250d,-- charlie
f238d78ff48f,-- charlie
9dc282d46217,-- charlie
afd0ba94d624,-- charlie
92ee4dc87191,-- charlie
b35a0e4acc09,-- charlie
756ef55e2507,-- charlie
447ab7fd5a6b,-- charlie
932b9cb730ef,-- charlie
1f1a0a111b5b,-- charlie
ad9e0a1ca2f7,-- charlie
d58023ba2bdc,-- charlie
62ced42a6d87,-- charlie
2548a443df28,-- charlie
2ed3b15e7c0f,-- charlie
#
60012e9ba3fa,
#
de1fcbec764b,
81bfbe8cacba,
bff123126c9b,
2f47741062a0,
b4166b0a27ea,
a170d9b59f95,
400bc9be8976,
d80511fc2ab4,
1fcef3005bcf,
bb467463acd6,
e67c8010502d,
ff58ba1b4478,
# Data from https://pastebin.com/Kz8xp4ev
fbf225dc5d58,
#
# Data https://pastebin.com/BEm6bdAE
# vingcard.txt
4708111c8604,
3d50d902ea48,
96a301bce267,
6700f10fec09,
7a09cc1db70a,
560f7cff2d81,
66b31e64ca4b,
9e53491f685b,
3a09911d860c,
8a036920ac0c,
361f69d2c462,
d9bcde7fc489,
0c03a720f208,
6018522fac02,
#
# Data from https://pastebin.com/4t2yFMgt
# Mifare technische Universität Graz TUG
D58660D1ACDE,
50A11381502C,
C01FC822C6E5,
0854BF31111E,
# More keys:
8a19d40cf2b5,
ae8587108640,
135b88a94b8b, SafLock standalone door locks.
#
# Russian Troika card
08B386463229,
0E8F64340BA4,
0F1C63013DBA,
2AA05ED1856F,
2B7F3253FAC5,
69A32F1C2F19,
73068F118C13,
9BECDF3D9273,
A73F5DC1D333,
A82607B01C0D,
AE3D65A3DAD4,
CD4C61C26E3D,
D3EAFB5DF46D,
E35173494A81,
FBC2793D540B,
5125974CD391,
ECF751084A80,
7545DF809202,
AB16584C972A,
7A38E3511A38,
C8454C154CB5,
04C297B91308,
EFCB0E689DB3,
07894FFEC1D6,
FBA88F109B32,
2FE3CB83EA43,
B90DE525CEB6,
1CC219E9FEC1,
A74332F74994,
764CD061F1E6,
8F79C4FD8A01,
CD64E567ABCD,
CE26ECB95252,
ABA208516740,
9868925175BA,
16A27AF45407,
372CC880F216,
3EBCE0925B2F,
73E5B9D9D3A4,
0DB520C78C1C,
70D901648CB9,
C11F4597EFB5,
B39D19A280DF,
403D706BA880,
7038CD25C408,
6B02733BB6EC,
EAAC88E5DC99,
4ACEC1205D75,
2910989B6880,
31C7610DE3B0,
5EFBAECEF46B,
F8493407799D,
6B8BD9860763,
D3A297DC2698,
#
# Keys from MifareClassicTool project
044CE1872BC3,
045CECA15535,
0BE5FAC8B06A,
0CE7CD2CC72B,
0EB23CC8110B,
0F01CEFF2742,
0F318130ED18,
114D6BE9440C,
18E3A02B5EFF,
19FC84A3784B,
1B61B2E78C75,
22052B480D11,
3367BFAA91DB,
3A8A139C20B4,
42E9B54E51AB,
46D78E850A7E,
4B609876BBA3,
518DC6EEA089,
6B07877E2C5C,
7259FA0197C6,
72F96BDD3714,
7413B599C4EA,
77DABC9825E1,
7A396F0D633D,
7A86AA203788,
8791B2CCB5C4,
8A8D88151A00,
8C97CD7A0E56,
8E26E45E7D65,
9D993C5D4EF4,
9EA3387A63C1,
A3FAA6DAFF67,
A7141147D430,
AAFB06045877,
ACFFFFFFFFFF,
AFCEF64C9913,
B27ADDFB64B0,
B81F2B0C2F66,
B9F8A7D83978,
BAFF3053B496,
BB52F8CCE07F,
BC2D1791DEC1,
BC4580B7F20B,
C65D4EAA645B,
C76BF71A2509,
D5524F591EED,
E328A1C7156D,
E4821A377B75,
E56AC127DD45,
EA0FD73CB149,
FC0001877BF7,
FD8705E721B0,
00ada2cd516d,
#
#
D3F7D3F7D3F7
##
237a4d0d9119,
0ed7846c2bc9,
FFFFD06F83E3,
FFFFAE82366C,
F89C86B2A961,
F83466888612,
ED3A7EFBFF56,
E96246531342,
E1DD284379D4,
DFED39FFBB76,
DB5181C92CBE,
CFC738403AB0,
BCFE01BCFE01,
BA28CFD15EE8,
B0699AD03D17,
AABBCC660429,
A4EF6C3BB692,
A2B2C9D187FB,
9B1DD7C030A1,
9AEDF9931EC1,
8F9B229047AC,
872B71F9D15A,
833FBD3CFE51,
5D293AFC8D7E,
5554AAA96321,
474249437569,
435330666666,
1A2B3C4D5E6F,
123456ABCDEF,
83BAB5ACAD62,
64E2283FCF5E,
64A2EE93B12B,
46868F6D5677,
40E5EA1EFC00,
37D4DCA92451,
2012053082AD,
2011092119F1,
200306202033,
1795902DBAF9,
17505586EF02,
022FE48B3072,
013940233313,
#
# Hotel Adina
9EBC3EB37130,
#
# mostlikely diverised individual keys.
# data from: https://github.com/korsehindi/proxmark3/commit/24fdbfa9a1d5c996aaa5c192bc07e4ab28db4c5c
491CDC863104,
A2F63A485632,
98631ED2B229,
19F1FFE02563,
563A22C01FC8, -- Argentina
43CA22C13091, -- Argentina
25094DF2C1BD, -- Argentina
#
# OMNITEC.ES HOTEL TIMECARD / MAINTENANCECARD
AFBECD120454,
#
# OMNITEC.ES HOTEL EMERGENCYCARD
842146108088,
#
# TAPCARD PUBLIC TRANSPORT LA
#
EA1B88DF0A76,
D1991E71E2C5,
05F89678CFCF,
D31463A7AB6D,
C38197C36420,
772219470B38,
1C1532A6F1BC,
FA38F70215AD,
E907470D31CC,
160F4B7AB806,
1D28C58BBE8A,
B3830B95CA34,
6A0E215D1EEB,
E41E6199318F,
C4F271F5F0B3,
1E352F9E19E5,
0E0E8C6D8EB6,
C342F825B01B,
CB911A1A1929,
E65B66089AFC,
B81846F06EDF,
37FC71221B46,
880C09CFA23C,
6476FA0746E7,
419A13811554,
2C60E904539C,
4ECCA6236400,
10F2BBAA4D1C,
4857DD68ECD9,
C6A76CB2F3B5,
E3AD9E9BA5D4,
6C9EC046C1A4,
#
# ROC HIGHSCHOOL ACCESSCARD
#
B021669B44BB,
B18CDCDE52B7,
A22647F422AE,
B268F7C9CA63,
A37A30004AC9,
B3630C9F11C8,
A4CDFF3B1848,
B42C4DFD7A90,
A541538F1416,
B5F454568271,
A6C028A12FBB,
B6323F550F54,
A7D71AC06DC2,
B7C344A36D88,
A844F4F52385,
B8457ACC5F5D,
A9A4045DCE77,
B9B8B7B6B5B3,
AA4D051954AC,
BA729428E808,
AB28A44AD5F5,
BB320A757099,
AC45AD2D620D,
BCF5A6B5E13F,
AD5645062534,
BDF837787A71,
AE43F36C1A9A,
BE7C4F6C7A9A,
5EC7938F140A,
82D58AA49CCB,
#
# MELONCARD
#
323334353637,
#
#
CEE3632EEFF5,
827ED62B31A7,
03EA4053C6ED,
C0BEEFEC850B,
F57F410E18FF,
0AF7DB99AEE4,
A7FB4824ACBF,
207FFED492FD,
1CFA22DBDFC3,
30FFB6B056F5,
39CF885474DD,
00F0BD116D70,
4CFF128FA3EF,
10F3BEBC01DF,
#
# Transportes Insular La Palma
#
0172066b2f03,
0000085f0000,
1a80b93f7107,
70172066b2f0,
b1a80c94f710,
0b0172066b2f,
0f1a81c95071,
f0f0172066b2,
1131a81d9507,
2f130172066b,
71171a82d951,
b2f170172066,
1711b1a82e96,
6b2f1b017206,
62711f1a83e9,
66b2f1f01720,
97271231a83f,
066b2f230172,
f97371271a84,
2066b2f27017,
50983712b1a8,
72066b2f2b01,
850984712f1a,
172066b2f2f0,
a85198481331,
0172066b2f33,
1a8619858137,
70172066b2f3,
b1a862985913,
3b0172066b2f,
3f1a87298691,
f3f0172066b2,
#
# Tehran ezpay
#
38A88AEC1C43
CBD2568BC7C6
7BCB4774EC8F
22ECE9316461
AE4B497A2527
EEC0626B01A1
2C71E22A32FE
91142568B22F
7D56759A974A
D3B1C7EA5C53
41C82D231497
0B8B21C692C2
604Ac8D87C7E
8E7B29460F12
BB3D7B11D224
#
# Chaco
#
b210cfa436d2
b8b1cfa646a8
a9f95891f0a4
#
# Keys from APK application "Scan Badge"
4A4C474F524D
444156494442
434143445649
434456495243
A00002000021
EF61A3D48E2A
A23456789123
010000000000
363119000001
A00003000084
675A32413770
395244733978
A0004A000036
2C9F3D45BA13
4243414F5250
DFE73BE48AC6
#
B069D0D03D17
000131B93F28

View file

@ -1,123 +0,0 @@
# known cloners
# ref. http://www.proxmark.org/forum/viewtopic.php?id=2022
51243648,
000D8787,
19920427,
65857569, //chinese "handheld RFID writer" blue cloner from circa 2013 (also sold by xfpga.com)
# ref. http://kazus.ru/forums/showpost.php?p=1045937&postcount=77
05D73B9F,
# ref. http://www.proxmark.org/forum/viewtopic.php?=
89A69E60,
# ref lock
314159E0,
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=28115#p28115
AA55BBBB,
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=33376#p33376
A5B4C3D2,
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=30379#p30379
1C0B5848,
# http://www.proxmark.org/forum/viewtopic.php?pid=35075#p35075
00434343,
44B44CAE,
88661858,
# paxton bullit?
575F4F4B,
#
50520901,
# Default pwd, simple:
00000000,
11111111,
22222222,
33333333,
44444444,
55555555,
66666666,
77777777,
88888888,
99999999,
AAAAAAAA,
BBBBBBBB,
CCCCCCCC,
DDDDDDDD,
EEEEEEEE,
FFFFFFFF,
a0a1a2a3,
b0b1b2b3,
aabbccdd,
bbccddee,
ccddeeff,
50415353,
00000001,
00000002,
0000000a,
0000000b,
01020304,
02030405,
03040506,
04050607,
05060708,
06070809,
0708090A,
08090A0B,
090A0B0C,
0A0B0C0D,
0B0C0D0E,
0C0D0E0F,
01234567,
12345678,
10000000,
20000000,
30000000,
40000000,
50000000,
60000000,
70000000,
80000000,
90000000,
A0000000,
B0000000,
C0000000,
D0000000,
E0000000,
F0000000,
10101010,
01010101,
11223344,
22334455,
33445566,
44556677,
55667788,
66778899,
778899AA,
8899AABB,
99AABBCC,
AABBCCDD,
BBCCDDEE,
CCDDEEFF,
0CB7E7FC, //rfidler?
FABADA11, //china?
# 20 most common len==8
87654321,
12341234,
69696969,
12121212,
12344321,
1234ABCD,
11112222,
13131313,
10041004,
#
31415926, //pii
abcd1234,
20002000,
19721972,
aa55aa55, // amiboo
55aa55aa, // rev amiboo
4f271149, // seeds ul-ev1
07d7bb0b, // seeds ul-ev1
9636ef8f, // seeds ul-ev1
b5f44686, // seeds ul-ev1
9E3779B9, // TEA
C6EF3720, // TEA
7854794A, // xbox tea constant :)
F1EA5EED, // burtle

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,12 @@
#
# iClass Default Keys
# -- iceman fork version --
# -- contribute to this list, sharing is caring --
#
AEA684A6DAB23278 # AA1
7665544332211000 # key1/Kc from PicoPass 2k documentation
0123456789ABCDEF # SAGEM
5b7c62c491c11b39 # from loclass demo file.
F0E1D2C3B4A59687 # Kd from PicoPass 2k documentation
5CBCF1DA45D5FB4F # PicoPass Default Exchange Key
31ad7ebd2f282168 # From HID multiclassSE reader

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,57 @@
010203040506
013940233313
022FE48B3072
123456789ABC
123456ABCDEF
17505586EF02
1795902DBAF9
1A2B3C4D5E6F
1A982C7E459A
200306202033
2011092119F1
2012053082AD
37D4DCA92451
40E5EA1EFC00
435330666666
46868F6D5677
474249437569
4D3A99C351DD
533CB6C723F6
5554AAA96321
587EE5F9350F
5A1B85FCE20A
5D293AFC8D7E
64A2EE93B12B
64E2283FCF5E
714C5C886E97
833FBD3CFE51
83BAB5ACAD62
872B71F9D15A
8F9B229047AC
8FD0A4F256E9
9AEDF9931EC1
9B1DD7C030A1
A0478CC39091
A0A1A2A3A4A5
A2B2C9D187FB
A4EF6C3BB692
AABBCC660429
AABBCCDDEEFF
ABCDEF123456
B0699AD03D17
B0B1B2B3B4B5
BA28CFD15EE8
BCFE01BCFE01
C0C1C2C3C4C5
CFC738403AB0
D0D1D2D3D4D5
D3F7D3F7D3F7
DB5181C92CBE
DFED39FFBB76
E1DD284379D4
E96246531342
ED3A7EFBFF56
F83466888612
F89C86B2A961
FFFFAE82366C
FFFFD06F83E3

View file

@ -2,4 +2,5 @@
# Mifare Ultralight Default Keys
# -- iceman fork version --
# -- contribute to this list, sharing is caring --
425245414B4D454946594F5543414E21 -- Sample Key (BREAKMEIFYOUCAN!)
#
425245414B4D454946594F5543414E21 # Sample Key (BREAKMEIFYOUCAN!)

View file

@ -1,57 +0,0 @@
010203040506,
013940233313,
022FE48B3072,
123456789ABC,
123456ABCDEF,
17505586EF02,
1795902DBAF9,
1A2B3C4D5E6F,
1A982C7E459A,
200306202033,
2011092119F1,
2012053082AD,
37D4DCA92451,
40E5EA1EFC00,
435330666666,
46868F6D5677,
474249437569,
4D3A99C351DD,
533CB6C723F6,
5554AAA96321,
587EE5F9350F,
5A1B85FCE20A,
5D293AFC8D7E,
64A2EE93B12B,
64E2283FCF5E,
714C5C886E97,
833FBD3CFE51,
83BAB5ACAD62,
872B71F9D15A,
8F9B229047AC,
8FD0A4F256E9,
9AEDF9931EC1,
9B1DD7C030A1,
A0478CC39091,
A0A1A2A3A4A5,
A2B2C9D187FB,
A4EF6C3BB692,
AABBCC660429,
AABBCCDDEEFF,
ABCDEF123456,
B0699AD03D17,
B0B1B2B3B4B5,
BA28CFD15EE8,
BCFE01BCFE01,
C0C1C2C3C4C5,
CFC738403AB0,
D0D1D2D3D4D5,
D3F7D3F7D3F7,
DB5181C92CBE,
DFED39FFBB76,
E1DD284379D4,
E96246531342,
ED3A7EFBFF56,
F83466888612,
F89C86B2A961,
FFFFAE82366C,
FFFFD06F83E3,

View file

@ -0,0 +1,123 @@
# known cloners
# ref. http://www.proxmark.org/forum/viewtopic.php?id=2022
51243648
000D8787
19920427
65857569 //chinese "handheld RFID writer" blue cloner from circa 2013 (also sold by xfpga.com)
# ref. http://kazus.ru/forums/showpost.php?p=1045937&postcount=77
05D73B9F
# ref. http://www.proxmark.org/forum/viewtopic.php?=
89A69E60
# ref lock
314159E0
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=28115#p28115
AA55BBBB
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=33376#p33376
A5B4C3D2
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=30379#p30379
1C0B5848
# ref. http://www.proxmark.org/forum/viewtopic.php?pid=35075#p35075
00434343
44B44CAE
88661858
# paxton bullit?
575F4F4B
#
50520901
# Default pwd, simple:
00000000
11111111
22222222
33333333
44444444
55555555
66666666
77777777
88888888
99999999
AAAAAAAA
BBBBBBBB
CCCCCCCC
DDDDDDDD
EEEEEEEE
FFFFFFFF
a0a1a2a3
b0b1b2b3
aabbccdd
bbccddee
ccddeeff
50415353
00000001
00000002
0000000a
0000000b
01020304
02030405
03040506
04050607
05060708
06070809
0708090A
08090A0B
090A0B0C
0A0B0C0D
0B0C0D0E
0C0D0E0F
01234567
12345678
10000000
20000000
30000000
40000000
50000000
60000000
70000000
80000000
90000000
A0000000
B0000000
C0000000
D0000000
E0000000
F0000000
10101010
01010101
11223344
22334455
33445566
44556677
55667788
66778899
778899AA
8899AABB
99AABBCC
AABBCCDD
BBCCDDEE
CCDDEEFF
0CB7E7FC # rfidler?
FABADA11 # china?
# 20 most common len==8
87654321
12341234
69696969
12121212
12344321
1234ABCD
11112222
13131313
10041004
#
31415926 # pii
abcd1234
20002000
19721972
aa55aa55 # amiboo
55aa55aa # rev amiboo
4f271149 # seeds ul-ev1
07d7bb0b # seeds ul-ev1
9636ef8f # seeds ul-ev1
b5f44686 # seeds ul-ev1
9E3779B9 # TEA
C6EF3720 # TEA
7854794A # xbox tea constant :)
F1EA5EED # burtle

View file

@ -232,7 +232,7 @@ static int CmdEMVGPO(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("kK", "keep", "keep field ON for next command"),
arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for PDOLdata making from PDOL and parameters"),
arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for PDOLdata making from PDOL and parameters"),
arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (by default uses default parameters)"),
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
@ -398,7 +398,7 @@ static int CmdEMVAC(const char *Cmd) {
arg_lit0("kK", "keep", "keep field ON for next command"),
arg_lit0("cC", "cda", "executes CDA transaction. Needs to get SDAD in results."),
arg_str0("dD", "decision", "<aac|tc|arqc>", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"),
arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for CDOLdata making from CDOL and parameters"),
arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for CDOLdata making from CDOL and parameters"),
arg_lit0("mM", "make", "make CDOLdata from CDOL (tag 8C and 8D) and parameters (by default uses default parameters)"),
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
@ -564,7 +564,7 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) {
void *argtable[] = {
arg_param_begin,
arg_lit0("kK", "keep", "keep field ON for next command"),
arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for DDOLdata making from DDOL and parameters"),
arg_lit0("pP", "params", "load parameters from `emv_defparams.json` file for DDOLdata making from DDOL and parameters"),
arg_lit0("mM", "make", "make DDOLdata from DDOL (tag 9F49) and parameters (by default uses default parameters)"),
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
@ -785,7 +785,7 @@ static int CmdEMVExec(const char *Cmd) {
arg_lit0("sS", "select", "activate field and select card."),
arg_lit0("aA", "apdu", "show APDU reqests and responses."),
arg_lit0("tT", "tlv", "TLV decode results."),
arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."),
arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file."),
arg_lit0("fF", "forceaid", "Force search AID. Search AID instead of execute PPSE."),
arg_rem("By default:", "Transaction type - MSD"),
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
@ -1376,7 +1376,7 @@ static int CmdEMVScan(const char *Cmd) {
arg_lit0("aA", "apdu", "show APDU reqests and responses."),
arg_lit0("tT", "tlv", "TLV decode results."),
arg_lit0("eE", "extract", "Extract TLV elements and fill Application Data"),
arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."),
arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file."),
arg_rem("By default:", "Transaction type - MSD"),
arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),

View file

@ -29,6 +29,8 @@
#include "ui.h"
#include "crypto.h"
#include "proxmark3.h"
#include "fileutils.h"
#include "pm3_cmd.h"
#define BCD(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \
-1)
@ -483,13 +485,12 @@ struct emv_pk *emv_pk_get_ca_pk(const unsigned char *rid, unsigned char idx) {
}
}
*/
const char *relfname = "emv/capk.txt";
char fname[strlen(get_my_executable_directory()) + strlen(relfname) + 1];
strcpy(fname, get_my_executable_directory());
strcat(fname, relfname);
pk = emv_pk_get_ca_pk_from_file(fname, rid, idx);
char *path;
if (searchFile(&path, RESOURCES_SUBDIR, "capk", ".txt", false) != PM3_SUCCESS) {
return NULL;
}
pk = emv_pk_get_ca_pk_from_file(path, rid, idx);
free(path);
if (!pk)
return NULL;

View file

@ -401,11 +401,11 @@ static const struct emv_tag emv_tags[] = {
{ 0xdf811b, "Kernel Configuration", EMV_TAG_GENERIC, NULL },
{ 0xdf811c, "Max Lifetime of Torn Transaction Log Record", EMV_TAG_GENERIC, NULL },
{ 0xdf811d, "Max Number of Torn Transaction Log Records", EMV_TAG_GENERIC, NULL },
{ 0xdf811e, "Mag-stripe CVM Capability CVM Required", EMV_TAG_GENERIC, NULL },
{ 0xdf811e, "Mag-stripe CVM Capability - CVM Required", EMV_TAG_GENERIC, NULL },
{ 0xdf811f, "Security Capability", EMV_TAG_GENERIC, NULL },
{ 0xdf8120, "Terminal Action Code Default", EMV_TAG_GENERIC, NULL },
{ 0xdf8121, "Terminal Action Code Denial", EMV_TAG_GENERIC, NULL },
{ 0xdf8122, "Terminal Action Code Online", EMV_TAG_GENERIC, NULL },
{ 0xdf8120, "Terminal Action Code - Default", EMV_TAG_GENERIC, NULL },
{ 0xdf8121, "Terminal Action Code - Denial", EMV_TAG_GENERIC, NULL },
{ 0xdf8122, "Terminal Action Code - Online", EMV_TAG_GENERIC, NULL },
{ 0xdf8123, "Reader Contactless Floor Limit", EMV_TAG_GENERIC, NULL },
{ 0xdf8124, "Reader Contactless Transaction Limit (No On-device CVM)", EMV_TAG_GENERIC, NULL },
{ 0xdf8125, "Reader Contactless Transaction Limit (On-device CVM)", EMV_TAG_GENERIC, NULL },
@ -415,7 +415,7 @@ static const struct emv_tag emv_tags[] = {
{ 0xdf8129, "Outcome Parameter Set", EMV_TAG_GENERIC, NULL },
{ 0xdf812a, "DD Card (Track1)", EMV_TAG_GENERIC, NULL },
{ 0xdf812b, "DD Card (Track2)", EMV_TAG_GENERIC, NULL },
{ 0xdf812c, "Mag-stripe CVM Capability No CVM Required", EMV_TAG_GENERIC, NULL },
{ 0xdf812c, "Mag-stripe CVM Capability - No CVM Required", EMV_TAG_GENERIC, NULL },
{ 0xdf812d, "Message Hold Time", EMV_TAG_GENERIC, NULL },
{ 0xff8101, "Torn Record", EMV_TAG_GENERIC, NULL },

View file

@ -17,6 +17,8 @@
#include "util.h"
#include "proxmark3.h"
#include "emv_tags.h"
#include "fileutils.h"
#include "pm3_cmd.h"
static const ApplicationDataElm ApplicationData[] = {
{0x82, "AIP"},
@ -303,13 +305,12 @@ bool ParamLoadFromJson(struct tlvdb *tlv) {
return false;
}
// current path + file name
const char *relfname = "emv/defparams.json";
char fname[strlen(get_my_executable_directory()) + strlen(relfname) + 1];
strcpy(fname, get_my_executable_directory());
strcat(fname, relfname);
root = json_load_file(fname, 0, &error);
char *path;
if (searchFile(&path, RESOURCES_SUBDIR, "emv_defparams", ".json", false) != PM3_SUCCESS) {
return false;
}
root = json_load_file(path, 0, &error);
free(path);
if (!root) {
PrintAndLogEx(ERR, "Load params: json error on line " _YELLOW_("%d") ": %s", error.line, error.text);
return false;

View file

@ -58,7 +58,13 @@ int ExecuteCryptoTests(bool verbose) {
res = mbedtls_entropy_self_test(verbose);
if (res) TestFail = true;
res = mbedtls_timing_self_test(verbose);
// retry for CI (when resources too low)
for (int i = 0; i < 3; i++) {
res = mbedtls_timing_self_test(verbose);
if (!res)
break;
PrintAndLogEx(WARNING, "Repeat timing test %d", i + 1);
}
if (res) TestFail = true;
res = mbedtls_ctr_drbg_self_test(verbose);

View file

@ -36,6 +36,7 @@
// Name: Yubico U2F Root CA Serial 457200631
// Issued: 2014-08-01
// https://github.com/Yubico/developers.yubico.com/tree/master/static/U2F
#define YUBICO_CA \
"-----BEGIN CERTIFICATE-----\r\n" \
"MIIDHjCCAgagAwIBAgIEG0BT9zANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZ\r\n" \

View file

@ -34,18 +34,23 @@
*
*
****************************************************************************/
// this define is needed for scandir/alphasort to work
#define _GNU_SOURCE
#include "fileutils.h"
#include <dirent.h>
#include <ctype.h>
#include "pm3_cmd.h"
#include "commonutil.h"
#include "proxmark3.h"
#include "util.h"
#ifdef _WIN32
#include "scandir.h"
#endif
#ifndef ON_DEVICE
#define PATH_MAX_LENGTH 100
#define PATH_MAX_LENGTH 200
/**
* @brief checks if a file exists
@ -98,9 +103,9 @@ static char *newfilenamemcopy(const char *preferredName, const char *suffix) {
int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen) {
if (data == NULL) return 1;
if (data == NULL) return PM3_EINVARG;
char *fileName = newfilenamemcopy(preferredName, suffix);
if (fileName == NULL) return 1;
if (fileName == NULL) return PM3_EMALLOC;
/* We should have a valid filename now, e.g. dumpdata-3.bin */
@ -121,9 +126,9 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si
int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize) {
if (data == NULL) return 1;
if (data == NULL) return PM3_EINVARG;
char *fileName = newfilenamemcopy(preferredName, ".eml");
if (fileName == NULL) return 1;
if (fileName == NULL) return PM3_EMALLOC;
int retval = PM3_SUCCESS;
int blocks = datalen / blocksize;
@ -166,9 +171,9 @@ out:
int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen) {
if (data == NULL) return 1;
if (data == NULL) return PM3_EINVARG;
char *fileName = newfilenamemcopy(preferredName, ".json");
if (fileName == NULL) return 1;
if (fileName == NULL) return PM3_EMALLOC;
int retval = PM3_SUCCESS;
@ -276,6 +281,19 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s
}
break;
}
case jsfIclass: {
JsonSaveStr(root, "FileType", "iclass");
uint8_t csn[8] = {0};
memcpy(csn, data, 8);
JsonSaveBufAsHexCompact(root, "$.Card.CSN", csn, sizeof(csn));
for (size_t i = 0; i < (datalen / 8); i++) {
char path[PATH_MAX_LENGTH] = {0};
sprintf(path, "$.blocks.%zu", i);
JsonSaveBufAsHexCompact(root, path, data + (i * 8), 8);
}
break;
}
}
int res = json_dump_file(root, fileName, JSON_INDENT(2));
@ -293,11 +311,42 @@ out:
return retval;
}
int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr) {
uint8_t tmpKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
int i;
if (fptr == NULL) {
return PM3_EINVARG;
}
FILE *fkeys = fopen(fptr, "wb");
if (fkeys == NULL) {
PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), fptr);
return PM3_EFILE;
}
PrintAndLogEx(SUCCESS, "Printing keys to binary file " _YELLOW_("%s")"...", fptr);
for (i = 0; i < sectorsCnt; i++) {
num_to_bytes(e_sector[i].Key[0], 6, tmpKey);
fwrite(tmpKey, 1, 6, fkeys);
}
for (i = 0; i < sectorsCnt; i++) {
num_to_bytes(e_sector[i].Key[1], 6, tmpKey);
fwrite(tmpKey, 1, 6, fkeys);
}
fclose(fkeys);
PrintAndLogEx(SUCCESS, "Found keys have been dumped to " _YELLOW_("%s")" --> 0xffffffffffff has been inserted for unknown keys.", fptr);
return PM3_SUCCESS;
}
int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen) {
if (data == NULL) return 1;
char *fileName = filenamemcopy(preferredName, suffix);
if (fileName == NULL) return 1;
if (fileName == NULL) return PM3_EINVARG;
int retval = PM3_SUCCESS;
@ -315,23 +364,24 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m
if (fsize <= 0) {
PrintAndLogEx(FAILED, "error, when getting filesize");
retval = 1;
retval = PM3_EFILE;
goto out;
}
uint8_t *dump = calloc(fsize, sizeof(uint8_t));
if (!dump) {
PrintAndLogEx(FAILED, "error, cannot allocate memory");
retval = 2;
retval = PM3_EMALLOC;
goto out;
}
size_t bytes_read = fread(dump, 1, fsize, f);
fclose(f);
if (bytes_read != fsize) {
PrintAndLogEx(FAILED, "error, bytes read mismatch file size");
free(dump);
retval = 3;
retval = PM3_EFILE;
goto out;
}
@ -348,17 +398,66 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m
*datalen = bytes_read;
out:
fclose(f);
free(fileName);
return retval;
}
int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen) {
char *path;
int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, suffix, false);
if (res != PM3_SUCCESS) {
return PM3_EFILE;
}
int retval = PM3_SUCCESS;
FILE *f = fopen(path, "rb");
if (!f) {
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path);
free(path);
return PM3_EFILE;
}
free(path);
// get filesize in order to malloc memory
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
if (fsize <= 0) {
PrintAndLogEx(FAILED, "error, when getting filesize");
fclose(f);
return PM3_EFILE;
}
*pdata = calloc(fsize, sizeof(uint8_t));
if (!pdata) {
PrintAndLogEx(FAILED, "error, cannot allocate memory");
fclose(f);
return PM3_EMALLOC;
}
size_t bytes_read = fread(*pdata, 1, fsize, f);
fclose(f);
if (bytes_read != fsize) {
PrintAndLogEx(FAILED, "error, bytes read mismatch file size");
return PM3_EFILE;
}
*datalen = bytes_read;
PrintAndLogEx(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName);
return retval;
}
int loadFileEML(const char *preferredName, void *data, size_t *datalen) {
if (data == NULL) return 1;
if (data == NULL) return PM3_EINVARG;
char *fileName = filenamemcopy(preferredName, ".eml");
if (fileName == NULL) return 1;
if (fileName == NULL) return PM3_EMALLOC;
size_t counter = 0;
int retval = PM3_SUCCESS, hexlen = 0;
@ -384,7 +483,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) {
break;
fclose(f);
PrintAndLogEx(FAILED, "File reading error.");
retval = 2;
retval = PM3_EFILE;
goto out;
}
@ -410,9 +509,9 @@ out:
int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen) {
if (data == NULL) return 1;
if (data == NULL) return PM3_EINVARG;
char *fileName = filenamemcopy(preferredName, ".json");
if (fileName == NULL) return 1;
if (fileName == NULL) return PM3_EMALLOC;
*datalen = 0;
json_t *root;
@ -423,13 +522,13 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
root = json_load_file(fileName, 0, &error);
if (!root) {
PrintAndLogEx(ERR, "ERROR: json " _YELLOW_("%s") " error on line %d: %s", fileName, error.line, error.text);
retval = 2;
retval = PM3_ESOFT;
goto out;
}
if (!json_is_object(root)) {
PrintAndLogEx(ERR, "ERROR: Invalid json " _YELLOW_("%s") " format. root must be an object.", fileName);
retval = 3;
retval = PM3_ESOFT;
goto out;
}
@ -445,7 +544,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
size_t sptr = 0;
for (int i = 0; i < 256; i++) {
if (sptr + 16 > maxdatalen) {
retval = 5;
retval = PM3_EMALLOC;
goto out;
}
@ -467,7 +566,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
size_t sptr = 0;
for (int i = 0; i < 256; i++) {
if (sptr + 4 > maxdatalen) {
retval = 5;
retval = PM3_EMALLOC;
goto out;
}
@ -489,7 +588,7 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
size_t sptr = 0;
for (size_t i = 0; i < (maxdatalen / 4); i++) {
if (sptr + 4 > maxdatalen) {
retval = 5;
retval = PM3_EMALLOC;
goto out;
}
@ -507,6 +606,27 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
*datalen = sptr;
}
if (!strcmp(ctype, "iclass")) {
size_t sptr = 0;
for (size_t i = 0; i < (maxdatalen / 8); i++) {
if (sptr + 8 > maxdatalen) {
retval = PM3_EMALLOC;
goto out;
}
char path[30] = {0};
sprintf(path, "$.blocks.%zu", i);
size_t len = 0;
JsonLoadBufAsHex(root, path, &udata[sptr], 8, &len);
if (!len)
break;
sptr += len;
}
*datalen = sptr;
}
PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName);
out:
json_decref(root);
@ -516,10 +636,10 @@ out:
int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) {
if (data == NULL) return 1;
char *fileName = filenamemcopy(preferredName, ".dic");
if (fileName == NULL) return 1;
if (data == NULL) return PM3_EINVARG;
char *path;
if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS)
return PM3_EFILE;
// t5577 == 4bytes
// mifare == 6 bytes
@ -537,9 +657,9 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u
size_t counter = 0;
int retval = PM3_SUCCESS;
FILE *f = fopen(fileName, "r");
FILE *f = fopen(path, "r");
if (!f) {
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName);
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path);
retval = PM3_EFILE;
goto out;
}
@ -571,12 +691,98 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u
counter += (keylen >> 1);
}
fclose(f);
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, fileName);
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, path);
if (datalen)
*datalen = counter;
out:
free(fileName);
free(path);
return retval;
}
int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt) {
int retval = PM3_SUCCESS;
char *path;
if (searchFile(&path, DICTIONARIES_SUBDIR, preferredName, ".dic", false) != PM3_SUCCESS)
return PM3_EFILE;
// t5577 == 4bytes
// mifare == 6 bytes
// iclass == 8 bytes
// default to 6 bytes.
if (keylen != 4 && keylen != 6 && keylen != 8) {
keylen = 6;
}
size_t mem_size;
size_t block_size = 10 * keylen;
// double up since its chars
keylen <<= 1;
char line[255];
// allocate some space for the dictionary
*pdata = calloc(block_size, sizeof(uint8_t));
if (*pdata == NULL)
return PM3_EFILE;
mem_size = block_size;
FILE *f = fopen(path, "r");
if (!f) {
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path);
retval = PM3_EFILE;
goto out;
}
// read file
while (fgets(line, sizeof(line), f)) {
// check if we have enough space (if not allocate more)
if ((*keycnt * (keylen >> 1)) >= mem_size) {
mem_size += block_size;
*pdata = realloc(*pdata, mem_size);
if (*pdata == NULL) {
return PM3_EFILE;
} else {
memset(*pdata + (mem_size - block_size), 0, block_size);
}
}
// add null terminator
line[keylen] = 0;
// smaller keys than expected is skipped
if (strlen(line) < keylen)
continue;
// The line start with # is comment, skip
if (line[0] == '#')
continue;
if (!isxdigit(line[0])) {
PrintAndLogEx(FAILED, "file content error. '%s' must include " _BLUE_("%2d") "HEX symbols", line, keylen);
continue;
}
uint64_t key = strtoull(line, NULL, 16);
num_to_bytes(key, keylen >> 1, *pdata + (*keycnt * (keylen >> 1)));
(*keycnt)++;
memset(line, 0, sizeof(line));
}
fclose(f);
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, path);
out:
free(path);
return retval;
}
@ -612,7 +818,211 @@ int convertOldMfuDump(uint8_t **dump, size_t *dumplen) {
return PM3_SUCCESS;
}
static int filelist(const char *path, const char *ext, bool last, bool tentative) {
struct dirent **namelist;
int n;
#else //if we're on ARM
n = scandir(path, &namelist, NULL, alphasort);
if (n == -1) {
if (!tentative)
PrintAndLogEx(NORMAL, "%s── %s", last ? "" : "", path);
return PM3_EFILE;
}
#endif
PrintAndLogEx(NORMAL, "%s── %s", last ? "" : "", path);
for (uint16_t i = 0; i < n; i++) {
if (((ext == NULL) && (namelist[i]->d_name[0] != '.')) || (str_endswith(namelist[i]->d_name, ext))) {
PrintAndLogEx(NORMAL, "%s   %s── %-21s", last ? " " : "", i == n - 1 ? "" : "", namelist[i]->d_name);
}
free(namelist[i]);
}
free(namelist);
return PM3_SUCCESS;
}
int searchAndList(const char *pm3dir, const char *ext) {
// display in same order as searched by searchFile
// try pm3 dirs in current workdir (dev mode)
if (get_my_executable_directory() != NULL) {
char script_directory_path[strlen(get_my_executable_directory()) + strlen(pm3dir) + 1];
strcpy(script_directory_path, get_my_executable_directory());
strcat(script_directory_path, pm3dir);
filelist(script_directory_path, ext, false, true);
}
// try pm3 dirs in user .proxmark3 (user mode)
const char *user_path = get_my_user_directory();
if (user_path != NULL) {
char script_directory_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + 1];
strcpy(script_directory_path, user_path);
strcat(script_directory_path, PM3_USER_DIRECTORY);
strcat(script_directory_path, pm3dir);
filelist(script_directory_path, ext, false, false);
}
// try pm3 dirs in pm3 installation dir (install mode)
const char *exec_path = get_my_executable_directory();
if (exec_path != NULL) {
char script_directory_path[strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + 1];
strcpy(script_directory_path, exec_path);
strcat(script_directory_path, PM3_SHARE_RELPATH);
strcat(script_directory_path, pm3dir);
filelist(script_directory_path, ext, true, false);
}
return PM3_SUCCESS;
}
static int searchFinalFile(char **foundpath, const char *pm3dir, const char *searchname, bool silent) {
if ((foundpath == NULL) || (pm3dir == NULL) || (searchname == NULL)) return PM3_ESOFT;
// explicit absolute (/) or relative path (./) => try only to match it directly
char *filename = calloc(strlen(searchname) + 1, sizeof(char));
if (filename == NULL) return PM3_EMALLOC;
strcpy(filename, searchname);
if ((g_debugMode == 2) && (!silent)) {
PrintAndLogEx(INFO, "Searching %s", filename);
}
if (((strlen(filename) > 1) && (filename[0] == '/')) ||
((strlen(filename) > 2) && (filename[0] == '.') && (filename[1] == '/'))) {
if (fileExists(filename)) {
*foundpath = filename;
if ((g_debugMode == 2) && (!silent)) {
PrintAndLogEx(INFO, "Found %s", *foundpath);
}
return PM3_SUCCESS;
} else {
goto out;
}
}
// else
// try implicit relative path
{
if (fileExists(filename)) {
*foundpath = filename;
if ((g_debugMode == 2) && (!silent)) {
PrintAndLogEx(INFO, "Found %s", *foundpath);
}
return PM3_SUCCESS;
}
}
// try pm3 dirs in user .proxmark3 (user mode)
const char *user_path = get_my_user_directory();
if (user_path != NULL) {
char *path = calloc(strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
if (path == NULL)
goto out;
strcpy(path, user_path);
strcat(path, PM3_USER_DIRECTORY);
strcat(path, pm3dir);
strcat(path, filename);
if ((g_debugMode == 2) && (!silent)) {
PrintAndLogEx(INFO, "Searching %s", path);
}
if (fileExists(path)) {
free(filename);
*foundpath = path;
if ((g_debugMode == 2) && (!silent)) {
PrintAndLogEx(INFO, "Found %s", *foundpath);
}
return PM3_SUCCESS;
} else {
free(path);
}
}
// try pm3 dirs in current client workdir (dev mode)
const char *exec_path = get_my_executable_directory();
if ((exec_path != NULL) &&
((strcmp(DICTIONARIES_SUBDIR, pm3dir) == 0) ||
(strcmp(LUA_LIBRARIES_SUBDIR, pm3dir) == 0) ||
(strcmp(LUA_SCRIPTS_SUBDIR, pm3dir) == 0) ||
(strcmp(CMD_SCRIPTS_SUBDIR, pm3dir) == 0) ||
(strcmp(RESOURCES_SUBDIR, pm3dir) == 0))) {
char *path = calloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
if (path == NULL)
goto out;
strcpy(path, exec_path);
strcat(path, pm3dir);
strcat(path, filename);
if ((g_debugMode == 2) && (!silent)) {
PrintAndLogEx(INFO, "Searching %s", path);
}
if (fileExists(path)) {
free(filename);
*foundpath = path;
if ((g_debugMode == 2) && (!silent)) {
PrintAndLogEx(INFO, "Found %s", *foundpath);
}
return PM3_SUCCESS;
} else {
free(path);
}
}
// try pm3 dirs in current repo workdir (dev mode)
if ((exec_path != NULL) &&
((strcmp(TRACES_SUBDIR, pm3dir) == 0) ||
(strcmp(FIRMWARES_SUBDIR, pm3dir) == 0) ||
(strcmp(BOOTROM_SUBDIR, pm3dir) == 0) ||
(strcmp(FULLIMAGE_SUBDIR, pm3dir) == 0))) {
char *above = "../";
char *path = calloc(strlen(exec_path) + strlen(above) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
if (path == NULL)
goto out;
strcpy(path, exec_path);
strcat(path, above);
strcat(path, pm3dir);
strcat(path, filename);
if ((g_debugMode == 2) && (!silent)) {
PrintAndLogEx(INFO, "Searching %s", path);
}
if (fileExists(path)) {
free(filename);
*foundpath = path;
if ((g_debugMode == 2) && (!silent)) {
PrintAndLogEx(INFO, "Found %s", *foundpath);
}
return PM3_SUCCESS;
} else {
free(path);
}
}
// try pm3 dirs in pm3 installation dir (install mode)
{
char *path = calloc(strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
if (path == NULL)
goto out;
strcpy(path, exec_path);
strcat(path, PM3_SHARE_RELPATH);
strcat(path, pm3dir);
strcat(path, filename);
if ((g_debugMode == 2) && (!silent)) {
PrintAndLogEx(INFO, "Searching %s", path);
}
if (fileExists(path)) {
free(filename);
*foundpath = path;
if ((g_debugMode == 2) && (!silent)) {
PrintAndLogEx(INFO, "Found %s", *foundpath);
}
return PM3_SUCCESS;
} else {
free(path);
}
}
out:
free(filename);
return PM3_EFILE;
}
int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent) {
if (foundpath == NULL)
return PM3_EINVARG;
char *filename = filenamemcopy(searchname, suffix);
if (filename == NULL) return PM3_EMALLOC;
int res = searchFinalFile(foundpath, pm3dir, filename, silent);
if (res != PM3_SUCCESS) {
if ((res == PM3_EFILE) && (!silent))
PrintAndLogEx(FAILED, "Error - can't find %s", filename);
free(filename);
return res;
}
free(filename);
return PM3_SUCCESS;
}

View file

@ -38,17 +38,16 @@
#ifndef FILEUTILS_H
#define FILEUTILS_H
#ifndef ON_DEVICE
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <stdarg.h>
#include "../ui.h"
#include "../emv/emvjson.h"
#include "ui.h"
#include "emv/emvjson.h"
#include "mifare/mifare4.h"
#include "mifare/mifarehost.h"
#include "cmdhfmfu.h"
typedef enum {
@ -56,12 +55,20 @@ typedef enum {
jsfCardMemory,
jsfMfuMemory,
jsfHitag,
jsfIclass,
// jsf14b,
// jsf15,
// jsfLegic,
// jsfT55xx,
} JSONFileType;
typedef enum {
BIN = 0,
EML,
JSON,
DICTIONARY,
} DumpFileType_t;
int fileExists(const char *filename);
/**
@ -103,7 +110,17 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t
*/
int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen);
/** STUB
/**
* @brief Utility function to save a keydump.
*
* @param sectorsCnt the used sectors
* @param e_sector the keys in question
* @param fptr string pointer to the filename
* @return 0 for ok, 1 for failz
*/
int createMfcKeyDump(uint8_t sectorsCnt, sector_t *e_sector, char *fptr);
/**
* @brief Utility function to load data from a binary file. This method takes a preferred name.
* E.g. dumpdata-15.bin
*
@ -112,10 +129,22 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s
* @param data The data array to store the loaded bytes from file
* @param maxdatalen the number of bytes that your data array has
* @param datalen the number of bytes loaded from file
* @return 0 for ok, 1 for failz
* @return PM3_SUCCESS for ok, PM3_E* for failz
*/
int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen);
/**
* @brief Utility function to load data from a binary file. This method takes a preferred name.
* E.g. dumpdata-15.bin, tries to search for it, and allocated memory.
*
* @param preferredName
* @param suffix the file suffix. Including the ".".
* @param data The data array to store the loaded bytes from file
* @param datalen the number of bytes loaded from file
* @return PM3_SUCCESS for ok, PM3_E* for failz
*/
int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, size_t *datalen);
/**
* @brief Utility function to load data from a textfile (EML). This method takes a preferred name.
* E.g. dumpdata-15.txt
@ -139,10 +168,9 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen);
*/
int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen);
/**
* @brief Utility function to load data from a DICTIONARY textfile. This method takes a preferred name.
* E.g. default_keys.dic
* E.g. mfc_default_keys.dic
*
* @param preferredName
* @param data The data array to store the loaded bytes from file
@ -153,6 +181,17 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
*/
int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt);
/**
* @brief Utility function to load data safely from a DICTIONARY textfile. This method takes a preferred name.
* E.g. mfc_default_keys.dic
*
* @param preferredName
* @param pdata A pointer to a pointer (for reverencing the loaded dictionary)
* @param keylen the number of bytes a key per row is
* @return 0 for ok, 1 for failz
*/
int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint16_t *keycnt);
/**
* @brief Utility function to check and convert old mfu dump format to new
*
@ -162,20 +201,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u
*/
int convertOldMfuDump(uint8_t **dump, size_t *dumplen);
#define PrintAndLogEx(level, format, args...) PrintAndLogEx(level, format , ## args)
#else
/**
* Utility function to print to console. This is used consistently within the library instead
* of printf, but it actually only calls printf. The reason to have this method is to
*make it simple to plug this library into proxmark, which has this function already to
* write also to a logfile. When doing so, just point this function to use PrintAndLog
* @param fmt
*/
#define PrintAndLogEx(level, format, args...) { }
#endif //ON_DEVICE
int searchAndList(const char *pm3dir, const char *ext);
int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent);
#endif // FILEUTILS_H

View file

@ -83,7 +83,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
ctx->segments = calloc(sizeof(flash_seg_t) * num_phdrs, sizeof(uint8_t));
if (!ctx->segments) {
PrintAndLogEx(ERR, "Out of memory");
return -1;
return PM3_EMALLOC;
}
ctx->num_segs = 0;
seg = ctx->segments;
@ -113,19 +113,19 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
if (filesz != memsz) {
PrintAndLogEx(ERR, "Error: PHDR file size does not equal memory size\n"
"(DATA+BSS PHDRs do not make sense on ROM platforms!)");
return -1;
return PM3_EFILE;
}
if (paddr < last_end) {
PrintAndLogEx(ERR, "Error: PHDRs not sorted or overlap");
return -1;
return PM3_EFILE;
}
if (paddr < FLASH_START || (paddr + filesz) > flash_end) {
PrintAndLogEx(ERR, "Error: PHDR is not contained in Flash");
return -1;
return PM3_EFILE;
}
if (vaddr >= FLASH_START && vaddr < flash_end && (flags & PF_W)) {
PrintAndLogEx(ERR, "Error: Flash VMA segment is writable");
return -1;
return PM3_EFILE;
}
uint8_t *data;
@ -133,12 +133,12 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
data = calloc(filesz + BLOCK_SIZE, sizeof(uint8_t));
if (!data) {
PrintAndLogEx(ERR, "Error: Out of memory");
return -1;
return PM3_EMALLOC;
}
if (fseek(fd, offset, SEEK_SET) < 0 || fread(data, 1, filesz, fd) != filesz) {
PrintAndLogEx(ERR, "Error while reading PHDR payload");
free(data);
return -1;
return PM3_EFILE;
}
uint32_t block_offset = paddr & (BLOCK_SIZE - 1);
@ -157,7 +157,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
if (!new_data) {
PrintAndLogEx(ERR, "Error: Out of memory");
free(data);
return -1;
return PM3_EMALLOC;
}
memset(new_data, 0xff, new_length);
memcpy(new_data, prev_seg->data, prev_seg->length);
@ -191,7 +191,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
last_end = paddr + filesz;
phdr++;
}
return 0;
return PM3_SUCCESS;
}
// Sanity check segments and check for bootloader writes
@ -201,26 +201,26 @@ static int check_segs(flash_file_t *ctx, int can_write_bl, uint32_t flash_end) {
if (seg->start & (BLOCK_SIZE - 1)) {
PrintAndLogEx(ERR, "Error: Segment is not aligned");
return -1;
return PM3_EFILE;
}
if (seg->start < FLASH_START) {
PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds");
return -1;
return PM3_EFILE;
}
if (seg->start + seg->length > flash_end) {
PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds");
return -1;
return PM3_EFILE;
}
if (!can_write_bl && seg->start < BOOTLOADER_END) {
PrintAndLogEx(ERR, "Attempted to write bootloader but bootloader writes are not enabled");
return -1;
return PM3_EINVARG;
}
if (can_write_bl && seg->start < BOOTLOADER_END && (seg->start + seg->length > BOOTLOADER_END)) {
PrintAndLogEx(ERR, "Error: Segment is outside of bootloader bounds");
return -1;
return PM3_EFILE;
}
}
return 0;
return PM3_SUCCESS;
}
// Load an ELF file and prepare it for flashing
@ -230,11 +230,12 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
Elf32_Phdr *phdrs = NULL;
uint16_t num_phdrs;
uint32_t flash_end = FLASH_START + flash_size;
int res;
int res = PM3_EUNDEF;
fd = fopen(name, "rb");
if (!fd) {
PrintAndLogEx(ERR, _RED_("Could not open file") "%s >>> ", name);
res = PM3_EFILE;
goto fail;
}
@ -242,28 +243,34 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
if (fread(&ehdr, sizeof(ehdr), 1, fd) != 1) {
PrintAndLogEx(ERR, "Error while reading ELF file header");
res = PM3_EFILE;
goto fail;
}
if (memcmp(ehdr.e_ident, elf_ident, sizeof(elf_ident))
|| le32(ehdr.e_version) != 1) {
PrintAndLogEx(ERR, "Not an ELF file or wrong ELF type");
res = PM3_EFILE;
goto fail;
}
if (le16(ehdr.e_type) != ET_EXEC) {
PrintAndLogEx(ERR, "ELF is not executable");
res = PM3_EFILE;
goto fail;
}
if (le16(ehdr.e_machine) != EM_ARM) {
PrintAndLogEx(ERR, "Wrong ELF architecture");
res = PM3_EFILE;
goto fail;
}
if (!ehdr.e_phnum || !ehdr.e_phoff) {
PrintAndLogEx(ERR, "ELF has no PHDRs");
res = PM3_EFILE;
goto fail;
}
if (le16(ehdr.e_phentsize) != sizeof(Elf32_Phdr)) {
// could be a structure padding issue...
PrintAndLogEx(ERR, "Either the ELF file or this code is made of fail");
res = PM3_EFILE;
goto fail;
}
num_phdrs = le16(ehdr.e_phnum);
@ -271,28 +278,31 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t));
if (!phdrs) {
PrintAndLogEx(ERR, "Out of memory");
res = PM3_EMALLOC;
goto fail;
}
if (fseek(fd, le32(ehdr.e_phoff), SEEK_SET) < 0) {
PrintAndLogEx(ERR, "Error while reading ELF PHDRs");
res = PM3_EFILE;
goto fail;
}
if (fread(phdrs, sizeof(Elf32_Phdr), num_phdrs, fd) != num_phdrs) {
res = PM3_EFILE;
PrintAndLogEx(ERR, "Error while reading ELF PHDRs");
goto fail;
}
res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs, flash_end);
if (res < 0)
if (res != PM3_SUCCESS)
goto fail;
res = check_segs(ctx, can_write_bl, flash_end);
if (res < 0)
if (res != PM3_SUCCESS)
goto fail;
free(phdrs);
fclose(fd);
ctx->filename = name;
return 0;
return PM3_SUCCESS;
fail:
if (phdrs)
@ -300,7 +310,7 @@ fail:
if (fd)
fclose(fd);
flash_free(ctx);
return -1;
return res;
}
// Get the state of the proxmark, backwards compatible
@ -326,22 +336,23 @@ static int get_proxmark_state(uint32_t *state) {
break;
default:
PrintAndLogEx(ERR, _RED_("Error:") "Couldn't get Proxmark3 state, bad response type: 0x%04x", resp.cmd);
return -1;
return PM3_EFATAL;
break;
}
return 0;
return PM3_SUCCESS;
}
// Enter the bootloader to be able to start flashing
static int enter_bootloader(char *serial_port_name) {
uint32_t state;
int ret;
if (get_proxmark_state(&state) < 0)
return -1;
if ((ret = get_proxmark_state(&state)) != PM3_SUCCESS)
return ret;
/* Already in flash state, we're done. */
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM)
return 0;
return PM3_SUCCESS;
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
PrintAndLogEx(SUCCESS, _BLUE_("Entering bootloader..."));
@ -364,15 +375,15 @@ static int enter_bootloader(char *serial_port_name) {
if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) {
PrintAndLogEx(NORMAL, " " _GREEN_("Found"));
return 0;
return PM3_SUCCESS;
} else {
PrintAndLogEx(ERR, _RED_("Error:") "Proxmark3 not found.");
return -1;
return PM3_ETIMEOUT;
}
}
PrintAndLogEx(ERR, _RED_("Error:") "Unknown Proxmark3 mode");
return -1;
return PM3_EFATAL;
}
static int wait_for_ack(PacketResponseNG *ack) {
@ -383,9 +394,9 @@ static int wait_for_ack(PacketResponseNG *ack) {
ack->cmd,
(ack->cmd == CMD_NACK) ? "NACK" : ""
);
return -1;
return PM3_ESOFT;
}
return 0;
return PM3_SUCCESS;
}
static void flash_suggest_update_bootloader(void) {
@ -401,12 +412,15 @@ static void flash_suggest_update_flasher(void) {
int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *max_allowed) {
uint32_t state;
uint32_t chipinfo = 0;
int ret;
if (enter_bootloader(serial_port_name) < 0)
return -1;
ret = enter_bootloader(serial_port_name);
if (ret != PM3_SUCCESS)
return ret;
if (get_proxmark_state(&state) < 0)
return -1;
ret = get_proxmark_state(&state);
if (ret != PM3_SUCCESS)
return ret;
if (state & DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO) {
SendCommandBL(CMD_CHIP_INFO, 0, 0, 0, NULL, 0);
@ -485,7 +499,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("START_FLASH") _RED_("command")));
flash_suggest_update_bootloader();
}
return 0;
return PM3_SUCCESS;
}
static int write_block(uint32_t address, uint8_t *data, uint32_t length) {
@ -531,7 +545,7 @@ int flash_write(flash_file_t *ctx) {
if (write_block(baddr, data, block_size) < 0) {
PrintAndLogEx(ERR, "Error writing block %d of %u", block, blocks);
return -1;
return PM3_EFATAL;
}
data += block_size;
@ -544,7 +558,7 @@ int flash_write(flash_file_t *ctx) {
PrintAndLogEx(NORMAL, " " _GREEN_("OK"));
fflush(stdout);
}
return 0;
return PM3_SUCCESS;
}
// free a file context
@ -564,5 +578,5 @@ void flash_free(flash_file_t *ctx) {
int flash_stop_flashing(void) {
SendCommandBL(CMD_HARDWARE_RESET, 0, 0, 0, NULL, 0);
msleep(100);
return 0;
return PM3_SUCCESS;
}

View file

@ -11,6 +11,9 @@
#include "common.h"
#define FLASH_MAX_FILES 4
#define ONE_KB 1024
typedef struct {
void *data;
uint32_t start;

View file

@ -1,130 +0,0 @@
//-----------------------------------------------------------------------------
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Flasher frontend tool
//-----------------------------------------------------------------------------
#include <string.h>
#include <unistd.h>
#include "usart_defs.h"
#include "flash.h"
#include "comms.h"
#include "ui.h"
#define MAX_FILES 4
#define ONE_KB 1024
static void usage(char *argv0) {
PrintAndLogEx(NORMAL, "Usage: %s <port> [-b] image.elf [image.elf...]", argv0);
PrintAndLogEx(NORMAL, " %s <port> -i\n", argv0);
PrintAndLogEx(NORMAL, "\t-b\tEnable flashing of bootloader area (DANGEROUS)");
PrintAndLogEx(NORMAL, "\t-i\tProbe the connected Proxmark3 to retrieve its memory size");
PrintAndLogEx(NORMAL, "\nExamples:\n\t %s "SERIAL_PORT_EXAMPLE_H" -i", argv0);
PrintAndLogEx(NORMAL, "\t %s "SERIAL_PORT_EXAMPLE_H" armsrc/obj/fullimage.elf", argv0);
#ifdef __linux__
PrintAndLogEx(NORMAL, "\nNote (Linux):\nif the flasher gets stuck in 'Waiting for Proxmark3 to reappear on <DEVICE>',");
PrintAndLogEx(NORMAL, "you need to blacklist Proxmark3 for modem-manager - see documentation for more details:");
PrintAndLogEx(NORMAL, "* https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md");
PrintAndLogEx(NORMAL, "\nMore info on flashing procedure from the official Proxmark3 wiki:");
PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Gentoo%%20Linux");
PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/Ubuntu%%20Linux");
PrintAndLogEx(NORMAL, "* https://github.com/Proxmark/proxmark3/wiki/OSX\n");
#endif
}
int main(int argc, char **argv) {
int can_write_bl = 0;
int num_files = 0;
int res;
int ret = 0;
flash_file_t files[MAX_FILES];
char *filenames[MAX_FILES];
bool info = false;
memset(files, 0, sizeof(files));
session.supports_colors = false;
session.stdinOnTTY = isatty(STDIN_FILENO);
session.stdoutOnTTY = isatty(STDOUT_FILENO);
#if defined(__linux__) || (__APPLE__)
if (session.stdinOnTTY && session.stdoutOnTTY)
session.supports_colors = true;
#endif
session.help_dump_mode = false;
if (argc < 3) {
usage(argv[0]);
return -1;
}
for (int i = 2; i < argc; i++) {
if (argv[i][0] == '-') {
if (!strcmp(argv[i], "-b")) {
can_write_bl = 1;
} else if (!strcmp(argv[i], "-i")) {
info = true;
} else {
usage(argv[0]);
return -1;
}
} else {
filenames[num_files] = argv[i];
num_files++;
}
}
char *serial_port_name = argv[1];
if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) {
PrintAndLogEx(NORMAL, _GREEN_("Found"));
} else {
PrintAndLogEx(ERR, "Could not find Proxmark3 on " _RED_("%s") ".\n", serial_port_name);
return -1;
}
uint32_t max_allowed = 0;
res = flash_start_flashing(can_write_bl, serial_port_name, &max_allowed);
if (res < 0) {
ret = -1;
goto finish;
}
if (info)
goto finish;
for (int i = 0 ; i < num_files; ++i) {
res = flash_load(&files[i], filenames[i], can_write_bl, max_allowed * ONE_KB);
if (res < 0) {
ret = -1;
goto finish;
}
PrintAndLogEx(NORMAL, "");
}
PrintAndLogEx(SUCCESS, "\n" _BLUE_("Flashing..."));
for (int i = 0; i < num_files; i++) {
res = flash_write(&files[i]);
if (res < 0) {
ret = -1;
goto finish;
}
flash_free(&files[i]);
PrintAndLogEx(NORMAL, "\n");
}
finish:
res = flash_stop_flashing();
if (res < 0)
ret = -1;
CloseProxmark();
if (ret == 0)
PrintAndLogEx(SUCCESS, _BLUE_("All done."));
else
PrintAndLogEx(ERR, "Aborted on error.");
PrintAndLogEx(NORMAL, "\nHave a nice day!");
return ret;
}

View file

@ -65,11 +65,13 @@ THE SOFTWARE.
#include "util_posix.h"
#include "crapto1/crapto1.h"
#include "parity.h"
#include "fileutils.h"
#include "pm3_cmd.h"
#define NUM_BRUTE_FORCE_THREADS (num_CPUs())
#define DEFAULT_BRUTE_FORCE_RATE (120000000.0) // if benchmark doesn't succeed
#define TEST_BENCH_SIZE (6000) // number of odd and even states for brute force benchmark
#define TEST_BENCH_FILENAME "hardnested/bf_bench_data.bin"
#define TEST_BENCH_FILENAME "hardnested_bf_bench_data.bin"
//#define WRITE_BENCH_FILE
// debugging options
@ -265,8 +267,12 @@ void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte) {
#if defined (WRITE_BENCH_FILE)
static void write_benchfile(statelist_t *candidates) {
printf("Writing brute force benchmark data...");
FILE *benchfile = fopen(TEST_BENCH_FILENAME, "wb");
PrintAndLogEx(NORMAL, "Writing brute force benchmark data in " RESOURCES_SUBDIR " subdirectory...");
FILE *benchfile = fopen(RESOURCES_SUBDIR TEST_BENCH_FILENAME, "wb");
if (benchfile == NULL) {
PrintAndLogEx(ERR, "Can't write " RESOURCES_SUBDIR TEST_BENCH_FILENAME", abort!");
return;
}
fwrite(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile);
for (uint32_t i = 0; i < nonces_to_bruteforce; i++) {
fwrite(&(bf_test_nonce[i]), 1, sizeof(bf_test_nonce[i]), benchfile);
@ -283,7 +289,7 @@ static void write_benchfile(statelist_t *candidates) {
fwrite(&(candidates->states[ODD_STATE][i]), 1, sizeof(uint32_t), benchfile);
}
fclose(benchfile);
printf("done.\n");
PrintAndLogEx(NORMAL, "Done");
}
#endif
@ -360,14 +366,17 @@ static bool read_bench_data(statelist_t *test_candidates) {
uint32_t num_states = 0;
uint32_t states_read = 0;
char bench_file_path[strlen(get_my_executable_directory()) + strlen(TEST_BENCH_FILENAME) + 1];
strcpy(bench_file_path, get_my_executable_directory());
strcat(bench_file_path, TEST_BENCH_FILENAME);
FILE *benchfile = fopen(bench_file_path, "rb");
if (benchfile == NULL) {
char *path;
if (searchFile(&path, RESOURCES_SUBDIR, TEST_BENCH_FILENAME, "", false) != PM3_SUCCESS) {
return false;
}
FILE *benchfile = fopen(path, "rb");
if (benchfile == NULL) {
free(path);
return false;
}
free(path);
bytes_read = fread(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile);
if (bytes_read != sizeof(nonces_to_bruteforce)) {
fclose(benchfile);

View file

@ -1,81 +1,21 @@
# Hide full compilation line:
ifneq ($(V),1)
Q?=@
endif
# To see full command lines, use make V=1
include_HEADERS = jansson.h
nodist_include_HEADERS = jansson_config.h
LIB_A = libjansson.a
libjansson_la_SOURCES = \
MYSRCPATHS =
MYINCLUDES = -I.
MYCFLAGS = -std=c99 -D_ISOC99_SOURCE -Wno-unused-function
MYDEFS = -DHAVE_STDINT_H
MYSRCS = \
dump.c \
error.c \
hashtable.c \
hashtable.h \
hashtable_seed.c \
jansson_private.h \
load.c \
lookup3.h \
memory.c \
pack_unpack.c \
strbuffer.c \
strbuffer.h \
strconv.c \
utf.c \
utf.h \
path.c \
value.c
libjansson_la_LDFLAGS = \
-no-undefined \
-export-symbols-regex '^json_' \
-version-info 15:0:11
LIB_A = libjansson.a
CFILES = $(filter %.c, $(libjansson_la_SOURCES))
CMDOBJS = $(CFILES:%.c=%.o)
CLEAN = $(CMDOBJS)
platform = $(shell uname)
CC= gcc
CFLAGS= -O2 -Wall -Wno-unused-variable -Wno-unused-function
LDFLAGS= $(SYSLDFLAGS) $(libjansson_la_LDFLAGS)
LIBS= $(SYSLIBS) $(MYLIBS)
DEFAULT_INCLUDES = -I.
DEFS = -DHAVE_STDINT_H
ifeq ($(platform),Darwin)
AR= /usr/bin/ar rcs
RANLIB= /usr/bin/ranlib
else
AR= ar rcs
RANLIB= ranlib
endif
RM= rm -f
TST= echo
SYSLDFLAGS=
SYSLIBS=
MYLIBS=
MYOBJS=
$(LIB_A): $(CMDOBJS)
$(info [=] AR $@)
$(Q)$(AR) $(LIB_A) $(CMDOBJS)
$(Q)$(RANLIB) $(LIB_A)
all: $(LIB_A)
clean:
$(Q)$(RM) $(CLEAN)
$(Q)$(RM) $(LIB_A)
%.o: %.c
$(info [-] CC $<)
$(Q)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(CFLAGS) -c -o $@ $< $(LIBS)
.PHONY: all clean
include ../../Makefile.host

View file

@ -1,106 +1,27 @@
# Makefile for building Lua
# See ../doc/readme.html for installation and customization instructions.
MYSRCPATHS =
MYINCLUDES = -I.
# Lua lib is not ready for C99 style...
#MYCFLAGS = -std=c99 -D_ISOC99_SOURCE
MYCFLAGS =
MYDEFS = -DLUA_COMPAT_ALL $(SYSCFLAGS)
MYSRCS = lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c \
lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c \
ltm.c lundump.c lvm.c lzio.c \
lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c \
lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c
# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
SYSCFLAGS=
# Hide full compilation line:
ifneq ($(V),1)
Q?=@
endif
# To see full command lines, use make V=1
LIB_A= liblua.a
# Your platform. See PLATS for possible values.
PLAT= none
platform= $(shell uname)
CC= gcc
CFLAGS= -O3 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS)
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
LIBS= -lm $(SYSLIBS) $(MYLIBS)
ifeq ($(platform),Darwin)
AR= /usr/bin/ar rc
RANLIB= /usr/bin/ranlib
else
AR= ar rc
RANLIB= ranlib
endif
RM= rm -f
SYSCFLAGS=
SYSLDFLAGS=
SYSLIBS=
MYCFLAGS=
MYLDFLAGS=
MYLIBS=
MYOBJS=
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
%.o: %.c
$(info [-] CC $<)
$(Q)$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
LUA_A= liblua.a
CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
ltm.o lundump.o lvm.o lzio.o
LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \
lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o
BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)
LUA_T= lua
LUA_O= lua.o
LUAC_T= luac
LUAC_O= luac.o
ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
ALL_A= $(LUA_A)
# Targets start here.
default: $(PLAT)
all: $(ALL_T)
o: $(ALL_O)
a: $(ALL_A)
$(LUA_A): $(BASE_O)
$(info [=] AR $@)
$(Q)$(AR) $@ $(BASE_O)
$(Q)$(RANLIB) $@
$(LUA_T): $(LUA_O) $(LUA_A)
$(info [=] LD $@)
$(Q)$(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
$(LUAC_T): $(LUAC_O) $(LUA_A)
$(info [=] LD $@)
$(Q)$(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)
clean:
$(Q)$(RM) $(ALL_T) $(ALL_O)
depend:
$(info GEN DEPS)
$(Q)$(CC) $(CFLAGS) -MM l*.c
echo:
@echo "PLAT= $(PLAT)"
@echo "CC= $(CC)"
@echo "CFLAGS= $(CFLAGS)"
@echo "LDFLAGS= $(SYSLDFLAGS)"
@echo "LIBS= $(LIBS)"
@echo "AR= $(AR)"
@echo "RANLIB= $(RANLIB)"
@echo "RM= $(RM)"
include ../../Makefile.host
# Convenience targets for popular platforms
ALL= all
@ -110,99 +31,32 @@ none:
@echo " $(PLATS)"
aix:
$(Q)$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall"
$(Q)$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN"
ansi:
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI"
bsd:
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E"
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN"
freebsd:
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline"
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX"
generic: $(ALL)
linux:
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline -ltermcap -lncurses"
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX"
macosx:
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX"
mingw:
$(Q)$(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \
"AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
"SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe
$(Q)$(MAKE) "LUAC_T=luac.exe" luac.exe
$(Q)$(MAKE) $(ALL)
posix:
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX"
solaris:
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl"
# list targets that do not create files (but not all makes understand .PHONY)
.PHONY: all $(PLATS) default o a clean depend echo none
# DO NOT DELETE
lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \
lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h \
lvm.h
lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h
lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h
lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h
lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \
lstring.h ltable.h lvm.h
lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h
lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h
ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h
ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \
ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \
lfunc.h lstring.h lgc.h ltable.h lvm.h
ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \
lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \
lstring.h ltable.h lundump.h lvm.h
ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \
lzio.h lmem.h lundump.h
lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \
lstate.h ltm.h lzio.h lmem.h
lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h
liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h
llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \
lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h
lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h
lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
ltm.h lzio.h lmem.h ldo.h lgc.h
loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h
lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h
lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h
loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h
lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \
lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h \
lstring.h lgc.h ltable.h
lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \
ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \
ltable.h
lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \
ltm.h lzio.h lstring.h lgc.h
lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h
ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h
ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \
lmem.h lstring.h lgc.h ltable.h
lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h
luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \
ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h
lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h
lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \
lzio.h
$(Q)$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN"
.PHONY: all $(PLATS) default clean depend none

View file

@ -226,8 +226,8 @@ void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) {
reverse_arraybytes(dest, sizeof(dest));
memcpy(mac, dest, 4);
//free(cc_nr);
return;
}
void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4]) {
uint8_t *address_data;
uint8_t div_key[8];
@ -245,7 +245,6 @@ void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_ke
reverse_arraybytes(dest, sizeof(dest));
memcpy(mac, dest, 4);
free(address_data);
return;
}
#ifndef ON_DEVICE
@ -267,8 +266,8 @@ int testMAC() {
PrintAndLogEx(FAILED, "FAILED: MAC calculation failed:");
printarr(" Calculated_MAC", calculated_mac, 4);
printarr(" Correct_MAC ", correct_MAC, 4);
return 1;
return PM3_ESOFT;
}
return 0;
return PM3_SUCCESS;
}
#endif

View file

@ -39,6 +39,7 @@
#ifndef CIPHER_H
#define CIPHER_H
#include <stdint.h>
#include "pm3_cmd.h"
void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]);
void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4]);

View file

@ -39,7 +39,7 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "util.h" // sprint_hex
#include "commonutil.h" // ARRAYLEN
#include "fileutils.h"
@ -127,18 +127,21 @@ uint64_t x_bytes_to_num(uint8_t *src, size_t len) {
}
return num;
}
uint8_t reversebytes(uint8_t b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
void reverse_arraybytes(uint8_t *arr, size_t len) {
uint8_t i;
for (i = 0; i < len ; i++) {
arr[i] = reversebytes(arr[i]);
}
}
void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len) {
uint8_t i;
for (i = 0; i < len ; i++) {
@ -160,23 +163,14 @@ void printarr(const char *name, uint8_t *arr, int len) {
}
void printvar(const char *name, uint8_t *arr, int len) {
int cx, i;
size_t outsize = 40 + strlen(name) + len * 2;
char *output = calloc(outsize, sizeof(char));
cx = snprintf(output, outsize, "%s = ", name);
for (i = 0; i < len; i++) {
cx += snprintf(output + cx, outsize - cx, "%02x", *(arr + i)); //2 bytes per byte
}
PrintAndLogEx(NORMAL, output);
free(output);
PrintAndLogEx(NORMAL, "%s = " _YELLOW_("%s"), name, sprint_hex(arr, len));
}
void printarr_human_readable(const char *title, uint8_t *arr, int len) {
int cx, i;
int cx = 0, i;
size_t outsize = 100 + strlen(title) + len * 4;
char *output = calloc(outsize, sizeof(char));
cx = snprintf(output, outsize, "\n\t%s\n", title);
PrintAndLogEx(NORMAL, "\n %s", title);
for (i = 0; i < len; i++) {
if (i % 16 == 0)
cx += snprintf(output + cx, outsize - cx, "\n%02x| ", i);
@ -211,9 +205,9 @@ static int testBitStream() {
for (i = 0 ; i < ARRAYLEN(input) ; i++) {
PrintAndLogEx(NORMAL, " IN %02x, OUT %02x", input[i], output[i]);
}
return 1;
return PM3_ESOFT;
}
return 0;
return PM3_SUCCESS;
}
static int testReversedBitstream() {
@ -241,9 +235,9 @@ static int testReversedBitstream() {
for (i = 0 ; i < ARRAYLEN(input) ; i++) {
PrintAndLogEx(NORMAL, " IN %02x, MIDDLE: %02x, OUT %02x", input[i], reverse[i], output[i]);
}
return 1;
return PM3_ESOFT;
}
return 0;
return PM3_SUCCESS;
}

View file

@ -41,6 +41,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "pm3_cmd.h"
typedef struct {
uint8_t *buffer;

View file

@ -475,11 +475,11 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) {
memcpy(master_key, key64, 8);
if (memcmp(z_0, result, 4) != 0) {
PrintAndLogEx(WARNING, "Failed to verify calculated master key (k_cus)! Something is wrong.");
PrintAndLogEx(WARNING, _RED_("Failed to verify") "calculated master key (k_cus)! Something is wrong.");
return 1;
} else {
PrintAndLogEx(NORMAL, "\n");
PrintAndLogEx(SUCCESS, "Key verified ok!\n");
PrintAndLogEx(SUCCESS, _GREEN_("Key verified ok!"));
}
return 0;
}
@ -502,11 +502,19 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) {
for (i = 0 ; i * itemsize < dumpsize ; i++) {
memcpy(attack, dump + i * itemsize, itemsize);
errors += bruteforceItem(*attack, keytable);
if (errors)
break;
}
free(attack);
t1 = msclock() - t1;
PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds", t1 / 1000);
if (errors) {
PrintAndLogEx(ERR, "loclass exiting. Try run " _YELLOW_("`hf iclass sim 2`") "again and collect new data");
return 1;
}
// Pick out the first 16 bytes of the keytable.
// The keytable is now in 16-bit ints, where the upper 8 bits
// indicate crack-status. Those must be discarded for the
@ -516,8 +524,10 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) {
for (i = 0 ; i < 16 ; i++) {
first16bytes[i] = keytable[i] & 0xFF;
if (!(keytable[i] & CRACKED))
if (!(keytable[i] & CRACKED)) {
PrintAndLogEx(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i);
return 1;
}
}
errors += calculateMasterKey(first16bytes, NULL);
return errors;
@ -530,37 +540,14 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) {
* @return
*/
int bruteforceFile(const char *filename, uint16_t keytable[]) {
FILE *f = fopen(filename, "rb");
if (!f) {
PrintAndLogEx(WARNING, "Failed to read from file '%s'", filename);
return 1;
size_t dumplen = 0;
uint8_t *dump = NULL;
if (loadFile_safe(filename, "", (void **)&dump, &dumplen) != PM3_SUCCESS) {
return PM3_EFILE;
}
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
fseek(f, 0, SEEK_SET);
if (fsize <= 0) {
PrintAndLogEx(ERR, "Error, when getting filesize");
fclose(f);
return 1;
}
uint8_t *dump = calloc(fsize, sizeof(uint8_t));
if (!dump) {
PrintAndLogEx(WARNING, "Failed to allocate memory");
fclose(f);
return 2;
}
size_t bytes_read = fread(dump, 1, fsize, f);
fclose(f);
if (bytes_read < fsize) {
PrintAndLogEx(WARNING, "Warning: could only read %d bytes (should be %d)", bytes_read, fsize);
}
uint8_t res = bruteforceDump(dump, fsize, keytable);
uint8_t res = bruteforceDump(dump, dumplen, keytable);
free(dump);
return res;
}
@ -582,39 +569,30 @@ int bruteforceFileNoKeys(const char *filename) {
// TEST CODE BELOW
// ----------------------------------------------------------------------------
static int _testBruteforce() {
int errors = 0;
if (true) {
// First test
PrintAndLogEx(INFO, "Testing crack from dumpfile...");
/**
Expected values for the dumpfile:
High Security Key Table
PrintAndLogEx(INFO, "Testing crack from dumpfile...");
00 F1 35 59 A1 0D 5A 26 7F 18 60 0B 96 8A C0 25 C1
10 BF A1 3B B0 FF 85 28 75 F2 1F C6 8F 0E 74 8F 21
20 14 7A 55 16 C8 A9 7D B3 13 0C 5D C9 31 8D A9 B2
30 A3 56 83 0F 55 7E DE 45 71 21 D2 6D C1 57 1C 9C
40 78 2F 64 51 42 7B 64 30 FA 26 51 76 D3 E0 FB B6
50 31 9F BF 2F 7E 4F 94 B4 BD 4F 75 91 E3 1B EB 42
60 3F 88 6F B8 6C 2C 93 0D 69 2C D5 20 3C C1 61 95
70 43 08 A0 2F FE B3 26 D7 98 0B 34 7B 47 70 A0 AB
/**
Expected values for the dumpfile:
High Security Key Table
**** The 64-bit HS Custom Key Value = 5B7C62C491C11B39 ****
**/
uint16_t keytable[128] = {0};
00 F1 35 59 A1 0D 5A 26 7F 18 60 0B 96 8A C0 25 C1
10 BF A1 3B B0 FF 85 28 75 F2 1F C6 8F 0E 74 8F 21
20 14 7A 55 16 C8 A9 7D B3 13 0C 5D C9 31 8D A9 B2
30 A3 56 83 0F 55 7E DE 45 71 21 D2 6D C1 57 1C 9C
40 78 2F 64 51 42 7B 64 30 FA 26 51 76 D3 E0 FB B6
50 31 9F BF 2F 7E 4F 94 B4 BD 4F 75 91 E3 1B EB 42
60 3F 88 6F B8 6C 2C 93 0D 69 2C D5 20 3C C1 61 95
70 43 08 A0 2F FE B3 26 D7 98 0B 34 7B 47 70 A0 AB
//Test a few variants
if (fileExists("iclass_dump.bin")) {
errors |= bruteforceFile("iclass_dump.bin", keytable);
} else if (fileExists("loclass/iclass_dump.bin")) {
errors |= bruteforceFile("loclass/iclass_dump.bin", keytable);
} else if (fileExists("client/loclass/iclass_dump.bin")) {
errors |= bruteforceFile("client/loclass/iclass_dump.bin", keytable);
} else {
PrintAndLogEx(ERR, "Error: The file iclass_dump.bin was not found!");
}
**** The 64-bit HS Custom Key Value = 5B7C62C491C11B39 ****
**/
uint16_t keytable[128] = {0};
int errors = bruteforceFile("iclass_dump.bin", keytable);
if (errors) {
PrintAndLogEx(ERR, "Error: The file " _YELLOW_("iclass_dump.bin") "was not found!");
}
return errors;
}

Some files were not shown because too many files have changed in this diff Show more