[phpBB Debug] PHP Warning: in file [ROOT]/ext/tas2580/privacyprotection/cron/task/anonymize_ip.php on line 83: A non-numeric value encountered
Inoffizielles deutsches Xbase-Forum • Projektpfad aus EXE ermitteln
Seite 1 von 1

Projektpfad aus EXE ermitteln

Verfasst: Fr, 23. Feb 2018 13:41
von azzo
Hallo,
ich suche nach einer Möglichkeit, eine EXE Datei zu lesen und nach einem Wort zu suchen.
Memoread oder f_open funktioniert bei mir leider nicht.

Man kann eine EXE mit F3 vom TotalCommander aus aufmachen und dann nach:
INITSTATICS
suchen.
Man sieht dann, den Projektpfad.
LG
Otto

Re: Projektpfad aus EXE ermitteln

Verfasst: Fr, 23. Feb 2018 13:59
von HaPe
Hallo Otto !
Memoread oder f_open funktioniert bei mir leider nicht.
Welcher Rückgabe-Code bzw. Fehler-Code kommt denn?
Was sagt FError()?

Re: Projektpfad aus EXE ermitteln

Verfasst: Fr, 23. Feb 2018 14:00
von brandelh
FOpen() kann JE Datei öffnen, solange genug Rechte auf dem Verzeichnis vorhanden sind.
Du schreibst deine Funktion anders, also könnte es eine spezielle Version sein, die eventuell die Parameter anders setzt.
FOpen( <cFilename>, [<nMode>]) --> nHandle

<nMode> ist ein ganzzahliger, numerischer Wert, der den Modus für den Dateizugriff spezifiziert. Der Standardwert ist 0, d.h. wenn <nMode> nicht angegeben ist, wird eine Datei im "Read-only" und "shared" Modus geöffnet. Für das Argument <nMode> sind in der Header-Datei "Fileio.ch" verschiedene symbolische Konstanten definiert, mit denen der Zugriffsmodus für eine Einzelplatz- oder eine Netzwerkanwendung spezifiziert werden kann.
bei der Standardversion wird Read-Only und shared geöffnet, somit sollte das auch auf einem Laufwerk funktionieren, bei dem die EXE läuft und das Schreibschutz hat.

Re: Projektpfad aus EXE ermitteln

Verfasst: Fr, 23. Feb 2018 14:19
von Tom
Ich kann F_Open(), MemoRead() und FileStr() mit jeder beliebigen Datei veranstalten, wenn ich an sie rankomme. Das funktioniert auch bei EXEn, die über 100 MB groß sind.

Aber, mal ganz blöd gefragt: Was soll der "Projektpfad" sein, der irgendwo in der Nähe von "INITSTATICS" in der EXE steckt? Ich kann eine EXE ja in jedes beliebige Verzeichnis kopieren und dort starten, aber ihr Inhalt ändert sich dadurch nicht. Das wäre ja auch noch schöner. Ich finde allerdings bei DEBUG=yes Pfad und Name von PRG und OBJ (sonst nicht!), und bei direkt gelinktem Manifest alle darin enthaltenen Informationen. Anders gefragt: Wonach suchst Du?

Re: Projektpfad aus EXE ermitteln

Verfasst: Fr, 23. Feb 2018 14:25
von brandelh
Ich habe dieses Programm mal in der Workbench laufen lassen ...

Code: Alles auswählen

#include "Common.ch"
PROCEDURE Main
   LOCAL cExe, cBinBuffer, nError, cSuch
   /* we use the ansi charset by default */
   SET CHARSET TO ANSI

   SET ALTERNATE TO test.txt
   SET ALTERNATE ON

   cSuch := "INIT" + "STATICS"  // sonst wird es wegen diesem String gefunden
   cExe  := AppName(.T.)
   ?
   ? "Testprogramm: ",cExe
   ?
   ? "Versuche EXE zu öffenen ..."

   cBinBuffer := file2Str(cExe,,,@nError)

   ? "Ergebnis nError=",nError,"  Eingelesene Bytes: ",len(cBinBuffer)

   ? "Ist '"+cSuch+"' EXE vorhanden ? "

   IF cSuch $ upper(cBinBuffer)
      ? "JA, ab Byte", at(cSuch,cBinBuffer)
   ELSE
      ? "NEIN"
   END IF

   SET ALTERNATE OFF

   inkey(20)


   /* $TODO: place your application code here */
RETURN


*---------------------------------------------------------------------------------------------
FUNCTION File2Str(cFile,nStartPos,nLen,nError)      // memoread() könnte Umwandeln !!!
   LOCAL nHandle, cBuffer, nReadBytes,nSeekPos      // nError muss per Referenz übergeben werden
   cBuffer    := ""
   nReadBytes := 0
   DEFAULT nStartPos TO 1    // normalerweise will man ab dem 1. Zeichen.
   DEFAULT nLen      TO 0    // 0 steht für keine Begrenzung
   IF nStartPos < 1
      nStartPos := 1
   ENDIF
   nError  := 0              // 0 steht für keinen Fehler
   nHandle := FOpen(cFile)
   IF nHandle = -1
      nError := FError()
   ELSE
      IF nLen=0
         nLen := FSize( nHandle )
      ENDIF
      IF nStartPos > 1
         nSeekPos := FSeek( nHandle, nStartPos-1 )
         IF nSeekPos <> nStartPos-1
            nError := -2
         ENDIF
      ENDIF
      cBuffer    := space(nLen)
      nReadBytes := FRead( nHandle, @cBuffer, nLen)
      IF nReadBytes < nLen    // eventuell kein Fehler, sondern nur weniger Daten verf³gbar.
         nError := FError()
      ENDIF
   ENDIF
   FClose(nHandle)
RETURN left(cBuffer,nReadBytes)
das ist das Ergebnis:
Testprogramm: C:\Users\BRANDELH\Documents\Xbase++\Projects\test\Test.exe

Versuche EXE zu öffenen ...
Ergebnis nError= 0 Eingelesene Bytes: 16384
Ist 'INITSTATICS' EXE vorhanden ?
JA, ab Byte 10997
also, es geht ganz einfach mit fOpen() oder meiner damit erstellten Funktion, die EXE Längen sollten auch kein Problem darstellen

Re: Projektpfad aus EXE ermitteln

Verfasst: Fr, 23. Feb 2018 14:31
von brandelh
OK, prüfen wir noch DEBUG=OFF ... EXE wird neu erstellt, direkt gestartet und ...
Testprogramm: C:\Users\BRANDELH\Documents\Xbase++\Projects\test\Test.exe

Versuche EXE zu ”ffenen ...
Ergebnis nError= 0 Eingelesene Bytes: 14848
Ist 'INITSTATICS' EXE vorhanden ?
JA, ab Byte 10997
Es sind weniger Bytes, also wird was weg gelassen, aber die Sprungadresse auf INITSTATICS bleibt gleich.
Was man dort finden soll weiß ich aber auch nicht ...

Re: Projektpfad aus EXE ermitteln

Verfasst: Fr, 23. Feb 2018 17:49
von azzo
Hallo Hubert,
danke für deine Hilfe.
Ich habe deinen Code mit xHarbour kompiliert.
Ich musste nur SET CHARSET TO ANSI kommentieren und habe den Pfad zur gewünschten EXE fix eingegeben.
Hier erhalte ich keinen Treffer.
Könntest du mir bitte zum Testen eine EXE mit xBase geben. Vielleicht kannst du meinen Pfad eingeben.

Mit bestem Dank im Voraus,
Otto

Code: Alles auswählen

  LOCAL cExe, cBinBuffer, nError, cSuch
   /* we use the ansi charset by default */
//  SET CHARSET TO ANSI

   SET ALTERNATE TO test.txt
   SET ALTERNATE ON

   cSuch := "INIT" + "STATICS"  // sonst wird es wegen diesem String gefunden
   cExe  := "c:\xwinhotel\xZahlung.exe" //AppName(.T.)


Testprogramm: c:\xwinhotel\xZahlung.exe
Versuche EXE zu öffenen ...
Ergebnis nError= 0 Eingelesene Bytes: 2075
Ist 'INITSTATICS' EXE vorhanden ?
NEIN

Re: Projektpfad aus EXE ermitteln

Verfasst: Fr, 23. Feb 2018 17:55
von azzo
Hallo Tom,
danke für deine Infos. Ich suche die prg-Datei , die die main Funktion der EXE enthält.

LG
Otto

Re: Projektpfad aus EXE ermitteln

Verfasst: Fr, 23. Feb 2018 23:15
von AUGE_OHR
Frage : über welche Xbase++ Version redet ihr :?:

ich habe das \SOURCE\samples\ Verzeichnis mit TC nach *.EXE und Text = "INITSTATICS" und "DEBUG" durchsucht und nichts gefunden :shock:

Re: Projektpfad aus EXE ermitteln

Verfasst: So, 25. Feb 2018 0:12
von brandelh
Jimmy,

ich habe das mal mit 2 normalen EXE Dateien auspropiert und kann dir nur Zustimmen, warum mein anderes Beispiel etwas gefunden hat ... vermutlich den Suchbegriff selbst

Re: Projektpfad aus EXE ermitteln

Verfasst: So, 25. Feb 2018 1:12
von brandelh
So ich habe mein Programm angepasst, damit der String nicht aus dem Quellcode direkt in der EXE landet und siehe da ... den gibt es gar nicht ;-)

Code: Alles auswählen

#include "Common.ch"
PROCEDURE Main
   LOCAL cExe, cBinBuffer, nError, cSuch1, cSuch2, cSuch
   /* we use the ansi charset by default */
   //   SET CHARSET TO ANSI

   SET ALTERNATE TO test.txt
   SET ALTERNATE ON

   cSuch1 := "IniT"     // sonst wird es wegen diesem String gefunden
   cSuch2 := "STaTICS"  // sonst wird es wegen diesem String gefunden
   cSuch  := upper(rtrim(ltrim(cSuch1)-ltrim(cSuch2)))
   // cExe  := AppName(.T.)
   cExe  := "c:\xwinhotel\xZahlung.exe" //AppName(.T.)
   ?
   ? "Testprogramm: ",cExe
   ?
   ? "Versuche EXE zu öffenen ..."

   cBinBuffer := file2Str(cExe,,,@nError)

   ? "Ergebnis nError=",nError,"  Eingelesene Bytes: ",len(cBinBuffer)

   ? "Ist '"+cSuch+"' in EXE vorhanden ? "

   IF cSuch1 $ upper(cBinBuffer)
      ? "JA, ab Byte", at(cSuch,cBinBuffer)
   ELSE
      ? "NEIN"
   END IF

   SET ALTERNATE OFF

   inkey(20)


   /* $TODO: place your application code here */
RETURN


*---------------------------------------------------------------------------------------------
FUNCTION File2Str(cFile,nStartPos,nLen,nError)      // memoread() könnte Umwandeln !!!
   LOCAL nHandle, cBuffer, nReadBytes,nSeekPos      // nError muss per Referenz übergeben werden
   cBuffer    := ""
   nReadBytes := 0
   DEFAULT nStartPos TO 1    // normalerweise will man ab dem 1. Zeichen.
   DEFAULT nLen      TO 0    // 0 steht für keine Begrenzung
   IF nStartPos < 1
      nStartPos := 1
   ENDIF
   nError  := 0              // 0 steht für keinen Fehler
   nHandle := FOpen(cFile)
   IF nHandle = -1
      nError := FError()
   ELSE
      IF nLen=0
         nLen := FSize( nHandle )
      ENDIF
      IF nStartPos > 1
         nSeekPos := FSeek( nHandle, nStartPos-1 )
         IF nSeekPos <> nStartPos-1
            nError := -2
         ENDIF
      ENDIF
      cBuffer    := space(nLen)
      nReadBytes := FRead( nHandle, @cBuffer, nLen)
      IF nReadBytes < nLen    // eventuell kein Fehler, sondern nur weniger Daten verf³gbar.
         nError := FError()
      ENDIF
   ENDIF
   FClose(nHandle)
RETURN left(cBuffer,nReadBytes)
Ergebnis in test.txt:

Testprogramm: c:\xwinhotel\xZahlung.exe
Versuche EXE zu öffenen ...
Ergebnis nError= 0 Eingelesene Bytes: 10752
Ist 'INITSTATICS' in EXE vorhanden ?
NEIN
Diese Variable wird nicht von Xbase++ selbst gesetzt ... versuchen wir es noch mit DEBUG=YES ...


Testprogramm: c:\xwinhotel\xZahlung.exe
Versuche EXE zu öffenen ...
Ergebnis nError= 0 Eingelesene Bytes: 11776
Ist 'INITSTATICS' in EXE vorhanden ?
NEIN
Wichtig an der Geschichte ist aber, dass fOpen() die EXE fehlerfrei öffnet (nError=0 bedeutet KEIN Fehler) und meine Funktion die Datei in einen String lädt.

Re: Projektpfad aus EXE ermitteln

Verfasst: So, 25. Feb 2018 1:31
von azzo
Hallo Hubert,
auch hier wird mit fOpen() die Datei geöffnet. Aber leider wird nach einigen Bytes dann der Lesevorgang abgebrochen.
LG
Otto

Re: Projektpfad aus EXE ermitteln

Verfasst: So, 25. Feb 2018 7:30
von georg
Hallo, Otto -


wie liest Du, verwendest Du fRead() oder fReadStr()?

fReadStr() hört auf, wenn ein Chr(0) gelesen wird, und das hört sich nach Deinem Problem an.

Re: Projektpfad aus EXE ermitteln

Verfasst: So, 25. Feb 2018 19:51
von azzo
Hallo Georg,
danke für deine Hilfe und den Hinweis Chr(0).

Genau das war mein Problem.

Ich habe mir immer nur
cBuf := MEMOREAD( cExe )
angeschaut und anzeigen lassen.
Hier wird dann nach dem ersten CHR(0) einfach abgeschnitten.
Anbei die Funktion die bei mir nun funktioniert.
Die Funktion liefert den Pfad des prg Files - file in dem die main -Funktion enthalten ist - der EXE zurück.
Die Funktion dürfte 1:1 auch mit xBase funktionieren.
LG
Otto


Code: Alles auswählen

function PrjPath( cExe )

   local cBuf, nAt

   if Empty( cExe )
      return nil
   endif

   cBuf  := MEMOREAD( cExe )
   cBuf  := AfterAtNum( "(_INITSTATICS", cBuf, 1 )
   cBuf  := AfterAtNum( Chr( 0 ), cBuf, 1 )
   cBuf  := BeforAtNum( Chr( 0 ), cBuf, 1 )

return cBuf


Re: Projektpfad aus EXE ermitteln

Verfasst: Mo, 26. Feb 2018 9:20
von brandelh
Und wieder einmal zeigt es sich, dass es NICHT egal ist mit welchem Clipper Nachfolger man arbeitet !

1. EXE von Xbase++ oder auch PowerBasic enthalten kein Schlüsselwort INITSTATICS, das habe ich jetzt bei 5 EXE Dateien mit HEX-Editor überprüft.

2. MemoRead() aus Xbase++ liest eine BIN Datei (also auch jede EXE) komplett ein, egal ob chr(0) oder sonstwas drin enthalten ist; wobei ich nicht auf chr(26) getestet habe.

Hier die Ausgabe eines Abwandelten Xbase++ Test Programmes (einmal mit memoedit(), das zweite mal mit meiner file2str() Funktion):
Versuche EXE zu öffenen, MemoEdit() ...
Ergebnis Eingelesene Bytes: 15360
Versuche EXE zu öffenen, File2Str() ...
Ergebnis nError= 0 Eingelesene Bytes: 15360
Ist 'IniTStaTICS' EXE vorhanden ?
NEIN
(x)Harbour übersetzt ja RRG Code nach C-Code und ein C-Compiler übersetzt das dann.
Für C-Compiler Funktionen ist es normal bei chr(0) nicht mehr weiter zu lesen.

Alaska hat bei Xbase++ beide Verhaltensweisen ...

Memoread() liest alles, aber fReadStr() hört auch bei chr(0) auf.
Dennoch, Memoread() sollte laut Alaska nicht verwendet werden, da es eigentlich eine Text-Funktion ist, EXE Dateien etc. sind aber Binär-Daten.

Re: Projektpfad aus EXE ermitteln

Verfasst: Mo, 26. Feb 2018 11:09
von ramses
Hallo Hubert

bist du dir mit Harbour sicher?
Meine Version die ich unter FreeBSD verwende übersetzt PRG's in Pseudo-Code und das Runtime-Modul arbeitet diese dann ab.

Gruss Carlo

Re: Projektpfad aus EXE ermitteln

Verfasst: Mo, 26. Feb 2018 11:27
von brandelh
Ich ging davon aus, dass das von AZZO beschriebene Verhalten von Memoedit() unter xHarbour beobachtet wurde.

Da könnte ich mich aber auch täuschen. Wie die Runtime das dann umsetzt weiß ich auch nicht, aber dass C-Funktionen normalerweise chr(0) als Ende des Strings interpretieren stimmt.
Wenn man das anders machen möchte, muss man die "Strings" als Array of Byte behandeln und dann geht das auch mit den chr(0) im Datenstrom, sonst wäre eine Verarbeitung von Binär-Daten ja nicht möglich.
Aber um es deutlich zu sagen, meine C-Kenntnisse beschränken sich auf das Lesen von Parameter Aufrufen für meine DLL Libs ;-)

Was ich eigentlich nur sagen wollte ist:

Wenn man wie in diesem Thread (zudem unter Allgemein !) ein (Fehl-)Verhalten schildert und eben NICHT Xbase++ nutzt, bitte dazu schreiben soll, dass es um XYZ Compiler geht.

Re: Projektpfad aus EXE ermitteln

Verfasst: Mo, 26. Feb 2018 14:51
von ramses
Hallo Otto

du könntest doch mit dem Texteditor eine "File Suche" in den prg's in deinen Verzeichnisen und Unterverzeichnisen suchen. z.B. nach " main" Multiedit liefert dir dann alle Dateien im gewählten Verzeichnisbaum die " main" enthalten.

Gruss Carlo

Re: Projektpfad aus EXE ermitteln

Verfasst: Mo, 26. Feb 2018 15:36
von azzo
Hallo Carlo,
ich habe schon weiter oben gepostet, dass ich dank eurer Hilfe das Problem lösen konnte.
Danke nochmals an alle.
LG
Otto

Hallo Georg,
danke für deine Hilfe und den Hinweis Chr(0).

Genau das war mein Problem.

Ich habe mir immer nur
cBuf := MEMOREAD( cExe )
angeschaut und anzeigen lassen.
Hier wird dann nach dem ersten CHR(0) einfach abgeschnitten.
Anbei die Funktion die bei mir nun funktioniert.
Die Funktion liefert den Pfad des prg Files - file in dem die main -Funktion enthalten ist - der EXE zurück.
Die Funktion dürfte 1:1 auch mit xBase funktionieren.
LG
Otto

Code: Alles auswählen

function PrjPath( cExe )

   local cBuf, nAt

   if Empty( cExe )
      return nil
   endif

   cBuf  := MEMOREAD( cExe )
   cBuf  := AfterAtNum( "(_INITSTATICS", cBuf, 1 )
   cBuf  := AfterAtNum( Chr( 0 ), cBuf, 1 )
   cBuf  := BeforAtNum( Chr( 0 ), cBuf, 1 )

return cBuf