html

Показаны сообщения с ярлыком Delphi. Показать все сообщения
Показаны сообщения с ярлыком Delphi. Показать все сообщения

воскресенье, 25 октября 2015 г.

Компонент Delphi TChromium. Версии

1. Как показывает исследование с несколькими пакетами, версию TChromium определяет библиотека libcef.dll : 
libcef.dll версии 3.1547.1412.0
libcef.dll версии 3.1547.1412.0
 

2. В данный момент исходники и библиотеки проекта TChromium –а DCEF3 находится по адресу https://github.com/hgourvest/dcef3 . Список версий (коммитов) – по адресу https://github.com/hgourvest/dcef3/commits/master . В этой директории находим необходимую версию пакете , в котором и библиотека libcef.dll и качаем ее : 
Скачивание необходимой версии Tchromium и libcef.dll
Скачивание необходимой версии TChromium и libcef.dll
 
Посты по теме :

четверг, 1 марта 2012 г.

Динамический массив в Delphi

1. Динамические массивы в Delphi не имеют фиксированного размера . Чтобы объявить такой массив необходимо  записать:

var da_MyArray : array of integer;

Как  видим , мы просто говорим Delphi, что нам нужен одномерный массив типа Integer, а об его размере мы скажем  когда нибудь потом.

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

2. Для выделения памяти для динамического массива в Delphi используется процедура SetLength:

SetLength(da_MyArray,20);
 
После вызова этой процедуры будет выделена память для 20 элементов массива, которые будут проиндексированы от 0 до 19 (обратите внимание: индексирование начинается с нуля, а не с единицы!).
После этого можно работать с динамическим массивом- присваивать ему значения, производить с элементами различные вычисления, вывод на печать и т.д.
Например

   da_MyArray[0] :=  5 ;
   da_MyArray[9] :=  9 ;
   da_MyArray[1] :=  da_MyArray[0]+ da_MyArray[9] ;


3. Как только динамический массив был распределен, вы можете передавать массив стандартным функциям Length, High, Low и SizeOf Функция Length возвращает число элементов в динамическом массиве, High возвращает самый высокий индекс массива (то есть Length - 1), Low возвращает 0. В случае с массивом нулевой длины наблюдается интересная ситуация: High возвращает -1, а Low - 0, получается, что High  меньше  Low.  :) Функция SizeOf всегда возвращает 4 - длина в байтах  памяти указателя на динамический массив


   iHigh   := High (da_MyArray3);
   iLow    := Low  (da_MyArray3);
   iLength := Length (da_MyArray3);
   iSizeOf := SizeOf (da_MyArray3);

4. Доступ к данным динамических массивов с помощью низкоуровневых процедур типа ReadFile или WriteFile , или любых других подпрограмм, получающих доступ сразу ко всему массиву, часто выполняется неправильно. Для обычного массива (его часто называют также статическим массивом - в противоположность динамическому массиву) переменная массива тождественна его данным. Для динамического массива это не так - переменная  это указатель. Так что если вы хотите получить доступ к данным динамического массива - вы не должны использовать саму переменную массива, а использовать вместо неё первый элемент массива.

правильно
WriteFile(FHandle, da_MyArray02[0], Length(da_MyArray02), dwTemp, nil)


неправильно
WriteFile(FHandle, da_MyArray02, Length(da_MyArray02), dwTemp, nil)

5. Рассмотрим  пример присваивания динамических массивов одного другому
var
  da_A,da_B: array of integer;
begin
  SetLength(da_A,2);
  SetLength(da_B,2);
  da_A[0]:=2;
  da_B[0]:=3;
  da_A:=da_B;
  da_B[0]:=4;
end;

После этих манипуляций da_A[0] равно 4. Дело в том , что  при присвоении da_A:=da_B не происходит копирование т.к. da_A, da_B, это всего лишь указатели на область памяти. Для копирования необходимо использовать функцию Copy.

6.  Рассмотрим  пример копирования динамических массивов с использованием функции Copy

var
  da_A,da_B: array of integer;
begin
  SetLength(da_A,2);
  SetLength(da_B,2);
  da_A[0]:=2;
  da_B[0]:=3;
  da_A:=Copy (da_B);
  da_B[0]:=4;
end;

После этих манипуляций da_A[0] равно 3. После функции Copy da_A и da_B указывают на разные области памяти, поэтому при изменении da_B в da_A ничего не происходит и его значения остаются неизменными.

7. Динамические массивы (например, array of Integer) в Delphi в памяти расположены следующим образом. Библиотека runtime добавляет специальный код, который управляет доступом и присваиваниями. В участке памяти ниже адреса, на который указывает ссылка динамического массива, располагаются служебные данные массива: два поля - число выделенных элементов и счётчик ссылок (reference count).
Расположение динамического массива в памяти
Расположение динамического массива в памяти

Если, как на диаграмме выше, N - это адрес в переменной динамического массива, то счётчик ссылок массива лежит по адресу N - 8, а число выделенных элементов (указатель длины) лежит по адресу N - 4. Первый элемент массива (сами данные) лежит по адресу N.
Для каждой добавляемой ссылки (т.е. при присваивании, передаче как параметр в подпрограмму и т.п.) увеличивается счётчик ссылок, а для каждой удаляемой ссылки (т.е. когда переменная выходит из области видимости или при переприсваивании или присваивании nil) счётчик уменьшается.

8. Написал 2 программы, которые иллюстрируют теоретические сведения по динамическим массивам , приведенным в посте.
Окно программы примера 1
Окно программы примера 1

Окно программы примера 2
Окно программы примера 2

Скачать программы- примеры с исходными кодами  здесь : Dynamic-Array.rar

Использовались функции SetLength, High, Low, Length, SizeOf, OpenFile, WriteFile, SetFilePointer, ReadFile, CloseHandle, ShellExecute, IntToStr, IntToHex, Integer, Copy, Ptr

9. Полезные ссылки:

-- Работа с указателями
-- ReadFile & Array of Byte, Можно так делать и как правильно?
-- Динамические массивы 4 

  Посты по теме :





воскресенье, 12 февраля 2012 г.

Таблица секций в PE файле

0. Таблица секций - это база данных из заголовков секций, для всех секций , используемых в PE файле. После окончания опционального заголовка сразу следует таблица секций. Таблица секций представляет собой  массив элементов типа TImageSectionHeader. Количество элементов  этого типа определяется полем NumberOfSections заголовка FileHeader.    Входы в таблице секций  нумеруются,  начиная  с  1.


1. Элемент типа  TImageSectionHeader  подробно расписан в файле Windows.pas комплекта Delphi 7.0:
-----------------------------
  PImageSectionHeader = ^TImageSectionHeader;
  _IMAGE_SECTION_HEADER = packed record
    Name: packed array[0..IMAGE_SIZEOF_SHORT_NAME-1] of Byte;
    Misc: TISHMisc;
    VirtualAddress: DWORD;
    SizeOfRawData: DWORD;
    PointerToRawData: DWORD;
    PointerToRelocations: DWORD;
    PointerToLinenumbers: DWORD;
    NumberOfRelocations: Word;
    NumberOfLinenumbers: Word;
    Characteristics: DWORD;
  end;
  {$EXTERNALSYM _IMAGE_SECTION_HEADER}
  TImageSectionHeader = _IMAGE_SECTION_HEADER;
  IMAGE_SECTION_HEADER = _IMAGE_SECTION_HEADER;
  {$EXTERNALSYM IMAGE_SECTION_HEADER}
------------------------------


2. Описание полей структуры из статьи ФОРМАТ ИСПОЛНЯЕМЫХ ФАЙЛОВ PortableExecutables (PE) написанной Hard Wisdom

Немного исправил названия, согласно файлу Windows.pas

-=====T=======T=======================T=================================¬
¦     ¦ Size  ¦                       ¦                                 ¦
¦Base ¦  or   ¦     Name Of field     ¦       Brief description         ¦
¦     ¦ Type  ¦                       ¦                                 ¦
¦=====+=======+=======================+=================================¦
¦ 00h ¦  08h  ¦ Name                  ¦ Имя объекта, остаток заполнен   ¦
¦     ¦       ¦                       ¦ нулями, если имя объекта имеет  ¦
¦     ¦       ¦                       ¦ длину 8 символов, то заключи-   ¦
¦     ¦       ¦                       ¦ тельного 0 нет. Некоторые PE    ¦
¦     ¦       ¦                       ¦ дамперы падают на этом факте.   ¦
¦     ¦       ¦                       ¦ Имя - штука отфонарная и никого ¦
¦     ¦       ¦                       ¦ ни к чему не обязывает.         ¦
+-----+-------+-----------------------+---------------------------------+
¦ 08h ¦ DWord ¦                       ¦ Виртуальный размер секции,      ¦
¦     ¦       ¦ Misc.VirtualSize      ¦ именно столько памяти будет от- ¦
¦     ¦       ¦                       ¦ ведено под секцию. Если Virtual ¦
¦     ¦       ¦                       ¦ Size превышает SizeOfRawData,   ¦
¦     ¦       ¦                       ¦ то разница заполняется нулями,  ¦
¦     ¦       ¦                       ¦ так определяются секции неини-  ¦
¦     ¦       ¦                       ¦ циализированных данных (        ¦
¦     ¦       ¦                       ¦ SizeOfRawData = 0)              ¦
+-----+-------+-----------------------+ - - - - - - - - - - - - - - - - +
¦ 0Ch ¦ DWord ¦ VirtualAddress        ¦ Размещение секции в памяти,     ¦
¦     ¦       ¦                       ¦ виртуальный ее адрес относитель-¦
¦     ¦       ¦                       ¦ но Image Base. Позиция каждой   ¦
¦     ¦       ¦                       ¦ секции выравнена на границу     ¦
¦     ¦       ¦                       ¦ SectionAlignment(степень2 от 512¦
¦     ¦       ¦                       ¦ до 256М включительно, по умол-  ¦
¦     ¦       ¦                       ¦ чанию 64К) и секции упакованы   ¦
¦     ¦       ¦                       ¦ впритык друг к другу, впрочем,  ¦
¦     ¦       ¦                       ¦ можно это не соблюдать.         ¦
+-----+-------+-----------------------+---------------------------------+
¦ 10h ¦ DWord ¦ SizeOfRawData         ¦ Размер секции (ее инициализиро- ¦
¦     ¦       ¦                       ¦ ванной части) в файле, кратно   ¦
¦     ¦       ¦                       ¦ полю FileAlignment в заголовкеPE¦
¦     ¦       ¦                       ¦ Header, обычно он меньше или    ¦
¦     ¦       ¦                       ¦ равен VirtualSize.  Играя с     ¦
¦     ¦       ¦                       ¦ этим полем можно добиться неко- ¦
¦     ¦       ¦                       ¦ торых результатов ;-) загрузчик ¦
¦     ¦       ¦                       ¦ по идее хлопает всю секцию в    ¦
¦     ¦       ¦                       ¦ отведенное ОЗУ! SizeOfRawData   ¦
¦     ¦       ¦                       ¦ может быть больше, чем Virtual  ¦
¦     ¦       ¦                       ¦ Size. Это происходит, когда     ¦
¦     ¦       ¦                       ¦ "умный" линкер заявляет строгий ¦
¦     ¦       ¦                       ¦ размер секции (не кратный       ¦
¦     ¦       ¦                       ¦ SectionAlignment).В таком случае¦
¦     ¦       ¦                       ¦ хвост секции теоретически не    ¦
¦     ¦       ¦                       ¦ используется.                   ¦
+-----+-------+-----------------------+ - - - - - - - - - - - - - - - - +
¦ 14h ¦ DWord ¦ PointerToRawData      ¦ Физическое смещение относитель- ¦
¦     ¦       ¦                       ¦ но начала EXE файла, выровнено  ¦
¦     ¦       ¦                       ¦ на границу FileAlignment поля за¦
¦     ¦       ¦                       ¦ головка PE Header. Смещение     ¦
¦     ¦       ¦                       ¦ используется загрузчиком как    ¦
¦     ¦       ¦                       ¦ seek значение.                  ¦
+-----+-------+-----------------------+---------------------------------+
¦ 18h ¦  0Ch  ¦ PointerToRelocations  ¦ зарезервировано для OBJ файла,  ¦
¦     ¦       ¦ PointerToLinenumbers  ¦ в экзешниках смысла не имеет    ¦
¦     ¦       ¦ NumberOfRelocations   ¦                                 ¦
¦     ¦       ¦ NumberOfLinenumbers   ¦                                 ¦
¦     ¦       ¦                       ¦                                 ¦
+-----+-------+-----------------------+---------------------------------+
¦ 24h ¦ DWord ¦ Characteristics       ¦ битовые флаги секции, см.ниже   ¦
¦=====¦=======¦=======================+=================================¦
¦ Total Structure size      28h       ¦ Общий размер описателя секции   ¦
L=====================================¦=================================-


3. Хорошо расписана таблица заголовков секций в книге Bill Prisoner “От зеленого к красному”. (http://vxheavens.com/lib/vbp01.html#c29)  Кроме того, надо обязательно читать спецификации Microsoft.


Окно программы
4. Написал на Delphi программу, которая выводит всю таблицу заголовков секций. Попробую в дальнейшем довести эту программу до упаковщика или криптора PE-файла.


5. Программу с исходниками, а также с дополнительными файлами - спецификациями Microsoft для PE-файлов версий 8.0,8.1 и 8.2 (094_pecoff_v8.pdf, pecoff_v8.doc , pecoff_v8.pdf ) , статьей ФОРМАТ ИСПОЛНЯЕМЫХ ФАЙЛОВ PortableExecutables (PE) написанной Hard Wisdom  и  файлом Windows.pas , скачать можно здесь : SectionHeaders.rar

среда, 8 февраля 2012 г.

Заголовок NTHeader в PE файле

0. Заголовок файла PE  состоит из заголовка  MS -DOS  в самом начале файла  и из NT заголовка (NTHeader). NT заголовок (NTHeader), в свою очередь состоит из сигнатуры PE файла (Signature), заголовка файла (FileHeader) и опционального заголовка (OptionalHeader).

1. Заголовок файла NT   подробно расписан в файле Windows.pas комплекта Delphi 7.0:

-----------------------
type
  PImageNtHeaders = ^TImageNtHeaders;
  _IMAGE_NT_HEADERS = packed record
    Signature: DWORD;
    FileHeader: TImageFileHeader;
    OptionalHeader: TImageOptionalHeader;
  end;
  {$EXTERNALSYM _IMAGE_NT_HEADERS}
  TImageNtHeaders = _IMAGE_NT_HEADERS;
  IMAGE_NT_HEADERS = _IMAGE_NT_HEADERS;
  {$EXTERNALSYM IMAGE_NT_HEADERS}
-----------------------

2. Заголовок файла (FileHeader)  также расписан в файле Windows.pas комплекта Delphi 7.0:
-----------------------
  PImageFileHeader = ^TImageFileHeader;
  _IMAGE_FILE_HEADER = packed record
    Machine: Word;
    NumberOfSections: Word;
    TimeDateStamp: DWORD;
    PointerToSymbolTable: DWORD;
    NumberOfSymbols: DWORD;
    SizeOfOptionalHeader: Word;
    Characteristics: Word;
  end;
  {$EXTERNALSYM _IMAGE_FILE_HEADER}
  TImageFileHeader = _IMAGE_FILE_HEADER;
  IMAGE_FILE_HEADER = _IMAGE_FILE_HEADER;
  {$EXTERNALSYM IMAGE_FILE_HEADER}
-----------------------
3. Значение каждого поля можно посмотреть в техническом описании  Microsoft  и в статье ФОРМАТ ИСПОЛНЯЕМЫХ ФАЙЛОВ PortableExecutables (PE), написанной Hard Wisdom  (она на русском языке)

Окно программы
4. Написал программу, которая определяет, является ли данный файл PE файлом и выводит сигнатуру PE файла (Signature),  и заголовок файла (FileHeader) .В дальнейшем, после последующего развития, эта программа пригодится при написании упаковщика или криптора PE-файла.

5. Программу с исходниками, а  также с дополнительными файлами - файлом Windows.pas ,статьей ФОРМАТ ИСПОЛНЯЕМЫХ ФАЙЛОВ PortableExecutables (PE) написанной Hard Wisdom  и спецификациями Microsoft для PE-файлов версий 8.0,8.1 и 8.2 (094_pecoff_v8.pdf, pecoff_v8.doc , pecoff_v8.pdf )  скачать можно здесь : NTHeader.rar

6 Полезные ссылки 
--  Формат исполняемого файла ОС Windows - http://vxheavens.com/lib/vbp01.html#c2
Хорошо объяснен формат PE файла. Статья на русском . Лучше чем  статья  Hard Wisdom ФОРМАТ ИСПОЛНЯЕМЫХ ФАЙЛОВ PortableExecutables (PE)

четверг, 2 февраля 2012 г.

Заголовок файла MS-DOS формата Exe

0.Любой PE-файл начинается с маленькой  программы, записанной в формате исполняемых файлов MS-DOS. Эта программа выводит на экран сообщение  подобное этому: "This program cannot be run in DOS mode".

1.Подробно расписан заголовок MS-DOS в файле Windows.pas комплекта Delphi 7.0 :
---------------------------------------------------
type
  PImageDosHeader = ^TImageDosHeader;
    {EXTERNALSYM _IMAGE_DOS_HEADER}
  _IMAGE_DOS_HEADER = packed record      { DOS .EXE header                  }
      e_magic: Word;                     { Magic number                     }+00
      e_cblp: Word;                      { Bytes on last page of file       }+02
      e_cp: Word;                        { Pages in file                    }+04
      e_crlc: Word;                      { Relocations                      }+06
      e_cparhdr: Word;                   { Size of header in paragraphs     }+08
      e_minalloc: Word;                  { Minimum extra paragraphs needed  }+0a
      e_maxalloc: Word;                  { Maximum extra paragraphs needed  }+0c
      e_ss: Word;                        { Initial (relative) SS value      }+0e
      e_sp: Word;                        { Initial SP value                 }+10
      e_csum: Word;                      { Checksum                         }+12
      e_ip: Word;                        { Initial IP value                 }+14
      e_cs: Word;                        { Initial (relative) CS value      }+16
      e_lfarlc: Word;                    { File address of relocation table }+18
      e_ovno: Word;                      { Overlay number                   }+1a
      e_res: array [0..3] of Word;       { Reserved words                   }
      e_oemid: Word;                     { OEM identifier (for e_oeminfo)   }+24
      e_oeminfo: Word;                   { OEM information; e_oemid specific}+26
      e_res2: array [0..9] of Word;      { Reserved words                   }
      _lfanew: LongInt;                  { File address of new exe header   }+3С
  end;
  TImageDosHeader = _IMAGE_DOS_HEADER;
  {$EXTERNALSYM IMAGE_DOS_HEADER}
  IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;
----------------------------------------------------

2. Из справочной программы Tech 6.0  информация о Dos заголовке:
-------------------------------------------------
ExeHeaderRec
  Offset Size Contents

   +0      2  wSignature   5a4dH .EXE file signature ('MZ')
   +2      2  wPartPage    length of partial page at end (generally ignored)
   +4      2  wPageCnt     length of image in 512-byte pages, incl. header
   +6      2  wReloCnt     number of items in relocation table
   +8      2  wHdrSize     size of header in 16-byte paragraphs
  +0aH     2  wMinAlloc    minimum RAM needed above end of prog (paragraphs)
  +0cH     2  wMaxAlloc    maximum RAM needed above end of prog (paragraphs)
  +0eH     2  wInitSS      segment offset of stack segment (for setting SS)
  +10H     2  wInitSP      value for SP register when started
  +12H     2  wChkSum      file checksum (negative sum of all words in file)
  +14H     2  wInitIP      value for IP register when started
  +16H     2  wInitCS      segment offset of code segment (for setting CS)
  +18H     2  wTablOff     file-offset of first relo item (often 001cH)
  +1aH     2  wOverlayNo   overlay number (0 for base module)
          28               size of formatted portion of EXE header
--------------------------------------------------

Окно программы
Окно программы
3.Написал программу на Delphi , которая читает и анализирует заголовок MS - DOS  с целью определить этот файл  формата DOS  или Windows.Пригодится в дальнейшей разработке упаковщика или криптора.  Можно скачать с исходниками, а также с дополнительными файлами - файлом Windows.pas и программой Tech 6.0 здесь: DosHeader.rar

4. Полезные ссылки.
This page is intended to document the format of DOS executable files