Daten in Bmp-Bildern verstecken

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

 

Krümel

Betreff: Daten in Bmp-Bildern verstecken

BeitragMo, Jan 08, 2007 11:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo!
ich habe vor Kurzem die Idee gehabt, Bmp-Bilder als Träger "geheimer Daten" zu missbrauchen. nach kurzer Rechereche viel mir auf, dass ich damit keinesfalls eine neue Idee geboren hatte, vielmehr gab es etwas ähnliches schon zu Zeiten der alten Griechen.
Das ganze nennt sich Steganographie (nicht zu verwechseln mit Stenografie).

Die Daten werden so in der Bmp-Datei untergebracht, dass sich die Dateigröße des Bildes nicht ändert und es sich optisch vom Original nicht unterscheidet.

Alles was man braucht ist eine Bmp-Datei und eine zu verteckende Datei.
Die Bmp-Datei muss mindestens 8 mal größer als die zu versteckende Datei sein. (Diese kann natürlich vorher gepackt werden)

*Edit*
Hätte ich die Forensuche benutzt dann hätte ich gemerkt dass sowas schonmal gepostet wurde... Rolling Eyes

Hier mein kleines Programm:
Code: [AUSKLAPPEN]

;Programm zum Einbetten von Daten in Bmp-Bildern.
;Voraussetzung:
;- Bmp muss Farbtiefe von 24-Bit haben
;- Bmp muss min. 8 mal so gross wie zu versteckende Datei sein

WriteSecretBmp("Picture.Bmp" , "secret.txt")

ReadSecretBmp ("Picture.Bmp")

Function WriteSecretBmp(BmpFile$ , inFile$)
   If FileSize(inFile) > (FileSize(BmpFile) / 8 ) Then
      RuntimeError Chr$(34) + BmpFile + Chr$(34) + " too small !" + Chr$(10) + "Size:" + Chr$(9) + Chr$(9) + FileSize(BmpFile) Shr 10 + " KB " + Chr$(10) + "min Size: " + Chr$(9) + FileSize(inFile) Shr 7 + " KB"
   EndIf
   
   Bmp = OpenFile(BmpFile) : If Bmp = 0 RuntimeError BmpFile + " not found !"
   in =  ReadFile(inFile)  : If in  = 0 RuntimeError inFile  + " not found !"

   SeekFile Bmp , 10 : SeekFile Bmp , ReadInt (Bmp)
   HeaderString$= "SEC" + LSet(FileSize(inFile) , 10) + LSet(Len(inFile),4) + inFile + "  "

   b = Asc( Left$(HeaderString , 1) ) : bi$ = Right$( Bin$( b ) , 8)
   HeaderString=Mid$( HeaderString , 2)

   SizeBmp=FileSize(BmpFile) : sizeSec=FileSize(inFile)
   For t = FilePos(Bmp) To SizeBmp
      SeekFile Bmp , t   
      b=ReadByte(Bmp)
      If (b * 0.5) = (b Shr 1) Then b1 = 0 Else b1 = 1      

      If b1 <> Mid$(bi$ , ofs+1 , 1) Then
         SeekFile Bmp , t
         If b = 0 Then b = 2
         WriteByte Bmp , b - 1
      EndIf
      
      ofs = (ofs + 1) Mod 8
      If ofs = 0 Then
         If Eof(in) Then Exit
         If HeaderString<>""
            b = Asc( Left$(HeaderString , 1) )
            HeaderString=Mid$( HeaderString , 2)
         Else
            b = ReadByte(in)
         EndIf   
         bi$ = Right$( Bin( b ) , 8)
         c = c + 1 : If c = 5000 Then c = 0 AppTitle "write secret " + ((t Shr 3) * 100) / SizeSec + "%"
      EndIf
   Next
   CloseFile Bmp
   CloseFile in
   Print inFile + " written to " + BmpFile
End Function

Function ReadSecretBmp(BmpFile$)
   Bmp = ReadFile(BmpFile$) : If Bmp = 0 RuntimeError BmpFile + " not found !"
   Local HeadInfo$[4]

   SeekFile Bmp , 10 : SeekFile Bmp , ReadInt (Bmp)
   ReadHeader=True
   SizeBmp=FileSize(BmpFile)
   For t = pos=FilePos(Bmp) To SizeBmp
      b = ReadByte(Bmp)
      If (b * 0.5) <> (b Shr 1) Then byte = byte Or ( 1 Shl (7 - ofs) )

      ofs = (ofs + 1) Mod 8
      If ofs = 0 Then
         If ReadHeader = True
            If HeadOfs <   3 HeadInfo[0] = HeadInfo[0] + Chr(byte) Else If HeadInfo[0] <> "SEC" Then RuntimeError BmpFile + " enthält keine Daten"
            If HeadOfs >=  3 And HeadOfs < 13 HeadInfo[1] = HeadInfo[1] + Chr(byte)               
            If HeadOfs >= 13 And HeadOfs < 17 HeadInfo[2] = HeadInfo[2] + Chr(byte)            
            If HeadOfs >= 17 And HeadOfs < (18 + Int(HeadInfo[2]))   HeadInfo[3] = HeadInfo[3] + Chr(byte)            
            If HeadOfs >= (18 + Int(HeadInfo[2]))
               out = WriteFile("extracted." + HeadInfo[3]): If out = 0 RuntimeError "can't save " + HeadInfo[3]
               SizeSec = Int(HeadInfo[1])
               ReadHeader = False
            End If
            HeadOfs = HeadOfs + 1
         Else
            WriteByte out , byte
            cnt = cnt + 1 : If cnt = SizeSec Then Exit            
         EndIf   
         byte = 0
         c = c + 1 : If c = 100 Then c = 0 AppTitle "Read secret " + ((cnt * 100) / sizeSec) + "%"
      EndIf
   Next
   CloseFile Bmp
   CloseFile out
   Print HeadInfo[3] + " extracted from " + BmpFile   
End Function
 

#Reaper

Newsposter

BeitragMo, Jan 08, 2007 15:31
Antworten mit Zitat
Benutzer-Profile anzeigen
schon ne tolle sache Wink

hatte mal gesehen, dass jemand eine .jpg oder .bmp (weiß nimmer genau) so erstellt hat, dass wenn man das Bild in .rar umbenannt hat, eine richtige (und funktionierende) rar-Datei rausbekommen hat, kA wie die das genau machten Wink
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7

Eingeproggt

BeitragMo, Jan 08, 2007 20:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich nehme an, das Bild konnte man sich vorher anschauen, weil sonst wärs echt keine Kunst Wink
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

Smily

BeitragMo, Jan 08, 2007 20:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde mal sagen, dass man, wenn man mit dem Dateiaufbau von JPG, BMP und RAR genau vertraut ist, sowas relativ einfach machen kann.
Wobei ich mich hier nicht genauer festelegen möchte, da ich mich noch nicht mit den Dateiformaten auseinandergesetzt habe.

Soweit ich war doch Steganographie aber eher so, dass die Daten durch minimale änderung der Farbwerte in den Pixeln in das Bild eingespeist werden.

Wieso muss das Bild eigentlich 8 mal so groß sein wie die Originaldatei?
Ich habe mich auch mal mit Steganografie beschäftigt und habe dabei gemerkt, dass man ein Byte nicht auf 8 verteilen muss.
Wenn man die Letzten 2 oder 3 Bits eines farb-Bytes verändert dürfte der Unterschied auch noch nicht großartig auffallen.

Gruß, Smily0412
Lesestoff:
gegen Softwarepatente | Netzzensur | brain.exe | Unabhängigkeitserklärung des Internets

"Wir müssen die Rechte der Andersdenkenden selbst dann beachten, wenn sie Idioten oder schädlich sind. Wir müssen aufpassen. Wachsamkeit ist der Preis der Freiheit --- Keine Zensur!"
stummi.org
 

Krümel

BeitragMo, Jan 08, 2007 21:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:

Wieso muss das Bild eigentlich 8 mal so groß sein wie die Originaldatei?
Ich habe mich auch mal mit Steganografie beschäftigt und habe dabei gemerkt, dass man ein Byte nicht auf 8 verteilen muss.
Wenn man die Letzten 2 oder 3 Bits eines farb-Bytes verändert dürfte der Unterschied auch noch nicht großartig auffallen.


Ja, das wäre natürlich machbar. Aber in meinem Programm ändere ich nur das letzte Bit. deshalb 8 x größer. Würde ich mehr Bits ändern könnten sich entsprechend größere Datenmengen unterbringen lassen. (Ist mir leider erst nach meinen posting eingefallen).

Smily

BeitragMo, Jan 08, 2007 22:03
Antworten mit Zitat
Benutzer-Profile anzeigen
machs doch so, dass man das einstellen kann, also auf wieviel die zerlegten Bytes Nachricht verteilt werden sollen.

bis ungefähr 3 Bits ist der Qualitätsverlust noch relativ gering.
Aber gerade die 3 hat das Problem, dass die Zerlegten Bytes nicht gleichmäßig über die Bits verteilt werden können.

die daten würden sich so auf die bits verteilen:

die 0's stehen für die Bilddaten.
die 1, 2 und 3en stehen für die Zerlegten Datanbytes. (Nehmen natürlich nur 0 oder 1 an ^^)

00000111 00000111 000000112 000000222 000000222 000000233 000000333 000000333

Ist etwas Komplizierter. Ich hatte dazu mal vor ein paar monaten einen kleinen Ansatz gehabt, aber das Projekt dann aus Zeitgründen einstellen müssen. Ist auch nichts wirklich brauchbares geworden ^^

Gruß, Smily0412
Lesestoff:
gegen Softwarepatente | Netzzensur | brain.exe | Unabhängigkeitserklärung des Internets

"Wir müssen die Rechte der Andersdenkenden selbst dann beachten, wenn sie Idioten oder schädlich sind. Wir müssen aufpassen. Wachsamkeit ist der Preis der Freiheit --- Keine Zensur!"
stummi.org
 

Krümel

BeitragMi, Jan 10, 2007 0:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier ist eine neue Version.
Jetzt kann man auch die Anzahl der Bits verändern. (Werte über 3 machen aber wenig Sinn)


Code: [AUSKLAPPEN]

;Programm zum Einbetten von Daten in Bmp-Bildern.

Const Bits=2   

WriteSecretBmp("Picture.bmp" , "Secret.txt")
ReadSecretBmp ("Picture.bmp")

Function WriteSecretBmp(BitmapFile$ , SecretFile$)
   Bitmap  = ReadFile(BitmapFile) : If Bitmap = 0 RuntimeError BitmapFile + " not found !"
   Bitmap2 = OpenFile(BitmapFile)
   Secret = ReadFile(SecretFile) : If Secret = 0 RuntimeError SecretFile + " not found !"
   If Bits<1 Or Bits>8 RuntimeError "Bitvalue must be 1-8"

   SizeBitmap = FileSize(BitmapFile)
   SizeSecret = FileSize(SecretFile)   

   If (SizeSecret * (8-Bits)) > SizeBitmap Then
      string1$ = Chr$(10) + "Size:" +      Chr$(9) + Ceil(SizeBitmap / 1024.0) + " KB "
      string2$ = Chr$(10) + "min Size: " + Chr$(9) + Ceil((SizeSecret * (8-Bits)) / 1024.0) + " KB "
      RuntimeError Chr$(34) + BitmapFile + Chr$(34) + " too small !" + String1  + String2
   EndIf

   SeekFile Bitmap , 10 : SeekFile Bitmap , ReadInt (Bitmap) : SeekFile Bitmap2 , FilePos(Bitmap)
   HeaderString$= "SEC" + LSet(FileSize(SecretFile) , 10) + LSet(Len(SecretFile),4) + SecretFile + "  "

   SizeSecret = FileSize(SecretFile)
   BitMask = (1 Shl Bits) - 1
   Byte = Asc( Left$(HeaderString , 1))
   HeaderString=Mid$( HeaderString , 2)

   For t = FilePos(Bitmap) To SizeBitmap
      ByteOld = ReadByte(Bitmap)
      
      ByteNew = (ByteOld And (-Bitmask-1)) + ( (Byte Shr ofs) And BitMask )

      SeekFile Bitmap2 , t
      WriteByte Bitmap2 , ByteNew
      
      ofs = (ofs + Bits)
      If ofs > 7 Then
         ofs = 0
         ByteOld = Byte
         If HeaderString<>""
            Byte = Asc( Left$(HeaderString , 1) )
            HeaderString=Mid$( HeaderString , 2)
         Else
            cnt = cnt + 1 : If cnt > (SizeSecret+1) Exit         
            Byte = ReadByte(Secret)
         EndIf
         c = c + 1 : If c = 5000 Then c = 0 AppTitle "write secret " + ((cnt * 100) / SizeSecret) + "%"
      EndIf
   Next
   CloseFile Bitmap
   CloseFile Secret
   Print SecretFile + " written to " + BitmapFile
End Function

Function ReadSecretBMP(BitmapFile$)
   Bitmap = ReadFile(BitmapFile$) : If Bitmap = 0 RuntimeError BitmapFile + " not found !"
   Local HeadInfo$[4]

   SeekFile Bitmap , 10 : SeekFile Bitmap , ReadInt (Bitmap)
   ReadHeader=True
   SizeBitmap=FileSize(BitmapFile)
   BitMask= (1 Shl Bits)-1   

   For t = FilePos(Bitmap) To SizeBitmap
      Byte1 = ReadByte(Bitmap)
      Byte=Byte Or ((Byte1 And BitMask) Shl ofs)
      ofs = (ofs + Bits)
      If ofs > 7 Then
         ofs = 0
         If ReadHeader = True
            If HeadOfs <   3 HeadInfo[0] = HeadInfo[0] + Chr(Byte) Else If HeadInfo[0] <> "SEC" Then RuntimeError "no data in " + BitmapFile
            If HeadOfs >=  3 And HeadOfs < 13 HeadInfo[1] = HeadInfo[1] + Chr(Byte)               
            If HeadOfs >= 13 And HeadOfs < 17 HeadInfo[2] = HeadInfo[2] + Chr(Byte)            
            If HeadOfs >= 17 And HeadOfs < (18 + Int(HeadInfo[2]))   HeadInfo[3] = HeadInfo[3] + Chr(Byte)            
            If HeadOfs >= (18 + Int(HeadInfo[2]))
               Secret = WriteFile("extracted." + HeadInfo[3]): If Secret = 0 RuntimeError "can't save " + HeadInfo[3]
               SizeSecret = Int(HeadInfo[1])
               ReadHeader = False
            End If
            HeadOfs = HeadOfs + 1
         Else
            cnt = cnt + 1 : If cnt > SizeSecret Then Exit         
            WriteByte Secret , Byte
         EndIf   
         Byte = 0
         c = c + 1 : If c = 100 Then c = 0 AppTitle "Read secret " + ((cnt * 100) / SizeSecret) + "%"
      EndIf
   Next
   CloseFile Bitmap
   CloseFile Secret
   Print HeadInfo[3] + " extracted from " + BitmapFile   
End Function

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group