mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-01-01 05:07:03 +08:00
add: 'hf 15 dump' added save data to file. It saves two files (EML/BIN)
This commit is contained in:
parent
f4d703edf0
commit
a130b58c82
4 changed files with 143 additions and 37 deletions
|
@ -571,7 +571,7 @@ int HF15Reader(const char *Cmd, bool verbose) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog(" UID : %s", sprintUID(NULL, uid));
|
PrintAndLog(" UID : %s", sprintUID(NULL, uid));
|
||||||
PrintAndLog(" TYPE : %s", getTagInfo_15(uid));
|
PrintAndLog(" TYPE : %s", getTagInfo_15(uid));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -621,20 +621,56 @@ int CmdHF15Afi(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t lock;
|
||||||
|
uint8_t block[4];
|
||||||
|
} t15memory;
|
||||||
|
|
||||||
// Reads all memory pages
|
// Reads all memory pages
|
||||||
// need to write to file
|
// need to write to file
|
||||||
// helptext
|
// helptext
|
||||||
int CmdHF15Dump(const char*Cmd) {
|
int CmdHF15Dump(const char*Cmd) {
|
||||||
|
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
uint8_t fileNameLen = 0;
|
||||||
if (cmdp == 'h' || cmdp == 'H') return usage_15_dump();
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
|
char * fptr = filename;
|
||||||
|
bool errors = false;
|
||||||
|
uint8_t cmdp = 0;
|
||||||
|
|
||||||
uint8_t uid[8] = {0,0,0,0,0,0,0,0};
|
uint8_t uid[8] = {0,0,0,0,0,0,0,0};
|
||||||
|
|
||||||
if (!getUID(uid)) {
|
if (!getUID(uid)) {
|
||||||
PrintAndLog("No Tag found.");
|
PrintAndLog("No tag found.");
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
switch(param_getchar(Cmd, cmdp)) {
|
||||||
|
case 'h':
|
||||||
|
case 'H':
|
||||||
|
return usage_15_dump();
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
fileNameLen = param_getstr(Cmd, cmdp+1, filename);
|
||||||
|
if (fileNameLen < 1) {
|
||||||
|
PrintAndLog("Using UID as filename");
|
||||||
|
|
||||||
|
fptr += sprintf(fptr, "dump15_");
|
||||||
|
|
||||||
|
for (int j = sizeof(uid)-1; j >=0 ; j--) {
|
||||||
|
fptr += sprintf(fptr, "%02X", uid[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Validations
|
||||||
|
if (errors) return usage_15_dump();
|
||||||
|
|
||||||
// detect blocksize from card :)
|
// detect blocksize from card :)
|
||||||
|
|
||||||
PrintAndLog("Reading memory from tag UID %s", sprintUID(NULL, uid));
|
PrintAndLog("Reading memory from tag UID %s", sprintUID(NULL, uid));
|
||||||
|
@ -642,6 +678,9 @@ int CmdHF15Dump(const char*Cmd) {
|
||||||
int reqlen = 0, blocknum = 0;
|
int reqlen = 0, blocknum = 0;
|
||||||
uint8_t *recv = NULL;
|
uint8_t *recv = NULL;
|
||||||
|
|
||||||
|
// memory.
|
||||||
|
t15memory mem[256];
|
||||||
|
|
||||||
uint8_t data[256*4] = {0};
|
uint8_t data[256*4] = {0};
|
||||||
memset(data, 0, sizeof(data));
|
memset(data, 0, sizeof(data));
|
||||||
|
|
||||||
|
@ -677,6 +716,9 @@ int CmdHF15Dump(const char*Cmd) {
|
||||||
|
|
||||||
if (!(recv[0] & ISO15_RES_ERROR)) {
|
if (!(recv[0] & ISO15_RES_ERROR)) {
|
||||||
|
|
||||||
|
mem[blocknum].lock = resp.d.asBytes[0];
|
||||||
|
memcpy(mem[blocknum].block, resp.d.asBytes + 1, 4);
|
||||||
|
|
||||||
memcpy(data + (blocknum * 4), resp.d.asBytes + 1, 4);
|
memcpy(data + (blocknum * 4), resp.d.asBytes + 1, 4);
|
||||||
|
|
||||||
retry = 0;
|
retry = 0;
|
||||||
|
@ -686,32 +728,33 @@ int CmdHF15Dump(const char*Cmd) {
|
||||||
} else {
|
} else {
|
||||||
PrintAndLog("\nTag returned Error %i: %s", recv[1], TagErrorStr(recv[1]) );
|
PrintAndLog("\nTag returned Error %i: %s", recv[1], TagErrorStr(recv[1]) );
|
||||||
break;
|
break;
|
||||||
// return 1;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
PrintAndLog("crc fail");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
PrintAndLog("Blk| data | ascii");
|
PrintAndLog("Block# | Data |lck| Ascii");
|
||||||
PrintAndLog("---+---------------------+----------");
|
PrintAndLog("---------+--------------+---+----------");
|
||||||
for (int i=0; i < blocknum; i++) {
|
for (int i = 0; i < blocknum; i++) {
|
||||||
PrintAndLog("%02x | %s", i, sprint_hex_ascii(data + (i*4) , 4 ) );
|
PrintAndLog("%3d/0x%02X | %s | %d | %s", i, i, sprint_hex(mem[i].block, 4 ), mem[i].lock, sprint_ascii(mem[i].block, 4) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: need fix
|
printf("\n");
|
||||||
// if (resp.arg[0]<3)
|
|
||||||
// PrintAndLog("Lost Connection");
|
size_t datalen = blocknum*4;
|
||||||
// else if (ISO15_CRC_CHECK != Crc(resp.d.asBytes, resp.arg[0]-2))
|
saveFileEML(filename, "eml", data, datalen, 4);
|
||||||
// PrintAndLog("CRC Failed");
|
saveFile(filename, "bin", data, datalen);
|
||||||
// else
|
return 0;
|
||||||
// PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHF15Restore(const char*Cmd) {
|
int CmdHF15Restore(const char*Cmd) {
|
||||||
// read from file
|
// read from file
|
||||||
// write to tag
|
// loop file
|
||||||
|
// write block to tag
|
||||||
|
// end loop
|
||||||
return usage_15_restore();
|
return usage_15_restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -949,7 +992,7 @@ int CmdHF15Readmulti(const char *Cmd) {
|
||||||
|
|
||||||
recv = resp.d.asBytes;
|
recv = resp.d.asBytes;
|
||||||
|
|
||||||
if (ISO15_CRC_CHECK == Crc(recv, status-2)) {
|
if (ISO15_CRC_CHECK == Crc(recv, status)) {
|
||||||
PrintAndLog("CRC failed");
|
PrintAndLog("CRC failed");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
@ -1017,7 +1060,7 @@ int CmdHF15Read(const char *Cmd) {
|
||||||
|
|
||||||
recv = resp.d.asBytes;
|
recv = resp.d.asBytes;
|
||||||
|
|
||||||
if (ISO15_CRC_CHECK == Crc(recv, status-2)) {
|
if (ISO15_CRC_CHECK == Crc(recv, status)) {
|
||||||
PrintAndLog("CRC failed");
|
PrintAndLog("CRC failed");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
@ -1097,7 +1140,7 @@ int CmdHF15Write(const char *Cmd) {
|
||||||
|
|
||||||
recv = resp.d.asBytes;
|
recv = resp.d.asBytes;
|
||||||
|
|
||||||
if (ISO15_CRC_CHECK == Crc(recv, status-2)) {
|
if (ISO15_CRC_CHECK == Crc(recv, status)) {
|
||||||
PrintAndLog("CRC failed");
|
PrintAndLog("CRC failed");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "iso15693tools.h" // iso15 crc
|
#include "iso15693tools.h" // iso15 crc
|
||||||
#include "cmdmain.h"
|
#include "cmdmain.h"
|
||||||
#include "cmddata.h" // getsamples
|
#include "cmddata.h" // getsamples
|
||||||
|
#include "loclass/fileutils.h" // savefileEML
|
||||||
|
|
||||||
int CmdHF15(const char *Cmd);
|
int CmdHF15(const char *Cmd);
|
||||||
|
|
||||||
|
|
|
@ -63,33 +63,82 @@ int fileExists(const char *filename) {
|
||||||
|
|
||||||
int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen)
|
int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen)
|
||||||
{
|
{
|
||||||
int size = sizeof(char) * (strlen(preferredName)+strlen(suffix)+10);
|
int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10);
|
||||||
char * fileName = malloc(size);
|
char * fileName = malloc(size);
|
||||||
|
|
||||||
memset(fileName,0,size);
|
memset(fileName, 0, size);
|
||||||
int num = 1;
|
int num = 1;
|
||||||
sprintf(fileName,"%s.%s", preferredName, suffix);
|
sprintf(fileName,"%s.%s", preferredName, suffix);
|
||||||
while(fileExists(fileName))
|
while (fileExists(fileName)) {
|
||||||
{
|
|
||||||
sprintf(fileName,"%s-%d.%s", preferredName, num, suffix);
|
sprintf(fileName,"%s-%d.%s", preferredName, num, suffix);
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
/* We should have a valid filename now, e.g. dumpdata-3.bin */
|
/* We should have a valid filename now, e.g. dumpdata-3.bin */
|
||||||
|
|
||||||
/*Opening file for writing in binary mode*/
|
/*Opening file for writing in binary mode*/
|
||||||
FILE *f = fopen(fileName,"wb");
|
FILE *f = fopen(fileName, "wb");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
prnlog("Failed to write to file '%s'", fileName);
|
prnlog("File not found or locked. '%s'", fileName);
|
||||||
free(fileName);
|
free(fileName);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
fwrite(data, 1, datalen, f);
|
fwrite(data, 1, datalen, f);
|
||||||
if (f)
|
fflush(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
prnlog("Saved data to '%s'", fileName);
|
prnlog("Saved %u bytes to binary file %s", datalen, fileName);
|
||||||
free(fileName);
|
free(fileName);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int saveFileEML(const char *preferredName, const char *suffix, uint8_t* data, size_t datalen, size_t blocksize) {
|
||||||
|
|
||||||
|
if ( preferredName == NULL ) return 1;
|
||||||
|
if ( suffix == NULL ) return 1;
|
||||||
|
if ( data == NULL ) return 1;
|
||||||
|
|
||||||
|
int retval = 0;
|
||||||
|
int blocks = datalen/blocksize;
|
||||||
|
int i,j;
|
||||||
|
int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10);
|
||||||
|
char * fileName = malloc(size);
|
||||||
|
|
||||||
|
memset(fileName, 0, size);
|
||||||
|
int num = 1;
|
||||||
|
sprintf(fileName,"%s.%s", preferredName, suffix);
|
||||||
|
while (fileExists(fileName)) {
|
||||||
|
sprintf(fileName,"%s-%d.%s", preferredName, num, suffix);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We should have a valid filename now, e.g. dumpdata-3.bin */
|
||||||
|
|
||||||
|
/*Opening file for writing in text mode*/
|
||||||
|
FILE *f = fopen(fileName, "w+");
|
||||||
|
if (!f) {
|
||||||
|
prnlog("File not found or locked. '%s'", fileName);
|
||||||
|
retval = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < datalen; i++) {
|
||||||
|
fprintf(f, "%02X", data[i] );
|
||||||
|
if ( (i+1) % 4 == 0)
|
||||||
|
fprintf(f, "\n");
|
||||||
|
}
|
||||||
|
// left overs
|
||||||
|
if ( datalen % blocksize != 0) {
|
||||||
|
int index = blocks * blocksize;
|
||||||
|
for (j = 0; j < datalen % blocksize; j++) {
|
||||||
|
fprintf(f, "%02X", data[index + j] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fflush(f);
|
||||||
|
fclose(f);
|
||||||
|
prnlog("Saved %d blocks to text file %s", blocks, fileName);
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(fileName);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility function to print to console. This is used consistently within the library instead
|
* Utility function to print to console. This is used consistently within the library instead
|
||||||
|
@ -107,7 +156,6 @@ void prnlog(char *fmt, ...)
|
||||||
vsprintf (buffer,fmt, args);
|
vsprintf (buffer,fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
PrintAndLog(buffer);
|
PrintAndLog(buffer);
|
||||||
|
|
||||||
}
|
}
|
||||||
#else //if we're on ARM
|
#else //if we're on ARM
|
||||||
void prnlog(char *fmt,...)
|
void prnlog(char *fmt,...)
|
||||||
|
|
|
@ -41,8 +41,9 @@
|
||||||
|
|
||||||
#ifndef ON_DEVICE
|
#ifndef ON_DEVICE
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
/**
|
/**
|
||||||
* @brief Utility function to save data to a file. This method takes a preferred name, but if that
|
* @brief Utility function to save data to a binary file. This method takes a preferred name, but if that
|
||||||
* file already exists, it tries with another name until it finds something suitable.
|
* file already exists, it tries with another name until it finds something suitable.
|
||||||
* E.g. dumpdata-15.txt
|
* E.g. dumpdata-15.txt
|
||||||
* @param preferredName
|
* @param preferredName
|
||||||
|
@ -51,7 +52,20 @@
|
||||||
* @param datalen the length of the data
|
* @param datalen the length of the data
|
||||||
* @return 0 for ok, 1 for failz
|
* @return 0 for ok, 1 for failz
|
||||||
*/
|
*/
|
||||||
int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen);
|
extern int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Utility function to save data to a textfile. This method takes a preferred name, but if that
|
||||||
|
* file already exists, it tries with another name until it finds something suitable.
|
||||||
|
* E.g. dumpdata-15.txt
|
||||||
|
* @param preferredName
|
||||||
|
* @param suffix the file suffix. Leave out the ".".
|
||||||
|
* @param data The binary data to write to the file
|
||||||
|
* @param datalen the length of the data
|
||||||
|
* @param blocksize the length of one row
|
||||||
|
* @return 0 for ok, 1 for failz
|
||||||
|
*/
|
||||||
|
extern int saveFileEML(const char *preferredName, const char *suffix, uint8_t* data, size_t datalen, size_t blocksize);
|
||||||
/**
|
/**
|
||||||
* @brief Utility function to save load binary data from a a file. This method takes a filename,
|
* @brief Utility function to save load binary data from a a file. This method takes a filename,
|
||||||
* Should only be used for fixed-size binary files
|
* Should only be used for fixed-size binary files
|
||||||
|
|
Loading…
Reference in a new issue