This commit is contained in:
Willy-JL
2024-01-13 02:36:39 +00:00
25 changed files with 577 additions and 217 deletions
+19 -4
View File
@@ -8,12 +8,14 @@ typedef enum {
LFRFIDEventStopMode = (1 << 1),
LFRFIDEventRead = (1 << 2),
LFRFIDEventWrite = (1 << 3),
LFRFIDEventEmulate = (1 << 4),
LFRFIDEventReadRaw = (1 << 5),
LFRFIDEventEmulateRaw = (1 << 6),
LFRFIDEventWriteWithPass = (1 << 4),
LFRFIDEventEmulate = (1 << 5),
LFRFIDEventReadRaw = (1 << 6),
LFRFIDEventEmulateRaw = (1 << 7),
LFRFIDEventAll =
(LFRFIDEventStopThread | LFRFIDEventStopMode | LFRFIDEventRead | LFRFIDEventWrite |
LFRFIDEventEmulate | LFRFIDEventReadRaw | LFRFIDEventEmulateRaw),
LFRFIDEventWriteWithPass | LFRFIDEventEmulate | LFRFIDEventReadRaw |
LFRFIDEventEmulateRaw),
} LFRFIDEventType;
static int32_t lfrfid_worker_thread(void* thread_context);
@@ -69,6 +71,18 @@ void lfrfid_worker_write_start(
furi_thread_flags_set(furi_thread_get_id(worker->thread), LFRFIDEventWrite);
}
void lfrfid_worker_write_with_pass_start(
LFRFIDWorker* worker,
LFRFIDProtocol protocol,
LFRFIDWorkerWriteCallback callback,
void* context) {
furi_assert(worker->mode_index == LFRFIDWorkerIdle);
worker->protocol = protocol;
worker->write_cb = callback;
worker->cb_ctx = context;
furi_thread_flags_set(furi_thread_get_id(worker->thread), LFRFIDEventWriteWithPass);
}
void lfrfid_worker_emulate_start(LFRFIDWorker* worker, LFRFIDProtocol protocol) {
furi_assert(worker->mode_index == LFRFIDWorkerIdle);
worker->protocol = protocol;
@@ -145,6 +159,7 @@ static int32_t lfrfid_worker_thread(void* thread_context) {
// switch mode
if(flags & LFRFIDEventRead) worker->mode_index = LFRFIDWorkerRead;
if(flags & LFRFIDEventWrite) worker->mode_index = LFRFIDWorkerWrite;
if(flags & LFRFIDEventWriteWithPass) worker->mode_index = LFRFIDWorkerWriteWithPass;
if(flags & LFRFIDEventEmulate) worker->mode_index = LFRFIDWorkerEmulate;
if(flags & LFRFIDEventReadRaw) worker->mode_index = LFRFIDWorkerReadRaw;
if(flags & LFRFIDEventEmulateRaw) worker->mode_index = LFRFIDWorkerEmulateRaw;
+14
View File
@@ -106,6 +106,20 @@ void lfrfid_worker_write_start(
LFRFIDWorkerWriteCallback callback,
void* context);
/**
* @brief Start write with pass mode
*
* @param worker
* @param protocol
* @param callback
* @param context
*/
void lfrfid_worker_write_with_pass_start(
LFRFIDWorker* worker,
LFRFIDProtocol protocol,
LFRFIDWorkerWriteCallback callback,
void* context);
/**
* Start emulate mode
* @param worker
+1
View File
@@ -22,6 +22,7 @@ typedef enum {
LFRFIDWorkerIdle,
LFRFIDWorkerRead,
LFRFIDWorkerWrite,
LFRFIDWorkerWriteWithPass,
LFRFIDWorkerEmulate,
LFRFIDWorkerReadRaw,
LFRFIDWorkerEmulateRaw,
+91
View File
@@ -574,6 +574,96 @@ static void lfrfid_worker_mode_write_process(LFRFIDWorker* worker) {
free(read_data);
}
static void lfrfid_worker_mode_write_with_pass_process(LFRFIDWorker* worker) {
LFRFIDProtocol protocol = worker->protocol;
LFRFIDWriteRequest* request = malloc(sizeof(LFRFIDWriteRequest));
request->write_type = LFRFIDWriteTypeT5577;
bool can_be_written = protocol_dict_get_write_data(worker->protocols, protocol, request);
uint32_t write_start_time = furi_get_tick();
bool too_long = false;
size_t unsuccessful_reads = 0;
size_t data_size = protocol_dict_get_data_size(worker->protocols, protocol);
uint8_t* verify_data = malloc(data_size);
uint8_t* read_data = malloc(data_size);
protocol_dict_get_data(worker->protocols, protocol, verify_data, data_size);
if(can_be_written) {
while(!lfrfid_worker_check_for_stop(worker)) {
FURI_LOG_D(TAG, "Data write");
uint8_t size;
const uint32_t* password_list = t5577_get_default_passwords(&size);
uint32_t pass = password_list[rand() % size];
request->t5577.mask = 0b1111111;
request->t5577.block[0] |= 0b10000;
request->t5577.block[7] = pass;
t5577_write_with_mask(&request->t5577, 0, 0);
ProtocolId read_result = PROTOCOL_NO;
LFRFIDWorkerReadState state = lfrfid_worker_read_internal(
worker,
protocol_dict_get_features(worker->protocols, protocol),
LFRFID_WORKER_WRITE_VERIFY_TIME_MS,
&read_result);
if(state == LFRFIDWorkerReadOK) {
bool read_success = false;
if(read_result == protocol) {
protocol_dict_get_data(worker->protocols, protocol, read_data, data_size);
if(memcmp(read_data, verify_data, data_size) == 0) {
read_success = true;
}
}
if(read_success) {
FURI_LOG_D(TAG, "Write with password %08lX success", pass);
if(worker->write_cb) {
worker->write_cb(LFRFIDWorkerWriteOK, worker->cb_ctx);
}
break;
} else {
unsuccessful_reads++;
if(unsuccessful_reads == LFRFID_WORKER_WRITE_MAX_UNSUCCESSFUL_READS) {
if(worker->write_cb) {
worker->write_cb(LFRFIDWorkerWriteFobCannotBeWritten, worker->cb_ctx);
}
}
}
} else if(state == LFRFIDWorkerReadExit) {
break;
}
if(!too_long &&
(furi_get_tick() - write_start_time) > LFRFID_WORKER_WRITE_TOO_LONG_TIME_MS) {
too_long = true;
if(worker->write_cb) {
worker->write_cb(LFRFIDWorkerWriteTooLongToWrite, worker->cb_ctx);
}
}
lfrfid_worker_delay(worker, LFRFID_WORKER_WRITE_DROP_TIME_MS);
}
} else {
if(worker->write_cb) {
worker->write_cb(LFRFIDWorkerWriteProtocolCannotBeWritten, worker->cb_ctx);
}
}
free(request);
free(verify_data);
free(read_data);
}
/**************************************************************************************************/
/******************************************* READ RAW *********************************************/
/**************************************************************************************************/
@@ -629,6 +719,7 @@ const LFRFIDWorkerModeType lfrfid_worker_modes[] = {
[LFRFIDWorkerIdle] = {.process = NULL},
[LFRFIDWorkerRead] = {.process = lfrfid_worker_mode_read_process},
[LFRFIDWorkerWrite] = {.process = lfrfid_worker_mode_write_process},
[LFRFIDWorkerWriteWithPass] = {.process = lfrfid_worker_mode_write_with_pass_process},
[LFRFIDWorkerEmulate] = {.process = lfrfid_worker_mode_emulate_process},
[LFRFIDWorkerReadRaw] = {.process = lfrfid_worker_mode_read_raw_process},
[LFRFIDWorkerEmulateRaw] = {.process = lfrfid_worker_mode_emulate_raw_process},
+51 -4
View File
@@ -13,6 +13,33 @@
#define T5577_OPCODE_PAGE_1 0b11
#define T5577_OPCODE_RESET 0b00
#define T5577_BLOCKS_IN_PAGE_0 8
#define T5577_BLOCKS_IN_PAGE_1 4
//TODO: use .txt file in resources for passwords.
const uint32_t default_passwords[] = {
0x51243648, 0x000D8787, 0x19920427, 0x50524F58, 0xF9DCEBA0, 0x65857569, 0x05D73B9F, 0x89A69E60,
0x314159E0, 0xAA55BBBB, 0xA5B4C3D2, 0x1C0B5848, 0x00434343, 0x444E4752, 0x4E457854, 0x44B44CAE,
0x88661858, 0xE9920427, 0x575F4F4B, 0x50520901, 0x20206666, 0x65857569, 0x5469616E, 0x7686962A,
0xC0F5009A, 0x07CEE75D, 0xfeedbeef, 0xdeadc0de, 0x00000000, 0x11111111, 0x22222222, 0x33333333,
0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x88888888, 0x99999999, 0xAAAAAAAA, 0xBBBBBBBB,
0xCCCCCCCC, 0xDDDDDDDD, 0xEEEEEEEE, 0xFFFFFFFF, 0xa0a1a2a3, 0xb0b1b2b3, 0x50415353, 0x00000001,
0x00000002, 0x0000000a, 0x0000000b, 0x01020304, 0x02030405, 0x03040506, 0x04050607, 0x05060708,
0x06070809, 0x0708090A, 0x08090A0B, 0x090A0B0C, 0x0A0B0C0D, 0x0B0C0D0E, 0x0C0D0E0F, 0x01234567,
0x12345678, 0x10000000, 0x20000000, 0x30000000, 0x40000000, 0x50000000, 0x60000000, 0x70000000,
0x80000000, 0x90000000, 0xA0000000, 0xB0000000, 0xC0000000, 0xD0000000, 0xE0000000, 0xF0000000,
0x10101010, 0x01010101, 0x11223344, 0x22334455, 0x33445566, 0x44556677, 0x55667788, 0x66778899,
0x778899AA, 0x8899AABB, 0x99AABBCC, 0xAABBCCDD, 0xBBCCDDEE, 0xCCDDEEFF, 0x0CB7E7FC, 0xFABADA11,
0x87654321, 0x12341234, 0x69696969, 0x12121212, 0x12344321, 0x1234ABCD, 0x11112222, 0x13131313,
0x10041004, 0x31415926, 0xabcd1234, 0x20002000, 0x19721972, 0xaa55aa55, 0x55aa55aa, 0x4f271149,
0x07d7bb0b, 0x9636ef8f, 0xb5f44686, 0x9E3779B9, 0xC6EF3720, 0x7854794A, 0xF1EA5EED, 0x69314718,
0x57721566, 0x93C467E3, 0x27182818, 0x50415353};
const uint32_t* t5577_get_default_passwords(uint8_t* len) {
*len = sizeof(default_passwords) / sizeof(uint32_t);
return default_passwords;
}
static void t5577_start() {
furi_hal_rfid_tim_read_start(125000, 0.5);
@@ -52,6 +79,7 @@ static void t5577_write_reset() {
}
static void t5577_write_block_pass(
uint8_t page,
uint8_t block,
bool lock_bit,
uint32_t data,
@@ -62,8 +90,8 @@ static void t5577_write_block_pass(
// start gap
t5577_write_gap(T5577_TIMING_START_GAP);
// opcode for page 0
t5577_write_opcode(T5577_OPCODE_PAGE_0);
// opcode for page
t5577_write_opcode((page == 1) ? T5577_OPCODE_PAGE_1 : T5577_OPCODE_PAGE_0);
// password
if(with_pass) {
@@ -92,7 +120,7 @@ static void t5577_write_block_pass(
}
static void t5577_write_block_simple(uint8_t block, bool lock_bit, uint32_t data) {
t5577_write_block_pass(block, lock_bit, data, false, 0);
t5577_write_block_pass(0, block, lock_bit, data, false, 0);
}
void t5577_write(LFRFIDT5577* data) {
@@ -110,9 +138,28 @@ void t5577_write_with_pass(LFRFIDT5577* data, uint32_t password) {
t5577_start();
FURI_CRITICAL_ENTER();
for(size_t i = 0; i < data->blocks_to_write; i++) {
t5577_write_block_pass(i, false, data->block[i], true, password);
t5577_write_block_pass(0, i, false, data->block[i], true, password);
}
t5577_write_reset();
FURI_CRITICAL_EXIT();
t5577_stop();
}
void t5577_write_with_mask(LFRFIDT5577* data, uint8_t page, uint32_t password) {
t5577_start();
FURI_CRITICAL_ENTER();
uint8_t mask = data->mask;
size_t pages_total = (page == 0) ? T5577_BLOCKS_IN_PAGE_0 : T5577_BLOCKS_IN_PAGE_1;
for(size_t i = 0; i < pages_total; i++) {
bool need_to_write = mask & 1;
mask >>= 1;
if(!need_to_write) continue;
t5577_write_block_pass(page, i, false, data->block[i], true, password);
}
t5577_write_reset();
FURI_CRITICAL_EXIT();
t5577_stop();
}
+5
View File
@@ -42,8 +42,11 @@ extern "C" {
typedef struct {
uint32_t block[LFRFID_T5577_BLOCK_COUNT];
uint32_t blocks_to_write;
uint8_t mask;
} LFRFIDT5577;
const uint32_t* t5577_get_default_passwords(uint8_t* len);
/**
* @brief Write T5577 tag data to tag
*
@@ -53,6 +56,8 @@ void t5577_write(LFRFIDT5577* data);
void t5577_write_with_pass(LFRFIDT5577* data, uint32_t password);
void t5577_write_with_mask(LFRFIDT5577* data, uint8_t page, uint32_t password);
#ifdef __cplusplus
}
#endif
@@ -22,6 +22,7 @@ MfClassicPoller* mf_classic_poller_alloc(Iso14443_3aPoller* iso14443_3a_poller)
instance->rx_plain_buffer = bit_buffer_alloc(MF_CLASSIC_MAX_BUFF_SIZE);
instance->rx_encrypted_buffer = bit_buffer_alloc(MF_CLASSIC_MAX_BUFF_SIZE);
instance->current_type_check = MfClassicType4k;
instance->card_state = MfClassicCardStateLost;
instance->mfc_event.data = &instance->mfc_event_data;
+2 -15
View File
@@ -18,7 +18,6 @@ struct SubGhzFileEncoderWorker {
volatile bool worker_running;
volatile bool worker_stopping;
bool level;
bool is_storage_slow;
FuriString* str_data;
FuriString* file_path;
@@ -41,19 +40,8 @@ void subghz_file_encoder_worker_callback_end(
void subghz_file_encoder_worker_add_level_duration(
SubGhzFileEncoderWorker* instance,
int32_t duration) {
bool res = true;
if(duration < 0 && !instance->level) {
res = false;
} else if(duration > 0 && instance->level) {
res = false;
}
if(res) {
instance->level = !instance->level;
furi_stream_buffer_send(instance->stream, &duration, sizeof(int32_t), 100);
} else {
FURI_LOG_E(TAG, "Invalid level in the stream");
}
size_t ret = furi_stream_buffer_send(instance->stream, &duration, sizeof(int32_t), 100);
if(sizeof(int32_t) != ret) FURI_LOG_E(TAG, "Invalid add duration in the stream");
}
bool subghz_file_encoder_worker_data_parse(SubGhzFileEncoderWorker* instance, const char* strStart) {
@@ -214,7 +202,6 @@ SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() {
instance->str_data = furi_string_alloc();
instance->file_path = furi_string_alloc();
instance->level = false;
instance->worker_stopping = true;
return instance;