unit Sections;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, Menus;

function EditSection(Index:integer; SectionName:string; VOffset:DWORD; VSize:DWORD; ROffset:DWORD; RSize:DWORD; Flags:DWORD):boolean;
function HexToInt(s: string): Integer;

type
  TfrmSections = class(TForm)
    lsSections: TListView;
    PopMain: TPopupMenu;
    DumpSection1: TMenuItem;
    EditSection1: TMenuItem;
    HexViewer1: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure DumpSection1Click(Sender: TObject);
    procedure EditSection1Click(Sender: TObject);
    procedure HexViewer1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmSections: TfrmSections;

implementation

uses Main, SectionEditor, HexViewer;

{$R *.dfm}

function HexToInt(s: string): Integer;
begin
  Result := StrToInt('$' + s);
end;

function ReadSection(sPath:string; Start:DWORD; Size:DWORD):AnsiString;
var
sBuff:  AnsiString;
hFile:  THandle;
dRead:  DWORD;
begin
  hFile := CreateFile(PChar(sPath), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
  if hFile <> INVALID_HANDLE_VALUE then
  begin
    SetFilePointer(hFile, Start, nil, FILE_BEGIN);
    SetLength(sBuff, Size);
    ReadFile(hFile, sBuff[1], Size, dRead, nil);
    Result := sBuff;
  end;
  CloseHandle(hFile);
end;

procedure TfrmSections.FormCreate(Sender: TObject);
begin
SetWindowPos(frmSections.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE)
end;

function EditSection(Index:integer; SectionName:string; VOffset:DWORD; VSize:DWORD; ROffset:DWORD; RSize:DWORD; Flags:DWORD):boolean;
var
hFile:    THandle;
dWritten: DWORD;
begin
  hFile := CreateFile(PChar(sFile), GENERIC_WRITE, FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
  if hFile <> INVALID_HANDLE_VALUE then
  begin
    Move(SectionName[1], ISH.Name[0], 8);
    ISH.VirtualAddress := VOffset;
    ISH.Misc.VirtualSize := VSize;
    ISH.PointerToRawData := ROffset;
    ISH.SizeOfRawData := RSize;
    ISH.Characteristics := Flags;
    SetFilePointer(hFile, IDH._lfanew + 248 + (Index) * 40, nil, FILE_BEGIN);
    if WriteFile(hFile, ISH, SizeOf(ISH), dWritten, nil) then
      Result := TRUE
    else
      Result := FALSE;
    CloseHandle(hFile);
  end;
end;

procedure TfrmSections.DumpSection1Click(Sender: TObject);
var
hFile:    THandle;
dRead:    DWORD;
dWritten: DWORD;
pData:    Pointer;
dSize:    DWORD;
begin
  hFile := CreateFile(PChar(sFile), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
  if hFile <> INVALID_HANDLE_VALUE then
  begin
    SetFilePointer(hFile, HexToInt(lsSections.Selected.SubItems[2]), nil, FILE_BEGIN);
    dSize := HexToInt(lsSections.Selected.SubItems[3]);
    GetMem(pData, dSize);
    ReadFile(hFile, pData^, dSize, dRead, nil);
    CloseHandle(hFile);

    if dRead <> 0 then
    begin
      hFile := CreateFile(PChar(ExtractFileName(sFile) + '-section-' + IntToStr(lsSections.Selected.Index) + '.dmp'), GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_ALWAYS, 0, 0);
      SetFilePointer(hFile, 0, nil, FILE_BEGIN);
      WriteFile(hFile, pData^, dSize, dWritten, nil);
      CloseHandle(hFile);
    end;
    FreeMem(pData, dSize);
  end;
end;

procedure TfrmSections.EditSection1Click(Sender: TObject);
begin
  frmSectionEditor.Show;
end;

procedure TfrmSections.HexViewer1Click(Sender: TObject);
begin
  frmHex.Hex1.Undo;
  frmHex.Hex1.InsertBuffer(PChar(ReadSection(sFile, HexToInt(lsSections.Selected.SubItems[2]), HexToInt(lsSections.Selected.SubItems[3]))), HexToInt(lsSections.Selected.SubItems[3]), 0, '');
  frmHex.Show;
  frmHex.Hex1.SelStart := 0;
end;

end.
