РЭДЛАЙН
Лучшие решения для Вас и Вашего бизнеса!
На нашем сайте вы можете получить информацию о веб-разработке, обслуживании и продвижении сайта. Интернет-маркетинге. SEO (поисковой оптимизации). Контекстной и медийной рекламе в Интернете. SMM. Регистрации доменов и хостинговых услугах. И современном дизайне сайтов. Вообщем того что касается веб-разработки, а также много другой полезной информации из мира интернета, бизнеса и интернет-технологий...
Создаем доступные и современные сайты, которые работают! Обслуживаем и эффективно продвигаем интернет-проекты с 2006 года!
Главная Блоги Пишем упаковщик по шагам. Шаг шестой. TLS.


Пишем упаковщик по шагам. Шаг шестой. TLS.

Предыдущий шаг здесь.

Появилась новая версия библиотеки для работы с PE-файлами (0.1.5). Перекачайте и пересоберите ее.

Пришло время заняться обработкой такой важной вещи, как Thread Local Storage (TLS) - локальной памяти потока. Что она из себя представляет? Это небольшая структура, которая говорит загрузчику PE-файлов о том, где находятся данные, которые должны быть выделены в памяти для каждого потока. Загрузчиком также производится вызов функции TlsAlloc, и значение, возвращенное ей, записывается по адресу, также указанному в этой структуре (называется это индексом). Кроме того, эта же структура может содержать адрес массива, хранящего набор коллбэков (адресов функций), которые будут вызваны загрузчиком при загрузке файла в память или при создании нового потока в процессе.

С TLS, признаться честно, все будет несколько хардкорнее, чем с остальным, так что приготовьтесь и напрягите мозг. Мой прошлый упаковщик TLS-коллбэки не поддерживал, трусливо выдавая сообщение о том, что они есть, но не обрабатываются. В принципе, поведение разумное, так как TLS-коллбеки имеют в основном всякие странные файлы, использующие эту вещь как антиотладочный прием. Ни один штатный линкер, вроде линкера от Майкрософт или Борланд, не поддерживают создание TLS-коллбэков. Тем не менее, для создания годного упаковщика мы их поддержку запилим.

Но начнем по порядку. Как обычно, будем править структуру packed_file_info (файл structures.h проекта simple_pe_packer). В нее на этот раз добавятся четыре поля:

//Сюда загрузчик будет записывать TLS-индекс
  DWORD tls_index;//Относительный адрес индекса TLS в оригинальном файле
  DWORD original_tls_index_rva;//Оригинальный адрес массива TLS-коллбэков в оригинальном файле
  DWORD original_rva_of_tls_callbacks;//Относительный адрес массива TLS-коллбэков в файле//после нашей модификации
  DWORD new_rva_of_tls_callbacks;

В этих полях мы будем хранить необходимые для распаковщика значения, связанные с TLS. Отдельно поясню про коллбэки. Поле AddressOfCallBacks структуры IMAGE_TLS_DIRECTORY указывает на массив абсолютных виртуальных адресов (т.е. на адреса, идущие друг за другом), которые, в свою очередь, указывают на функции, являющиеся коллбэками. Завершается этот массив нулевым элементом. Загрузчик по очереди дергает все функции в этом массиве при следующих событиях: создание процесса, создание потока, завершение потока, завершение процесса. Первый раз они вызываются даже до того, как процесс получит управление. Чтобы дать понять загрузчику, что в нашем упакованном файле есть TLS-коллбеки (разумеется, если они были в оригинальном), мы сделаем следующее: поле AddressOfCallBacks обнулять не будем, а запишем туда адрес массива, содержащий один-единственный пустой коллбэк (не нули, а реальный коллбэк, который ничего не делает). При загрузке упакованного образа в память этот коллбэк будет выполнен и загрузчик с этого момента будет знать, что у файла есть TLS-коллбэки. Если бы мы записали в поле AddressOfCallbacks ноль или указатель на пустой массив, то загрузчика впоследствии уже не смогли бы убедить в том, что коллбэки есть. А вот сам массив коллбэков можно будет впоследствии уже менять, так как загрузчик перечитывает его каждый раз, когда он ему становится нужен.

Индекс TLS и данные, которыми инициализируется память потока, мы переместим в свою секцию (которую мы назвали kaimi.ru, помните?), дабы они не перетерлись после распаковки, а непосредственно в распаковщике уже имеющийся от загрузчика индекс запишем туда, где он должен быть в оригинальном файле. Саму структуру IMAGE_TLS_DIRECTORY (точнее, IMAGE_TLS_DIRECTORY32, мы ведь пакуем 32-разрядные бинарники) мы также запишем в свою секцию. Туда же запишем и массив наших подложных коллбэков из единственного пустого, если они есть в оригинальном файле.

Переходим к написанию кода. После этого блока кода:

//Проверим, что файл реально стал меньшеif(out_buf.size()>= src_length){
      std::cout<<"File is incompressible!"<< std::endl;return-1;}

допишем следующее:

//Если файл имеет TLS, получим информацию о нем
    std::auto_ptr<pe_base::tls_info> tls;if(image.has_tls()){
      std::cout<<"Reading TLS..."<< std::endl;
      tls.reset(new pe_base::tls_info(image.get_tls_info()));}

Теперь добавим немного кода после места, где мы пересобираем ресурсы:

//Если у файла был TLSif(tls.get()){//Указатель на нашу структуру с информацией//для распаковщика//Эта структура в самом начале свежедобавленной секции,//мы ее туда добавили чуть раньше
        packed_file_info* info =reinterpret_cast<packed_file_info*>(&added_section.get_raw_data()[0]);
 
        //Запишем относительный виртуальный адрес//оригинального TLS
        info->original_tls_index_rva = tls->get_index_rva();
 
        //Если у нас были TLS-коллбэки, запишем в структуру//относительный виртуальный адрес их массива в оригинальном файлеif(!tls->get_tls_callbacks().empty())
          info->original_rva_of_tls_callbacks = tls->get_callbacks_rva();
 
        //Теперь относительный виртуальный адрес индекса TLS//будет другим - мы заставим загрузчик записать его в поле tls_index//структуры packed_file_info
        tls->set_index_rva(pe_base::rva_from_section_offset(added_section, offsetof(packed_file_info, tls_index)));}

Здесь мы просто сохраняем в нашу структуру с информацией об оригинальном файле всяческую необходимую информацию об оригинальном TLS. Кроме того, в нее же загрузчик теперь запишет TLS-индекс, который мы в распаковщике переложим туда, где он должен находиться.

Далее работаем с секцией "kaimi.ru", в которую мы раньше записывали только тело распаковщика. Добавим ей, во-первых, атрибут доступа на запись, заменив строку

      unpacker_section.readable(true).executable(true);

на

//Доступна на запись, чтение и исполнение
      unpacker_section.readable(true).executable(true).writeable(true);

Заменим также строку

const pe_base::section& unpacker_added_section = image.add_section(unpacker_section);

на

    pe_base::section& unpacker_added_section = image.add_section(unpacker_section);

потому что с этой секцией мы теперь будем работать.

Теперь на некоторое время перейдем к проекту распаковщика (unpacker). Опишу детально, как мы будем обрабатывать TLS, имеющий коллбеки. Мы сохраняем все оригинальные адреса TLS (это мы уже сделали). Далее мы создаем свой массив коллбэков, имеющий всего один коллбэк, да и тот пустой, чтобы просто дать понять загрузчику, что коллбэки есть. Мы в новом TLS указываем на этот массив. Далее, сразу после распаковки файла мы вручную выполняем все коллбэки оригинального файла, потому что загрузчик по понятным причинам этого не сделает - у него всего один пустой коллбэк. После этого мы правим массив коллбэков, созданный нами, записывая туда все адреса уже оригинальных функций, и с этого момента управление TLS-коллбэками переходит во власть загрузчика, нам больше делать ничего не надо. Таким образом, наша текущая задача - сделать в распаковщике пустой TLS-коллбэк. Дабы не плодить дополнительных функций, просто модифицируем пролог функции unpacker_main:

//Пролог вручную
  __asm
  {
    jmp next;
    ret 0xC;
next:
 
    push ebp;
    mov ebp, esp;
    sub esp, 256;}

Распаковщик, таким образом, начнет исполняться с инструкции jmp next, сразу перепрыгнув на свое основное тело. А вот тот самый пустой коллбэк, который нам нужен, выглядит как "ret 0xC", и на эту инструкцию мы сделаем указатель в массиве коллбэков. Эта инструкция просто отдает управление, предварительно убрав из стека 0xC = 12 байтов. Если кто-то не в курсе, прототип TLS-коллбэка выглядит так:

typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK)(
    PVOID DllHandle,
    DWORD Reason,
    PVOID Reserved
    );

и использует он соглашение вызовов stdcall и три четырехбайтовых параметра. Итого, мы должны убрать из стека 3 * 4 = 12 байтов. Коллбэк не возвращает значения, поэтому модифицировать регистр eax в его теле необязательно.

Теперь заменим все эти строки:

//Относительный виртуальный адрес директории импорта
  DWORD original_import_directory_rva;//Виртуальный размер директории импорта
  DWORD original_import_directory_size;//Относительный виртуальный адрес директории ресурсов
  DWORD original_resource_directory_rva;//Виртуальный размер директории ресурсов
  DWORD original_resource_directory_size;//Оригинальная точка входа
  DWORD original_entry_point;//Общий размер всех секций файла
  DWORD total_virtual_size_of_sections;//Количество секций в оригинальном файле
  BYTE number_of_sections;
 
  //Копируем эти значения из структуры packed_file_info,//которую для нас записал упаковщик
  original_import_directory_rva = info->original_import_directory_rva;
  original_import_directory_size = info->original_import_directory_size;
  original_resource_directory_rva = info->original_resource_directory_rva;
  original_resource_directory_size = info->original_resource_directory_size;
  total_virtual_size_of_sections = info->total_virtual_size_of_sections;
  number_of_sections = info->number_of_sections;

на одно копирование структуры, а то слишком много лишнего кода получается:

//Копируем все поля структуры packed_file_info, так как они нам будут//нужны далее, но структуру по указателю info мы скоро затрем
  packed_file_info info_copy;memcpy(&info_copy, info, sizeof(info_copy));

Заменим теперь все обращения к вышеперечисленным переменным соответствующим образом, меняя, например, original_import_directory_rva на info_copy.original_import_directory_rva.

Поправим файлик parameters.h, у нас изменились необходимые для упаковщика смещения, кроме того, добавилось еще одно:

#pragma once
 
staticconstunsignedint original_image_base_offset =0x11;staticconstunsignedint rva_of_first_section_offset =0x1B;staticconstunsignedint empty_tls_callback_offset =0x2;

Последнее смещение в коде распаковщика (empty_tls_callback_offset) - это как раз смещение на инструкцию ret, осуществляющую выход из TLS-коллбэка.

Идем дальше. В отличие от директории импортов и директории ресурсов, директорию TLS мы восстанавливать не будем - это бессмысленно. Загрузчик все равно ее не будет перечитывать. Перейдем к обработке TLS. Код будем размещать в распаковщике после той части, в которой фиксим импорты. Для начала скопируем индекс, который нам предоставил загрузчик, в ячейку памяти, где он должен лежать:

//Скопируем TLS-индексif(info_copy.original_tls_index_rva)*reinterpret_cast<DWORD*>(info_copy.original_tls_index_rva+ original_image_base)= info_copy.tls_index;

Далее - более сложная часть. Обработаем TLS-коллбэки:

if(info_copy.original_rva_of_tls_callbacks){//Если TLS имеет коллбэки
    PIMAGE_TLS_CALLBACK* tls_callback_address;//Указатель на первый коллбэк оригинального массива
    tls_callback_address =reinterpret_cast<PIMAGE_TLS_CALLBACK*>(info_copy.original_rva_of_tls_callbacks+ original_image_base);while(true){//Если коллбэк нулевой - это конец массиваif(!*tls_callback_address)break;
 
      //Скопируем в наш массив коллбэков//адрес оригинального*reinterpret_cast<PIMAGE_TLS_CALLBACK*>(info_copy.new_rva_of_tls_callbacks+ original_image_base)=*tls_callback_address;
 
      //Перейдем к следующему коллбэку++tls_callback_address;}
 
    //Вернемся на начало уже нового массива
    tls_callback_address =reinterpret_cast<PIMAGE_TLS_CALLBACK*>(info_copy.new_rva_of_tls_callbacks+ original_image_base);while(true){//Если коллбэк нулевой - это конец массиваif(!*tls_callback_address)break;
 
      //Вызовем коллбэк(*tls_callback_address)(reinterpret_cast<PVOID>(original_image_base), DLL_PROCESS_ATTACH, 0);
 
      //Перейдем к следующему коллбэку++tls_callback_address;}}

Сначала мы перечисляем все адреса коллбэков в оригинальном массиве и копируем их в наш массив TLS-коллбэков, чтобы загрузчик их подхватил, когда они понадобятся в следующий раз. Однако, при создании процесса загрузчик дернул только наш единственный пустой коллбэк, а PE-файл ожидает, что будут вызваны его коллбэки с параметром DLL_PROCESS_ATTACH. Поэтому нам нужен второй цикл, в котором мы вызываем все коллбэки из оригинального массива, передав в них базовый адрес загрузки образа в первом параметре и DLL_PROCESS_ATTACH (=1) во втором. Третий параметр не используется, смотрите прототип выше. Можно было бы, конечно, скопировать адреса коллбэков и вызвать их и в одном цикле, но вдруг в коллбэках бинарник модифицирует сам себя или ожидает, чтобы массив коллбэков был сразу заполнен? В любом случае, два цикла - тоже не панацея, но это более надежно.

С распаковщиком все, и теперь мы возвращаемся к упаковщику. Необходимо разместить директорию TLS в секции "kaimi.ru", а также скопировать туда файловые данные, использующиеся для инициализации локальных данных новых потоков.

//Если у файла есть TLSif(tls.get()){
        std::cout<<"Rebuilding TLS..."<< std::endl;
 
        //Ссылка на сырые данные секции распаковщика//Сейчас там есть только тело распаковщика
        std::string& data = unpacker_added_section.get_raw_data();
 
        //Изменим размер данных секции распаковщика ровно//по количеству байтов в теле распаковщика//(на случай, если нулевые байты с конца были обрезаны//библиотекой для работы с PE)
        data.resize(sizeof(unpacker_data));
 
        //Вычислим позицию, в которую запишем структуру IMAGE_TLS_DIRECTORY32
        DWORD directory_pos = data.size();//Выделим место под эту структуру//запас sizeof(DWORD) нужен для выравнивания, так как//IMAGE_TLS_DIRECTORY32 должна быть выровнена 4-байтовую на границу
        data.resize(data.size()+sizeof(IMAGE_TLS_DIRECTORY32)+sizeof(DWORD));
 
        //Если у TLS есть коллбэки...if(!tls->get_tls_callbacks().empty()){//Необходимо зарезервировать место//под оригинальные TLS-коллбэки//Плюс 1 ячейка под нулевой DWORD
          DWORD first_callback_offset = data.size();
          data.resize(data.size()+sizeof(DWORD)*(tls->get_tls_callbacks().size()+1));
 
          //Первый коллбэк будет нашим пустым (ret 0xC),//запишем его адрес*reinterpret_cast<DWORD*>(&data[first_callback_offset])=
            image.rva_to_va_32(pe_base::rva_from_section_offset(unpacker_added_section, empty_tls_callback_offset));
 
          //Запишем относительный виртуальный адрес//новой таблицы TLS-коллбэков
          tls->set_callbacks_rva(pe_base::rva_from_section_offset(unpacker_added_section, first_callback_offset));
 
          //Теперь запишем в структуру packed_file_info, которую мы//записали в самое начало первой секции,//относительный адрес новой таблицы коллбэковreinterpret_cast<packed_file_info*>(&image.get_image_sections().at(0).get_raw_data()[0])->new_rva_of_tls_callbacks = tls->get_callbacks_rva();}else{//Если нет коллбэков, на всякий случай обнулим адрес
          tls->set_callbacks_rva(0);}
 
        //Очистим массив коллбэков, они нам больше не нужны//Мы их сделали вручную
        tls->clear_tls_callbacks();
 
        //Установим новый относительный адрес//данных для инициализации локальной памяти потока
        tls->set_raw_data_start_rva(pe_base::rva_from_section_offset(unpacker_added_section, data.size()));//Пересчитываем адрес конца этих данных
        tls->recalc_raw_data_end_rva();
 
        //Пересобираем TLS//Указываем пересборщику, что не нужно писать данные и коллбэки//Мы сделаем это вручную (коллбэки уже записали, куда надо)//Также указываем, что не нужно обрезать нулевые байты в конце секции
        image.rebuild_tls(*tls, unpacker_added_section, directory_pos, false, false, pe_base::tls_data_expand_raw, true, false);
 
        //Дополняем секцию данными для инициализации//локальной памяти потока
        unpacker_added_section.get_raw_data()+= tls->get_raw_data();//Теперь установим виртуальный размер секции "kaimi.ru"//с учетом SizeOfZeroFill поля TLS
        image.set_section_virtual_size(unpacker_added_section, data.size()+ tls->get_size_of_zero_fill());//Наконец, обрежем уже ненужные нулевые байты с конца секции
        pe_base::strip_nullbytes(unpacker_added_section.get_raw_data());//и пересчитаем ее размеры (физический и виртуальный)
        image.prepare_section(unpacker_added_section);}

Опишу этот внушительный кусок кода. Сначала мы зарезервировали место под структуру IMAGE_TLS_DIRECTORY32 в последней секции с распаковщиком ("kaimi.ru") сразу после его кода, затем выделели место под массив TLS-коллбэков по их оригинальному количеству (каждый из них занимает 4 байта, плюс последний элемент - нулевой). В новый массив коллбэков записали указатель на код в распаковщике, который ничего не делает, кроме выравнивания стека (ret 0xC). Это даст понять загрузчику, что коллбэки у файла есть. Далее пересчитали указатели на данные, которые загрузчик будет использовать для инициализации локальных данных потоков. Мы размещаем эти данные после структуры IMAGE_TLS_DIRECTORY32 и массива TLS-коллбэков. Потом мы пересобираем TLS с помощью библиотеки для работы с PE (по сути, она просто записывает структуру IMAGE_TLS_DIRECTORY32 куда надо и заполняет ее, автоматическую запись коллбэков и данных мы отключили). Наконец, мы пересчитываем виртуальный размер секции с учетом значения поля SizeOfZeroFill в TLS оригинального файла (мы это значение не меняем). Я точно не могу сказать, как это поле обрабатывается (и описаний толковых в интернете, увы, не нашел) - зануляет ли загрузчик данные после EndAddressOfRawData прямо внутри секции, либо же после инициализации локальной памяти потока, но лучше перестраховаться и выделить место прямо в секции. На размер упакованного файла это не влияет, так как мы увеличиваем виртуальный размер секции, а не физический. После всего этого мы наконец-то обрезаем с конца секции ненужные нулевые байты (она последняя, и мы можем так сделать, об этом я уже как-то писал) и пересчитываем виртуальный и физический размеры секции (реально может поменяться только физический, так как виртуальный мы сами назначили, и он больше или равен физическому).

Уберем теперь добавленную раньше строку:

    image.remove_directory(IMAGE_DIRECTORY_ENTRY_TLS);

Остается протестировать работоспособность. Обработку TLS без коллбэков можно проверить на любой скомпилированной Борландом программе. Можно также собрать программу с помощью Microsoft Visual Studio любой версии, используя в коде __declspec(thread). TLS с коллбэками сделать не так просто, я пользовался примером отсюда, компилируя его в Visual C++ 6.0, хотя можно было бы собрать TLS с коллбэками руками и на MASM32. После небольшой проверки я удостоверился, что все работает, как надо!

Честно сказать, я заметил одну особенность, которая присуща всем упаковщикам, которые я опробовал - они все не меняют значение адреса индекса TLS. Не могу пока что сказать, почему это так, но вполне вероятно, что причина такого поведения есть. В комментариях в исходных кодах UPX сказано, что массив TLS-коллбэков должен быть также, как и структура IMAGE_TLS_DIRECTORY32, выровнен на границу DWORD'а, однако я не стал этого делать, так как даже на XP PE-файл с невыровненным массивом отлично работал.

Есть еще замечание по старому коду. Внезапно выяснилось, что Win XP плохеет, если урезаны директории данных в PE-заголовке (Data Directory), и его explorer.exe перестает отображать иконки у файлов. Поэтому придется закомментировать строку

//image.strip_data_directories(16 - 4); //Закомментировали из-за непереносимости в WinXP

для сохранения совместимости.

Полный солюшен для этого шага: Own PE Packer, step 6

Также рекомендую почитать

Пишем упаковщик по шагам. Шаг шестой. TLS. Обсудить на форуме


Источник: http://feedproxy.google.com/~r/kaimi/dev/~3/Ge43--WMNxA/

Пишем упаковщик по шагам. Шаг шестой. TLS. | | 2012-09-21 23:39:00 | | Блоги и всяко-разно | | Предыдущий шаг здесь.Появилась новая версия библиотеки для работы с PE-файлами (0.1.5). Перекачайте и пересоберите ее.Пришло время заняться обработкой такой важной вещи, как Thread Local Storage (TLS) - локальной памяти потока. Что она из себя представляет? Эт | РэдЛайн, создание сайта, заказать сайт, разработка сайтов, реклама в Интернете, продвижение, маркетинговые исследования, дизайн студия, веб дизайн, раскрутка сайта, создать сайт компании, сделать сайт, создание сайтов, изготовление сайта, обслуживание сайтов, изготовление сайтов, заказать интернет сайт, создать сайт, изготовить сайт, разработка сайта, web студия, создание веб сайта, поддержка сайта, сайт на заказ, сопровождение сайта, дизайн сайта, сайт под ключ, заказ сайта, реклама сайта, хостинг, регистрация доменов, хабаровск, краснодар, москва, комсомольск |
 
Дайджест новых статей по интернет-маркетингу на ваш email
Подписаться

Продающие сайты "под ключ"!

Наши сайты зарабытывают вам деньги. Landing-page. Эффективные продающие сайты точно в срок и под ключ! Всего от 14700 рублей
Подробнее...

Интернет-магазины и каталоги "под ключ"!

Эффективные и удобные инструменты торговли (электронной торговли) "под ключ". Продают, даже когда вы спите! Всего от 33800 рублей
Подробнее...

Комплексный интернет-маркетинг и продвижение сайтов

Максимальную эффективность дает не какой-то конкретный метод, а их комбинация. Комбинация таких методов и называется комплексным интернет-маркетингом. Всего от 8000 рублей в месяц
Подробнее...

Реклама в Yandex и Google

Контекстная реклама нацелена лишь на тех пользователей, которые непосредственно заинтересованы в рекламе Ваших услуг или товаров. Всего от 8000 рублей в месяц
Подробнее...

Social media marketing (SMM) — продвижение в социальных медиа

Реклама в Однокласcниках и на Mail.ru Создание, ведение и раскрутка групп и реклама ВКонтакте и Facebook. Всего от 8000 рублей в месяц
Подробнее...

Приглашаем к сотрудничеству рекламные агентства и веб-студии!

Внимание Акция! Приглашаем к сотрудничеству рекламные агентства и различные веб-студии России! Индивидуальные и взаимовыгодные условия сотрудничества.
Подробнее...

Ускоренная разработка любого сайта от 5 дней!

Внимание Акция! Ускоренная разработка любого сайта! Ваш сайт будет готов за 5-10 дней. Вы можете заказать разработку любого сайта "под ключ" за 5-10 рабочих дней, с доплатой всего 30% от его стоимости!
Подробнее...

Ждем новых друзей!

Внимание Акция! Ждем новых друзей! Скидка 10% на услуги по созданию и(или) обслуживанию вашего сайта при переходе к нам от другого разработчика.
Подробнее...

Приведи друга и получи скидку!

Внимание Акция! Приведи друга и получи скидку! Скидка 10% на услуги по созданию и(или) обслуживанию вашего сайта, если клиент заказавший наши услуги, пришел по Вашей рекомендации.
Подробнее...

1 2 3 4 5 6 7 8 9

Новые статьи и публикации


Услуги интернет компании Редлайн

Секрет быть несчастным: иметь время занудствовать на тему, счастлив ты или нет

Шоу Джордж Бернард - (1856-1950) - английский писатель. В своем творчестве ниспровергал догматизм и предвзятость, традиционность представлений

Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!

Качественное и объемное представление своего бизнеса в Сети требуется любой растущей коммерческой структуре, стремящейся увеличить продажи, именно по этой причине среди наших клиентов как крупные так и небольшие компании во многих городах России и ближнего зарубежья.
Как мы работаем

Заявка
Позвоните или оставьте заявку на сайте.


Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!


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


Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.


Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.

Остались еще вопросы? Просто позвоните и задайте их специалистам
с 2:30 до 11:30 по Мск, звонок бесплатный
Или напишите нам в WhatsApp
с 9:30 до 18:30 по Хабаровску
Или напишите нам в WhatsApp
Веб-студия и агентство комплексного интернет-маркетинга «РЭДЛАЙН» © 2006 - 2024

Профессиональная Веб-разработка. Создание сайтов и магазинов "под ключ" , а также по всей России и зарубежью. Продвижение и реклама. Веб-дизайн. Приложения. Сопровождение. Модернизация. Интеграции. Консалтинг. Продвижение и реклама. Комплексный Интернет-маркетинг.

Оставьте заявку / Задайте вопрос

Нажимая на кнопку ОТПРАВИТЬ, я даю согласие на обработку персональных данных
×

Заказать услугу

Нажимая на кнопку ОТПРАВИТЬ, я даю согласие на обработку персональных данных
×

Обратный звонок

Нажимая на кнопку ОТПРАВИТЬ, я даю согласие на обработку персональных данных
×

Подписка на дайджест новостей

Нажимая на кнопку ОТПРАВИТЬ, я даю согласие на обработку персональных данных
×

Заказать услуги со скидкой \ Бесплатная консультация







КАКИЕ УСЛУГИ ВАС ИНТЕРЕСУЮТ?

КАКИЕ ДОПОЛНИТЕЛЬНЫЕ УСЛУГИ ПОТРЕБУЮТСЯ?

Нажимая на кнопку ОТПРАВИТЬ, я даю согласие на обработку персональных данных
×

Высококачественные сайты по доступным ценамМы создаем практически любые сайты от продающих страниц до сложных, высоконагруженных и нестандартных веб приложений! Наши сайты это надежные маркетинговые инструменты для успеха Вашего бизнеса и увеличения вашей прибыли! Мы делаем красивые и максимально эффектные сайты по доступным ценам уже много лет!

Что нужно сделать, чтобы заказать создание сайта у нас?

Ну для начала вам нужно представлять (хотя бы в общих чертах), что вы хотите получить от сайта и возможно каким вы хотите его видеть. А дальше все просто. Позвоните нам или оставьте заявку нашим менеджерам, чтобы они связались с Вами, проконсультировали и помогли определиться с подходящим именно Вам сайтом по цене, сроку, дизайну или функционалу. Если вы все ещё не уверены, какой сайт вам нужен, просто обратитесь к нам! Мы вместе проанализируем вашу ситуацию и определим максимально эффективный для вас вариант.

Быстрый заказ \ Консультация

Для всех тарифных планов на создание и размещение сайтов включено:

Комплексная раскрутка сайтов и продвижение сайта Комплексный подход это не просто продвижение сайта, это целый комплекс мероприятий, который определяется целями и задачами поставленными перед сайтом и организацией, которая за этим стоит. Время однобоких методов в продвижении сайтов уже прошло, конкуренция слишком высока, чтобы была возможность расслабиться и получать \ удерживать клиентов из Интернета, просто сделав сайт и не занимаясь им...

Комплексная раскрутка работает в рамках стратегии развития вашего бизнеса в сети и направлена

Быстрый заказ \ Консультация

ЭФФЕКТИВНОЕ СОПРОВОЖДЕНИЕ (ПОДДЕРЖКА, ОБСЛУЖИВАНИЕ) САЙТОВ

Полный комплекс услуг по сопровождению сайтаМы оказываем полный комплекс услуг по сопровождению сайта: информационному и техническому обслуживанию и развитию Интернет сайтов.

Передав свой сайт для поддержки в руки наших специалистов, Вы избавитесь от проблем, связанных с обновлением информации и контролем за работой ресурса.

Наша компания осуществляет техническую и информационную поддержку уже имеющихся сайтов. В понятие «поддержка сайтов» также входят услуги администрирования сайтов, обновления сайтов и их модернизация.

Быстрый заказ \ Консультация

Редизайн сайта и Адаптивный веб дизайн

Современный, технологичный, кроссбраузерный ... Профессиональный дизайн сайтов и веб-приложений

Редизайн сайта — создание нового дизайна сайта с целью улучшения внешнего вида, функциональности и удобства использования. Редизайн сайта – это способ преобразовать проект к извлечению из него максимальной отдачи и средств. В современном мире задачами редизайна является поднятие существующего сайта на новый уровень для внедрения новых технологий, при этом сохраняя многолетний сформировавшийся опыт и успешные решения компаний.

Адаптивный дизайн сайтов и веб-приложений

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

На сегодняшний день адаптивный дизайн является стандартным подходом при разработке новых сайтов (или веб-приложений) и в идеале ваш сайт должен смотреться и функционировать так, как вы задумывали, на всём разнообразии устройств.

Быстрый заказ \ Консультация

Контекстная реклама в Яндекс и GoogleКонтекстная реклама - это эффективный инструмент в интернет маркетинге, целью которого является увеличение продаж. Главный плюс контекстной рекламы заключается в том, что она работает избирательно.

Реклама в поисковых системах Яндекс и Google. Профессиональная настройка рекламы и отслеживание эффективности!

Рекламные объявления показываются именно тем пользователям, которые ищут информацию о Ваших товарах или услугах, поэтому такая реклама не является навязчивой и раздражающей в отличие от других видов рекламы, с которыми мы сталкиваемся на телевидении или радио. Контекстная реклама нацелена лишь на тех пользователей, которые непосредственно заинтересованы в рекламе Ваших услуг или товаров.

Быстрый заказ \ Консультация

Скидка

1500 руб.
Заинтересовались услугами создания, обслуживания или продвижения вашей компании в Интернете?!
Получите 1500 руб.
за он-лайн заявку
Предложение ограничено.

После получения заявки с Вами свяжутся наши специалисты и уточнят все детали по интересующей вас услуге.
«Нажимая на кнопку "Получить скидку", я даю согласие на обработку персональных данных»
×
Получите 1500 рублей!
×
×