Witam,
mam taki problem że potrzebuje otrzymać dany wskaźnik na procedurę, którą znam tylko ze stringa. Dla przykładu chciałbym wywołać procedure którą mam w polu EDIT1, np 'ShowMessage'. Czy jest jakis odpowiednim takiego przeszukiwania procedur jak MethodAddress tylko nie dla danych klas a dla całej pamięci programu?
Pozdrawiam,
Kicinski Patryk
Jeżeli w programie zapisane są symbole debugujące, to może (ale tylko może) można by spróbować je odnaleźć i poszukać adresu procedury wewnątrz nich. Niczego wbudowanego afair nie ma.
Edit: chyba, że mowa o DLL-kach, wtedy masz do dyspozycji GetProcAddress
, lecz to nie zadziała w przypadku programów, ponieważ zwyczajowo takie symbole są strip-owane z exeka.
Btw, po co Ci takie coś?
Cos musi być na pewno skoro przy kompilacji nazwy każdej poszczególnej procedury czy to w bezposrednim kodzie programu czy modułach również są zapisywane. Łatwo mozna odnaleźć metody należące do klas po nazwie-chociazby MethodAddress z modulu TypInfo. Natomiast nie moge poradzic sobie z procedurami nie należącymi do zadnej klasy
Łatwo mozna odnaleźć metody należące do klas po nazwie-chociazby MethodAddress z modulu TypInfo.
Wyczuwasz delikatną różnicę pomiędzy metodą, a procedurą?
RTTI istnieją tylko dla klas, dlatego możesz użyć sobie MethodAddress
; nazwy nieeksportowanych procedur oraz funkcji są usuwane z kodu wynikowego, ponieważ są po prostu zbędne i zaśmiecałyby plik wykonywalny.
Probowalem z GetProcAddress ale u mnie to nie dziala. Chodzi o cos takiego by dziaał głupi przykład na ShowMessage. Siedze juz sporo czasu nad tym i nie mogę wymyslec.
Co do odpowiedzi Patryka - poki nie zwróciłeś uwagi na to dałbym sobie rękę uciąć że nazwy procedur są zapisywane w pliku wykonywalnym, teraz widzę że tych nie wchodzących w metody nie. Mialbys wiec jakis inny pomysl jak to rozwiązać prócz tysiąca ifów i odwołań do procedur/funkcji?
Mialbys wiec jakis inny pomysl jak to rozwiązać prócz tysiąca ifów i odwołań do procedur/funkcji?
Zacząłbym od pytania: po co?
Jednym z rozwiązań byłoby coś a'la mapa:
Var ProcData: Array[0..cośtam] of Record
Name: String;
Proc: Pointer;
End =
(
(Name: 'ShowMessage'; Proc: @ShowMessage),
(Name: 'MojaProcedura'; Proc: @MojaProcedura),
...
);
Lecz przy kilkuset funkcjach robienie tego ręcznie byłoby strasznie mozolne...
Rozwiązań jest kilka, posortowane zgodnie z trudnością ich wykonania:
1.Symbole debugujące (najłatwiejsze do wykonania - właściwie każdy kompilator jakieś generuje (np.FPC wspiera DWARF
oraz Stabs
), pozostaje tylko kwestia napisania parsera takich symboli, też nic przesadnie trudnego).
2.Zawsze napisać prosty parser Pascala (lub skorzystać z któregoś z gotowych (może coś z pakietu JEDI? afaik Lazarus korzysta z niego do formatowania kodu)), który będzie wykrywał wszystkie funkcje i procedury z danego kodu źródłowego, a w wyniku generował taką tabelkę, jak powyżej.
3.Napisanie własnego kompilatora/zmodyfikowanie istniejącego (to bardziej, jeżeli masz dostęp do kodu źródłowego (czyli właściwie FPC-only :P)).

- Rejestracja:ponad 18 lat
- Ostatnio:około 8 lat
- Lokalizacja:Poznań
- Postów:295
a co z exportami z exe? Kiedys tak robilem przy komunikacji dll - application. Dll dostawal uchwyt aplikacji przypisywala sobie go do wlasnego Application i pobierala adres eksportowany z aplikacji.
moglbys wtedy zrobic tak
Aplikacja
procedure ShowMessageEx(const AMessage: OleVariant); safecall;
begin
ShowMessage(VarToStr(AMessage));
end;
exports
ShowMessageEx;
Z czasem jednak dojdziesz do wniosku ze lepiej przekazywac do dll instancje interface hosta np IHostContainer = interface(IUnknown) (GUID i procedury, metody, property)
dodanie znacznika <code class="delphi"> - fp

- Rejestracja:ponad 13 lat
- Ostatnio:prawie 3 lata
Patryk27 napisał(a):
Łatwo mozna odnaleźć metody należące do klas po nazwie-chociazby MethodAddress z modulu TypInfo.
Wyczuwasz delikatną różnicę pomiędzy metodą, a procedurą?
RTTI istnieją tylko dla klas, dlatego możesz użyć sobieMethodAddress
; nazwy nieeksportowanych procedur oraz funkcji są usuwane z kodu wynikowego, ponieważ są po prostu zbędne i zaśmiecałyby plik wykonywalny.
Poprawka, RTTI - AFAIK - występuje tylko dla metod "published" - co jest rzadkością. Ale tego już w opisie nie napisali.
Łażenie po kodzie wg nazwy jest tylko możliwe w tych przypadkach które już wymieniono:
- funkcja eksportowana (DLL/COM)
- metoda published
- dostępne symbole debuggera (dłubanina)
W innych przypadkach kompilator skrzętnie usuwa ślady - po co miałby ułatwiać komuś reverse engineering.
Żeby to potwierdzić, wystarczy przejrzeć plik EXE edytorem hexa - o ile nie ma tam żadnej kompresji (sam kompilator jej nie robi), to zobaczymy wszystkie symbole dostępne przez nazwę.
Program "Process Explorer" umożliwia zobaczenie wszystkich tych symboli bez kodowania:
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
- prawy klik na procesie, zakładka Strings. Uwaga: pokazuje także symbole wykorzystywane przez program i wszelkie inne łańcuchy w nim zdefiniowane.