Интересно...
0 отговора
71 прегледа
Интересно...
Докато се рових за нещо намерих следния код - не съм го пробвал - но ако някой има желание и време - може да каже резултатите. Кода който е по долу би трябвало да връща всички класове ползвани от дадено приложение?!?
---
Колкото повече, толкова повече.
Here is the first hack I think you will be interested with:
A classes hack.
It enables you to find all classes used by a Delphi program ;-)
Just run it, specifying an instance handle and a call back function.
There is only 120 lines of code, so I decided to post it entirely.
If you think it's too big, next time I'll not post them.
(I let you searching for the way I do my hacks ;-))
I don't want any specific hack in exchange, but I hope you post your own
hack as I did ;-))
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
type
TPOSearchClassesCallBack = function (AClass: TClass): Boolean of object;
// Call back function must return whether we want other classes or not (in
case you are searching for a specific class, for example)
procedure POSearchClasses(AnInstance: Cardinal; ACallBack:
TPOSearchClassesCallBack);
type
PPointer = ^Pointer;
var
DosHeader: PIMAGE_DOS_HEADER;
NTHeader: PIMAGE_NT_HEADERS;
SectionHeader: PIMAGE_SECTION_HEADER;
pCodeBegin,
pCodeEnd: PChar;
pCode,
p: PChar;
function GetSectionHeader(const ASectionName: string): Boolean;
var
i: Integer;
begin
SectionHeader := PIMAGE_SECTION_HEADER(NTHeader);
Inc(PIMAGE_NT_HEADERS(SectionHeader));
Result := True;
for i := 0 to NTHeader.FileHeader.NumberOfSections - 1 do
begin
if Strlicomp(SectionHeader.Name, PChar(ASectionName),
IMAGE_SIZEOF_SHORT_NAME) = 0
then Exit;
Inc(SectionHeader);
end;
Result := False;
end;
function InRangeOrNil(APointer, pMin, pMax: Pointer): Boolean;
//begin
// Result := (APointer = nil) or
// ((Integer(pMin) <= Integer(APointer)) and (Integer(APointer)
<= Integer(pMax)));
asm // a little bit more efficient (no stack frame;-)
TEST APointer,APointer
JZ @_EndTrue
CMP APointer,pMin
JL @_EndFalse
CMP APointer,pMax
JLE @_EndTrue
@_EndFalse:
XOR EAX,EAX
RET
@_EndTrue:
MOV AL,1
RET
end;
function IsIdent(p: PChar): Boolean;
var
lg,
i: Integer;
begin
lg := ord(p^);
Inc(p);
Result := (lg > 0) and
(p^ in ['A'..'Z', 'a'..'z', '_']);
if not Result
then Exit;
for i := 2 to lg do
begin
inc(p);
if not (p^ in ['0'..'9', 'A'..'Z', 'a'..'z', '_'])
then begin
Result := False;
Exit;
end;
end;
end;
begin
{ Read the DOS header }
DosHeader := PIMAGE_DOS_HEADER(AnInstance);
if not DosHeader.e_magic = IMAGE_DOS_SIGNATURE
then // POUnrecognizedFileFormat;
Exit;
{ Read the NT header (PE format) }
NTHeader := PIMAGE_NT_HEADERS(Longint(DosHeader) + DosHeader.e_lfanew);
if IsBadReadPtr(NTHeader, SizeOf(IMAGE_NT_HEADERS)) or
(NTHeader.Signature <> IMAGE_NT_SIGNATURE)
then // PONotAPEFile
Exit;
{ Find the code section }
if not GetSectionHeader('CODE')
then // PONoInitializedData;
Exit;
{ Computes beginning & end of the code section }
pCodeBegin := PChar(AnInstance + SectionHeader.VirtualAddress);
pCodeEnd := pCodeBegin + (SectionHeader.SizeOfRawData - 3);
pCode := pCodeBegin;
while pCode < pCodeEnd do
begin
p := PPointer(pCode)^;
{ Search for a class }
if (p = (pCode - vmtSelfPtr)) and // Is it SelfPtr pointer?
InRangeOrNil(PPointer(p+vmtClassName)^, p, pCodeEnd) and
InRangeOrNil(PPointer(p+vmtDynamicTable)^, p, pCodeEnd) and
InRangeOrNil(PPointer(p+vmtMethodTable)^, p, pCodeEnd) and
InRangeOrNil(PPointer(p+vmtFieldTable)^, p, pCodeEnd) and
InRangeOrNil(PPointer(p+vmtTypeInfo)^, pCodeBegin, pCodeEnd) and
InRangeOrNil(PPointer(p+vmtInitTable)^, pCodeBegin, pCodeEnd) and
InRangeOrNil(PPointer(p+vmtAutoTable)^, pCodeBegin, pCodeEnd) and
InRangeOrNil(PPointer(p+vmtIntfTable)^, pCodeBegin, pCodeEnd) and
IsIdent(PPointer(p+vmtClassName)^)
then begin
if not ACallBack(TClass(p))
then Exit;
Inc(pCode, 4);
end
else Inc(pCode);
end;
end;
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
---
Колкото повече, толкова повече.