Forum: Compiler & IDEs String im Kompilat


von Siegfried (Gast)


Lesenswert?

Hallo,

ich würde gerne für eine Versinkennung einen String aus dem Quellcode in 
der kompilierten Binärdatei wieder finden:

#define FIND "TEST123"
printf("%s", FIND);

Ich kann den String "TEST123" nach dem kompilieren in der Binärdatei 
aber nicht finden. Ist so etwas möglich?

Siegfried

von Peter II (Gast)


Lesenswert?

Siegfried schrieb:
> Ist so etwas möglich?

scheinbar schon, sonst würdest du ihn ja finden. Aber ich üblicherweise 
ist er drin. Oder suchst du im Hexfile?

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Nein. Such noch mal ;)

von Ralf G. (ralg)


Lesenswert?

Siegfried schrieb:
> #define FIND "TEST123"
> printf("%s", FIND);

Ist das nur ein Beispiel? Oder hast du das exakt so im Quelltext stehen?

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

Siegfried schrieb:
> Versinkennung

wasn das?

von amateur (Gast)


Lesenswert?

Z.B. wenn Du mit 16-Bit-Zeichen arbeitest.

Ob Dein oben angeführtes Beispiel überhaupt funktioniert weiß ich nicht, 
aber Du bist möglicherweise über die Füße von Billy Boy gestolpert.
Die Windows-Suchfunktion ignoriert einen ganzen Sack voll Erweiterungen, 
ich weiß es von .Pas her und durchsucht diese (Kommentarlos) überhaupt 
nicht.
Also geh' mal ruhig fremd und freunde Dich, mit einer anderen 
(Suchhilfe) an.

von Siegfried (Gast)


Lesenswert?

@Wegstaben Verbuchsler
So mit einer Prise nachdenken, was könnte es heißen, na, na?, naaa? 
Vielleicht Versionskennung? Jetzt wo es klar ist, weißt Du bestimmt die 
Lösung...

Ansonsten:
Ich habe die Datei mit einem Texteditor durchsucht. Dabei ist mir 
aufgefallen dass kein einziger in der Software vorkommender String zu 
sehen ist. Kann es sein dass die exe vom Compiler implizit gepackt wird? 
Es ist übrigens ein GCC Crosscompiler der Code für einen ARM9 µC Linux 
Kleinrechner erzeugt.

Grüße
Siegfried

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Vielleicht wide char ?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Du kannst in der vom Compiler generierten Assembler-Datei des 
entsprechenden Moduls nachschauen, ob und in welcher Form der Textstring 
Eingang in das Executable findet.

von tare (Gast)


Lesenswert?

Siegfried schrieb:
> Ich habe die Datei mit einem Texteditor durchsucht
Suchst du auch in der richtigen Datei?

von Ralf G. (ralg)


Lesenswert?

Ralf G. schrieb:
> Ist das nur ein Beispiel?

Ich versuch's nochmal: Machst du mit dem definierten String irgendwas 
sinnvolles? Vielleicht hat der Compiler den eingespart. Oder erledigt 
die Ausgabe anders?

von Helmut L. (helmi1)


Lesenswert?

Siegfried schrieb:
> Ich habe die Datei mit einem Texteditor durchsucht.

Ich wuerde da mal einen Hexeditor nehmen.

von Siegfried (Gast)


Lesenswert?

Im Moment gebe ich den String nur einmal an fprint, sonst ist dieser 
unbenutzt. Ich suche nochmal mit dem Hexeditor...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Und die Stelle, an der Du den String "an fprintf gibst", die wird auch 
tatsächlich aufgerufen und ist nicht wegoptimiert?

von cppler (Gast)


Lesenswert?

Dann mach Dir eine Versionsanzeige auf der Kommandozeile wie unter Un*x 
üblich.
Also "meinprogramm /v" gibt dann "Version 1.02" aus.

von Thomas E. (thomase)


Lesenswert?

Siegfried schrieb:
> Im Moment gebe ich den String nur einmal an fprint, sonst ist dieser
> unbenutzt. Ich suche nochmal mit dem Hexeditor...

Im *.hex wirst du den auch so nicht finden. Da musst du nach den 
ASCII-Zeichen des ASCII-Codes deiner Zeichen im String suchen. Wenn es 
denn ASCII ist.
"T" ist 0x54. Im *.hex steht dann "54"
"TEST123" >> "54455354313233". Danach musst du suchen(lassen).

mfg.

von Andreas B. (andreas_b77)


Lesenswert?

Thomas Eckmann schrieb:
> "T" ist 0x54. Im *.hex steht dann "54"
> "TEST123" >> "54455354313233". Danach musst du suchen(lassen).

Außer in der .hex ist mitten in diesem String ein Zeilenumbruch… Wenn 
das Entwicklungssystem gcc-basiert ist, dann sind die binutils auch 
dabei. Darin gibt es das Programm strings, das aus ausführbaren und 
Objektdateien alle Strings ausgeben kann (definiert als Abfolge von 
mindestens 4 druckbaren Zeichen). Das sollte auch mit Hex-Dateien 
arbeiten können.

von Klaus W. (mfgkw)


Lesenswert?

Häufig wird im Quelltext des Hauptmoduls etwa folgendes geschrieben als 
globales Objekt:
1
const char *version = "ganztoll (tm) 0.99a 2013-04-01 (C) 2013 Lug&Trug GmbH&Co.KG";
bzw. Version und Datum darin automatisch generiert, z.B. über svn.
Dadurch daß es eine globale Variable ist, kann der Compiler sie nicht 
wegoptimieren - er weiß ja nicht, ob sie nicht in anderen Modulen 
benötigt wird.



cppler schrieb:
> Also "meinprogramm /v" gibt dann "Version 1.02" aus.

meinprogramm -v wäre etwas unixüblicher :-)

von Dr. Sommer (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Dadurch daß es eine globale Variable ist, kann der Compiler sie nicht
> wegoptimieren - er weiß ja nicht, ob sie nicht in anderen Modulen
> benötigt wird.
Da es aber der Linker weiß, macht er genau das; wird u.a. verwendet um 
nicht benutzte Bibliotheksfunktionen wegzuoptimieren. Dieses Feature 
muss man zwar nicht einschalten, aber dadurch verliert man eben die 
sonstige Wegoptimierung von unbenutzten Variablen. Beim GCC kann man 
stattdessen __attribute__((used)) an die Variable schreiben um ein 
Wegoptimieren dieser einen Variable komplett zu verhindern.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Dr. Sommer schrieb:
> Klaus Wachtler schrieb:
>> Dadurch daß es eine globale Variable ist, kann der Compiler sie nicht
>> wegoptimieren - er weiß ja nicht, ob sie nicht in anderen Modulen
>> benötigt wird.
> Da es aber der Linker weiß, macht er genau das; wird u.a. verwendet um
> nicht benutzte Bibliotheksfunktionen wegzuoptimieren. Dieses Feature
> muss man zwar nicht einschalten, aber dadurch verliert man eben die
> sonstige Wegoptimierung von unbenutzten Variablen. Beim GCC kann man
> stattdessen __attribute__((used)) an die Variable schreiben um ein
> Wegoptimieren dieser einen Variable komplett zu verhindern.

Er hatte das aber mit printf() ausgegeben, da sollte es vorhanden sein
weil's angesprochen bzw. verwendet wird (s. erster Post).

von Dr. Sommer (Gast)


Lesenswert?

Joachim Drechsel schrieb:
> Er hatte das aber mit printf() ausgegeben, da sollte es vorhanden sein
> weil's angesprochen bzw. verwendet wird (s. erster Post).
Ja, mein Hinweis bezog sich auf Klaus Wachtler's Vorschlag, der kein 
printf() verwendet und einfach davon ausgeht, dass nichts wegoptimiert 
wird.

von amateur (Gast)


Lesenswert?

Ich glaube hier geht irgendetwas durcheinander.

Von Siegfried:
>in der kompilierten Binärdatei wieder finden
>Kann es sein dass die exe vom Compiler implizit gepackt
>Es ist übrigens ein GCC Crosscompiler der Code für einen ARM9 µC Linux

An anderer Stelle:
>Du kannst in der vom Compiler generierten Assembler-Datei
>Ich habe die Datei mit einem Texteditor durchsucht
>Ich suche nochmal mit dem Hexeditor
>Im *.hex wirst du den auch so nicht finden.

Mich würde mal interessieren ob hier über:
xxxx,
xxxx.o,
xxxx.exe (Sonderwunsch),
xxxx.asm,
xxxx.hex,
xxxx.obj oder
wie auch immer die Dinger heißen geredet wird?

Vielleicht lässt sich dann irgendein System aufstellen, zusammen mit 
einem kleinen Hinweis darauf, ob mit dem guten, alten ASCII, oder mit 
einem seiner 16-Bit Verwandten, gearbeitet wird.

von Alex W. (a20q90)


Lesenswert?

Du musst sowas schreiben:

const char *version = "V1.00";

Klaus Wachtler schrieb:

> cppler schrieb:
>> Also "meinprogramm /v" gibt dann "Version 1.02" aus.
>
> meinprogramm -v wäre etwas unixüblicher :-)

ein / ist heute aber viel cooler! Vorallem seit dem es /dance oder /huhn 
gibt

von Klaus W. (mfgkw)


Lesenswert?

... und man / eine Option nicht von einem Pfad-Argument unterscheiden 
kann; dadurch wird alles viel spannender!

von Rolf Magnus (Gast)


Lesenswert?

Siegfried schrieb:
> Ich habe die Datei mit einem Texteditor durchsucht.

Und der kommt auch mit Binärdateien zurecht?

> Dabei ist mir aufgefallen dass kein einziger in der Software vorkommender
> String zu sehen ist. Kann es sein dass die exe vom Compiler implizit
> gepackt wird?

Was ist denn "die exe"? Um welches Dateiformat handelt es sich?

von Klaus (Gast)


Lesenswert?

Siegfried schrieb:
> Es ist übrigens ein GCC Crosscompiler ....

Endianess?

MfG Klaus

von test (Gast)


Lesenswert?

Alex W. schrieb:
>> meinprogramm -v wäre etwas unixüblicher :-)
>
> ein / ist heute aber viel cooler! Vorallem seit dem es /dance oder /huhn
> gibt

trotzdem ist das -v bei vielen einfach im Blut wenn sie die Version 
eines Programms erfragen möchten. (Also bei allen, die ernsthaft 
arbeiten, also mit Unixartigen Systemen.)

Das /h oder /v kenne ich soweit nur aus der Windowswelt. Und die ist ja 
insbesondere für die Konsistenz und Mächtigkeit auf der Kommandozeile 
bekannt. ;)

von Siegfried (Gast)


Lesenswert?

Also, ich habe zuerst in der erzeugten Assemblerdatei nachgesehen, da 
finde ich die Strings, z.B.

-LC11:
  .ascii "###VERSIONTOKEN1.21***\000
  .align2

Vermutlich deutet das align schon darauf hin dass jedes zeichen in 2 
Bytes verpackt wird?

von Karl H. (kbuchegg)


Lesenswert?

Vielleicht.
Vielleicht auch nicht.

Was ich tun würde:
Das restliche Programm exakt gleich lassen und lediglich 1 Buchstaben 
des Strings verändern.

D.h. du hast dann 2 EXE, die an und für sich identisch sind, bis auf 
einen Buchstaben in einem auszugebenden String. Jedes Difference-Tool 
wird dir diesen Unterschied in den beiden EXE finden. Und dann schau ich 
mir in einem Hex-Editor die Umgebung dieser gefundenen 
Differenz-Position an. Danach weiß ich es genau.

von Siegfried (Gast)


Lesenswert?

Wenn ich auch nur ein einziges Zeichen ändere (einen einzelnen 
Buchstaben inmitten eines Strings) flippt das diff Tool aus, da ist 
allesmögliche anders! Ist warscheinlich irgendwie gepackt...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Siegfried schrieb:
> .align2
>
> Vermutlich deutet das align schon darauf hin dass jedes zeichen in 2
> Bytes verpackt wird?

Nein.  Es bedeutet nur, dass danach ggf. ein Füllbyte eingefügt
werden muss, damit die folgenden Befehle wieder auf einer geraden
Adresse beginnen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.