0x00 ausgeben mit printf in c

Gast #4450740
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
Gast #4451625
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...
#4451627
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
Moderator #4452602
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.
Moderator #4452631
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.
Gast #4453565
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!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren