mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
relocated "pwd block management" from device to client
This commit is contained in:
parent
8a1558757c
commit
ae96cd869a
2 changed files with 81 additions and 87 deletions
|
@ -1488,17 +1488,15 @@ static uint32_t get_pwd(uint8_t *pwds, int cnt) {
|
||||||
|
|
||||||
void em4x50_chk(uint32_t *offset) {
|
void em4x50_chk(uint32_t *offset) {
|
||||||
|
|
||||||
// check passwords from dictionary in flash memory
|
// check passwords from dictionary content in flash memory
|
||||||
|
|
||||||
bool bsuccess = false;
|
bool bsuccess = false;
|
||||||
int block_count = 1;
|
|
||||||
int pwds_remain = 0;
|
|
||||||
uint8_t counter[2] = {0x00, 0x00};
|
uint8_t counter[2] = {0x00, 0x00};
|
||||||
uint16_t isok = 0;
|
uint16_t isok = 0;
|
||||||
uint16_t pwd_count = 0;
|
uint16_t pwd_count = 0;
|
||||||
uint16_t pwd_size_available = 0;
|
uint16_t pwd_size_available = 0;
|
||||||
uint32_t pwd = 0x0;
|
uint32_t pwd = 0x0;
|
||||||
uint8_t *pwd_block = BigBuf_get_EM_addr();
|
uint8_t *pwds = BigBuf_get_EM_addr();
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_LF) here although FPGA is not
|
// Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_LF) here although FPGA is not
|
||||||
|
@ -1513,74 +1511,34 @@ void em4x50_chk(uint32_t *offset) {
|
||||||
if (Flash_ReadData(*offset, counter, sizeof(counter)) != sizeof(counter))
|
if (Flash_ReadData(*offset, counter, sizeof(counter)) != sizeof(counter))
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
|
||||||
*offset += 2;
|
|
||||||
|
|
||||||
pwd_count = (uint16_t)(counter[1] << 8 | counter[0]);
|
pwd_count = (uint16_t)(counter[1] << 8 | counter[0]);
|
||||||
if (pwd_count == 0)
|
if (pwd_count == 0)
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
|
||||||
pwd_size_available = 4 * pwd_count;
|
pwd_size_available = 4 * pwd_count;
|
||||||
|
|
||||||
// since flash can report way too many pwds, we need to limit it.
|
isok = Flash_ReadData(*offset + 2, pwds, pwd_size_available);
|
||||||
// bigbuff EM size is determined by CARD_MEMORY_SIZE
|
if (isok != pwd_size_available)
|
||||||
// a password is 4bytes.
|
goto OUT;
|
||||||
// pwd_size_available = MIN(CARD_MEMORY_SIZE, pwd_count * 4);
|
|
||||||
if (pwd_size_available > CARD_MEMORY_SIZE) {
|
em4x50_setup_read();
|
||||||
|
|
||||||
// we have to use more than one block of passwords
|
// set gHigh and gLow
|
||||||
block_count = (4 * pwd_count) / CARD_MEMORY_SIZE;
|
if (get_signalproperties() && find_em4x50_tag()) {
|
||||||
pwds_remain = pwd_count - block_count * CARD_MEMORY_SIZE / 4;
|
|
||||||
|
|
||||||
if (pwds_remain != 0)
|
|
||||||
block_count++;
|
|
||||||
|
|
||||||
// adjust pwd_size_available and pwd_count
|
|
||||||
pwd_size_available = CARD_MEMORY_SIZE;
|
|
||||||
pwd_count = pwd_size_available / 4;
|
|
||||||
|
|
||||||
Dbprintf("Passwords divided into %i blocks", block_count);
|
// try to login with current password
|
||||||
|
for (int i = 0; i < pwd_count; i++) {
|
||||||
}
|
|
||||||
|
|
||||||
for (int n = 0; n < block_count; n++) {
|
// manual interruption
|
||||||
|
if (BUTTON_PRESS())
|
||||||
|
goto OUT;
|
||||||
|
|
||||||
// adjust parameters if more than 1 block
|
// get next password from flash memory
|
||||||
if (n != 0) {
|
pwd = get_pwd(pwds, i);
|
||||||
*offset += pwd_size_available;
|
|
||||||
|
bsuccess = login(pwd);
|
||||||
// final run with remaining passwords
|
if (bsuccess)
|
||||||
if (n == block_count - 1) {
|
break;
|
||||||
pwd_count = pwds_remain;
|
|
||||||
pwd_size_available = 4 * pwds_remain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Dbprintf("Using block #%i with %i passwords", n + 1, pwd_count);
|
|
||||||
|
|
||||||
// read next password block
|
|
||||||
isok = Flash_ReadData(*offset, pwd_block, pwd_size_available);
|
|
||||||
if (isok != pwd_size_available)
|
|
||||||
goto OUT;
|
|
||||||
|
|
||||||
em4x50_setup_read();
|
|
||||||
|
|
||||||
// set gHigh and gLow
|
|
||||||
if (get_signalproperties() && find_em4x50_tag()) {
|
|
||||||
|
|
||||||
// try to login with current password
|
|
||||||
for (int i = 0; i < pwd_count; i++) {
|
|
||||||
|
|
||||||
// manual interruption
|
|
||||||
if (BUTTON_PRESS())
|
|
||||||
goto OUT;
|
|
||||||
|
|
||||||
// get next password from flash memory
|
|
||||||
pwd = get_pwd(pwd_block, i);
|
|
||||||
|
|
||||||
bsuccess = login(pwd);
|
|
||||||
if (bsuccess)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "em4x50.h"
|
#include "em4x50.h"
|
||||||
|
|
||||||
#define FLASH_MEM_PAGE_SIZE 0x10000
|
#define FLASH_MEM_PAGE_SIZE 0x10000
|
||||||
|
#define CARD_MEMORY_SIZE 4096
|
||||||
|
|
||||||
static int loadFileEM4x50(const char *filename, uint8_t *data, size_t data_len, size_t *bytes_read) {
|
static int loadFileEM4x50(const char *filename, uint8_t *data, size_t data_len, size_t *bytes_read) {
|
||||||
|
|
||||||
|
@ -91,7 +92,6 @@ static int em4x50_write_flash(uint8_t *data, int offset, size_t datalen) {
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
conn.block_after_ACK = false;
|
conn.block_after_ACK = false;
|
||||||
//free(data);
|
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,6 @@ static int em4x50_write_flash(uint8_t *data, int offset, size_t datalen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.block_after_ACK = false;
|
conn.block_after_ACK = false;
|
||||||
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu")" bytes to offset "_GREEN_("%u"), datalen, offset);
|
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1032,7 +1031,6 @@ int CmdEM4x50Sim(const char *Cmd) {
|
||||||
|
|
||||||
if (bytes_read * 8 > FLASH_MEM_MAX_SIZE) {
|
if (bytes_read * 8 > FLASH_MEM_MAX_SIZE) {
|
||||||
PrintAndLogEx(FAILED, "Filesize is larger than available memory");
|
PrintAndLogEx(FAILED, "Filesize is larger than available memory");
|
||||||
//free(data);
|
|
||||||
return PM3_EOVFLOW;
|
return PM3_EOVFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1230,10 +1228,14 @@ int CmdEM4x50Chk(const char *Cmd) {
|
||||||
|
|
||||||
// upload passwords from dictionary to flash memory and start password check
|
// upload passwords from dictionary to flash memory and start password check
|
||||||
|
|
||||||
|
bool key_found = false;
|
||||||
int res = 0, slen = 0;
|
int res = 0, slen = 0;
|
||||||
|
int keys_remain = 0;
|
||||||
|
int block_count = 1;
|
||||||
size_t datalen = 0;
|
size_t datalen = 0;
|
||||||
uint8_t data[FLASH_MEM_MAX_SIZE] = {0x0};
|
uint8_t data[FLASH_MEM_MAX_SIZE] = {0x0};
|
||||||
uint32_t keycnt = 0, offset = 0;
|
uint8_t *keys = data;
|
||||||
|
uint32_t key_count = 0, offset = 0;
|
||||||
char filename[FILE_PATH_SIZE] = {0};
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
|
||||||
|
@ -1263,38 +1265,72 @@ int CmdEM4x50Chk(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "treating file as T55xx passwords");
|
PrintAndLogEx(INFO, "treating file as T55xx passwords");
|
||||||
}
|
}
|
||||||
|
|
||||||
res = loadFileDICTIONARY(filename, data + 2, &datalen, 4, &keycnt);
|
res = loadFileDICTIONARY(filename, data + 2, &datalen, 4, &key_count);
|
||||||
if (res || !keycnt) {
|
if (res || !key_count)
|
||||||
//free(data);
|
|
||||||
return PM3_EFILE;
|
return PM3_EFILE;
|
||||||
}
|
|
||||||
// limited space on flash mem
|
|
||||||
if (keycnt > 0xFFFF)
|
|
||||||
keycnt &= 0xFFFF;
|
|
||||||
|
|
||||||
data[0] = (keycnt >> 0) & 0xFF;
|
// limited space on flash mem
|
||||||
data[1] = (keycnt >> 8) & 0xFF;
|
if (key_count > 0xFFFF)
|
||||||
datalen += 2;
|
key_count &= 0xFFFF;
|
||||||
|
|
||||||
if (datalen > FLASH_MEM_MAX_SIZE) {
|
if (datalen > FLASH_MEM_MAX_SIZE) {
|
||||||
PrintAndLogEx(FAILED, "error, filesize is larger than available memory");
|
PrintAndLogEx(FAILED, "error, filesize is larger than available memory");
|
||||||
//free(data);
|
|
||||||
return PM3_EOVFLOW;
|
return PM3_EOVFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send to device
|
if (datalen > CARD_MEMORY_SIZE) {
|
||||||
res = em4x50_write_flash(data, offset, datalen);
|
|
||||||
if (res != PM3_SUCCESS) {
|
// we have to use more than one block of passwords
|
||||||
PrintAndLogEx(WARNING, "Error uploading to flash.");
|
block_count = (4 * key_count) / CARD_MEMORY_SIZE;
|
||||||
return res;
|
keys_remain = key_count - block_count * CARD_MEMORY_SIZE / 4;
|
||||||
|
|
||||||
|
if (keys_remain != 0)
|
||||||
|
block_count++;
|
||||||
|
|
||||||
|
// adjust pwd_size_available and pwd_count
|
||||||
|
datalen = CARD_MEMORY_SIZE;
|
||||||
|
key_count = datalen / 4;
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Passwords divided into %i blocks", block_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int n = 0; n < block_count; n++) {
|
||||||
|
|
||||||
|
// adjust parameters if more than 1 block
|
||||||
|
if (n != 0) {
|
||||||
|
|
||||||
|
keys += datalen;
|
||||||
|
|
||||||
|
// final run with remaining passwords
|
||||||
|
if (n == block_count - 1) {
|
||||||
|
key_count = keys_remain;
|
||||||
|
datalen = 4 * keys_remain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keys[0] = (key_count >> 0) & 0xFF;
|
||||||
|
keys[1] = (key_count >> 8) & 0xFF;
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Checking block #%i (%i passwords)", n + 1, key_count);
|
||||||
|
|
||||||
|
// send to device
|
||||||
|
res = em4x50_write_flash(keys, offset, datalen + 2);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(WARNING, "Error uploading to flash.");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_LF_EM4X50_CHK, (uint8_t *)&offset, sizeof(offset));
|
||||||
|
WaitForResponseTimeoutW(CMD_LF_EM4X50_CHK, &resp, -1, false);
|
||||||
|
|
||||||
|
key_found = (bool)resp.status;
|
||||||
|
if (key_found)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommandNG(CMD_LF_EM4X50_CHK, (uint8_t *)&offset, sizeof(offset));
|
|
||||||
WaitForResponseTimeoutW(CMD_LF_EM4X50_CHK, &resp, -1, false);
|
|
||||||
|
|
||||||
// print response
|
// print response
|
||||||
if ((bool)resp.status)
|
if (key_found)
|
||||||
PrintAndLogEx(SUCCESS, "Password " _GREEN_("found: %02x %02x %02x %02x"),
|
PrintAndLogEx(SUCCESS, "Password " _GREEN_("found: %02x %02x %02x %02x"),
|
||||||
resp.data.asBytes[3],
|
resp.data.asBytes[3],
|
||||||
resp.data.asBytes[2],
|
resp.data.asBytes[2],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue