📄 dededisasm.pas
字号:
s,sc : String;
b : Byte;
OffsInfStr : TOffsInfStruct;
RefLst, SmartLst : TStringList;
bFound : Boolean;
Begin
Result:='';
// saves the PEStream postion
bk:=PEStream.Position;
// Gets the physical offset of the addres of
// the procedure thet is being called
phys:=RVAConverter.GetPhys(HEX2DWORD(DWORD2HEX(AwdOffset)));
if (phys<0) or (phys+_PatternSize>=PEStream.Size) then exit;
if bSMARTMODE Then
begin
sc:=GetRegVal(rgEAX);
OffsInfStr:=OffsInfArchive.GetOffsInfoByClassName(sc);
end;
RefLst:=TStringList.Create;
SmartLst:=TStringList.Create;
Try
PEStream.Seek(phys,soFromBeginning);
// reads the procedure bytes in buff1
PEStream.ReadBuffer(buff[1],_PatternSize);
// if the first read byte is not found in the
// First byte set then skip searching fo that reference
if FirstByteSet*[buff[1]]=[] then Exit;
// removes all absolute offsets
UnlinkCalls(buff,0,rva);
// Loops among the all loaded symbols
For i:=0 To SymbolsList.Count-1 Do
Begin
// Gets a symbol
Sym:=TDeDeSymbol(SymbolsList[i]);
// the current symbol file is not for the current Delphi version
// so process next DSF
if (Sym.Mode and DelphiVestionCompability)=0 then Continue;
// initializes the streams
Sym.Sym.Seek(0,soFromBeginning);
Sym.Str.Seek(0,soFromBeginning);
// Loops among the entries
For j:=0 To Sym.Count-1 Do
Begin
// Reads the pattern
Sym.Sym.ReadBuffer(buff1[1],_PatternSize);
// and compare it to buff1
If CompareMem(@buff[1],@buff1[1],_PatternSize) Then
Begin
// If equal, then a reference is found
// goes to the offset of the procedure name
// in the DeDeSymbol object
Sym.Str.Seek(Sym.Index[j],soFromBeginning);
Sym.Str.ReadBuffer(b,1);
SetLength(s,b);
// Reads the procedure name
Sym.Str.ReadBuffer(s[1],b);
// And add it to the reference list
RefLst.Add(s);
End;
End;
End;
Finally
// restores the PEStream position
PEStream.Seek(bk,soFromBeginning);
// Gets only those DSF references in which names
// the EAX class name or it's parents is included
if (bSMARTMODE) and (sc<>'') then
begin
bFound:=False;
For i:=0 to RefLst.Count-1 Do
if Pos(LowerCase(sc),LowerCase(RefLst[i]))<>0
then begin
bFound:=True;
SmartLst.Add(RefLst[i]);
end;
if (not bFound) and (OffsInfStr<>nil) then
for j:=0 to OffsInfStr.FHierarchyList.Count-1 do
begin
sc:=OffsInfStr.FHierarchyList[j];
For i:=0 to RefLst.Count-1 Do
if Pos(sc,RefLst[i])<>0
then begin
bFound:=True;
SmartLst.Add(RefLst[i]);
end;
if bFound then Break;
end;
if bFound then RefLst.Assign(SmartLst);
end;
// Max 6 references
While RefLst.Count>MAX_DSF_REFERENCES_COUNT do RefLst.Delete(RefLst.Count-1);
For i:=0 to RefLst.Count-1 Do
if i=0 then RefLst[i]:=sREF_TEXT_REF_DSF+' '+RefLst[i]
else RefLst[i]:=sREF_TEXT_REF_DSF_OR+' '+RefLst[i];
RefLst.Add('|');
Result:=#13#10+RefLst.Text;
RefLst.Free;
SmartLst.Free;
End;
End;
// Description : Finds CALL references
//
// Last Modified : N/A
//
Function RefCall(var ss : String; AwdOffset : DWORD) : String;
var b1,b2,b3,b4 : Byte;
phys,ofs,bk : DWORD;
s : String;
i,j : Integer;
cd : TClassDumper;
Begin
Result:='';
phys:=RVAConverter.GetPhys(AwdOffset);
if phys>=PEStream.Size Then Exit;
// Reads the first 2 bytes of the procedure
// that is being called.
bk:=PEStream.Position;
Try
PEStream.Seek(phys,soFromBeginning);
PEStream.ReadBuffer(b1,1);
PEStream.ReadBuffer(b2,1);
//In the case of import call
If (b1=$FF) and (b2=$25) Then
Begin
PEStream.ReadBuffer(b1,1);
PEStream.ReadBuffer(b2,1);
PEStream.ReadBuffer(b3,1);
PEStream.ReadBuffer(b4,1);
ofs:=b1+b2*256+256*256*(b3+b4*256);
// Gets the import function name
If GlobGetImports Then
begin
//Dont
Try
s:=GetImportReference(DWORD2HEX(ofs));
Except
on e:Exception do Raise Exception.Create('Cant resolve import reference ');
End;
If s<>'' Then Result:=#13#10+sREF_TEXT_IMPORT+' '+s+'()'#13#10+'|'+#13#10;
end;
End;
Finally
PEStream.Seek(bk,soFromBeginning);
End;
// If no other call reference is found then
// searches for a SymbolReference
If Result='' Then Result:=GetSymbolReference(AwdOffset);
// This should find published/VIRT/USER
// procedure call references
if Result=#13#10'|'#13#10 then
If ClsDmp<>nil Then
For j:=0 To DeDeMainForm.ClassesDumper.Classes.Count-1 Do
Begin
cd:=TClassDumper(DeDeMainForm.ClassesDumper.Classes[j]);
For i:=0 To cd.MethodData.Count-1 Do
If TMethodRec(cd.MethodData.Methods[i]).dwRVA=AwdOffset
Then Begin
Result:=#13#10+sREF_TEXT_PUBLISHED+' '+cd.FsClassName+'.'+TMethodRec(cd.MethodData.Methods[i]).sName+'()'#13#10+'|'+#13#10;
Exit;
End;
End;
// If no other call reference is found
// then name proc UNITOFFSET.PROC_OFFSET
if Result=#13#10'|'#13#10 then
if bUnitReferences then
begin
For i:=0 To DeDeMainForm.ClassesDumper.PackageInfoTable.dwUnitCount-2 do
if (AwdOffset>=DeDeMainForm.ClassesDumper.PackageInfoTable.UnitsStartPtrs[i])
and (AwdOffset<=DeDeMainForm.ClassesDumper.PackageInfoTable.UnitsStartPtrs[i+1])
then begin
Result:=#13#10+sREF_TEXT_REF_DSF+' '+DeDeMainForm.ClassesDumper.PackageInfoTable.UnitsNames[i]+
'.Proc_'+DWORD2HEX(AwdOffset)+Result;
Break;
end;
end
else Result:=#13#10#13#10;
End;
// Gets the ClassName of the ControlName
// Uses the DFMText TStringList to find it
Function GetControlClass(sControlName : String) : String;
var i,j : Integer;
Begin
Result:='N.A.';
// If DFMText is not loaded then use the Ex function
// The class name is get from ClsDmp
If (DFMText.Count=0) and (ClsDmp<>nil) then Result:=GetControlClassEx(ClsDmp.FsClassName,sControlName)
else
For i:=0 To DFMText.Count-1 Do
Begin
j:=Pos(sControlName+':',DFMText[i]);
If j<>0 Then
Begin
Result:=Copy(DFMText[i],j+2+Length(sControlName),Length(DFMText[i])-j-Length(sControlName)-1);
Break;
End;
End;
End;
// Gets the ClassName of the ControlName
// Uses the DFMText TStringList to find it
Function GetControlClassEx(sClassName, sControlName : String) : String;
var i,j : Integer;
blah : TStringList;
Begin
Result:='N.A.';
blah:=DeDeMainForm.ClassesDumper.GetDFMTXTDATA(sClassName);
if blah=nil then exit;
For i:=0 To blah.Count-1 Do
Begin
j:=Pos(sControlName+':',blah[i]);
If (j<>0) and (Pos('''',blah[i])=0) Then
Begin
Result:=Copy(blah[i],j+2+Length(sControlName),Length(blah[i])-j-Length(sControlName)-1);
Break;
End;
End;
End;
// Gets the event prototype searching the class data provided from classes.lst
Function GetEventPrototype(sClassName, sHandlerName : String) : String;
var i,j,jPos : Integer;
blah : TStringList;
sType, sEvent, sEventType : String;
Begin
Result:='procedure(Sender : TObject);';
blah:=DeDeMainForm.ClassesDumper.GetDFMTXTDATA(sClassName);
if blah=nil then exit;
sEvent:='';
For i:=1 to blah.Count-1 Do
begin
j:=Pos(' = '+sHandlerName,blah[i]);
If (j<>0) and (Pos('''',blah[i])=0) Then
begin
sEvent:=Trim(Copy(blah[i],1,j));
break;
end;
end;
if sEvent='' then exit;
blah:=DeDeMainForm.ClassInfoList;
if blah=nil then exit;
jPos:=0;
For i:=0 To blah.Count-1 Do
Begin
j:=Pos(sType+'(',blah[i]);
If (j<>0) Then
Begin
jPos:=i;
break;
End;
End;
if jPos=0 then exit;
sEventType:='';
For i:=jPos to blah.Count-1 Do
begin
j:=Pos(sEvent+':',blah[i]);
If (j<>0) Then
begin
sEventType:=Trim(Copy(blah[i],j+1,Length(blah[i])-j));
break;
end;
end;
if sEventType='' then exit;
For i:=0 To blah.Count-1 Do
Begin
j:=Pos(sEventType+'=',blah[i]);
If (j<>0) Then
Begin
Result:=Copy(blah[i],j+1,Length(blah[i])-j);
break;
End;
End;
end;
// Description : Finds a control references
//
// TODO : ControlIDs and ControlNames should be
// cut from DeDeDisAsm and ClsDmp.Fields object
// should be used instead
//
// Last Moified : N/A
//
Function ControlRef(dta : String; sReg, sDestReg : String): String;
var ce, cn, s,st : String;
i : Integer;
cls : TClassDumper;
Begin
s:=''; dta:=dta+']'; i:=1;
while dta[i]<>']' do inc(i);
dta:=copy(dta,1,i-1);
// Offset list is stored with this mask (8 zeros)
While Length(dta)<8 Do dta:='0'+dta;
// Get Owner Class Name from Class Emulator
ce:=DeDeClassEmulator.GetRegVal(Str2TRegister(sReg));
// Get TClassDump data from class emulator class name
cls:=nil;
if (GlobBEmulation) and (not GlobCBuilder) and (ce<>'')
then cls:=DeDeMainForm.ClassesDumper.GetClassWFields(ce);
// If not such class then use the current !!!
if cls=nil then i:=ControlIDs.IndexOf(dta)
else i:=cls.FieldData.GetFieldIdx(HEX2DWORD(dta));
If i<>-1 Then
Begin
if cls=nil then cn:=ControlNames[i]
else cn:=cls.FieldData.GetFieldName(HEX2DWORD(dta));
if cls=nil then st:=GetControlClass(cn)
else st:=GetControlClassEx(ce,cn);
if cls=nil then ce:='' else ce:=ce+'.';
Result:=#13#10+sREF_TEXT_CONTROL+' '+ce+cn+' : '+st+''+#13#10+'|'+#13#10;
// Change Class Emulator Register Classes
DeDeClassEmulator.SetRegVal(Str2TRegister(sDestReg),st);
bControlRef:=True;
End
Else Begin
if (GlobBEmulation) and (ce<>'') then
begin
bControlRef:=True;
if OffsInfArchive.GetReferenceEx(ce,HEX2DWORD(dta),rtMOV,cn,st)
then begin
if st<>'' then cn:=ce+'.'+cn+' : '+st
else cn:=ce+'.'+cn;
Result:=#13#10+sREF_TEXT_FIELD+' '+cn+#13#10+'|'+#13#10;
// Set That Source has been accessed - Inc Time-To-Live
ExpireCounter[Str2TRegister(sReg)]:=ExpireCount;
end
else if HEX2DWORD(dta)<>0 then
begin
st:='';
cn:=ce+'.'+'OFFS_'
// Remove the first 4 zeros
+Copy(dta,5,4);
Result:=#13#10+sREF_TEXT_FIELD+' '+cn+#13#10+'|'+#13#10;
end;
// Change Class Emulator Register Classes
DeDeClassEmulator.SetRegVal(Str2TRegister(sDestReg),st);
end
// In sDestReg is put unrecognized public field of the Form - so cut this register
else ClearRegister(Str2TRegister(sDestReg));
End;
End;
// Returns true if the current instruction is
// the beginning of a TRY block
Function IsTryExceptBlock : Boolean;
var bk : DWORD;
ph : DWORD;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -