Autor Beitrag
Jan2k
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18



BeitragVerfasst: Do 15.12.05 19:18 
Hallo

Ich programmiere gerade an dieser DLL. Nur leider funktioniert sie nicht! Wie ihr vielleicht am Code erkennt bin ich ein N00B. Diese DLL sollte den Speicher eines anderen Programmes durchsuchen und die gefundenen Adressen nach Wert sortieren. Ich wäre euch sehr zu Dank verbunden wenn mir jemand diesen Code verbessern könnte. BITTE! :roll:


ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
library Project1;



uses
  SysUtils,
  Classes;


{$R *.RES}  

var
puffer : Array[10000000 .. 20000000] of DWord;
a : Array[1 .. 5] of DWord;
b : Array[1 .. 5] of DWord;
c : Array[1 .. 5] of DWord;
d : Array[1 .. 5] of DWord;
e : Array[1 .. 5] of DWord;
f : Array[1 .. 5] of DWord;
g : Array[1 .. 5] of DWord;
h : Array[1 .. 5] of DWord;
i : Array[1 .. 5] of DWord;
j : Array[1 .. 5] of DWord;
k : Array[1 .. 5] of DWord;
l : Array[1 .. 5] of DWord;
x : Integer
ya : Integer
yb : Integer
yc : Integer
yd : Integer
ye : Integer
yf : Integer
yg : Integer
yh : Integer
yi : Integer
yj : Integer
yk : Integer
yl : Integer
WindowName  :  integer;
ProcessId  :  integer;
ThreadId  :  integer;
WHandle  :  Integer;
BytesRead : DWord;
p : pointer;


function rm(serial: integer,titel: string): integer; stdcall;
begin
WindowName  :=  FindWindow(nil,titel);
ThreadId  :=  GetWindowThreadProcessId(WindowName,@ProcessId);  
WHandle  :=  OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId);  

x := 10000000;
p := ptr(x);
ReadProcessMemory( WHandle, p, @puffer[10000000], SizeOf(Puffer), BytesRead );

repeat
x := x + 1;
case puffer[x] of
54321:
ya := ya + 1;
a[ya] = x;
54322:
yb := yb + 1;
b[yb] = x;
54323:
yc := yc + 1;
c[yc] = x;
54324:
yd := yd + 1;
d[yd] = x;
54325:
ye := ye + 1;
e[ye] = x;
54326:
yf := yf + 1;
f[yf] = x;
54327:
yg := yg + 1;
g[yg] = x;
54328:
yh := yh + 1;
h[yh] = x;
54329:
yi := yi + 1;
i[yi] = x;
54330:
yj := yj + 1;
j[yj] = x;
54331:
yk := yk + 1;
k[yk] = x;
54332:
yl := yl + 1;
l[yl] = x;
end;
until x = 20000000

end.


THX
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 15.12.05 20:54 
user profile iconJan2k hat folgendes geschrieben:
Nur leider funktioniert sie nicht!

Ah ja. Schön. Und teilst du uns auch mit WAS nicht funktioniert? :roll:

Zitat:

Wie ihr vielleicht am Code erkennt bin ich ein N00B. Diese DLL sollte den Speicher eines anderen Programmes durchsuchen und die gefundenen Adressen nach Wert sortieren.

Denkst du wirklich, dass es dir viel bringt, wenn du gleich mit so ziemlich dem schwersten Anfängst, was es gibt? Du hast keine Ahnung von Delphi, keine Ahnung von DLLs und wohl wenig Ahnung, wie das Betriebssystem überhaupt funktioniert. Keine guten Grundlagen dir helfen zu können so dass du es verstehst.
Alstar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 827



BeitragVerfasst: Do 15.12.05 21:33 
Du hast einfach den exports-Abschnitt vergessen

Alstar
DaRkFiRe
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 526

WinXP Home & Professional
C, C++, Delphi
BeitragVerfasst: Fr 16.12.05 00:05 
Jo und wenn String exportiert wird, sollte man sich mal über die Unit ShareMem informieren.

_________________
Lang ist der Weg durch Lehren - kurz und wirksam durch Beispiele! Seneca
Jan2k Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18



BeitragVerfasst: Mo 26.12.05 15:17 
Ich habe den Code jetzt mal so abgeändert wie ihr es gesagt habt. Jedoch bringt er mir jetzt immer einen Fehler bei der Variabeln-Deklaration. Kann mir da jemand helfen?

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
library Project1;

 

 

 
uses  
  SysUtils,  
  Classes;

 


{$R *.RES}    

 
var
puffer : Array[10000000 .. 20000000] of DWord;
a : Array[1 .. 5] of DWord;
b : Array[1 .. 5] of DWord;  
c : Array[1 .. 5] of DWord;
d : Array[1 .. 5] of DWord;  
e : Array[1 .. 5] of DWord;  
f : Array[1 .. 5] of DWord;  
g : Array[1 .. 5] of DWord;
h : Array[1 .. 5] of DWord;  
i : Array[1 .. 5] of DWord;  
j : Array[1 .. 5] of DWord;  
k : Array[1 .. 5] of DWord;
l : Array[1 .. 5] of DWord;  
x : Integer
ya : Integer
yb : Integer
yc : Integer
yd : Integer
ye : Integer
yf : Integer
yg : Integer
yh : Integer
yi : Integer
yj : Integer
yk : Integer
yl : Integer
WindowName  :  integer;
ProcessId  :  integer;  
ThreadId  :  integer;
WHandle  :  Integer;  
BytesRead : DWord;
p : pointer;  

 

 
function rm(serial: integer): integer; stdcall;
begin  
WindowName  :=  FindWindow(nil,titel);
ThreadId  :=  GetWindowThreadProcessId(WindowName,@ProcessId);    
WHandle  :=  OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId);


x := 10000000;  
p := ptr(x);
ReadProcessMemory( WHandle, p, @puffer[10000000], SizeOf(Puffer), BytesRead );  


repeat
x := x + 1;
case puffer[x] of
54321:
ya := ya + 1;
a[ya] = x;
54322:
yb := yb + 1;
b[yb] = x;
54323:
yc := yc + 1;
c[yc] = x;  
54324:
yd := yd + 1;  
d[yd] = x;
54325:  
ye := ye + 1;
e[ye] = x;
54326:
yf := yf + 1;
f[yf] = x;
54327:
yg := yg + 1;
g[yg] = x;
54328:
yh := yh + 1;
h[yh] = x;
54329:
yi := yi + 1;
i[yi] = x;
54330:
yj := yj + 1;
j[yj] = x;
54331:
yk := yk + 1;
k[yk] = x;
54332:
yl := yl + 1;
l[yl] = x;
end;
until x = 20000000


end.

exports
rm;

begin

end.


Vielen Dank
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 26.12.05 17:09 
user profile iconJan2k hat folgendes geschrieben:
Jedoch bringt er mir jetzt immer einen Fehler bei der Variabeln-Deklaration.

Auch nicht lehrnfähig oder? Schon in meiner ersten Antwort hab eich die gefragt, was nicht funktioniert. Jetzt verschweigst du uns schon wieder den Fehler. Das ist hiwer keine Quizsendung.
MadDoctor
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 88

Win XP Pro
Delphie 2005
BeitragVerfasst: Mo 26.12.05 17:24 
zu deinem fehler in den variablen ich glaube du hast da einige ; vergessen !

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
x : Integer
ya : Integer
yb : Integer
yc : Integer
yd : Integer
ye : Integer
yf : Integer
yg : Integer
yh : Integer
yi : Integer
yj : Integer
yk : Integer
yl : Integer


... da müssen noch ; hinter !

==========
[EDIT]
==========

Und ich würde dir noch anraten ein wenig übersichtlicher zu Programmieren, einrücken und mal eine zeile freilassen wirkt da wunder ;)

_________________
Grüße an alle Grevener [NRW]
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 28

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Mo 26.12.05 18:12 
und vielleicht mal ein anfänger tutorial lesen, das von christian zum beispiel ;)

bei delphi ist es denke ich noch am schwersten semikolons zu vergessen, bei php mach ich das auch des öfteren, aber dann auch nur, weil es ohne syntax highlighting alles ein wenig konfus aussieht ;)
Jan2k Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18



BeitragVerfasst: Mo 26.12.05 18:49 
Das Quiz geht in die nächste Runde...^^ Also, ich habe die Semikolons jetzt gesetzt, doch der Compiler brint mir immer den Fehler "Undefinierter Bezeichner: "DWord"" in der Zeile

ausblenden Delphi-Quelltext
1:
puffer : Array[10000000 .. 20000000] of DWord;					


Kann mir jemand sagen warum?
THX

Moderiert von user profile iconChristian S.: Delphi-Tags hinzugefügt.
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 28

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Mo 26.12.05 18:56 
F1 drücken, wenn du dann noch nicht weiter weißt -> Anfänger tuts lesen :!:
MadDoctor
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 88

Win XP Pro
Delphie 2005
BeitragVerfasst: Mo 26.12.05 18:59 
Ohne es wirklich zu wissen sag ich jetzt einfach mal:

Dieser eintrag:
ausblenden Delphi-Quelltext
1:
BytesRead : DWord;					


Muss ganz am Anfang stehen ...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
{...}
var
BytesRead : DWord;  //<----
puffer : Array[10000000 .. 20000000] of DWord;
a : Array[1 .. 5] of DWord;
b : Array[1 .. 5] of DWord;
c : Array[1 .. 5] of DWord;
d : Array[1 .. 5] of DWord;
e : Array[1 .. 5] of DWord;
f : Array[1 .. 5] of DWord;
{...}


Ich weis es nicht sicher, aber ich würde das jetzt mal sobegründen, wie soll eine variable gefunden werden die zu diesem zeitpunkt noch nicht existiert ?

_________________
Grüße an alle Grevener [NRW]
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 28

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Mo 26.12.05 19:32 
nee das ist nicht korrekt, DWord ist ja keine Variable :!:
MadDoctor
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 88

Win XP Pro
Delphie 2005
BeitragVerfasst: Mo 26.12.05 19:56 
Dann möchte ich mich für die fehl information entschuldigen :)

_________________
Grüße an alle Grevener [NRW]
Jan2k Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18



BeitragVerfasst: Mo 26.12.05 19:59 
Irgendetwas kann mit der Deklaration nicht stimmen... der bringt dort fast überall einen Fehler...
Alstar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 827



BeitragVerfasst: Mo 26.12.05 20:57 
user profile iconJan2k hat folgendes geschrieben:
Irgendetwas kann mit der Deklaration nicht stimmen... der bringt dort fast überall einen Fehler...

Wie schon von user profile iconLuckie bemerkt: Wir haben hier noch keine Kristallkugeln. Mit Informationen wie "Es funktioniert nicht" oder "Da tritt ein Fehler auf" können wir schlecht was anfangen.

Also: Wo bringt er welche Fehler?


Außerdem: Es ist reichlich unwahrscheinlich, dass er als erste Meldung "Undefinierter Bezeichner: "DWord"" herauswirft, da dieser Datentyp immer vorhanden ist (es sein denn, man hat sein Delphi gemodded / zerschossen).
Vielleicht hast Du nur einen Buchstabendreher drin?!

Alstar

Edit: Grammatikfehler verbessert
Alstar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 827



BeitragVerfasst: Mo 26.12.05 21:06 
Halt!
Ich revidiere meine Aussage! Ich hatte ursprünglich angenommen, DWord sei in der System.pas deklariert. Dem ist aber nicht so.

Also: Einfach die Unit Windows einbinden!

Alstar
Jan2k Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18



BeitragVerfasst: Mo 26.12.05 21:11 
Ich sehe Licht... Aber, wie kann ich diese Unit einbinden? THX
Alstar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 827



BeitragVerfasst: Mo 26.12.05 21:23 
Ich kann dem nur zustimmen:
user profile iconF34r0fTh3D4rk hat folgendes geschrieben:
[...] -> Anfänger tuts lesen :!:


Nimm am besten den Crashkurs Delphi von user profile iconChristian S.
Die Passage die Du suchst befindet sich hier

Alstar
Jan2k Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18



BeitragVerfasst: Mo 26.12.05 21:39 
Vielen Dank, ich bin jetzt ein ganzes Stück weiter gekommen. Nur leider erscheint jetzt wieder eine Fehlermeldung... und zwar "Konstantenausdruck erwartet" bei volgender Zeile:

ausblenden Delphi-Quelltext
1:
a[ya] = x;					


Hier den aktuellen Source:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
library Project1;









uses    
  SysUtils,
  Classes,
  Windows;







{$R *.RES}      

 

var
puffer : Array[10000000 .. 20000000] of DWord;  
a : Array[1 .. 5] of Integer;
b : Array[1 .. 5] of Integer;
c : Array[1 .. 5] of Integer;
d : Array[1 .. 5] of Integer;
e : Array[1 .. 5] of Integer;
f : Array[1 .. 5] of Integer;
g : Array[1 .. 5] of Integer;
h : Array[1 .. 5] of Integer;
i : Array[1 .. 5] of Integer;
j : Array[1 .. 5] of Integer;
k : Array[1 .. 5] of Integer;
l : Array[1 .. 5] of Integer;
x : Integer;
ya : Integer;
yb : Integer;
yc : Integer;
yd : Integer;
ye : Integer;
yf : Integer;
yg : Integer;
yh : Integer;
yi : Integer;
yj : Integer;
yk : Integer;
yl : Integer;
WindowName  :  integer;
ProcessId  :  integer;
ThreadId  :  integer;
WHandle  :  Integer;    
BytesRead : DWord;
p : pointer;






function rm(serial: integer): integer; stdcall;
begin
WindowName  :=  FindWindow(nil,'halo');
ThreadId  :=  GetWindowThreadProcessId(WindowName,@ProcessId);
WHandle  :=  OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId);



 
x := 10000000;
p := ptr(x);  
ReadProcessMemory( WHandle, p, @puffer[10000000], SizeOf(Puffer), BytesRead );    

 


repeat  
x := x + 1;  
case puffer[x] of
54321:
ya := ya + 1;  
a[ya] = x;
54322:
yb := yb + 1;  
b[yb] = x;
54323:  
yc := yc + 1;
c[yc] = x;    
54324:
yd := yd + 1;
d[yd] = x;
54325:    
ye := ye + 1;
e[ye] = x;
54326:
yf := yf + 1;  
f[yf] = x;
54327:
yg := yg + 1;
g[yg] = x;  
54328:
yh := yh + 1;  
h[yh] = x;
54329:
yi := yi + 1;
i[yi] = x;
54330:
yj := yj + 1;
j[yj] = x;
54331:
yk := yk + 1;
k[yk] = x;
54332:
yl := yl + 1;
l[yl] = x;
end;
until x = 20000000




end;


exports
rm;


begin


end.
MisterBum83
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 245
Erhaltene Danke: 2

WIN XP
Delphi 6
BeitragVerfasst: Di 27.12.05 20:33 
Ich hab dir das ganze mal überarbeitet. Hier der Code (keine DLL)

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  puffer: array[10000000..20000000] of DWord;
  a: array[1..5] of Integer;
  b: array[1..5] of Integer;
  c: array[1..5] of Integer;
  d: array[1..5] of Integer;
  e: array[1..5] of Integer;
  f: array[1..5] of Integer;
  g: array[1..5] of Integer;
  h: array[1..5] of Integer;
  i: array[1..5] of Integer;
  j: array[1..5] of Integer;
  k: array[1..5] of Integer;
  l: array[1..5] of Integer;
  x: Integer;
  ya: Integer;
  yb: Integer;
  yc: Integer;
  yd: Integer;
  ye: Integer;
  yf: Integer;
  yg: Integer;
  yh: Integer;
  yi: Integer;
  yj: Integer;
  yk: Integer;
  yl: Integer;
  WindowName: integer;
  ProcessId: integer;
  ThreadId: integer;
  WHandle: Integer;
  BytesRead: DWord;
  p: pointer;



implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
  WindowName := FindWindow(nil, PChar(Edit1.Text));
  if WindowName = 0 then
  begin
    MessageDlg('Nix gefunden!', mtWarning, [mbOK], 0);
    exit;
  end;
  ThreadId := GetWindowThreadProcessId(WindowName, @ProcessId);
  WHandle := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);

  x := 10000000;
  p := ptr(x);
  ReadProcessMemory(WHandle, p, @puffer[10000000], SizeOf(Puffer), BytesRead);

  repeat
    x := x + 1;
    case puffer[x] of
      54321:
        begin
          ya := ya + 1;
          a[ya] := x;
        end;
      54322:
        begin
          yb := yb + 1;
          b[yb] := x;
        end;
      54323:
        begin
          yc := yc + 1;
          c[yc] := x;
        end;
      54324:
        begin
          yd := yd + 1;
          d[yd] := x;
        end;
      54325:
        begin
          ye := ye + 1;
          e[ye] := x;
        end;
      54326:
        begin
          yf := yf + 1;
          f[yf] := x;
        end;
      54327:
        begin
          yg := yg + 1;
          g[yg] := x;
        end;
      54328:
        begin
          yh := yh + 1;
          h[yh] := x;
        end;
      54329:
        begin
          yi := yi + 1;
          i[yi] := x;
        end;
      54330:
        begin
          yj := yj + 1;
          j[yj] := x;
        end;
      54331:
        begin
          yk := yk + 1;
          k[yk] := x;
        end;
      54332:
        begin
          yl := yl + 1;
          l[yl] := x;
        end;
    end;
  until x = 20000000;
  MessageDlg('Fertig!', mtInformation, [mbOK], 0);
end;

end.