From: Iceman Date: Mon, 19 Dec 2016 15:09:58 +0000 (+0100) Subject: Merge pull request #202 from marshmellow42/master X-Git-Tag: v3.0.0~75 X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/910ad5470d913baeaf9d882a22fc1b853318a5da?hp=d1057e7a2105d5e2696df185482176f22a5bd669 Merge pull request #202 from marshmellow42/master add hitag2 uid read and fixes for iclass write --- diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b09e461..bb2952b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] ### Added +- Added hitag2 read UID only and added that to lf search (marshmellow) - Added lf pyramid commands (iceman) - Added lf presco commands - some bits not fully understood... (iceman) - Added experimental HitagS support (Oguzhan Cicek, Hendrik Schwartke, Ralf Spenneberg) @@ -34,9 +35,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added 'hf snoop'. This command take digitalized signal from FPGA and put in BigBuffer. (pwpiwi + enio) - Added Topaz (NFC type 1) protocol support ('hf topaz reader', 'hf list topaz', 'hf 14a raw -T', 'hf topaz snoop'). (piwi) - Added option c to 'hf list' (mark CRC bytes) (piwi) -- Added option `l` or `h` to `hw tune` to save time and unnecessary fpga writes if you are only interested in lf or hf. ### Changed +- Fixed bug in lf sim and continuous demods not turning off antenna when finished +- Fixed bug(s) in hf iclass write - Fixed bug in lf biphase sim - `lf simask b` (and any tagtype that relies on it - gproxii...) (marshmellow) - Fixed bug in lf viking clone/sim (iceman) - Fixed broken `data askedgedetect` (marshmellow) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 46432d83..d79b29fe 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -697,6 +697,42 @@ static bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx return true; } +static bool hitag2_read_uid(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) { + // Reset the transmission frame length + *txlen = 0; + + // Try to find out which command was send by selecting on length (in bits) + switch (rxlen) { + // No answer, try to resurrect + case 0: { + // Just starting or if there is no answer + *txlen = 5; + memcpy(tx,"\xc0",nbytes(*txlen)); + } break; + // Received UID + case 32: { + // Check if we received answer tag (at) + if (bAuthenticating) { + bAuthenticating = false; + } else { + // Store the received block + memcpy(tag.sectors[blocknr],rx,4); + blocknr++; + } + if (blocknr > 0) { + //DbpString("Read successful!"); + bSuccessful = true; + return false; + } + } break; + // Unexpected response + default: { + Dbprintf("Uknown frame length: %d",rxlen); + return false; + } break; + } + return true; +} void SnoopHitag(uint32_t type) { int frame_count; @@ -1123,19 +1159,18 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { set_tracing(TRUE); clear_trace(); - DbpString("Starting Hitag reader family"); + //DbpString("Starting Hitag reader family"); // Check configuration switch(htf) { case RHT2F_PASSWORD: { Dbprintf("List identifier in password mode"); memcpy(password,htd->pwd.password,4); - blocknr = 0; + blocknr = 0; bQuitTraceFull = false; bQuiet = false; bPwd = false; } break; - case RHT2F_AUTHENTICATE: { DbpString("Authenticating using nr,ar pair:"); memcpy(NrAr,htd->auth.NrAr,8); @@ -1145,7 +1180,6 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { bAuthenticating = false; bQuitTraceFull = true; } break; - case RHT2F_CRYPTO: { DbpString("Authenticating using key:"); memcpy(key,htd->crypto.key,6); //HACK; 4 or 6?? I read both in the code. @@ -1156,7 +1190,6 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { bAuthenticating = false; bQuitTraceFull = true; } break; - case RHT2F_TEST_AUTH_ATTEMPTS: { Dbprintf("Testing %d authentication attempts",(auth_table_len/8)); auth_table_pos = 0; @@ -1165,7 +1198,13 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { bQuiet = false; bCrypto = false; } break; - + case RHT2F_UID_ONLY: { + blocknr = 0; + bQuiet = false; + bCrypto = false; + bAuthenticating = false; + bQuitTraceFull = true; + } break; default: { Dbprintf("Error, unknown function: %d",htf); return; @@ -1222,22 +1261,22 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { // hitagS settings reset_sof = 1; t_wait = 200; - DbpString("Configured for hitagS reader"); + //DbpString("Configured for hitagS reader"); } else if (htf < 20) { // hitag1 settings reset_sof = 1; t_wait = 200; - DbpString("Configured for hitag1 reader"); + //DbpString("Configured for hitag1 reader"); } else if (htf < 30) { // hitag2 settings reset_sof = 4; t_wait = HITAG_T_WAIT_2; - DbpString("Configured for hitag2 reader"); + //DbpString("Configured for hitag2 reader"); } else { Dbprintf("Error, unknown hitag reader type: %d",htf); return; } - + uint8_t attempt_count=0; while(!bStop && !BUTTON_PRESS()) { // Watchdog hit WDT_HIT(); @@ -1272,6 +1311,11 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { case RHT2F_TEST_AUTH_ATTEMPTS: { bStop = !hitag2_test_auth_attempts(rx,rxlen,tx,&txlen); } break; + case RHT2F_UID_ONLY: { + bStop = !hitag2_read_uid(rx, rxlen, tx, &txlen); + attempt_count++; //attempt 3 times to get uid then quit + if (!bStop && attempt_count == 3) bStop = true; + } break; default: { Dbprintf("Error, unknown function: %d",htf); return; @@ -1288,6 +1332,8 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. // All timer values are in terms of T0 units while(AT91C_BASE_TC0->TC_CV < T0*(t_wait+(HITAG_T_TAG_HALF_PERIOD*lastbit))); + + //Dbprintf("DEBUG: Sending reader frame"); // Transmit the reader frame hitag_reader_send_frame(tx,txlen); @@ -1317,7 +1363,9 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { bSkip = true; tag_sof = reset_sof; response = 0; - + //Dbprintf("DEBUG: Waiting to receive frame"); + uint32_t errorCount = 0; + // Receive frame, watch for at most T0*EOF periods while (AT91C_BASE_TC1->TC_CV < T0*HITAG_T_WAIT_MAX) { // Check if falling edge in tag modulation is detected @@ -1333,19 +1381,29 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { // Capture tag frame (manchester decoding using only falling edges) if(ra >= HITAG_T_EOF) { if (rxlen != 0) { - //DbpString("wierd1?"); + //Dbprintf("DEBUG: Wierd1"); } // Capture the T0 periods that have passed since last communication or field drop (reset) // We always recieve a 'one' first, which has the falling edge after a half period |-_| response = ra-HITAG_T_TAG_HALF_PERIOD; } else if(ra >= HITAG_T_TAG_CAPTURE_FOUR_HALF) { // Manchester coding example |-_|_-|-_| (101) + + //need to test to verify we don't exceed memory... + //if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) { + // break; + //} rx[rxlen / 8] |= 0 << (7-(rxlen%8)); rxlen++; rx[rxlen / 8] |= 1 << (7-(rxlen%8)); rxlen++; } else if(ra >= HITAG_T_TAG_CAPTURE_THREE_HALF) { // Manchester coding example |_-|...|_-|-_| (0...01) + + //need to test to verify we don't exceed memory... + //if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) { + // break; + //} rx[rxlen / 8] |= 0 << (7-(rxlen%8)); rxlen++; // We have to skip this half period at start and add the 'one' the second time @@ -1357,6 +1415,11 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { bSkip = !bSkip; } else if(ra >= HITAG_T_TAG_CAPTURE_TWO_HALF) { // Manchester coding example |_-|_-| (00) or |-_|-_| (11) + + //need to test to verify we don't exceed memory... + //if ( ((rxlen+2) / 8) > HITAG_FRAME_LEN) { + // break; + //} if (tag_sof) { // Ignore bits that are transmitted during SOF tag_sof--; @@ -1366,22 +1429,27 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { rxlen++; } } else { + //Dbprintf("DEBUG: Wierd2"); + errorCount++; // Ignore wierd value, is to small to mean anything } } - + //if we saw over 100 wierd values break it probably isn't hitag... + if (errorCount >100) break; // We can break this loop if we received the last bit from a frame if (AT91C_BASE_TC1->TC_CV > T0*HITAG_T_EOF) { if (rxlen>0) break; } } } + //Dbprintf("DEBUG: Done waiting for frame"); + LED_B_OFF(); LED_D_OFF(); AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - Dbprintf("frame received: %d",frame_count); - DbpString("All done"); + //Dbprintf("frame received: %d",frame_count); + //DbpString("All done"); cmd_send(CMD_ACK,bSuccessful,0,0,(byte_t*)tag.sectors,48); } diff --git a/armsrc/iclass.c b/armsrc/iclass.c index f99d0eca..eb5a5a79 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1473,7 +1473,7 @@ void CodeIClassCommand(const uint8_t * cmd, int len) for(j = 0; j < 4; j++) { for(k = 0; k < 4; k++) { if(k == (b & 3)) { - ToSend[++ToSendMax] = 0x0f; + ToSend[++ToSendMax] = 0xf0; } else { ToSend[++ToSendMax] = 0x00; @@ -1580,8 +1580,8 @@ void setupIclassReader() { FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // Reset trace buffer - set_tracing(TRUE); - clear_trace(); + set_tracing(TRUE); + clear_trace(); // Setup SSC FpgaSetupSsc(); @@ -1671,7 +1671,7 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) return read_status; } -uint8_t handshakeIclassTag(uint8_t *card_data){ +uint8_t handshakeIclassTag(uint8_t *card_data) { return handshakeIclassTag_ext(card_data, false); } @@ -1983,18 +1983,26 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) { } bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t *data) { - uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //uint8_t readblockdata[10]; //write[1] = blockNo; memcpy(write+2, data, 12); // data + mac + char *wrCmd = (char *)(write+1); + uint16_t wrCrc = iclass_crc16(wrCmd, 13); + write[14] = wrCrc >> 8; + write[15] = wrCrc & 0xff; uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0}; - bool isOK; + bool isOK = false; + isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10); - if (isOK) { + if (isOK) { //if reader responded correctly //Dbprintf("WriteResp: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",resp[0],resp[1],resp[2],resp[3],resp[4],resp[5],resp[6],resp[7],resp[8],resp[9]); - if (memcmp(write+2,resp,8)) { - //error try again - isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10); + if (memcmp(write+2,resp,8)) { //if response is not equal to write values + if (blockNo != 3 && blockNo != 4) { //if not programming key areas (note key blocks don't get programmed with actual key data it is xor data) + //error try again + isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10); + } + } } return isOK; diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 2079f263..d607b0fd 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -403,6 +403,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) //wait until SSC_CLK goes HIGH while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { if(BUTTON_PRESS() || (usb_poll_validate_length() )) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); DbpString("Stopped"); return; } @@ -420,8 +421,9 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) LED_D_OFF(); //wait until SSC_CLK goes LOW while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { - if(BUTTON_PRESS()) { + if(BUTTON_PRESS() || (usb_poll_validate_length() )) { DbpString("Stopped"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); return; } WDT_HIT(); @@ -436,6 +438,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) SpinDelayUs(gap); } } + } } @@ -840,13 +843,15 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) if (ledcontrol) LED_A_OFF(); *high = hi; *low = lo; - return; + break; } // reset } hi2 = hi = lo = idx = 0; WDT_HIT(); } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); DbpString("Stopped"); if (ledcontrol) LED_A_OFF(); } @@ -931,12 +936,13 @@ void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol) } if (findone){ if (ledcontrol) LED_A_OFF(); - return; + break; } // reset idx = 0; WDT_HIT(); } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); DbpString("Stopped"); if (ledcontrol) LED_A_OFF(); } @@ -991,13 +997,14 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) if (ledcontrol) LED_A_OFF(); *high=lo>>32; *low=lo & 0xFFFFFFFF; - return; + break; } } WDT_HIT(); hi = lo = size = idx = 0; clk = invert = errCnt = 0; } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); DbpString("Stopped"); if (ledcontrol) LED_A_OFF(); } @@ -1056,7 +1063,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) //LED_A_OFF(); *high=code; *low=code2; - return; + break; } code=code2=0; version=facilitycode=0; @@ -1065,6 +1072,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) WDT_HIT(); } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); DbpString("Stopped"); if (ledcontrol) LED_A_OFF(); } diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 309880d2..cd4b4440 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -777,10 +777,10 @@ int CmdHFiClassReader_Dump(const char *Cmd) { if (have_debit_key) memcpy(tag_data+(3*8),div_key,8); if (have_credit_key) memcpy(tag_data+(4*8),c_div_key,8); // print the dump - printf("CSN |00| %02X %02X %02X %02X %02X %02X %02X %02X |\n",tag_data[0],tag_data[1],tag_data[2] - ,tag_data[3],tag_data[4],tag_data[5],tag_data[6],tag_data[7]); - printIclassDumpContents(tag_data, 1, (gotBytes/8)-1, gotBytes-8); - + printf("------+--+-------------------------+\n"); + printf("CSN |00| %s|\n",sprint_hex(tag_data, 8)); + printIclassDumpContents(tag_data, 1, (gotBytes/8), gotBytes); + if (filename[0] == 0){ snprintf(filename, FILE_PATH_SIZE,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x", tag_data[0],tag_data[1],tag_data[2],tag_data[3], @@ -1255,7 +1255,6 @@ int CmdHFiClass_loclass(const char *Cmd) { } void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize) { - uint8_t blockdata[8]; uint8_t mem_config; memcpy(&mem_config, iclass_dump + 13,1); uint8_t maxmemcount; @@ -1270,18 +1269,19 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e startblock = 6; if ((endblock > maxmemcount) || (endblock == 0)) endblock = maxmemcount; - if (endblock > filemaxblock) + + // remember endblock need to relate to zero-index arrays. + if (endblock > filemaxblock-1) endblock = filemaxblock; + int i = startblock; - int j; - while (i <= endblock){ - printf("Block |%02X| ",i); - memcpy(blockdata,iclass_dump + (i * 8),8); - for (j = 0;j < 8;j++) - printf("%02X ",blockdata[j]); - printf("|\n"); + printf("------+--+-------------------------+\n"); + while (i <= endblock) { + uint8_t *blk = iclass_dump + (i * 8); + printf("Block |%02X| %s|\n", i, sprint_hex(blk, 8) ); i++; } + printf("------+--+-------------------------+\n"); } int usage_hf_iclass_readtagfile() { @@ -1327,7 +1327,8 @@ int CmdHFiClassReadTagFile(const char *Cmd) { size_t bytes_read = fread(dump, 1, fsize, f); fclose(f); uint8_t *csn = dump; - printf("CSN [00] | %02X %02X %02X %02X %02X %02X %02X %02X |\n",csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]); + printf("------+--+-------------------------+\n"); + printf("CSN |00| %s|\n", sprint_hex(csn, 8) ); // printIclassDumpInfo(dump); printIclassDumpContents(dump,startblock,endblock,bytes_read); free(dump); diff --git a/client/cmdlf.c b/client/cmdlf.c index 016f0fe2..2000f6d0 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -38,7 +38,7 @@ static int CmdHelp(const char *Cmd); -int usage_lf_cmdread() +int usage_lf_cmdread(void) { PrintAndLog("Usage: lf cmdread d z o c [H] "); PrintAndLog("Options: "); @@ -430,7 +430,7 @@ int CmdIndalaClone(const char *Cmd) return 0; } -int usage_lf_read() +int usage_lf_read(void) { PrintAndLog("Usage: lf read"); PrintAndLog("Options: "); @@ -440,7 +440,7 @@ int usage_lf_read() PrintAndLog("Use 'lf config' to set parameters."); return 0; } -int usage_lf_snoop() +int usage_lf_snoop(void) { PrintAndLog("Usage: lf snoop"); PrintAndLog("Options: "); @@ -450,7 +450,7 @@ int usage_lf_snoop() return 0; } -int usage_lf_config() +int usage_lf_config(void) { PrintAndLog("Usage: lf config [H|] [b ] [d ] [a 0|1]"); PrintAndLog("Options: "); @@ -685,7 +685,7 @@ int usage_lf_simpsk(void) return 0; } -// by marshmellow - sim ask data given clock, fcHigh, fcLow, invert +// by marshmellow - sim fsk data given clock, fcHigh, fcLow, invert // - allow pull data from DemodBuffer int CmdLFfskSim(const char *Cmd) { @@ -1180,6 +1180,13 @@ int CmdLFfind(const char *Cmd) return 1; } + if (!offline && (cmdp != '1')){ + ans=CmdLFHitagReader("26"); + if (ans==0) { + return 1; + } + } + PrintAndLog("\nNo Known Tags Found!\n"); if (testRaw=='u' || testRaw=='U'){ //test unknown tag formats (raw mode) diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 07247364..ad8fd33b 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -214,14 +214,19 @@ int CmdLFHitagReader(const char *Cmd) { } break; case RHT2F_CRYPTO: { num_to_bytes(param_get64ex(Cmd,1,0,16),6,htd->crypto.key); -// num_to_bytes(param_get32ex(Cmd,2,0,16),4,htd->auth.NrAr+4); + // num_to_bytes(param_get32ex(Cmd,2,0,16),4,htd->auth.NrAr+4); } break; case RHT2F_TEST_AUTH_ATTEMPTS: { // No additional parameters needed } break; + case RHT2F_UID_ONLY: { + // No additional parameters needed + } break; default: { - PrintAndLog("Error: unkown reader function %d",htf); - PrintAndLog("Hitag reader functions"); + PrintAndLog("\nError: unkown reader function %d",htf); + PrintAndLog(""); + PrintAndLog("Usage: hitag reader "); + PrintAndLog("Reader Functions:"); PrintAndLog(" HitagS (0*)"); PrintAndLog(" 01 (Challenge) read all pages from a Hitag S tag"); PrintAndLog(" 02 (set to 0 if no authentication is needed) read all pages from a Hitag S tag"); @@ -231,6 +236,7 @@ int CmdLFHitagReader(const char *Cmd) { PrintAndLog(" 22 (authentication)"); PrintAndLog(" 23 (authentication) key is in format: ISK high + ISK low"); PrintAndLog(" 25 (test recorded authentications)"); + PrintAndLog(" 26 just read UID"); return 1; } break; } @@ -238,32 +244,38 @@ int CmdLFHitagReader(const char *Cmd) { // Copy the hitag2 function into the first argument c.arg[0] = htf; - // Send the command to the proxmark - SendCommand(&c); - - UsbCommand resp; - WaitForResponse(CMD_ACK,&resp); - - // Check the return status, stored in the first argument - if (resp.arg[0] == false) return 1; - - uint32_t id = bytes_to_num(resp.d.asBytes,4); - char filename[256]; - FILE* pf = NULL; - - sprintf(filename,"%08x_%04x.ht2",id,(rand() & 0xffff)); - if ((pf = fopen(filename,"wb")) == NULL) { - PrintAndLog("Error: Could not open file [%s]",filename); - return 1; - } - - // Write the 48 tag memory bytes to file and finalize - fwrite(resp.d.asBytes,1,48,pf); - fclose(pf); + // Send the command to the proxmark + SendCommand(&c); - PrintAndLog("Succesfully saved tag memory to [%s]",filename); - - return 0; + UsbCommand resp; + WaitForResponse(CMD_ACK,&resp); + + // Check the return status, stored in the first argument + if (resp.arg[0] == false) return 1; + + uint32_t id = bytes_to_num(resp.d.asBytes,4); + + if (htf == RHT2F_UID_ONLY){ + PrintAndLog("Valid Hitag2 tag found - UID: %08x",id); + } else { + char filename[256]; + FILE* pf = NULL; + + sprintf(filename,"%08x_%04x.ht2",id,(rand() & 0xffff)); + if ((pf = fopen(filename,"wb")) == NULL) { + PrintAndLog("Error: Could not open file [%s]",filename); + return 1; + } + + // Write the 48 tag memory bytes to file and finalize + fwrite(resp.d.asBytes,1,48,pf); + fclose(pf); + + PrintAndLog("Succesfully saved tag memory to [%s]",filename); + } + + + return 0; } diff --git a/include/hitag2.h b/include/hitag2.h index 284b5ecb..00447623 100644 --- a/include/hitag2.h +++ b/include/hitag2.h @@ -14,14 +14,15 @@ #define _HITAG2_H_ typedef enum { - RHTSF_CHALLENGE = 01, - RHTSF_KEY = 02, + RHTSF_CHALLENGE = 01, + RHTSF_KEY = 02, WHTSF_CHALLENGE = 03, WHTSF_KEY = 04, RHT2F_PASSWORD = 21, RHT2F_AUTHENTICATE = 22, RHT2F_CRYPTO = 23, RHT2F_TEST_AUTH_ATTEMPTS = 25, + RHT2F_UID_ONLY = 26 } hitag_function; typedef struct {