Merge branch 'master' into topaz

Conflicts:
	armsrc/Makefile
	client/Makefile
This commit is contained in:
pwpiwi 2015-04-05 19:32:12 +02:00
commit 6306ff4bac
31 changed files with 6975 additions and 5480 deletions

28
CHANGELOG.md Normal file
View file

@ -0,0 +1,28 @@
# Change Log
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]
### Changed
- Iclass read, `hf iclass read` now also reads tag config and prints configuration. (holiman)
### Fixed
- Fixed issue #19, problems with LF T55xx commands (marshmellow)
### Added
- Added changelog
## [2.0.0] - 2015-03-25
### Changed
- LF sim operations now abort when new commands arrive over the USB - not required to push the device button anymore.
### Fixed
- Mifare simulation, `hf mf sim` (was broken a long time) (pwpiwi)
- Major improvements in LF area and data operations. (marshmellow, iceman1001)
- Issues regarding LF simulation (pwpiwi)
### Added
- iClass functionality: full simulation of iclass tags, so tags can be simulated with data (not only CSN). Not yet support for write/update, but readers don't seem to enforce update. (holiman).
- iClass decryption. Proxmark can now decrypt data on an iclass tag, but requires you to have the HID decryption key locally on your computer, as this is not bundled with the sourcecode.

View file

@ -23,8 +23,8 @@ help:
@echo + all - Make bootrom, armsrc and the OS-specific host directory
@echo + client - Make only the OS-specific host directory
@echo + flash-bootrom - Make bootrom and flash it
@echo + flash-os - Make armsrc and flash os
@echo + flash-fpga - Make armsrc and flash fpga
@echo + flash-os - Make armsrc and flash os (includes fpga)
@echo + flash-fpga - (Deprecated:) Make armsrc and flash fpga
@echo + flash-both - Make armsrc and flash os and fpga image
@echo + flash-all - Make bootrom and armsrc and flash bootrom, os and fpga image
@echo + clean - Clean in bootrom, armsrc and the OS-specific host directory
@ -37,13 +37,13 @@ flash-bootrom: bootrom/obj/bootrom.elf $(FLASH_TOOL)
flash-os: armsrc/obj/osimage.elf $(FLASH_TOOL)
$(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$<)
flash-fpga: armsrc/obj/fpgaimage.elf $(FLASH_TOOL)
$(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$<)
#flash-fpga: armsrc/obj/fpgaimage.elf $(FLASH_TOOL)
# $(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$<)
flash-both: armsrc/obj/osimage.elf armsrc/obj/fpgaimage.elf $(FLASH_TOOL)
flash-both: armsrc/obj/osimage.elf $(FLASH_TOOL)
$(FLASH_TOOL) $(FLASH_PORT) $(subst /,$(PATHSEP),$(filter-out $(FLASH_TOOL),$^))
flash-all: bootrom/obj/bootrom.elf armsrc/obj/osimage.elf armsrc/obj/fpgaimage.elf $(FLASH_TOOL)
flash-all: bootrom/obj/bootrom.elf armsrc/obj/osimage.elf $(FLASH_TOOL)
$(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$(filter-out $(FLASH_TOOL),$^))
newtarbin:

View file

@ -10,7 +10,7 @@ APP_INCLUDES = apps.h
#remove one of the following defines and comment out the relevant line
#in the next section to remove that particular feature from compilation
APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE -fno-strict-aliasing -O2
APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE -fno-strict-aliasing -ffunction-sections -fdata-sections
#-DWITH_LCD
#SRC_LCD = fonts.c LCD.c
@ -51,7 +51,8 @@ APP_CFLAGS += -I.
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
include ../common/Makefile.common
OBJS = $(OBJDIR)/osimage.s19 $(OBJDIR)/fpgaimage.s19
OBJS = $(OBJDIR)/osimage.s19
#$(OBJDIR)/fpgaimage.s19
all: $(OBJS)
@ -64,11 +65,11 @@ $(OBJDIR)/fpga_hf.o: fpga_hf.bit
$(OBJDIR)/fullimage.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_lf.o $(OBJDIR)/fpga_hf.o $(THUMBOBJ) $(ARMOBJ)
$(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
$(OBJDIR)/fpgaimage.elf: $(OBJDIR)/fullimage.elf
$(OBJCOPY) -F elf32-littlearm --only-section .fpgaimage $^ $@
#$(OBJDIR)/fpgaimage.elf: $(OBJDIR)/fullimage.elf
# $(OBJCOPY) -F elf32-littlearm --only-section .fpgaimage $^ $@
$(OBJDIR)/osimage.elf: $(OBJDIR)/fullimage.elf
$(OBJCOPY) -F elf32-littlearm --remove-section .fpgaimage $^ $@
$(OBJCOPY) -F elf32-littlearm $^ $@
tarbin: $(OBJS)
$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(OBJS:%=armsrc/%) $(OBJS:%.s19=armsrc/%.elf)

View file

@ -648,7 +648,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
setSamplingConfig((sample_config *) c->d.asBytes);
break;
case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
cmd_send(CMD_ACK,SampleLF(),0,0,0,0);
cmd_send(CMD_ACK,SampleLF(c->arg[0]),0,0,0,0);
break;
case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);

View file

@ -1627,7 +1627,10 @@ uint8_t handshakeIclassTag(uint8_t *card_data)
static uint8_t act_all[] = { 0x0a };
static uint8_t identify[] = { 0x0c };
static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static uint8_t readcheck_cc[]= { 0x88, 0x02 };
static uint8_t readcheck_cc[]= { 0x88, 0x02,};
uint8_t resp[ICLASS_BUFFER_SIZE];
uint8_t read_status = 0;
@ -1662,27 +1665,32 @@ uint8_t handshakeIclassTag(uint8_t *card_data)
if(ReaderReceiveIClass(resp) == 8) {
//Save CC (e-purse) in response data
memcpy(card_data+8,resp,8);
//Got both
read_status = 2;
read_status++;
}
return read_status;
}
// Reader iClass Anticollission
void ReaderIClass(uint8_t arg0) {
uint8_t card_data[24]={0};
uint8_t card_data[6 * 8]={0xFF};
uint8_t last_csn[8]={0};
//Read conf block CRC(0x01) => 0xfa 0x22
uint8_t readConf[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x01, 0xfa, 0x22};
//Read conf block CRC(0x05) => 0xde 0x64
uint8_t readAA[] = { ICLASS_CMD_READ_OR_IDENTIFY,0x05, 0xde, 0x64};
int read_status= 0;
uint8_t result_status = 0;
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
bool get_cc = arg0 & FLAG_ICLASS_READER_GET_CC;
set_tracing(TRUE);
setupIclassReader();
size_t datasize = 0;
while(!BUTTON_PRESS())
{
@ -1695,15 +1703,40 @@ void ReaderIClass(uint8_t arg0) {
read_status = handshakeIclassTag(card_data);
if(read_status == 0) continue;
if(read_status == 1) datasize = 8;
if(read_status == 2) datasize = 16;
if(read_status == 1) result_status = FLAG_ICLASS_READER_CSN;
if(read_status == 2) result_status = FLAG_ICLASS_READER_CSN|FLAG_ICLASS_READER_CC;
//Todo, read the public blocks 1,5 aswell:
//
// 0 : CSN (we already have)
// handshakeIclass returns CSN|CC, but the actual block
// layout is CSN|CONFIG|CC, so here we reorder the data,
// moving CC forward 8 bytes
memcpy(card_data+16,card_data+8, 8);
//Read block 1, config
if(arg0 & FLAG_ICLASS_READER_CONF)
{
if(sendCmdGetResponseWithRetries(readConf, sizeof(readConf),card_data+8, 10, 10))
{
Dbprintf("Failed to dump config block");
}else
{
result_status |= FLAG_ICLASS_READER_CONF;
}
}
//Read block 5, AA
if(arg0 & FLAG_ICLASS_READER_AA){
if(sendCmdGetResponseWithRetries(readAA, sizeof(readAA),card_data+(8*4), 10, 10))
{
// Dbprintf("Failed to dump AA block");
}else
{
result_status |= FLAG_ICLASS_READER_AA;
}
}
// 0 : CSN
// 1 : Configuration
// 2 : e-purse (we already have)
// (3,4 write-only)
// 2 : e-purse
// (3,4 write-only, kc and kd)
// 5 Application issuer area
//
//Then we can 'ship' back the 8 * 5 bytes of data,
@ -1713,10 +1746,10 @@ void ReaderIClass(uint8_t arg0) {
//Send back to client, but don't bother if we already sent this
if(memcmp(last_csn, card_data, 8) != 0)
{
if(!get_cc || (get_cc && read_status == 2))
// If caller requires that we get CC, continue until we got it
if( (arg0 & read_status & FLAG_ICLASS_READER_CC) || !(arg0 & FLAG_ICLASS_READER_CC))
{
cmd_send(CMD_ACK,read_status,0,0,card_data,datasize);
cmd_send(CMD_ACK,result_status,0,0,card_data,sizeof(card_data));
if(abort_after_read) {
LED_A_OFF();
return;
@ -1724,7 +1757,7 @@ void ReaderIClass(uint8_t arg0) {
//Save that we already sent this....
memcpy(last_csn, card_data, 8);
}
//If 'get_cc' was specified and we didn't get a CC, we'll just keep trying...
}
LED_B_OFF();
}

View file

@ -11,8 +11,7 @@ INCLUDE ../common/ldscript.common
PHDRS
{
fpgaimage PT_LOAD FLAGS(4);
text PT_LOAD;
text PT_LOAD FLAGS(5);
data PT_LOAD;
bss PT_LOAD;
}
@ -20,11 +19,6 @@ PHDRS
ENTRY(Vector)
SECTIONS
{
.fpgaimage : {
*(fpga_lf_bit.data)
*(fpga_hf_bit.data)
} >fpgaimage :fpgaimage
.start : {
*(.startos)
} >osimage :text
@ -40,6 +34,8 @@ SECTIONS
.rodata : {
*(.rodata)
*(.rodata.*)
*(fpga_lf_bit.data)
*(fpga_hf_bit.data)
KEEP(*(.version_information))
} >osimage :text

View file

@ -622,7 +622,7 @@ static void askSimBit(uint8_t c, int *n, uint8_t clock, uint8_t manchester)
uint8_t *dest = BigBuf_get_addr();
uint8_t halfClk = clock/2;
// c = current bit 1 or 0
if (manchester){
if (manchester==1){
memset(dest+(*n), c, halfClk);
memset(dest+(*n) + halfClk, c^1, halfClk);
} else {
@ -631,26 +631,54 @@ static void askSimBit(uint8_t c, int *n, uint8_t clock, uint8_t manchester)
*n += clock;
}
static void biphaseSimBit(uint8_t c, int *n, uint8_t clock, uint8_t *phase)
{
uint8_t *dest = BigBuf_get_addr();
uint8_t halfClk = clock/2;
if (c){
memset(dest+(*n), c ^ 1 ^ *phase, halfClk);
memset(dest+(*n) + halfClk, c ^ *phase, halfClk);
} else {
memset(dest+(*n), c ^ *phase, clock);
*phase ^= 1;
}
}
// args clock, ask/man or askraw, invert, transmission separator
void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
{
int ledcontrol = 1;
int n=0, i=0;
uint8_t clk = (arg1 >> 8) & 0xFF;
uint8_t manchester = arg1 & 1;
uint8_t encoding = arg1 & 1;
uint8_t separator = arg2 & 1;
uint8_t invert = (arg2 >> 8) & 1;
if (encoding==2){ //biphase
uint8_t phase=0;
for (i=0; i<size; i++){
askSimBit(BitStream[i]^invert, &n, clk, manchester);
biphaseSimBit(BitStream[i]^invert, &n, clk, &phase);
}
if (manchester==0 && BitStream[0]==BitStream[size-1]){ //run a second set inverted (for biphase phase)
if (BitStream[0]==BitStream[size-1]){ //run a second set inverted to keep phase in check
for (i=0; i<size; i++){
askSimBit(BitStream[i]^invert^1, &n, clk, manchester);
biphaseSimBit(BitStream[i]^invert, &n, clk, &phase);
}
}
} else { // ask/manchester || ask/raw
for (i=0; i<size; i++){
askSimBit(BitStream[i]^invert, &n, clk, encoding);
}
if (encoding==0 && BitStream[0]==BitStream[size-1]){ //run a second set inverted (for biphase phase)
for (i=0; i<size; i++){
askSimBit(BitStream[i]^invert^1, &n, clk, encoding);
}
}
}
if (separator==1) Dbprintf("sorry but separator option not yet available");
Dbprintf("Simulating with clk: %d, invert: %d, manchester: %d, separator: %d, n: %d",clk, invert, manchester, separator, n);
Dbprintf("Simulating with clk: %d, invert: %d, encoding: %d, separator: %d, n: %d",clk, invert, encoding, separator, n);
//DEBUG
//Dbprintf("First 32:");
//uint8_t *dest = BigBuf_get_addr();
@ -727,8 +755,8 @@ void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
uint8_t *dest = BigBuf_get_addr();
const size_t sizeOfBigBuff = BigBuf_max_traceLen();
size_t size = 0;
//const size_t sizeOfBigBuff = BigBuf_max_traceLen();
size_t size;
uint32_t hi2=0, hi=0, lo=0;
int idx=0;
// Configure to go in 125Khz listen mode
@ -741,16 +769,16 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
DoAcquisition_default(-1,true);
// FSK demodulator
size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use
//size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use
size = 50*128*2; //big enough to catch 2 sequences of largest format
idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
if (idx>0 && lo>0){
// final loop, go over previously decoded manchester data and decode into usable tag ID
// 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
if (hi2 != 0){ //extra large HID tags
if (idx>0 && lo>0 && (size==96 || size==192)){
// go over previously decoded manchester data and decode into usable tag ID
if (hi2 != 0){ //extra large HID tags 88/192 bits
Dbprintf("TAG ID: %x%08x%08x (%d)",
(unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
}else { //standard HID tags <38 bits
}else { //standard HID tags 44/96 bits
//Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
uint8_t bitlen = 0;
uint32_t fc = 0;
@ -805,8 +833,8 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
return;
}
// reset
hi2 = hi = lo = 0;
}
hi2 = hi = lo = idx = 0;
WDT_HIT();
}
DbpString("Stopped");
@ -819,6 +847,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
size_t size=0, idx=0;
int clk=0, invert=0, errCnt=0, maxErr=20;
uint32_t hi=0;
uint64_t lo=0;
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
@ -830,16 +859,24 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
DoAcquisition_default(-1,true);
size = BigBuf_max_traceLen();
//Dbprintf("DEBUG: Buffer got");
//askdemod and manchester decode
if (size > 16385) size = 16385; //big enough to catch 2 sequences of largest format
errCnt = askmandemod(dest, &size, &clk, &invert, maxErr);
//Dbprintf("DEBUG: ASK Got");
WDT_HIT();
if (errCnt>=0){
lo = Em410xDecode(dest, &size, &idx);
//Dbprintf("DEBUG: EM GOT");
if (lo>0){
if (errCnt<0) continue;
errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
if (errCnt){
if (size>64){
Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
hi,
(uint32_t)(lo>>32),
(uint32_t)lo,
(uint32_t)(lo&0xFFFF),
(uint32_t)((lo>>16LL) & 0xFF),
(uint32_t)(lo & 0xFFFFFF));
} else {
Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
(uint32_t)(lo>>32),
(uint32_t)lo,
@ -847,21 +884,17 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
(uint32_t)((lo>>16LL) & 0xFF),
(uint32_t)(lo & 0xFFFFFF));
}
if (findone){
if (ledcontrol) LED_A_OFF();
*high=lo>>32;
*low=lo & 0xFFFFFFFF;
return;
}
} else{
//Dbprintf("DEBUG: No Tag");
}
WDT_HIT();
lo = 0;
clk=0;
invert=0;
errCnt=0;
size=0;
hi = lo = size = idx = 0;
clk = invert = errCnt = 0;
}
DbpString("Stopped");
if (ledcontrol) LED_A_OFF();
@ -885,7 +918,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
//fskdemod and get start index
WDT_HIT();
idx = IOdemodFSK(dest, BigBuf_max_traceLen());
if (idx>0){
if (idx<0) continue;
//valid tag found
//Index map
@ -909,7 +942,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
code = bytebits_to_byte(dest+idx,32);
code2 = bytebits_to_byte(dest+idx+32,32);
version = bytebits_to_byte(dest+idx+27,8); //14,4
facilitycode = bytebits_to_byte(dest+idx+18,8) ;
facilitycode = bytebits_to_byte(dest+idx+18,8);
number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
@ -925,7 +958,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
version=facilitycode=0;
number=0;
idx=0;
}
WDT_HIT();
}
DbpString("Stopped");
@ -991,10 +1024,12 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
* To compensate antenna falling times shorten the write times
* and enlarge the gap ones.
*/
#define START_GAP 250
#define WRITE_GAP 160
#define WRITE_0 144 // 192
#define WRITE_1 400 // 432 for T55x7; 448 for E5550
#define START_GAP 50*8 // 10 - 50fc 250
#define WRITE_GAP 20*8 // - 30fc 160
#define WRITE_0 24*8 // 16 - 63fc 54fc 144
#define WRITE_1 54*8 // 48 - 63fc 54fc 432 for T55x7; 448 for E5550 //400
#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..)
// Write one bit to card
void T55xxWriteBit(int bit)
@ -1013,16 +1048,11 @@ void T55xxWriteBit(int bit)
// Write one card block in page 0, no lock
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
//unsigned int i; //enio adjustment 12/10/14
uint32_t i;
uint32_t i = 0;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
SpinDelay(150);
// Set up FPGA, 125kHz
// Wait for config.. (192+8190xPOW)x8 == 67ms
LFSetupFPGAForADC(0, true);
// Now start writting
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -1055,30 +1085,28 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
void TurnReadLFOn(){
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
SpinDelayUs(8*150);
}
// Read one card block in page 0
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
uint32_t i = 0;
uint8_t *dest = BigBuf_get_addr();
//int m=0, i=0; //enio adjustment 12/10/14
uint32_t m=0, i=0;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
m = BigBuf_max_traceLen();
uint16_t bufferlength = BigBuf_max_traceLen();
if ( bufferlength > T55xx_SAMPLES_SIZE )
bufferlength = T55xx_SAMPLES_SIZE;
// Clear destination buffer before sending the command
memset(dest, 128, m);
// Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc();
memset(dest, 0x80, bufferlength);
LED_D_ON();
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
SpinDelay(150);
// Now start writting
// Set up FPGA, 125kHz
// Wait for config.. (192+8190xPOW)x8 == 67ms
LFSetupFPGAForADC(0, true);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
@ -1097,53 +1125,40 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
T55xxWriteBit(Block & i);
// Turn field on to read the response
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
TurnReadLFOn();
// Now do the acquisition
i = 0;
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
AT91C_BASE_SSC->SSC_THR = 0x43;
LED_D_ON();
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
// we don't care about actual value, only if it's more or less than a
// threshold essentially we capture zero crossings for later analysis
// if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
i++;
if (i >= m) break;
LED_D_OFF();
if (i >= bufferlength) break;
}
}
cmd_send(CMD_ACK,0,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
DbpString("DONE!");
}
// Read card traceability data (page 1)
void T55xxReadTrace(void){
uint32_t i = 0;
uint8_t *dest = BigBuf_get_addr();
int m=0, i=0;
uint16_t bufferlength = BigBuf_max_traceLen();
if ( bufferlength > T55xx_SAMPLES_SIZE )
bufferlength= T55xx_SAMPLES_SIZE;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
m = BigBuf_max_traceLen();
// Clear destination buffer before sending the command
memset(dest, 128, m);
// Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc();
memset(dest, 0x80, bufferlength);
LED_D_ON();
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
SpinDelay(150);
// Now start writting
LFSetupFPGAForADC(0, true);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
@ -1152,25 +1167,26 @@ void T55xxReadTrace(void){
T55xxWriteBit(1); //Page 1
// Turn field on to read the response
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
TurnReadLFOn();
// Now do the acquisition
i = 0;
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
AT91C_BASE_SSC->SSC_THR = 0x43;
LED_D_ON();
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
i++;
if (i >= m) break;
LED_D_OFF();
if (i >= bufferlength) break;
}
}
cmd_send(CMD_ACK,0,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
DbpString("DONE!");
}
/*-------------- Cloning routines -----------*/

View file

@ -224,21 +224,21 @@ uint32_t DoAcquisition_config( bool silent)
,silent);
}
uint32_t ReadLF(bool activeField)
uint32_t ReadLF(bool activeField, bool silent)
{
printConfig();
if (!silent) printConfig();
LFSetupFPGAForADC(config.divisor, activeField);
// Now call the acquisition routine
return DoAcquisition_config(false);
return DoAcquisition_config(silent);
}
/**
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
* @return number of bits sampled
**/
uint32_t SampleLF()
uint32_t SampleLF(bool printCfg)
{
return ReadLF(true);
return ReadLF(true, printCfg);
}
/**
* Initializes the FPGA for snoop-mode (field off), and acquires the samples.
@ -247,5 +247,5 @@ uint32_t SampleLF()
uint32_t SnoopLF()
{
return ReadLF(false);
return ReadLF(false, true);
}

View file

@ -5,7 +5,7 @@
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
* @return number of bits sampled
**/
uint32_t SampleLF();
uint32_t SampleLF(bool silent);
/**
* Initializes the FPGA for snoop-mode (field off), and acquires the samples.

View file

@ -66,6 +66,7 @@ CMDSRCS = nonce2key/crapto1.c\
loclass/elite_crack.c\
loclass/fileutils.c\
mifarehost.c\
crc.c \
crc16.c \
iso14443crc.c \
iso15693tools.c \
@ -100,8 +101,7 @@ CMDSRCS = nonce2key/crapto1.c\
cmdscript.c\
pm3_bitlib.c\
aes.c\
protocols.c\
protocols.c
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)

View file

@ -22,6 +22,7 @@
#include "cmddata.h"
#include "lfdemod.h"
#include "usb_cmd.h"
#include "crc.h"
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
uint8_t g_debugMode;
@ -32,6 +33,12 @@ static int CmdHelp(const char *Cmd);
//by marshmellow
void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx)
{
if (buff == NULL)
return;
if ( size >= MAX_DEMOD_BUF_LEN)
size = MAX_DEMOD_BUF_LEN;
size_t i = 0;
for (; i < size; i++){
DemodBuffer[i]=buff[startIdx++];
@ -79,7 +86,8 @@ void printDemodBuff(void)
DemodBuffer[i+12],
DemodBuffer[i+13],
DemodBuffer[i+14],
DemodBuffer[i+15]);
DemodBuffer[i+15]
);
}
return;
}
@ -253,15 +261,16 @@ void printBitStream(uint8_t BitStream[], uint32_t bitLen)
BitStream[i+12],
BitStream[i+13],
BitStream[i+14],
BitStream[i+15]);
BitStream[i+15]
);
}
return;
}
//by marshmellow
//print 64 bit EM410x ID in multiple formats
void printEM410x(uint64_t id)
void printEM410x(uint32_t hi, uint64_t id)
{
if (id !=0){
if (id || hi){
uint64_t iii=1;
uint64_t id2lo=0;
uint32_t ii=0;
@ -271,29 +280,111 @@ void printEM410x(uint64_t id)
id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8)));
}
}
//output em id
PrintAndLog("EM TAG ID : %010llx", id);
PrintAndLog("Unique TAG ID: %010llx", id2lo);
if (hi){
//output 88 bit em id
PrintAndLog("\nEM TAG ID : %06x%016llx", hi, id);
} else{
//output 40 bit em id
PrintAndLog("\nEM TAG ID : %010llx", id);
PrintAndLog("Unique TAG ID : %010llx", id2lo);
PrintAndLog("\nPossible de-scramble patterns");
PrintAndLog("HoneyWell IdentKey {");
PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF);
PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF);
PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFFFF);
PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF));
PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF));
PrintAndLog("DEZ 3.5B : %03lld.%05lld",(id & 0xFF000000) >> 24,(id & 0xFFFF));
PrintAndLog("DEZ 3.5C : %03lld.%05lld",(id & 0xFF0000) >> 16,(id & 0xFFFF));
PrintAndLog("DEZ 14/IK2 : %014lld",id);
PrintAndLog("DEZ 15/IK3 : %015lld",id2lo);
PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));
PrintAndLog("DEZ 20/ZK : %02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld",
(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;
PrintAndLog("}\nOther : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));
PrintAndLog("Pattern Paxton : %0d", paxton);
uint32_t p1id = (id & 0xFFFFFF);
uint8_t arr[32] = {0x00};
int i =0;
int j = 23;
for (; i < 24; ++i, --j ){
arr[i] = (p1id >> i) & 1;
}
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;
PrintAndLog("Pattern 1 : 0x%X - %d", p1, p1);
uint16_t sebury1 = id & 0xFFFF;
uint8_t sebury2 = (id >> 16) & 0x7F;
uint32_t sebury3 = id & 0x7FFFFF;
PrintAndLog("Pattern Sebury : %d %d %d (hex: %X %X %X)", sebury1, sebury2, sebury3, sebury1, sebury2, sebury3);
}
}
return;
}
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo)
{
int ans = ASKmanDemod(Cmd, FALSE, FALSE);
if (!ans) return 0;
size_t idx=0;
if (Em410xDecode(DemodBuffer,(size_t *) &DemodBufferLen, &idx, hi, lo)){
if (g_debugMode){
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, DemodBufferLen);
printDemodBuff();
}
return 1;
}
return 0;
}
//by marshmellow
//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
int CmdAskEM410xDemod(const char *Cmd)
{
int invert=0;
int clk=0;
int maxErr=100;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data askem410xdemod [clock] <0|1> [maxError]");
@ -306,50 +397,13 @@ int CmdAskEM410xDemod(const char *Cmd)
PrintAndLog(" : data askem410xdemod 32 1 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data");
PrintAndLog(" : data askem410xdemod 1 = demod an EM410x Tag ID from GraphBuffer while inverting data");
PrintAndLog(" : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors");
return 0;
}
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
if (invert != 0 && invert != 1) {
PrintAndLog("Invalid argument: %s", Cmd);
return 0;
}
size_t BitLen = getFromGraphBuf(BitStream);
if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
if (BitLen==0) return 0;
int errCnt=0;
errCnt = askmandemod(BitStream, &BitLen, &clk, &invert, maxErr);
if (errCnt<0||BitLen<16){ //if fatal error (or -1)
if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
return 0;
}
PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
//output
if (errCnt>0){
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
}
//PrintAndLog("ASK/Manchester decoded bitstream:");
// Now output the bitstream to the scrollback by line of 16 bits
setDemodBuf(BitStream,BitLen,0);
//printDemodBuff();
uint64_t lo =0;
size_t idx=0;
lo = Em410xDecode(BitStream, &BitLen, &idx);
if (lo>0){
//set GraphBuffer for clone or sim command
setDemodBuf(BitStream, BitLen, idx);
if (g_debugMode){
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
printDemodBuff();
}
uint32_t hi = 0;
uint64_t lo = 0;
if (AskEm410xDemod(Cmd, &hi, &lo)) {
PrintAndLog("EM410x pattern found: ");
if (BitLen > 64) PrintAndLog("\nWarning! Length not what is expected - Length: %d bits\n",BitLen);
printEM410x(lo);
printEM410x(hi, lo);
return 1;
}
return 0;
@ -360,7 +414,10 @@ int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch)
int invert=0;
int clk=0;
int maxErr=100;
//param_getdec(Cmd, 0, &clk);
//param_getdec(Cmd, 1, &invert);
//maxErr = param_get32ex(Cmd, 2, 0xFFFFFFFF, 10);
//if (maxErr == 0xFFFFFFFF) maxErr=100;
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
if (invert != 0 && invert != 1) {
@ -380,21 +437,21 @@ int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch)
if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
return 0;
}
if (verbose) PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
if (verbose || g_debugMode) PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
//output
if (errCnt>0){
if (verbose) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
if (verbose || g_debugMode) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
}
if (verbose) PrintAndLog("ASK/Manchester decoded bitstream:");
if (verbose || g_debugMode) PrintAndLog("ASK/Manchester decoded bitstream:");
// Now output the bitstream to the scrollback by line of 16 bits
setDemodBuf(BitStream,BitLen,0);
if (verbose) printDemodBuff();
if (verbose || g_debugMode) printDemodBuff();
uint64_t lo =0;
uint32_t hi =0;
size_t idx=0;
if (emSearch){
lo = Em410xDecode(BitStream, &BitLen, &idx);
if (lo>0){
if (Em410xDecode(BitStream, &BitLen, &idx, &hi, &lo)){
//set GraphBuffer for clone or sim command
setDemodBuf(BitStream, BitLen, idx);
if (g_debugMode){
@ -402,7 +459,7 @@ int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch)
printDemodBuff();
}
if (verbose) PrintAndLog("EM410x pattern found: ");
if (verbose) printEM410x(lo);
if (verbose) printEM410x(hi, lo);
return 1;
}
}
@ -472,13 +529,13 @@ int Cmdmandecoderaw(const char *Cmd)
printBitStream(BitStream, size);
if (errCnt==0){
uint64_t id = 0;
uint32_t hi = 0;
size_t idx=0;
id = Em410xDecode(BitStream, &size, &idx);
if (id>0){
if (Em410xDecode(BitStream, &size, &idx, &hi, &id)){
//need to adjust to set bitstream back to manchester encoded data
//setDemodBuf(BitStream, size, idx);
printEM410x(id);
printEM410x(hi, id);
}
}
return 1;
@ -496,53 +553,53 @@ int Cmdmandecoderaw(const char *Cmd)
// width waves vs small width waves to help the decode positioning) or askbiphdemod
int CmdBiphaseDecodeRaw(const char *Cmd)
{
int i = 0;
int errCnt=0;
size_t size=0;
int offset=0;
int invert=0;
int high=0, low=0;
int offset=0, invert=0, maxErr=20, errCnt=0;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data biphaserawdecode [offset] <invert>");
PrintAndLog(" Converts 10 or 01 to 0 and 11 or 00 to 1");
PrintAndLog("Usage: data biphaserawdecode [offset] [invert] [maxErr]");
PrintAndLog(" Converts 10 or 01 to 1 and 11 or 00 to 0");
PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)");
PrintAndLog(" --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester");
PrintAndLog("");
PrintAndLog(" [offset <0|1>], set to 0 not to adjust start position or to 1 to adjust decode start position");
PrintAndLog(" [invert <0|1>], set to 1 to invert output");
PrintAndLog(" [maxErr int], set max errors tolerated - default=20");
PrintAndLog("");
PrintAndLog(" sample: data biphaserawdecode = decode biphase bitstream from the demodbuffer");
PrintAndLog(" sample: data biphaserawdecode 1 1 = decode biphase bitstream from the demodbuffer, set offset, and invert output");
return 0;
}
sscanf(Cmd, "%i %i", &offset, &invert);
if (DemodBufferLen==0) return 0;
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
//get graphbuffer & high and low
for (;i<DemodBufferLen;++i){
if(DemodBuffer[i]>high)high=DemodBuffer[i];
else if(DemodBuffer[i]<low)low=DemodBuffer[i];
BitStream[i]=DemodBuffer[i];
}
if (high>1 || low <0){
PrintAndLog("Error: please raw demod the wave first then decode");
sscanf(Cmd, "%i %i %i", &offset, &invert, &maxErr);
if (DemodBufferLen==0){
PrintAndLog("DemodBuffer Empty - run 'data rawdemod ar' first");
return 0;
}
size=i;
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
memcpy(BitStream, DemodBuffer, DemodBufferLen);
size = DemodBufferLen;
errCnt=BiphaseRawDecode(BitStream, &size, offset, invert);
if (errCnt>=20){
if (errCnt<0){
PrintAndLog("Error during decode:%d", errCnt);
return 0;
}
if (errCnt>maxErr){
PrintAndLog("Too many errors attempting to decode: %d",errCnt);
return 0;
}
PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt);
if (errCnt>0){
PrintAndLog("# Errors found during Demod (shown as 77 in bit stream): %d",errCnt);
}
PrintAndLog("Biphase Decoded using offset: %d - # invert:%d - data:",offset,invert);
printBitStream(BitStream, size);
PrintAndLog("\nif bitstream does not look right try offset=1");
if (offset == 1) setDemodBuf(DemodBuffer,DemodBufferLen-1,1); //remove first bit from raw demod
if (offset) setDemodBuf(DemodBuffer,DemodBufferLen-offset, offset); //remove first bit from raw demod
return 1;
}
// set demod buffer back to raw after biphase demod
void setBiphaseDemodBuf(uint8_t *BitStream, size_t size)
void setBiphasetoRawDemodBuf(uint8_t *BitStream, size_t size)
{
uint8_t rawStream[512]={0x00};
size_t i=0;
@ -564,6 +621,7 @@ void setBiphaseDemodBuf(uint8_t *BitStream, size_t size)
setDemodBuf(rawStream,i,0);
return;
}
//by marshmellow
//takes 4 arguments - clock, invert, maxErr as integers and amplify as char
//attempts to demodulate ask only
@ -578,7 +636,7 @@ int ASKrawDemod(const char *Cmd, bool verbose)
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
sscanf(Cmd, "%i %i %i %c", &clk, &invert, &maxErr, &amp);
if (invert != 0 && invert != 1) {
if (verbose) PrintAndLog("Invalid argument: %s", Cmd);
if (verbose || g_debugMode) PrintAndLog("Invalid argument: %s", Cmd);
return 0;
}
if (clk==1){
@ -591,20 +649,20 @@ int ASKrawDemod(const char *Cmd, bool verbose)
int errCnt=0;
errCnt = askrawdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp);
if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
if (verbose) PrintAndLog("no data found");
if (g_debugMode==1 && verbose) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert);
if (verbose || g_debugMode) PrintAndLog("no data found");
if (g_debugMode) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert);
return 0;
}
if (verbose) PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen);
if (verbose || g_debugMode) PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen);
//move BitStream back to DemodBuffer
setDemodBuf(BitStream,BitLen,0);
//output
if (errCnt>0 && verbose){
if (errCnt>0 && (verbose || g_debugMode)){
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d", errCnt);
}
if (verbose){
if (verbose || g_debugMode){
PrintAndLog("ASK demoded bitstream:");
// Now output the bitstream to the scrollback by line of 16 bits
printBitStream(BitStream,BitLen);
@ -612,6 +670,73 @@ int ASKrawDemod(const char *Cmd, bool verbose)
return 1;
}
//by marshmellow
// - ASK Demod then Biphase decode GraphBuffer samples
int ASKbiphaseDemod(const char *Cmd, bool verbose)
{
//ask raw demod GraphBuffer first
int offset=0, clk=0, invert=0, maxErr=0, ans=0;
ans = sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr);
if (ans>0)
ans = ASKrawDemod(Cmd+1, FALSE);
else
ans = ASKrawDemod(Cmd, FALSE);
if (!ans) {
if (g_debugMode || verbose) PrintAndLog("Error AskrawDemod: %d", ans);
return 0;
}
//attempt to Biphase decode DemodBuffer
size_t size = DemodBufferLen;
uint8_t BitStream[MAX_DEMOD_BUF_LEN];
memcpy(BitStream, DemodBuffer, DemodBufferLen);
int errCnt = BiphaseRawDecode(BitStream, &size, offset, invert);
if (errCnt < 0){
if (g_debugMode || verbose) PrintAndLog("Error BiphaseRawDecode: %d", errCnt);
return 0;
}
if (errCnt > maxErr) {
if (g_debugMode || verbose) PrintAndLog("Error BiphaseRawDecode too many errors: %d", errCnt);
return 0;
}
//success set DemodBuffer and return
setDemodBuf(BitStream, size, 0);
if (g_debugMode || verbose){
PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt);
printDemodBuff();
}
return 1;
}
//by marshmellow - see ASKbiphaseDemod
int Cmdaskbiphdemod(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data rawdemod ab [offset] [clock] <invert> [maxError] <amplify>");
PrintAndLog(" [offset], offset to begin biphase, default=0");
PrintAndLog(" [set clock as integer] optional, if not set, autodetect");
PrintAndLog(" <invert>, 1 to invert output");
PrintAndLog(" [set maximum allowed errors], default = 100");
PrintAndLog(" <amplify>, 'a' to attempt demod with ask amplification, default = no amp");
PrintAndLog(" NOTE: <invert> can be entered as second or third argument");
PrintAndLog(" NOTE: <amplify> can be entered as first, second or last argument");
PrintAndLog(" NOTE: any other arg must have previous args set to work");
PrintAndLog("");
PrintAndLog(" NOTE: --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester");
PrintAndLog("");
PrintAndLog(" sample: data rawdemod ab = demod an ask/biph tag from GraphBuffer");
PrintAndLog(" : data rawdemod ab a = demod an ask/biph tag from GraphBuffer, amplified");
PrintAndLog(" : data rawdemod ab 1 32 = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32");
PrintAndLog(" : data rawdemod ab 0 32 1 = demod an ask/biph tag from GraphBuffer using a clock of RF/32 and inverting data");
PrintAndLog(" : data rawdemod ab 0 1 = demod an ask/biph tag from GraphBuffer while inverting data");
PrintAndLog(" : data rawdemod ab 0 64 1 0 = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
PrintAndLog(" : data rawdemod ab 0 64 1 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp");
return 0;
}
return ASKbiphaseDemod(Cmd, TRUE);
}
//by marshmellow
//attempts to demodulate and identify a G_Prox_II verex/chubb card
//WARNING: if it fails during some points it will destroy the DemodBuffer data
@ -619,32 +744,16 @@ int ASKrawDemod(const char *Cmd, bool verbose)
//if successful it will push askraw data back to demod buffer ready for emulation
int CmdG_Prox_II_Demod(const char *Cmd)
{
int ans = ASKrawDemod(Cmd, FALSE);
if (ans <= 0) {
if (g_debugMode) PrintAndLog("Error AskrawDemod: %d",ans);
return ans;
if (!ASKbiphaseDemod(Cmd, FALSE)){
if (g_debugMode) PrintAndLog("ASKbiphaseDemod failed 1st try");
return 0;
}
size_t size = DemodBufferLen;
ans = BiphaseRawDecode(DemodBuffer, &size, 0, 0);
if (ans !=0) {
if (g_debugMode) PrintAndLog("Error BiphaseRawDecode: %d",ans);
return ans;
}
//call lfdemod.c demod for gProxII
ans = gProxII_Demod(DemodBuffer, &size);
int ans = gProxII_Demod(DemodBuffer, &size);
if (ans < 0){
if (g_debugMode) PrintAndLog("Error gProxII_Demod 1st Try: %d",ans);
//try biphase again
ans = BiphaseRawDecode(DemodBuffer, &size, 1, 0);
if (ans != 0) {
if (g_debugMode) PrintAndLog("Error BiphaseRawDecode: %d",ans);
return ans;
}
ans = gProxII_Demod(DemodBuffer, &size);
if (ans < 0) {
if (g_debugMode) PrintAndLog("Error gProxII_Demod 1st Try: %d",ans);
return ans;
}
if (g_debugMode) PrintAndLog("Error gProxII_Demod");
return 0;
}
//got a good demod
uint32_t ByteStream[65] = {0x00};
@ -658,7 +767,7 @@ int CmdG_Prox_II_Demod(const char *Cmd)
//spacer bit - should be 0
if (DemodBuffer[startIdx+idx] != 0) {
if (g_debugMode) PrintAndLog("Error spacer not 0: %d, pos: %d",DemodBuffer[startIdx+idx],startIdx+idx);
return -1;
return 0;
}
continue;
}
@ -702,7 +811,7 @@ int CmdG_Prox_II_Demod(const char *Cmd)
PrintAndLog("Unknown G-Prox-II Fmt Found: FmtLen %d",fmtLen);
}
PrintAndLog("Raw: %08x%08x%08x", raw1,raw2,raw3);
setBiphaseDemodBuf(DemodBuffer+ans, 96);
setDemodBuf(DemodBuffer+ans, 96, 0);
return 1;
}
@ -729,38 +838,80 @@ int Cmdaskrawdemod(const char *Cmd)
return ASKrawDemod(Cmd, TRUE);
}
int CmdAutoCorr(const char *Cmd)
int AutoCorrelate(int window, bool SaveGrph, bool verbose)
{
static int CorrelBuffer[MAX_GRAPH_TRACE_LEN];
int window = atoi(Cmd);
if (window == 0) {
PrintAndLog("needs a window");
return 0;
}
if (window >= GraphTraceLen) {
PrintAndLog("window must be smaller than trace (%d samples)",
GraphTraceLen);
return 0;
}
PrintAndLog("performing %d correlations", GraphTraceLen - window);
size_t Correlation = 0;
int maxSum = 0;
int lastMax = 0;
if (verbose) PrintAndLog("performing %d correlations", GraphTraceLen - window);
for (int i = 0; i < GraphTraceLen - window; ++i) {
int sum = 0;
for (int j = 0; j < window; ++j) {
sum += (GraphBuffer[j]*GraphBuffer[i + j]) / 256;
}
CorrelBuffer[i] = sum;
if (sum >= maxSum-100 && sum <= maxSum+100){
//another max
Correlation = i-lastMax;
lastMax = i;
if (sum > maxSum) maxSum = sum;
} else if (sum > maxSum){
maxSum=sum;
lastMax = i;
}
}
if (Correlation==0){
//try again with wider margin
for (int i = 0; i < GraphTraceLen - window; i++){
if (CorrelBuffer[i] >= maxSum-(maxSum*0.05) && CorrelBuffer[i] <= maxSum+(maxSum*0.05)){
//another max
Correlation = i-lastMax;
lastMax = i;
//if (CorrelBuffer[i] > maxSum) maxSum = sum;
}
}
}
if (verbose && Correlation > 0) PrintAndLog("Possible Correlation: %d samples",Correlation);
if (SaveGrph){
GraphTraceLen = GraphTraceLen - window;
memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int));
RepaintGraphWindow();
}
return Correlation;
}
int usage_data_autocorr(void)
{
//print help
PrintAndLog("Usage: data autocorr [window] [g]");
PrintAndLog("Options: ");
PrintAndLog(" h This help");
PrintAndLog(" [window] window length for correlation - default = 4000");
PrintAndLog(" g save back to GraphBuffer (overwrite)");
return 0;
}
int CmdAutoCorr(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H')
return usage_data_autocorr();
int window = 4000; //set default
char grph=0;
bool updateGrph = FALSE;
sscanf(Cmd, "%i %c", &window, &grph);
if (window >= GraphTraceLen) {
PrintAndLog("window must be smaller than trace (%d samples)",
GraphTraceLen);
return 0;
}
if (grph == 'g') updateGrph=TRUE;
return AutoCorrelate(window, updateGrph, TRUE);
}
int CmdBitsamples(const char *Cmd)
{
int cnt = 0;
@ -998,7 +1149,7 @@ int FSKrawDemod(const char *Cmd, bool verbose)
if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
if (rfLen==1){
invert=1; //if invert option only is used
invert = 1; //if invert option only is used
rfLen = 0;
}
}
@ -1008,9 +1159,8 @@ int FSKrawDemod(const char *Cmd, bool verbose)
if (BitLen==0) return 0;
//get field clock lengths
uint16_t fcs=0;
uint8_t dummy=0;
if (fchigh==0 || fclow == 0){
fcs = countFC(BitStream, BitLen, &dummy);
fcs = countFC(BitStream, BitLen, 1);
if (fcs==0){
fchigh=10;
fclow=8;
@ -1274,7 +1424,19 @@ int CmdFSKdemodIO(const char *Cmd)
uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4
uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ;
uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9
PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
uint8_t crc = bytebits_to_byte(BitStream+idx+54,8);
uint16_t calccrc = 0;
for (uint8_t i=1; i<6; ++i){
calccrc += bytebits_to_byte(BitStream+idx+9*i,8);
//PrintAndLog("%d", calccrc);
}
calccrc &= 0xff;
calccrc = 0xff - calccrc;
char *crcStr = (crc == calccrc) ? "crc ok": "!crc";
PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr);
setDemodBuf(BitStream,64,idx);
if (g_debugMode){
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing demod buffer:",idx,64);
@ -1435,6 +1597,16 @@ int CmdFSKdemodPyramid(const char *Cmd)
// p = unknown checksum
// (26 bit format shown)
//get bytes for checksum calc
uint8_t checksum = bytebits_to_byte(BitStream + idx + 120, 8);
uint8_t csBuff[14] = {0x00};
for (uint8_t i = 0; i < 13; i++){
csBuff[i] = bytebits_to_byte(BitStream + idx + 16 + (i*8), 8);
}
//check checksum calc
//checksum calc thanks to ICEMAN!!
uint32_t checkCS = CRC8Maxim(csBuff,13);
//get raw ID before removing parities
uint32_t rawLo = bytebits_to_byte(BitStream+idx+96,32);
uint32_t rawHi = bytebits_to_byte(BitStream+idx+64,32);
@ -1444,7 +1616,8 @@ int CmdFSKdemodPyramid(const char *Cmd)
size = removeParity(BitStream, idx+8, 8, 1, 120);
if (size != 105){
if (g_debugMode==1) PrintAndLog("DEBUG: Error at parity check-tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size, idx, rawHi3);
if (g_debugMode==1)
PrintAndLog("DEBUG: Error at parity check - tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size, idx, rawHi3);
return 0;
}
@ -1502,6 +1675,11 @@ int CmdFSKdemodPyramid(const char *Cmd)
PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
}
}
if (checksum == checkCS)
PrintAndLog("Checksum %02x passed", checksum);
else
PrintAndLog("Checksum %02x failed - should have been %02x", checksum, checkCS);
if (g_debugMode){
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128);
printDemodBuff();
@ -1641,30 +1819,35 @@ int PSKDemod(const char *Cmd, bool verbose)
}
if (invert != 0 && invert != 1) {
if (verbose) PrintAndLog("Invalid argument: %s", Cmd);
return -1;
return 0;
}
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t BitLen = getFromGraphBuf(BitStream);
if (BitLen==0) return -1;
uint8_t carrier=countPSK_FC(BitStream, BitLen);
uint8_t carrier=countFC(BitStream, BitLen, 0);
if (carrier!=2 && carrier!=4 && carrier!=8){
//invalid carrier
return -1;
return 0;
}
int errCnt=0;
errCnt = pskRawDemod(BitStream, &BitLen, &clk, &invert);
if (errCnt > maxErr){
if (g_debugMode==1 && verbose) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
return -1;
return 0;
}
if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
if (g_debugMode==1 && verbose) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
return -1;
return 0;
}
if (verbose){
PrintAndLog("Tried PSK Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
if (errCnt>0){
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
}
}
if (verbose) PrintAndLog("Tried PSK Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
//prime demod buffer for output
setDemodBuf(BitStream,BitLen,0);
return errCnt;
return 1;
}
// Indala 26 bit decode
@ -1679,7 +1862,7 @@ int CmdIndalaDecode(const char *Cmd)
ans = PSKDemod("32", 0);
}
if (ans < 0){
if (!ans){
if (g_debugMode==1)
PrintAndLog("Error1: %d",ans);
return 0;
@ -1773,21 +1956,19 @@ int NRZrawDemod(const char *Cmd, bool verbose)
int errCnt=0;
errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, maxErr);
if (errCnt > maxErr){
if (g_debugMode==1 && verbose) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
if (g_debugMode) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
return 0;
}
if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
if (g_debugMode==1 && verbose) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
if (errCnt<0 || BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
if (g_debugMode) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
return 0;
}
PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
if (verbose || g_debugMode) PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
//prime demod buffer for output
setDemodBuf(BitStream,BitLen,0);
if (errCnt>0 && verbose){
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
}
if (verbose) {
if (errCnt>0 && (verbose || g_debugMode)) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
if (verbose || g_debugMode) {
PrintAndLog("NRZ demoded bitstream:");
// Now output the bitstream to the scrollback by line of 16 bits
printDemodBuff();
@ -1820,7 +2001,7 @@ int CmdNRZrawDemod(const char *Cmd)
// prints binary found and saves in demodbuffer for further commands
int CmdPSK1rawDemod(const char *Cmd)
{
int errCnt;
int ans;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data rawdemod p1 [clock] <0|1> [maxError]");
@ -1835,15 +2016,13 @@ int CmdPSK1rawDemod(const char *Cmd)
PrintAndLog(" : data rawdemod p1 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
return 0;
}
errCnt = PSKDemod(Cmd, TRUE);
ans = PSKDemod(Cmd, TRUE);
//output
if (errCnt<0){
if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt);
if (!ans){
if (g_debugMode) PrintAndLog("Error demoding: %d",ans);
return 0;
}
if (errCnt>0){
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
}
PrintAndLog("PSK demoded bitstream:");
// Now output the bitstream to the scrollback by line of 16 bits
printDemodBuff();
@ -1854,7 +2033,7 @@ int CmdPSK1rawDemod(const char *Cmd)
// takes same args as cmdpsk1rawdemod
int CmdPSK2rawDemod(const char *Cmd)
{
int errCnt=0;
int ans=0;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data rawdemod p2 [clock] <0|1> [maxError]");
@ -1869,24 +2048,15 @@ int CmdPSK2rawDemod(const char *Cmd)
PrintAndLog(" : data rawdemod p2 64 1 0 = demod a psk2 tag from GraphBuffer using a clock of RF/64, inverting output and allowing 0 demod errors");
return 0;
}
errCnt=PSKDemod(Cmd, TRUE);
if (errCnt<0){
if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt);
ans=PSKDemod(Cmd, TRUE);
if (!ans){
if (g_debugMode) PrintAndLog("Error demoding: %d",ans);
return 0;
}
psk1TOpsk2(DemodBuffer, DemodBufferLen);
if (errCnt>0){
if (g_debugMode){
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
PrintAndLog("PSK2 demoded bitstream:");
// Now output the bitstream to the scrollback by line of 16 bits
printDemodBuff();
}
}else{
PrintAndLog("PSK2 demoded bitstream:");
// Now output the bitstream to the scrollback by line of 16 bits
printDemodBuff();
}
return 1;
}
@ -1897,12 +2067,14 @@ int CmdRawDemod(const char *Cmd)
if (strlen(Cmd) > 14 || cmdp == 'h' || cmdp == 'H' || strlen(Cmd)<2) {
PrintAndLog("Usage: data rawdemod [modulation] <help>|<options>");
PrintAndLog(" [modulation] as 2 char, 'am' for ask/manchester, 'ar' for ask/raw, 'fs' for fsk, 'nr' for nrz/direct, 'p1' for psk1, 'p2' for psk2");
PrintAndLog(" [modulation] as 2 char, 'ab' for ask/biphase, 'am' for ask/manchester, 'ar' for ask/raw, 'fs' for fsk, ...");
PrintAndLog(" 'nr' for nrz/direct, 'p1' for psk1, 'p2' for psk2");
PrintAndLog(" <help> as 'h', prints the help for the specific modulation");
PrintAndLog(" <options> see specific modulation help for optional parameters");
PrintAndLog("");
PrintAndLog(" sample: data rawdemod fs h = print help for ask/raw demod");
PrintAndLog(" sample: data rawdemod fs h = print help specific to fsk demod");
PrintAndLog(" : data rawdemod fs = demod GraphBuffer using: fsk - autodetect");
PrintAndLog(" : data rawdemod ab = demod GraphBuffer using: ask/biphase - autodetect");
PrintAndLog(" : data rawdemod am = demod GraphBuffer using: ask/manchester - autodetect");
PrintAndLog(" : data rawdemod ar = demod GraphBuffer using: ask/raw - autodetect");
PrintAndLog(" : data rawdemod nr = demod GraphBuffer using: nrz/direct - autodetect");
@ -1913,17 +2085,19 @@ int CmdRawDemod(const char *Cmd)
char cmdp2 = Cmd[1];
int ans = 0;
if (cmdp == 'f' && cmdp2 == 's'){
ans = CmdFSKrawdemod(Cmd+3);
ans = CmdFSKrawdemod(Cmd+2);
} else if(cmdp == 'a' && cmdp2 == 'b'){
ans = Cmdaskbiphdemod(Cmd+2);
} else if(cmdp == 'a' && cmdp2 == 'm'){
ans = Cmdaskmandemod(Cmd+3);
ans = Cmdaskmandemod(Cmd+2);
} else if(cmdp == 'a' && cmdp2 == 'r'){
ans = Cmdaskrawdemod(Cmd+3);
ans = Cmdaskrawdemod(Cmd+2);
} else if(cmdp == 'n' && cmdp2 == 'r'){
ans = CmdNRZrawDemod(Cmd+3);
ans = CmdNRZrawDemod(Cmd+2);
} else if(cmdp == 'p' && cmdp2 == '1'){
ans = CmdPSK1rawDemod(Cmd+3);
ans = CmdPSK1rawDemod(Cmd+2);
} else if(cmdp == 'p' && cmdp2 == '2'){
ans = CmdPSK2rawDemod(Cmd+3);
ans = CmdPSK2rawDemod(Cmd+2);
} else {
PrintAndLog("unknown modulation entered - see help ('h') for parameter structure");
}
@ -2027,15 +2201,17 @@ uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b)
return val;
}
int CmdSamples(const char *Cmd)
int getSamples(const char *Cmd, bool silent)
{
//If we get all but the last byte in bigbuf,
// we don't have to worry about remaining trash
// in the last byte in case the bits-per-sample
// does not line up on byte boundaries
uint8_t got[BIGBUF_SIZE-1] = { 0 };
int n = strtol(Cmd, NULL, 0);
if (n == 0)
n = sizeof(got);
@ -2080,6 +2256,11 @@ int CmdSamples(const char *Cmd)
return 0;
}
int CmdSamples(const char *Cmd)
{
return getSamples(Cmd, false);
}
int CmdTuneSamples(const char *Cmd)
{
int timeout = 0;
@ -2577,11 +2758,9 @@ static command_t CommandTable[] =
{"amp", CmdAmp, 1, "Amplify peaks"},
//{"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
{"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave (default = 25)"},
{"askem410xdemod",CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
{"askgproxiidemod",CmdG_Prox_II_Demod,1, "Demodulate a G Prox II tag from GraphBuffer"},
//{"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"},
//{"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output bin (args optional)"},
{"autocorr", CmdAutoCorr, 1, "<window length> -- Autocorrelation over window"},
{"askem410xdemod", CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
{"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
{"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
{"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
{"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
//{"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"},
@ -2593,9 +2772,8 @@ static command_t CommandTable[] =
//{"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"},
{"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate a HID FSK tag from GraphBuffer"},
{"fskiodemod", CmdFSKdemodIO, 1, "Demodulate an IO Prox FSK tag from GraphBuffer"},
{"fskpyramiddemod",CmdFSKdemodPyramid,1, "Demodulate a Pyramid FSK tag from GraphBuffer"},
{"fskparadoxdemod",CmdFSKdemodParadox,1, "Demodulate a Paradox FSK tag from GraphBuffer"},
//{"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to bin (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"},
{"fskpyramiddemod", CmdFSKdemodPyramid, 1, "Demodulate a Pyramid FSK tag from GraphBuffer"},
{"fskparadoxdemod", CmdFSKdemodParadox, 1, "Demodulate a Paradox FSK tag from GraphBuffer"},
{"getbitstream", CmdGetBitStream, 1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
{"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
{"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
@ -2608,20 +2786,15 @@ static command_t CommandTable[] =
{"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream in DemodBuffer"},
{"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"},
{"norm", CmdNorm, 1, "Normalize max/min to +/-128"},
//{"nrzdetectclock",CmdDetectNRZClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
//{"nrzrawdemod", CmdNRZrawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate nrz tags and output binary (args optional)"},
{"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"},
//{"pskdetectclock",CmdDetectPSKClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
{"printdemodbuffer",CmdPrintDemodBuff,1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"},
{"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Demodulate an indala tag (PSK1) from GraphBuffer (args optional)"},
//{"psk1rawdemod", CmdPSK1rawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk1 tags and output binary (args optional)"},
//{"psk2rawdemod", CmdPSK2rawDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate psk2 tags and output binary (args optional)"},
{"printdemodbuffer",CmdPrintDemodBuff, 1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"},
{"pskindalademod", CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Demodulate an indala tag (PSK1) from GraphBuffer (args optional)"},
{"rawdemod", CmdRawDemod, 1, "[modulation] ... <options> -see help (h option) -- Demodulate the data in the GraphBuffer and output binary"},
{"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window (GraphBuffer)"},
{"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
{"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
{"setdebugmode", CmdSetDebugMode, 1, "<0|1> -- Turn on or off Debugging Mode for demods"},
{"shiftgraphzero",CmdGraphShiftZero, 1, "<shift> -- Shift 0 for Graphed wave + or - shift value"},
{"shiftgraphzero", CmdGraphShiftZero, 1, "<shift> -- Shift 0 for Graphed wave + or - shift value"},
//{"threshold", CmdThreshold, 1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
{"dirthreshold", CmdDirectionalThreshold, 1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
{"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"},

View file

@ -23,6 +23,7 @@ int CmdAskEM410xDemod(const char *Cmd);
int CmdG_Prox_II_Demod(const char *Cmd);
int Cmdaskrawdemod(const char *Cmd);
int Cmdaskmandemod(const char *Cmd);
int AutoCorrelate(int window, bool SaveGrph, bool verbose);
int CmdAutoCorr(const char *Cmd);
int CmdBiphaseDecodeRaw(const char *Cmd);
int CmdBitsamples(const char *Cmd);
@ -62,11 +63,16 @@ int CmdThreshold(const char *Cmd);
int CmdDirectionalThreshold(const char *Cmd);
int CmdZerocrossings(const char *Cmd);
int CmdIndalaDecode(const char *Cmd);
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo);
int ASKbiphaseDemod(const char *Cmd, bool verbose);
int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch);
int ASKrawDemod(const char *Cmd, bool verbose);
int FSKrawDemod(const char *Cmd, bool verbose);
int PSKDemod(const char *Cmd, bool verbose);
int NRZrawDemod(const char *Cmd, bool verbose);
void printEM410x(uint32_t hi, uint64_t id);
int getSamples(const char *Cmd, bool silent);
#define MAX_DEMOD_BUF_LEN (1024*128)
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];

View file

@ -30,6 +30,7 @@
#include "loclass/elite_crack.h"
#include "loclass/fileutils.h"
#include "protocols.h"
#include "usb_cmd.h"
static int CmdHelp(const char *Cmd);
@ -166,29 +167,25 @@ int CmdHFiClassSim(const char *Cmd)
int CmdHFiClassReader(const char *Cmd)
{
UsbCommand c = {CMD_READER_ICLASS, {0}};
UsbCommand c = {CMD_READER_ICLASS, {FLAG_ICLASS_READER_CSN|
FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_AA}};
SendCommand(&c);
UsbCommand resp;
while(!ukbhit()){
if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
uint8_t isOK = resp.arg[0] & 0xff;
uint8_t readStatus = resp.arg[0] & 0xff;
uint8_t * data = resp.d.asBytes;
PrintAndLog("isOk:%02x", isOK);
if( isOK == 0){
PrintAndLog("Readstatus:%02x", readStatus);
if( readStatus == 0){
//Aborted
PrintAndLog("Quitting...");
return 0;
}
if(isOK > 0)
{
PrintAndLog("CSN: %s",sprint_hex(data,8));
}
if(isOK >= 1)
{
PrintAndLog("CC: %s",sprint_hex(data+8,8));
}else{
PrintAndLog("No CC obtained");
if( readStatus & FLAG_ICLASS_READER_CSN) PrintAndLog("CSN: %s",sprint_hex(data,8));
if( readStatus & FLAG_ICLASS_READER_CC) PrintAndLog("CC: %s",sprint_hex(data+16,8));
if( readStatus & FLAG_ICLASS_READER_CONF){
printIclassDumpInfo(data);
}
} else {
PrintAndLog("Command execute timeout");
@ -269,7 +266,7 @@ int CmdHFiClassReader_Dump(const char *Cmd)
uint8_t key_sel_p[8] = { 0 };
UsbCommand c = {CMD_READER_ICLASS, {0}};
c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_GET_CC;
c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_CC;
SendCommand(&c);
@ -284,7 +281,7 @@ int CmdHFiClassReader_Dump(const char *Cmd)
uint8_t * data = resp.d.asBytes;
memcpy(CSN,data,8);
memcpy(CCNR,data+8,8);
memcpy(CCNR,data+16,8);
PrintAndLog("isOk:%02x", isOK);

View file

@ -1539,7 +1539,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
char buf[64] = {0x00};
uint8_t buf8[64] = {0x00};
uint8_t fillFromEmulator = 0;
int i, len, blockNum, flags;
int i, len, blockNum, flags=0;
if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
PrintAndLog("It loads magic Chinese card from the file `filename.eml`");

View file

@ -320,7 +320,7 @@ int CmdHFTopazReader(const char *Cmd)
for (uint16_t j = 0; j < 8; j++) {
sprintf(&line[3*j], "%02x ", topaz_tag.data_blocks[i][j] /*rall_response[2 + 8*i + j]*/);
}
PrintAndLog(" 0x%02x | 0x%02x | %s| %-3s", i, i*8, line, topaz_block_is_locked(i, &topaz_tag.data_blocks[0x0d][0]) ? "yes" : "no");
PrintAndLog(" 0x%02x | 0x%02x | %s| %-3s", i, i*8, line, topaz_block_is_locked(i, &topaz_tag.data_blocks[0x0e][0]) ? "yes" : "no");
}
PrintAndLog("");

View file

@ -362,6 +362,7 @@ int usage_lf_read()
PrintAndLog("Usage: lf read");
PrintAndLog("Options: ");
PrintAndLog(" h This help");
PrintAndLog(" s silent run no printout");
PrintAndLog("This function takes no arguments. ");
PrintAndLog("Use 'lf config' to set parameters.");
return 0;
@ -481,13 +482,15 @@ int CmdLFSetConfig(const char *Cmd)
int CmdLFRead(const char *Cmd)
{
uint8_t cmdp =0;
if(param_getchar(Cmd, cmdp) == 'h')
uint8_t cmdp = 0;
bool arg1 = false;
if (param_getchar(Cmd, cmdp) == 'h')
{
return usage_lf_read();
}
if (param_getchar(Cmd, cmdp) == 's') arg1 = true; //suppress print
//And ship it to device
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K};
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
SendCommand(&c);
WaitForResponse(CMD_ACK,NULL);
return 0;
@ -570,12 +573,13 @@ int usage_lf_simfsk(void)
int usage_lf_simask(void)
{
//print help
PrintAndLog("Usage: lf simask [c <clock>] [i] [m|r] [s] [d <raw hex to sim>]");
PrintAndLog("Usage: lf simask [c <clock>] [i] [b|m|r] [s] [d <raw hex to sim>]");
PrintAndLog("Options: ");
PrintAndLog(" h This help");
PrintAndLog(" c <clock> Manually set clock - can autodetect if using DemodBuffer");
PrintAndLog(" i invert data");
PrintAndLog(" m sim ask/manchester");
PrintAndLog(" b sim ask/biphase");
PrintAndLog(" m sim ask/manchester - Default");
PrintAndLog(" r sim ask/raw");
PrintAndLog(" s TBD- -to enable a gap between playback repetitions - default: no gap");
PrintAndLog(" d <hexdata> Data to sim as hex - omit to sim from DemodBuffer");
@ -703,7 +707,7 @@ int CmdLFaskSim(const char *Cmd)
{
//autodetect clock from Graphbuffer if using demod buffer
//will need clock, invert, manchester/raw as m or r, separator as s, and bitstream
uint8_t manchester = 1, separator = 0;
uint8_t encoding = 1, separator = 0;
//char cmdp = Cmd[0], par3='m', par4=0;
uint8_t clk=0, invert=0;
bool errors = FALSE;
@ -725,12 +729,16 @@ int CmdLFaskSim(const char *Cmd)
errors |= param_getdec(Cmd,cmdp+1,&clk);
cmdp+=2;
break;
case 'b':
encoding=2; //biphase
cmdp++;
break;
case 'm':
manchester=1;
encoding=1;
cmdp++;
break;
case 'r':
manchester=0;
encoding=0;
cmdp++;
break;
case 's':
@ -771,10 +779,10 @@ int CmdLFaskSim(const char *Cmd)
setDemodBuf(data, dataLen, 0);
}
if (clk == 0) clk = 64;
if (manchester == 0) clk = clk/2; //askraw needs to double the clock speed
if (encoding == 0) clk = clk/2; //askraw needs to double the clock speed
uint16_t arg1, arg2;
size_t size=DemodBufferLen;
arg1 = clk << 8 | manchester;
arg1 = clk << 8 | encoding;
arg2 = invert << 8 | separator;
if (size > USB_CMD_DATA_SIZE) {
PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE);
@ -1011,7 +1019,7 @@ int CmdLFfind(const char *Cmd)
int ans=0;
char cmdp = param_getchar(Cmd, 0);
char testRaw = param_getchar(Cmd, 1);
if (strlen(Cmd) > 2 || cmdp == 'h' || cmdp == 'H') {
if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: lf search <0|1> [u]");
PrintAndLog(" <use data from Graphbuffer> , if not set, try reading data from tag.");
PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags.");
@ -1032,72 +1040,88 @@ int CmdLFfind(const char *Cmd)
return 0;
}
if (cmdp == 'u' || cmdp == 'U') testRaw = 'u';
PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag");
PrintAndLog("False Positives ARE possible\n");
PrintAndLog("\nChecking for known tags:\n");
ans=CmdFSKdemodIO("");
if (ans>0) {
PrintAndLog("\nValid IO Prox ID Found!");
return 1;
}
ans=CmdFSKdemodPyramid("");
if (ans>0) {
PrintAndLog("\nValid Pyramid ID Found!");
return 1;
}
ans=CmdFSKdemodParadox("");
if (ans>0) {
PrintAndLog("\nValid Paradox ID Found!");
return 1;
}
ans=CmdFSKdemodAWID("");
if (ans>0) {
PrintAndLog("\nValid AWID ID Found!");
return 1;
}
ans=CmdFSKdemodHID("");
if (ans>0) {
PrintAndLog("\nValid HID Prox ID Found!");
return 1;
}
//add psk and indala
ans=CmdIndalaDecode("");
if (ans>0) {
PrintAndLog("\nValid Indala ID Found!");
return 1;
}
ans=CmdAskEM410xDemod("");
if (ans>0) {
PrintAndLog("\nValid EM410x ID Found!");
return 1;
}
ans=CmdG_Prox_II_Demod("");
if (ans>0) {
PrintAndLog("\nValid G Prox II ID Found!");
return 1;
}
PrintAndLog("\nNo Known Tags Found!\n");
if (testRaw=='u' || testRaw=='U'){
//test unknown tag formats (raw mode)
PrintAndLog("\nChecking for Unknown tags:\n");
ans=CmdDetectClockRate("f");
ans=AutoCorrelate(4000, FALSE, FALSE);
if (ans > 0) PrintAndLog("Possible Auto Correlation of %d repeating samples",ans);
ans=GetFskClock("",FALSE,FALSE); //CmdDetectClockRate("F"); //
if (ans != 0){ //fsk
ans=CmdFSKrawdemod("");
ans=FSKrawDemod("",FALSE);
if (ans>0) {
PrintAndLog("\nUnknown FSK Modulated Tag Found!");
printDemodBuff();
return 1;
}
}
ans=Cmdaskmandemod("");
ans=ASKmanDemod("",FALSE,FALSE);
if (ans>0) {
PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!");
PrintAndLog("\nif it does not look right it could instead be ASK/Biphase - try 'data rawdemod ab'");
printDemodBuff();
return 1;
}
ans=CmdPSK1rawDemod("");
if (ans>0) {
PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data psk2rawdemod'");
PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'");
PrintAndLog("\nCould also be PSK3 - [currently not supported]");
PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod");
printDemodBuff();
return 1;
}
PrintAndLog("\nNo Data Found!\n");
@ -1116,7 +1140,7 @@ static command_t CommandTable[] =
{"io", CmdLFIO, 1, "{ ioProx tags... }"},
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
{"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
{"read", CmdLFRead, 0, "Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
{"read", CmdLFRead, 0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
{"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"},
{"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
{"simask", CmdLFaskSim, 0, "[clock] [invert <1|0>] [manchester/raw <'m'|'r'>] [msg separator 's'] [d <hexdata>] -- Simulate LF ASK tag from demodbuffer or input"},

View file

@ -43,163 +43,24 @@ int CmdEMdemodASK(const char *Cmd)
*/
int CmdEM410xRead(const char *Cmd)
{
int i, j, clock, header, rows, bit, hithigh, hitlow, first, bit2idx, high, low;
int parity[4];
char id[11] = {0x00};
char id2[11] = {0x00};
int retested = 0;
uint8_t BitStream[MAX_GRAPH_TRACE_LEN];
high = low = 0;
uint32_t hi=0;
uint64_t lo=0;
/* Detect high and lows and clock */
for (i = 0; i < GraphTraceLen; i++)
{
if (GraphBuffer[i] > high)
high = GraphBuffer[i];
else if (GraphBuffer[i] < low)
low = GraphBuffer[i];
}
/* get clock */
clock = GetAskClock(Cmd, false, false);
/* parity for our 4 columns */
parity[0] = parity[1] = parity[2] = parity[3] = 0;
header = rows = 0;
// manchester demodulate
bit = bit2idx = 0;
for (i = 0; i < (int)(GraphTraceLen / clock); i++)
{
hithigh = 0;
hitlow = 0;
first = 1;
/* Find out if we hit both high and low peaks */
for (j = 0; j < clock; j++)
{
if (GraphBuffer[(i * clock) + j] >= high)
hithigh = 1;
else if (GraphBuffer[(i * clock) + j] <= low)
hitlow = 1;
/* it doesn't count if it's the first part of our read
because it's really just trailing from the last sequence */
if (first && (hithigh || hitlow))
hithigh = hitlow = 0;
else
first = 0;
if (hithigh && hitlow)
break;
}
/* If we didn't hit both high and low peaks, we had a bit transition */
if (!hithigh || !hitlow)
bit ^= 1;
BitStream[bit2idx++] = bit;
}
retest:
/* We go till 5 before the graph ends because we'll get that far below */
for (i = 1; i < bit2idx - 5; i++)
{
/* Step 2: We have our header but need our tag ID */
if (header == 9 && rows < 10)
{
/* Confirm parity is correct */
if ((BitStream[i] ^ BitStream[i+1] ^ BitStream[i+2] ^ BitStream[i+3]) == BitStream[i+4])
{
/* Read another byte! */
sprintf(id+rows, "%x", (8 * BitStream[i]) + (4 * BitStream[i+1]) + (2 * BitStream[i+2]) + (1 * BitStream[i+3]));
sprintf(id2+rows, "%x", (8 * BitStream[i+3]) + (4 * BitStream[i+2]) + (2 * BitStream[i+1]) + (1 * BitStream[i]));
rows++;
/* Keep parity info */
parity[0] ^= BitStream[i];
parity[1] ^= BitStream[i+1];
parity[2] ^= BitStream[i+2];
parity[3] ^= BitStream[i+3];
/* Move 4 bits ahead */
i += 4;
}
/* Damn, something wrong! reset */
else
{
PrintAndLog("Thought we had a valid tag but failed at word %d (i=%d)", rows + 1, i);
/* Start back rows * 5 + 9 header bits, -1 to not start at same place */
i -= 9 + (5 * rows) - 5;
rows = header = 0;
}
}
/* Step 3: Got our 40 bits! confirm column parity */
else if (rows == 10)
{
/* We need to make sure our 4 bits of parity are correct and we have a stop bit */
if (BitStream[i] == parity[0] && BitStream[i+1] == parity[1] &&
BitStream[i+2] == parity[2] && BitStream[i+3] == parity[3] &&
BitStream[i+4] == 0)
{
/* Sweet! */
PrintAndLog("EM410x Tag ID: %s", id);
PrintAndLog("Unique Tag ID: %s", id2);
global_em410xId = id;
/* Stop any loops */
return 1;
}
/* Crap! Incorrect parity or no stop bit, start all over */
else
{
rows = header = 0;
/* Go back 59 bits (9 header bits + 10 rows at 4+1 parity) */
i -= 59;
}
}
/* Step 1: get our header */
else if (header < 9)
{
/* Need 9 consecutive 1's */
if (BitStream[i] == 1)
header++;
/* We don't have a header, not enough consecutive 1 bits */
else
header = 0;
}
}
/* if we've already retested after flipping bits, return */
if (retested++){
PrintAndLog("Failed to decode");
if(!AskEm410xDemod("", &hi, &lo)) return 0;
PrintAndLog("EM410x pattern found: ");
printEM410x(hi, lo);
if (hi){
PrintAndLog ("EM410x XL pattern found");
return 0;
}
char id[12] = {0x00};
sprintf(id, "%010llx",lo);
/* if this didn't work, try flipping bits */
for (i = 0; i < bit2idx; i++)
BitStream[i] ^= 1;
goto retest;
global_em410xId = id;
return 1;
}
/* emulate 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
*/
// emulate an EM410X tag
int CmdEM410xSim(const char *Cmd)
{
int i, n, j, binary[4], parity[4];
@ -282,27 +143,24 @@ int CmdEM410xSim(const char *Cmd)
*/
int CmdEM410xWatch(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
int read_h = (cmdp == 'h');
do {
if (ukbhit()) {
printf("\naborted via keyboard!\n");
break;
}
CmdLFRead(read_h ? "h" : "");
CmdSamples("6000");
} while (
!CmdEM410xRead("")
);
CmdLFRead("s");
getSamples("8192",true); //capture enough to get 2 full messages
} while (!CmdEM410xRead(""));
return 0;
}
int CmdEM410xWatchnSpoof(const char *Cmd)
{
CmdEM410xWatch(Cmd);
PrintAndLog("# Replaying : %s",global_em410xId);
CmdEM410xSim(global_em410xId);
PrintAndLog("# Replaying captured ID: %s",global_em410xId);
CmdLFaskSim("");
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -10,12 +10,57 @@
#ifndef CMDLFT55XX_H__
#define CMDLFT55XX_H__
int CmdLFT55XX(const char *Cmd);
typedef struct {
enum {
DEMOD_NRZ = 0x00,
DEMOD_PSK1 = 0x01,
DEMOD_PSK2 = 0x02,
DEMOD_PSK3 = 0x03,
DEMOD_FSK1 = 0x04,
DEMOD_FSK1a = 0x05,
DEMOD_FSK2 = 0x06,
DEMOD_FSK2a = 0x07,
DEMOD_FSK = 0xF0, //generic FSK (auto detect FCs)
DEMOD_ASK = 0x08,
DEMOD_BI = 0x10,
DEMOD_BIa = 0x18,
} modulation;
bool inverted;
uint8_t offset;
uint32_t block0;
enum {
RF_8 = 0x00,
RF_16 = 0x01,
RF_32 = 0x02,
RF_40 = 0x03,
RF_50 = 0x04,
RF_64 = 0x05,
RF_100 = 0x06,
RF_128 = 0x07,
} bitrate;
} t55xx_conf_block_t;
int CmdReadBlk(const char *Cmd);
int CmdReadBlkPWD(const char *Cmd);
int CmdWriteBlk(const char *Cmd);
int CmdWriteBLkPWD(const char *Cmd);
int CmdReadTrace(const char *Cmd);
int CmdLFT55XX(const char *Cmd);
int CmdT55xxSetConfig(const char *Cmd);
int CmdT55xxReadBlock(const char *Cmd);
int CmdT55xxWriteBlock(const char *Cmd);
int CmdT55xxReadTrace(const char *Cmd);
int CmdT55xxInfo(const char *Cmd);
int CmdT55xxDetect(const char *Cmd);
char * GetBitRateStr(uint32_t id);
char * GetSaferStr(uint32_t id);
char * GetModulationStr( uint32_t id);
char * GetModelStrFromCID(uint32_t cid);
char * GetSelectedModulationStr( uint8_t id);
uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bitstream);
void printT55xxBlock(const char *demodStr);
void printConfiguration( t55xx_conf_block_t b);
bool DecodeT55xxBlock();
bool tryDetectModulation();
bool test(uint8_t mode, uint8_t *offset);
int special(const char *Cmd);
int AquireData( uint8_t block );
#endif

View file

@ -146,7 +146,7 @@ uint8_t GetPskCarrier(const char str[], bool printAns, bool verbose)
}
//uint8_t countPSK_FC(uint8_t *BitStream, size_t size)
carrier = countPSK_FC(grph,size);
carrier = countFC(grph,size,0);
// Only print this message if we're not looping something
if (printAns){
PrintAndLog("Auto-detected PSK carrier rate: %d", carrier);
@ -232,8 +232,7 @@ uint8_t fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, bool verbose)
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t size = getFromGraphBuf(BitStream);
if (size==0) return 0;
uint8_t dummy = 0;
uint16_t ans = countFC(BitStream, size, &dummy);
uint16_t ans = countFC(BitStream, size, 1);
if (ans==0) {
if (verbose) PrintAndLog("DEBUG: No data found");
return 0;

View file

@ -0,0 +1,139 @@
local cmds = require('commands')
local getopt = require('getopt')
local bin = require('bin')
local utils = require('utils')
local format=string.format
local floor=math.floor
example =[[
1. script run test_t55x7_ask
]]
author = "Iceman"
usage = "script run test_t55x7_ask"
desc =[[
This script will program a T55x7 TAG with the configuration: block 0x00 data 0x000100
The outlined procedure is as following:
--ASK
00 00 80 40
-- max 2
-- manchester
-- bit rate
"lf t55xx write 0 00008040"
"lf t55xx detect"
"lf t55xx info"
Loop:
change the configuretion block 0 with:
-xx 00 xxxx = RF/8
-xx 04 xxxx = RF/16
-xx 08 xxxx = RF/32
-xx 0C xxxx = RF/40
-xx 10 xxxx = RF/50
-xx 14 xxxx = RF/64
-xx 18 xxxx = RF/100
-xx 1C xxxx = RF/128
testsuit for the ASK/MANCHESTER demod
Arguments:
-h : this help
]]
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
local DEBUG = true -- the debug flag
--BLOCK 0 = 00008040 ASK / MAN
local config1 = '00'
local config2 = '8040'
local procedurecmds = {
[1] = '%s%02X%s',
[2] = 'lf t55xx detect',
[3] = 'lf t55xx info',
}
---
-- A debug printout-function
function dbg(args)
if not DEBUG then
return
end
if type(args) == "table" then
local i = 1
while args[i] do
dbg(args[i])
i = i+1
end
else
print("###", args)
end
end
---
-- This is only meant to be used when errors occur
function oops(err)
print("ERROR: ",err)
end
---
-- Usage help
function help()
print(desc)
print("Example usage")
print(example)
end
--
-- Exit message
function ExitMsg(msg)
print( string.rep('--',20) )
print( string.rep('--',20) )
print(msg)
print()
end
function test()
local y
for y = 0x0, 0x1d, 0x4 do
for _ = 1, #procedurecmds do
local pcmd = procedurecmds[_]
if #pcmd == 0 then
elseif _ == 1 then
local config = pcmd:format(config1, y, config2)
dbg(('lf t55xx write 0 %s'):format(config))
config = tonumber(config,16)
local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config}
local err = core.SendCommand(writecmd:getBytes())
if err then return oops(err) end
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
else
dbg(pcmd)
core.console( pcmd )
end
end
core.clearCommandBuffer()
end
print( string.rep('--',20) )
end
local function main(args)
print( string.rep('--',20) )
print( string.rep('--',20) )
-- Arguments for the script
for o, arg in getopt.getopt(args, 'h') do
if o == "h" then return help() end
end
core.clearCommandBuffer()
test()
print( string.rep('--',20) )
end
main(args)

View file

@ -0,0 +1,133 @@
local cmds = require('commands')
local getopt = require('getopt')
local bin = require('bin')
local utils = require('utils')
example =[[
1. script run test_t55x7_bi
]]
author = "Iceman"
usage = "script run test_t55x7_bi"
desc =[[
This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00010040
The outlined procedure is as following:
--BIPHASE 00010040
--
"lf t55xx write 0 00010040"
"lf t55xx detect"
"lf t55xx info"
Loop:
change the configuretion block 0 with:
-xx01xxxx = RF/8
-xx05xxxx = RF/16
-xx09xxxx = RF/32
-xx0Dxxxx = RF/40
-xx11xxxx = RF/50
-xx15xxxx = RF/64
-xx19xxxx = RF/100
-xx1Dxxxx = RF/128
testsuit for the BIPHASE demod
Arguments:
-h : this help
]]
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
local DEBUG = true -- the debug flag
--BLOCK 0 = 00010040 BIPHASE
local config1 = '00'
local config2 = '0040'
local procedurecmds = {
[1] = '%s%02X%s',
[2] = 'lf t55xx detect',
[3] = 'lf t55xx info',
}
---
-- A debug printout-function
function dbg(args)
if not DEBUG then
return
end
if type(args) == "table" then
local i = 1
while args[i] do
dbg(args[i])
i = i+1
end
else
print("###", args)
end
end
---
-- This is only meant to be used when errors occur
function oops(err)
print("ERROR: ",err)
end
---
-- Usage help
function help()
print(desc)
print("Example usage")
print(example)
end
--
-- Exit message
function ExitMsg(msg)
print( string.rep('--',20) )
print( string.rep('--',20) )
print(msg)
print()
end
function test()
local y
for y = 1, 0x1D, 4 do
for _ = 1, #procedurecmds do
local pcmd = procedurecmds[_]
if #pcmd == 0 then
elseif _ == 1 then
local config = pcmd:format(config1, y, config2)
dbg(('lf t55xx wr 0 %s'):format(config))
config = tonumber(config,16)
local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config}
local err = core.SendCommand(writecmd:getBytes())
if err then return oops(err) end
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
else
dbg(pcmd)
core.console( pcmd )
end
end
core.clearCommandBuffer()
end
print( string.rep('--',20) )
end
local function main(args)
print( string.rep('--',20) )
print( string.rep('--',20) )
-- Arguments for the script
for o, arg in getopt.getopt(args, 'h') do
if o == "h" then return help() end
end
core.clearCommandBuffer()
test()
print( string.rep('--',20) )
end
main(args)

View file

@ -0,0 +1,139 @@
local cmds = require('commands')
local getopt = require('getopt')
local bin = require('bin')
local utils = require('utils')
example =[[
1. script run test_t55x7_fsk
]]
author = "Iceman"
usage = "script run test_t55x7_fsk"
desc =[[
This script will program a T55x7 TAG with the configuration: block 0x00 data 0x000100
The outlined procedure is as following:
--ASK
00 00 80 40
-- max 2 blocks
-- FSK1
-- bit rate
"lf t55xx write 0 00007040"
"lf t55xx detect"
"lf t55xx info"
Loop:
change the configuretion block 0 with:
-xx 00 xxxx = RF/8
-xx 04 xxxx = RF/16
-xx 08 xxxx = RF/32
-xx 0C xxxx = RF/40
-xx 10 xxxx = RF/50
-xx 14 xxxx = RF/64
-xx 18 xxxx = RF/100
-xx 1C xxxx = RF/128
testsuit for the ASK/MANCHESTER demod
Arguments:
-h : this help
]]
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
local DEBUG = true -- the debug flag
--BLOCK 0 = 00008040 FSK
local config1 = '00'
local config2 = '040'
local procedurecmds = {
[1] = '%s%02X%X%s',
[2] = 'lf t55xx detect',
[3] = 'lf t55xx info',
}
---
-- A debug printout-function
function dbg(args)
if not DEBUG then
return
end
if type(args) == "table" then
local i = 1
while args[i] do
dbg(args[i])
i = i+1
end
else
print("###", args)
end
end
---
-- This is only meant to be used when errors occur
function oops(err)
print("ERROR: ",err)
end
---
-- Usage help
function help()
print(desc)
print("Example usage")
print(example)
end
--
-- Exit message
function ExitMsg(msg)
print( string.rep('--',20) )
print( string.rep('--',20) )
print(msg)
print()
end
function test(modulation)
local y
for y = 0x0, 0x1d, 0x4 do
for _ = 1, #procedurecmds do
local pcmd = procedurecmds[_]
if #pcmd == 0 then
elseif _ == 1 then
local config = pcmd:format(config1, y, modulation, config2)
dbg(('lf t55xx write 0 %s'):format(config))
config = tonumber(config,16)
local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config}
local err = core.SendCommand(writecmd:getBytes())
if err then return oops(err) end
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
else
dbg(pcmd)
core.console( pcmd )
end
end
core.clearCommandBuffer()
end
print( string.rep('--',20) )
end
local function main(args)
print( string.rep('--',20) )
print( string.rep('--',20) )
-- Arguments for the script
for o, arg in getopt.getopt(args, 'h') do
if o == "h" then return help() end
end
core.clearCommandBuffer()
test(4)
test(5)
test(6)
test(7)
print( string.rep('--',20) )
end
main(args)

View file

@ -2,15 +2,14 @@ local cmds = require('commands')
local getopt = require('getopt')
local bin = require('bin')
local utils = require('utils')
local dumplib = require('html_dumplib')
example =[[
1. script run tracetest
2. script run tracetest -o
1. script run test_t55x7_psk
2. script run test_t55x7_psk -o
]]
author = "Iceman"
usage = "script run test_t55x7_psk -o <filename>"
usage = "script run test_t55x7_psk"
desc =[[
This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00088040
The outlined procedure is as following:
@ -39,26 +38,35 @@ In all 12 individual test for the PSK demod
Arguments:
-h : this help
-o : logfile name
]]
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
local DEBUG = true -- the debug flag
--BLOCK 0 = 00088040
local config1 = '0008'
local config2 = '40'
-- local procedurecmds = {
-- [1] = '%s%s%s%s',
-- [2] = 'lf read',
-- --[3] = '',
-- [3] = 'data samples',
-- [4] = 'data pskdetectclock',
-- [5] = 'data psknrzrawdemod',
-- [6] = 'data pskindalademod',
-- }
-- --BLOCK 0 = 00 08 80 40 PSK
-- -----------
-- 08------- bitrate
-- 8----- modulation PSK1
-- 0---- PSK ClockRate
-- 40 max 2 blocks
local procedurecmds = {
[1] = '%s%s%s%s',
[2] = 'lf read',
[1] = '00%02X%X%X40',
[2] = 'lf t55xx detect',
--[3] = '',
[3] = 'data samples',
[4] = 'data pskdetectclock',
[5] = 'data psknrzrawdemod',
[6] = 'data pskindalademod',
[3] = 'lf t55xx info',
}
---
-- A debug printout-function
function dbg(args)
@ -97,9 +105,13 @@ function ExitMsg(msg)
print()
end
function pskTest(modulation)
local y
for y = 0, 8, 4 do
function test(modulation)
local bitrate
local clockrate
for bitrate = 0x0, 0x1d, 0x4 do
for clockrate = 0,8,4 do
for _ = 1, #procedurecmds do
local cmd = procedurecmds[_]
@ -109,24 +121,14 @@ function pskTest(modulation)
dbg("Writing to T55x7 TAG")
local configdata = cmd:format( config1, modulation , y, config2)
local config = cmd:format(bitrate, modulation, clockrate)
dbg(('lf t55xx write 0 %s'):format(config))
dbg( configdata)
local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = configdata ,arg2 = 0, arg3 = 0}
config = tonumber(config,16)
local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config ,arg2 = 0, arg3 = 0}
local err = core.SendCommand(writecommand:getBytes())
if err then return oops(err) end
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
if response then
local count,cmd,arg0 = bin.unpack('LL',response)
if(arg0==1) then
dbg("Writing success")
else
return nil, "Couldn't read block.."
end
end
else
dbg(cmd)
core.console( cmd )
@ -134,8 +136,8 @@ function pskTest(modulation)
end
core.clearCommandBuffer()
end
end
print( string.rep('--',20) )
end
local function main(args)
@ -143,20 +145,16 @@ local function main(args)
print( string.rep('--',20) )
print( string.rep('--',20) )
local outputTemplate = os.date("testpsk_%Y-%m-%d_%H%M%S")
-- Arguments for the script
for o, arg in getopt.getopt(args, 'ho:') do
for o, arg in getopt.getopt(args, 'h') do
if o == "h" then return help() end
if o == "o" then outputTemplate = arg end
end
core.clearCommandBuffer()
pskTest(1)
pskTest(2)
pskTest(3)
pskTest(8)
test(1) -- PSK1
--test(2) -- PSK2
--test(3) -- PSK3
print( string.rep('--',20) )
end

View file

@ -6,19 +6,20 @@ local dumplib = require('html_dumplib')
example =[[
1. script run tracetest
2. script run tracetest -o
]]
author = "Iceman"
usage = "script run tracetest -o <filename>"
usage = "script run tracetest"
desc =[[
This script will load several traces files in ../traces/ folder and do
"data load"
"lf search"
"lf search 1 u"
The following tracefiles will be loaded:
em*.pm3
m*.pm3
Arguments:
-h : this help
-o : logfile name
]]
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
@ -71,12 +72,12 @@ local function main(args)
local tracesEM = "find '../traces/' -iname 'em*.pm3' -type f"
local tracesMOD = "find '../traces/' -iname 'm*.pm3' -type f"
local write2File = false
local outputTemplate = os.date("testtest_%Y-%m-%d_%H%M%S")
-- Arguments for the script
for o, arg in getopt.getopt(args, 'ho:') do
for o, arg in getopt.getopt(args, 'h') do
if o == "h" then return help() end
if o == "o" then outputTemplate = arg end
end
core.clearCommandBuffer()
@ -97,7 +98,7 @@ local function main(args)
end
p.close();
local cmdLFSEARCH = "lf search 1"
local cmdLFSEARCH = "lf search 1 u"
-- main loop
io.write('Starting to test traces > ')
@ -119,13 +120,6 @@ local function main(args)
end
io.write('\n')
-- Write dump to files
if not DEBUG then
local bar = dumplib.SaveAsText(emldata, outputTemplate..'.txt')
print(("Wrote output to: %s"):format(bar))
end
-- Show info
print( string.rep('--',20) )
end

View file

@ -5,8 +5,9 @@
//-----------------------------------------------------------------------------
// Generic CRC calculation code.
//-----------------------------------------------------------------------------
#include "crc.h"
#include <stdint.h>
#include <stddef.h>
void crc_init(crc_t *crc, int order, uint32_t polynom, uint32_t initial_value, uint32_t final_xor)
{
@ -40,3 +41,16 @@ uint32_t crc_finish(crc_t *crc)
{
return ( crc->state ^ crc->final_xor ) & crc->mask;
}
//credits to iceman
uint32_t CRC8Maxim(uint8_t *buff, size_t size)
{
crc_t crc;
crc_init(&crc, 9, 0x8c, 0x00, 0x00);
crc_clear(&crc);
for (size_t i=0; i < size; ++i){
crc_update(&crc, buff[i], 8);
}
return crc_finish(&crc);
}

View file

@ -10,6 +10,7 @@
#define __CRC_H
#include <stdint.h>
#include <stddef.h>
typedef struct crc {
uint32_t state;
@ -36,6 +37,8 @@ extern void crc_clear(crc_t *crc);
/* Get the result of the crc calculation */
extern uint32_t crc_finish(crc_t *crc);
// Calculate CRC-8/Maxim checksum
uint32_t CRC8Maxim(uint8_t *buff, size_t size );
/* Static initialization of a crc structure */
#define CRC_INITIALIZER(_order, _polynom, _initial_value, _final_xor) { \
.state = ((_initial_value) & ((1L<<(_order))-1)), \

View file

@ -1,6 +1,7 @@
/*
-----------------------------------------------------------------------------
This code is licensed to you under the terms of the GNU GPL, version 2 or,
This code is licensed to you under the ter
ms of the GNU GPL, version 2 or,
at your option, any later version. See the LICENSE.txt file for the text of
the license.
-----------------------------------------------------------------------------
@ -13,8 +14,7 @@ MEMORY
{
bootphase1 : ORIGIN = 0x00100000, LENGTH = 0x200 /* Phase 1 bootloader: Copies real bootloader to RAM */
bootphase2 : ORIGIN = 0x00100200, LENGTH = 0x2000 - 0x200 /* Main bootloader code, stored in Flash, executed from RAM */
fpgaimage : ORIGIN = 0x00102000, LENGTH = 96k - 0x2000 /* Place where the FPGA image will end up */
osimage : ORIGIN = 0x00118000, LENGTH = 256K - 96k /* Place where the main OS will end up */
osimage : ORIGIN = 0x00102000, LENGTH = 256K - 0x2000 /* Place where the main OS will end up */
ram : ORIGIN = 0x00200000, LENGTH = 64K - 0x20 /* RAM, minus small common area */
commonarea : ORIGIN = 0x00200000 + 64K - 0x20, LENGTH = 0x20 /* Communication between bootloader and main OS */
}

File diff suppressed because it is too large Load diff

View file

@ -16,8 +16,9 @@
#include <stdint.h>
int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr);
uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low);
int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr);
uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx);
uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo);
int ManchesterEncode(uint8_t *BitStream, size_t size);
int manrawdecode(uint8_t *BitStream, size_t *size);
int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
@ -32,18 +33,15 @@ void psk1TOpsk2(uint8_t *BitStream, size_t size);
void psk2TOpsk1(uint8_t *BitStream, size_t size);
int DetectNRZClock(uint8_t dest[], size_t size, int clock);
int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
void pskCleanWave(uint8_t *bitStream, size_t size);
int PyramiddemodFSK(uint8_t *dest, size_t *size);
int AWIDdemodFSK(uint8_t *dest, size_t *size);
size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t *mostFC);
uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj);
uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow);
int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
uint8_t justNoise(uint8_t *BitStream, size_t size);
uint8_t countPSK_FC(uint8_t *BitStream, size_t size);
int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert);
int DetectPSKClock(uint8_t dest[], size_t size, int clock);

View file

@ -199,7 +199,11 @@ typedef struct{
//Iclass reader flags
#define FLAG_ICLASS_READER_ONLY_ONCE 0x01
#define FLAG_ICLASS_READER_GET_CC 0x02
#define FLAG_ICLASS_READER_CC 0x02
#define FLAG_ICLASS_READER_CSN 0x04
#define FLAG_ICLASS_READER_CONF 0x08
#define FLAG_ICLASS_READER_AA 0x10
// CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions: