Ðåôåðàò: Ñåìàíòè÷åñêèé àíàëèç ñòðóêòóðû EXE ôàéëà è äèñàññåìáëåð (ñ ïðèìåðàìè è èñõîäíèêàìè), âèðóñîëîãèÿ
begin
if Entry1.reference = Entry2.reference then
Less := Ord(Entry1.reftype) < Ord(Entry2.reftype)
else (* compare the Entries as unsigned integers *)
if ((Entry1.reference XOR Entry2.reference) AND $8000) = 0 then
Less := Entry1.reference < Entry2.reference
else if (Entry1.reference AND $8000)= $8000 then Less := false
else Less := true;
end;
procedure StoreReference(_Offset, _Label: INTEGER; _RefType: ReferenceTypes;
_position: BYTE);
(* This procedure keeps a table of locations referenced *)
(* including the type of reference *)
begin
(* if _RefType = N then begin
write('label at ');
writeHexInt(_Offset); write(' value: ');
writeHexInt(_Label);
end else begin
write('var ref at ');
writeHexInt(_Offset); write(' to location ');
writehexint(_Label);
write(' type: ', rep[_RefType]);
end;
*)
with SymbolTable[Current_SymbolTable_Index] do begin
offset := _Offset;
reference := _Label;
reftype := _RefType;
position := _position
end;
Current_SymbolTable_Index := succ(Current_SymbolTable_Index);
if Current_SymbolTable_Index = SymbolTableSize then begin
writeln(' SymbolTable overflow ..., program halted');
halt
end;
end;
procedure ParseLine(var Result: ParseTypes);
(* Parses one line of disassembly output *)
label
EndParseLine;
type
CharSet = SET OF CHAR;
const
U : CharSet = [#0 .. #$FF];
var
j, k : INTEGER;
procedure SkipBT; (* Skip blanks and tabs *)
label
EndSkip;
begin
while CharPos <= Ord(Line[0]) do begin
case Line[CharPos] of
blank: CharPos := succ(CharPos);
tab: CharPos := succ(CharPos)
else goto EndSkip
end
end;
EndSkip: end;
procedure SkipBTC; (* Skip blanks, tabs and commas *)
label
EndSkip;
begin
while CharPos <= Ord(Line[0]) do begin
case Line[CharPos] of
blank: CharPos:=succ(CharPos);
comma: CharPos:=succ(CharPos);
tab: CharPos:=succ(CharPos)
else goto EndSkip
end
end;
EndSkip: end;
procedure SkipUBT;
label
EndSkip;
begin
(* Structered code was: *)
(* *)
(* while (Line[CharPos] IN U-[blank,tab,semicolon]) do *)
(* CharPos:=succ(CharPos) *)
(* while ( (Line[CharPos] <> blank) AND (Line[CharPos] <> tab) *)
(* AND (Line[CharPos] <> semicolon) ) *)
(* AND (CharPos <= Length(Line)) do CharPos:= succ(CharPos); *)
while CharPos <= Ord(Line[0]) do begin
case Line[CharPos] of
blank: goto EndSkip;
tab: goto EndSkip;
semicolon: goto EndSkip
else CharPos := succ(CharPos)
end
end;
EndSkip: end;
procedure SkipUBTC;
label
EndSkip;
begin
(* !! Structered code was: *)
(* *)
(* while ( (Line[CharPos] <> blank) *)
(* AND (Line[CharPos] <> tab) *)
(* AND (Line[CharPos] <> comma) *)
(* AND (Line[CharPos] <> semicolon) *)
(* AND (CharPos <= Length(Line) ) do *)
(* CharPos:= succ(CharPos); *)
while CharPos <= Ord(Line[0]) do begin
case Line[CharPos] of
blank: goto EndSkip;
comma: goto EndSkip;
tab: goto EndSkip;
semicolon: goto EndSkip
else CharPos := succ(CharPos)
end
end;
EndSkip: end;
function Stop: BOOLEAN;
begin
(* code was: Stop := (Line[CharPos]=semicolon) *)
(* OR (CharPos > Length(Line) ) *)
(* remark: this function should perhaps be inline *)
if CharPos > Ord(Line[0]) then Stop := true
else if Line[CharPos] = semicolon then begin
Stop := true;
Result.Comment := CharPos
end
else Stop := false
end;
function Appropriate: BOOLEAN;
(* Find out whether the current line should be parsed *)
var
k: INTEGER;
begin
CharPos := 1;
if (Length(Line)<5) OR (Line[1]='-') then Appropriate := false
else begin
k := 1;
while NOT (Line[k] IN [colon, semicolon]) AND (k<6) do k:= succ(k);
if Line[k] <> semicolon then begin
Appropriate := true;
if Line[k] = colon then begin
CharPos := k + 1;
end
end else begin
Appropriate := false;
Result.Comment := k
end
end
end;
begin (* ParseLine *)
with Result do begin
TypeOverride := None;
Offset[0] := Chr(0);
HexCode[0] := Chr(0);
OpCode[0] := Chr(0);
Operand1[0] := Chr(0);
Operand2[0] := Chr(0);
Comment := Ord(Line[0]) + 1;
if NOT Appropriate then goto EndParseLine;
SkipBT; if Stop then goto EndParseLine;
k := CharPos;
SkipUBT;
(* Offset := Copy(Line, k, CharPos-k); *)
Offset[0] := Chr(CharPos-k);
Move(Line[k], Offset[1], CharPos-k);
SkipBT; if Stop then goto EndParseLine;
k := CharPos;
SkipUBT;
(* HexCode := Copy(Line, k, CharPos-k); *)
HexCode[0] := Chr(CharPos-k);
Move(Line[k], HexCode[1], CharPos-k);
SkipBT; if Stop then goto EndParseLine;
k := CharPos;
SkipUBT;
(* OpCode := Copy(Line, k, CharPos-k); *)
OpCode[0] := Chr(CharPos-k);
Move(Line[k], OpCode[1], CharPos-k);
SkipBT; if Stop then goto EndParseLine;
(* at first operand *)
k := CharPos;
SkipUBTC;
(* Operand1 := Copy(Line, k, CharPos-k); *)
Operand1[0] := Chr(CharPos-k);
Move(Line[k], Operand1[1], CharPos-k);
case Operand1[1] of
'B': if Operand1 = 'BYTE' then begin
TypeOverride := B;
SkipBT; if Stop then goto EndParseLine;
SkipUBT;
SkipBT; if Stop then goto EndParseLine;
k := CharPos;
SkipUBTC;
(* Operand1 := Copy(Line, k, CharPos-k); *)
Operand1[0] := Chr(CharPos-k);
Move(Line[k], Operand1[1], CharPos-k);
end;
'W': if Operand1 = 'WORD' then begin
TypeOverride := W;
SkipBT; if Stop then goto EndParseLine;
SkipUBT;
SkipBT; if Stop then goto EndParseLine;
k := CharPos;
SkipUBTC;
(* Operand1 := Copy(Line, k, CharPos-k); *)
Operand1[0] := Chr(CharPos-k);
Move(Line[k], Operand1[1], CharPos-k);
end;
'D': if Operand1 = 'DWORD' then begin
TypeOverride := D;
SkipBT; if Stop then goto EndParseLine;
SkipUBT;
SkipBT; if Stop then goto EndParseLine;
k := CharPos;
SkipUBTC;
(* Operand1 := Copy(Line, k, CharPos-k); *)
Operand1[0] := Chr(CharPos-k);
Move(Line[k], Operand1[1], CharPos-k);
end;
'F': if Operand1 = 'FAR' then begin
TypeOverride := F;
SkipBT; if Stop then goto EndParseLine;
k := CharPos;
SkipUBTC;
(* Operand1 := Copy(Line, k, CharPos-k); *)
Ñòðàíèöû: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17