mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
sam_seos: add option to send arbitrary requests
This commit is contained in:
parent
dfb5fa3de4
commit
0f7574c982
5 changed files with 205 additions and 135 deletions
|
@ -2246,7 +2246,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_SAM_SEOS: {
|
case CMD_HF_SAM_SEOS: {
|
||||||
sam_seos_get_pacs();
|
sam_seos_get_pacs(packet);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
#include "optimized_cipher.h"
|
#include "optimized_cipher.h"
|
||||||
#include "fpgaloader.h"
|
#include "fpgaloader.h"
|
||||||
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
|
|
||||||
|
@ -146,10 +147,10 @@ inline static uint16_t sam_seos_copy_payload_nfc2sam(uint8_t *sam_tx, uint8_t *
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(sam_tx, payload, sizeof(payload));
|
memcpy(sam_tx, payload, sizeof(payload));
|
||||||
|
|
||||||
sam_append_asn1_node(sam_tx, sam_tx+4, 0x80, nfc_rx, nfc_len);
|
sam_append_asn1_node(sam_tx, sam_tx+4, 0x80, nfc_rx, nfc_len);
|
||||||
sam_append_asn1_node(sam_tx, sam_tx+4, 0x81, tag81, sizeof(tag81));
|
sam_append_asn1_node(sam_tx, sam_tx+4, 0x81, tag81, sizeof(tag81));
|
||||||
|
|
||||||
return sam_tx[1] + 2; // length of the ASN1 tree
|
return sam_tx[1] + 2; // length of the ASN1 tree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,18 +188,21 @@ inline static uint16_t sam_seos_copy_payload_sam2nfc(uint8_t * nfc_tx_buf, uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copies the payload from the SAM receive buffer to the NFC transmit buffer.
|
* @brief Sends a request to the SAM and retrieves the response.
|
||||||
*
|
*
|
||||||
* Unpacks data to be transmitted from ASN1 tree in APDU received from SAM.
|
* Unpacks request to the SAM and relays ISO14A traffic to the card.
|
||||||
|
* If no request data provided, sends a request to get PACS data.
|
||||||
*
|
*
|
||||||
* @param pacs Pointer to the buffer where the decoded PACS data will be stored.
|
* @param request Pointer to the buffer containing the request to be sent to the SAM.
|
||||||
* @param pacs_len Pointer to the variable where the length of the PACS data will be stored.
|
* @param request_len Length of the request to be sent to the SAM.
|
||||||
|
* @param response Pointer to the buffer where the retreived data will be stored.
|
||||||
|
* @param response_len Pointer to the variable where the length of the retreived data will be stored.
|
||||||
* @return Status code indicating success or failure of the operation.
|
* @return Status code indicating success or failure of the operation.
|
||||||
*/
|
*/
|
||||||
static int sam_request_pacs(uint8_t * pacs, uint8_t * pacs_len){
|
static int sam_send_request_iso14a(const uint8_t * const request, const uint8_t request_len, uint8_t * response, uint8_t * response_len){
|
||||||
int res = PM3_SUCCESS;
|
int res = PM3_SUCCESS;
|
||||||
if (g_dbglevel >= DBG_DEBUG)
|
if (g_dbglevel >= DBG_DEBUG)
|
||||||
DbpString("start sam_request_pacs");
|
DbpString("start sam_send_request_iso14a");
|
||||||
|
|
||||||
uint8_t buf1[ISO7816_MAX_FRAME] = {0};
|
uint8_t buf1[ISO7816_MAX_FRAME] = {0};
|
||||||
uint8_t buf2[ISO7816_MAX_FRAME] = {0};
|
uint8_t buf2[ISO7816_MAX_FRAME] = {0};
|
||||||
|
@ -215,18 +219,23 @@ static int sam_request_pacs(uint8_t * pacs, uint8_t * pacs_len){
|
||||||
uint8_t * nfc_rx_buf = buf2;
|
uint8_t * nfc_rx_buf = buf2;
|
||||||
uint16_t nfc_rx_len;
|
uint16_t nfc_rx_len;
|
||||||
|
|
||||||
// send get pacs
|
if(request_len > 0){
|
||||||
static const uint8_t payload[] = {
|
sam_tx_len = request_len;
|
||||||
0xa0, 19, // <- SAM command
|
memcpy(sam_tx_buf, request, sam_tx_len);
|
||||||
0xA1, 17, // <- SamCommandGetContentElement
|
}else{
|
||||||
0x80, 1,
|
// send get pacs
|
||||||
0x04, // <- implicitFormatPhysicalAccessBits
|
static const uint8_t payload[] = {
|
||||||
0x84, 12,
|
0xa0, 19, // <- SAM command
|
||||||
0x2B, 0x06, 0x01, 0x04, 0x01, 0x81, 0xE4, 0x38, 0x01, 0x01, 0x02, 0x04 // <- SoRootOID
|
0xA1, 17, // <- SamCommandGetContentElement
|
||||||
};
|
0x80, 1,
|
||||||
|
0x04, // <- implicitFormatPhysicalAccessBits
|
||||||
|
0x84, 12,
|
||||||
|
0x2B, 0x06, 0x01, 0x04, 0x01, 0x81, 0xE4, 0x38, 0x01, 0x01, 0x02, 0x04 // <- SoRootOID
|
||||||
|
};
|
||||||
|
|
||||||
sam_tx_len = sizeof(payload);
|
sam_tx_len = sizeof(payload);
|
||||||
memcpy(sam_tx_buf, payload, sam_tx_len);
|
memcpy(sam_tx_buf, payload, sam_tx_len);
|
||||||
|
}
|
||||||
|
|
||||||
sam_send_payload(
|
sam_send_payload(
|
||||||
0x44, 0x0a, 0x44,
|
0x44, 0x0a, 0x44,
|
||||||
|
@ -234,51 +243,53 @@ static int sam_request_pacs(uint8_t * pacs, uint8_t * pacs_len){
|
||||||
sam_rx_buf, &sam_rx_len
|
sam_rx_buf, &sam_rx_len
|
||||||
);
|
);
|
||||||
|
|
||||||
// tag <-> SAM exchange starts here
|
if(sam_rx_buf[1] == 0x61){ // commands to be relayed to card starts with 0x61
|
||||||
for(int i = 0; i < 20; i++){
|
// tag <-> SAM exchange starts here
|
||||||
switch_clock_to_countsspclk();
|
while(sam_rx_buf[1] == 0x61){
|
||||||
nfc_tx_len = sam_seos_copy_payload_sam2nfc(nfc_tx_buf, sam_rx_buf);
|
switch_clock_to_countsspclk();
|
||||||
|
nfc_tx_len = sam_seos_copy_payload_sam2nfc(nfc_tx_buf, sam_rx_buf);
|
||||||
|
|
||||||
nfc_rx_len = iso14_apdu(
|
nfc_rx_len = iso14_apdu(
|
||||||
nfc_tx_buf,
|
nfc_tx_buf,
|
||||||
nfc_tx_len,
|
nfc_tx_len,
|
||||||
false,
|
false,
|
||||||
nfc_rx_buf,
|
nfc_rx_buf,
|
||||||
ISO7816_MAX_FRAME,
|
ISO7816_MAX_FRAME,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
switch_clock_to_ticks();
|
switch_clock_to_ticks();
|
||||||
sam_tx_len = sam_seos_copy_payload_nfc2sam(sam_tx_buf, nfc_rx_buf, nfc_rx_len-2);
|
sam_tx_len = sam_seos_copy_payload_nfc2sam(sam_tx_buf, nfc_rx_buf, nfc_rx_len-2);
|
||||||
|
|
||||||
|
sam_send_payload(
|
||||||
|
0x14, 0x0a, 0x14,
|
||||||
|
sam_tx_buf, &sam_tx_len,
|
||||||
|
sam_rx_buf, &sam_rx_len
|
||||||
|
);
|
||||||
|
|
||||||
|
// last SAM->TAG
|
||||||
|
// c1 61 c1 00 00 a1 02 >>82<< 00 90 00
|
||||||
|
if(sam_rx_buf[7] == 0x82){
|
||||||
|
// tag <-> SAM exchange ends here
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static const uint8_t hfack[] = {
|
||||||
|
0xbd, 0x04, 0xa0, 0x02, 0x82, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
sam_tx_len = sizeof(hfack);
|
||||||
|
memcpy(sam_tx_buf, hfack, sam_tx_len);
|
||||||
|
|
||||||
sam_send_payload(
|
sam_send_payload(
|
||||||
0x14, 0x0a, 0x14,
|
0x14, 0x0a, 0x00,
|
||||||
sam_tx_buf, &sam_tx_len,
|
sam_tx_buf, &sam_tx_len,
|
||||||
sam_rx_buf, &sam_rx_len
|
sam_rx_buf, &sam_rx_len
|
||||||
);
|
);
|
||||||
|
|
||||||
// last SAM->TAG
|
|
||||||
// c1 61 c1 00 00 a1 02 >>82<< 00 90 00
|
|
||||||
if(sam_rx_buf[7] == 0x82){
|
|
||||||
// tag <-> SAM exchange ends here
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint8_t hfack[] = {
|
|
||||||
0xbd, 0x04, 0xa0, 0x02, 0x82, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
sam_tx_len = sizeof(hfack);
|
|
||||||
memcpy(sam_tx_buf, hfack, sam_tx_len);
|
|
||||||
|
|
||||||
sam_send_payload(
|
|
||||||
0x14, 0x0a, 0x00,
|
|
||||||
sam_tx_buf, &sam_tx_len,
|
|
||||||
sam_rx_buf, &sam_rx_len
|
|
||||||
);
|
|
||||||
|
|
||||||
// resp:
|
// resp:
|
||||||
// c1 64 00 00 00
|
// c1 64 00 00 00
|
||||||
// bd 09
|
// bd 09
|
||||||
|
@ -286,13 +297,16 @@ static int sam_request_pacs(uint8_t * pacs, uint8_t * pacs_len){
|
||||||
// 03 05 <- include tag for pm3 client
|
// 03 05 <- include tag for pm3 client
|
||||||
// 06 85 80 6d c0 <- decoded PACS data
|
// 06 85 80 6d c0 <- decoded PACS data
|
||||||
// 90 00
|
// 90 00
|
||||||
if(sam_rx_buf[5+2] != 0x8a && sam_rx_buf[5+4] != 0x03){
|
if(request_len == 0){
|
||||||
if (g_dbglevel >= DBG_ERROR)
|
if(sam_rx_buf[5] != 0xbd && sam_rx_buf[5+2] != 0x8a && sam_rx_buf[5+4] != 0x03){
|
||||||
Dbprintf("Invalid SAM response");
|
if (g_dbglevel >= DBG_ERROR)
|
||||||
goto err;
|
Dbprintf("Invalid SAM response");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*pacs_len = sam_rx_buf[5+5] +2;
|
|
||||||
memcpy(pacs, sam_rx_buf+5+4, *pacs_len);
|
*response_len = sam_rx_buf[5+1] +2;
|
||||||
|
memcpy(response, sam_rx_buf+5, *response_len);
|
||||||
res=PM3_SUCCESS;
|
res=PM3_SUCCESS;
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -312,7 +326,13 @@ static int sam_request_pacs(uint8_t * pacs, uint8_t * pacs_len){
|
||||||
*
|
*
|
||||||
* @return Status code indicating success or failure of the operation.
|
* @return Status code indicating success or failure of the operation.
|
||||||
*/
|
*/
|
||||||
int sam_seos_get_pacs(void){
|
int sam_seos_get_pacs(PacketCommandNG *c) {
|
||||||
|
bool disconnectAfter = c->oldarg[0] & 0x01;
|
||||||
|
bool skipDetect = c->oldarg[1] & 0x01;
|
||||||
|
|
||||||
|
uint8_t *cmd = c->data.asBytes;
|
||||||
|
uint16_t cmd_len = (uint16_t) c->oldarg[2];
|
||||||
|
|
||||||
int res = PM3_EFAILED;
|
int res = PM3_EFAILED;
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
@ -324,32 +344,31 @@ int sam_seos_get_pacs(void){
|
||||||
// step 1: ping SAM
|
// step 1: ping SAM
|
||||||
sam_get_version();
|
sam_get_version();
|
||||||
|
|
||||||
// step 2: get card information
|
if(!skipDetect){
|
||||||
iso14a_card_select_t card_a_info;
|
// step 2: get card information
|
||||||
|
iso14a_card_select_t card_a_info;
|
||||||
|
|
||||||
// implicit StartSspClk() happens here
|
// implicit StartSspClk() happens here
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
||||||
if (!iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)){
|
if (!iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)){
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_clock_to_ticks();
|
||||||
|
|
||||||
|
// step 3: SamCommand CardDetected
|
||||||
|
sam_set_card_detected(&card_a_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_clock_to_ticks();
|
|
||||||
|
|
||||||
// step 3: SamCommand CardDetected
|
|
||||||
sam_set_card_detected(&card_a_info);
|
|
||||||
|
|
||||||
// step 3: SamCommand RequestPACS, relay NFC communication
|
// step 3: SamCommand RequestPACS, relay NFC communication
|
||||||
|
uint8_t sam_response[ISO7816_MAX_FRAME] = { 0x00 };
|
||||||
uint8_t pacs[10] = { 0x00 };
|
uint8_t sam_response_len = 0;
|
||||||
uint8_t pacs_len = 0;
|
res = sam_send_request_iso14a(cmd, cmd_len, sam_response, &sam_response_len);
|
||||||
res = sam_request_pacs(pacs, &pacs_len);
|
|
||||||
if(res != PM3_SUCCESS){
|
if(res != PM3_SUCCESS){
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (g_dbglevel >= DBG_INFO)
|
if (g_dbglevel >= DBG_INFO)
|
||||||
print_result("PACS data", pacs, pacs_len);
|
print_result("Response data", sam_response, sam_response_len);
|
||||||
|
|
||||||
sam_send_ack();
|
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
goto off;
|
goto off;
|
||||||
|
@ -359,10 +378,12 @@ int sam_seos_get_pacs(void){
|
||||||
reply_ng(CMD_HF_SAM_SEOS, res, NULL, 0);
|
reply_ng(CMD_HF_SAM_SEOS, res, NULL, 0);
|
||||||
goto off;
|
goto off;
|
||||||
out:
|
out:
|
||||||
reply_ng(CMD_HF_SAM_SEOS, PM3_SUCCESS, pacs, pacs_len);
|
reply_ng(CMD_HF_SAM_SEOS, PM3_SUCCESS, sam_response, sam_response_len);
|
||||||
goto off;
|
goto off;
|
||||||
off:
|
off:
|
||||||
switch_off();
|
if(disconnectAfter){
|
||||||
|
switch_off();
|
||||||
|
}
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
StopTicks();
|
StopTicks();
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
#define __SAM_SEOS_H
|
#define __SAM_SEOS_H
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "pm3_cmd.h"
|
||||||
|
|
||||||
int sam_seos_get_pacs(void);
|
int sam_seos_get_pacs(PacketCommandNG *c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5434,6 +5434,8 @@ static int CmdHFiClassSAM(const char *Cmd) {
|
||||||
|
|
||||||
// CSN, config, epurse, NR/MAC, AIA
|
// CSN, config, epurse, NR/MAC, AIA
|
||||||
// PACS
|
// PACS
|
||||||
|
// 03 05
|
||||||
|
// 06 85 80 6d c0
|
||||||
// first byte skip
|
// first byte skip
|
||||||
// second byte length
|
// second byte length
|
||||||
// third padded
|
// third padded
|
||||||
|
|
|
@ -1635,63 +1635,18 @@ static int CmdHfSeosList(const char *Cmd) {
|
||||||
return CmdTraceListAlias(Cmd, "hf seos", "seos -c");
|
return CmdTraceListAlias(Cmd, "hf seos", "seos -c");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdHfSeosSAM(const char *Cmd) {
|
static int dump_PACS_bits(const uint8_t * const data, const uint8_t length, bool verbose){
|
||||||
CLIParserContext *ctx;
|
uint8_t n = length - 1;
|
||||||
CLIParserInit(&ctx, "hf seos sam",
|
uint8_t pad = data[0];
|
||||||
"Extract PACS via a HID SAM\n",
|
char *binstr = (char *)calloc((length * 8) + 1, sizeof(uint8_t));
|
||||||
"hf seos sam\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
void *argtable[] = {
|
|
||||||
arg_param_begin,
|
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
|
||||||
arg_param_end
|
|
||||||
};
|
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
|
||||||
bool verbose = arg_get_lit(ctx, 1);
|
|
||||||
CLIParserFree(ctx);
|
|
||||||
|
|
||||||
if (IsHIDSamPresent(verbose) == false) {
|
|
||||||
return PM3_ESOFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommandNG(CMD_HF_SAM_SEOS, NULL, 0);
|
|
||||||
PacketResponseNG resp;
|
|
||||||
if (WaitForResponseTimeout(CMD_HF_SAM_SEOS, &resp, 4000) == false) {
|
|
||||||
PrintAndLogEx(WARNING, "SAM timeout");
|
|
||||||
return PM3_ETIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (resp.status) {
|
|
||||||
case PM3_SUCCESS:
|
|
||||||
break;
|
|
||||||
case PM3_ENOPACS:
|
|
||||||
PrintAndLogEx(SUCCESS, "No PACS data found. Card empty?");
|
|
||||||
return resp.status;
|
|
||||||
default:
|
|
||||||
PrintAndLogEx(WARNING, "SAM select failed");
|
|
||||||
return resp.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CSN, config, epurse, NR/MAC, AIA
|
|
||||||
// PACS
|
|
||||||
// first byte skip
|
|
||||||
// second byte length
|
|
||||||
// third padded
|
|
||||||
// fourth ..
|
|
||||||
uint8_t *d = resp.data.asBytes;
|
|
||||||
uint8_t n = d[1] - 1; // skip length byte
|
|
||||||
uint8_t pad = d[2];
|
|
||||||
char *binstr = (char *)calloc((n * 8) + 1, sizeof(uint8_t));
|
|
||||||
if (binstr == NULL) {
|
if (binstr == NULL) {
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes_2_binstr(binstr, d + 3, n);
|
bytes_2_binstr(binstr, data + 1, n);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(SUCCESS, "PACS......... " _GREEN_("%s"), sprint_hex_inrow(d + 2, resp.length - 2));
|
PrintAndLogEx(SUCCESS, "PACS......... " _GREEN_("%s"), sprint_hex_inrow(data, length));
|
||||||
PrintAndLogEx(SUCCESS, "padded bin... " _GREEN_("%s") " ( %zu )", binstr, strlen(binstr));
|
PrintAndLogEx(SUCCESS, "padded bin... " _GREEN_("%s") " ( %zu )", binstr, strlen(binstr));
|
||||||
|
|
||||||
binstr[strlen(binstr) - pad] = '\0';
|
binstr[strlen(binstr) - pad] = '\0';
|
||||||
|
@ -1749,7 +1704,98 @@ static int CmdHfSeosSAM(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
}
|
}
|
||||||
free(binstr);
|
free(binstr);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdHfSeosSAM(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf seos sam",
|
||||||
|
"Extract PACS via a HID SAM\n",
|
||||||
|
"hf seos sam\n"
|
||||||
|
"hd seos sam -d a005a103800104 -> get PACS data\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
|
arg_lit0("k", "keep", "keep the field active after command executed"),
|
||||||
|
arg_lit0("n", "nodetect", "skip selecting the card and sending card details to SAM"),
|
||||||
|
arg_lit0("t", "tlv", "decode TLV"),
|
||||||
|
arg_strx0("d", "data", "<hex>", "DER encoded command to send to SAM"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
|
bool verbose = false;
|
||||||
|
if (arg_get_lit(ctx, 1)) {
|
||||||
|
verbose = true;
|
||||||
|
}
|
||||||
|
bool disconnectAfter = true;
|
||||||
|
if(arg_get_lit(ctx, 2)){
|
||||||
|
disconnectAfter = false;
|
||||||
|
}
|
||||||
|
bool skipDetect = false;
|
||||||
|
if(arg_get_lit(ctx, 3)){
|
||||||
|
skipDetect = true;
|
||||||
|
}
|
||||||
|
bool decodeTLV = false;
|
||||||
|
if(arg_get_lit(ctx, 4)){
|
||||||
|
decodeTLV = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t data[PM3_CMD_DATA_SIZE] = {0};
|
||||||
|
int datalen = 0;
|
||||||
|
CLIGetHexBLessWithReturn(ctx, 5, data, &datalen, 0);
|
||||||
|
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
if (IsHIDSamPresent(verbose) == false) {
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
// void SendCommandMIX(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, const void *data, size_t len) {
|
||||||
|
SendCommandMIX(CMD_HF_SAM_SEOS, disconnectAfter, skipDetect, datalen, data, datalen);
|
||||||
|
// SendCommandNG(CMD_HF_SAM_SEOS, NULL, 0);
|
||||||
|
PacketResponseNG resp;
|
||||||
|
if (WaitForResponseTimeout(CMD_HF_SAM_SEOS, &resp, 4000) == false) {
|
||||||
|
PrintAndLogEx(WARNING, "SAM timeout");
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (resp.status) {
|
||||||
|
case PM3_SUCCESS:
|
||||||
|
break;
|
||||||
|
case PM3_ENOPACS:
|
||||||
|
PrintAndLogEx(SUCCESS, "No PACS data found. Card empty?");
|
||||||
|
return resp.status;
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "SAM select failed");
|
||||||
|
return resp.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *d = resp.data.asBytes;
|
||||||
|
// check for standard SamCommandGetContentElement response
|
||||||
|
// bd 09
|
||||||
|
// 8a 07
|
||||||
|
// 03 05 <- tag + length
|
||||||
|
// 06 85 80 6d c0 <- decoded PACS data
|
||||||
|
if(d[0] == 0xbd && d[2] == 0x8a && d[4] == 0x03){
|
||||||
|
uint8_t pacs_length = d[5];
|
||||||
|
uint8_t * pacs_data = d + 6;
|
||||||
|
int res = dump_PACS_bits(pacs_data, pacs_length, verbose);
|
||||||
|
if(res != PM3_SUCCESS){
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print_hex(d, resp.length);
|
||||||
|
}
|
||||||
|
if (decodeTLV) {
|
||||||
|
asn1_print(d, d[1] + 2, " ");
|
||||||
|
}
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue