mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -07:00
chg: 'hf iclass sim' - turning of antenna after simulation is done.
chg: 'hf iclass sim' - use @holiman 's 8 csn instead of the original @carl55 (15), and a new first entry csn, to see if the old one got blacklisted.
This commit is contained in:
parent
1d6b0c0c6a
commit
db515ba6c4
4 changed files with 91 additions and 78 deletions
|
@ -994,20 +994,17 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
||||||
//Use the emulator memory for SIM
|
//Use the emulator memory for SIM
|
||||||
uint8_t *emulator = BigBuf_get_EM_addr();
|
uint8_t *emulator = BigBuf_get_EM_addr();
|
||||||
|
|
||||||
if(simType == 0) {
|
if (simType == 0) {
|
||||||
// Use the CSN from commandline
|
// Use the CSN from commandline
|
||||||
memcpy(emulator, datain, 8);
|
memcpy(emulator, datain, 8);
|
||||||
doIClassSimulation(MODE_SIM_CSN,NULL);
|
doIClassSimulation(MODE_SIM_CSN,NULL);
|
||||||
}else if(simType == 1)
|
} else if (simType == 1) {
|
||||||
{
|
|
||||||
//Default CSN
|
//Default CSN
|
||||||
uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
|
uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
|
||||||
// Use the CSN from commandline
|
// Use the CSN from commandline
|
||||||
memcpy(emulator, csn_crc, 8);
|
memcpy(emulator, csn_crc, 8);
|
||||||
doIClassSimulation(MODE_SIM_CSN,NULL);
|
doIClassSimulation(MODE_SIM_CSN,NULL);
|
||||||
}
|
} else if(simType == 2) {
|
||||||
else if(simType == 2)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint8_t mac_responses[USB_CMD_DATA_SIZE] = { 0 };
|
uint8_t mac_responses[USB_CMD_DATA_SIZE] = { 0 };
|
||||||
Dbprintf("Going into attack mode, %d CSNS sent", numberOfCSNS);
|
Dbprintf("Going into attack mode, %d CSNS sent", numberOfCSNS);
|
||||||
|
@ -1015,30 +1012,28 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
||||||
// in order to collect MAC's from the reader. This can later be used in an offlne-attack
|
// in order to collect MAC's from the reader. This can later be used in an offlne-attack
|
||||||
// in order to obtain the keys, as in the "dismantling iclass"-paper.
|
// in order to obtain the keys, as in the "dismantling iclass"-paper.
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for( ; i < numberOfCSNS && i*8+8 < USB_CMD_DATA_SIZE; i++)
|
for( ; i < numberOfCSNS && i*8+8 < USB_CMD_DATA_SIZE; i++) {
|
||||||
{
|
|
||||||
// The usb data is 512 bytes, fitting 65 8-byte CSNs in there.
|
// The usb data is 512 bytes, fitting 65 8-byte CSNs in there.
|
||||||
|
|
||||||
memcpy(emulator, datain+(i*8), 8);
|
memcpy(emulator, datain+(i*8), 8);
|
||||||
if(doIClassSimulation(MODE_EXIT_AFTER_MAC,mac_responses+i*8))
|
if (doIClassSimulation(MODE_EXIT_AFTER_MAC,mac_responses+i*8)) {
|
||||||
{
|
|
||||||
cmd_send(CMD_ACK,CMD_SIMULATE_TAG_ICLASS,i,0,mac_responses,i*8);
|
cmd_send(CMD_ACK,CMD_SIMULATE_TAG_ICLASS,i,0,mac_responses,i*8);
|
||||||
return; // Button pressed
|
return; // Button pressed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd_send(CMD_ACK,CMD_SIMULATE_TAG_ICLASS,i,0,mac_responses,i*8);
|
cmd_send(CMD_ACK,CMD_SIMULATE_TAG_ICLASS,i,0,mac_responses,i*8);
|
||||||
|
|
||||||
}else if(simType == 3){
|
} else if (simType == 3){
|
||||||
//This is 'full sim' mode, where we use the emulator storage for data.
|
//This is 'full sim' mode, where we use the emulator storage for data.
|
||||||
doIClassSimulation(MODE_FULLSIM, NULL);
|
doIClassSimulation(MODE_FULLSIM, NULL);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
// We may want a mode here where we hardcode the csns to use (from proxclone).
|
// We may want a mode here where we hardcode the csns to use (from proxclone).
|
||||||
// That will speed things up a little, but not required just yet.
|
// That will speed things up a little, but not required just yet.
|
||||||
Dbprintf("The mode is not implemented, reserved for future use");
|
Dbprintf("The mode is not implemented, reserved for future use");
|
||||||
}
|
}
|
||||||
Dbprintf("Done...");
|
Dbprintf("Done...");
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
}
|
}
|
||||||
void AppendCrc(uint8_t* data, int len)
|
void AppendCrc(uint8_t* data, int len)
|
||||||
{
|
{
|
||||||
|
@ -1564,7 +1559,9 @@ int ReaderReceiveIClass(uint8_t* receivedAnswer)
|
||||||
{
|
{
|
||||||
int samples = 0;
|
int samples = 0;
|
||||||
if (!GetIClassAnswer(receivedAnswer,160,&samples,0)) return false;
|
if (!GetIClassAnswer(receivedAnswer,160,&samples,0)) return false;
|
||||||
|
|
||||||
rsamples += samples;
|
rsamples += samples;
|
||||||
|
|
||||||
if (tracing) {
|
if (tracing) {
|
||||||
uint8_t parity[MAX_PARITY_SIZE];
|
uint8_t parity[MAX_PARITY_SIZE];
|
||||||
GetParity(receivedAnswer, Demod.len, parity);
|
GetParity(receivedAnswer, Demod.len, parity);
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
#define NUM_CSNS 15
|
#define NUM_CSNS 8
|
||||||
|
|
||||||
#define ICLASS_KEYS_MAX 8
|
#define ICLASS_KEYS_MAX 8
|
||||||
static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = {
|
static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = {
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
||||||
|
@ -182,7 +183,7 @@ int usage_hf_iclass_reader(void) {
|
||||||
PrintAndLog(" hf iclass reader 1");
|
PrintAndLog(" hf iclass reader 1");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int usage_hf_iclass_replay(void){
|
int usage_hf_iclass_replay(void) {
|
||||||
PrintAndLog("HELP: Replay a collected mac message");
|
PrintAndLog("HELP: Replay a collected mac message");
|
||||||
PrintAndLog("Usage: hf iclass replay [h] <mac>");
|
PrintAndLog("Usage: hf iclass replay [h] <mac>");
|
||||||
PrintAndLog("Options:");
|
PrintAndLog("Options:");
|
||||||
|
@ -192,13 +193,29 @@ int usage_hf_iclass_replay(void){
|
||||||
PrintAndLog(" hf iclass replay 00112233");
|
PrintAndLog(" hf iclass replay 00112233");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int usage_hf_iclass_snoop(void){
|
int usage_hf_iclass_snoop(void) {
|
||||||
PrintAndLog("HELP: Snoops the communication between reader and tag");
|
PrintAndLog("HELP: Snoops the communication between reader and tag");
|
||||||
PrintAndLog("Usage: hf iclass snoop [h]");
|
PrintAndLog("Usage: hf iclass snoop [h]");
|
||||||
PrintAndLog("Samples:");
|
PrintAndLog("Samples:");
|
||||||
PrintAndLog(" hf iclass snoop");
|
PrintAndLog(" hf iclass snoop");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int usage_hf_iclass_loclass(void) {
|
||||||
|
PrintAndLog("Usage: hf iclass loclass [options]");
|
||||||
|
PrintAndLog("Options:");
|
||||||
|
PrintAndLog("h Show this help");
|
||||||
|
PrintAndLog("t Perform self-test");
|
||||||
|
PrintAndLog("f <filename> Bruteforce iclass dumpfile");
|
||||||
|
PrintAndLog(" An iclass dumpfile is assumed to consist of an arbitrary number of");
|
||||||
|
PrintAndLog(" malicious CSNs, and their protocol responses");
|
||||||
|
PrintAndLog(" The binary format of the file is expected to be as follows: ");
|
||||||
|
PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
|
||||||
|
PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
|
||||||
|
PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
|
||||||
|
PrintAndLog(" ... totalling N*24 bytes");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int xorbits_8(uint8_t val) {
|
int xorbits_8(uint8_t val) {
|
||||||
uint8_t res = val ^ (val >> 1); //1st pass
|
uint8_t res = val ^ (val >> 1); //1st pass
|
||||||
res = res ^ (res >> 1); // 2nd pass
|
res = res ^ (res >> 1); // 2nd pass
|
||||||
|
@ -252,8 +269,26 @@ int CmdHFiClassSim(const char *Cmd) {
|
||||||
UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}};
|
UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}};
|
||||||
UsbCommand resp = {0};
|
UsbCommand resp = {0};
|
||||||
|
|
||||||
|
// pre-defined 8 CSN by Holiman
|
||||||
|
// but new entry[0] by iceman
|
||||||
uint8_t csns[8*NUM_CSNS] = {
|
uint8_t csns[8*NUM_CSNS] = {
|
||||||
0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
|
//0X00, 0X0B, 0X0F, 0XFF, 0XF7, 0XFF, 0X12, 0XE0, // 0,1,69
|
||||||
|
0x00, 0x8b, 0x8f, 0x7f, 0xf7, 0xff, 0x12, 0xe0,
|
||||||
|
0X00, 0X13, 0X94, 0X7E, 0X76, 0XFF, 0X12, 0XE0, // 2,12
|
||||||
|
0X2A, 0X99, 0XAC, 0X79, 0XEC, 0XFF, 0X12, 0XE0, // 7,11
|
||||||
|
0X17, 0X12, 0X01, 0XFD, 0XF7, 0XFF, 0X12, 0XE0, // 3,15
|
||||||
|
0XCD, 0X56, 0X01, 0X7C, 0X6F, 0XFF, 0X12, 0XE0, // 4,8
|
||||||
|
0X4B, 0X5E, 0X0B, 0X72, 0XEF, 0XFF, 0X12, 0XE0, // 6,14
|
||||||
|
0X00, 0X73, 0XD8, 0X75, 0X58, 0XFF, 0X12, 0XE0, // 9,5
|
||||||
|
0X0C, 0X90, 0X32, 0XF3, 0X5D, 0XFF, 0X12, 0XE0 // 10,13
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
// pre-defined 15 CSN by Carl55
|
||||||
|
// but new entry[0] by iceman
|
||||||
|
uint8_t csns[8*NUM_CSNS] = {
|
||||||
|
//0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
|
||||||
|
0x00, 0x8b, 0x8f, 0x7f, 0xf7, 0xff, 0x12, 0xe0,
|
||||||
0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
|
0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
|
||||||
0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
|
0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
|
||||||
0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
|
0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
|
||||||
|
@ -267,8 +302,9 @@ int CmdHFiClassSim(const char *Cmd) {
|
||||||
0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
|
0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
|
||||||
0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
|
0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
|
||||||
0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
|
0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
|
||||||
0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
|
0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0
|
||||||
|
};
|
||||||
|
*/
|
||||||
memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
|
memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
|
@ -1284,23 +1320,11 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
|
||||||
int CmdHFiClass_loclass(const char *Cmd) {
|
int CmdHFiClass_loclass(const char *Cmd) {
|
||||||
char opt = param_getchar(Cmd, 0);
|
char opt = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
if (strlen(Cmd)<1 || opt == 'h') {
|
if (strlen(Cmd)<1 || opt == 'h')
|
||||||
PrintAndLog("Usage: hf iclass loclass [options]");
|
usage_hf_iclass_loclass();
|
||||||
PrintAndLog("Options:");
|
|
||||||
PrintAndLog("h Show this help");
|
|
||||||
PrintAndLog("t Perform self-test");
|
|
||||||
PrintAndLog("f <filename> Bruteforce iclass dumpfile");
|
|
||||||
PrintAndLog(" An iclass dumpfile is assumed to consist of an arbitrary number of");
|
|
||||||
PrintAndLog(" malicious CSNs, and their protocol responses");
|
|
||||||
PrintAndLog(" The binary format of the file is expected to be as follows: ");
|
|
||||||
PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
|
|
||||||
PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
|
|
||||||
PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
|
|
||||||
PrintAndLog(" ... totalling N*24 bytes");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
char fileName[FILE_PATH_SIZE] = {0};
|
char fileName[FILE_PATH_SIZE] = {0};
|
||||||
if(opt == 'f') {
|
if (opt == 'f') {
|
||||||
if(param_getstr(Cmd, 1, fileName) > 0) {
|
if(param_getstr(Cmd, 1, fileName) > 0) {
|
||||||
return bruteforceFileNoKeys(fileName);
|
return bruteforceFileNoKeys(fileName);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1308,7 +1332,7 @@ int CmdHFiClass_loclass(const char *Cmd) {
|
||||||
// no return?
|
// no return?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(opt == 't') {
|
else if (opt == 't') {
|
||||||
int errors = testCipherUtils();
|
int errors = testCipherUtils();
|
||||||
errors += testMAC();
|
errors += testMAC();
|
||||||
errors += doKeyTests(0);
|
errors += doKeyTests(0);
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "elite_crack.h"
|
#include "elite_crack.h"
|
||||||
|
|
||||||
void calc_score(uint8_t* csn, uint8_t* k)
|
void calc_score(uint8_t* csn, uint8_t* k) {
|
||||||
{
|
|
||||||
uint8_t score =0 ;
|
uint8_t score =0 ;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
uint8_t goodvals[16] = {0};
|
uint8_t goodvals[16] = {0};
|
||||||
|
@ -17,64 +16,58 @@ void calc_score(uint8_t* csn, uint8_t* k)
|
||||||
memset(uniq_vals, 0x00, 8);
|
memset(uniq_vals, 0x00, 8);
|
||||||
uint8_t badval = 0;
|
uint8_t badval = 0;
|
||||||
int badscore =0;
|
int badscore =0;
|
||||||
for(i=0; i < 8 ; i++)
|
for ( i=0; i < 8 ; i++) {
|
||||||
{
|
if (k[i] == 0x01) continue;
|
||||||
if(k[i] == 0x01) continue;
|
if (k[i] == 0x00) continue;
|
||||||
if(k[i] == 0x00) continue;
|
if (k[i] == 0x45) continue;
|
||||||
if(k[i] == 0x45) continue;
|
if (k[i] < 16){
|
||||||
if(k[i] < 16){
|
|
||||||
goodvals[k[i]] = 1;
|
goodvals[k[i]] = 1;
|
||||||
}
|
}
|
||||||
// if(k[i] ==9 || k[i]==2){
|
// if(k[i] ==9 || k[i]==2){
|
||||||
// goodvals[k[i]] = 1;
|
// goodvals[k[i]] = 1;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
else if(k[i]>=16){
|
else if (k[i]>=16){
|
||||||
badscore++;
|
badscore++;
|
||||||
badval = k[i];
|
badval = k[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(i =0; i < 16; i++)
|
for (i =0; i < 16; i++) {
|
||||||
{
|
if (goodvals[i]) {
|
||||||
if(goodvals[i])
|
|
||||||
{
|
|
||||||
uniq_vals[score] = i;
|
uniq_vals[score] = i;
|
||||||
score +=1;
|
score +=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(score >=2 && badscore < 2)
|
|
||||||
{
|
if (score >=2 && badscore < 2) {
|
||||||
printf("CSN\t%02x%02x%02x%02x%02x%02x%02x%02x\t%02x %02x %02x %02x %02x %02x %02x %02x\t"
|
printf("CSN\t%02x%02x%02x%02x%02x%02x%02x%02x\t%02x %02x %02x %02x %02x %02x %02x %02x\t"
|
||||||
,csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]
|
,csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]
|
||||||
,k[0],k[1],k[2],k[3],k[4],k[5],k[6],k[7]
|
,k[0],k[1],k[2],k[3],k[4],k[5],k[6],k[7]
|
||||||
);
|
);
|
||||||
for(i =0 ; i < score; i++)
|
|
||||||
{
|
for (i=0 ; i < score; i++) {
|
||||||
printf("%d,", uniq_vals[i]);
|
printf("%d,", uniq_vals[i]);
|
||||||
}
|
}
|
||||||
printf("\tbadscore: %d (%02x)", badscore, badval);
|
printf("\tbadscore: %d (%02x)", badscore, badval);
|
||||||
printf("\r\n");
|
printf("\r\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void brute_hash1(){
|
void brute_hash1(void){
|
||||||
|
uint16_t a,b,c,d;
|
||||||
uint8_t csn[8] = {0,0,0,0,0xf7,0xff,0x12,0xe0};
|
uint8_t csn[8] = {0,0,0,0,0xf7,0xff,0x12,0xe0};
|
||||||
uint8_t k[8]= {0,0,0,0,0,0,0,0};
|
uint8_t k[8]= {0,0,0,0,0,0,0,0};
|
||||||
uint16_t a,b,c,d;
|
uint8_t testcsn[8] = {0x00,0x0d,0x0f,0xfd,0xf7,0xff,0x12,0xe0} ;
|
||||||
uint8_t testcsn[8] ={0x00,0x0d,0x0f,0xfd,0xf7,0xff,0x12,0xe0} ;
|
uint8_t testkey[8] = {0x05 ,0x01 ,0x00 ,0x10 ,0x45 ,0x08 ,0x45,0x56} ;
|
||||||
uint8_t testkey[8] ={0x05 ,0x01 ,0x00 ,0x10 ,0x45 ,0x08 ,0x45,0x56} ;
|
|
||||||
calc_score(testcsn,testkey);
|
calc_score(testcsn,testkey);
|
||||||
printf("Brute forcing hashones\n");
|
printf("Brute forcing hashones\n");
|
||||||
//exit(1);
|
//exit(1);
|
||||||
for(a=0;a < 256;a++)
|
|
||||||
{
|
for (a=0; a < 256; a++) {
|
||||||
//if(a > 0)printf("%d/256 done...\n", a);
|
//if(a > 0)printf("%d/256 done...\n", a);
|
||||||
for(b=0;b < 256 ; b++)
|
for (b=0; b < 256; b++)
|
||||||
for(c=0;c < 256;c++)
|
for (c=0; c < 256; c++)
|
||||||
for(d=0;d < 256;d++)
|
for (d=0; d < 256; d++) {
|
||||||
{
|
|
||||||
csn[0] = a;
|
csn[0] = a;
|
||||||
csn[1] = b;
|
csn[1] = b;
|
||||||
csn[2] = c;
|
csn[2] = c;
|
||||||
|
@ -87,6 +80,5 @@ void brute_hash1(){
|
||||||
calc_score(csn,k);
|
calc_score(csn,k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef HASH1_BRUTE_H
|
#ifndef HASH1_BRUTE_H
|
||||||
#define HASH1_BRUTE_H
|
#define HASH1_BRUTE_H
|
||||||
void brute_hash1();
|
extern void brute_hash1();
|
||||||
|
|
||||||
#endif // HASH1_BRUTE_H
|
#endif // HASH1_BRUTE_H
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue