mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -07:00
ADD: 'mem' commands. For RDV40 devices only.
If you don't have one, comment out inside client/Makefile this line CFLAGS += -DWITH_FLASH
This commit is contained in:
parent
d0b9d12bde
commit
021c0a1349
11 changed files with 394 additions and 123 deletions
|
@ -1127,18 +1127,65 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
}
|
}
|
||||||
case CMD_WRITE_FLASH_MEM: {
|
case CMD_WRITE_FLASH_MEM: {
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
|
uint8_t isok = 0;
|
||||||
|
uint16_t res = 0;
|
||||||
uint32_t startidx = c->arg[0];
|
uint32_t startidx = c->arg[0];
|
||||||
uint16_t len = c->arg[1];
|
uint16_t len = c->arg[1];
|
||||||
uint16_t res = Flash_WriteData(startidx, c->d.asBytes, len);
|
|
||||||
uint8_t isok = (res == len) ? 1 : 0;
|
Dbprintf("FlashMem init idx | %u | len %u ", startidx, len );
|
||||||
|
|
||||||
|
uint32_t tmp = startidx + len;
|
||||||
|
|
||||||
|
// inside 256b page?
|
||||||
|
if ( (tmp & 0xFF) != 0) {
|
||||||
|
|
||||||
|
// is offset+len larger than a page?
|
||||||
|
tmp = (startidx & 0xFF ) + len;
|
||||||
|
if (tmp > 0xFF ) {
|
||||||
|
|
||||||
|
// offset xxxx10,
|
||||||
|
uint8_t first_len = (~startidx & 0xFF)+1;
|
||||||
|
|
||||||
|
// first mem page
|
||||||
|
res = Flash_WriteData(startidx, c->d.asBytes, first_len);
|
||||||
|
Dbprintf("after 1. offset and larger A | %u | %u | %u == %u", startidx , len, first_len, res);
|
||||||
|
|
||||||
|
// second mem page (should be a mod 256)
|
||||||
|
res = Flash_WriteData(startidx + first_len, c->d.asBytes + first_len, len - first_len);
|
||||||
|
Dbprintf("after 2. offset and larger B | %u | %u | %u == %u", startidx + first_len, len, len-first_len, res);
|
||||||
|
|
||||||
|
isok = (res == (len - first_len)) ? 1 : 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
res = Flash_WriteData(startidx, c->d.asBytes, len);
|
||||||
|
Dbprintf("offset and within | %u | %u | %u", startidx, len, res);
|
||||||
|
isok = (res == len) ? 1 : 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res = Flash_WriteData(startidx, c->d.asBytes, len);
|
||||||
|
Dbprintf("writing idx | %u | len %u ", startidx, len );
|
||||||
|
isok = (res == len) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
cmd_send(CMD_ACK, isok, 0, 0, 0, 0);
|
cmd_send(CMD_ACK, isok, 0, 0, 0, 0);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_UPLOAD_FLASH_MEM:
|
case CMD_WIPE_FLASH_MEM:
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
|
uint8_t page = c->arg[0];
|
||||||
|
uint8_t initalwipe = c->arg[1];
|
||||||
|
bool isok = false;
|
||||||
|
if ( initalwipe ) {
|
||||||
|
isok = Flash_WipeMemory();
|
||||||
|
cmd_send(CMD_ACK, isok, 0, 0, 0, 0);
|
||||||
|
LED_B_OFF();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( page >= 0 && page < 3)
|
||||||
|
isok = Flash_WipeMemoryPage(page);
|
||||||
|
|
||||||
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
cmd_send(CMD_ACK, isok, 0, 0, 0, 0);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
case CMD_DOWNLOAND_FLASH_MEM: {
|
case CMD_DOWNLOAND_FLASH_MEM: {
|
||||||
|
|
|
@ -240,8 +240,8 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Max 256 bytes write
|
// Max 256 bytes write
|
||||||
if (((address & 255) + len) > 256) {
|
if (((address & 0xFF) + len) > 256) {
|
||||||
Dbprintf("Flash_WriteData 256 fail");
|
Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,6 +279,19 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Flash_WipeMemoryPage(uint8_t page) {
|
||||||
|
if (!FlashInit()) {
|
||||||
|
Dbprintf("Flash_WriteData init fail");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Flash_ReadStat1();
|
||||||
|
|
||||||
|
// Each block is 64Kb. One block erase takes 1s ( 1000ms )
|
||||||
|
Flash_WriteEnable(); Flash_Erase64k(page); Flash_CheckBusy(1000);
|
||||||
|
|
||||||
|
FlashStop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// Wipes flash memory completely, fills with 0xFF
|
// Wipes flash memory completely, fills with 0xFF
|
||||||
bool Flash_WipeMemory() {
|
bool Flash_WipeMemory() {
|
||||||
if (!FlashInit()) {
|
if (!FlashInit()) {
|
||||||
|
|
|
@ -122,6 +122,7 @@ uint8_t Flash_ReadStat2(void);
|
||||||
uint16_t FlashSendByte(uint32_t data);
|
uint16_t FlashSendByte(uint32_t data);
|
||||||
|
|
||||||
void Flash_WriteEnable();
|
void Flash_WriteEnable();
|
||||||
|
bool Flash_WipeMemoryPage(uint8_t page);
|
||||||
bool Flash_WipeMemory();
|
bool Flash_WipeMemory();
|
||||||
bool Flash_Erase4k(uint8_t block, uint8_t sector);
|
bool Flash_Erase4k(uint8_t block, uint8_t sector);
|
||||||
//bool Flash_Erase32k(uint32_t address);
|
//bool Flash_Erase32k(uint32_t address);
|
||||||
|
|
|
@ -81,6 +81,9 @@ else
|
||||||
QTGUIOBJS = $(OBJDIR)/guidummy.o
|
QTGUIOBJS = $(OBJDIR)/guidummy.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# RDV40 flag enables flashmemory commands in client. comment out if you don't have rdv40
|
||||||
|
CFLAGS += -DWITH_FLASH
|
||||||
|
|
||||||
# Flags to generate temporary dependency files
|
# Flags to generate temporary dependency files
|
||||||
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
|
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
|
||||||
# make temporary to final dependeny files after successful compilation
|
# make temporary to final dependeny files after successful compilation
|
||||||
|
@ -180,6 +183,7 @@ CMDSRCS = crapto1/crapto1.c \
|
||||||
cmdlfviking.c \
|
cmdlfviking.c \
|
||||||
cmdlfvisa2000.c \
|
cmdlfvisa2000.c \
|
||||||
cmdtrace.c \
|
cmdtrace.c \
|
||||||
|
cmdflashmem.c \
|
||||||
cmdparser.c \
|
cmdparser.c \
|
||||||
cmdmain.c \
|
cmdmain.c \
|
||||||
pm3_binlib.c \
|
pm3_binlib.c \
|
||||||
|
|
|
@ -464,23 +464,10 @@ int CmdAnalyseA(const char *Cmd){
|
||||||
int hexlen = 0;
|
int hexlen = 0;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
uint32_t startindex = 0, len = 0, cmd = 0;
|
|
||||||
uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
|
uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
|
||||||
|
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
case 'l':
|
|
||||||
len = param_get32ex(Cmd, cmdp+1, 0, 10);
|
|
||||||
cmdp += 2;
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
startindex = param_get32ex(Cmd, cmdp+1, 0, 10);
|
|
||||||
cmdp += 2;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
cmd = param_get8ex(Cmd, cmdp+1, 0, 10);
|
|
||||||
cmdp += 2;
|
|
||||||
break;
|
|
||||||
case 'd':
|
case 'd':
|
||||||
param_gethex_ex(Cmd, cmdp+1, data, &hexlen);
|
param_gethex_ex(Cmd, cmdp+1, data, &hexlen);
|
||||||
if ( hexlen != sizeof(data) ) {
|
if ( hexlen != sizeof(data) ) {
|
||||||
|
@ -499,78 +486,6 @@ int CmdAnalyseA(const char *Cmd){
|
||||||
//Validations
|
//Validations
|
||||||
if (errors || cmdp == 0 ) return usage_analyse_checksum();
|
if (errors || cmdp == 0 ) return usage_analyse_checksum();
|
||||||
|
|
||||||
UsbCommand c, resp;
|
|
||||||
|
|
||||||
switch ( cmd ) {
|
|
||||||
case 0:
|
|
||||||
c = (UsbCommand) {CMD_READ_FLASH_MEM, {startindex, len, 0}};
|
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommand(&c);
|
|
||||||
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) {
|
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
// write flash mem
|
|
||||||
case 1:
|
|
||||||
c = (UsbCommand) {CMD_WRITE_FLASH_MEM, {startindex, len, 0}};
|
|
||||||
memcpy(c.d.asBytes, data, len);
|
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommand(&c);
|
|
||||||
|
|
||||||
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) {
|
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
uint8_t isok = resp.arg[0] & 0xFF;
|
|
||||||
if (isok)
|
|
||||||
PrintAndLogEx(SUCCESS, "Flash write ok");
|
|
||||||
else
|
|
||||||
PrintAndLogEx(FAILED, "Flash write fail");
|
|
||||||
|
|
||||||
break;
|
|
||||||
// downloading mem to client
|
|
||||||
case 2: {
|
|
||||||
uint8_t got[0x3FFFF];
|
|
||||||
memset(got, 0, sizeof(got));
|
|
||||||
PrintAndLogEx(NORMAL, "downloading %u bytes from flashmem", sizeof(got));
|
|
||||||
GetFromDevice(FLASH_MEM, got, sizeof(got), 0, NULL, -1, true);
|
|
||||||
|
|
||||||
print_hex(got, 8);
|
|
||||||
|
|
||||||
for(uint32_t i=0; i< sizeof(got); i++) {
|
|
||||||
if ( got[i] < 0xFF) {
|
|
||||||
printf("I %u (0x%x) | %x \n", i, i, got[i] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// binary
|
|
||||||
saveFile("flash_mem", "bin", got, sizeof(got));
|
|
||||||
|
|
||||||
// eml
|
|
||||||
saveFileEML("flash_mem", "eml", got, sizeof(got), 16);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// wipe
|
|
||||||
case 3: {
|
|
||||||
c = (UsbCommand) {CMD_UPLOAD_FLASH_MEM, {0, 0, 0}};
|
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommand(&c);
|
|
||||||
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 8000) ) {
|
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
uint8_t isok = resp.arg[0] & 0xFF;
|
|
||||||
if (isok)
|
|
||||||
PrintAndLogEx(SUCCESS, "Flash WIPE ok");
|
|
||||||
else
|
|
||||||
PrintAndLogEx(FAILED, "Flash WIPE failed");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "-- " _BLUE_(its my message) "\n");
|
PrintAndLogEx(NORMAL, "-- " _BLUE_(its my message) "\n");
|
||||||
PrintAndLogEx(NORMAL, "-- " _RED_(its my message) "\n");
|
PrintAndLogEx(NORMAL, "-- " _RED_(its my message) "\n");
|
||||||
PrintAndLogEx(NORMAL, "-- " _YELLOW_(its my message) "\n");
|
PrintAndLogEx(NORMAL, "-- " _YELLOW_(its my message) "\n");
|
||||||
|
|
272
client/cmdflashmem.c
Normal file
272
client/cmdflashmem.c
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2018 iceman
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Proxmark3 RDV40 Flash memory commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#include "cmdflashmem.h"
|
||||||
|
|
||||||
|
#define FLASH_MEM_BLOCK_SIZE 256
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
int usage_flashmem_load(void){
|
||||||
|
PrintAndLogEx(NORMAL, "Loads binary file into flash memory on device");
|
||||||
|
PrintAndLogEx(NORMAL, "Usage: mem load o <offset> f <file name>");
|
||||||
|
PrintAndLogEx(NORMAL, " o <offset> : offset in memory");
|
||||||
|
PrintAndLogEx(NORMAL, " f <filename> : file name");
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
|
PrintAndLogEx(NORMAL, " mem load f myfile"); // upload file myfile at default offset 0
|
||||||
|
PrintAndLogEx(NORMAL, " mem load f myfile o 1024"); // upload file myfile at offset 1024
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int usage_flashmem_save(void){
|
||||||
|
PrintAndLogEx(NORMAL, "Saves flash memory on device into the file");
|
||||||
|
PrintAndLogEx(NORMAL, " Usage: mem save o <offset> l <length> f <file name>");
|
||||||
|
PrintAndLogEx(NORMAL, " o <offset> : offset in memory");
|
||||||
|
PrintAndLogEx(NORMAL, " l <length> : length");
|
||||||
|
PrintAndLogEx(NORMAL, " f <filename> : file name");
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
|
PrintAndLogEx(NORMAL, " mem save f myfile"); // download whole flashmem to file myfile
|
||||||
|
PrintAndLogEx(NORMAL, " mem save f myfile l 4096"); // download 4096 bytes from default offset 0 to file myfile
|
||||||
|
PrintAndLogEx(NORMAL, " mem save f myfile o 1024 l 4096"); // downlowd 4096 bytes from offset 1024 to file myfile
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int usage_flashmem_wipe(void){
|
||||||
|
|
||||||
|
PrintAndLogEx(WARNING, "[OBS] use with caution.");
|
||||||
|
PrintAndLogEx(NORMAL, "Wipe flash memory on device, which fills memory with 0xFF\n");
|
||||||
|
|
||||||
|
PrintAndLogEx(NORMAL, " Usage: mem save p <page>");
|
||||||
|
PrintAndLogEx(NORMAL, " p <page> : 0,1,2 page memory");
|
||||||
|
// PrintAndLogEx(NORMAL, " i : inital total wipe");
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
|
PrintAndLogEx(NORMAL, " mem wipe "); // wipe page 0,1,2
|
||||||
|
PrintAndLogEx(NORMAL, " mem wipe p 0"); // wipes first page.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int CmdFlashMemLoad(const char *Cmd){
|
||||||
|
|
||||||
|
FILE *f;
|
||||||
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
|
uint8_t cmdp = 0;
|
||||||
|
bool errors = false;
|
||||||
|
uint32_t start_index = 0;
|
||||||
|
|
||||||
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
case 'o':
|
||||||
|
start_index = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
//File handling and reading
|
||||||
|
if ( param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE ) {
|
||||||
|
PrintAndLogEx(FAILED, "Filename too long");
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
return usage_flashmem_load();
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Validations
|
||||||
|
if (errors || cmdp == 0 ) return usage_flashmem_load();
|
||||||
|
|
||||||
|
// load file
|
||||||
|
f = fopen(filename, "rb");
|
||||||
|
if ( !f ){
|
||||||
|
PrintAndLogEx(FAILED, "File: %s: not found or locked.", filename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get filesize in order to malloc memory
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
long fsize = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
|
if (fsize < 0) {
|
||||||
|
PrintAndLogDevice(WARNING, "error, when getting filesize");
|
||||||
|
fclose(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *dump = calloc(fsize, sizeof(uint8_t));
|
||||||
|
if (!dump) {
|
||||||
|
PrintAndLogDevice(WARNING, "error, cannot allocate memory ");
|
||||||
|
fclose(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bytes_read = fread(dump, 1, fsize, f);
|
||||||
|
if (f)
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
//Send to device
|
||||||
|
uint32_t bytes_sent = 0;
|
||||||
|
uint32_t bytes_remaining = bytes_read;
|
||||||
|
|
||||||
|
while (bytes_remaining > 0){
|
||||||
|
uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
|
||||||
|
|
||||||
|
UsbCommand c = {CMD_WRITE_FLASH_MEM, {start_index + bytes_sent, bytes_in_packet, 0}};
|
||||||
|
|
||||||
|
memcpy(c.d.asBytes, dump + start_index + bytes_sent, bytes_in_packet);
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommand(&c);
|
||||||
|
|
||||||
|
bytes_remaining -= bytes_in_packet;
|
||||||
|
bytes_sent += bytes_in_packet;
|
||||||
|
|
||||||
|
UsbCommand resp;
|
||||||
|
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
|
free(dump);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t isok = resp.arg[0] & 0xFF;
|
||||||
|
if (!isok)
|
||||||
|
PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent);
|
||||||
|
|
||||||
|
}
|
||||||
|
free(dump);
|
||||||
|
|
||||||
|
PrintAndLogEx(SUCCESS, "Wrote %u bytes to offset %u", bytes_read, start_index);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int CmdFlashMemSave(const char *Cmd){
|
||||||
|
|
||||||
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
|
uint8_t cmdp = 0;
|
||||||
|
bool errors = false;
|
||||||
|
uint32_t start_index = 0, len = 0x3FFFF;
|
||||||
|
|
||||||
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
case 'h': return usage_flashmem_save();
|
||||||
|
case 'l':
|
||||||
|
len = param_get32ex(Cmd, cmdp+1, 0x3FFFF, 10);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
start_index = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
//File handling
|
||||||
|
if ( param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE ) {
|
||||||
|
PrintAndLogEx(FAILED, "Filename too long");
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Validations
|
||||||
|
if (errors || cmdp == 0 ) return usage_flashmem_save();
|
||||||
|
|
||||||
|
uint8_t* dump = calloc(len, sizeof(uint8_t));
|
||||||
|
if (!dump) {
|
||||||
|
PrintAndLogDevice(WARNING, "error, cannot allocate memory ");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(NORMAL, "downloading %u bytes from flashmem", len);
|
||||||
|
if ( !GetFromDevice(FLASH_MEM, dump, len, start_index, NULL, -1, true) ) {
|
||||||
|
PrintAndLogEx(FAILED, "ERROR; downloading flashmem");
|
||||||
|
free(dump);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveFile(filename, "bin", dump, len);
|
||||||
|
saveFileEML(filename, "eml", dump, len, 16);
|
||||||
|
free(dump);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int CmdFlashMemWipe(const char *Cmd){
|
||||||
|
|
||||||
|
uint8_t cmdp = 0;
|
||||||
|
bool errors = false;
|
||||||
|
bool initalwipe = false;
|
||||||
|
uint8_t page = 0;
|
||||||
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
case 'h': return usage_flashmem_wipe();
|
||||||
|
case 'p':
|
||||||
|
page = param_get8ex(Cmd, cmdp+1, 0, 10);
|
||||||
|
if ( page > 2 ) {
|
||||||
|
PrintAndLogEx(WARNING, "page must be 0, 1 or 2");
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
initalwipe = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Validations
|
||||||
|
if (errors || cmdp == 0 ) return usage_flashmem_wipe();
|
||||||
|
|
||||||
|
UsbCommand c = {CMD_WIPE_FLASH_MEM, {page, initalwipe, 0}};
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommand(&c);
|
||||||
|
UsbCommand resp;
|
||||||
|
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 8000) ) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
uint8_t isok = resp.arg[0] & 0xFF;
|
||||||
|
if (isok)
|
||||||
|
PrintAndLogEx(SUCCESS, "Flash WIPE ok");
|
||||||
|
else
|
||||||
|
PrintAndLogEx(FAILED, "Flash WIPE failed");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static command_t CommandTable[] = {
|
||||||
|
{"help", CmdHelp, 1, "This help"},
|
||||||
|
{"load", CmdFlashMemLoad, 1, "Load data into flash memory [rdv40]"},
|
||||||
|
{"save", CmdFlashMemSave, 1, "Save data from flash memory [rdv40]"},
|
||||||
|
{"wipe", CmdFlashMemWipe, 1, "Wipe data from flash memory [rdv40]"},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
int CmdFlashMem(const char *Cmd) {
|
||||||
|
clearCommandBuffer();
|
||||||
|
CmdsParse(CommandTable, Cmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdHelp(const char *Cmd) {
|
||||||
|
CmdsHelp(CommandTable);
|
||||||
|
return 0;
|
||||||
|
}
|
32
client/cmdflashmem.h
Normal file
32
client/cmdflashmem.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2018 iceman
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Proxmark3 RDV40 Flash memory commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef CMDFLASHMEM_H__
|
||||||
|
#define CMDFLASHMEM_H__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "proxmark3.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "cmdparser.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "util_posix.h" // msclock
|
||||||
|
#include "loclass/fileutils.h" //saveFile
|
||||||
|
#include "cmdmain.h" //getfromdevice
|
||||||
|
|
||||||
|
extern int CmdFlashMem(const char *Cmd);
|
||||||
|
|
||||||
|
extern int CmdFlashMemLoad(const char* cmd);
|
||||||
|
extern int CmdFlashMemSave(const char* cmd);
|
||||||
|
extern int CmdFlashMemWipe(const char *Cmd);
|
||||||
|
#endif
|
|
@ -43,6 +43,9 @@ static command_t CommandTable[] = {
|
||||||
{"reveng", CmdRev, 1, "Crc calculations from the software reveng 1.44"},
|
{"reveng", CmdRev, 1, "Crc calculations from the software reveng 1.44"},
|
||||||
{"script", CmdScript, 1, "{ Scripting commands }"},
|
{"script", CmdScript, 1, "{ Scripting commands }"},
|
||||||
{"trace", CmdTrace, 1, "{ Trace manipulation... }"},
|
{"trace", CmdTrace, 1, "{ Trace manipulation... }"},
|
||||||
|
#ifdef WITH_FLASH
|
||||||
|
{"mem", CmdFlashMem,1, "{ RDV40, Flash Memory manipulation... }"},
|
||||||
|
#endif
|
||||||
{"quit", CmdQuit, 1, ""},
|
{"quit", CmdQuit, 1, ""},
|
||||||
{"exit", CmdQuit, 1, "Exit program"},
|
{"exit", CmdQuit, 1, "Exit program"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
|
@ -215,6 +218,19 @@ void UsbCommandReceived(UsbCommand* _ch) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data transfer from Proxmark to client. This method times out after
|
||||||
|
* ms_timeout milliseconds.
|
||||||
|
* @brief GetFromDevice
|
||||||
|
* @param memtype Type of memory to download from proxmark
|
||||||
|
* @param dest Destination address for transfer
|
||||||
|
* @param bytes number of bytes to be transferred
|
||||||
|
* @param start_index offset into Proxmark3 BigBuf[]
|
||||||
|
* @param response struct to copy last command (CMD_ACK) into
|
||||||
|
* @param ms_timeout timeout in milliseconds
|
||||||
|
* @param show_warning display message after 2 seconds
|
||||||
|
* @return true if command was returned, otherwise false
|
||||||
|
*/
|
||||||
bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning) {
|
bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning) {
|
||||||
|
|
||||||
if (dest == NULL) return false;
|
if (dest == NULL) return false;
|
||||||
|
@ -253,31 +269,6 @@ bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint3
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Data transfer from Proxmark to client. This method times out after
|
|
||||||
* ms_timeout milliseconds.
|
|
||||||
* @brief GetFromBigBuf
|
|
||||||
* @param dest Destination address for transfer
|
|
||||||
* @param bytes number of bytes to be transferred
|
|
||||||
* @param start_index offset into Proxmark3 BigBuf[]
|
|
||||||
* @param response struct to copy last command (CMD_ACK) into
|
|
||||||
* @param ms_timeout timeout in milliseconds
|
|
||||||
* @param show_warning display message after 2 seconds
|
|
||||||
* @return true if command was returned, otherwise false
|
|
||||||
*/
|
|
||||||
bool GetFromBigBuf(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning) {
|
|
||||||
|
|
||||||
if (dest == NULL) return false;
|
|
||||||
if (bytes == 0) return true;
|
|
||||||
|
|
||||||
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
|
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommand(&c);
|
|
||||||
|
|
||||||
return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd) {
|
bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning, uint32_t rec_cmd) {
|
||||||
|
|
||||||
uint32_t bytes_completed = 0;
|
uint32_t bytes_completed = 0;
|
||||||
|
@ -328,4 +319,3 @@ bool dl_it(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *resp
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "cmdscript.h"
|
#include "cmdscript.h"
|
||||||
#include "cmdcrc.h"
|
#include "cmdcrc.h"
|
||||||
#include "cmdanalyse.h"
|
#include "cmdanalyse.h"
|
||||||
|
#include "cmdflashmem.h" // rdv40 flashmem commands
|
||||||
|
|
||||||
//For storing command that are received from the device
|
//For storing command that are received from the device
|
||||||
#define CMD_BUFFER_SIZE 50
|
#define CMD_BUFFER_SIZE 50
|
||||||
|
@ -53,8 +54,4 @@ extern command_t* getTopLevelCommandTable();
|
||||||
|
|
||||||
extern bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning);
|
extern bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning);
|
||||||
|
|
||||||
bool GetFromBigBuf(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning);
|
|
||||||
//bool GetEMLFromBigBuf(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning);
|
|
||||||
//bool GetFromFlashMen(uint8_t *dest, uint32_t bytes, uint32_t start_index, UsbCommand *response, size_t ms_timeout, bool show_warning);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -59,7 +59,7 @@ typedef struct {
|
||||||
// For Flash memory operations
|
// For Flash memory operations
|
||||||
#define CMD_READ_FLASH_MEM 0x0120
|
#define CMD_READ_FLASH_MEM 0x0120
|
||||||
#define CMD_WRITE_FLASH_MEM 0x0121
|
#define CMD_WRITE_FLASH_MEM 0x0121
|
||||||
#define CMD_UPLOAD_FLASH_MEM 0x0122
|
#define CMD_WIPE_FLASH_MEM 0x0122
|
||||||
#define CMD_DOWNLOAND_FLASH_MEM 0x0123
|
#define CMD_DOWNLOAND_FLASH_MEM 0x0123
|
||||||
|
|
||||||
// For low-frequency tags
|
// For low-frequency tags
|
||||||
|
|
|
@ -70,7 +70,7 @@ typedef struct{
|
||||||
// For Flash memory operations
|
// For Flash memory operations
|
||||||
#define CMD_READ_FLASH_MEM 0x0120
|
#define CMD_READ_FLASH_MEM 0x0120
|
||||||
#define CMD_WRITE_FLASH_MEM 0x0121
|
#define CMD_WRITE_FLASH_MEM 0x0121
|
||||||
#define CMD_UPLOAD_FLASH_MEM 0x0122
|
#define CMD_WIPE_FLASH_MEM 0x0122
|
||||||
#define CMD_DOWNLOAND_FLASH_MEM 0x0123
|
#define CMD_DOWNLOAND_FLASH_MEM 0x0123
|
||||||
#define CMD_DOWNLOADED_FLASHMEM 0x0124
|
#define CMD_DOWNLOADED_FLASHMEM 0x0124
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue