unit Gen1;
(************************************************************************
Copyright (C) 2009, 2010 by Russell J. Peters, Roger Aelbrecht,
Eric W. Engler and Chris Vleghert.
This file is part of TZipMaster Version 1.9.
TZipMaster is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TZipMaster is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TZipMaster. If not, see <http://www.gnu.org/licenses/>.
contact: problems@delphizip.org (include ZipMaster in the subject).
updates: http://www.delphizip.org
DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip
************************************************************************)
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Panel1: TPanel;
Button2: TButton;
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
// procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
funcs: TStringList;
template: TStringList;
public
function LoadFuncList(const fn: string): Integer;
function LoadTemplate(const fn: string): Integer;
function MakeAsm(const aName, sName: string): Integer;
// function MakeAsm(dll: Integer; const fn: String): Integer;
function MakeFunc(dst: TStrings; const func: string; dll: Integer): integer;
// function Process(const base: string): Integer;
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//#define DLL_KERNEL32 0
//#define DLL_USER32 1
//#define DLL_SHELL32 2
const
MAX_DLL = 2;
DLL_Names: array [0..MAX_DLL] of string = (
'KERNAL' , 'USER', 'SHELL');
// ASM_Names: array [0..MAX_DLL] of string = (
// 'DZKnl.asm', 'DZUsr.asm', 'DZShl.asm');
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(funcs);
FreeAndNil(template);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
funcs := TSTringList.Create;
template := TStringList.Create;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
l: integer;
begin
try
l := LoadFuncList('..\FuncList.txt');
except
l := -999;
end;
if l < 1 then
begin
Memo1.Lines.Add(' could not load function list');
exit;
end;
try
l := MakeAsm('..\jmps.asm', '..\funcs.cpp');
except
l := -999;
end;
if l < 12 then
begin
Memo1.Lines.Add(' could not write asm');
exit;
end;
end;
function TForm1.LoadFuncList(const fn: string): Integer;
var
good: boolean;
i: integer;
n: integer;
c: integer;
s: string;
d: string;
f: string;
begin
funcs.Clear;
funcs.LoadFromFile(fn);
i := funcs.Count -1;
while i >= 0 do
begin
good := false;
s := StringReplace(funcs[i], ' ', '', [rfReplaceAll]);
if (Length(s) > 6) and (s[1] in ['A'..'Z']) then
begin
c := Pos(',', s);
if c >= 5 then
begin
d := copy(s, 1, c-1);
for n := 0 to MAX_DLL do
if d = Dll_Names[n] then
begin
// check the function
f := copy(s, c+1, 70);
if (length(f) >= 4) and (f[1] in ['a'..'z', 'A'..'Z', '_']) then
begin
good := True;
end;
break;
end;
end;
end;
if not good then
begin
Memo1.Lines.Add(' removed ' + funcs[i]);
funcs.Delete(i); // remove rubbish
end;
dec(i);
end;
Result := funcs.Count;
end;
function TForm1.LoadTemplate(const fn: string): Integer;
begin
template.Clear;
template.LoadFromFile(fn);
Result := template.Count;
end;
function DllNo(const dname: string): Integer;
begin
result := 0;
while Result <= MAX_Dll do
begin
if dname = Dll_Names[Result] then
exit;
inc(Result);
end;
Result := -1;
end;
function TForm1.MakeAsm(const aName, sName: string): Integer;
var
// ids: integer;
asmtxt: TStringList;
nametxt: TStringList;
func: string;
i: integer;
c: integer;
dll: integer;
d: string;
s: string;
begin
Result := 10;
nametxt := nil;
asmtxt := TStringList.Create;
try
nametxt := TStringList.Create;
asmtxt.Add(' .486p');
asmtxt.Add(' model flat');
asmtxt.Add(' ');
for i := 0 to Funcs.Count - 1 do
begin
s := funcs[i];
c := Pos(',', s);
if c >= 5 then
begin
d := copy(s, 1, c-1);
dll := DllNo(d);
if dll < 0 then
begin
Memo1.Lines.Add(' failed to make: ' + s);
exit;
end;
// get the function
func := copy(s, c+1, 70);
asmtxt.Add(' extern z' + func + ' : proc');
asmtxt.Add(' global ' + func + ' : proc');
end;
end;
asmtxt.Add(' ');
asmtxt.Add(' public _u_jmps');
asmtxt.Add(' ');
asmtxt.Add('_DATA segment dword public use32 ''DATA''');
asmtxt.Add('_u_jmps:');
for i := 0 to Funcs.Count - 1 do
begin
s := funcs[i];
c := Pos(',', s);
if c >= 5 then
begin
// get the function
func := copy(s, c+1, 70);
asmtxt.Add(' dd z' + func);
end;
end;
asmtxt.Add('_DATA ends');
asmtxt.Add(' ');
asmtxt.Add('_TEXT segment dword public use32 ''CODE''');
nametxt.Add(' ');
// nametxt.Add('STRINGTABLE LANGUAGE 9, 1 // 0409');
nametxt.Add('const char *func_names[] =');
nametxt.Add('{');
// ids := 512;
Result := 0;
for i := 0 to Funcs.Count - 1 do
begin
s := funcs[i];
c := Pos(',', s);
if c >= 5 then
begin
d := copy(s, 1, c-1);
dll := DllNo(d);
if dll < 0 then
begin
Memo1.Lines.Add(' failed to make: ' + s);
Result := -1;
break;
end;
// get the function
func := copy(s, c+1, 70);
asmtxt.Add(func + ' proc near');
asmtxt.Add(' jmp dword ptr [_u_jmps + ' + IntToStr(i * 4) + ' ]');
asmtxt.Add(func + ' endp');
asmtxt.Add(' ');
// nametxt.Add(' ' + IntToStr(ids) + ', "' + IntToStr(dll) + func + '"');
nametxt.Add(' "' + IntToStr(dll) + func + '",');
inc(Result);
// inc(ids);
end;
end;
asmtxt.Add('_TEXT ends');
asmtxt.Add(' ');
asmtxt.Add(' end');
// nametxt.Add('} ');
nametxt.Add(' 0');
nametxt.Add('};');
if Result > 0 then
begin
asmtxt.SaveToFile(aname);
nametxt.SaveToFile(sName);
end;
finally
asmtxt.Free;
FreeAndNil(nametxt);
end;
end;
function TForm1.MakeFunc(dst: TStrings; const func: string; dll: Integer):
integer;
var
lno: integer;
active: boolean;
s: string;
dno: string;
begin
Memo1.Lines.Add('Making: ' + DLL_Names[dll] + '.' + func);
Result := 0;
active := false;
dno := IntToStr(dll);
for lno := 0 to template.Count -1 do
begin
s := template[lno];
if (length(s) >= 3) and (copy(s, 1, 3) = ';;;') then
begin
if active then
break;
active := true;
continue;
end;
if active then
begin
s := StringReplace(s, 'NAME', func, [rfReplaceAll]);
s := StringReplace(s, 'DLL', dno, [rfReplaceAll]);
dst.Add(s);
inc(Result);
end;
end;
end;
end.