воскресенье, 31 июля 2011 г.

Конкурс от журнала ПРОграммист. Проверка пароля

Беру следующий кусок кода:

loc_8E90:
move.w #$10,d1 ; d1 = 16
bsr.w sub_93AA ;вызов подпрограммы
sub_93AA:
clr.w d0 ;d0 = 0
subq.w #1,d1 ;d1 = d1 - 1
loc_93AE:
asl $7742(a4) ;подпрограмма сдвигает 2 старших байта пароля
roxl $7740(a4) ;приведенного по таблице к 5-битовым значениям
roxl $773E(a4) ;и 2 младших байта пароля записывает в регистр d0
roxl $773C(a4) ;
roxl.w #1,d0 ;
dbf d1,loc_93AE ; повторить 16 раз
move.w d0,$3A56(a4) ;записать по адресу в память 2 младших знака пароля
bsr.w sub_9372 ;вызов подпрограммы
move.w $773C(a4),d0 ;подпрограмма складывает между собой по модулю 2
move.w $773E(a4),d1 ;символы пароля, приведенные по
eor.w d1,d0 ; таблице к 5-битовым значениям
eor.w d1,d0 ;
move.w $7742(a4),d1 ;мне кажется, что здесь должен быть 0
eor.w d1,d0 ;и прибавляет к ним число 0x6573
eori.w #$6573,d0 ;
rts
cmp.w $3A56(a4),d0 ;результат подпрограммы сравнивается с младшими байтами пароля
bne.s loc_8EB0

Таким образом, у нас есть 4 слова пароля.
W1 W2 W3 W4

Должно выполняться условие
W1 = W2 W3 W4 0x6573

Чтобы проверить - напишу тестовую программу, которая будет генерировать правильный пароль. W2, W2, W3 будут выбираться случайным образом. W1 будет получаться из формулы выше.

Функция генерации выглядит так:

Password GeneratePassword()
{
Password result;
unsigned short W1 = rand()%0xFFFF ;
unsigned short W2 = rand()%0xFFFF ^ 0x56B2;
unsigned short W3 = rand()%0xFFFF ^ 0xB2Eb;
unsigned short W4 = (rand()%0xFFFF) & 0xFFF0 ^ 0xB200;
W1 = W2 ^ W3 ^ W4 ^ 0x6573;
W1 = W1 ^ 0xB29A;
W2 = W2 ^ 0x56B2;
W3 = W3 ^ 0xB2Eb;
W4 = W4 ^ 0xB200;
memcpy(&result,&W4,2);
memcpy((long*)(((long)&result)+2),&W3,2);
memcpy((long*)(((long)&result)+4),&W2,2);
memcpy((long*)(((long)&result)+6),&W1,2);
return result;
}

И она работает! Теперь осталось отследить какие символы пароля оказывают влияние на игру

1 комментарий: