Fremde Ressourcen DLL auslesen

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.
Antworten
Lorca
Beiträge: 196
Registriert: Di 3. Nov 2020, 12:25

Fremde Ressourcen DLL auslesen

Beitrag von Lorca »

Hallo zusammen,

gerne würde ich aus einer fremden Ressourcen DLL die gesamte Stringtabelle in einem Dynamischen StringArray auslesen. Da ich ja nicht weiß wie viele Einträge gefunden werden.

Mit LoadLibrary wird die fremde DLL ins eigene Programm geladen und auch das Handle erzeugt. Aber wie geht es dann weiter?

Also:
- Lese: Ressourcen DLL in eine Stringtabelle.
Und
- Lese einen einzelnen String aus einer Ressourcen DLL

Wie verhält es sich mit der ID? Handelt es sich hier um den Index eines Strings innerhalb der Stringtabelle?


Viele Grüße
Lorca

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Fremde Ressourcen DLL auslesen

Beitrag von fliegermichl »


Lorca
Beiträge: 196
Registriert: Di 3. Nov 2020, 12:25

Re: Fremde Ressourcen DLL auslesen

Beitrag von Lorca »

Hallo Fliegermichel

zunächst danke für Deine schnelle Antwort :)

Dennoch habe ich weitere Fragen

Ich fange an mit

PROCEDURE Tform.Button1click( Sender : Tobject) ;
VAR lv_Len : Cardinal; lv_LibHDL : TLibHandle; lv_HRSRC : HRSRC; lv_p : pchar;
BEGIN
{ hier wird ein sauberes Handle geliefert. Funzt also }
lv_LibHDL := LoadLibrary( PChar( FEDT.Text ) );

{Hier funktioniert das nicht }
lv_Len := LoadString( lv_LibHDL, 0, lv_p, 5000 );

Nun meine Fragen:
- lv_LibHDL: Ich denke das dies so korrekt ist
- 0: Hier habe ich keine Vorstellung was mit dem Parameter "uID" gemeint ist. Was für ein Wert wird hier erwartet?
- lv_p: eine lokale PChar Variable. Ich möchte aber ein STRINGARRAY gefüllt haben dessen benötigte Größe ich zu diesem Zeitpunkt
nicht kenne
- 5000: Das soll die Größe des Puffers sein. Da es sich um eine fremde DLL handelt habe ich keine Ahnung wieviel Einträge vorliegen.
Ebenfalls weiß ich nicht wieviel Bytes ich übergeben muss.

Bei meiner Recherche auf "https://www.freepascal.org/docs-html/prog/progse61.html"
habe ich zwar folgendes gefunden:
SetLength(Result,LoadString(FindResource(0,Nil,RT_STRING), Index,
@Result[1],
SizeOf(Result)) ) ;

Wobei ich für "Result" mein StringArray einsetzen würde. Aber auch hier habe ich keine Vorstellung
Was ist "Index" und wie groß mein StringArray sein muss ?

Mir ist sowohl die Anzahl der Tabellen Einträge in der fremden DLL unbekannt, als auch das Lesen bis EoF nicht funktioniert bzw. mir nicht bekannt ist. Woran erkenne ich dann wie viele Tabelleneinträge vorliegen bzw. wie lassen sich diese ermitteln?

Kann mir hierbei jemand helfen, den für mich gordischen Knoten zu lösen? :)

Gruß
Lorca

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Fremde Ressourcen DLL auslesen

Beitrag von Socke »

Um herauszufinden, wie viele Strings in der DLL enthalten sind, kannst du die EnumResource* Funktionen nutzen. Tipp: Da die Resource-IDs Lücken enthalten oder auch negativ sein können, kannst du nicht einfach den höchsten Wert ermitteln, deinen Array anpassen und den Array-Index als Resource-ID verwenden.

Die WinAPI arbeitet nur mit PChar bzw. PWideChar. Du kannst also zuerst die Länge des Strings ermitteln (SizeofResource), die Länge des Strings setzen und dann den String als PChar an LoadString übergeben.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Lorca
Beiträge: 196
Registriert: Di 3. Nov 2020, 12:25

Re: Fremde Ressourcen DLL auslesen

Beitrag von Lorca »

Hallo Socke,

herzlichen Dank für Deine Info. :)

Gut zu wissen das mit EnumResource* nicht die korrekte Anzahl ermittelt werden kann. So wie ich ich das in Deinem Link (Danke dafür, hatte ich noch nicht gefunden) verstehe, kann damit die Anzahl der verschiedenen Typen (Image, Html ....) ermittelt werden.

Da ich (durch ResHacker http://www.angusj.com/ ) weiß, das die StringTabelle in mehreren Blöcken unterteilt ist
frage ich mich natürlich ob diese Funktion (EnumResource*) etwas damit zu tun hat.
Ich werde dies mal recherchieren.

Blockaufteilung in ResHacker:
1 : 1033
14 : 1033
108 : 1033
usw.

Ganz herzlichen Dank an euch alle

Gruß
Lorca

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Fremde Ressourcen DLL auslesen

Beitrag von Socke »

Lorca hat geschrieben:
Mi 25. Aug 2021, 13:36
Gut zu wissen das mit EnumResource* nicht die korrekte Anzahl ermittelt werden kann. So wie ich ich das in Deinem Link (Danke dafür, hatte ich noch nicht gefunden) verstehe, kann damit die Anzahl der verschiedenen Typen (Image, Html ....) ermittelt werden.
Es gibt verschiedene Funktionen: EnumResourceType zählt alle Typen auf (Image, String, usw.) während EnumResourceNames die einzelnen Ressourcen eines Typs durchläuft. Zwei Links weiter sind auch Beispiele in C++: https://docs.microsoft.com/en-us/window ... -resources
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

PascalDragon
Beiträge: 825
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Fremde Ressourcen DLL auslesen

Beitrag von PascalDragon »

Lorca hat geschrieben:
Mi 25. Aug 2021, 07:30
gerne würde ich aus einer fremden Ressourcen DLL die gesamte Stringtabelle in einem Dynamischen StringArray auslesen. Da ich ja nicht weiß wie viele Einträge gefunden werden.
Als Alternative zur WinAPI kannst du auch die Wrapper verwenden, die durch FPC bereitgestellt werden:

Code: Alles auswählen

program tstrres;

{$mode objfpc}{$H+}

uses
  resource, winpeimagereader, stringtableresource;

var
  res: TResources;
  i, j: LongInt;
  strtbl: TStringTableResource;
begin
  res := TResources.Create;
  try
    res.LoadFromFile(ParamStr(1));
    for i := 0 to res.Count - 1 do begin
      if res.Items[i]._Type.ID = RT_STRING then begin
        strtbl := res.Items[i] as TStringTableResource;

        Writeln('Got string table ', strtbl.Name.Name, ' of language ', strtbl.LangID, ' with ', strtbl.Count, ' entries:');
        for j := 0 to strtbl.Count - 1 do
          Writeln(#9, '#', j + strtbl.FirstID, #9, strtbl.Strings[j + strtbl.FirstID]);
      end;
    end;
  finally
    res.Free;
  end;
end.
Und hier die Ausgabe:

Code: Alles auswählen

PS C:\fpc\git> .\testoutput\tstrres.exe C:\Windows\System32\MUI\0409\mscorees.dll
Got string table 1 of language 1033 with 16 entries:
        #0
        #1      Please set registry key HKLM\Software\Microsoft\.NETFramework\InstallRoot to point
to the .NET Framework install location
        #2      .NET Framework Initialization Error
        #3      %s could not be loaded
        #4      Runtime probably not installed:
Unable to determine the latest version
        #5      To run this application, you first must install one of the following versions of the .NET Framework:
  %s
Contact your application publisher for instructions about obtaining the appropriate version of the .NET Framework.
        #6      Unable to initialize the runtime due to low memory conditions.
        #7      Unable to find a version of the runtime to run this application.
        #8
        #9
        #10
        #11
        #12
        #13
        #14
        #15
Got string table 4 of language 1033 with 16 entries:
        #48
        #49
        #50     Found a mscoree.local file. Using the local runtime.
        #51     Found a supportedRuntime tag in the config file
        #52     Using supportedRuntime: %s
        #53     ERROR: None of the listed supported runtimes are installed on the machine.
        #54     Found a requiredRuntime tag in the config file : %s
        #55     Applying Standards mapping to the requiredRuntime: %s
        #56     COMPLUS_VERSION is set to force us to use: %s
        #57     Host supplied version: %s
        #58     Alternative value set by host: %s
        #59     %s was built with version: %s
        #60     The executing assembly was built with: %s
        #61     Applying Standards mapping to the executing assembly version: %s
        #62     %s is not installed on the machine. Floating to: %s
        #63     Build Flavor: %s
Got string table 5 of language 1033 with 16 entries:
        #64     Default version of the runtime on the machine: %s
        #65     ERROR: Unable to find a version of the runtime to use.
        #66     ERROR: Version %s is not present on the machine.
        #67     Decided on runtime: %s
        #68     COMPLUS_DEFAULTVERSION set to: %s
        #69     Found config file: %s
        #70     -----------------------------------
        #71     Host supplied values (usually set via CorBindToRuntime)
        #72     Default Application Name: %s
        #73     Host Config: %s
        #74     App Config: %s
        #75     Default Version: %s
        #76     Log started at %s on %s
        #77     CLR Loading log for %s
        #78     RTL_False
        #79     Appcompat lockback shim found, locked to version %s
FPC Compiler Entwickler

Lorca
Beiträge: 196
Registriert: Di 3. Nov 2020, 12:25

Re: Fremde Ressourcen DLL auslesen

Beitrag von Lorca »

Hallo zusammen

nochmals Danke an alle und jetzt auch noch an socke und PascalDragon

Ganz lieben an euch allen.
Sobald ich wieder Luft habe, werde ich die Vorschläge ausprobieren.

Viele Grüße
Lorca

Lorca
Beiträge: 196
Registriert: Di 3. Nov 2020, 12:25

Re: Fremde Ressourcen DLL auslesen

Beitrag von Lorca »

Hallo zusammen, hallo Socke, hallo PascalDragon, :)

da mir andere dinge sehr doll auf den Nägeln brannten, hatte ich mein Problem mit den Ressourcen DLLs zurückgestellt.
Nun hatte ich heute Zeit, das Coding von PascalDragon auszuprobieren.
Dein Beispiel ist echt simpel und genial gehalten. Genau so wie ich es mag. :D
Eine wirklich coole Sache.

Die Infos von Socke waren auch echt klasse. Jedoch sind die ganzen PChar's sind nicht wirklich meine Freunde. Die sind im Watch Fenster nicht gut zu überwachen. Daher hatte ich ein unglückliches Händchen beim verstehen deines Beispiel Codings.
Egal wie, alle eure Hinweise haben mir zum Ziel verholfen. Danke dafür.

Jetzt funzt es auch mit der Ermittlung eines Ressourcen Strings über die ID. :)

Danke nochmals, auch an alle anderen die mir immer so nett aus der Patsche helfen

Gruß
Lorca

Antworten