Ру-сфера загнулась?

Тема в разделе "WASM.HEAP", создана пользователем _edge, 13 фев 2018.

  1. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    527
    X-Shar, не хотите потестировать вашу локальную модель qwen3, на СИ коде средней сложности. Просто любопытно, справится или нет. Если конечно, у вас есть на это время. А в коде нужно найти и устранить логическую ошибку. Сам код компилируется и работает, но некорректно (криво).

    Если что, код здесь: https://github.com/XXXRef/DisASM
     
  2. X-Shar

    X-Shar Active Member

    Публикаций:
    0
    Регистрация:
    24 фев 2017
    Сообщения:
    358
    Давай попробуем, а что нужно сделать, запустить на сервере просто ?

    А отличие от обычной qwen3, зачем самим собирать ?

    Я не против потестить.)
    --- Сообщение объединено, 24 июл 2026 в 15:02 ---
    Ну и у меня если-что графика с 24 гигов, больше нет возможностей, это учитывать надо.
    Если модель не влезет, то не получится...
    --- Сообщение объединено, 24 июл 2026 в 15:04 ---
    А-ты хочешь постестить код:
    https://github.com/XXXRef/DisASM

    Я думал ты хочешь свою модель потестить, сорян...

    Криво прочитал.

    Да, давай потестим...
     
  3. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    527
    X-Shar нравится это.
  4. X-Shar

    X-Shar Active Member

    Публикаций:
    0
    Регистрация:
    24 фев 2017
    Сообщения:
    358
    GRAFik для сравнения спросил у трех нейронок.

    Вопрос у всех один:

    ### USER
    Во вложении код, расскажи что он делает, в нём логическая ошибка, как можно поправить ?

    Спросил у zer0kernel (По сути это почти дефолтный Qwen3 Coder, Kimi 2.6 и у меня еще ChatGPT 5.5 с высоким уровнем рассуждения).

    Вот результаты.

    Все нейронки указали на разные ошибки.)

    Лучше всего проанализировал GPT как по мне...
    Но там модель с рассуждением.

    ### USER
    Во вложении код, расскажи что он делает, в нём логическая ошибка, как можно поправить ?
    ### ASSISTANT
    Код, представленный в приложении, написан на языке C и, судя по структуре, предназначен для анализа или декодирования инструкций x86-ассемблера. Он включает в себя логику обработки параметров операндов, выделения памяти и взаимодействия с файлами. Ниже приведено пошаговое описание функциональности и указание на возможную логическую ошибку.
    ---
    ### Описание функциональности
    #### 1. **Меняет местами параметры**
    ```c
    if(cp->par[1]!='i'){
    buf=cp->par[1];
    cp->par[1]=cp->par[0];
    cp->par[0]=buf;
    }
    ```
    Этот фрагмент меняет местами два параметра (`cp->par[0]` и `cp->par[1]`), если второй параметр не равен `'i'`. Это может быть частью логики обработки операндов, где порядок параметров важен.
    #### 2. **Выделение памяти для массива параметров**
    ```c
    cp->parameters=(char**)malloc(sizeof(char*)*(cp->par_count));
    ext_len=0;
    while(ext_len<cp->par_count){
    cp->parameters[ext_len]=(char*)malloc(40);
    ext_len++;
    }
    ```
    Здесь выделяется память для массива указателей на строки (`cp->parameters`) и для каждой строки выделяется 40 байт. Это может быть связано с хранением строковых представлений операндов.
    #### 3. **Обработка операндов**
    ```c
    switch(cp->par[counter]){
    case 'r': // регистр
    ...
    case '1': // константа 1
    cp->parameters[counter][0]='1';
    cp->parameters[counter][1]=0;
    break;
    case 'a': // al, ax, eax
    ...
    ```
    В этом фрагменте происходит обработка различных типов операндов, таких как регистры (`'r'`) и специальные значения (`'1'`, `'a'`). Например, если встречается `'a'`, то в зависимости от флага `w` записывается `al`, `ax` или `eax`.
    #### 4. **Функция `CharEnter()`**
    ```c
    char*CharEnter(){
    char*res=NULL;
    int i=0;
    do{
    i++;
    res=(char*)realloc(res,i);
    res[i-1]=(char)getchar();
    }while(res[i-1]!='\n');
    res[i-1]=0;
    return res;
    }
    ```
    Функция читает строку с клавиатуры до символа новой строки (`'\n'`) и возвращает её. Она используется для ввода данных пользователем.
    #### 5. **Поиск секции кода**
    ```c
    IMAGE_SECTION_HEADER findCodeSection(FILE* hFile) {
    // TODO: реализация поиска секции кода
    }
    ```
    Функция предназначена для поиска секции кода в PE-файле по значению `AddressOfEntryPoint`, но пока не реализована полностью.
    ---
    ### Возможная логическая ошибка
    #### Вопрос: Какая логическая ошибка может быть в коде?
    Одна из потенциальных проблем — **неправильное управление памятью**, особенно в части выделения и освобождения памяти. В следующем фрагменте:
    ```c
    free(cp->parameters[0]);
    cp->parameters[0]=temp_char1;
    break;
    ```
    Если `temp_char1` — это указатель на строку, выделенную через `malloc`, и `cp->parameters[0]` ранее был выделен через `malloc`, то может возникнуть **двойное освобождение памяти**, если `temp_char1` указывает на ту же область, что и `cp->parameters[0]`.
    Также, если `temp_char1` — это строка, выделенная через `malloc`, но не инициализирована корректно, это может привести к **непредсказуемому поведению**.
    ---
    ### Как можно исправить
    1. **Проверка на дублирование указателей**:
    Перед вызовом `free(cp->parameters[0])` необходимо убедиться, что `cp->parameters[0]` не совпадает с `temp_char1`.
    2. **Инициализация `temp_char1`**:
    Убедиться, что `temp_char1` корректно инициализирована и не указывает на освобожденную память.
    3. **Использование `strdup` вместо `malloc` + `strcpy`**:
    Если `temp_char1` — это строка, лучше использовать `strdup`, чтобы избежать ошибок при копировании.
    Пример исправления:
    ```c
    free(cp->parameters[0]);
    cp->parameters[0] = strdup(temp_char1); // безопасное копирование строки
    ```
    ---
    ### Заключение
    Код представляет собой часть программы, которая анализирует x86-инструкции и обрабатывает их операнды. В нем есть потенциальная ошибка, связанная с неправильным управлением памятью, особенно при освобождении и переназначении указателей. Для исправления следует добавить проверки на дублирование указателей и корректную работу с динамически выделенной памятью.
    Если нужно, могу помочь с более подробным анализом конкретных участков кода.

    ### USER
    Во вложении код, расскажи что он делает, в нём логическая ошибка, как можно поправить ?
    ### ASSISTANT
    Проанализировал код из `main.c` [1]. Это фрагмент **дизассемблера x86-инструкций**, который парсит опкоды и операнды из внешнего файла опкодов (`hFileOpcodes`) и формирует текстовое представление команды.
    ## Что делает код
    ### Основные этапы работы:
    1. **Чтение мнемоники команды** — посимвольное чтение названия инструкции (mov, add, jmp и т.д.) до пробела
    2. **Чтение спецификации операндов** — парсинг шаблона операндов из файла опкодов (например, `"rm r"` — register/memory и register)
    3. **Обмен операндов при `d=0`** — если бит направления `d` сброшен и первый операнд не immediate, меняет местами операнды (это корректное поведение x86: `d=0` означает, что приёмник — src, источник — dst)
    4. **Выделение памяти под параметры** — `malloc(40)` на каждый операнд
    5. **Парсинг операндов по типам** — обработка регистров (`'r'`), control registers (`'c'` — cr0-cr7), и других типов
    ## Логическая ошибка: некорректный обмен операндов
    ### Проблема в этом блоке:
    ```c
    if((cp->sf.d==0) && (cp->par_count>=2)){
    if(cp->par[1]!='i'){ // ← ПРОВЕРЯЕТ ТОЛЬКО par[1]
    buf=cp->par[1];
    cp->par[1]=cp->par[0];
    cp->par[0]=buf;
    }
    }
    ```
    ### Почему это ошибка:
    | Сценарий | Поведение | Проблема |
    |---------|-----------|----------|
    | `par[0] == 'i'` (immediate первый) | Обмен **не** происходит | ✓ Корректно |
    | `par[1] == 'i'` (immediate второй) | Обмен **не** происходит | ✗ **ОШИБКА** — должен происходить, иначе `d=0` сломает семантику |
    | Оба не `'i'` | Обмен происходит | ✓ Корректно |
    **Суть**: В x86 при `d=0` направление операндов инвертировано. Если **любой** из операндов — immediate, обмен опасен или некорректен. Но текущая логика защищает только от `par[1]=='i'`, пропуская случай `par[0]=='i'`.
    При `par[0]=='i'` и `par[1]!='i'` код **всё равно обменивает**, получая immediate в позиции приёмника — что генерирует невалидную инструкцию (immediate нельзя записать в, например, `mov 5, eax` вместо `mov eax, 5`).
    ### Исправление:
    ```c
    if((cp->sf.d==0) && (cp->par_count>=2)){
    // Не обменивать, если ЛЮБОЙ операнд — immediate
    if(cp->par[0]!='i' && cp->par[1]!='i'){
    buf=cp->par[1];
    cp->par[1]=cp->par[0];
    cp->par[0]=buf;
    }
    }
    ```
    Или, если семантика требует сохранить immediate на месте источника:
    ```c
    if((cp->sf.d==0) && (cp->par_count>=2)){
    // Обмен только если immediate строго на второй позиции (корректно для d=0)
    if(cp->par[0]!='i'){ // первый не immediate — можно менять
    buf=cp->par[1];
    cp->par[1]=cp->par[0];
    cp->par[0]=buf;
    }
    // иначе: par[0]=='i' — уже корректно для d=0 (src=imm, dst=par[1])
    }
    ```
    ## Дополнительные замечания
    | Проблема | Место | Риск |
    |---------|-------|------|
    | Утечка памяти | `cp->par`, `cp->com_text`, `cp->parameters` — нет `free()` | При длительной работе |
    | Жёстко заданный размер | `malloc(40)` на операнд | Переполнение при длинных именах |
    | Нет проверки `realloc`/`malloc` на NULL | Везде | SEGFAULT при нехватке памяти |
    | `fread(&buf,1,1,...)` — `buf` как `char`, но используется как `int` в сравнениях | Весь код | Потенциальные проблемы с signed/unsigned |
    Код явно находится в стадии разработки (много `//printf("DEBUG")`), так что некоторые проблемы — ожидаемый технический долг.

    Во вложении код, расскажи что он делает, в нём логическая ошибка, как можно поправить ?
    ЧТО ДЕЛАЕТ ПРОГРАММА
    Это простой дизассемблер для Windows PE-файлов, рассчитанный преимущественно на 32-битные инструкции x86.
    Программа работает следующим образом:
    1. Запрашивает путь к EXE-файлу или другому PE-файлу.
    2. Читает из DOS-заголовка поле e_lfanew, которое находится по смещению 0x3C.
    3. Переходит к PE-заголовку и получает:
    * количество секций;
    * размер Optional Header;
    * RVA точки входа AddressOfEntryPoint.
    4. Просматривает таблицу секций и находит секцию, внутри которой расположена точка входа программы.
    5. Переходит к полю PointerToRawData найденной секции, то есть к физическому смещению секции в файле.
    6. Вызывает функцию GetCommand(), которая:
    * читает до 15 байт, поскольку 15 байт — максимальная длина инструкции x86;
    * разбирает префиксы LOCK, REP, REPNZ, 0x66, 0x67 и сегментные префиксы;
    * ищет инструкцию во внешней таблице res/opcodes.ttt;
    * разбирает opcode, ModR/M, SIB, регистры, смещения и непосредственные значения;
    * формирует текст инструкции и список операндов;
    * перемещает файловый указатель на фактическую длину разобранной инструкции.
    7. Функция main() выводит полученные инструкции на экран.
    Например, результат работы может выглядеть так:
    push ebp
    mov ebp, esp
    sub esp, 20
    При этом архив неполный. Для сборки отсутствуют следующие файлы:
    command_format.h
    res/opcodes.ttt
    Поэтому собрать и полностью проверить программу в текущем виде невозможно.
    ГЛАВНАЯ ЛОГИЧЕСКАЯ ОШИБКА
    Основная логическая ошибка находится в следующем фрагменте:
    int i = 1;
    while (...) {
    ...
    ```
    while (i < command.par_count) {
    printf(", %s", command.parameters);
    i++;
    }
    ```
    }
    Переменная i создаётся один раз перед основным циклом и не сбрасывается перед выводом каждой следующей инструкции.
    Предположим, первая инструкция имеет два операнда:
    mov eax, ebx
    При её выводе переменная i увеличится с 1 до 2.
    Следующая инструкция также имеет два операнда:
    add ecx, edx
    Но условие:
    i < command.par_count
    превратится в:
    2 < 2
    Это условие ложно. Поэтому программа выведет только:
    add ecx
    Второй операнд edx выведен не будет.
    КАК ИСПРАВИТЬ ОСНОВНУЮ ОШИБКУ
    Минимальное исправление — сбрасывать i перед выводом дополнительных операндов:
    while ((GetCommand(&command, hFile) == RET_SUCCESS) &&
    (ftell(hFile) < (sSection.PointerToRawData + sSection.SizeOfRawData))) {
    ```
    printf("%s", command.com_text);
    if (command.par_count != 0) {
    printf(" %s", command.parameters[0]);
    }
    i = 1;
    while (i < command.par_count) {
    printf(", %s", command.parameters);
    i++;
    }
    printf("\n");
    ```
    }
    Однако лучше вообще заменить внутренний цикл while на for:
    for (i = 1; i < command.par_count; i++) {
    printf(", %s", command.parameters);
    }
    В таком случае переменная i автоматически будет начинаться с 1 при обработке каждой инструкции.
    ОШИБКА В УСЛОВИИ ОСНОВНОГО ЦИКЛА
    В исходном коде используется примерно такое условие:
    while ((GetCommand(&command, hFile) == RET_SUCCESS) &&
    (ftell(hFile) < sectionEnd))
    Проблема заключается в порядке вычисления условий.
    Сначала вызывается GetCommand(), которая пытается прочитать очередную инструкцию, и только после этого проверяется, не вышел ли файловый указатель за пределы секции.
    В результате функция может прочитать данные за пределами текущей PE-секции.
    Безопаснее сначала проверять положение файлового указателя:
    long sectionEnd =
    (long)sSection.PointerToRawData +
    (long)sSection.SizeOfRawData;
    while (ftell(hFile) >= 0 && ftell(hFile) < sectionEnd) {
    int result = GetCommand(&command, hFile);
    ```
    if (result != RET_SUCCESS) {
    break;
    }
    if (ftell(hFile) > sectionEnd) {
    break;
    }
    printf("%s", command.com_text);
    if (command.par_count > 0) {
    printf(" %s", command.parameters[0]);
    }
    for (i = 1; i < command.par_count; i++) {
    printf(", %s", command.parameters);
    }
    printf("\n");
    ```
    }
    Но это исправление только предотвращает вывод инструкции, которая пересекла границу секции.
    Для полного исправления функция GetCommand() должна получать количество оставшихся байт секции.
    Например:
    remaining = sectionEnd - ftell(hFile);
    После этого количество читаемых байт должно вычисляться так:
    size_t readSize =
    remaining < MAX_COMMAND_LEN
    ? (size_t)remaining
    : MAX_COMMAND_LEN;
    com_len1 = fread(mp, 1, readSize, hFile);
    ВОЗМОЖНАЯ ОШИБКА С ТОЧКОЙ ВХОДА
    Программа находит секцию, содержащую AddressOfEntryPoint, но затем начинает дизассемблирование с самого начала этой секции:
    fseek(hFile, sSection.PointerToRawData, SEEK_SET);
    Начало секции и точка входа программы — это не обязательно одно и то же место.
    Например:
    VirtualAddress секции: 0x1000
    AddressOfEntryPoint: 0x1370
    PointerToRawData: 0x0400
    Физическое смещение точки входа в файле вычисляется так:
    entryFileOffset =
    sSection.PointerToRawData +
    (AddressOfEntryPoint - sSection.VirtualAddress);
    Для приведённого примера:
    0x0400 + (0x1370 - 0x1000) = 0x0770
    Следовательно, если требуется начинать дизассемблирование именно с точки входа программы, нужно перейти по смещению 0x0770, а не по смещению 0x0400.
    Исправленный переход может выглядеть так:
    long entryFileOffset =
    (long)sSection.PointerToRawData +
    ((long)AddressOfEntryPoint - (long)sSection.VirtualAddress);
    fseek(hFile, entryFileOffset, SEEK_SET);
    Если же задача программы заключается в дизассемблировании всей секции целиком, переход на PointerToRawData является нормальным.
    УТЕЧКА ПАМЯТИ MP
    В функции GetCommand() выделяется память:
    mp = (unsigned char *)malloc(MAX_COMMAND_LEN);
    Но при нормальном завершении функции она не освобождается:
    fclose(hFileOpcodes);
    return RET_SUCCESS;
    Необходимо добавить вызов free():
    free(mp);
    fclose(hFileOpcodes);
    return RET_SUCCESS;
    Память также нужно освобождать во всех ветках функции, которые завершаются через return.
    ЗАПИСЬ ЗА ПРЕДЕЛЫ ВЫДЕЛЕННОЙ ПАМЯТИ
    В коде присутствует следующий фрагмент:
    temp_char1 = (char *)malloc(ext_len + 7);
    temp_char1[ext_len + 7] = 0;
    Если выделено ext_len + 7 байт, допустимые индексы находятся в диапазоне:
    0 ... ext_len + 6
    Индекс ext_len + 7 находится уже за пределами выделенного блока памяти.
    Правильный вариант:
    temp_char1 = malloc(ext_len + 7);
    temp_char1[ext_len + 6] = '\0';
    Аналогичная ошибка присутствует в другом месте:
    temp_char1 = (char *)malloc(ext_len + 5);
    temp_char1[ext_len + 5] = 0;
    Правильный индекс:
    temp_char1[ext_len + 4] = '\0';
    Однако если сразу после выделения памяти используется strcpy(), предварительно устанавливать завершающий нулевой символ обычно не требуется. Функция strcpy() сама копирует завершающий символ строки.
    НЕДОСТИЖИМЫЙ КОД
    В программе есть конструкция примерно следующего вида:
    case 7:
    return RET_ERROR;
    fclose(hFileOpcodes);
    free(mp);
    break;
    После выполнения return функция немедленно завершается.
    Следовательно, строки:
    fclose(hFileOpcodes);
    free(mp);
    break;
    никогда не выполняются.
    Правильный порядок:
    case 7:
    fclose(hFileOpcodes);
    free(mp);
    return RET_ERROR;
    НЕТ ПРОВЕРКИ ФОРМАТА PE-ФАЙЛА
    Программа практически не проверяет корректность загружаемого файла.
    Желательно проверить:
    * сигнатуру MZ в DOS-заголовке;
    * сигнатуру PE\0\0;
    * значение Machine;
    * поле Magic в Optional Header;
    * корректность числа секций;
    * корректность смещений;
    * соответствие размеров секций размеру файла;
    * успешность каждого вызова fread() и fseek().
    Без таких проверок повреждённый или специально сформированный файл может привести к чтению неверных областей, аварийному завершению программы или повреждению памяти.
    ПРИМЕР ИСПРАВЛЕННОЙ ЛОГИКИ MAIN
    Основную часть main() можно переписать примерно так:
    long sectionStart;
    long sectionEnd;
    long entryFileOffset;
    int result;
    int i;
    sectionStart = (long)sSection.PointerToRawData;
    sectionEnd = sectionStart + (long)sSection.SizeOfRawData;
    entryFileOffset =
    sectionStart +
    ((long)AddressOfEntryPoint - (long)sSection.VirtualAddress);
    if (entryFileOffset < sectionStart || entryFileOffset >= sectionEnd) {
    printf("Ошибка: точка входа находится за пределами найденной секции.\n");
    fclose(hFile);
    return RET_ERROR;
    }
    if (fseek(hFile, entryFileOffset, SEEK_SET) != 0) {
    printf("Ошибка перехода к точке входа.\n");
    fclose(hFile);
    return RET_ERROR;
    }
    while (1) {
    long position = ftell(hFile);
    ```
    if (position < 0 || position >= sectionEnd) {
    break;
    }
    result = GetCommand(&command, hFile);
    if (result != RET_SUCCESS) {
    break;
    }
    if (ftell(hFile) > sectionEnd) {
    printf("Ошибка: инструкция выходит за пределы секции.\n");
    break;
    }
    printf("%s", command.com_text);
    if (command.par_count > 0) {
    printf(" %s", command.parameters[0]);
    }
    for (i = 1; i < command.par_count; i++) {
    printf(", %s", command.parameters);
    }
    printf("\n");
    ```
    }
    fclose(hFile);
    ИТОГ
    Главная логическая ошибка заключается в том, что переменная i, используемая для вывода операндов, не сбрасывается перед обработкой каждой следующей инструкции.
    Из-за этого после первой инструкции с несколькими операндами последующие инструкции могут выводиться не полностью.
    Основное исправление:
    for (i = 1; i < command.par_count; i++) {
    printf(", %s", command.parameters);
    }
    Кроме этого, в программе обнаружены и другие проблемы:
    * GetCommand() вызывается до проверки границы секции;
    * дизассемблирование начинается с начала секции, а не обязательно с точки входа;
    * присутствуют утечки памяти;
    * имеются записи за пределами выделенной памяти;
    * есть недостижимый код после return;
    * отсутствует полноценная проверка структуры PE-файла;
    * архив не содержит command_format.h и res/opcodes.ttt, поэтому полностью собрать программу в текущем виде нельзя.
    --- Сообщение объединено, 24 июл 2026 в 15:46 ---
    Main_fixed от ChatGPT, во вложении...
     

    Вложения:

    • main_fixed.zip
      Размер файла:
      9,1 КБ
      Просмотров:
      5
  5. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    527
    Ну как я понял, локальная модель не справилась с задачей. Так или не совсем ? :)
     
  6. X-Shar

    X-Shar Active Member

    Публикаций:
    0
    Регистрация:
    24 фев 2017
    Сообщения:
    358
    Частично справилась, но хуже всех.)

    Всё три модели указали на разные ошибки и я с этими ошибками согласен:

    1)Zer0Kernel:

    Я согласен что лучше переписать код так:

    Код (Text):
    1. if (cp->parameters[0] != temp_char1) {
    2.     free(cp->parameters[0]);
    3.     cp->parameters[0] = temp_char1;
    4. }
    5. break;
    Также менее информативно проанализировала код, что он делает...
    Но не уверен что итоговая проблема в этом, но лучше попрвить, я не запускал код, незнаю что там за ошибка в итоге.

    2)Kimi:

    Перестановка:

    Код (C):
    1. if ((cp->sf.d == 0) && (cp->par_count >= 2)) {
    2.     if (cp->par[1] != 'i') {
    3.         buf = cp->par[1];
    4.         cp->par[1] = cp->par[0];
    5.         cp->par[0] = buf;
    6.     }
    7. }
    **Суть**: В x86 при `d=0` направление операндов инвертировано. Если **любой** из операндов — immediate, обмен опасен или некорректен. Но текущая логика защищает только от `par[1]=='i'`, пропуская случай `par[0]=='i'`.
    При `par[0]=='i'` и `par[1]!='i'` код **всё равно обменивает**, получая immediate в позиции приёмника — что генерирует невалидную инструкцию (immediate нельзя записать в, например, `mov 5, eax` вместо `mov eax, 5`).

    Вроде тоже соглашусь.)

    3)GPT:

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

    Код (C):
    1. int i = 1;
    2.  
    3. while (...) {
    4. ...
    5.  
    6. while (i < command.par_count) {
    7.     printf(", %s", command.parameters[i]);
    8.     i++;
    9. }
    10.  
    11. }
    Короче тут комплекс проблем похоже...
     
  7. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.443
    X-Shar, рад тебя видеть живым и бодрым, заходи но новую дамагу, если будет желание встретить других знакомых старичков.
     
    X-Shar нравится это.
  8. X-Shar

    X-Shar Active Member

    Публикаций:
    0
    Регистрация:
    24 фев 2017
    Сообщения:
    358
    Привет!
    Рад видеть!

    Я уже там, но тор не очень удобен конечно...:dntknw:

    А Инде всё, не заходит больше никуда ?
     
  9. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    760
    X-Shar,

    Заходит. Rel считает что индий свихнулся, я так не думаю :sarcastic:
     
  10. X-Shar

    X-Shar Active Member

    Публикаций:
    0
    Регистрация:
    24 фев 2017
    Сообщения:
    358
    Это нормальное его состояние...)

    Просто интересно чем сейчас занимается, всё визоры пилит, или как он там называл свои творения не помню уже...
     
  11. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.443
    Он увлекся биологией и креационизмом, заимствует теории своего рода опальных ученых, типа Шапиро, придумывает новые термины на их базе, постит сюда огромные пдфники, сгенерированные нейронками, которые никто не читает. В общем, некоторый новый виток эволюции Индия.
     
  12. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    29 мар 2021
    Сообщения:
    386
    Старичков-фбрвичков.
     
  13. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.443
    Свято место пусто не бывает, это тебе любой Инде-креационист подтвердит.
     
  14. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    29 мар 2021
    Сообщения:
    386
    Похоже на хроническое бредовое расстройство.