Option Explicit DefLng A-Z '--------------------------------------------------------------------------------------------- #Const Test = False '--------------------------------------------------------------------------------------------- Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wmsg As Long, ByVal wparam As Long, lparam As Any) As Long Private Const EM_GETFIRSTVISIBLELINE As Long = &HCE Private Const EM_LINESCROLL As Long = &HB6 Private Declare Sub GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hobject As Long, ByVal ncount As Long, lpobject As Any) Private Type BITMAP bmtype As Long bmwidth As Long bmheight As Long bmwidthbytes As Long bmplanes As Integer bmbitspixel As Integer bmbits As Long End Type Private PicOrigProps As BITMAP Private PicStegoProps As BITMAP Private Picbyte As Byte Private AndMask As Byte Private OrMask As Byte Private i, j, k Private Pointer Private Increment Private Ascii Private BytCount As Long Private ModCount As Long Private PicByteCompare As Byte # '------------------------------------------------------------------------------------- Private CanQuit As Boolean Private SecretText As String Private DroppedFilename As String Private Const EdiMask As String = "(00000)" Private Const VertBar As String = " " Private Const FtBmp As String = "Bitmap Pictures (*.bmp)" & VertBar & "*.bmp" Private Const FtJpg As String = "JPEG Pictures (*.jpg, *.jpeg)" & VertBar & "*.jp*" Private Const FtRtf As String = "RTF Text files (*.rtf)" & VertBar & "*.rtf" Private Const FtTxt As String = "Text files (*.txt)" & VertBar & "*.txt" Private Const FtAll As String = "All files (*.*)" & VertBar & "*.*" Private Const NoSave As String = "You haven't saved the picture yet. " & vbcrlf & vbcrlf Private Declare Sub InitCommonControls Lib "comctl32" () Private Sub bthide_click() Dim TopLine As Long PicStego = PicOrig GetObject PicStego, Len(PicStegoProps), PicStegoProps With PicStegoProps If opbpb Then Increment = 1 BtHide.Enabled = False
Else 'OPBPB = FALSE/0 Increment =.bmbitspixel / 8 If.bmBitsPixel = 8 Then OrMask = 64 'this seems quite good, but anyway... MsgBox "Citra digital Penampung pesan adalah citra dengan format di luar yang ditentukan. Citra yang dihasilkan akan memiliki tampilan yang berbeda dengan aslinya dan mungkin hasilnya akan kurang memuaskan.", vbinformation Else 'NOT.BMBITSPIXEL... OrMask = 1 'use the lsb for minimum color shift AndMask = &HFF And Not OrMask If TextFits(Len(EdiMask & Format$(Len(rtfText), EdiMask) & rtftext), PicStegoProps) Then SecretText = Encrypt(EdiMask & Format$(Len(rtfText), EdiMask), txpw) & Encrypt(rtfText, txpw) Enabled = False Screen.MousePointer = vbhourglass 'save textbox top line TopLine = SendMessage(rtfText.hWnd, EM_GETFIRSTVISIBLELINE, 0, ByVal 0) 'save text box posn 'initialize pointer Pointer =.bmbits BytCount = 0 ModCount = 0 # '------------------------------------------------------------------------------------- 'hide text For i = 1 To Len(SecretText) 'scroll text for a visual feedback rtftext.selstart = i - 1 For j = 0 To 7 'get a byte from pic CopyMemory Picbyte, ByVal Pointer, 1 PicByteCompare = Picbyte # '------------------------------------------------------------------------------------- 'set/reset/leave bit Picbyte = (Picbyte And AndMask) Or IIf(Asc(Mid$(SecretText, i, 1)) And 2 ^ j, OrMask, 0) BytCount = BytCount + 1 ModCount = ModCount - (Picbyte <> PicByteCompare) # '------------------------------------------------------------------------------------- 'restore byte in pic CopyMemory ByVal Pointer, Picbyte, 1 'inrement pointer Pointer = Pointer + Increment Next j, i 'done - restore text box top line position SendMessage rtftext.hwnd, EM_LINESCROLL, 0, ByVal TopLine - SendMessage(rtfText.hWnd, EM_GETFIRSTVISIBLELINE, 0, ByVal 0) Screen.MousePointer = vbdefault MsgBox ModCount & " bytes of " & BytCount & " modified, total picsize is " &.bmheight *.bmwidth *.bmbitspixel / 8 & " Bytes" # '------------------------------------------------------------------------------------- btsave.enabled = True
Enabled = True PicStego.Refresh CanQuit = False Else 'NOT TEXTFITS(LEN(EDIMASK... btsave.enabled = False PicStego = LoadPicture(vbNullString) CanQuit = True End With 'PICSTEGOPROPS Private Sub btload_click() Const Cet As String = "Can't extract text." If CanQuit = False Then i = (MsgBox(NoSave & "Load a new picture anyway?", vbquestion Or vbyesno) = vbyes) Else 'NOT CANQUIT... i = True If i Then 'can load a new picture With cdlg If Len(DroppedFilename) Then 'file dropped.filename = DroppedFilename DroppedFilename = vbnullstring i = 0 Else 'LEN(Droppedfilename) = FALSE/0.Filename = vbnullstring.flags = cdlofnlongnames.filter = FtBmp & VertBar & FtJpg & VertBar & FtAll.FilterIndex = 1.ShowOpen i = Err If i = 0 Then btsave.enabled = False PicStego = LoadPicture(vbNullString) CanQuit = True PicOrig = LoadPicture(.Filename) i = Err If i Then MsgBox.Filename & vbcrlf & "is not a valid picture file.", vbcritical Else 'I = FALSE/0 GetObject PicOrig, Len(PicOrigProps), PicOrigProps rtftext = vbnullstring If PicOrigProps.bmBitsPixel < 8 Then BtHide.Enabled = False MsgBox "The Picture must have at least 8 Bits per Pixel.", vbcritical Else 'NOT PICORIGPROPS.BMBITSPIXEL... Enabled = False With PicOrigProps
BtHide.Enabled = True SecretText = vbnullstring If.bmBitsPixel = 8 Then OrMask = 64 Else 'NOT.BMBITSPIXEL... OrMask = 1 AndMask = &HFF And Not OrMask If opbpb Then Increment = 1 Else 'OPBPB = FALSE/0 Increment =.bmbitspixel / 8 Pointer =.bmbits For i = 1 To Len(EdiMask) * 2 'get marker and length Ascii = 0 For j = 0 To 7 CopyMemory Picbyte, ByVal Pointer, 1 If Picbyte And OrMask Then Ascii = Ascii Or 2 ^ j Pointer = Pointer + Increment Next j SecretText = SecretText & Chr$(Ascii) Next i SecretText = Decrypt(SecretText, txpw) If Left$(SecretText, Len(EdiMask)) = EdiMask Then 'found Marker - try to extract text SecretText = Mid$(SecretText, Len(EdiMask) + 2, Len(EdiMask) - 2) 'this should be the length If IsNumeric(SecretText) Then Screen.MousePointer = vbhourglass k = Val(SecretText) SecretText = vbnullstring For i = 1 To k Ascii = 0 For j = 0 To 7 CopyMemory Picbyte, ByVal Pointer, 1 If Picbyte And OrMask Then Ascii = Ascii Or 2 ^ j Pointer = Pointer + Increment Next j SecretText = SecretText & Chr$(Ascii) Next i rtftext = Decrypt(SecretText, txpw) rtftext.selstart = 0 Display "Text extracted.", vbblack, False Screen.MousePointer = vbdefault Else 'ISNUMERIC(SECRETTEXT) = FALSE/0 Display Cet, vbred, True Else 'NOT LEFT$(SECRETTEXT,... Display Cet, vbred, True End With 'PICORIGPROPS BtHide.Enabled = True Enabled = True
End With 'CDLG Private Sub btloadtext_click() With cdlg.filename = ModifyFilename(.Filename, "").Flags = cdlofnlongnames.filter = FtRtf & VertBar & FtTxt & VertBar & FtAll.FilterIndex = 1.ShowOpen i = Err If i = 0 Then rtftext = "" i = FreeFile Open.Filename For Input As i If.FilterIndex = 1 Then rtftext = Input(LOF(i) - 1, i) Else 'NOT.FILTERINDEX... rtftext.text = Input(LOF(i) - 1, i) Close i Display "Text loaded.", vbblack, False End With 'CDLG Private Sub btsave_click() With cdlg.filename = ModifyFilename(.Filename, "bmp").flags = cdlofnlongnames Or cdlofnoverwriteprompt.filter = FtBmp.FilterIndex = 1.ShowSave If Err = 0 Then SavePicture PicStego,.Filename CanQuit = True End With 'CDLG rtftext.text = " " txpw.text = " " BtHide.Enabled = False btload.enabled = False btsave.enabled = False Private Sub btsavetext_click() With cdlg.filename = ModifyFilename(.Filename, "").Flags = cdlofnlongnames Or cdlofnoverwriteprompt
.Filter = FtRtf & VertBar & FtTxt.FilterIndex = 1.ShowSave i = Err If i = 0 Then i = FreeFile ModifyFilename.Filename, IIf(.FilterIndex = 1, "rtf", "txt") Open.Filename For Output As i Print #i, IIf(.FilterIndex = 1, rtftext, rtftext.text) Close i End With 'CDLG Private Function CRC4(Text As String, Key As String) As String 'Found at PSC and modified to include keylength 'The version found at PSC would accept abc and abcabc for example as identical keys :-(( Dim X(0 To 255), Y(0 To 256) For i = 0 To 255 X(i) = i Next i i = 0 j = Len(Key) + 1 Do If j > Len(Key) Then j = 1 Y(i) = Len(Key) i = i + 1 Y(i) = Asc(Mid$(Key, j, 1)) j = j + 1 i = i + 1 Loop Until i > 255 j = 0 For i = 0 To 255 j = (j + X(i) + Y(i)) Mod 256 GoSub Swap Next i i = 0 j = 0 For k = 1 To Len(Text) i = (i + 1) Mod 256 j = (j + X(i)) Mod 256 GoSub Swap CRC4 = CRC4 & Chr$(Asc(Mid$(Text, k, 1)) Xor X((X(i) + (X(j) Mod 256)) Mod 256)) Next k Exit Function Swap: X(i) = X(i) Xor X(j) X(j) = X(j) Xor X(i) X(i) = X(i) Xor X(j) Return Private Function Decrypt(Text As String, Key As String) As String Decrypt = CRC4(Text, Key)
Private Sub Display(Text As String, Color As Long, Bold As Boolean) lbused.fontbold = Bold lbused.forecolor = Color lbused = Text Private Function Encrypt(Text As String, Key As String) As String Encrypt = CRC4(Text, Key) Private Sub Command1_Click() End Private Sub Form_Initialize() InitCommonControls Private Sub Form_Load() CanQuit = True DroppedFilename = Command$ If Len(DroppedFilename) Then DroppedFilename = Mid$(DroppedFilename, 2, Len(DroppedFilename) - 2) 'remove quotes at either end If InStr(DroppedFilename, """") = 0 Then If Len(Dir$(DroppedFilename)) Then 'user dropped a file onto the.exe icon btload_click Else 'NOT INSTR(DROPPEDFILENAME,... MsgBox "Please drop only one file.", vbcritical DroppedFilename = vbnullstring Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) If CanQuit = False Then Cancel = (MsgBox(NoSave & "Quit anyway?", vbquestion Or vbyesno) = vbno) Private Function ModifyFilename(Filename As String, Filetype As String) As String 'Remove existing filetype if any and append new filetype if any i = InStrRev(Filename, ".") If i Then Filename = Left$(Filename, i - 1) ModifyFilename = Filename & IIf(Len(Filetype), "." & Filetype, vbnullstring) Private Sub opbpb_mouseup(button As Integer, Shift As Integer, X As Single, Y As Single) BtHide.Enabled = False Private Sub opbpp_mouseup(button As Integer, Shift As Integer, X As Single, Y As Single) Private Function TextFits(NumChars As Long, Props As BITMAP) As Boolean Dim Percent As Single With Props Percent = 6400 * NumChars * Increment /.bmheight /.bmwidth /.bmbitspixel + 0.05 End With 'PROPS If NumChars < 100000 And Percent <= 99.9 Then Display Format$(Percent, "0.0") & "% of available space used.", vbblack, False
TextFits = True Else 'NOT NUMCHARS... Display "Text too long / Picture too small.", vbred, True TextFits = False Private Sub txpw_change() btload.enabled = (Len(txPW) >= 2) Private Sub txpw_gotfocus() txpw_change Private Sub rtftext_change() lbtext = "Text " & Len(rtfText.Text) & " bytes + " & Len(rtfText) - Len(rtfText.Text) & " formatting" Private Sub rtftext_keydown(keycode As Integer, Shift As Integer) Display "Text modified.", vbblack, False ':) Ulli's VB Code Formatter V2.14.7 (27.08.2002 11:18:33) 88 + 440 = 528 Lines