Seite 1 von 4

Prüfen, ob eine Adresse auf eine Procedure zeigt

Verfasst: 08.10.2015 17:16
von Kiffi
Hallo,

kann ich überprüfen, ob eine Adresse auf eine Procedure zeigt?

also im Prinzip so:

Code: Alles auswählen

Procedure myCallback()
EndProcedure

Debug IsProcedure(@myCallback()) ; -> True
Debug IsProcedure(123) ; -> False
Danke im Voraus & Grüße ... Peter

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Verfasst: 08.10.2015 17:42
von Falko
Ich weiß nicht, ob ich hiermit richtig liege.
Aber wenn ich das richtig verstanden habe, müsste es mit
Runtime aus PB gehen (siehe PB-Hilfe).

Gruß,
Falko

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Verfasst: 08.10.2015 17:44
von NicTheQuick
Ich würde auf diese Art und Weise dran gehen. Interessant ist schon mal, dass Procedures mit und ohne Parameter anders beginnen.

Code: Alles auswählen

Procedure isProcedure(*proc)
	If ExamineAssembly(*proc)
		While NextInstruction()
			Text$ + RSet(Hex(InstructionAddress()), SizeOf(Integer)*2, "0")
			Text$ + " " + InstructionString() + Chr(13)
			If InstructionString() = "ret " : Break : EndIf
		Wend
	EndIf
	Debug Text$
	
EndProcedure

Procedure a()
EndProcedure
Procedure b(a.i)
EndProcedure
Procedure c(a.i, b.s)
EndProcedure

Debug "a()"
isProcedure(@a())
Debug "b()"
isProcedure(@b())
Debug "c()"
isProcedure(@c())

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Verfasst: 08.10.2015 18:23
von mk-soft
Gab auch eine API. War aber so weit ich weiss auch nicht ganz sicher.

Function "IsBadCodePtr" ???

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Verfasst: 08.10.2015 19:02
von RSBasic
@NicTheQuick
Interessanter Code. :allright:

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Verfasst: 08.10.2015 19:04
von _JON_
Wozu brauch man den sowas?

Einzige Möglichkeit die mir einfällt, alle prüfen.

Code: Alles auswählen

Procedure IsProcedure(adresse.i)
  
  Select adresse
    Case @myCallback()
      ProcedureReturn 1
    ;Case ...
      
    ;Case ...
  EndSelect
  
EndProcedure

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Verfasst: 08.10.2015 21:27
von GPI
Dürfte wirklich eine gute Frage sein: wozu braucht man sowas :)


Ich wollte gerade vorschlagen am Beginn eines Quellcodes ein Label zu setzen und am Ende des Quellcodes. Nur blöd ist, das die Proceduren in Speicher den End-Label gesetzt werden :)

Aber das kann man so ausnutzen

Code: Alles auswählen

Declare IsProcedure(*pointer)

Procedure Test()
EndProcedure

DataSection
  LabelInData:
  Data.i 0
EndDataSection


Define var.i

Debug IsProcedure(@Test())
Debug IsProcedure(?LabelInData)
Debug IsProcedure(@var)

;Folgendes muss wirklich am ende des Quellcodes kommen - wirklich GANZ zum schluss!
StartOfPrg:
Procedure IsProcedure(*pointer)
  Debug Hex(*pointer)+" "+Hex(?StartOfPrg)+" "+Hex(@IsProcedure())
  If *pointer>?StartOfPrg And *pointer<@IsProcedure()
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

End
Es wird kontrolliert, ob der Pointer in den Bereich ist, wo normalerweise alle Proceduren landen. Das verhalten kann sich natürlich mit jeder neuen PureBasic-Version ändern. Von daher eigentlich auch unbrauchbar.

Wenn man noch Pointer von DLLs etc. bekommt, passt das sowieso nicht mehr.

Allerdings ist die Frage durchaus berechtigt: Wozu braucht man sowas? Wenn man nicht weis, wohin der Pointer zeigt, ist das imo eine gefährliche Lücke in Programmcode. Spontan würde ich sagen, dass das zugrundeliegende Konzept fehlerhaft ist.

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Verfasst: 08.10.2015 21:35
von RSBasic
Vielleicht hat Kiffi eine dynamische/generierte/automatisierte Liste aller Speicheradressen verschiedener Typen (Procedures, Images, File handles, ...) und möchte gerne den Typ abfragen.
Und je nach Typ soll eine bestimmte Aktion automatisch durchgeführt werden. Aber wofür genau bzw. was das für eine Anwendung sein soll, möchte ich auch gerne wissen. :)

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Verfasst: 08.10.2015 22:16
von Kiffi
Örzmal vielen Dank für die rege Beteiligung! :)

Leider sind die vorgeschlagenen Lösungen für mich bisher nicht praktikabel.

* Ich möchte ungern API verwenden. Bisher ist mein Code cross platform und soll es auch nach Möglichkeit bleiben.
* Ich kann nicht unbedingt sagen, welche Prozeduren in dem Code vorkommen.
* Die Lösung von NTQ sieht 'interessant' aus, wenn ich aber eine ungültige Adresse angebe, gibt's einen IMA bei NextInstruction() (und IMAs will ich ja vermeiden).
wozu braucht man sowas?
Ganz simpel: Ich habe eine Main.pb und eine Include.pbi. In der Main starte ich einen Vorgang innerhalb dessen ich eine Prozedur der Main.pb aufrufen möchte.

Main.pb

Code: Alles auswählen

Procedure myCallback()
  Debug "Piep!"
EndProcedure

MachMalPiep = @myCallback()

SeiFleissig()
Include.pbi:

Code: Alles auswählen

Procedure SeiFleissig()
 ... TuDies()
 ... CallFunctionFast(MachMalPiep)
 ... TuDas()
EndProcedure
Letztendlich schreibe ich das Include, welches der Anwender (also Ihr) in seine Main einbinden kann. Und ich würde halt gerne wissen, ob MachMalPiep() eine wirklich existierende Prozedur aufruft.

Grüße ... Peter

// Edit: Hätte ich beinahe vergessen: @Falko: Runtime ist dafür leider nicht geeignet. Dennoch Danke!

Re: Prüfen, ob eine Adresse auf eine Procedure zeigt

Verfasst: 08.10.2015 23:44
von NicTheQuick
Naja, du musst natürlich schon noch überprüfen, ob der Pointer wirklich gültig ist. Meine Idee zielte nur darauf ab zu erkennen, ob da wirklich eine ausführbare Funktion hinter dem Pointer steckt. Da muss man eben noch ein bisschen was drum herum bauen.