Hi.
Dank einiger Starthilfe durch andere Mitglieder hier im Forum habe ich einen kleinen DLL-Betrachter und -Tester geschrieben. Er kann Funktionen aufrufen und sollte Abschuss-sicher sein (jedenfalls ist er das auf meinem System).
Viel ist es nicht, aber doch mal etwas Nützliches, falls man noch keinen hat. TS-Soft hat auch einen geschrieben, der sieht besser aus, aber ich glaube, bei dem konnte man die Funktionen nicht aufrufen? Bin mir jetzt nicht so sicher.
Also, hier, DLLex:
Code:
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * *
; * DLLex - DLL function viewer and executer *
; * (Programmbiliotheksbetrachter und -Tester) *
; * *
; * 09/25/2014 *
; * *
; * PureBasic 5.30 (x86/x64) - no demo *
; * done With lots of help of the community *
; * *
; * written by es_91@forums.purebasic.fr/german *
; * Edit at will but NEVER claim it's yours! *
; * *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Procedure Settings_ChangesMade()
Shared Var_FastCall
Shared Var_CCall
Shared CBDLLexSettings
If Not GetGadgetState(CBDLLexSettings) = Var_CCall
Select MessageRequester("Frage", "Möchten Sie die Änderungen speichern?", #PB_MessageRequester_YesNoCancel)
Case #PB_MessageRequester_Yes
Var_CCall = GetGadgetState(CBDLLexSettings)
ProcedureReturn #True
Case #PB_MessageRequester_No
ProcedureReturn #True
EndSelect
Else
ProcedureReturn #True
EndIf
EndProcedure
Structure PARAMETER
ID.i
Type$
Value$
ValuePtr.i
EndStructure
Structure FUNCTION
Address.i
Name.s
URL.s
List Parameters.PARAMETER()
EndStructure
NewList Functions.FUNCTION()
ProgramName$ = "DLLex"
OpenPreferences("DLLex.pref")
Var_CCall = ReadPreferenceLong("C Call", #False)
ClosePreferences()
DLLex = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 630, 340, ProgramName$, #PB_Window_SystemMenu| #PB_Window_MinimizeGadget| #PB_Window_TitleBar| #PB_Window_ScreenCentered)
LIDLLex = ListIconGadget(#PB_Any, 20, 20, 590, 280, "Adresse", 90, #PB_ListIcon_FullRowSelect| #PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(LIDLLex, 1, "Funktion", 300)
MNDLLex = CreateMenu(#PB_Any, WindowID(DLLex))
MenuTitle("Datei")
MenuItem(1, "Bibliothek öffnen...")
MenuItem(2, "Bibliothek schließen")
MenuBar()
MenuItem(9, "Beenden")
MenuTitle("Ausführung")
MenuItem(11, "Schnellaufruf (ohne Parameter)")
MenuItem(12, "Funktion mit Parametern testen...")
MenuTitle("Optionen")
MenuItem(20, "Einstellungen...")
MenuTitle("?")
MenuItem(39, "Über...")
LoadLibrary$ = ProgramParameter()
If LoadLibrary$
FileName$ = LoadLibrary$
Gosub OpenLibrary
EndIf
NewList Strings$()
NewList Floats.f()
NewList Doubles.d()
NewList Quads.q()
Repeat
Select WaitWindowEvent(#True)
Case #PB_Event_Gadget
Select EventGadget()
Case LIDllex
If Not GetGadgetState(LIDLLex) = -1
SelectElement(Functions(), GetGadgetState(LIDLLex))
EndIf
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case 1
FileName$ = OpenFileRequester("", "", "", 0)
If FileName$
LoadLibrary$ = FileName$
Gosub OpenLibrary
EndIf
Case 2
If IsLibrary(Library)
CloseLibrary(Library)
ClearGadgetItems(LIDLLex)
ClearList(Functions())
SetWindowTitle(DLLex, ProgramName$)
Else
MessageRequester("Fehler", "Es ist derzeit keine Bibliothek geöffnet.")
EndIf
Case 9
End
Case 11
If Not GetGadgetState(LIDLLex) = -1
Gosub Run
Else
Gosub Error_Library
EndIf
Case 12
If Not GetGadgetState(LIDLLex) = -1
If ParametersSet
HideWindow(DLLex, #False)
Else
ParametersSet = #True
DisableWindow(DLLex, #True)
DLLexRun = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 446, 240, "Parameter", #PB_Window_WindowCentered| #PB_Window_SystemMenu| #PB_Window_TitleBar, WindowID(DLLex))
LIDLLexRun = ListIconGadget(#PB_Any, 20, 50, 406, 140, "#", 25, #PB_ListIcon_FullRowSelect| #PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(LIDLLexRun, 1, "Wert", 270)
AddGadgetColumn(LIDLLexRun, 2, "Typ", 90)
BN1DLLexRun = ButtonGadget(#PB_Any, 20, 20, 80, 20, "Hinzufügen...")
BN2DLLexRun = ButtonGadget(#PB_Any, 110, 20, 80, 20, "Entfernen")
BN3DLLexRun = ButtonGadget(#PB_Any, 346, 200, 80, 20, "Ausführen", #PB_Button_Default)
Repeat
Select WaitWindowEvent(#True)
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case BN1DLLexRun
If ParameterSpecified
DisableWindow(DLLexRun, #True)
HideWindow(DLLexRunParameter, #False)
Else
DisableWindow(DLLexRun, #True)
ParameterSpecified = #True
DLLexRunParameter = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 315, 170, "Neuer Parameter", #PB_Window_SystemMenu| #PB_Window_WindowCentered| #PB_Window_TitleBar, WindowID(DLLexRun))
ON1DLLexRunParameter = OptionGadget(#PB_Any, 20, 20, 110, 20, "Long-Int (Ganzzahl):")
ON2DLLexRunParameter = OptionGadget(#PB_Any, 20, 60, 110, 20, "Pointer (Zeiger) auf:")
SG1DLLexRunParameter = StringGadget(#PB_Any, 150, 20, 145, 20, "0", #PB_String_Numeric)
SG2DLLexRunParameter = StringGadget(#PB_Any, 150, 60, 145, 20, "0")
ON3DLLexRunParameter = OptionGadget(#PB_Any, 20, 100, 55, 20, "String")
ON4DLLexRunParameter = OptionGadget(#PB_Any, 95, 100, 55, 20, "Float")
ON5DLLexRunParameter = OptionGadget(#PB_Any, 170, 100, 55, 20, "Double")
ON6DLLexRunParameter = OptionGadget(#PB_Any, 245, 100, 55, 20, "Quad")
BN1DLLexRunParameter = ButtonGadget(#PB_Any, 20, 130, 80, 20, "Abbrechen")
BN2DLLexRunParameter = ButtonGadget(#PB_Any, 215, 130, 80, 20, "Ok", #PB_Button_Default)
DisableGadget(BN2DLLexRunParameter, #True)
DisableGadget(SG1DLLexRunParameter, #True)
DisableGadget(SG2DLLexRunParameter, #True)
DisableGadget(ON3DLLexRunParameter, #True)
SetGadgetState(ON3DLLexRunParameter, #True)
DisableGadget(ON4DLLexRunParameter, #True)
DisableGadget(ON5DLLexRunParameter, #True)
DisableGadget(ON6DLLexRunParameter, #True)
EndIf
Repeat
Select WaitWindowEvent(#True)
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case BN1DLLexRunParameter
Break
Case BN2DLLexRunParameter
Parameter$ = GetGadgetText(SG1DLLexRunParameter)
If GetGadgetState(ON1DLLexRunParameter)
Type$ = "Value"
Parameter$ = GetGadgetText(SG1DLLexRunParameter)
ElseIf GetGadgetState(ON2DLLexRunParameter)
Parameter$ = GetGadgetText(SG2DLLexRunParameter)
If GetGadgetState(ON3DLLexRunParameter)
Type$ = "StringPtr"
ElseIf GetGadgetState(ON4DLLexRunParameter)
Type$ = "FloatPtr"
ElseIf GetGadgetState(ON5DLLexRunParameter)
Type$ = "DoublePtr"
ElseIf GetGadgetState(ON6DLLexRunParameter)
Type$ = "QuadPtr"
EndIf
EndIf
AddGadgetItem(LIDLLexRun, -1, Str(CountGadgetItems(LIDLLexRun) + 1) + #LF$ + Parameter$ + #LF$ + Type$)
AddElement(Functions()\Parameters())
Functions()\Parameters()\Value$ = Parameter$
Functions()\Parameters()\Type$ = Type$
Break
Case ON1DLLexRunParameter
DisableGadget(BN2DLLexRunParameter, #False)
DisableGadget(SG1DLLexRunParameter, #False)
DisableGadget(SG2DLLexRunParameter, #True)
DisableGadget(ON3DLLexRunParameter, #True)
DisableGadget(ON4DLLexRunParameter, #True)
DisableGadget(ON5DLLexRunParameter, #True)
DisableGadget(ON6DLLexRunParameter, #True)
Case ON2DLLexRunParameter
DisableGadget(BN2DLLexRunParameter, #False)
DisableGadget(SG1DLLexRunParameter, #True)
DisableGadget(SG2DLLexRunParameter, #False)
DisableGadget(ON3DLLexRunParameter, #False)
DisableGadget(ON4DLLexRunParameter, #False)
DisableGadget(ON5DLLexRunParameter, #False)
DisableGadget(ON6DLLexRunParameter, #False)
EndSelect
EndSelect
ForEver
HideWindow(DLLexRunParameter, #True)
DisableWindow(DLLexRun, #False)
Case BN2DLLexRun
If Not GetGadgetState(LIDLLexRun) = -1
If MessageRequester("Frage", "Möchten Sie Parameter " + GetGadgetItemText(LIDLLexRun, GetGadgetState(LIDLLexRun), 0) + " wirklich entfernen?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
DeleteElement(Functions()\Parameters())
Gosub RefillLIDLLexRun
EndIf
Else
MessageRequester("Fehler", "Wählen Sie zuerst einen Parameter aus!")
EndIf
Case BN3DLLexRun
ClearList(Functions()\Parameters())
For ParameterIndex = #Null To CountGadgetItems(LIDLLexRun) - 1
AddElement(Functions()\Parameters())
Functions()\Parameters()\ID = Val(GetGadgetItemText(LIDLLexRun, ParameterIndex, 0))
Functions()\Parameters()\Type$ = GetGadgetItemText(LIDLLexRun, ParameterIndex, 2)
Functions()\Parameters()\Value$ = GetGadgetItemText(LIDLLexRun, ParameterIndex, 1)
Next
Gosub Run
EndSelect
EndSelect
If Not GetGadgetState(LIDLLexRun) = -1
SelectElement(Functions()\Parameters(), GetGadgetState(LIDLLexRun))
EndIf
ForEver
HideWindow(DLLexRun, #True)
DisableWindow(DLLex, #False)
EndIf
Else
If IsLibrary(Library)
MessageRequester("Fehler", "Wählen Sie zuerst eine Funktion aus!")
Else
MessageRequester("Fehler", "Sie haben keine Bibliothek geöffnet.")
EndIf
EndIf
Case 20
DisableWindow(DLLex, #True)
DLLexSettings = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 315, 170, "Einstellungen", #PB_Window_SystemMenu| #PB_Window_WindowCentered| #PB_Window_TitleBar, WindowID(DLLex))
FrameGadget(#PB_Any, 20, 20, 275, 90, "Funktionsaufruf")
CBDLLexSettings = CheckBoxGadget(#PB_Any, 40, 40, 235, 20, "C-typischer Aufruf (cdecl)")
SetGadgetState(CBDLLexSettings, Var_CCall)
BN1DLLexSettings = ButtonGadget(#PB_Any, 20, 130, 80, 20, "Abbrechen")
BN2DLLexSettings = ButtonGadget(#PB_Any, 215, 130, 80, 20, "Übernehmen", #PB_Button_Default)
Repeat
Select WaitWindowEvent(#True)
Case #PB_Event_CloseWindow
If Settings_ChangesMade()
Break
EndIf
Case #PB_Event_Gadget
Select EventGadget()
Case BN1DLLexSettings
If Settings_ChangesMade()
Break
EndIf
Case BN2DLLexSettings
Var_CCall = GetGadgetState(CBDLLexSettings)
Break
EndSelect
EndSelect
ForEver
CloseWindow(DLLexSettings)
DisableWindow(DLLex, #False)
Case 39
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
CompilerBitDepth$ = "32 Bit"
CompilerElseIf #PB_Compiler_Processor = #PB_Processor_x64
CompilerBitDepth$ = "64 Bit"
CompilerEndIf
MessageRequester("Über", "DLLex - Bibliotheksbetrachter (" + CompilerBitDepth$ + ");" + #LFCR$ + #LFCR$ + "geschrieben von Enrico Seidel, 19. - 22.09.2014;" + #LFCR$ + #LFCR$ + "kompiliert mit PureBasic " + Left(Str(#PB_Compiler_Version), 1) + "." + Right(Str(#PB_Compiler_Version), 2))
EndSelect
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
CreatePreferences("DLLex.pref")
WritePreferenceLong("C Call", Var_CCall)
ClosePreferences()
End
Error_Library:
If IsLibrary(Library)
MessageRequester("Fehler", "Wählen Sie zuerst eine Funktion aus!")
Else
MessageRequester("Fehler", "Sie haben keine Bibliothek geöffnet.")
EndIf
Return
OpenLibrary:
OldLibrary = Library
Library = OpenLibrary(#PB_Any, FileName$)
If Library
If ExamineLibraryFunctions(Library)
CloseLibrary(OldLibrary)
ClearGadgetItems(LIDLLex)
ClearList(Functions())
While NextLibraryFunction()
AddGadgetItem(LIDLLex, -1, Str(LibraryFunctionAddress()) + #LF$ + LibraryFunctionName())
AddElement(Functions())
Functions()\Address = LibraryFunctionAddress()
Functions()\Name = LibraryFunctionName()
ClearList(Functions()\Parameters())
Wend
SetWindowTitle(DLLex, ProgramName$ + " - " + GetFilePart(FileName$))
SetGadgetState(LIDLLex, 0)
Else
MessageRequester("Fehler", "Die Bibliothek konnte nicht eingelesen werden.")
CloseLibrary(Library)
SetWindowTitle(DLLex, ProgramName$)
Library = OldLibrary
EndIf
Else
MessageRequester("Fehler", "Die Bibliothek konnte nicht geladen werden.")
EndIf
Return
Run:
MD5Value = Random(65535)
MD5String$ = Str(MD5Value)
MD5String$ = MD5Fingerprint(@MD5String$, Len(MD5String$))
ResultError = #False
If ParametersSet
ForEach Functions()\Parameters()
Parameters$ + Functions()\Parameters()\Type$ + " "
Parameters$ + Chr(34) + Functions()\Parameters()\Value$ + Chr(34) + " "
If ListIndex(Functions()\Parameters()) = ListSize(Functions()\Parameters()) - 1
Parameters$ + "End"
EndIf
Next
EndIf
Program = RunProgram("dllexrun.exe", Chr(34) + LoadLibrary$ + Chr(34) + " " + Chr(34) + Functions()\Name + Chr(34) + " " + Str(MD5Value) + " " + MD5String$ + " " + GetGadgetItemText(LIDLLex, GetGadgetState(LIDLLex), 0) + " " + Str(Var_CCall) + " " + Parameters$, "", #PB_Program_Open| #PB_Program_Read| #PB_Program_Hide)
Parameters$ = ""
Repeat
Delay(1)
Until AvailableProgramOutput(Program)
ProgramString$ = ReadProgramString(Program)
Select ProgramString$
Case "Error " + MD5Fingerprint(@MD5String$, Len(MD5String$))
ResultError = #True
Default
If Left(ProgramString$, 5) = "Error"
MessageRequester("Fehler", "Fehlermeldung: " + Right(ProgramString$, Len(ProgramString$) - 6))
ResultError = #True
Else
Result = Val(ProgramString$)
ResultError = #False
EndIf
EndSelect
KillProgram(Program)
If ResultError
MessageRequester("Information", "Die Funktion gab keinen Wert zurück.")
Else
MessageRequester("Information", "Die Funktion gab folgenden Wert zurück: " + Str(Result))
EndIf
Return
RefillLIDLLexRun:
ClearGadgetItems(LIDLLexRun)
ForEach Functions()\Parameters()
AddGadgetItem(LIDLLexRun, -1, Str(CountGadgetItems(LIDLLexRun) + 1) + #LF$ + Functions()\Parameters()\Value$ + #LF$ + Functions()\Parameters()\Type$)
Next
Return
... das Hauptprogramm und eine externe
DLLexRun.exe:
Code:
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; * *
; * DLLex - DLL function viewer and executer *
; * (Programmbiliotheksbetrachter und -Tester) *
; * *
; * 09/25/2014 *
; * *
; * This is an external program. Edit at your own risk! *
; * *
; * *
; * written by es_91@forums.purebasic.fr/german *
; * Edit at will but NEVER claim it's yours! *
; * *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Global MD5String$
Dim Values(20)
NewList Strings$()
NewList Floats.f()
NewList Doubles.d()
NewList Quads.q()
NewList Integers.i()
Procedure ErrorHandler()
PrintN("Error " + MD5Fingerprint(@MD5String$, Len(MD5String$)))
End
EndProcedure
OpenConsole()
MD5Value$ = ProgramParameter(2)
MD5String$ = ProgramParameter(3)
If MD5Fingerprint(@MD5Value$, Len(MD5Value$)) = MD5String$
*Function = Val(ProgramParameter(4))
Var_CCall = Val(ProgramParameter(5))
Library = OpenLibrary(#PB_Any, ProgramParameter(0))
FuncName$ = ProgramParameter(1)
OnErrorCall(@ErrorHandler())
For ParameterIndex = 6 To 45 Step 2
Type$ = ProgramParameter(ParameterIndex)
Value$ = ProgramParameter(ParameterIndex + 1)
Select Type$
Case "StringPtr"
AddElement(Strings$())
Strings$() = Value$
Values((ParameterIndex - 3) / 2) = PeekI(@Strings$())
Case "FloatPtr"
AddElement(Floats())
Floats() = ValF(Value$)
Values((ParameterIndex - 3) / 2) = @Floats()
Case "DoublePtr"
AddElement(Doubles())
Doubles() = ValD(Value$)
Values((ParameterIndex - 3) / 2) = @Doubles()
Case "QuadPtr"
AddElement(Quads())
Quads() = Val(Value$)
Values((ParameterIndex - 3) / 2) = @Quads()
Case "Value"
AddElement(Integers())
Integers() = Val(Value$)
Values((ParameterIndex - 3) / 2) = @Integers()
Case "End"
Break
EndSelect
ParametersCount + 1
Next
Select ParametersCount
Case 0
If Var_CCall
Result = CallCFunction(Library, FuncName$)
PrintN(Str(Result))
Else
Result = CallFunction(Library, FuncName$)
PrintN(Str(Result))
EndIf
Case 1
If Var_CCall
Result = CallCFunction(Library, FuncName$, Values(1))
PrintN(Str(Result))
Else
Result = CallFunction(Library, FuncName$, Values(1))
PrintN(Str(Result))
EndIf
Case 2
If Var_CCall
Result = CallCFunction(Library, FuncName$, Values(1), Values(2))
PrintN(Str(Result))
Else
Result = CallFunction(Library, FuncName$, Values(1), Values(2))
PrintN(Str(Result))
EndIf
Case 3
If Var_CCall
Result = CallCFunction(Library, FuncName$, Values(1), Values(2), Values(3))
PrintN(Str(Result))
Else
Result = CallFunction(Library, FuncName$, Values(1), Values(2), Values(3))
PrintN(Str(Result))
EndIf
Case 4
If Var_CCall
Result = CallCFunction(Library, FuncName$, Values(1), Values(2), Values(3), Values(4))
PrintN(Str(Result))
Else
Result = CallFunction(Library, FuncName$, Values(1), Values(2), Values(3), Values(4))
PrintN(Str(Result))
EndIf
Case 5
If Var_CCall
Result = CallCFunction(Library, FuncName$, Values(1), Values(2), Values(3), Values(4), Values(5))
PrintN(Str(Result))
Else
Result = CallFunction(Library, FuncName$, Values(1), Values(2), Values(3), Values(4), Values(5))
PrintN(Str(Result))
EndIf
Case 6
If Var_CCall
Result = CallCFunction(Library, FuncName$, Values(1), Values(2), Values(3), Values(4), Values(5), Values(6))
PrintN(Str(Result))
Else
Result = CallFunction(Library, FuncName$, Values(1), Values(2), Values(3), Values(4), Values(5), Values(6))
PrintN(Str(Result))
EndIf
Case 7
If Var_CCall
Result = CallCFunction(Library, FuncName$, Values(1), Values(2), Values(3), Values(4), Values(5), Values(6), Values(7))
PrintN(Str(Result))
Else
Result = CallFunction(Library, FuncName$, Values(1), Values(2), Values(3), Values(4), Values(5), Values(6), Values(7))
PrintN(Str(Result))
EndIf
Case 8
If Var_CCall
Result = CallCFunction(Library, FuncName$, Values(1), Values(2), Values(3), Values(4), Values(5), Values(6), Values(7), Values(8))
PrintN(Str(Result))
Else
Result = CallFunction(Library, FuncName$, Values(1), Values(2), Values(3), Values(4), Values(5), Values(6), Values(7), Values(8))
PrintN(Str(Result))
EndIf
Default
If Var_CCall
Result = CallCFunction(Library, FuncName$, Values(1), Values(2), Values(3), Values(4), Values(5), Values(6), Values(7), Values(8))
PrintN(Str(Result))
Else
Result = CallFunction(Library, FuncName$, Values(1), Values(2), Values(3), Values(4), Values(5), Values(6), Values(7), Values(8))
PrintN(Str(Result))
EndIf
EndSelect
CloseLibrary(Library)
Else
PrintN("Error The external program 'DLLexRun.exe' is corrupt.")
EndIf
Das Programm kann jede Funktion mit bis zu acht Parametern aufrufen. Alle Parameter müssen vom Typ her ganzzahlig sein - Pointer können verwendet werden.
Ich übernehme keine Haftung für Schäden, sollten welche Auftreten.