Forum: PC-Programmierung 0x00 ausgeben mit printf in c


von xvzf (Gast)


Lesenswert?

Hallo,

Ich habe ein kleines Problem.
Im Sinne eines Projekts muss ich einen Shellcode in C Ausgeben, jetzt 
muss die Bytefolge 0x00 0xf1 0x34 ausgegeben werden.

Verwendet werden muss printf, das Problem ist, 0x00 bzw \0 ist der 
Terminator eines char strings, wird also als "Ende erkannt" und es wird 
nicht weiter ausgegeben? Wie kann ich das umgehen? Ich habe google schon 
gefragt aber offenbar nicht die richtigen Suchbegriffe eingegeben.

Gruß,
Matthias

von rüdiger (Gast)


Lesenswert?

Zum Beispiel mit
1
printf("%c", '\0')

von xvzf (Gast)


Lesenswert?

Herzlichen Dank!

von Oliver S. (oliverso)


Lesenswert?

Nur am Rande gefragt: Was für ein Zeichen erwartest du dabei als Ausgabe 
am Bildschirm?

Oliver

von Peter D. (peda)


Lesenswert?

xvzf schrieb:
> Herzlichen Dank!

Wofür?
Du zwingst damit nur printf einen leeren String anzulegen, aber 
ausgegeben wird der trotzdem nicht.
printf ruft putchar auf und bricht bei der 0 ab. Da die 0 zuerst im 
Puffer steht, wird nichts ausgegeben.

Man kann nunmal aus einem Sieb keinen Kaffee trinken.

von Peter S. (psavr)


Lesenswert?

putchar(0);

von eric (Gast)


Lesenswert?

Peter D. schrieb:
> Du zwingst damit nur printf einen leeren String anzulegen, aber
> ausgegeben wird der trotzdem nicht.

Das waere bei %s der Fall, %c gibt trotzdem ein Zeichen aus. Wenn du mir 
nicht glaubst, probier es halt selber aus, leite die Ausgabe in eine 
Datei und guck sie dir im Hexeditor an...

von Mikro 7. (mikro77)


Lesenswert?

Peter D. schrieb:

> printf ruft putchar auf und bricht bei der 0 ab. Da die 0 zuerst im
> Puffer steht, wird nichts ausgegeben.

Wieso sollte die Null nicht ausgegeben werden? Nur bei ASCIIZ (%s) ist 
es das Endezeichen. Bei %c wird das Zeichen ausgegeben.
1
#include <stdio.h>
2
int main()
3
{
4
  printf("%c",0) ;
5
  return 0 ;
6
}
1
prompt> ./test | od -c
2
0000000  \0
3
0000001

von Daniel A. (daniel-a)


Lesenswert?

Alernativen:
1
fwrite((uint8_t[]){0x00,0xf1,0x34},1,3,stdout);
2
//oder 
3
fwrite("\0\xf1\x34",1,3,stdout);

von Peter D. (peda)


Lesenswert?

eric schrieb:
> Das waere bei %s der Fall, %c gibt trotzdem ein Zeichen aus.

Dann habe ich das wohl mit sprintf verwechselt, das kann kein 0-Byte 
ausgeben.

Trotzdem würde ich printf nie für Binärdaten verwenden, das ist einfach 
das falsche Werkzeug dafür.

von Mark B. (markbrandis)


Lesenswert?

Peter D. schrieb:
> Trotzdem würde ich printf nie für Binärdaten verwenden, das ist einfach
> das falsche Werkzeug dafür.

Warum?

Zu Zwecken des Debuggings kann man mit printf wunderbar Binärdaten als 
Hex-Werte auf der Konsole ausgeben (oder Dezimalwerte, oder Oktalwerte, 
oder Gleitkommazahlen, ...). Klappt einwandfrei.

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Peter D. schrieb:
> eric schrieb:
>> Das waere bei %s der Fall, %c gibt trotzdem ein Zeichen aus.
>
> Dann habe ich das wohl mit sprintf verwechselt, das kann kein 0-Byte
> ausgeben.

Auch sprintf gibt – genauso wie fprintf und printf – das NUL-Zeichen und
alle ggf. danach kommenden Zeichen aus. Das kannst du bspw. mit Hilfe
eines Debuggers oder fwrite feststellen.

Wenn du dir das Ergebnis allerdings mit puts oder einer anderen
stringbasierten I/O-Funktion anschauen möchtest, wird die Ausgabe beim
ersten NUL-Zeichen abgebrochen. Das ist aber eine Eigenschaft dieser
Stringfunktionen, nicht von sprintf.

Beispiel:

sprintftest.c:
1
#include <stdio.h>
2
3
int main(void) {
4
  char buf[16];
5
  int n;
6
7
  n = sprintf(buf, "Anfang%cEnde\n", 0);
8
  fwrite(buf, sizeof (char), n, stdout);
9
  puts(buf);
10
  return 0;
11
}

1
$ sprintftest | cat -v
2
Anfang^@Ende
3
Anfang

Das "^@" steht für das NUL-Zeichen.

: Bearbeitet durch Moderator
von Yalu X. (yalu) (Moderator)


Lesenswert?

Mark B. schrieb:
> Zu Zwecken des Debuggings kann man mit printf wunderbar Binärdaten als
> Hex-Werte auf der Konsole ausgeben

Peter meinte die direkte Ausgabe der Binärdaten. Wenn diese per %x in
die Hex-Darstellung konvertiert werden, sind die ausgegebenen Zeichen ja
wieder ganz gewöhnliche, druckbare Zeichen.

Ob [fs]printf auch für die Ausgabe von nichtdruckbaren Zeichen genutzt
wird, ist IMHO eine Frage der konkreten Anwendungsfalls und des
persönlichen Geschmacks.

von xvzf (Gast)


Lesenswert?

Das ganze war eine Ausgabe für Shellcode, ich erwarte kein Zeichen! Nur 
eine Bytefolge um schnell etwas zu testen!

Und es funktioniert. Ist eine quickndirty Lösung und wird später richtig 
implementiert. Aber bis dahin muss printf reichen!

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.