All streams
Search
Write a publication
Pull to refresh
271
0.1
Send message
BCM это просто продвинутый блок предохранителей.
Не уверен, что именно этот компонент может быть обновлен, хотя туда и ставят достаточно производительные чипы, но лепить возможность обновления на этот критичный блок системы не самая лучшая идея.
Затаив дыхание, я поднимался по чугунной лестнице. Принято считать, что если, поднимаясь по лестнице Ротонды, закрыть глаза, то никогда не дойдешь до конца… Всё это, конечно, сказки, но атмосфера загадочности здесь действительно будто бы витала в воздухе. Я любил подняться до ротондовского тупичка, своего рода, лестничной площадки, и сидеть там, поворачиваясь так и сяк – вдруг и правда удастся увидеть тень от несуществующей, седьмой колонны?

Похоже, не так давно кто-то уже успел здесь побывать… На площадке лежала дискета. Не валялась, а именно лежала, чистая – ни пылинки! Как будто кто-то незадолго до моего прихода ее здесь бережно положил. Почему-то я сразу вспомнил незнакомца в черном. Брать чужие вещи, конечно, нельзя, но я как чувствовал: мне надо знать, что на этой дискете!

Дома, едва скинув куртку и ботинки, я уселся за компьютер. Скачивание и настройка эмулятора флоппи-дисковода заняли минут 15, и вот передо мной уже образ дискеты…
km и запятые не самое плохое что есть/было в тексте. Глаз больше цеплялся за раздельные «не» и «на» там, где это явно не нужно.
Перечитывать текст не очень охота, но вот, к примеру — «свет (на сколько».
Да и какие-то странные игры с дефисом («какой- то» «какой — нибудь»).
Запятые иногда лишние («аппарата «Новые Горизонты», который, был сделан им»).
Вводные слова частенько не выделяются («К сожалению вставить сюда»).

И это еще что бросилось в глаза мне, совсем не граммар-наци, а, скорее, наоборот.

Было бы это парой ошибок, то легко можно было бы через личку сообщить, но здесь же их десятки.
Я пошёл путём статического анализа, после того, как сдампил расшифрованный кусок.
Ну и изредка gdb для проверок того, что всё верно понял (автоматом архитектура не менялась и сыпались ошибки, поэтому через несколько бряков пришлось работать):
Скрипт GDB
target remote localhost:1234
display/3i $pc
hbreak *0x04000148
break *0x200318
set arch i386:x86-64
break *0xFFFFF80000204E19 if $rdx == 12*0x18

Мнемоники инструкций ВМ даже не проверял, работу смотрел непосредственно в хэндлерах. Набросал скрипт который дизассемблит байт-код, даже интерпретатор влепил на всякий случай.
Скрипт дизассемблера
<?php

$code =
[
    [0x633272, '0x7233', '0x1505'],
...
    [0x726574, 0, 0]
];

$regs = [];

$regMap =
[
    0x7230 => 'r0',   // +0x0  PASSWORD
    0x7231 => 'r1',   // +0x8
    0x7232 => 'r2',   // +0x10
    0x7233 => 'r3',   // +0x18
    0x7234 => 'r4',   // +0x20 PASSWORD
    0x7235 => 'r5',   // +0x28
    0 => 'pc',        // +0x30
    0x726573 => 'r6', // +0x38
    0x727362 => 'r7'  // +0x40
];

function getByte($ptr)
{
    return 0;
}

function getVMRegister($reg)
{
    global $regMap;
    return $regMap[$reg];
}

function setVMRegister($reg, $value)
{
    global $regMap;
    $regMap[$reg] = $value;
}

$opcodes =
[
    0x726574 =>
    [
        'pc = r7',
        function ($arg1, $arg2) use ($regs)
        {
            $regs['pc'] = $regs['r7'];
            return 0;
        }
    ],
    0x69667A =>
    [
        'pc += (reg[$arg1] != 0) ? 1 : $arg2',
        function ($arg1, $arg2) use ($regs)
        {
            $reg = getVMRegister($arg1);
            $regs['pc'] += $reg ? 0x18 : $arg2 * 0x18;
            return 0;
        }
    ],
    0x616464 =>
    [
        'reg[$arg1] += reg[$arg2]',
        function ($arg1, $arg2) use ($regs)
        {
            setVMRegister($arg1, getVMRegister($arg1) + getVMRegister($arg2));
            $regs['pc'] += 0x18;
            return 0;
        }
    ],
    0x633272 =>
    [
        'reg[$arg1] = $arg2',
        function ($arg1, $arg2) use ($regs)
        {
            setVMRegister($arg1, $arg2);
            $regs['pc'] += 0x18;
            return 0;
        }
    ],
    0x6A6D70 =>
    [
        'pc += $arg1',
        function ($arg1, $arg2) use ($regs)
        {
            $regs['pc'] += $arg1 * 0x18;
            return 0;
        }
    ],
    0x723272 =>
    [
        'reg[$arg1] = reg[$arg2]',
        function ($arg1, $arg2) use ($regs)
        {
            setVMRegister($arg1, getVMRegister($arg2));
            $regs['pc'] += 0x18;
            return 0;
        }
    ],
    0x65786974 =>
    [
        'r6 = $arg1, exit from VM',
        function ($arg1, $arg2) use ($regs)
        {
            setVMRegister(0x726573, $arg1);
            return 0;
        }
    ],
    0x737562 =>
    [
        'reg[$arg1] -= reg[$arg2]',
        function ($arg1, $arg2) use ($regs)
        {
            setVMRegister($arg1, getVMRegister($arg1) - getVMRegister($arg2));
            $regs['pc'] += 0x18;
            return 0;
        }
    ],
    0x63616C6C =>
    [
        'r7 = pc + 1, pc += $arg1',
        function ($arg1, $arg2) use ($regs)
        {
            $regs['r7'] = $regs['pc'] + 0x18;
            $regs['pc'] += $arg1 * 0x18;
            return 0;
        }
    ],
    0x6D623272 =>
    [
        'reg[$arg1] = *(byte *)reg[$arg2]',
        function ($arg1, $arg2) use ($regs)
        {
            setVMRegister($arg1, getByte(getVMRegister($arg2)));
            $regs['pc'] += 0x18;
            return 0;
        }
    ],
    0x73686674 =>
    [
        'reg[$arg1] = $arg2 > 0 ? reg[$arg1] >> $arg2 : reg[$arg1] << -$arg2',
        function ($arg1, $arg2) use ($regs)
        {
            $reg = getVMRegister($arg1);
            setVMRegister($arg1, ($arg2 >= 0) ? $reg >> $arg2 : $reg << -$arg2);
            $regs['pc'] += 0x18;
            return 0;
        }
    ],
];

$pc = 0;
foreach ($code as $command)
{
    if (!isset($opcodes[$command[0]]))
    {
        echo "Unknown opcode, PC = $pc\n";
        break;
    }
    $cmd = $opcodes[$command[0]][0];
    $arg1 = $command[1];
    $arg2 = $command[2];

    if (isset($regMap[hexdec(substr($arg1, 2))]))
        $cmd = str_replace('reg[$arg1]', $regMap[hexdec(substr($arg1, 2))], $cmd);
    if (isset($regMap[hexdec(substr($arg2, 2))]))
        $cmd = str_replace('reg[$arg2]', $regMap[hexdec(substr($arg2, 2))], $cmd);

    if (preg_match('/0x0FFFFFFFFFFFFFF([0-9A-F]{1,2})/', $arg1, $matches))
        $arg1 = -(pow(16, strlen($matches[1])) - hexdec($matches[1]));
    if (preg_match('/0x0FFFFFFFFFFFFFF([0-9A-F]{1,2})/', $arg2, $matches))
        $arg2 = -(pow(16, strlen($matches[1])) - hexdec($matches[1]));
    $cmd = str_replace('$arg1', $arg1, $cmd);
    $cmd = str_replace('$arg2', $arg2, $cmd);

    echo '[' . str_pad($pc, 3, '0', STR_PAD_LEFT) . '] ' . $cmd . "\n";
    $pc++;
}


Результат:
Байткод
[000] r3 = 0x1505
[001] r1 = *(byte *)r0
[002] pc += (r1 != 0) ? 1 : 8
[003] r2 = r3
[004] r3 = -5 > 0 ? r3 >> -5 : r3 << --5
[005] r3 += r2
[006] r3 += r1
[007] r2 = 1
[008] r0 += r2
[009] pc += -8
[010] r2 = 0x40E1BAA8FF648029
[011] r3 -= r2
[012] pc += (r3 != 0) ? 1 : 2
[013] r6 = 0, exit from VM
[014] r7 = pc + 1, pc += 0x1F
[015] r5 = r3
[016] r7 = pc + 1, pc += 0x1D
[017] r2 = r5
[018] r2 -= r3
[019] r1 = 0x2A60386296A57940
[020] r2 -= r1
[021] pc += (r2 != 0) ? 1 : 2
[022] r6 = 0, exit from VM
[023] r2 = r3
[024] r2 = 0x20 > 0 ? r2 >> 0x20 : r2 << -0x20
[025] r1 = r3
[026] r1 = -32 > 0 ? r1 >> -32 : r1 << --32
[027] r1 = 0x20 > 0 ? r1 >> 0x20 : r1 << -0x20
[028] r2 -= r1
[029] r0 = 0x3394749A
[030] r2 -= r0
[031] pc += (r2 != 0) ? 1 : 2
[032] r6 = 0, exit from VM
[033] r2 = r3
[034] r2 = -32 > 0 ? r2 >> -32 : r2 << --32
[035] r2 = 0x30 > 0 ? r2 >> 0x30 : r2 << -0x30
[036] r1 = r3
[037] r1 = -48 > 0 ? r1 >> -48 : r1 << --48
[038] r1 = 0x30 > 0 ? r1 >> 0x30 : r1 << -0x30
[039] r2 -= r1
[040] r0 = 0x465E
[041] r2 -= r0
[042] pc += (r2 != 0) ? 1 : 2
[043] r6 = 0, exit from VM
[044] r6 = 1, exit from VM
[045] r3 = 0
[046] r0 = 0
[047] r2 = 0x10
[048] r0 -= r2
[049] pc += (r0 != 0) ? 1 : 2
[050] pc += 2
[051] pc = r7
[052] r0 += r2
[053] r1 = *(byte *)r4
[054] r2 = 0x61
[055] r1 -= r2
[056] pc += (r1 != 0) ? 1 : 2
[057] pc += 8
[058] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[059] r2 = 0x0A
[060] r3 += r2
[061] r2 = 1
[062] r4 += r2
[063] r0 += r2
[064] pc += -17
[065] r1 = *(byte *)r4
[066] r2 = 0x62
[067] r1 -= r2
[068] pc += (r1 != 0) ? 1 : 2
[069] pc += 8
[070] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[071] r2 = 0x0B
[072] r3 += r2
[073] r2 = 1
[074] r4 += r2
[075] r0 += r2
[076] pc += -12
[077] r1 = *(byte *)r4
[078] r2 = 0x63
[079] r1 -= r2
[080] pc += (r1 != 0) ? 1 : 2
[081] pc += 8
[082] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[083] r2 = 0x0C
[084] r3 += r2
[085] r2 = 1
[086] r4 += r2
[087] r0 += r2
[088] pc += -12
[089] r1 = *(byte *)r4
[090] r2 = 0x64
[091] r1 -= r2
[092] pc += (r1 != 0) ? 1 : 2
[093] pc += 8
[094] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[095] r2 = 0x0D
[096] r3 += r2
[097] r2 = 1
[098] r4 += r2
[099] r0 += r2
[100] pc += -12
[101] r1 = *(byte *)r4
[102] r2 = 0x65
[103] r1 -= r2
[104] pc += (r1 != 0) ? 1 : 2
[105] pc += 8
[106] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[107] r2 = 0x0E
[108] r3 += r2
[109] r2 = 1
[110] r4 += r2
[111] r0 += r2
[112] pc += -12
[113] r1 = *(byte *)r4
[114] r2 = 0x66
[115] r1 -= r2
[116] pc += (r1 != 0) ? 1 : 2
[117] pc += 8
[118] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[119] r2 = 0x0F
[120] r3 += r2
[121] r2 = 1
[122] r4 += r2
[123] r0 += r2
[124] pc += -12
[125] r1 = *(byte *)r4
[126] r2 = 0x30
[127] r1 -= r2
[128] pc += (r1 != 0) ? 1 : 2
[129] pc += 8
[130] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[131] r2 = 0
[132] r3 += r2
[133] r2 = 1
[134] r4 += r2
[135] r0 += r2
[136] pc += -12
[137] r1 = *(byte *)r4
[138] r2 = 0x31
[139] r1 -= r2
[140] pc += (r1 != 0) ? 1 : 2
[141] pc += 8
[142] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[143] r2 = 1
[144] r3 += r2
[145] r2 = 1
[146] r4 += r2
[147] r0 += r2
[148] pc += -12
[149] r1 = *(byte *)r4
[150] r2 = 0x32
[151] r1 -= r2
[152] pc += (r1 != 0) ? 1 : 2
[153] pc += 8
[154] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[155] r2 = 2
[156] r3 += r2
[157] r2 = 1
[158] r4 += r2
[159] r0 += r2
[160] pc += -12
[161] r1 = *(byte *)r4
[162] r2 = 0x33
[163] r1 -= r2
[164] pc += (r1 != 0) ? 1 : 2
[165] pc += 8
[166] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[167] r2 = 3
[168] r3 += r2
[169] r2 = 1
[170] r4 += r2
[171] r0 += r2
[172] pc += -12
[173] r1 = *(byte *)r4
[174] r2 = 0x34
[175] r1 -= r2
[176] pc += (r1 != 0) ? 1 : 2
[177] pc += 8
[178] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[179] r2 = 4
[180] r3 += r2
[181] r2 = 1
[182] r4 += r2
[183] r0 += r2
[184] pc += -12
[185] r1 = *(byte *)r4
[186] r2 = 0x35
[187] r1 -= r2
[188] pc += (r1 != 0) ? 1 : 2
[189] pc += 8
[190] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[191] r2 = 5
[192] r3 += r2
[193] r2 = 1
[194] r4 += r2
[195] r0 += r2
[196] pc += -12
[197] r1 = *(byte *)r4
[198] r2 = 0x36
[199] r1 -= r2
[200] pc += (r1 != 0) ? 1 : 2
[201] pc += 8
[202] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[203] r2 = 6
[204] r3 += r2
[205] r2 = 1
[206] r4 += r2
[207] r0 += r2
[208] pc += -12
[209] r1 = *(byte *)r4
[210] r2 = 0x37
[211] r1 -= r2
[212] pc += (r1 != 0) ? 1 : 2
[213] pc += 8
[214] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[215] r2 = 7
[216] r3 += r2
[217] r2 = 1
[218] r4 += r2
[219] r0 += r2
[220] pc += -12
[221] r1 = *(byte *)r4
[222] r2 = 0x38
[223] r1 -= r2
[224] pc += (r1 != 0) ? 1 : 2
[225] pc += 8
[226] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[227] r2 = 8
[228] r3 += r2
[229] r2 = 1
[230] r4 += r2
[231] r0 += r2
[232] pc += -12
[233] r1 = *(byte *)r4
[234] r2 = 0x39
[235] r1 -= r2
[236] pc += (r1 != 0) ? 1 : 2
[237] pc += 8
[238] r3 = -4 > 0 ? r3 >> -4 : r3 << --4
[239] r2 = 9
[240] r3 += r2
[241] r2 = 1
[242] r4 += r2
[243] r0 += r2
[244] pc += -12
[245] pc = r7 



Причёсанный код:
Вменяемый байт-код
r0 = r4 = password
r3 = 0x1505
while (r1 = *(byte *)r0)
  r3 = (r3 << 5) + r3 + r1
  r0++;
if (r3 != 0x40E1BAA8FF648029) return 0;

function 45
r5 = r3
function 45
if (r5 - r3 != 0x2A60386296A57940) return 0;
r2 = (r3 >> 32) - (r3 << 32) >> 32  # r2 = r3 [4..7] - r3 [0..3]
if (r2 != 0x3394749A) return 0;
r2 = (r3 << 32) >> 48 # r2 = r3 [2..3]
r1 = (r3 << 48) >> 48 # r1 = r3 [0..1]
return (r2 - r1 == 0x465E)

function 45:
  r3 = 0, r0 = 0
  while (r0 != 0x10)
    r1 = *(byte *)r4
    if (r1 >= 0x61 && t1 <= 0x66)
      r3 = r3 << 4 + (0x0A + (r1 - 0x61))
      r4++, r0++
      continue;
    if (r1 >= 0x30 && r1 <= 0x39)
      r3 = r3 << 4 + (r1 - 0x30)
      r4++, r0++
      continue



Кейген:
Скрытый текст
for i in range(0, 65536):
  word2 = (0x465E + i) & 0xFFFF
  dword1 = (word2 << 16) + i
  dword2 = (dword1 + 0x3394749A) & 0xFFFFFFFF
  qword2 = (dword2 << 32) + dword1
  qword1 = (qword2 + 0x2A60386296A57940) & 0xFFFFFFFFFFFFFFFF
  str = format(qword1, 'x') + format(qword2, 'x')
#  print hex(i) + ': ' + str
  r3 = 0x1505
  for c in str:
    r3 = ((r3 << 5) + r3 + ord(c)) & 0xFFFFFFFFFFFFFFFF
  if r3 == 0x40E1BAA8FF648029:
    print str
    break

Веселое задание, как жаль, что я его не видел. Тем более SPARC мне знаком.
Как можно было узнать о нём?
PS: у необита тоже был реверс кода для sparc'ов. Правда, там уже совсем всё просто.
> Все верно – внутри нет платы
И это здорово. Я прокладываю обычно скрытую проводку к регистратору от блока предохранителей или просто от прикуривателя (оставляя сам сокет свободным, конечно же). И меня очень радует, что не нужно париться с платой питания.
> Если вы пробовали снять его со стекла, то знаете – сделать это руками без вспомогательных инструментов невозможно
BlackVue первый раз снимал руками (от родного скотча). Просто вращательные движения. А вот уже от отдельно купленного 3M-скотча в следующий раз пришлось использовать лезвие.

В целом убедительно видно превосходство DataKam, на одну из машин его и поставлю, несмотря на предстаящую возню с питанием
Кастомы не такая уж и редкость. На те же субари частенько делают.
С завода есть, называется twincharger. Но их очень мало. Меньше даже чем с компрессором.
Да и машинки с этой технологией не особо интересны. Малолитражки.
Единственная русская аббревиатура (ВСУ) малось цепляет взгляд.
Тем более дальше используется англоязычный термин — APU.
> Путем простого перебора выясняем, что логин: root, а пароль 123456. Не очень-то все безопасно настроено, не так ли?
Single-mode в солярке не работает как ожидается (всё равно требует root-пароля), но зато можно загрузиться с CD и как обычно — mount / chroot / passwd.

> Такой путь требует много времени на изучение кода на относительно экзотической архитектуре sparc
У меня это заняло примерно полчаса :)
Большая часть времени ушла на поднятие и изучение виртуалки (причём это мне совершенно не помогло в решении этой задачи) + подбор логина.

> есть на Solaris 2.6 FTP клиент ftp, с помощью которого можно обмениваться файлами Windows с Solaris
OpenSSH наше всё ;)

Вообще мне показалось задание достаточно простым, ибо на реверс, и было очень очевидно что нужно делать.
Угу, мало их.
Из того, что сам видел — Audi S4 и Ягуары XF/XJ.
Ну и знаю еще про пачку спорт/супер-каров, типа корветта
«Вот чего я сейчас не понимаю, так это почему так мало компрессорных машин :(»
Ну там по движку смотреть надо. SLK230 есть 2 модификации с немного различными модификациями двигателя (M111).
> Вот тут как раз вам «ип» :)
www.zeroto60times.com/vehicle-make/mercedes-0-60-mph-times
Для M111.973 L4 — 6.8 для 0-60mph, то есть не более 6.9 для 0-62mph.
M111.983 L4 малость помощнее, так что выдаст чистые 6.8

> После замеров на нормальной телеметрии результат обычно сильно удивляет в неприятную сторону
Вполне возможно, но я всё-таки более-менее четко измерял раз со спеками совпадает.
Закажу конвертер/провод для DLC (он там круглый, 16-контактный OBDII) — чекну.
> По спекам стоковый выдаёт 7.0, емнип
Чекнул, 6.8, однако. Так что замеренные 6.5 довольно близки даже к стоку ;)
> Какой вес был у автомобиля?
Стандартный. ~1450kg.
Из читерства разве что слики были ;)
> Секундомером мерили? :)
Раскадровка GoPro. Не весть что, конечно, но лучше чем «один два три».
> upd: посмотрел спеки, 7,7 до сотки у вашего авто, абсолютно вменяемый результат
По спекам стоковый выдаёт 7.0, емнип.
> И 2jz 5 сек до сотни с 300hp не выдаст.
Ну сам ездил, помню еще. Погуглил, вот к примеру — www.drive2.ru/r/toyota/963718

PS: На следующей неделе драг-битва, там похожу-поспрашиваю кто сколько ездит.
SLK 230. Для города выбирал по внешнему виду / удобству, а не по характеристикам, поэтому возможно не самый эффективный вариант, да.
Драйв в чём? Я взял для города не особо жрущую машину, всего 200hp / 2.3L, но тем не менее, 6.5с 0-100 для меня по драйву вполне сравнимы с 5с, которые выдавал 2jz 300hp.
Конечно, 500hp+ это уже другой разговор, вот там драйв, так драйв. Сам не владел, но 402 метра ездил.
Вот чего я сейчас не понимаю, так это почему так мало компрессорных машин :(
Я много катался на турбированных машинах (скайлайны. чейзер, марки — 1/2jz, даже tt-шка).
Но сейчас по городу катаюсь на компрессорной машинке, и не нарадуюсь — никакого турболага, отличная тяга и при низких оборотах (иногда даже балуюсь ручным переключением передач вместо автомата), обслуживания вообще не требует. Сколько я парился с этими турбинами, брр.
Конечно, для автогонок только турбо, но мы же говорим про город/трассу?
У меня так и получилось :)
G27 на антресолях.
Правда мне до кольца всего 15 минут езды, поэтому заезжаю иногда, катаюсь.
Тем более машинка позволяет.
Ну почему же, если орбита стабильна, то можно три раза изменить положение розетты и замерить уровень сигнала. Затем провести как раз триангуляцию.
Только я не уверен что топлива / точности измерения хватит на это.

Information

Rating
3,018-th
Location
Красноярск, Красноярский край, Россия
Registered
Activity