Ðåôåðàò: Ñåìàíòè÷åñêèé àíàëèç ñòðóêòóðû EXE ôàéëà è äèñàññåìáëåð (ñ ïðèìåðàìè è èñõîäíèêàìè), âèðóñîëîãèÿ
Operand1[0] := Chr(CharPos-k);
Move(Line[k], Operand1[1], CharPos-k);
end;
end;
SkipBTC; if Stop then goto EndParseLine;
(* second operand *)
k := CharPos;
SkipUBTC;
(* Operand2 := Copy(Line, k, CharPos-k); *)
Operand2[0] := Chr(CharPos-k);
Move(Line[k], Operand2[1], CharPos-k);
(* check for type override operators *)
case Operand2[1] of
'B': if Operand2 = 'BYTE' then begin
TypeOverride := B;
SkipBT; if Stop then goto EndParseLine;
SkipUBT;
SkipBT; if Stop then goto EndParseLine;
k := CharPos;
SkipUBTC;
(* Operand2 := Copy(Line, k, CharPos-k); *)
Operand2[0] := Chr(CharPos-k);
Move(Line[k], Operand2[1], CharPos-k);
end;
'W': if Operand2 = 'WORD' then begin
TypeOverride := W;
SkipBT; if Stop then goto EndParseLine;
SkipUBT;
SkipBT; if Stop then goto EndParseLine;
k := CharPos;
SkipUBTC;
(* Operand2 := Copy(Line, k, CharPos-k); *)
Operand2[0] := Chr(CharPos-k);
Move(Line[k], Operand2[1], CharPos-k);
end;
'D': if Operand2 = 'DWORD' then begin
TypeOverride := D;
SkipBT; if Stop then goto EndParseLine;
SkipUBT;
SkipBT; if Stop then goto EndParseLine;
k := CharPos;
SkipUBTC;
(* Operand2 := Copy(Line, k, CharPos-k); *)
Operand2[0] := Chr(CharPos-k);
Move(Line[k], Operand2[1], CharPos-k);
end;
'F': if Operand2 = 'FAR' then begin
TypeOverride := F;
SkipBT; if Stop then goto EndParseLine;
k := CharPos;
SkipUBTC;
(* Operand2 := Copy(Line, k, CharPos-k); *)
Operand2[0] := Chr(CharPos-k);
Move(Line[k], Operand2[1], CharPos-k);
end
end
end;
EndParseLine: end;
procedure Pass1;
var
_Offset,
_Label, _Mem,
Status : INTEGER;
function OperandType(var Operand: STR12): ReferenceTypes;
begin
case Operand[2] of
'X': case Operand[1] of
'A': OperandType := W;
'B': OperandType := W;
'C': OperandType := W;
'D': OperandType := W
end;
'S': case Operand[1] of
'C': OperandType := W;
'D': OperandType := W;
'E': OperandType := W;
'S': OperandType := W
end;
'L': case Operand[1] of
'A': OperandType := B;
'B': OperandType := B;
'C': OperandType := B;
'D': OperandType := B
end;
'H': case Operand[1] of
'A': OperandType := B;
'B': OperandType := B;
'C': OperandType := B;
'D': OperandType := B
end;
'I': case Operand[1] of
'S': OperandType := W;
'D': OperandType := W
end;
'P': case Operand[1] of
'B': OperandType := W;
'S': OperandType := W
end
end (* case *)
end;
procedure MemoryOperand(var Operand, OperandX: STR12; Position: BYTE;
ExplicitType: ReferenceTypes);
begin
if (Ord(Operand[0])=6) then begin
if (Operand[1] = '[') AND (Operand[6] = ']') then begin
Val ( '$'+Copy(Operand, 2, 4), _Mem, Status);
if Status = 0 then begin (* valid 4 digit hex number *)
case ExplicitType of
N: ExplicitType := W; (* indirect jump or call *)
F: ExplicitType := D (* far indirect jump or call *)
end;
if (ExplicitType <> None) then
StoreReference (_Offset, _Mem, ExplicitType, Position)
else
StoreReference (_Offset, _Mem, OperandType(OperandX), Position);
end (* valid memory operand *)
end (* [,] *)
end (* length = 6 *)
end;
begin (* Pass 1 *)
gotoXY(1,25); Write('Pass 1 , Line ');
LineCount := 0;
while NOT EOF(f_in) do begin
readln(f_in, Line);
LineCount := succ(LineCount);
if (LineCount and $000F) = 0 then begin
gotoXY(16,25);
write(LineCount:3)
end;
ParseLine(ParsedLine);
with ParsedLine do begin
(****
gotoxy(12,wherey);writeln(offset,'|','|',opcode,'|',
operand1,'|',operand2,'|');
****)
Val ( '$'+Offset, _Offset, Status);
if Status = 0 then begin
Status := -1;
(* check for opcodes with CODE_LABEL operands *)
case OpCode[1] of
'J': begin
Val ( '$'+Operand1, _Label, Status);
if Status <> 0 then begin
if (OpCode = 'JMP') AND (TypeOverride=None) then
TypeOverride := N; (* try indirect NEAR jump *)
end
end;
'C': if OpCode = 'CALL' then begin
Val ( '$'+Operand1, _Label, Status);
if (Status <> 0) AND (Operand1[5]=':') then begin
Val('$'+Copy(Operand1, 6, 4), _Label, Status);
if Status = 0 then StoreReference (_Offset, _Label, F, 1);
Status := -1;
end
end;
'L': if (OpCode = 'LOOP') OR
(OpCode = 'LOOPZ') OR (OpCode = 'LOOPNZ')
then Val ( '$'+Operand1, _Label, Status);
'P': if OpCode = 'PUSH' then TypeOverride := W
else if OpCode = 'POP' then TypeOverride := W;
end (* case *);
if Status = 0 then begin (* valid near label *)
StoreReference (_Offset, _Label, N, 1)
end;
MemoryOperand(Operand1, Operand2, 1, TypeOverride);
MemoryOperand(Operand2, Operand1, 2, TypeOverride);
end (* valid offset *)
end (* with ParsedLine *)
end (* while *);
gotoXY(16,25); write(LineCount:3);
end (* Pass 1 *);
procedure Pass2;
type
PrefixTypes = (NoPrefix, REP, REPZ, REPNZ, LOCK, CS, DS, ES, SS);
var
k, _Offset,
NextOffset,
NextRef,
Status : INTEGER;
Prefix : PrefixTypes;
ASMLine : STR80;
function TestPrefix: BOOLEAN;
var
HexByte, Status: INTEGER;
begin
case ParsedLine.OpCode[3] of (* test for prefix opcodes *)
':', 'P', 'C' : begin
Val('$'+ParsedLine.HexCode, HexByte, Status);
case HexByte of
$2E: begin Prefix := CS; TestPrefix := true end;
$26: begin Prefix := ES; TestPrefix := true end;
$3E: begin Prefix := DS; TestPrefix := true end;
$36: begin Prefix := SS; TestPrefix := true end;
$F2: begin Prefix := REPNZ; TestPrefix := true end;
$F3: begin Prefix := REPZ; TestPrefix := true end;
$F0: begin Prefix := LOCK; TestPrefix := true end;
else TestPrefix := false
end
end
else TestPrefix := false
end;
end;
begin (* Pass 2 *)
gotoXY(1,25); Write('Pass 2 , Line ');
NextOffset := 0;
NextRef := 0;
Prefix := NoPrefix;
LineCount := 0;
while NOT EOF(f_in) do begin
readln(f_in, Line);
LineCount := succ(LineCount);
if (LineCount and $000F) = 0 then begin
gotoXY(16,25);
write(LineCount:3)
end;
ParseLine(ParsedLine);
if NOT TestPrefix then begin
with ParsedLine do begin
if (Prefix = REPZ) OR (Prefix = REPNZ) then begin
if (Opcode[1] IN ['M', 'L', 'S']) AND (Ord(OpCode[0])<>0) then
Prefix := REP
end;
Val ( '$'+Offset, _Offset, Status);
if Status = 0 then begin
if _Offset = SymbolTable[NextOffset].offset then begin
case SymbolTable[NextOffset].reftype of
N: begin
Move(Operand1[1], Operand1[3], 4);
Operand1[0] := succ(succ(Operand1[0]));
Operand1[1] := 'L';
Operand1[2] := '_';
Ñòðàíèöû: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17