Merge pull request #47 from RfidResearchGroup/master

Update
This commit is contained in:
mwalker33
2020-09-26 12:57:43 +10:00
committed by GitHub
103 changed files with 17927 additions and 778 deletions
+1
View File
@@ -32,6 +32,7 @@ version.c
*.swp
*.json.bak
*.pyc
*.bmp
# new build file for add-ons.
Makefile.platform
+2 -1
View File
@@ -3,7 +3,8 @@ 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]
- Add options to `lf read` and `lf cmdread` (@doegox)
- Add lf t55xx sniff to allow extracting commands and passwords used be cloners. (@mwalker33)
- Add options to `lf read`, `lf cmdread`, `lf sniff` for repeated acquisitions (@doegox)
- Change options of `lf read` to match `lf cmdread`, this affects historical `d` and `s` options (@doegox)
- Add `hf waveshare` to upload picture to Waveshare NFC-Powered e-Paper (@doegox)
- Add `hf 14a config` to deal with badly configured cards: invalid ATQA/BCC/SAK (@doegox)
+15 -13
View File
@@ -3,9 +3,9 @@
| Releases | Linux & OSX CI | Windows CI | Coverity |
| ------------------- |:-------------------:| -------------------:| -------------------:|
| [![Latest release](https://img.shields.io/github/v/release/rfidresearchgroup/proxmark3)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://api.travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)|
| Releases | Linux & OSX CI | Windows CI | Coverity | Contributors |
| ------------------- |:-------------------:| -------------------:| -------------------:| -------------------:|
| [![Latest release](https://img.shields.io/github/v/release/rfidresearchgroup/proxmark3)](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [![Build status](https://api.travis-ci.org/RfidResearchGroup/proxmark3.svg?branch=master)](https://travis-ci.org/RfidResearchGroup/proxmark3) | [![Build status](https://ci.appveyor.com/api/projects/status/b4gwrhq3nc876cuu/branch/master?svg=true)](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [![Coverity Status](https://scan.coverity.com/projects/19334/badge.svg)](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)| ![GitHub contributors](https://img.shields.io/github/contributors/rfidresearchgroup/proxmark3) |
@@ -57,14 +57,14 @@ On the software side: quite a lot, see the [Changelog file](CHANGELOG.md).
This repo compiles nicely on
- Proxspace v3.x
- [latest release v3.5](https://github.com/Gator96100/ProxSpace/releases)
- [latest release v3.6](https://github.com/Gator96100/ProxSpace/releases)
- Windows/mingw environment with Qt5.6.1 & GCC 4.9
- Ubuntu 1604 -> 2004
- Ubuntu 16.04 -> 20.04
- ParrotOS, Gentoo, Pentoo, Kali, Nethunter, Archlinux, Fedora, Debian
- Rasbian
- Android / Termux
- Mac OS X / Homebrew
- WSL, WSL2 (Windows subsystem linux) on Windows 10
- WSL1 (Windows subsystem linux) on Windows 10
- Docker container
- [ RRG / Iceman repo based ubuntu 18.04 container ](https://hub.docker.com/r/secopsconsult/proxmark3)
- [ Iceman fork based container v1.7 ](https://hub.docker.com/r/iceman1001/proxmark3/)
@@ -73,7 +73,7 @@ Hardware to run client on
- PC
- Android
- Raspberry Pi & Raspberry Pi Zero
- Jetson Nano
- Nvidia Jetson Nano
## Precompiled binaries
We don't maintain any precompiled binaries in this repo. There is community effort over at the Proxmark3 forum where @gator96100 has set up a google drive with many mingw binaries which is up-to-date. We link to these files here as to make it easier for users.
@@ -81,14 +81,15 @@ If you are having troubles with these files, contact the package maintainer @gat
Ref:
For Proxmark3 RDV4
- [Precompiled builds for RDV40 dedicated x86](https://drive.google.com/open?id=13zUs-aiQkYaSl5KWrBtuW5IWCoHJPsue)
- [Precompiled builds for RDV40 dedicated x64](https://drive.google.com/open?id=1SyPB8t5Vo8O0Lh7PjNm3Kv-mO4BNbxjX)
For Proxmark3 RDV4 with blueshark addon
- [Precompiled builds for RDV40 dedicated with Bluetooth addon x86](https://drive.google.com/open?id=1TqWYctkRvkLshQ1ZRBHPLDzYHR-asuMO)
- [Precompiled builds for RDV40 dedicated with Bluetooth addon x64](https://drive.google.com/open?id=17ful7u2QyYmMQzQzc5fAf8nJvyoDJfSL)
Generice Proxmark3 devices (non RDV4)
Generice Proxmark3 devices (non RDV4), for Proxmark3 Easy, RDV1, RDV2, RDV3, etc etc
- [Precompiled builds for RRG / Iceman repository x86](https://drive.google.com/open?id=1PI3Xr1mussPBPnYGu4ZjWzGPARK4N7JR)
- [Precompiled builds for RRG / Iceman repository x64](https://drive.google.com/open?id=1uX9RtYGinuFrpHybu4xq_BE3HrobI20e)
@@ -101,11 +102,12 @@ We usually merge your contributions fast since we do like the idea of getting a
## Issues & Troubleshooting
Please search the [issues](https://github.com/rfidresearchgroup/proxmark3/issues) page here and see if your issue is listed in the first instance. Next place to visit is the [Proxmark Forum](http://www.proxmark.org/forum/index.php). Learn to search it well and finally Google / duckduckgo is your friend :) You will find many blogposts, youtube videos, tweets, reddit
Please search the [issues](https://github.com/rfidresearchgroup/proxmark3/issues) page here and see if your issue is listed in the first instance.
Read the [Troubleshooting](/doc/md/Installation_Instructions/Troubleshooting.md) guide to weed out most known problems.
Offical channels
Next place to visit is the [Proxmark Forum](http://www.proxmark.org/forum/index.php). Learn to search it well and finally Google / duckduckgo is your friend :) You will find many blogposts, youtube videos, tweets, reddit
### Offical channels
- [Proxmark3 IRC channel](http://webchat.freenode.net/?channels=#proxmark3)
- [Proxmark3 sub reddit](https://www.reddit.com/r/proxmark3/)
- [Twitter](https://twitter.com/proxmark3/)
@@ -131,7 +133,7 @@ The separation from official Proxmark3 repo gives us a lot of freedom to create
## 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.
The new [Proxmark3 Universal GUI](https://github.com/burma69/PM3UniversalGUI) will work more or less. Change is needed in order to show helptext when client isn't connected to a device. We don't know how active the maintainers.
## The end
+136 -73
View File
@@ -7,6 +7,7 @@ environment:
proxspace_zip_folder_name: ProxSpace-*
proxspace_path: \ProxSpace
proxspace_home_path: \ProxSpace\pm3
wsl_git_path: C:\proxmark
init:
- ps: >-
@@ -34,14 +35,15 @@ clone_script:
- ps: >-
Function ExecUpdate($Text, $firstStart) {
Write-Host "$Text" -NoNewLine
Start-Process "cmd.exe" "/c ""cd /D $env:proxspace_path && call msys2\ps\setup.cmd && msys2\msys2_shell.cmd -mingw64 -defterm -no-start -c ""exit"""""
Write-Host "$Text"
Start-Process "cmd.exe" "/c ""cd /D $env:proxspace_path && runme64.bat -c ""exit"""""
$StartTime=[System.Environment]::TickCount
Start-Sleep -s 10
while($true) {
$cmdprocess = Get-Process "cmd" -ErrorAction SilentlyContinue
if (!$cmdprocess -Or $cmdprocess.HasExited) {
Write-Host "$Text" -NoNewLine
Write-Host "[ OK ]" -ForegroundColor Green
break
}
@@ -51,30 +53,67 @@ clone_script:
$tmp = $cmdprocess.CloseMainWindow()
Start-Sleep -s 5
Stop-Process -Name "cmd" -Force -ErrorAction SilentlyContinue
Write-Host "$Text" -NoNewLine
Write-Host "Exit by pacman.conf" -ForegroundColor Green
break
}
if ([System.Environment]::TickCount-$StartTime -gt 1000000) {
Write-Host "$Text" -NoNewLine
Write-host "Exit by timeout" -ForegroundColor Yellow
break
}
Start-Sleep -s 1
Start-Sleep -s 5
Receive-Job -Job $WSLjob
}
}
Write-Host "Removing ProxSpace..." -NoNewLine
$WSLjob = Start-Job -Name WSLInstall -ScriptBlock {
Function WSLExec($Text, $Cmd) {
Write-Host "$Text"
wsl -- bash -c $Cmd
Write-Host "$Text" -NoNewLine
Write-Host "[ OK ]" -ForegroundColor Green
}
$CloneTime=[System.Environment]::TickCount
$WSLInstallTime=[System.Environment]::TickCount
WSLExec "WSL update..." "sudo apt-get update 1>/dev/null"
WSLExec "WSL upgrade..." "sudo apt-get upgrade -y 1>/dev/null"
WSLExec "WSL cleanup..." "sudo apt-get auto-remove -y 1>/dev/null"
WSLExec "WSL install..." "sudo apt-get -y install --reinstall --no-install-recommends git ca-certificates build-essential pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev qtbase5-dev cmake 1>/dev/null"
WSLExec "WSL QT fix..." "sudo strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5"
Add-AppveyorMessage -Message "WSL setup took $(([System.Environment]::TickCount-$WSLInstallTime) / 1000) sec" -Category Information
}
Function GitClone($Text, $Folder) {
Write-Host "$Text" -NoNewLine
if(-not $env:appveyor_pull_request_number) {
git clone -q --branch=$env:appveyor_repo_branch https://github.com/$env:appveyor_repo_name.git $Folder
cd $Folder
git checkout -qf $env:appveyor_repo_commit
} else {
git clone -q https://github.com/$env:appveyor_repo_name.git $Folder
cd $Folder
git fetch -q origin +refs/pull/$env:appveyor_pull_request_number/merge:
git checkout -qf FETCH_HEAD
}
Write-Host "[ OK ]" -ForegroundColor Green
}
Write-Host "ProxSpace: Removing folder..." -NoNewLine
$PSInstallTime=[System.Environment]::TickCount
cd \
Remove-Item -Recurse -Force -Path $env:proxspace_path
Write-Host "[ OK ]" -ForegroundColor Green
Receive-Job -Job $WSLjob
Write-Host "Download ProxSpace..." -NoNewLine
Write-Host "ProxSpace: downloading..." -NoNewLine
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
@@ -82,7 +121,9 @@ clone_script:
Write-Host "[ OK ]" -ForegroundColor Green
Write-Host "Extracting ProxSpace..." -NoNewLine
Receive-Job -Job $WSLjob
Write-Host "ProxSpace: extracting..." -NoNewLine
Expand-Archive -LiteralPath "$env:proxspace_zip_file" -DestinationPath "\"
@@ -90,37 +131,30 @@ clone_script:
Write-Host "[ OK ]" -ForegroundColor Green
Write-Host "Renaming ProxSpace folder..." -NoNewLine
Receive-Job -Job $WSLjob
Write-Host "ProxSpace: renaming folder..." -NoNewLine
Get-ChildItem -Path "\$env:proxspace_zip_folder_name" | Rename-Item -NewName (Split-Path $env:proxspace_path -Leaf)
Write-Host "[ OK ]" -ForegroundColor Gree
ExecUpdate "Initial msys2 startup..." $true
ExecUpdate "ProxSpace: initial msys2 startup..." $true
ExecUpdate "Installing required packages..." $false
ExecUpdate "ProxSpace: installing required packages..." $false
$psversion = (Select-String -Pattern 'PSVERSION=' -SimpleMatch -Path "$env:proxspace_path\msys2\ps\09-proxspace_setup.post").Line.Split("""")[1]
Write-Host "ProxSpace version: $psversion" -ForegroundColor Yellow
Write-Host "Cloning repository <$env:appveyor_repo_name> to $env:appveyor_build_folder ..." -NoNewLine
if(-not $env:appveyor_pull_request_number) {
git clone -q --branch=$env:appveyor_repo_branch https://github.com/$env:appveyor_repo_name.git $env:appveyor_build_folder
cd $env:appveyor_build_folder
git checkout -qf $env:appveyor_repo_commit
} else {
git clone -q https://github.com/$env:appveyor_repo_name.git $env:appveyor_build_folder
cd $env:appveyor_build_folder
git fetch -q origin +refs/pull/$env:appveyor_pull_request_number/merge:
git checkout -qf FETCH_HEAD
}
Add-AppveyorMessage -Message "ProxSpace download and update took $(([System.Environment]::TickCount-$PSInstallTime) / 1000) sec" -Category Information
Write-Host "[ OK ]" -ForegroundColor Green
GitClone "ProxSpace: Cloning repository <$env:appveyor_repo_name> to $env:appveyor_build_folder ..." $env:appveyor_build_folder
Add-AppveyorMessage -Message "ProxSpace download and update took $(([System.Environment]::TickCount-$CloneTime) / 1000) sec" -Category Information
Receive-Job -Wait -Job $WSLjob
GitClone "WSL: Cloning repository <$env:appveyor_repo_name> to $env:wsl_git_path ..." $env:wsl_git_path
install:
@@ -131,90 +165,119 @@ build_script:
Function ExecMinGWCmd($Cmd) {
cd $env:proxspace_path
msys2\msys2_shell.cmd -mingw64 -defterm -no-start -c "cd $pmfolder && $Cmd"
./runme64.bat -c "cd $pmfolder && $Cmd"
}
Write-Host "---------- make ----------" -ForegroundColor Yellow
Function ExecCheck($Name) {
$testspass = ($LASTEXITCODE -eq 0)
$global:TestsPassed=$testspass
if ($testspass) {
Add-AppveyorTest -Name $Name -Framework NUnit -Filename $Name -Outcome Passed -Duration "$([System.Environment]::TickCount-$TestTime)"
Write-Host "$Name [ OK ]" -ForegroundColor Green
} else {
Add-AppveyorTest -Name $Name -Framework NUnit -Filename $Name -Outcome Failed -Duration "$([System.Environment]::TickCount-$TestTime)"
Write-Host "$Name [ ERROR ]" -ForegroundColor Red
throw "Tests error."
}
}
$WSLjob = Start-Job -Name WSLCompile -ScriptBlock {
Function ExecWSLCmd($Cmd) {
wsl -- bash -c $Cmd
}
Function ExecCheck($Name) {
$testspass = ($LASTEXITCODE -eq 0)
$global:TestsPassed=$testspass
if ($testspass) {
Add-AppveyorTest -Name $Name -Framework NUnit -Filename $Name -Outcome Passed -Duration "$([System.Environment]::TickCount-$TestTime)"
Write-Host "$Name [ OK ]" -ForegroundColor Green
} else {
Add-AppveyorTest -Name $Name -Framework NUnit -Filename $Name -Outcome Failed -Duration "$([System.Environment]::TickCount-$TestTime)"
Write-Host "$Name [ ERROR ]" -ForegroundColor Red
throw "Tests error."
}
}
#Windows Subsystem for Linux (WSL)
Write-Host "---------- WSL make ----------" -ForegroundColor Yellow
cd $env:wsl_git_path
$TestTime=[System.Environment]::TickCount
ExecWSLCmd "make clean;make V=1"
#some checks
if(!(Test-Path "$env:wsl_git_path\client\proxmark3")){
throw "Main file proxmark3 not exists."
}
ExecWSLCmd "make check"
ExecCheck "WSL make Tests"
Start-Sleep -s 2
Write-Host "---------- WSL btaddon ----------" -ForegroundColor Yellow
$TestTime=[System.Environment]::TickCount
ExecWSLCmd "make clean;make V=1 PLATFORM_EXTRAS=BTADDON"
ExecWSLCmd "make check"
ExecCheck "WSL BTaddon Tests"
Start-Sleep -s 2
Write-Host "---------- WSL make clean ----------" -ForegroundColor Yellow
ExecWSLCmd 'make clean'
Write-Host "---------- WSL cmake ----------" -ForegroundColor Yellow
$TestTime=[System.Environment]::TickCount
ExecWSLCmd 'mkdir -p client/build; cd client/build; cmake ..; make VERBOSE=1;'
Write-Host "---------- WSL cmake tests ----------" -ForegroundColor Yellow
ExecWSLCmd './tools/pm3_tests.sh --clientbin client/build/proxmark3 client'
ExecCheck "WSL cmake Tests"
}
#ProxSpace
Write-Host "---------- PS make ----------" -ForegroundColor Yellow
$TestTime=[System.Environment]::TickCount
#make
cd $env:proxspace_path
msys2\ps\setup.cmd
ExecMinGWCmd "make clean;make V=1"
#some checks
if(!(Test-Path "$env:proxspace_home_path\$pmfolder\client\proxmark3.exe")){
throw "Main file proxmark3.exe not exists."
throw "Main file proxmark3.exe not exists."
}
ExecMinGWCmd 'make check'
$testspass = ($LASTEXITCODE -eq 0)
ExecCheck "PS make Tests"
$global:TestsPassed=$testspass
if ($testspass) {
Add-AppveyorTest -Name "make Tests" -Framework NUnit -Filename "make check" -Outcome Passed -Duration "$([System.Environment]::TickCount-$TestTime)"
Write-Host "make Tests [ OK ]" -ForegroundColor Green
} else {
Add-AppveyorTest -Name "make Tests" -Framework NUnit -Filename "make check" -Outcome Failed -Duration "$([System.Environment]::TickCount-$TestTime)"
Write-Host "make Tests [ ERROR ]" -ForegroundColor Red
throw "Tests error."
}
Write-Host "---------- btaddon ----------" -ForegroundColor Yellow
Write-Host "---------- PS btaddon ----------" -ForegroundColor Yellow
$TestTime=[System.Environment]::TickCount
ExecMinGWCmd 'make clean;make V=1 PLATFORM_EXTRAS=BTADDON'
ExecMinGWCmd 'make check'
$testspass = ($LASTEXITCODE -eq 0)
$global:TestsPassed=(($global:TestsPassed) -and ($testspass))
if ($testspass) {
Add-AppveyorTest -Name "BTaddon Tests" -Framework NUnit -Filename "make check" -Outcome Passed -Duration "$([System.Environment]::TickCount-$TestTime)"
Write-Host "BTaddon Tests [ OK ]" -ForegroundColor Green
} else {
Add-AppveyorTest -Name "BTaddon Tests" -Framework NUnit -Filename "make check" -Outcome Failed -Duration "$([System.Environment]::TickCount-$TestTime)"
Write-Host "BTaddon Tests [ ERROR ]" -ForegroundColor Red
}
ExecCheck "PS BTaddon Tests"
Write-Host "---------- make clean ----------" -ForegroundColor Yellow
Write-Host "---------- PS make clean ----------" -ForegroundColor Yellow
ExecMinGWCmd 'make clean'
Write-Host "---------- cmake ----------" -ForegroundColor Yellow
Write-Host "---------- PS cmake ----------" -ForegroundColor Yellow
$TestTime=[System.Environment]::TickCount
ExecMinGWCmd 'mkdir -p client/build; cd client/build; cmake -G""MSYS Makefiles"" ..; make VERBOSE=1;'
Write-Host "---------- cmake tests ----------" -ForegroundColor Yellow
Write-Host "---------- PS cmake tests ----------" -ForegroundColor Yellow
ExecMinGWCmd './tools/pm3_tests.sh --clientbin client/build/proxmark3.exe client'
$testspass = ($LASTEXITCODE -eq 0)
$global:TestsPassed=(($global:TestsPassed) -and ($testspass))
ExecCheck "PS cmake Tests"
if ($testspass) {
Add-AppveyorTest -Name "cmake Tests" -Framework NUnit -Filename "make client/check" -Outcome Passed -Duration "$([System.Environment]::TickCount-$TestTime)"
Write-Host "cmake Tests [ OK ]" -ForegroundColor Green
} else {
Add-AppveyorTest -Name "cmake Tests" -Framework NUnit -Filename "make client/check" -Outcome Failed -Duration "$([System.Environment]::TickCount-$TestTime)"
Write-Host "cmake Tests [ ERROR ]" -ForegroundColor Red
}
Receive-Job -Wait -Job $WSLjob
test_script:
- ps: >-
+133 -8
View File
@@ -11,8 +11,15 @@
// Several parts of this code is based on code by Craig Young from HF_YOUNG
// This code does not:
// - Account for cards with authentication (MFU EV1 etc)
// - Determine if cards have block count that's not the same as the BLOCKS def
// - Account for cards with non-default keys on authentication (MFU EV1 etc)
// This code is designed to work with:
// - MIFARE Ultralight
// - MIFARE Ultralight EV1 (default keys)
// - MIFARE Ultralight Nano (untested, but should work)
// - Infineon My-d Move (without password set)
// - Infineon My-d Move Lean
// - Any other Ultralight clones that have no auth and MAX_DEFAULT_BLOCKS (16) blocks
#include "standalone.h" // standalone definitions
#include "proxmark3_arm.h"
@@ -22,10 +29,11 @@
#include "dbprint.h"
#include "ticks.h" // SpinDelay
#include "protocols.h" // MIFARE_ULEV1_VERSION, MIFARE_ULEV1_READSIG, MIFARE_ULEV1_READ_CNT, MIFARE_ULEV1_CHECKTEAR
#include <string.h> // memcmp
#include "mifareutil.h"
#include "iso14443a.h"
#define BLOCKS 16
#define SAK 0x00
#define ATQA0 0x44
#define ATQA1 0x00
@@ -34,6 +42,15 @@
#define STATE_READ 1
#define STATE_EMUL 2
// Taken from cmdhfmfu.c, increased by 01h to be 1 indexed
#define MAX_UL_BLOCKS 0x10
#define MAX_UL_NANO_40 0x0B
#define MAX_ULEV1a_BLOCKS 0x14
#define MAX_ULEV1b_BLOCKS 0x29
#define MAX_MY_D_MOVE 0x26
#define MAX_MY_D_MOVE_LEAN 0x10
#define MAX_DEFAULT_BLOCKS 0x10
typedef struct {
uint8_t uid[10];
uint8_t uidlen;
@@ -41,6 +58,70 @@ typedef struct {
uint8_t sak;
} PACKED card_clone_t;
int get_block_count(iso14a_card_select_t card, uint8_t version[], uint16_t version_len);
uint16_t get_ev1_version(iso14a_card_select_t card, uint8_t *version);
uint16_t get_ev1_signature(iso14a_card_select_t card, uint8_t *signature);
uint16_t get_ev1_counter(iso14a_card_select_t card, uint8_t counter, uint8_t *response);
uint16_t get_ev1_tearing(iso14a_card_select_t card, uint8_t counter, uint8_t *response);
uint16_t get_ev1_version(iso14a_card_select_t card, uint8_t *version) {
return mifare_sendcmd(MIFARE_ULEV1_VERSION, NULL, 0, version, NULL, NULL);
}
uint16_t get_ev1_signature(iso14a_card_select_t card, uint8_t *response) {
uint8_t cmd[4] = {MIFARE_ULEV1_READSIG, 0x00, 0x00, 0x00};
AddCrc14A(cmd, 2);
ReaderTransmit(cmd, sizeof(cmd), NULL);
return ReaderReceive(response, NULL);
}
uint16_t get_ev1_counter(iso14a_card_select_t card, uint8_t counter, uint8_t *response) {
uint8_t cmd[4] = {MIFARE_ULEV1_READ_CNT, counter, 0x00, 0x00};
AddCrc14A(cmd, 2);
ReaderTransmit(cmd, sizeof(cmd), NULL);
return ReaderReceive(response, NULL);
}
uint16_t get_ev1_tearing(iso14a_card_select_t card, uint8_t counter, uint8_t *response) {
uint8_t cmd[4] = {MIFARE_ULEV1_CHECKTEAR, counter, 0x00, 0x00};
AddCrc14A(cmd, 2);
ReaderTransmit(cmd, sizeof(cmd), NULL);
return ReaderReceive(response, NULL);
}
int get_block_count(iso14a_card_select_t card, uint8_t version[], uint16_t version_len) {
// Default to MAX_DEFAULT_BLOCKS blocks
int block_count = MAX_DEFAULT_BLOCKS;
// Most of this code is from cmdhfmfu.c
// Infineon manufacturer ID
if (card.uid[0] == 0x05) {
// Infinition MY-D tests Exam high nibble
uint8_t nib = (card.uid[1] & 0xf0) >> 4;
switch (nib) {
case 3:
block_count = MAX_MY_D_MOVE;
break; // or SLE 66R01P // 38 pages of 4 bytes
case 7:
block_count = MAX_MY_D_MOVE_LEAN;
break; // or SLE 66R01L // 16 pages of 4 bytes
}
} else {
// Moved this from case to if as I only care about non-ultralight ev0.
if (version_len == 0x0A) {
if (memcmp(version, "\x00\x04\x03\x01\x01\x00\x0B", 7) == 0) { block_count = MAX_ULEV1a_BLOCKS; }
else if (memcmp(version, "\x00\x04\x03\x01\x02\x00\x0B", 7) == 0) { block_count = MAX_UL_NANO_40; }
else if (memcmp(version, "\x00\x04\x03\x02\x01\x00\x0B", 7) == 0) { block_count = MAX_ULEV1a_BLOCKS; }
else if (memcmp(version, "\x00\x04\x03\x01\x01\x00\x0E", 7) == 0) { block_count = MAX_ULEV1b_BLOCKS; }
else if (memcmp(version, "\x00\x04\x03\x02\x01\x00\x0E", 7) == 0) { block_count = MAX_ULEV1b_BLOCKS; }
else if (memcmp(version, "\x00\x34\x21\x01\x01\x00\x0E", 7) == 0) { block_count = MAX_ULEV1b_BLOCKS; } // Mikron JSC Russia EV1 41 pages tag
else if (memcmp(version, "\x00\x34\x21\x01\x01\x00\x0E", 7) == 0) { block_count = MAX_UL_BLOCKS; }
else if (version[2] == 0x03) { block_count = MAX_ULEV1a_BLOCKS; }
}
}
return block_count;
}
void ModInfo(void) {
DbpString(" HF Mifare Ultralight read/simulation by Ave Ozkal");
}
@@ -88,33 +169,77 @@ void RunMod(void) {
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
iso14443a_select_card(NULL, NULL, NULL, true, 0, true);
bool read_successful = true;
// Get version and re-select card as UL EV0s like to shut off after a 0x60
uint8_t version[10] = {0x00};
uint16_t version_len = 0;
version_len = get_ev1_version(card, version);
iso14443a_select_card(NULL, NULL, NULL, true, 0, true);
int block_count = get_block_count(card, version, version_len);
Dbprintf("Card was determined as having %d blocks.", block_count);
Dbprintf("Contents:");
for (int i = 0; i < BLOCKS; i++) {
uint8_t dataout[4] = {0x00};
for (int i = 0; i < block_count; i++) {
uint8_t dataout[16] = {0x00};
if (mifare_ultra_readblock(i, dataout)) {
// If there's an error reading, go back to search state
read_successful = false;
break;
}
// We're skipping 14 blocks (56 bytes) here, as that "[...] has version/signature/counter data here" according to comments on dumptoemul-mfu
// We're skipping 14 blocks (56 bytes) here, as that "[...] has version/signature/counter data here" according to comments on hf_mfu_dumptoemulator
// When converting a bin, it's almost all 0 other than one 0x0F byte, and functionality seems to be unaffected if that byte is set to 0x00.
emlSetMem_xt(dataout, 14 + i, 1, 4);
Dbhexdump(4, dataout, 0);
}
// It's not the best way to determine this,
// but with what I'm trying to support It Should Be Okay
bool is_ev1 = (version_len != 0) && (block_count != 16);
if (read_successful) {
uint8_t signature[34] = {0x00};
if (is_ev1) {
get_ev1_signature(card, signature);
}
Dbprintf("Preparing emulator memory with:");
// Fill first 14 blocks with 0x00 (see comment above)
for (int i = 0; i < 14; i++) {
uint8_t dataout[4] = {0x00, 0x00, 0x00, 0x00};
if (is_ev1 && (i == 0 || i == 1)) {
// On block 0 and 1, set version on EV1
memcpy(dataout, version + (i * 4), 4);
} else if (i == 2) {
// On block 2, set last byte to the card's block count
dataout[3] = block_count;
} else if (is_ev1 && ((i > 2 && i < 11))) {
// On 3-10 add signature on EV1
memcpy(dataout, signature + ((i - 3) * 4), 4);
} else if (is_ev1 && (i > 10)) {
// On 11-14 read and set counter and tearing on EV1
uint8_t counter[5];
uint8_t tearing[3];
get_ev1_counter(card, i - 11, counter);
get_ev1_tearing(card, i - 11, tearing);
memcpy(dataout, counter, 3);
memcpy(dataout + 3, tearing, 1);
}
Dbhexdump(4, dataout, 0);
emlSetMem_xt(dataout, i, 1, 4);
}
Dbprintf("Successfully loaded into emulator memory...");
state = STATE_EMUL;
} else {
Dbprintf("Read failure, going back to search state.");
state = STATE_SEARCH;
}
} else if (state == 2) {
} else if (state == STATE_EMUL) {
uint8_t flags = FLAG_7B_UID_IN_DATA;
Dbprintf("Starting simulation, press pm3-button to stop and go back to search state.");
SimulateIso14443aTag(2, flags, card.uid);
SimulateIso14443aTag(7, flags, card.uid);
// Go back to search state if user presses pm3-button
state = STATE_SEARCH;
+2 -2
View File
@@ -15,7 +15,7 @@ The retrieved sniffing session can be acquired by connecting the device
to a client that supports the reconnect capability and issue 'hf 14a list'.
In order to view the grabbed authentication attempts in the flash mem,
you can simply run 'script run read_pwd_mem' or just 'mem dump p l 256'
you can simply run 'script run mem_readpwd' or just 'mem dump p l 256'
from the client to view the stored quadlets.
*/
@@ -249,5 +249,5 @@ void RunMod(void) {
LEDsoff();
SpinDelay(300);
Dbprintf("- [ End ] -> You can take shell back ...");
Dbprintf("- [ ! ] -> use 'script run read_pwd_mem_spiffs' to print passwords");
Dbprintf("- [ ! ] -> use 'script run data_read_pwd_mem_spiffs' to print passwords");
}
+18 -6
View File
@@ -770,18 +770,29 @@ static void PacketReceived(PacketCommandNG *packet) {
case CMD_LF_MOD_THEN_ACQ_RAW_ADC: {
struct p {
uint32_t delay;
uint16_t ones;
uint16_t zeros;
uint16_t period_0;
uint16_t period_1;
uint8_t symbol_extra[LF_CMDREAD_MAX_EXTRA_SYMBOLS];
uint16_t period_extra[LF_CMDREAD_MAX_EXTRA_SYMBOLS];
uint32_t samples : 31;
bool verbose : 1;
} PACKED;
struct p *payload = (struct p *)packet->data.asBytes;
ModThenAcquireRawAdcSamples125k(payload->delay, payload->zeros, payload->ones, packet->data.asBytes + sizeof(struct p), payload->verbose, payload->samples);
uint8_t symbol_extra[LF_CMDREAD_MAX_EXTRA_SYMBOLS];
uint16_t period_extra[LF_CMDREAD_MAX_EXTRA_SYMBOLS];
memcpy(symbol_extra, payload->symbol_extra, sizeof(symbol_extra));
memcpy(period_extra, payload->period_extra, sizeof(period_extra));
ModThenAcquireRawAdcSamples125k(payload->delay, payload->period_0, payload->period_1, symbol_extra, period_extra, packet->data.asBytes + sizeof(struct p), payload->verbose, payload->samples);
break;
}
case CMD_LF_SNIFF_RAW_ADC: {
uint32_t bits = SniffLF();
reply_mix(CMD_ACK, bits, 0, 0, 0, 0);
struct p {
uint32_t samples : 31;
bool verbose : 1;
} PACKED;
struct p *payload = (struct p *)packet->data.asBytes;
uint32_t bits = SniffLF(payload->verbose, payload->samples);
reply_ng(CMD_LF_SNIFF_RAW_ADC, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits));
break;
}
case CMD_LF_HID_WATCH: {
@@ -1344,7 +1355,8 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_MIFARE_CIDENT: {
MifareCIdent();
bool is_mfc = packet->data.asBytes[0];
MifareCIdent(is_mfc);
break;
}
// Gen 3 magic cards
+19 -6
View File
@@ -130,6 +130,8 @@ static int hitag2_init(void) {
#define HITAG_T_WAIT_2_MIN 90 /* T_wait2 should be at least 90 */
#define HITAG_T_WAIT_MAX 300 /* bit more than HITAG_T_WAIT_1 + HITAG_T_WAIT_2 */
#define HITAG_T_PROG 614
#define HITAG_T_WAIT_POWERUP 313 /* transponder internal powerup time is 312.5 */
#define HITAG_T_WAIT_START_AUTH_MAX 232 /* transponder waiting time to receive the START_AUTH command is 232.5, then it enters public mode */
#define HITAG_T_TAG_ONE_HALF_PERIOD 10
#define HITAG_T_TAG_TWO_HALF_PERIOD 25
@@ -1431,13 +1433,14 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
// init as reader
lf_init(true, false);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
uint8_t tag_modulation;
size_t max_nrzs = (8 * HITAG_FRAME_LEN + 5) * 2; // up to 2 nrzs per bit
uint8_t nrz_samples[max_nrzs];
bool turn_on = true;
size_t nrzs = 0;
int16_t checked = 0;
uint32_t signal_size = 10000;
while (bStop == false && BUTTON_PRESS() == false) {
@@ -1487,6 +1490,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
}
case RHT2F_UID_ONLY: {
bStop = !hitag2_read_uid(rx, rxlen, tx, &txlen);
if (bSuccessful) bStop = true;
attempt_count++; //attempt 3 times to get uid then quit
if (!bStop && attempt_count == 3)
bStop = true;
@@ -1498,11 +1502,20 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
goto out;
}
}
// Wait for t_wait_2 carrier periods after the last tag bit before transmitting,
lf_wait_periods(t_wait_2);
command_start += t_wait_2;
if (bStop) break;
if (turn_on) {
// Wait 50ms with field off to be sure the transponder gets reset
SpinDelay(50);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
turn_on = false;
// Wait with field on to be in "Wait for START_AUTH" timeframe
lf_wait_periods(HITAG_T_WAIT_POWERUP + HITAG_T_WAIT_START_AUTH_MAX / 4);
command_start += HITAG_T_WAIT_POWERUP + HITAG_T_WAIT_START_AUTH_MAX / 4;
} else {
// Wait for t_wait_2 carrier periods after the last tag bit before transmitting,
lf_wait_periods(t_wait_2);
command_start += t_wait_2;
}
// Transmit the reader frame
command_duration = hitag_reader_send_frame(tx, txlen);
response_start = command_start + command_duration;
+18 -9
View File
@@ -383,13 +383,15 @@ void loadT55xxConfig(void) {
* @param period_1
* @param command (in binary char array)
*/
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command, bool verbose, uint32_t samples) {
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint16_t period_0, uint16_t period_1, uint8_t *symbol_extra, uint16_t *period_extra, uint8_t *command, bool verbose, uint32_t samples) {
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// use lf config settings
sample_config *sc = getSamplingConfig();
LFSetupFPGAForADC(sc->divisor, true);
// this causes the field to turn on for uncontrolled amount of time, so we'll turn it off
// Make sure the tag is reset
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@@ -402,15 +404,14 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
// clear read buffer
BigBuf_Clear_keep_EM();
LFSetupFPGAForADC(sc->divisor, true);
// little more time for the tag to fully power up
WaitMS(20);
// if delay_off = 0 then just bitbang 1 = antenna on 0 = off for respective periods.
bool bitbang = (delay_off == 0);
// now modulate the reader field
// Some tags need to be interrogated very soon after activation else they enter their emulation mode
// Therefore it's up to the caller to add an initial symbol of adequate duration, except for bitbang mode.
if (bitbang) {
TurnReadLFOn(20000);
// HACK it appears the loop and if statements take up about 7us so adjust waits accordingly...
uint8_t hack_cnt = 7;
if (period_0 < hack_cnt || period_1 < hack_cnt) {
@@ -459,11 +460,19 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
} else { // old mode of cmd read using delay as off period
while (*command != '\0' && *command != ' ') {
LED_D_ON();
if (*(command++) == '0')
if (*command == '0') {
TurnReadLFOn(period_0);
else
} else if (*command == '1') {
TurnReadLFOn(period_1);
} else {
for (uint8_t i=0; i < LF_CMDREAD_MAX_EXTRA_SYMBOLS; i++) {
if (*command == symbol_extra[i]) {
TurnReadLFOn(period_extra[i]);
break;
}
}
}
command++;
LED_D_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(delay_off);
+1 -1
View File
@@ -15,7 +15,7 @@
#include "pm3_cmd.h" // struct
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command, bool verbose, uint32_t samples);
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint16_t period_0, uint16_t period_1, uint8_t *symbol_extra, uint16_t *period_extra, uint8_t *command, bool verbose, uint32_t samples);
void ReadTItag(void);
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
+6 -3
View File
@@ -243,8 +243,11 @@ void LFSetupFPGAForADC(int divisor, bool reader_field) {
StartTicks();
// 50ms for the resonant antenna to settle.
if (reader_field)
if (reader_field) {
WaitMS(50);
} else {
WaitMS(1);
}
}
/**
@@ -397,9 +400,9 @@ uint32_t SampleLF(bool verbose, uint32_t sample_size) {
* Initializes the FPGA for sniffer-mode (field off), and acquires the samples.
* @return number of bits sampled
**/
uint32_t SniffLF(void) {
uint32_t SniffLF(bool verbose, uint32_t sample_size) {
BigBuf_Clear_ext(false);
return ReadLF(false, true, 0);
return ReadLF(false, verbose, sample_size);
}
/**
+1 -1
View File
@@ -40,7 +40,7 @@ uint32_t SampleLF(bool verbose, uint32_t sample_size);
* Initializes the FPGA for sniff-mode (field off), and acquires the samples.
* @return number of bits sampled
**/
uint32_t SniffLF(void);
uint32_t SniffLF(bool verbose, uint32_t sample_size);
uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, int16_t trigger_threshold,
bool verbose, uint32_t sample_size, uint32_t cancel_after, int32_t samples_to_skip);
+31 -28
View File
@@ -1978,15 +1978,15 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype) {
uint64_t ui64Key = emlGetKey(sectorNo, keytype);
if (sectorNo == 0) {
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_FIRST)) {
retval = PM3_ESOFT;
retval = PM3_EPARTIAL;
if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth error", sectorNo);
goto out;
continue;
}
} else {
if (mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keytype, ui64Key, AUTH_NESTED)) {
retval = PM3_ESOFT;
retval = PM3_EPARTIAL;
if (DBGLEVEL > DBG_ERROR) Dbprintf("Sector[%2d]. Auth nested error", sectorNo);
goto out;
continue;
}
}
@@ -2236,14 +2236,14 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
OnSuccessMagic();
}
void MifareCIdent(void) {
void MifareCIdent(bool is_mfc) {
// variables
uint8_t isGen = 0;
uint8_t rec[1] = {0x00};
uint8_t recpar[1] = {0x00};
uint8_t rats[4] = { ISO14443A_CMD_RATS, 0x80, 0x31, 0x73 };
uint8_t rdbl[4] = { ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f};
uint8_t rdbl0[4] = { ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8};
uint8_t rdblf0[4] = { ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f};
uint8_t rdbl00[4] = { ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8};
uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE);
uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE);
uint8_t *uid = BigBuf_malloc(10);
@@ -2323,29 +2323,32 @@ void MifareCIdent(void) {
goto OUT;
}
// magic ntag test
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(40);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res == 2) {
ReaderTransmit(rdbl, sizeof(rdbl), NULL);
res = ReaderReceive(buf, par);
if (res == 18) {
isGen = MAGIC_NTAG21X;
if (! is_mfc) {
// magic ntag test
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(40);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res == 2) {
ReaderTransmit(rdblf0, sizeof(rdblf0), NULL);
res = ReaderReceive(buf, par);
if (res == 18) {
isGen = MAGIC_NTAG21X;
}
}
}
// magic MFC Gen3 test
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(40);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res == 2) {
ReaderTransmit(rdbl0, sizeof(rdbl0), NULL);
res = ReaderReceive(buf, par);
if (res == 18) {
isGen = MAGIC_GEN_3;
if (is_mfc) {
// magic MFC Gen3 test
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(40);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res == 2) {
ReaderTransmit(rdbl00, sizeof(rdbl00), NULL);
res = ReaderReceive(buf, par);
if (res == 18) {
isGen = MAGIC_GEN_3;
}
}
}
};
+1 -1
View File
@@ -41,7 +41,7 @@ int MifareECardLoadExt(uint8_t sectorcnt, 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);
void MifareCIdent(void); // is "magic chinese" card?
void MifareCIdent(bool is_mfc); // is "magic chinese" card?
void MifareHasStaticNonce(void); // Has the tag a static nonce?
int DoGen3Cmd(uint8_t *cmd, uint8_t cmd_len);
-3
View File
@@ -4,9 +4,6 @@
#include "common.h"
#include "usart_defs.h"
#define USART_BUFFLEN 512
#define USART_FIFOLEN (2*USART_BUFFLEN)
// Higher baudrates are pointless, only increasing overflow risk
extern uint32_t g_usart_baudrate;
+2 -2
View File
@@ -326,9 +326,9 @@ ifeq ($(SKIPQT),1)
else
ifeq ($(QT_FOUND),1)
ifeq ($(QT5_FOUND),1)
$(info GUI support: QT5 found, enabled)
$(info GUI support: QT5 found, enabled ($(shell QT_SELECT=5 qmake -v 2>/dev/null|grep -o 'Qt version.*')))
else
$(info GUI support: QT4 found, enabled)
$(info GUI support: QT4 found, enabled ($(shell QT_SELECT=4 qmake -v 2>/dev/null|grep -o 'Qt version.*')))
endif
else
$(info GUI support: QT not found, disabled)
+67
View File
@@ -1133,3 +1133,70 @@ c67beb41ffbf
c67beb41ffbf
b84d52971107
52b0d3f6116e
#
# Data from https://pastebin.com/cLSQQ9xN
ca3a24669d45
4087c6a75a96
160a91d29a9c
b7bf0c13066e
403f09848b87
d73438698eea
5f31f6fcd3a0
a0974382c4c5
a82045a10949
#
# Data from https://pastebin.com/2iV8h93h
#
# funnivarium
# forum ankara
#
2602FFFFFFFF
#
# macera adasi
# ankara kentpark
# INACTIVE
#
0A4600FF00FF
DFF293979FA7
4D6F62692E45
4118D7EF0902
#
# petrol ofisi
# positive card
# ode-gec
#
0406080A0C0E
#
# konya elkart
#
988ACDECDFB0
120D00FFFFFF
#
# bowlingo
# serdivan avym
#
4AE23A562A80
#
# kart54
#
2AFFD6F88B97
A9F3F289B70C
DB6819558A25
6130DFA578A0
B16B2E573235
42EF7BF572AB
274E6101FC5E
#
# crazy park
# kizilay avm
#
00DD300F4F10
#
# kartsistem B
#
FEE2A3FBC5B6
#
# toru ent
# taurus avm
#
005078565703
@@ -42,3 +42,5 @@ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
100f0e0d0c0b0a090807060504030201
404142434445464748494a4b4c4d4e4f
303132333435363738393a3b3c3d3e3f
9CABF398358405AE2F0E2B3D31C99A8A # Default key
605F5E5D5C5B5A59605F5E5D5C5B5A59 # access control
+1 -1
View File
@@ -27,4 +27,4 @@ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
100f0e0d0c0b0a090807060504030201
404142434445464748494a4b4c4d4e4f
303132333435363738393a3b3c3d3e3f
605F5E5D5C5B5A59605F5E5D5C5B5A59
@@ -9,11 +9,11 @@ desc = [[
This script calculates many checksums (CRC) over the provided hex input.
]]
example = [[
script run e -b 010203040506070809
script run e -b 010203040506070809 -w 16
script run data_hex_crc -b 010203040506070809
script run data_hex_crc -b 010203040506070809 -w 16
]]
usage = [[
script run e [-b <hex bytes] [-w <width>]
script run data_hex_crc [-b <hex bytes] [-w <width>]
]]
arguments = [[
-b data in hex

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