2010-02-21 08:47:22 +08:00
//-----------------------------------------------------------------------------
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
//
// 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.
//-----------------------------------------------------------------------------
// Low frequency EM4x commands
//-----------------------------------------------------------------------------
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
# include "cmdlfem4x.h"
2015-06-15 05:02:52 +08:00
2019-08-08 22:57:33 +08:00
# include <stdio.h>
# include <string.h>
# include <inttypes.h>
# include <ctype.h>
# include <stdlib.h>
# include "cmdparser.h" // command_t
# include "comms.h"
# include "commonutil.h"
# include "util_posix.h"
# include "protocols.h"
# include "ui.h"
# include "graph.h"
# include "cmddata.h"
# include "cmdlf.h"
# include "lfdemod.h"
2016-10-20 07:50:30 +08:00
uint64_t g_em410xid = 0 ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
static int CmdHelp ( const char * Cmd ) ;
2017-07-30 15:17:48 +08:00
//////////////// 410x commands
2019-04-10 19:06:05 +08:00
static int usage_lf_em410x_demod ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Usage: lf em 410x_demod [h] [clock] <0|1> [maxError] " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h - this help " ) ;
PrintAndLogEx ( NORMAL , " clock - set clock as integer, optional, if not set, autodetect. " ) ;
PrintAndLogEx ( NORMAL , " <0|1> - 0 normal output, 1 for invert output " ) ;
PrintAndLogEx ( NORMAL , " maxerror - set maximum allowed errors, default = 100. " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_demod = demod an EM410x Tag ID from GraphBuffer " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_demod 32 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_demod 32 1 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_demod 1 = demod an EM410x Tag ID from GraphBuffer while inverting data " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_demod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
2019-04-10 19:06:05 +08:00
static int usage_lf_em410x_write ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Writes EM410x ID to a T55x7 / T5555 (Q5) tag " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf em 410x_write [h] <id> <card> [clock] " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h - this help " ) ;
PrintAndLogEx ( NORMAL , " <id> - ID number " ) ;
PrintAndLogEx ( NORMAL , " <card> - 0|1 T5555 (Q5) / T55x7 " ) ;
PrintAndLogEx ( NORMAL , " <clock> - 16|32|40|64, optional, set R/F clock rate, defaults to 64 " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_write 0F0368568B 1 = write ID to t55x7 card " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
2019-04-10 19:06:05 +08:00
static int usage_lf_em410x_ws ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Watch 'nd Spoof, activates reader, waits until a EM410x tag gets presented then it starts simulating the found UID " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf em 410x_spoof [h] " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h - this help " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_spoof " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
2019-04-10 19:06:05 +08:00
static int usage_lf_em410x_sim ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Simulating EM410x tag " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf em 410x_sim [h] <uid> <clock> " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h - this help " ) ;
PrintAndLogEx ( NORMAL , " uid - uid (10 HEX symbols) " ) ;
PrintAndLogEx ( NORMAL , " clock - clock (32|64) (optional) " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_sim 0F0368568B " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_sim 0F0368568B 32 " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-02-27 21:04:50 +08:00
}
2019-04-10 19:06:05 +08:00
static int usage_lf_em410x_brute ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Bruteforcing by emulating EM410x tag " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf em 410x_brute [h] ids.txt [d 2000] [c clock] " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h - this help " ) ;
PrintAndLogEx ( NORMAL , " ids.txt - file with UIDs in HEX format, one per line " ) ;
PrintAndLogEx ( NORMAL , " d (2000) - pause delay in milliseconds between UIDs simulation, default 1000 ms (optional) " ) ;
PrintAndLogEx ( NORMAL , " c (32) - clock (32|64), default 64 (optional) " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_brute ids.txt " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_brute ids.txt c 32 " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_brute ids.txt d 3000 " ) ;
PrintAndLogEx ( NORMAL , " lf em 410x_brute ids.txt d 3000 c 32 " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
2017-02-27 21:04:50 +08:00
2017-07-30 15:17:48 +08:00
//////////////// 4050 / 4450 commands
2019-04-10 19:06:05 +08:00
static int usage_lf_em4x50_dump ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Dump EM4x50/EM4x69. Tag must be on antenna. " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf em 4x50_dump [h] <pwd> " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h - this help " ) ;
PrintAndLogEx ( NORMAL , " pwd - password (hex) (optional) " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x50_dump " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x50_dump 11223344 " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
2019-04-10 19:06:05 +08:00
static int usage_lf_em4x50_read ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Read EM 4x50/EM4x69. Tag must be on antenna. " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf em 4x50_read [h] <address> <pwd> " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h - this help " ) ;
PrintAndLogEx ( NORMAL , " address - memory address to read. (0-15) " ) ;
PrintAndLogEx ( NORMAL , " pwd - password (hex) (optional) " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x50_read 1 " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x50_read 1 11223344 " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
2019-04-10 19:06:05 +08:00
static int usage_lf_em4x50_write ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Write EM 4x50/4x69. Tag must be on antenna. " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf em 4x50_write [h] <address> <data> <pwd> " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h - this help " ) ;
PrintAndLogEx ( NORMAL , " address - memory address to write to. (0-15) " ) ;
PrintAndLogEx ( NORMAL , " data - data to write (hex) " ) ;
PrintAndLogEx ( NORMAL , " pwd - password (hex) (optional) " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x50_write 1 deadc0de " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x50_write 1 deadc0de 11223344 " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
//////////////// 4205 / 4305 commands
2019-04-10 19:06:05 +08:00
static int usage_lf_em4x05_dump ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Dump EM4x05/EM4x69. Tag must be on antenna. " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf em 4x05_dump [h] <pwd> " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h - this help " ) ;
PrintAndLogEx ( NORMAL , " pwd - password (hex) (optional) " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x05_dump " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x05_dump 11223344 " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
2019-04-10 19:06:05 +08:00
static int usage_lf_em4x05_read ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Read EM4x05/EM4x69. Tag must be on antenna. " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf em 4x05_read [h] <address> <pwd> " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h - this help " ) ;
PrintAndLogEx ( NORMAL , " address - memory address to read. (0-15) " ) ;
PrintAndLogEx ( NORMAL , " pwd - password (hex) (optional) " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x05_read 1 " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x05_read 1 11223344 " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
2019-04-10 19:06:05 +08:00
static int usage_lf_em4x05_write ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Write EM4x05/4x69. Tag must be on antenna. " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf em 4x05_write [h] <address> <data> <pwd> " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h - this help " ) ;
PrintAndLogEx ( NORMAL , " address - memory address to write to. (0-15) " ) ;
PrintAndLogEx ( NORMAL , " data - data to write (hex) " ) ;
PrintAndLogEx ( NORMAL , " pwd - password (hex) (optional) " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x05_write 1 deadc0de " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x05_write 1 deadc0de 11223344 " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
2019-04-10 19:06:05 +08:00
static int usage_lf_em4x05_info ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Tag information EM4205/4305/4469//4569 tags. Tag must be on antenna. " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf em 4x05_info [h] <pwd> " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h - this help " ) ;
PrintAndLogEx ( NORMAL , " pwd - password (hex) (optional) " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x05_info " ) ;
PrintAndLogEx ( NORMAL , " lf em 4x05_info deadc0de " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
2017-07-31 03:21:02 +08:00
/* Read the ID of an EM410x tag.
* Format :
* 1111 1111 1 < - - standard non - repeatable header
* XXXX [ row parity bit ] < - - 10 rows of 5 bits for our 40 bit tag ID
* . . . .
* CCCC < - - each bit here is parity for the 10 bits above in corresponding column
* 0 < - - stop bit , end of tag
*/
2017-07-30 15:17:48 +08:00
// Construct the graph for emulating an EM410X tag
2019-04-12 07:55:25 +08:00
static void ConstructEM410xEmulGraph ( const char * uid , const uint8_t clock ) {
2017-07-30 15:17:48 +08:00
2019-03-10 06:35:06 +08:00
int i , j , binary [ 4 ] , parity [ 4 ] ;
uint32_t n ;
/* clear our graph */
2019-05-22 20:32:30 +08:00
ClearGraph ( true ) ;
2019-06-08 03:40:33 +08:00
/* write 16 zero bit sledge */
2019-05-23 18:12:20 +08:00
for ( i = 0 ; i < 20 ; i + + )
2019-05-22 20:32:30 +08:00
AppendGraph ( false , clock , 0 ) ;
2019-03-10 06:35:06 +08:00
/* write 9 start bits */
for ( i = 0 ; i < 9 ; i + + )
AppendGraph ( false , clock , 1 ) ;
/* for each hex char */
parity [ 0 ] = parity [ 1 ] = parity [ 2 ] = parity [ 3 ] = 0 ;
2019-03-10 07:00:59 +08:00
for ( i = 0 ; i < 10 ; i + + ) {
2019-03-10 06:35:06 +08:00
/* read each hex char */
sscanf ( & uid [ i ] , " %1x " , & n ) ;
2019-03-10 07:00:59 +08:00
for ( j = 3 ; j > = 0 ; j - - , n / = 2 )
2019-03-10 06:35:06 +08:00
binary [ j ] = n % 2 ;
/* append each bit */
AppendGraph ( false , clock , binary [ 0 ] ) ;
AppendGraph ( false , clock , binary [ 1 ] ) ;
AppendGraph ( false , clock , binary [ 2 ] ) ;
AppendGraph ( false , clock , binary [ 3 ] ) ;
/* append parity bit */
AppendGraph ( false , clock , binary [ 0 ] ^ binary [ 1 ] ^ binary [ 2 ] ^ binary [ 3 ] ) ;
/* keep track of column parity */
parity [ 0 ] ^ = binary [ 0 ] ;
parity [ 1 ] ^ = binary [ 1 ] ;
parity [ 2 ] ^ = binary [ 2 ] ;
parity [ 3 ] ^ = binary [ 3 ] ;
}
/* parity columns */
AppendGraph ( false , clock , parity [ 0 ] ) ;
AppendGraph ( false , clock , parity [ 1 ] ) ;
AppendGraph ( false , clock , parity [ 2 ] ) ;
AppendGraph ( false , clock , parity [ 3 ] ) ;
/* stop bit */
AppendGraph ( true , clock , 0 ) ;
2017-07-30 15:17:48 +08:00
}
//by marshmellow
//print 64 bit EM410x ID in multiple formats
2019-03-10 18:20:22 +08:00
void printEM410x ( uint32_t hi , uint64_t id ) {
2017-07-30 15:17:48 +08:00
2019-03-10 06:35:06 +08:00
if ( ! id & & ! hi ) return ;
2019-07-24 06:52:24 +08:00
PrintAndLogEx ( SUCCESS , " EM410x%s pattern found " , ( hi ) ? " XL " : " " ) ;
2019-03-10 06:35:06 +08:00
2019-04-08 02:24:13 +08:00
uint64_t n = 1 ;
2019-03-10 07:00:59 +08:00
uint64_t id2lo = 0 ;
2019-04-08 16:33:06 +08:00
uint8_t m , i ;
2019-04-08 02:17:59 +08:00
for ( m = 5 ; m > 0 ; m - - ) {
2019-03-10 07:00:59 +08:00
for ( i = 0 ; i < 8 ; i + + ) {
2019-04-08 02:24:13 +08:00
id2lo = ( id2lo < < 1LL ) | ( ( id & ( n < < ( i + ( ( m - 1 ) * 8 ) ) ) ) > > ( i + ( ( m - 1 ) * 8 ) ) ) ;
2019-03-10 06:35:06 +08:00
}
}
2019-03-10 07:00:59 +08:00
if ( hi ) {
2019-03-10 06:35:06 +08:00
//output 88 bit em id
2019-05-22 20:32:30 +08:00
PrintAndLogEx ( NORMAL , " \n EM TAG ID : " _YELLOW_ ( " %06X%016 " PRIX64 ) , hi , id ) ;
2019-03-10 06:35:06 +08:00
} else {
//output 40 bit em id
2019-05-22 20:32:30 +08:00
PrintAndLogEx ( NORMAL , " \n EM TAG ID : " _YELLOW_ ( " %010 " PRIX64 ) , id ) ;
PrintAndLogEx ( NORMAL , " \n Possible de-scramble patterns \n " ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Unique TAG ID : %010 " PRIX64 , id2lo ) ;
PrintAndLogEx ( NORMAL , " HoneyWell IdentKey { " ) ;
PrintAndLogEx ( NORMAL , " DEZ 8 : %08 " PRIu64 , id & 0xFFFFFF ) ;
PrintAndLogEx ( NORMAL , " DEZ 10 : %010 " PRIu64 , id & 0xFFFFFFFF ) ;
2019-03-10 07:00:59 +08:00
PrintAndLogEx ( NORMAL , " DEZ 5.5 : %05 " PRIu64 " .%05 " PRIu64 , ( id > > 16LL ) & 0xFFFF , ( id & 0xFFFF ) ) ;
PrintAndLogEx ( NORMAL , " DEZ 3.5A : %03 " PRIu64 " .%05 " PRIu64 , ( id > > 32ll ) , ( id & 0xFFFF ) ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " DEZ 3.5B : %03 " PRIu64 " .%05 " PRIu64 , ( id & 0xFF000000 ) > > 24 , ( id & 0xFFFF ) ) ;
PrintAndLogEx ( NORMAL , " DEZ 3.5C : %03 " PRIu64 " .%05 " PRIu64 , ( id & 0xFF0000 ) > > 16 , ( id & 0xFFFF ) ) ;
PrintAndLogEx ( NORMAL , " DEZ 14/IK2 : %014 " PRIu64 , id ) ;
PrintAndLogEx ( NORMAL , " DEZ 15/IK3 : %015 " PRIu64 , id2lo ) ;
PrintAndLogEx ( NORMAL , " DEZ 20/ZK : %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 " %02 " PRIu64 ,
2019-03-10 07:00:59 +08:00
( id2lo & 0xf000000000 ) > > 36 ,
( id2lo & 0x0f00000000 ) > > 32 ,
( id2lo & 0x00f0000000 ) > > 28 ,
( id2lo & 0x000f000000 ) > > 24 ,
( id2lo & 0x0000f00000 ) > > 20 ,
( id2lo & 0x00000f0000 ) > > 16 ,
( id2lo & 0x000000f000 ) > > 12 ,
( id2lo & 0x0000000f00 ) > > 8 ,
( id2lo & 0x00000000f0 ) > > 4 ,
( id2lo & 0x000000000f )
) ;
uint64_t paxton = ( ( ( id > > 32 ) < < 24 ) | ( id & 0xffffff ) ) + 0x143e00 ;
PrintAndLogEx ( NORMAL , " } \n Other : %05 " PRIu64 " _%03 " PRIu64 " _%08 " PRIu64 , ( id & 0xFFFF ) , ( ( id > > 16LL ) & 0xFF ) , ( id & 0xFFFFFF ) ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Pattern Paxton : % " PRIu64 " [0x% " PRIX64 " ] " , paxton , paxton ) ;
uint32_t p1id = ( id & 0xFFFFFF ) ;
uint8_t arr [ 32 ] = { 0x00 } ;
int j = 23 ;
2019-04-08 02:17:59 +08:00
for ( int k = 0 ; k < 24 ; + + k , - - j ) {
arr [ k ] = ( p1id > > k ) & 1 ;
2019-03-10 06:35:06 +08:00
}
uint32_t p1 = 0 ;
p1 | = arr [ 23 ] < < 21 ;
p1 | = arr [ 22 ] < < 23 ;
p1 | = arr [ 21 ] < < 20 ;
p1 | = arr [ 20 ] < < 22 ;
p1 | = arr [ 19 ] < < 18 ;
p1 | = arr [ 18 ] < < 16 ;
p1 | = arr [ 17 ] < < 19 ;
p1 | = arr [ 16 ] < < 17 ;
p1 | = arr [ 15 ] < < 13 ;
p1 | = arr [ 14 ] < < 15 ;
p1 | = arr [ 13 ] < < 12 ;
p1 | = arr [ 12 ] < < 14 ;
p1 | = arr [ 11 ] < < 6 ;
p1 | = arr [ 10 ] < < 2 ;
p1 | = arr [ 9 ] < < 7 ;
p1 | = arr [ 8 ] < < 1 ;
p1 | = arr [ 7 ] < < 0 ;
p1 | = arr [ 6 ] < < 8 ;
p1 | = arr [ 5 ] < < 11 ;
p1 | = arr [ 4 ] < < 3 ;
p1 | = arr [ 3 ] < < 10 ;
p1 | = arr [ 2 ] < < 4 ;
p1 | = arr [ 1 ] < < 5 ;
p1 | = arr [ 0 ] < < 9 ;
PrintAndLogEx ( NORMAL , " Pattern 1 : %d [0x%X] " , p1 , p1 ) ;
uint16_t sebury1 = id & 0xFFFF ;
uint8_t sebury2 = ( id > > 16 ) & 0x7F ;
uint32_t sebury3 = id & 0x7FFFFF ;
PrintAndLogEx ( NORMAL , " Pattern Sebury : %d %d %d [0x%X 0x%X 0x%X] " , sebury1 , sebury2 , sebury3 , sebury1 , sebury2 , sebury3 ) ;
}
2017-07-30 15:17:48 +08:00
}
/* Read the ID of an EM410x tag.
* Format :
* 1111 1111 1 < - - standard non - repeatable header
* XXXX [ row parity bit ] < - - 10 rows of 5 bits for our 40 bit tag ID
* . . . .
* CCCC < - - each bit here is parity for the 10 bits above in corresponding column
* 0 < - - stop bit , end of tag
*/
2019-03-10 18:20:22 +08:00
int AskEm410xDecode ( bool verbose , uint32_t * hi , uint64_t * lo ) {
2019-03-10 06:35:06 +08:00
size_t idx = 0 ;
uint8_t bits [ 512 ] = { 0 } ;
size_t size = sizeof ( bits ) ;
2019-04-07 03:46:00 +08:00
if ( ! getDemodBuff ( bits , & size ) ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - Em410x problem during copy from ASK demod " ) ;
2019-05-22 20:32:30 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
int ans = Em410xDecode ( bits , & size , & idx , hi , lo ) ;
2019-03-10 07:00:59 +08:00
if ( ans < 0 ) {
2019-03-10 06:35:06 +08:00
if ( ans = = - 2 )
PrintAndLogEx ( DEBUG , " DEBUG: Error - Em410x not enough samples after demod " ) ;
else if ( ans = = - 4 )
PrintAndLogEx ( DEBUG , " DEBUG: Error - Em410x preamble not found " ) ;
else if ( ans = = - 5 )
PrintAndLogEx ( DEBUG , " DEBUG: Error - Em410x Size not correct: %d " , size ) ;
else if ( ans = = - 6 )
PrintAndLogEx ( DEBUG , " DEBUG: Error - Em410x parity failed " ) ;
2019-05-22 20:32:30 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
if ( ! lo & & ! hi ) {
PrintAndLogEx ( DEBUG , " DEBUG: Error - Em410x decoded to all zeros " ) ;
2019-05-22 20:32:30 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
//set GraphBuffer for clone or sim command
2019-04-07 03:46:00 +08:00
setDemodBuff ( DemodBuffer , ( size = = 40 ) ? 64 : 128 , idx + 1 ) ;
2019-03-10 07:00:59 +08:00
setClockGrid ( g_DemodClock , g_DemodStartIdx + ( ( idx + 1 ) * g_DemodClock ) ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Em410x idx: %d, Len: %d, Printing Demod Buffer: " , idx , size ) ;
if ( g_debugMode )
printDemodBuff ( ) ;
if ( verbose )
printEM410x ( * hi , * lo ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
}
2019-05-23 18:12:20 +08:00
2019-03-10 18:20:22 +08:00
int AskEm410xDemod ( const char * Cmd , uint32_t * hi , uint64_t * lo , bool verbose ) {
2019-03-10 06:35:06 +08:00
bool st = true ;
2019-05-22 20:32:30 +08:00
// em410x simulation etc uses 0/1 as signal data. This must be converted in order to demod it back again
2019-06-08 03:40:33 +08:00
if ( isGraphBitstream ( ) ) {
2019-05-23 18:12:20 +08:00
convertGraphFromBitstream ( ) ;
2019-05-22 20:32:30 +08:00
}
2019-06-08 03:40:33 +08:00
if ( ASKDemod_ext ( Cmd , false , false , 1 , & st ) ! = PM3_SUCCESS )
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
return AskEm410xDecode ( verbose , hi , lo ) ;
2017-07-30 15:17:48 +08:00
}
2019-04-12 07:55:25 +08:00
/*
2017-07-31 03:21:02 +08:00
// this read loops on device side.
// uses the demod in lfops.c
2019-04-12 07:55:25 +08:00
static int CmdEM410xRead_device ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
char cmdp = tolower ( param_getchar ( Cmd , 0 ) ) ;
uint8_t findone = ( cmdp = = ' 1 ' ) ? 1 : 0 ;
2019-08-04 01:17:00 +08:00
SendCommandMIX ( CMD_LF_EM410X_DEMOD , findone , 0 , 0 , NULL , 0 ) ;
2019-05-22 21:28:12 +08:00
return PM3_SUCCESS ;
2014-12-30 04:32:53 +08:00
}
2019-04-12 07:55:25 +08:00
*/
2019-03-10 07:00:59 +08:00
//by marshmellow
2017-07-31 03:21:02 +08:00
//takes 3 arguments - clock, invert and maxErr as integers
//attempts to demodulate ask while decoding manchester
//prints binary found and saves in graphbuffer for further commands
2019-04-12 07:55:25 +08:00
static int CmdEM410xDemod ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
char cmdp = tolower ( param_getchar ( Cmd , 0 ) ) ;
if ( strlen ( Cmd ) > 10 | | cmdp = = ' h ' ) return usage_lf_em410x_demod ( ) ;
2019-03-09 15:59:13 +08:00
2019-03-10 06:35:06 +08:00
uint32_t hi = 0 ;
uint64_t lo = 0 ;
2015-04-03 00:48:52 +08:00
2019-06-08 03:40:33 +08:00
if ( AskEm410xDemod ( Cmd , & hi , & lo , true ) ! = PM3_SUCCESS )
return PM3_ESOFT ;
2019-03-09 15:59:13 +08:00
2019-03-10 06:35:06 +08:00
g_em410xid = lo ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}
2019-04-12 07:55:25 +08:00
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdEM410xRead ( const char * Cmd ) {
2019-08-14 04:57:54 +08:00
lf_read ( true , 12288 ) ;
2019-04-12 07:55:25 +08:00
return CmdEM410xDemod ( Cmd ) ;
}
2015-03-23 03:28:48 +08:00
// emulate an EM410X tag
2019-04-12 07:55:25 +08:00
static int CmdEM410xSim ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
char cmdp = tolower ( param_getchar ( Cmd , 0 ) ) ;
if ( cmdp = = ' h ' ) return usage_lf_em410x_sim ( ) ;
2017-02-08 05:26:06 +08:00
2019-03-10 06:35:06 +08:00
uint8_t uid [ 5 ] = { 0x00 } ;
2017-07-14 22:20:34 +08:00
2019-03-10 06:35:06 +08:00
/* clock is 64 in EM410x tags */
2019-05-22 20:32:30 +08:00
uint8_t clk = 64 ;
2015-01-05 22:51:27 +08:00
2019-03-10 06:35:06 +08:00
if ( param_gethex ( Cmd , 0 , uid , 10 ) ) {
PrintAndLogEx ( FAILED , " UID must include 10 HEX symbols " ) ;
2019-05-22 21:28:12 +08:00
return PM3_EINVARG ;
2019-03-10 06:35:06 +08:00
}
2019-03-09 15:59:13 +08:00
2019-05-22 20:32:30 +08:00
param_getdec ( Cmd , 1 , & clk ) ;
2019-03-09 15:59:13 +08:00
2019-05-22 20:32:30 +08:00
PrintAndLogEx ( SUCCESS , " Starting simulating UID " _YELLOW_ ( " %02X%02X%02X%02X%02X " ) " clock: " _YELLOW_ ( " %d " ) , uid [ 0 ] , uid [ 1 ] , uid [ 2 ] , uid [ 3 ] , uid [ 4 ] , clk ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( SUCCESS , " Press pm3-button to abort simulation " ) ;
2015-04-03 00:48:52 +08:00
2019-05-22 20:32:30 +08:00
ConstructEM410xEmulGraph ( Cmd , clk ) ;
2019-03-09 15:59:13 +08:00
2019-03-10 06:35:06 +08:00
CmdLFSim ( " 0 " ) ; //240 start_gap.
2019-05-22 21:28:12 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
2016-10-20 06:41:34 +08:00
2019-04-12 07:55:25 +08:00
static int CmdEM410xBrute ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
char filename [ FILE_PATH_SIZE ] = { 0 } ;
FILE * f = NULL ;
char buf [ 11 ] ;
uint32_t uidcnt = 0 ;
uint8_t stUidBlock = 20 ;
uint8_t * uidBlock = NULL , * p = NULL ;
uint8_t uid [ 5 ] = { 0x00 } ;
/* clock is 64 in EM410x tags */
2019-04-08 15:42:27 +08:00
uint8_t clock1 = 64 ;
2019-03-10 06:35:06 +08:00
/* default pause time: 1 second */
uint32_t delay = 1000 ;
char cmdp = tolower ( param_getchar ( Cmd , 0 ) ) ;
if ( cmdp = = ' h ' ) return usage_lf_em410x_brute ( ) ;
cmdp = tolower ( param_getchar ( Cmd , 1 ) ) ;
if ( cmdp = = ' d ' ) {
delay = param_get32ex ( Cmd , 2 , 1000 , 10 ) ;
2019-04-08 15:42:27 +08:00
param_getdec ( Cmd , 4 , & clock1 ) ;
2019-03-10 06:35:06 +08:00
} else if ( cmdp = = ' c ' ) {
2019-04-08 15:42:27 +08:00
param_getdec ( Cmd , 2 , & clock1 ) ;
2019-03-10 06:35:06 +08:00
delay = param_get32ex ( Cmd , 4 , 1000 , 10 ) ;
}
int filelen = param_getstr ( Cmd , 0 , filename , FILE_PATH_SIZE ) ;
if ( filelen = = 0 ) {
2019-07-14 06:35:18 +08:00
PrintAndLogEx ( ERR , " Error: Please specify a filename " ) ;
2019-05-22 20:32:30 +08:00
return PM3_EINVARG ;
2019-03-10 06:35:06 +08:00
}
if ( ( f = fopen ( filename , " r " ) ) = = NULL ) {
2019-07-14 06:35:18 +08:00
PrintAndLogEx ( ERR , " Error: Could not open UIDs file [ " _YELLOW_ ( " %s " ) " ] " , filename ) ;
2019-05-22 20:32:30 +08:00
return PM3_EFILE ;
2019-03-10 06:35:06 +08:00
}
uidBlock = calloc ( stUidBlock , 5 ) ;
if ( uidBlock = = NULL ) {
fclose ( f ) ;
2019-05-22 20:32:30 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
2019-03-10 07:00:59 +08:00
while ( fgets ( buf , sizeof ( buf ) , f ) ) {
2019-03-10 06:35:06 +08:00
if ( strlen ( buf ) < 10 | | buf [ 9 ] = = ' \n ' ) continue ;
while ( fgetc ( f ) ! = ' \n ' & & ! feof ( f ) ) ; //goto next line
//The line start with # is comment, skip
2019-03-10 07:00:59 +08:00
if ( buf [ 0 ] = = ' # ' ) continue ;
2019-03-10 06:35:06 +08:00
if ( param_gethex ( buf , 0 , uid , 10 ) ) {
PrintAndLogEx ( FAILED , " UIDs must include 10 HEX symbols " ) ;
free ( uidBlock ) ;
fclose ( f ) ;
2019-05-22 20:32:30 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
buf [ 10 ] = 0 ;
2019-03-10 07:00:59 +08:00
if ( stUidBlock - uidcnt < 2 ) {
p = realloc ( uidBlock , 5 * ( stUidBlock + = 10 ) ) ;
if ( ! p ) {
PrintAndLogEx ( WARNING , " Cannot allocate memory for UIDs " ) ;
free ( uidBlock ) ;
fclose ( f ) ;
2019-05-22 20:32:30 +08:00
return PM3_ESOFT ;
2019-03-10 07:00:59 +08:00
}
uidBlock = p ;
2019-03-10 06:35:06 +08:00
}
memset ( uidBlock + 5 * uidcnt , 0 , 5 ) ;
num_to_bytes ( strtoll ( buf , NULL , 16 ) , 5 , uidBlock + 5 * uidcnt ) ;
uidcnt + + ;
memset ( buf , 0 , sizeof ( buf ) ) ;
}
fclose ( f ) ;
if ( uidcnt = = 0 ) {
PrintAndLogEx ( FAILED , " No UIDs found in file " ) ;
free ( uidBlock ) ;
2019-05-22 20:32:30 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
2019-05-22 20:32:30 +08:00
PrintAndLogEx ( SUCCESS , " Loaded " _YELLOW_ ( " %d " ) " UIDs from " _YELLOW_ ( " %s " ) " , pause delay: " _YELLOW_ ( " %d " ) " ms " , uidcnt , filename , delay ) ;
2019-03-10 06:35:06 +08:00
// loop
2019-03-10 07:00:59 +08:00
for ( uint32_t c = 0 ; c < uidcnt ; + + c ) {
2019-03-10 06:35:06 +08:00
char testuid [ 11 ] ;
testuid [ 10 ] = 0 ;
2019-07-11 19:01:34 +08:00
if ( kbd_enter_pressed ( ) ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( WARNING , " \n Aborted via keyboard! \n " ) ;
free ( uidBlock ) ;
2019-05-22 20:32:30 +08:00
return PM3_EOPABORTED ;
2019-03-10 06:35:06 +08:00
}
2019-03-10 07:00:59 +08:00
sprintf ( testuid , " %010 " PRIX64 , bytes_to_num ( uidBlock + 5 * c , 5 ) ) ;
2019-04-08 15:42:27 +08:00
PrintAndLogEx ( NORMAL , " Bruteforce %d / %d: simulating UID %s, clock %d " , c + 1 , uidcnt , testuid , clock1 ) ;
2019-03-10 06:35:06 +08:00
2019-04-08 15:42:27 +08:00
ConstructEM410xEmulGraph ( testuid , clock1 ) ;
2019-03-10 06:35:06 +08:00
CmdLFSim ( " 0 " ) ; //240 start_gap.
msleep ( delay ) ;
}
free ( uidBlock ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}
2015-01-05 22:51:27 +08:00
/* Function is equivalent of lf read + data samples + em410xread
2019-03-09 15:59:13 +08:00
* looped until an EM410x tag is detected
*
2015-01-05 22:51:27 +08:00
* Why is CmdSamples ( " 16000 " ) ?
* TBD : Auto - grow sample size based on detected sample rate . IE : If the
* rate gets lower , then grow the number of samples
2019-03-09 15:59:13 +08:00
* Changed by martin , 4000 x 4 = 16000 ,
2015-01-05 22:51:27 +08:00
* see http : //www.proxmark.org/forum/viewtopic.php?pid=7235#p7235
2017-07-14 22:20:34 +08:00
*
2019-03-10 06:35:06 +08:00
* EDIT - - capture enough to get 2 complete preambles at the slowest data rate known to be used ( rf / 64 ) ( 64 * 64 * 2 + 9 = 8201 ) marshmellow
2015-01-05 22:51:27 +08:00
*/
2019-04-12 07:55:25 +08:00
static int CmdEM410xWatch ( const char * Cmd ) {
2019-04-10 18:23:40 +08:00
( void ) Cmd ; // Cmd is not used so far
2019-03-10 06:35:06 +08:00
do {
2019-07-11 19:01:34 +08:00
if ( kbd_enter_pressed ( ) ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( WARNING , " \n aborted via keyboard! \n " ) ;
break ;
}
2019-08-14 04:57:54 +08:00
lf_read ( true , 12288 ) ;
2019-03-10 06:35:06 +08:00
2019-05-22 20:32:30 +08:00
} while ( CmdEM410xRead ( " " ) ! = PM3_SUCCESS ) ;
return PM3_SUCCESS ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}
2015-04-03 00:48:52 +08:00
//currently only supports manchester modulations
2019-04-12 07:55:25 +08:00
static int CmdEM410xWatchnSpoof ( const char * Cmd ) {
2019-03-09 15:59:13 +08:00
2019-03-10 06:35:06 +08:00
char cmdp = tolower ( param_getchar ( Cmd , 0 ) ) ;
if ( cmdp = = ' h ' ) return usage_lf_em410x_ws ( ) ;
2019-03-09 15:59:13 +08:00
2019-03-10 06:35:06 +08:00
// loops if the captured ID was in XL-format.
CmdEM410xWatch ( Cmd ) ;
2019-05-22 20:32:30 +08:00
PrintAndLogEx ( SUCCESS , " # Replaying captured ID: " _YELLOW_ ( " %010 " PRIx64 ) , g_em410xid ) ;
2019-03-10 06:35:06 +08:00
CmdLFaskSim ( " " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2015-01-08 07:17:40 +08:00
}
2019-04-12 07:55:25 +08:00
static int CmdEM410xWrite ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
char cmdp = tolower ( param_getchar ( Cmd , 0 ) ) ;
if ( cmdp = = 0x00 | | cmdp = = ' h ' ) return usage_lf_em410x_write ( ) ;
uint64_t id = 0xFFFFFFFFFFFFFFFF ; // invalid id value
int card = 0xFF ; // invalid card value
2019-04-08 16:33:06 +08:00
uint32_t clock1 = 0 ; // invalid clock value
2019-03-10 06:35:06 +08:00
2019-04-08 16:33:06 +08:00
sscanf ( Cmd , " % " SCNx64 " %d %d " , & id , & card , & clock1 ) ;
2019-03-10 06:35:06 +08:00
// Check ID
if ( id = = 0xFFFFFFFFFFFFFFFF ) {
2019-07-14 06:35:18 +08:00
PrintAndLogEx ( ERR , " Error! ID is required. \n " ) ;
2019-05-22 20:32:30 +08:00
return PM3_EINVARG ;
2019-03-10 06:35:06 +08:00
}
if ( id > = 0x10000000000 ) {
2019-07-14 06:35:18 +08:00
PrintAndLogEx ( ERR , " Error! Given EM410x ID is longer than 40 bits. \n " ) ;
2019-05-22 20:32:30 +08:00
return PM3_EINVARG ;
2019-03-10 06:35:06 +08:00
}
// Check Card
if ( card = = 0xFF ) {
2019-07-14 06:35:18 +08:00
PrintAndLogEx ( ERR , " Error! Card type required. \n " ) ;
2019-05-22 20:32:30 +08:00
return PM3_EINVARG ;
2019-03-10 06:35:06 +08:00
}
if ( card < 0 ) {
2019-07-14 06:35:18 +08:00
PrintAndLogEx ( ERR , " Error! Bad card type selected. \n " ) ;
2019-05-22 20:32:30 +08:00
return PM3_EINVARG ;
2019-03-10 06:35:06 +08:00
}
// Check Clock
2019-04-08 16:33:06 +08:00
if ( clock1 = = 0 )
clock1 = 64 ;
2019-03-10 06:35:06 +08:00
// Allowed clock rates: 16, 32, 40 and 64
2019-04-08 16:33:06 +08:00
if ( ( clock1 ! = 16 ) & & ( clock1 ! = 32 ) & & ( clock1 ! = 64 ) & & ( clock1 ! = 40 ) ) {
2019-07-14 06:35:18 +08:00
PrintAndLogEx ( ERR , " Error! Clock rate " _YELLOW_ ( " %d " ) " not valid. Supported clock rates are 16, 32, 40 and 64. \n " , clock1 ) ;
2019-05-22 20:32:30 +08:00
return PM3_EINVARG ;
2019-03-10 06:35:06 +08:00
}
if ( card = = 1 ) {
2019-04-08 16:33:06 +08:00
PrintAndLogEx ( SUCCESS , " Writing %s tag with UID 0x%010 " PRIx64 " (clock rate: %d) " , " T55x7 " , id , clock1 ) ;
2019-03-10 06:35:06 +08:00
// NOTE: We really should pass the clock in as a separate argument, but to
// provide for backwards-compatibility for older firmware, and to avoid
2019-08-04 01:17:00 +08:00
// having to add another argument to CMD_LF_EM410X_WRITE, we just store
2019-03-10 06:35:06 +08:00
// the clock rate in bits 8-15 of the card value
2019-04-08 16:33:06 +08:00
card = ( card & 0xFF ) | ( ( clock1 < < 8 ) & 0xFF00 ) ;
2019-03-10 06:35:06 +08:00
} else if ( card = = 0 ) {
2019-04-08 16:33:06 +08:00
PrintAndLogEx ( SUCCESS , " Writing %s tag with UID 0x%010 " PRIx64 , " T5555 " , id , clock1 ) ;
card = ( card & 0xFF ) | ( ( clock1 < < 8 ) & 0xFF00 ) ;
2019-03-10 06:35:06 +08:00
} else {
PrintAndLogEx ( FAILED , " Error! Bad card type selected. \n " ) ;
2019-05-22 20:32:30 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
2019-08-04 01:17:00 +08:00
SendCommandMIX ( CMD_LF_EM410X_WRITE , card , ( uint32_t ) ( id > > 32 ) , ( uint32_t ) id , NULL , 0 ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2015-04-03 11:55:12 +08:00
}
2012-03-07 21:44:53 +08:00
2017-07-30 15:17:48 +08:00
//**************** Start of EM4x50 Code ************************
2019-04-14 03:54:04 +08:00
static bool EM_EndParityTest ( uint8_t * bs , size_t size , uint8_t rows , uint8_t cols , uint8_t pType ) {
2019-03-10 06:35:06 +08:00
if ( rows * cols > size ) return false ;
uint8_t colP = 0 ;
//assume last col is a parity and do not test
2019-03-10 07:00:59 +08:00
for ( uint8_t colNum = 0 ; colNum < cols - 1 ; colNum + + ) {
2019-03-10 06:35:06 +08:00
for ( uint8_t rowNum = 0 ; rowNum < rows ; rowNum + + ) {
colP ^ = bs [ ( rowNum * cols ) + colNum ] ;
}
if ( colP ! = pType ) return false ;
}
return true ;
2015-04-03 00:48:52 +08:00
}
2019-04-14 03:54:04 +08:00
static bool EM_ByteParityTest ( uint8_t * bs , size_t size , uint8_t rows , uint8_t cols , uint8_t pType ) {
2019-03-10 06:35:06 +08:00
if ( rows * cols > size ) return false ;
uint8_t rowP = 0 ;
//assume last row is a parity row and do not test
2019-03-10 07:00:59 +08:00
for ( uint8_t rowNum = 0 ; rowNum < rows - 1 ; rowNum + + ) {
2019-03-10 06:35:06 +08:00
for ( uint8_t colNum = 0 ; colNum < cols ; colNum + + ) {
rowP ^ = bs [ ( rowNum * cols ) + colNum ] ;
}
if ( rowP ! = pType ) return false ;
}
return true ;
2017-02-20 06:24:19 +08:00
}
// EM word parity test.
// 9*5 = 45 bits in total
// 012345678|r1
// 012345678|r2
// 012345678|r3
// 012345678|r4
// ------------
2019-03-09 15:59:13 +08:00
//c012345678| 0
2017-02-20 06:24:19 +08:00
// |- must be zero
2019-05-28 17:15:12 +08:00
/*
2019-05-22 21:28:12 +08:00
static int EMwordparitytest ( uint8_t * bits ) {
2017-02-20 06:24:19 +08:00
2019-03-10 06:35:06 +08:00
// last row/col parity must be 0
2019-05-22 21:28:12 +08:00
if ( bits [ 44 ] ! = 0 ) return PM3_ESOFT ;
2019-03-09 15:59:13 +08:00
2019-03-10 06:35:06 +08:00
// col parity check
2019-03-10 07:00:59 +08:00
uint8_t c1 = bytebits_to_byte ( bits , 8 ) ^ bytebits_to_byte ( bits + 9 , 8 ) ^ bytebits_to_byte ( bits + 18 , 8 ) ^ bytebits_to_byte ( bits + 27 , 8 ) ;
uint8_t c2 = bytebits_to_byte ( bits + 36 , 8 ) ;
2019-05-22 21:28:12 +08:00
if ( c1 ! = c2 ) return PM3_ESOFT ;
2017-02-20 06:24:19 +08:00
2019-03-10 06:35:06 +08:00
// row parity check
uint8_t rowP = 0 ;
2019-03-10 07:00:59 +08:00
for ( uint8_t i = 0 ; i < 36 ; + + i ) {
2017-02-20 06:24:19 +08:00
2019-03-10 06:35:06 +08:00
rowP ^ = bits [ i ] ;
2019-03-10 07:00:59 +08:00
if ( i > 0 & & ( i % 9 ) = = 0 ) {
2019-03-09 15:59:13 +08:00
2019-03-10 07:00:59 +08:00
if ( rowP ! = EVEN )
2019-05-22 21:28:12 +08:00
return PM3_ESOFT ;
2017-02-20 06:24:19 +08:00
2019-03-10 06:35:06 +08:00
rowP = 0 ;
}
}
// all checks ok.
2019-05-22 21:28:12 +08:00
return PM3_SUCCESS ;
2015-04-03 00:48:52 +08:00
}
2019-05-28 17:15:12 +08:00
*/
2015-04-03 00:48:52 +08:00
2017-02-19 07:12:35 +08:00
//////////////// 4050 / 4450 commands
2019-04-14 03:54:04 +08:00
static uint32_t OutputEM4x50_Block ( uint8_t * BitStream , size_t size , bool verbose , bool pTest ) {
2019-03-10 07:00:59 +08:00
if ( size < 45 ) return 0 ;
2019-03-10 06:35:06 +08:00
2019-03-10 07:00:59 +08:00
uint32_t code = bytebits_to_byte ( BitStream , 8 ) ;
code = code < < 8 | bytebits_to_byte ( BitStream + 9 , 8 ) ;
code = code < < 8 | bytebits_to_byte ( BitStream + 18 , 8 ) ;
code = code < < 8 | bytebits_to_byte ( BitStream + 27 , 8 ) ;
2019-03-10 06:35:06 +08:00
2019-03-10 07:00:59 +08:00
if ( verbose | | g_debugMode ) {
for ( uint8_t i = 0 ; i < 5 ; i + + ) {
2019-03-10 06:35:06 +08:00
if ( i = = 4 ) PrintAndLogEx ( NORMAL , " " ) ; //parity byte spacer
PrintAndLogEx ( NORMAL , " %d%d%d%d%d%d%d%d %d -> 0x%02x " ,
2019-03-10 07:00:59 +08:00
BitStream [ i * 9 ] ,
BitStream [ i * 9 + 1 ] ,
BitStream [ i * 9 + 2 ] ,
BitStream [ i * 9 + 3 ] ,
BitStream [ i * 9 + 4 ] ,
BitStream [ i * 9 + 5 ] ,
BitStream [ i * 9 + 6 ] ,
BitStream [ i * 9 + 7 ] ,
BitStream [ i * 9 + 8 ] ,
bytebits_to_byte ( BitStream + i * 9 , 8 )
) ;
2019-03-10 06:35:06 +08:00
}
2019-04-12 16:55:09 +08:00
PrintAndLogEx ( SUCCESS , " Parity checks | %s " , ( pTest ) ? _GREEN_ ( " Passed " ) : _RED_ ( " Fail " ) ) ;
2019-03-10 06:35:06 +08:00
}
return code ;
2015-04-03 00:48:52 +08:00
}
2017-02-19 07:12:35 +08:00
2017-02-13 17:58:28 +08:00
/* Read the transmitted data of an EM4x50 tag from the graphbuffer
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
* Format :
*
* XXXXXXXX [ row parity bit ( even ) ] < - 8 bits plus parity
* XXXXXXXX [ row parity bit ( even ) ] < - 8 bits plus parity
* XXXXXXXX [ row parity bit ( even ) ] < - 8 bits plus parity
* XXXXXXXX [ row parity bit ( even ) ] < - 8 bits plus parity
* CCCCCCCC < - column parity bits
* 0 < - stop bit
* LW < - Listen Window
*
* This pattern repeats for every block of data being transmitted .
* Transmission starts with two Listen Windows ( LW - a modulated
* pattern of 320 cycles each ( 32 / 32 / 128 / 64 / 64 ) ) .
*
* Note that this data may or may not be the UID . It is whatever data
* is stored in the blocks defined in the control word First and Last
* Word Read values . UID is stored in block 32.
*/
2019-03-10 07:00:59 +08:00
//completed by Marshmellow
2019-03-10 18:20:22 +08:00
int EM4x50Read ( const char * Cmd , bool verbose ) {
2019-03-10 07:00:59 +08:00
uint8_t fndClk [ ] = { 8 , 16 , 32 , 40 , 50 , 64 , 128 } ;
2019-03-10 06:35:06 +08:00
int clk = 0 , invert = 0 , tol = 0 , phaseoff ;
int i = 0 , j = 0 , startblock , skip , block , start , end , low = 0 , high = 0 , minClk = 255 ;
uint32_t Code [ 6 ] ;
char tmp [ 6 ] ;
char tmp2 [ 20 ] ;
bool complete = false ;
int tmpbuff [ MAX_GRAPH_TRACE_LEN / 64 ] ;
2019-03-10 07:00:59 +08:00
memset ( tmpbuff , 0 , sizeof ( tmpbuff ) ) ;
2019-03-10 06:35:06 +08:00
// get user entry if any
sscanf ( Cmd , " %i %i " , & clk , & invert ) ;
uint8_t bits [ MAX_GRAPH_TRACE_LEN ] = { 0 } ;
size_t size = getFromGraphBuf ( bits ) ;
computeSignalProperties ( bits , size ) ;
signal_t * sp = getSignalProperties ( ) ;
high = sp - > high ;
low = sp - > low ;
// get to first full low to prime loop and skip incomplete first pulse
2019-03-19 00:53:46 +08:00
while ( ( i < size ) & & ( bits [ i ] < high ) )
2019-03-10 06:35:06 +08:00
+ + i ;
2019-03-19 00:53:46 +08:00
while ( ( i < size ) & & ( bits [ i ] > low ) )
2019-03-10 06:35:06 +08:00
+ + i ;
skip = i ;
// populate tmpbuff buffer with pulse lengths
while ( i < size ) {
// measure from low to low
2019-03-19 00:53:46 +08:00
while ( ( i < size ) & & ( bits [ i ] > low ) )
2019-03-10 06:35:06 +08:00
+ + i ;
2019-03-10 07:00:59 +08:00
start = i ;
2019-03-19 00:53:46 +08:00
while ( ( i < size ) & & ( bits [ i ] < high ) )
2019-03-10 06:35:06 +08:00
+ + i ;
2019-03-19 00:53:46 +08:00
while ( ( i < size ) & & ( bits [ i ] > low ) )
2019-03-10 06:35:06 +08:00
+ + i ;
2019-03-10 07:00:59 +08:00
if ( j > = ( MAX_GRAPH_TRACE_LEN / 64 ) ) {
2019-03-10 06:35:06 +08:00
break ;
}
tmpbuff [ j + + ] = i - start ;
2019-03-10 07:00:59 +08:00
if ( i - start < minClk & & i < size ) {
2019-03-10 06:35:06 +08:00
minClk = i - start ;
}
}
// set clock
if ( ! clk ) {
for ( uint8_t clkCnt = 0 ; clkCnt < 7 ; clkCnt + + ) {
tol = fndClk [ clkCnt ] / 8 ;
if ( minClk > = fndClk [ clkCnt ] - tol & & minClk < = fndClk [ clkCnt ] + 1 ) {
clk = fndClk [ clkCnt ] ;
break ;
}
}
if ( ! clk ) {
2019-07-14 06:35:18 +08:00
if ( verbose | | g_debugMode ) PrintAndLogEx ( ERR , " Error: EM4x50 - didn't find a clock " ) ;
2019-05-22 21:28:12 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
} else tol = clk / 8 ;
// look for data start - should be 2 pairs of LW (pulses of clk*3,clk*2)
start = - 1 ;
2019-03-10 07:00:59 +08:00
for ( i = 0 ; i < j - 4 ; + + i ) {
2019-03-10 06:35:06 +08:00
skip + = tmpbuff [ i ] ;
if ( tmpbuff [ i ] > = clk * 3 - tol & & tmpbuff [ i ] < = clk * 3 + tol ) //3 clocks
2019-03-10 07:00:59 +08:00
if ( tmpbuff [ i + 1 ] > = clk * 2 - tol & & tmpbuff [ i + 1 ] < = clk * 2 + tol ) //2 clocks
if ( tmpbuff [ i + 2 ] > = clk * 3 - tol & & tmpbuff [ i + 2 ] < = clk * 3 + tol ) //3 clocks
if ( tmpbuff [ i + 3 ] > = clk - tol ) { //1.5 to 2 clocks - depends on bit following
start = i + 4 ;
2019-03-10 06:35:06 +08:00
break ;
}
}
startblock = i + 4 ;
// skip over the remainder of LW
2019-03-10 07:00:59 +08:00
skip + = ( tmpbuff [ i + 1 ] + tmpbuff [ i + 2 ] + clk ) ;
2019-03-10 06:35:06 +08:00
2019-03-10 07:00:59 +08:00
if ( tmpbuff [ i + 3 ] > clk )
phaseoff = tmpbuff [ i + 3 ] - clk ;
2019-03-10 06:35:06 +08:00
else
phaseoff = 0 ;
// now do it again to find the end
for ( i + = 3 ; i < j - 4 ; + + i ) {
if ( tmpbuff [ i ] > = clk * 3 - tol & & tmpbuff [ i ] < = clk * 3 + tol ) //3 clocks
2019-03-10 07:00:59 +08:00
if ( tmpbuff [ i + 1 ] > = clk * 2 - tol & & tmpbuff [ i + 1 ] < = clk * 2 + tol ) //2 clocks
if ( tmpbuff [ i + 2 ] > = clk * 3 - tol & & tmpbuff [ i + 2 ] < = clk * 3 + tol ) //3 clocks
if ( tmpbuff [ i + 3 ] > = clk - tol ) { //1.5 to 2 clocks - depends on bit following
complete = true ;
2019-03-10 06:35:06 +08:00
break ;
}
}
end = i ;
// report back
if ( verbose | | g_debugMode ) {
if ( start > = 0 ) {
PrintAndLogEx ( NORMAL , " \n Note: one block = 50 bits (32 data, 12 parity, 6 marker) " ) ;
} else {
2019-06-09 03:24:12 +08:00
PrintAndLogEx ( NORMAL , " No data found!, clock tried: " _YELLOW_ ( " %d " ) , clk ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Try again with more samples. " ) ;
2019-06-09 03:24:12 +08:00
PrintAndLogEx ( NORMAL , " or after a " _YELLOW_ ( " 'data askedge' " ) " command to clean up the read " ) ;
2019-05-22 21:28:12 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
2019-05-22 21:28:12 +08:00
} else if ( start < 0 ) return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
start = skip ;
2019-03-10 07:00:59 +08:00
snprintf ( tmp2 , sizeof ( tmp2 ) , " %d %d 1000 %d " , clk , invert , clk * 47 ) ;
2019-03-10 06:35:06 +08:00
// save GraphBuffer - to restore it later
save_restoreGB ( GRAPH_SAVE ) ;
// get rid of leading crap
snprintf ( tmp , sizeof ( tmp ) , " %i " , skip ) ;
CmdLtrim ( tmp ) ;
bool AllPTest = true ;
// now work through remaining buffer printing out data blocks
block = 0 ;
i = startblock ;
while ( block < 6 ) {
if ( verbose | | g_debugMode ) PrintAndLogEx ( NORMAL , " \n Block %i: " , block ) ;
skip = phaseoff ;
// look for LW before start of next block
2019-03-10 07:00:59 +08:00
for ( ; i < j - 4 ; + + i ) {
2019-03-10 06:35:06 +08:00
skip + = tmpbuff [ i ] ;
if ( tmpbuff [ i ] > = clk * 3 - tol & & tmpbuff [ i ] < = clk * 3 + tol )
2019-03-10 07:00:59 +08:00
if ( tmpbuff [ i + 1 ] > = clk - tol )
2019-03-10 06:35:06 +08:00
break ;
}
2019-03-10 07:00:59 +08:00
if ( i > = j - 4 ) break ; //next LW not found
2019-03-10 06:35:06 +08:00
skip + = clk ;
2019-03-10 07:00:59 +08:00
if ( tmpbuff [ i + 1 ] > clk )
phaseoff = tmpbuff [ i + 1 ] - clk ;
2019-03-10 06:35:06 +08:00
else
phaseoff = 0 ;
i + = 2 ;
2019-05-22 21:28:12 +08:00
if ( ASKDemod ( tmp2 , false , false , 1 ) ! = PM3_SUCCESS ) {
2019-03-10 06:35:06 +08:00
save_restoreGB ( GRAPH_RESTORE ) ;
2019-05-22 21:28:12 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
//set DemodBufferLen to just one block
2019-03-10 07:00:59 +08:00
DemodBufferLen = skip / clk ;
2019-03-10 06:35:06 +08:00
//test parities
2019-06-08 00:41:39 +08:00
bool pTest = EM_ByteParityTest ( DemodBuffer , DemodBufferLen , 5 , 9 , 0 ) ;
2019-03-10 07:00:59 +08:00
pTest & = EM_EndParityTest ( DemodBuffer , DemodBufferLen , 5 , 9 , 0 ) ;
2019-03-10 06:35:06 +08:00
AllPTest & = pTest ;
//get output
Code [ block ] = OutputEM4x50_Block ( DemodBuffer , DemodBufferLen , verbose , pTest ) ;
2019-03-10 07:00:59 +08:00
PrintAndLogEx ( DEBUG , " \n skipping %d samples, bits:%d " , skip , skip / clk ) ;
2019-03-10 06:35:06 +08:00
//skip to start of next block
snprintf ( tmp , sizeof ( tmp ) , " %i " , skip ) ;
CmdLtrim ( tmp ) ;
block + + ;
if ( i > = end ) break ; //in case chip doesn't output 6 blocks
}
//print full code:
2019-03-10 07:00:59 +08:00
if ( verbose | | g_debugMode | | AllPTest ) {
2019-03-10 06:35:06 +08:00
if ( ! complete ) {
2019-03-10 07:56:00 +08:00
PrintAndLogEx ( NORMAL , _RED_ ( " * **Warning! " ) ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Partial data - no end found! " ) ;
PrintAndLogEx ( NORMAL , " Try again with more samples. " ) ;
}
PrintAndLogEx ( NORMAL , " Found data at sample: %i - using clock: %i " , start , clk ) ;
end = block ;
2019-03-10 07:00:59 +08:00
for ( block = 0 ; block < end ; block + + ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Block %d: %08x " , block , Code [ block ] ) ;
}
2019-04-12 16:55:09 +08:00
PrintAndLogEx ( NORMAL , " Parities checks | %s " , ( AllPTest ) ? _GREEN_ ( " Passed " ) : _RED_ ( " Fail " ) ) ;
2019-03-10 06:35:06 +08:00
2019-05-22 21:28:12 +08:00
if ( AllPTest = = false ) {
2019-03-10 07:56:00 +08:00
PrintAndLogEx ( NORMAL , " Try cleaning the read samples with " _YELLOW_ ( " 'data askedge' " ) ) ;
2019-03-10 06:35:06 +08:00
}
}
//restore GraphBuffer
save_restoreGB ( GRAPH_RESTORE ) ;
2019-05-22 21:28:12 +08:00
return AllPTest ? PM3_SUCCESS : PM3_ESOFT ;
2015-04-03 00:48:52 +08:00
}
2019-04-12 07:55:25 +08:00
static int CmdEM4x50Read ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
uint8_t ctmp = tolower ( param_getchar ( Cmd , 0 ) ) ;
2019-03-10 07:00:59 +08:00
if ( ctmp = = ' h ' ) return usage_lf_em4x50_read ( ) ;
2019-03-10 06:35:06 +08:00
return EM4x50Read ( Cmd , true ) ;
2012-03-07 21:44:53 +08:00
}
2019-04-12 07:55:25 +08:00
static int CmdEM4x50Write ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
uint8_t ctmp = tolower ( param_getchar ( Cmd , 0 ) ) ;
2019-03-10 07:00:59 +08:00
if ( ctmp = = ' h ' ) return usage_lf_em4x50_write ( ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " no implemented yet " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2013-03-01 01:04:23 +08:00
}
2019-04-12 07:55:25 +08:00
static int CmdEM4x50Dump ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
uint8_t ctmp = tolower ( param_getchar ( Cmd , 0 ) ) ;
2019-03-10 07:00:59 +08:00
if ( ctmp = = ' h ' ) return usage_lf_em4x50_dump ( ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " no implemented yet " ) ;
2019-05-22 20:32:30 +08:00
return PM3_SUCCESS ;
2017-02-17 02:48:50 +08:00
}
# define EM_PREAMBLE_LEN 6
2017-02-23 07:03:10 +08:00
// download samples from device and copy to Graphbuffer
2019-04-14 03:54:04 +08:00
static bool downloadSamplesEM ( ) {
2019-03-09 15:59:13 +08:00
2019-03-10 06:35:06 +08:00
// 8 bit preamble + 32 bit word response (max clock (128) * 40bits = 5120 samples)
uint8_t got [ 6000 ] ;
2019-07-24 03:33:52 +08:00
if ( ! GetFromDevice ( BIG_BUF , got , sizeof ( got ) , 0 , NULL , 0 , NULL , 2500 , false ) ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( WARNING , " command execution time out " ) ;
return false ;
}
setGraphBuf ( got , sizeof ( got ) ) ;
// set signal properties low/high/mean/amplitude and is_noise detection
computeSignalProperties ( got , sizeof ( got ) ) ;
RepaintGraphWindow ( ) ;
if ( getSignalProperties ( ) - > isnoise ) {
PrintAndLogEx ( DEBUG , " No tag found - signal looks like noise " ) ;
return false ;
}
return true ;
2017-02-17 02:48:50 +08:00
}
2017-02-23 07:03:10 +08:00
2019-03-09 15:59:13 +08:00
// em_demod
2019-04-14 03:54:04 +08:00
static bool doPreambleSearch ( size_t * startIdx ) {
2019-03-09 15:59:13 +08:00
2019-03-10 06:35:06 +08:00
// sanity check
2019-03-10 07:00:59 +08:00
if ( DemodBufferLen < EM_PREAMBLE_LEN ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - EM4305 demodbuffer too small " ) ;
return false ;
}
// set size to 20 to only test first 14 positions for the preamble
size_t size = ( 20 > DemodBufferLen ) ? DemodBufferLen : 20 ;
* startIdx = 0 ;
// skip first two 0 bits as they might have been missed in the demod
2019-03-10 07:00:59 +08:00
uint8_t preamble [ EM_PREAMBLE_LEN ] = { 0 , 0 , 1 , 0 , 1 , 0 } ;
2019-03-10 06:35:06 +08:00
2019-03-10 07:00:59 +08:00
if ( ! preambleSearchEx ( DemodBuffer , preamble , EM_PREAMBLE_LEN , & size , startIdx , true ) ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - EM4305 preamble not found :: %d " , * startIdx ) ;
return false ;
}
return true ;
2017-02-15 23:58:29 +08:00
}
2019-04-14 03:54:04 +08:00
static bool detectFSK ( ) {
2019-03-10 06:35:06 +08:00
// detect fsk clock
2019-05-22 20:32:30 +08:00
if ( GetFskClock ( " " , false ) = = 0 ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - EM: FSK clock failed " ) ;
return false ;
}
// demod
int ans = FSKrawDemod ( " 0 0 " , false ) ;
2019-05-22 20:32:30 +08:00
if ( ans ! = PM3_SUCCESS ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - EM: FSK Demod failed " ) ;
return false ;
}
return true ;
2017-02-16 23:38:09 +08:00
}
// PSK clocks should be easy to detect ( but difficult to demod a non-repeating pattern... )
2019-04-14 03:54:04 +08:00
static bool detectPSK ( ) {
2019-03-10 06:35:06 +08:00
int ans = GetPskClock ( " " , false ) ;
if ( ans < = 0 ) {
PrintAndLogEx ( DEBUG , " DEBUG: Error - EM: PSK clock failed " ) ;
return false ;
}
//demod
//try psk1 -- 0 0 6 (six errors?!?)
ans = PSKDemod ( " 0 0 6 " , false ) ;
2019-05-22 20:32:30 +08:00
if ( ans ! = PM3_SUCCESS ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - EM: PSK1 Demod failed " ) ;
//try psk1 inverted
ans = PSKDemod ( " 0 1 6 " , false ) ;
2019-05-22 20:32:30 +08:00
if ( ans ! = PM3_SUCCESS ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - EM: PSK1 inverted Demod failed " ) ;
return false ;
}
}
// either PSK1 or PSK1 inverted is ok from here.
// lets check PSK2 later.
return true ;
2017-02-16 23:38:09 +08:00
}
// try manchester - NOTE: ST only applies to T55x7 tags.
2019-04-14 03:54:04 +08:00
static bool detectASK_MAN ( ) {
2019-03-10 06:35:06 +08:00
bool stcheck = false ;
2019-05-22 20:32:30 +08:00
if ( ASKDemod_ext ( " 0 0 0 " , false , false , 1 , & stcheck ) ! = PM3_SUCCESS ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - EM: ASK/Manchester Demod failed " ) ;
return false ;
}
return true ;
2017-02-16 23:38:09 +08:00
}
2019-04-14 03:54:04 +08:00
static bool detectASK_BI ( ) {
2019-03-10 06:35:06 +08:00
int ans = ASKbiphaseDemod ( " 0 0 1 " , false ) ;
2019-05-22 20:32:30 +08:00
if ( ans ! = PM3_SUCCESS ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - EM: ASK/biphase normal demod failed " ) ;
ans = ASKbiphaseDemod ( " 0 1 1 " , false ) ;
2019-05-22 20:32:30 +08:00
if ( ans ! = PM3_SUCCESS ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - EM: ASK/biphase inverted demod failed " ) ;
return false ;
}
}
return true ;
2017-02-16 23:38:09 +08:00
}
2017-02-15 23:58:29 +08:00
2017-02-17 02:48:50 +08:00
// param: idx - start index in demoded data.
2019-05-22 21:28:12 +08:00
static int setDemodBufferEM ( uint32_t * word , size_t idx ) {
2017-02-19 07:12:35 +08:00
2019-03-10 06:35:06 +08:00
//test for even parity bits.
uint8_t parity [ 45 ] = { 0 } ;
2019-03-10 07:00:59 +08:00
memcpy ( parity , DemodBuffer , 45 ) ;
2019-05-28 17:15:12 +08:00
if ( ! EM_EndParityTest ( DemodBuffer + idx + EM_PREAMBLE_LEN , 45 , 5 , 9 , 0 ) ) {
2019-06-08 03:40:33 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - End Parity check failed " ) ;
2019-05-22 21:28:12 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
2019-03-09 15:59:13 +08:00
// test for even parity bits and remove them. (leave out the end row of parities so 36 bits)
2019-03-10 06:35:06 +08:00
if ( ! removeParity ( DemodBuffer , idx + EM_PREAMBLE_LEN , 9 , 0 , 36 ) ) {
PrintAndLogEx ( DEBUG , " DEBUG: Error - EM, failed removing parity " ) ;
2019-05-22 21:28:12 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
2019-04-07 03:46:00 +08:00
setDemodBuff ( DemodBuffer , 32 , 0 ) ;
2019-03-10 06:35:06 +08:00
* word = bytebits_to_byteLSBF ( DemodBuffer , 32 ) ;
2019-05-22 21:28:12 +08:00
return PM3_SUCCESS ;
2017-02-16 23:38:09 +08:00
}
2017-02-15 23:58:29 +08:00
2019-03-09 15:59:13 +08:00
// FSK, PSK, ASK/MANCHESTER, ASK/BIPHASE, ASK/DIPHASE
2017-02-16 23:38:09 +08:00
// should cover 90% of known used configs
// the rest will need to be manually demoded for now...
2019-05-22 21:28:12 +08:00
static int demodEM4x05resp ( uint32_t * word ) {
2019-03-10 06:35:06 +08:00
size_t idx = 0 ;
* word = 0 ;
2019-03-10 07:00:59 +08:00
if ( detectASK_MAN ( ) & & doPreambleSearch ( & idx ) )
2019-03-10 06:35:06 +08:00
return setDemodBufferEM ( word , idx ) ;
2019-03-10 07:00:59 +08:00
if ( detectASK_BI ( ) & & doPreambleSearch ( & idx ) )
2019-03-10 06:35:06 +08:00
return setDemodBufferEM ( word , idx ) ;
2019-03-10 07:00:59 +08:00
if ( detectFSK ( ) & & doPreambleSearch ( & idx ) )
2019-03-10 06:35:06 +08:00
return setDemodBufferEM ( word , idx ) ;
if ( detectPSK ( ) ) {
2019-03-10 07:00:59 +08:00
if ( doPreambleSearch ( & idx ) )
2019-03-10 06:35:06 +08:00
return setDemodBufferEM ( word , idx ) ;
psk1TOpsk2 ( DemodBuffer , DemodBufferLen ) ;
2019-03-10 07:00:59 +08:00
if ( doPreambleSearch ( & idx ) )
2019-03-10 06:35:06 +08:00
return setDemodBufferEM ( word , idx ) ;
}
2019-05-22 21:28:12 +08:00
return PM3_ESOFT ;
2017-02-19 07:12:35 +08:00
}
//////////////// 4205 / 4305 commands
2019-04-14 03:54:04 +08:00
static int EM4x05ReadWord_ext ( uint8_t addr , uint32_t pwd , bool usePwd , uint32_t * word ) {
2019-05-28 17:15:12 +08:00
2019-06-08 03:40:33 +08:00
struct {
2019-05-28 17:15:12 +08:00
uint32_t password ;
uint8_t address ;
uint8_t usepwd ;
} PACKED payload ;
2019-06-08 03:40:33 +08:00
2019-05-28 17:15:12 +08:00
payload . password = pwd ;
payload . address = addr ;
payload . usepwd = usePwd ;
2019-06-08 03:40:33 +08:00
2019-03-10 06:35:06 +08:00
clearCommandBuffer ( ) ;
2019-08-04 01:17:00 +08:00
SendCommandNG ( CMD_LF_EM4X_READWORD , ( uint8_t * ) & payload , sizeof ( payload ) ) ;
2019-04-18 18:43:35 +08:00
PacketResponseNG resp ;
2019-08-04 01:17:00 +08:00
if ( ! WaitForResponseTimeout ( CMD_LF_EM4X_READWORD , & resp , 2500 ) ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " timeout while waiting for reply. " ) ;
2019-05-22 20:32:30 +08:00
return PM3_ETIMEOUT ;
2019-03-10 06:35:06 +08:00
}
2019-03-10 07:00:59 +08:00
if ( ! downloadSamplesEM ( ) ) {
2019-05-22 20:32:30 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
return demodEM4x05resp ( word ) ;
2017-02-27 04:32:51 +08:00
}
2019-04-12 07:55:25 +08:00
static int CmdEM4x05Dump ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
uint8_t addr = 0 ;
uint32_t pwd = 0 ;
bool usePwd = false ;
uint8_t ctmp = tolower ( param_getchar ( Cmd , 0 ) ) ;
2019-03-10 07:00:59 +08:00
if ( ctmp = = ' h ' ) return usage_lf_em4x05_dump ( ) ;
2019-03-10 06:35:06 +08:00
// for now use default input of 1 as invalid (unlikely 1 will be a valid password...)
pwd = param_get32ex ( Cmd , 0 , 1 , 16 ) ;
2019-03-10 07:00:59 +08:00
if ( pwd ! = 1 )
2019-03-10 06:35:06 +08:00
usePwd = true ;
2019-05-28 17:15:12 +08:00
int success = PM3_SUCCESS ;
2019-03-10 06:35:06 +08:00
uint32_t word = 0 ;
PrintAndLogEx ( NORMAL , " Addr | data | ascii " ) ;
PrintAndLogEx ( NORMAL , " -----+--------+------ " ) ;
for ( ; addr < 16 ; addr + + ) {
if ( addr = = 2 ) {
if ( usePwd ) {
2019-03-10 07:00:59 +08:00
PrintAndLogEx ( NORMAL , " %02u | %08X " , addr , pwd , word ) ;
2019-03-10 06:35:06 +08:00
} else {
2019-03-10 07:56:00 +08:00
PrintAndLogEx ( NORMAL , " 02 | " _RED_ ( " cannot read " ) ) ;
2019-03-10 06:35:06 +08:00
}
} else {
success & = EM4x05ReadWord_ext ( addr , pwd , usePwd , & word ) ;
}
}
return success ;
2017-02-15 23:58:29 +08:00
}
2017-02-27 04:32:51 +08:00
2019-04-12 07:55:25 +08:00
static int CmdEM4x05Read ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
uint8_t addr ;
uint32_t pwd ;
bool usePwd = false ;
uint8_t ctmp = tolower ( param_getchar ( Cmd , 0 ) ) ;
2019-03-10 07:00:59 +08:00
if ( strlen ( Cmd ) = = 0 | | ctmp = = ' h ' ) return usage_lf_em4x05_read ( ) ;
2019-03-10 06:35:06 +08:00
addr = param_get8ex ( Cmd , 0 , 50 , 10 ) ;
2019-05-28 17:15:12 +08:00
pwd = param_get32ex ( Cmd , 1 , 0xFFFFFFFF , 16 ) ;
2019-03-10 06:35:06 +08:00
if ( addr > 15 ) {
PrintAndLogEx ( NORMAL , " Address must be between 0 and 15 " ) ;
2019-05-28 17:15:12 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
2019-05-28 17:15:12 +08:00
if ( pwd = = 0xFFFFFFFF ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Reading address %02u " , addr ) ;
} else {
usePwd = true ;
PrintAndLogEx ( NORMAL , " Reading address %02u | password %08X " , addr , pwd ) ;
}
uint32_t word = 0 ;
2019-05-28 17:15:12 +08:00
int status = EM4x05ReadWord_ext ( addr , pwd , usePwd , & word ) ;
if ( status = = PM3_SUCCESS )
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Address %02d | %08X - %s " , addr , word , ( addr > 13 ) ? " Lock " : " " ) ;
else
2019-04-12 16:55:09 +08:00
PrintAndLogEx ( NORMAL , " Read Address %02d | " _RED_ ( " Fail " ) , addr ) ;
2019-05-28 17:15:12 +08:00
return status ;
2013-03-01 01:04:23 +08:00
}
2019-04-12 07:55:25 +08:00
static int CmdEM4x05Write ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
uint8_t ctmp = tolower ( param_getchar ( Cmd , 0 ) ) ;
2019-03-10 07:00:59 +08:00
if ( strlen ( Cmd ) = = 0 | | ctmp = = ' h ' ) return usage_lf_em4x05_write ( ) ;
2019-03-10 06:35:06 +08:00
bool usePwd = false ;
2019-04-05 15:20:37 +08:00
uint8_t addr ;
uint32_t data , pwd ;
2019-03-10 06:35:06 +08:00
addr = param_get8ex ( Cmd , 0 , 50 , 10 ) ;
data = param_get32ex ( Cmd , 1 , 0 , 16 ) ;
2019-05-28 17:15:12 +08:00
pwd = param_get32ex ( Cmd , 2 , 0xFFFFFFFF , 16 ) ;
2019-03-10 06:35:06 +08:00
2019-03-10 07:00:59 +08:00
if ( addr > 15 ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Address must be between 0 and 15 " ) ;
2019-05-22 21:28:12 +08:00
return PM3_EINVARG ;
2019-03-10 06:35:06 +08:00
}
2019-05-28 17:15:12 +08:00
if ( pwd = = 0xFFFFFFFF )
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Writing address %d data %08X " , addr , data ) ;
else {
usePwd = true ;
PrintAndLogEx ( NORMAL , " Writing address %d data %08X using password %08X " , addr , data , pwd ) ;
}
2019-06-08 03:40:33 +08:00
struct {
2019-05-28 17:15:12 +08:00
uint32_t password ;
uint32_t data ;
uint8_t address ;
uint8_t usepwd ;
} PACKED payload ;
2019-06-08 03:40:33 +08:00
2019-05-28 17:15:12 +08:00
payload . password = pwd ;
payload . data = data ;
payload . address = addr ;
payload . usepwd = usePwd ;
2019-06-08 03:40:33 +08:00
2019-03-10 06:35:06 +08:00
clearCommandBuffer ( ) ;
2019-08-04 01:17:00 +08:00
SendCommandNG ( CMD_LF_EM4X_WRITEWORD , ( uint8_t * ) & payload , sizeof ( payload ) ) ;
2019-04-18 18:43:35 +08:00
PacketResponseNG resp ;
2019-08-04 01:17:00 +08:00
if ( ! WaitForResponseTimeout ( CMD_LF_EM4X_WRITEWORD , & resp , 2000 ) ) {
2019-07-14 06:35:18 +08:00
PrintAndLogEx ( ERR , " Error occurred, device did not respond during write operation. " ) ;
2019-05-22 21:28:12 +08:00
return PM3_ETIMEOUT ;
2019-03-10 06:35:06 +08:00
}
if ( ! downloadSamplesEM ( ) )
2019-05-22 21:28:12 +08:00
return PM3_ENODATA ;
2019-03-10 06:35:06 +08:00
//need 0 bits demoded (after preamble) to verify write cmd
uint32_t dummy = 0 ;
2019-05-28 17:15:12 +08:00
int status = demodEM4x05resp ( & dummy ) ;
if ( status = = PM3_SUCCESS )
2019-03-10 07:56:00 +08:00
PrintAndLogEx ( NORMAL , " Write " _GREEN_ ( " Verified " ) ) ;
2019-03-10 06:35:06 +08:00
else
2019-03-10 07:56:00 +08:00
PrintAndLogEx ( NORMAL , " Write could " _RED_ ( " not " ) " be verified " ) ;
2019-05-28 17:15:12 +08:00
return status ;
2013-03-01 01:04:23 +08:00
}
2019-04-14 03:54:04 +08:00
static void printEM4x05config ( uint32_t wordData ) {
2019-03-10 07:00:59 +08:00
uint16_t datarate = ( ( ( wordData & 0x3F ) + 1 ) * 2 ) ;
2019-03-10 06:35:06 +08:00
uint8_t encoder = ( ( wordData > > 6 ) & 0xF ) ;
char enc [ 14 ] ;
2019-03-10 07:00:59 +08:00
memset ( enc , 0 , sizeof ( enc ) ) ;
2019-03-10 06:35:06 +08:00
uint8_t PSKcf = ( wordData > > 10 ) & 0x3 ;
char cf [ 10 ] ;
2019-03-10 07:00:59 +08:00
memset ( cf , 0 , sizeof ( cf ) ) ;
2019-03-10 06:35:06 +08:00
uint8_t delay = ( wordData > > 12 ) & 0x3 ;
char cdelay [ 33 ] ;
2019-03-10 07:00:59 +08:00
memset ( cdelay , 0 , sizeof ( cdelay ) ) ;
2019-03-10 06:35:06 +08:00
uint8_t numblks = EM4x05_GET_NUM_BLOCKS ( wordData ) ;
2019-03-10 07:00:59 +08:00
uint8_t LWR = numblks + 5 - 1 ; //last word read
2019-03-10 06:35:06 +08:00
switch ( encoder ) {
2019-03-10 07:00:59 +08:00
case 0 :
snprintf ( enc , sizeof ( enc ) , " NRZ " ) ;
break ;
case 1 :
snprintf ( enc , sizeof ( enc ) , " Manchester " ) ;
break ;
case 2 :
snprintf ( enc , sizeof ( enc ) , " Biphase " ) ;
break ;
case 3 :
snprintf ( enc , sizeof ( enc ) , " Miller " ) ;
break ;
case 4 :
snprintf ( enc , sizeof ( enc ) , " PSK1 " ) ;
break ;
case 5 :
snprintf ( enc , sizeof ( enc ) , " PSK2 " ) ;
break ;
case 6 :
snprintf ( enc , sizeof ( enc ) , " PSK3 " ) ;
break ;
case 7 :
snprintf ( enc , sizeof ( enc ) , " Unknown " ) ;
break ;
case 8 :
snprintf ( enc , sizeof ( enc ) , " FSK1 " ) ;
break ;
case 9 :
snprintf ( enc , sizeof ( enc ) , " FSK2 " ) ;
break ;
default :
snprintf ( enc , sizeof ( enc ) , " Unknown " ) ;
break ;
2019-03-10 06:35:06 +08:00
}
switch ( PSKcf ) {
2019-03-10 07:00:59 +08:00
case 0 :
snprintf ( cf , sizeof ( cf ) , " RF/2 " ) ;
break ;
case 1 :
snprintf ( cf , sizeof ( cf ) , " RF/8 " ) ;
break ;
case 2 :
snprintf ( cf , sizeof ( cf ) , " RF/4 " ) ;
break ;
case 3 :
snprintf ( cf , sizeof ( cf ) , " unknown " ) ;
break ;
2019-03-10 06:35:06 +08:00
}
switch ( delay ) {
2019-03-10 07:00:59 +08:00
case 0 :
snprintf ( cdelay , sizeof ( cdelay ) , " no delay " ) ;
break ;
case 1 :
snprintf ( cdelay , sizeof ( cdelay ) , " BP/8 or 1/8th bit period delay " ) ;
break ;
case 2 :
snprintf ( cdelay , sizeof ( cdelay ) , " BP/4 or 1/4th bit period delay " ) ;
break ;
case 3 :
snprintf ( cdelay , sizeof ( cdelay ) , " no delay " ) ;
break ;
2019-03-10 06:35:06 +08:00
}
2019-03-10 07:00:59 +08:00
uint8_t readLogin = ( wordData & EM4x05_READ_LOGIN_REQ ) > > 18 ;
uint8_t readHKL = ( wordData & EM4x05_READ_HK_LOGIN_REQ ) > > 19 ;
uint8_t writeLogin = ( wordData & EM4x05_WRITE_LOGIN_REQ ) > > 20 ;
uint8_t writeHKL = ( wordData & EM4x05_WRITE_HK_LOGIN_REQ ) > > 21 ;
uint8_t raw = ( wordData & EM4x05_READ_AFTER_WRITE ) > > 22 ;
uint8_t disable = ( wordData & EM4x05_DISABLE_ALLOWED ) > > 23 ;
uint8_t rtf = ( wordData & EM4x05_READER_TALK_FIRST ) > > 24 ;
uint8_t pigeon = ( wordData & ( 1 < < 26 ) ) > > 26 ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " ConfigWord: %08X (Word 4) \n " , wordData ) ;
PrintAndLogEx ( NORMAL , " Config Breakdown: " ) ;
2019-06-09 03:24:12 +08:00
PrintAndLogEx ( NORMAL , " Data Rate: %02u | " _YELLOW_ ( " RF/%u " ) , wordData & 0x3F , datarate ) ;
PrintAndLogEx ( NORMAL , " Encoder: %u | " _YELLOW_ ( " %s " ) , encoder , enc ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " PSK CF: %u | %s " , PSKcf , cf ) ;
PrintAndLogEx ( NORMAL , " Delay: %u | %s " , delay , cdelay ) ;
PrintAndLogEx ( NORMAL , " LastWordR: %02u | Address of last word for default read - meaning %u blocks are output " , LWR , numblks ) ;
2019-07-13 06:38:30 +08:00
PrintAndLogEx ( NORMAL , " ReadLogin: %u | Read login is %s " , readLogin , readLogin ? _YELLOW_ ( " required " ) : _GREEN_ ( " not required " ) ) ;
PrintAndLogEx ( NORMAL , " ReadHKL: %u | Read housekeeping words login is %s " , readHKL , readHKL ? _YELLOW_ ( " required " ) : _GREEN_ ( " not required " ) ) ;
PrintAndLogEx ( NORMAL , " WriteLogin: %u | Write login is %s " , writeLogin , writeLogin ? _YELLOW_ ( " required " ) : _GREEN_ ( " not required " ) ) ;
PrintAndLogEx ( NORMAL , " WriteHKL: %u | Write housekeeping words login is %s " , writeHKL , writeHKL ? _YELLOW_ ( " required " ) : _GREEN_ ( " not Required " ) ) ;
2019-06-09 03:24:12 +08:00
PrintAndLogEx ( NORMAL , " R.A.W.: %u | Read after write is %s " , raw , raw ? " on " : " off " ) ;
PrintAndLogEx ( NORMAL , " Disable: %u | Disable command is %s " , disable , disable ? " accepted " : " not accepted " ) ;
PrintAndLogEx ( NORMAL , " R.T.F.: %u | Reader talk first is %s " , rtf , rtf ? _YELLOW_ ( " enabled " ) : " disabled " ) ;
PrintAndLogEx ( NORMAL , " Pigeon: %u | Pigeon mode is %s \n " , pigeon , pigeon ? _YELLOW_ ( " enabled " ) : " disabled " ) ;
2017-02-24 08:14:47 +08:00
}
2019-04-14 03:54:04 +08:00
static void printEM4x05info ( uint32_t block0 , uint32_t serial ) {
2019-03-09 15:59:13 +08:00
2019-03-10 06:35:06 +08:00
uint8_t chipType = ( block0 > > 1 ) & 0xF ;
uint8_t cap = ( block0 > > 5 ) & 3 ;
uint16_t custCode = ( block0 > > 9 ) & 0x3FF ;
2019-06-09 03:24:12 +08:00
char ctstr [ 50 ] ;
snprintf ( ctstr , sizeof ( ctstr ) , " \n Chip Type: %u | " , chipType ) ;
2019-03-10 06:35:06 +08:00
switch ( chipType ) {
2019-03-10 07:00:59 +08:00
case 9 :
2019-06-09 03:24:12 +08:00
snprintf ( ctstr + strlen ( ctstr ) , sizeof ( ctstr ) - strlen ( ctstr ) , _YELLOW_ ( " %s " ) , " EM4305 " ) ;
2019-03-10 07:00:59 +08:00
break ;
case 8 :
2019-07-13 06:38:30 +08:00
snprintf ( ctstr + strlen ( ctstr ) , sizeof ( ctstr ) - strlen ( ctstr ) , _YELLOW_ ( " %s " ) , " EM4205 " ) ;
2019-03-10 07:00:59 +08:00
break ;
case 4 :
2019-06-09 03:24:12 +08:00
snprintf ( ctstr + strlen ( ctstr ) , sizeof ( ctstr ) - strlen ( ctstr ) , _YELLOW_ ( " %s " ) , " Unknown " ) ;
2019-03-10 07:00:59 +08:00
break ;
case 2 :
2019-06-09 03:24:12 +08:00
snprintf ( ctstr + strlen ( ctstr ) , sizeof ( ctstr ) - strlen ( ctstr ) , _YELLOW_ ( " %s " ) , " EM4469 " ) ;
2019-03-10 07:00:59 +08:00
break ;
2019-03-10 06:35:06 +08:00
//add more here when known
2019-03-10 07:00:59 +08:00
default :
2019-06-09 03:24:12 +08:00
snprintf ( ctstr + strlen ( ctstr ) , sizeof ( ctstr ) - strlen ( ctstr ) , _YELLOW_ ( " %s " ) , " Unknown " ) ;
2019-03-10 07:00:59 +08:00
break ;
2019-03-10 06:35:06 +08:00
}
2019-06-09 03:24:12 +08:00
PrintAndLogEx ( NORMAL , " %s " , ctstr ) ;
2019-03-10 06:35:06 +08:00
switch ( cap ) {
2019-03-10 07:00:59 +08:00
case 3 :
PrintAndLogEx ( NORMAL , " Cap Type: %u | 330pF " , cap ) ;
break ;
case 2 :
PrintAndLogEx ( NORMAL , " Cap Type: %u | %spF " , cap , ( chipType = = 2 ) ? " 75 " : " 210 " ) ;
break ;
case 1 :
PrintAndLogEx ( NORMAL , " Cap Type: %u | 250pF " , cap ) ;
break ;
case 0 :
PrintAndLogEx ( NORMAL , " Cap Type: %u | no resonant capacitor " , cap ) ;
break ;
default :
PrintAndLogEx ( NORMAL , " Cap Type: %u | unknown " , cap ) ;
break ;
2019-03-10 06:35:06 +08:00
}
2019-03-10 07:00:59 +08:00
PrintAndLogEx ( NORMAL , " Cust Code: %03u | %s " , custCode , ( custCode = = 0x200 ) ? " Default " : " Unknown " ) ;
2019-03-10 06:35:06 +08:00
if ( serial ! = 0 )
2019-06-09 03:24:12 +08:00
PrintAndLogEx ( NORMAL , " \n Serial #: " _YELLOW_ ( " %08X " ) " \n " , serial ) ;
2017-02-24 08:14:47 +08:00
}
2019-04-14 03:54:04 +08:00
static void printEM4x05ProtectionBits ( uint32_t word ) {
2019-03-10 06:35:06 +08:00
for ( uint8_t i = 0 ; i < 15 ; i + + ) {
2019-06-09 03:24:12 +08:00
PrintAndLogEx ( NORMAL , " Word: %02u | %s " , i , ( ( ( 1 < < i ) & word ) | | i < 2 ) ? _RED_ ( " write Locked " ) : " unlocked " ) ;
2019-03-10 07:00:59 +08:00
if ( i = = 14 )
2019-06-09 03:24:12 +08:00
PrintAndLogEx ( NORMAL , " Word: %02u | %s " , i + 1 , ( ( ( 1 < < i ) & word ) | | i < 2 ) ? _RED_ ( " write locked " ) : " unlocked " ) ;
2019-03-10 06:35:06 +08:00
}
2017-02-24 08:14:47 +08:00
}
//quick test for EM4x05/EM4x69 tag
2019-03-10 18:20:22 +08:00
bool EM4x05IsBlock0 ( uint32_t * word ) {
2019-05-22 21:28:12 +08:00
return ( EM4x05ReadWord_ext ( 0 , 0 , false , word ) = = PM3_SUCCESS ) ;
2017-02-24 08:14:47 +08:00
}
2019-04-12 07:55:25 +08:00
static int CmdEM4x05Info ( const char * Cmd ) {
2017-02-27 04:32:51 +08:00
# define EM_SERIAL_BLOCK 1
# define EM_CONFIG_BLOCK 4
# define EM_PROT1_BLOCK 14
# define EM_PROT2_BLOCK 15
2019-03-10 06:35:06 +08:00
uint32_t pwd ;
uint32_t word = 0 , block0 = 0 , serial = 0 ;
bool usePwd = false ;
uint8_t ctmp = tolower ( param_getchar ( Cmd , 0 ) ) ;
2019-03-10 07:00:59 +08:00
if ( ctmp = = ' h ' ) return usage_lf_em4x05_info ( ) ;
2019-03-10 06:35:06 +08:00
// for now use default input of 1 as invalid (unlikely 1 will be a valid password...)
2019-05-28 17:15:12 +08:00
pwd = param_get32ex ( Cmd , 0 , 0xFFFFFFFF , 16 ) ;
2019-03-10 06:35:06 +08:00
2019-05-28 17:15:12 +08:00
if ( pwd ! = 0xFFFFFFFF )
2019-03-10 06:35:06 +08:00
usePwd = true ;
// read word 0 (chip info)
// block 0 can be read even without a password.
2019-05-22 21:28:12 +08:00
if ( EM4x05IsBlock0 ( & block0 ) = = false )
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
// read word 1 (serial #) doesn't need pwd
// continue if failed, .. non blocking fail.
EM4x05ReadWord_ext ( EM_SERIAL_BLOCK , 0 , false , & serial ) ;
printEM4x05info ( block0 , serial ) ;
// read word 4 (config block)
// needs password if one is set
2019-05-22 21:28:12 +08:00
if ( EM4x05ReadWord_ext ( EM_CONFIG_BLOCK , pwd , usePwd , & word ) ! = PM3_SUCCESS )
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
printEM4x05config ( word ) ;
// read word 14 and 15 to see which is being used for the protection bits
2019-05-22 21:28:12 +08:00
if ( EM4x05ReadWord_ext ( EM_PROT1_BLOCK , pwd , usePwd , & word ) ! = PM3_SUCCESS ) {
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
// if status bit says this is not the used protection word
if ( ! ( word & 0x8000 ) ) {
2019-05-22 21:28:12 +08:00
if ( EM4x05ReadWord_ext ( EM_PROT2_BLOCK , pwd , usePwd , & word ) ! = PM3_SUCCESS )
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
2019-05-22 21:28:12 +08:00
2019-03-10 06:35:06 +08:00
//something went wrong
2019-06-08 03:40:33 +08:00
if ( ! ( word & 0x8000 ) )
2019-05-22 21:28:12 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
printEM4x05ProtectionBits ( word ) ;
2019-05-22 21:28:12 +08:00
return PM3_SUCCESS ;
2017-02-24 08:14:47 +08:00
}
2017-02-08 05:26:06 +08:00
static command_t CommandTable [ ] = {
2019-05-02 02:48:15 +08:00
{ " help " , CmdHelp , AlwaysAvailable , " This help " } ,
2019-05-02 06:02:38 +08:00
//{"410x_demod", CmdEMdemodASK, IfPm3Lf, "Extract ID from EM410x tag on antenna)"},
2019-05-02 02:48:15 +08:00
{ " 410x_demod " , CmdEM410xDemod , AlwaysAvailable , " demodulate a EM410x tag from the GraphBuffer " } ,
2019-05-02 06:02:38 +08:00
{ " 410x_read " , CmdEM410xRead , IfPm3Lf , " attempt to read and extract tag data " } ,
{ " 410x_sim " , CmdEM410xSim , IfPm3Lf , " simulate EM410x tag " } ,
{ " 410x_brute " , CmdEM410xBrute , IfPm3Lf , " reader bruteforce attack by simulating EM410x tags " } ,
{ " 410x_watch " , CmdEM410xWatch , IfPm3Lf , " watches for EM410x 125/134 kHz tags (option 'h' for 134) " } ,
{ " 410x_spoof " , CmdEM410xWatchnSpoof , IfPm3Lf , " watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134) " } ,
{ " 410x_write " , CmdEM410xWrite , IfPm3Lf , " write EM410x UID to T5555(Q5) or T55x7 tag " } ,
{ " 4x05_dump " , CmdEM4x05Dump , IfPm3Lf , " dump EM4x05/EM4x69 tag " } ,
{ " 4x05_info " , CmdEM4x05Info , IfPm3Lf , " tag information EM4x05/EM4x69 " } ,
{ " 4x05_read " , CmdEM4x05Read , IfPm3Lf , " read word data from EM4x05/EM4x69 " } ,
{ " 4x05_write " , CmdEM4x05Write , IfPm3Lf , " write word data to EM4x05/EM4x69 " } ,
{ " 4x50_dump " , CmdEM4x50Dump , IfPm3Lf , " dump EM4x50 tag " } ,
{ " 4x50_read " , CmdEM4x50Read , IfPm3Lf , " read word data from EM4x50 " } ,
{ " 4x50_write " , CmdEM4x50Write , IfPm3Lf , " write word data to EM4x50 " } ,
2019-05-02 02:48:15 +08:00
{ NULL , NULL , NULL , NULL }
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
} ;
2019-04-12 07:55:25 +08:00
static int CmdHelp ( const char * Cmd ) {
( void ) Cmd ; // Cmd is not used so far
CmdsHelp ( CommandTable ) ;
2019-05-22 21:28:12 +08:00
return PM3_SUCCESS ;
2019-04-12 07:55:25 +08:00
}
2019-03-10 18:20:22 +08:00
int CmdLFEM4X ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
clearCommandBuffer ( ) ;
2019-04-19 06:47:51 +08:00
return CmdsParse ( CommandTable , Cmd ) ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}
2019-04-12 07:55:25 +08:00
int demodEM410x ( void ) {
return CmdEM410xDemod ( " " ) ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}