#include <Gdiplus.au3>
#include <WindowsConstants.au3>


_GDIPlus_Startup()
Local $bild,$img,$w,$h,$lock,$ptr,$str,$size

Local $was=MsgBox(4,"Steganografie","Wenn du Steganografieren willst, drücke auf ja, zum Desteganografieren auf nein!")

$bild=FileOpenDialog("Bild auswählen","","PNG(*.png)")
If $bild="" Then
	MsgBox(0,"Fertig","Abbgebrochen!")
	_GDIPlus_Shutdown()
	Exit
EndIf

$img=_GDIPlus_BitmapCreateFromFile($bild)
$w=_GDIPlus_ImageGetWidth($img)
$h=_GDIPlus_ImageGetHeight($img)
$lock=_GDIPlus_BitmapLockBits($img,0,0,$w,$h,BitOR($GDIP_ILMREAD,$GDIP_ILMWRITE),$GDIP_PXF32ARGB)
$ptr=DllStructGetData($lock,"Scan0")

Switch $was
	Case 6 ;Stegano
		Local $datei=FileOpenDialog("Datei zum reinschreiben auswählen","","Alle(*.*)")
		If $datei="" Then
			MsgBox(0,"Fertig","Abbgebrochen!")
			_GDIPlus_BitmapUnlockBits($img,$lock)
			_GDIPlus_BitmapDispose($img)
			_GDIPlus_Shutdown()
			Exit
		EndIf
		$size=FileGetSize($datei)
		$datei=FileOpen($datei,16)
		$str=FileRead($datei)
		FileClose($datei)
		If $w*$h*2<$size+2 Then
			MsgBox(0,"Fehler","Das Bild ist zu klein! Es werden "&($size+2)/2&" Pixel benötigt!")
			MsgBox(0,"Fertig","Abbgebrochen!")
			_GDIPlus_BitmapUnlockBits($img,$lock)
			_GDIPlus_BitmapDispose($img)
			_GDIPlus_Shutdown()
			Exit
		EndIf
		_Stegano($ptr,$str,$size)
		_GDIPlus_BitmapUnlockBits($img,$lock)
		$datei=FileSaveDialog("Bild speichern","","PNG(*.png)")
		If StringRight($datei,4)<>".png" Then $datei&=".png"
		_GDIPlus_ImageSaveToFile($img,$datei)
		_GDIPlus_BitmapDispose($img)
	Case 7 ;Destegano
		$str=_Destegano($ptr)
		_GDIPlus_BitmapUnlockBits($img,$lock)
		$datei=FileSaveDialog("Datei aus dem Bild speichern","","Alle(*.*)")
		If $datei="" Then
			MsgBox(0,"Fertig","Abbgebrochen!")
			_GDIPlus_BitmapDispose($img)
			_GDIPlus_Shutdown()
			Exit
		EndIf
		$datei=FileOpen($datei,18)
		FileWrite($datei,$str)
		FileClose($datei)
		_GDIPlus_BitmapDispose($img)
EndSwitch

MsgBox(0,"Fertig","Erfolgreich beendet!")
_GDIPlus_Shutdown()
Exit




;_Stegano: Parameter(Ptr auf Bitmapdaten (Bmp32/LockBits),Datenstruktur: Text/Binary,Größe der Daten; bei Text zählt das Nullbyte dazu)
;Return=True/False
Func _Stegano($ptr,$data,$size)
	If $ptr=0 Then Return False
	Local $struct=DllStructCreate("dword;byte["&$size&"]")
	DllStructSetData($struct,1,$size)
	DllStructSetData($struct,2,$data)
	Local $bin="0x568B7C24088B74240C9BDBE3ADBB0000FFFF21C3C1EB10FF342483042449BAF0F0F0F0211766B9F0F06621D966C1E9040FB6D5C1E21088CA66B90F0F6621D988EEC1E20888CA0917C383C7046689C38B042483C01EFFD083C70458F30F6FB8F4000000F30F6FB004010000F30F6FA814010000F30F6FA024010000F30F6F98340100008B4EFCBB0700000021CBC1E90309C9743AF20F1206660FDBC7F30F6F0F660FDBCEF30F6FD0660F73D204660FDBD4660FDBC3660FEBC2660F3800C5660FEBC1F30F7F0783C71083C608E2C689D909C9741FACB3F020C3B20F20D0C0EB0466BAF0F066231708DE08C266891783C702E2E1C3F0F0F0F0F0F0F0F00F0F0F0F0F0F0F0FF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0040C050D060E070F00080109020A030BFFFFFFFFFFFFFFFF00000000000000000000000000000000FFFFFFFFFFFFFFFF"
	_FasmCallBinary($bin,"none","ptr",$ptr,"ptr",DllStructGetPtr($struct))
	Return True
EndFunc


;_Destegano: Parameter(Ptr auf Bitmapdaten (Bmp32)
;Return=Binary-Daten/""
Func _Destegano($ptr)
	If $ptr=0 Then Return ""
	Local $daten=DllStructCreate("byte[8]",$ptr)
	Local $size="",$x
	For $x=4 To 1 Step -1
		$size&=Hex(BitAND(DllStructGetData($daten,1,$x),0x0F),1)
	Next
	For $x=8 To 5 Step -1
		$size&=Hex(BitAND(DllStructGetData($daten,1,$x),0x0F),1)
	Next
	$size=Dec($size)
	Local $struct=DllStructCreate("dword;byte["&$size&"]")
	DllStructSetData($struct,1,$size)
	Local $bin="0x89F08B7424048B7C24089BDBE383C6088B0F83C704BB0700000021CBC1E90309C97438F30F6F7873F30F6FB083000000F30F6F06660FDBC7660F3800C6F30F6FC8660F73D908660F73F104660FEBC1660FD60783C61083C708E2D589D909C9741166AD66BB0F0F6621D8C0E40408E0AAE2EFC30F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F090B0D0F01030507080A0C0E00020406"
	_FasmCallBinary($bin,"none","ptr",$ptr,"ptr",DllStructGetPtr($struct))
	Return DllStructGetData($struct,2)
EndFunc


Func _FasmCallBinary($vBytecode, $rettype = "none", $_type1 = "int", $_param1 = 0, $_type2 = "int", $_param2 = 0, $_type3 = "int", $_param3 = 0, $_type4 = "int", $_param4 = 0)
    ; Binärcode aufrufen
    Local $tCodebuffer = $vBytecode
    If Not IsDllStruct($vBytecode) Then
        $tCodebuffer = DllStructCreate("byte[" & StringLen($vBytecode) / 2 - 1 & "]")
        DllStructSetData($tCodebuffer, 1, $vBytecode)
    EndIf
    Local $aRet = DllCall("user32.dll", $rettype, "CallWindowProcW", "ptr", DllStructGetPtr($tCodebuffer), $_type1, $_param1, $_type2, $_param2, $_type3, $_param3, $_type4, $_param4)
    If IsArray($aRet) Then Return $aRet[0]
    Return 0
EndFunc   ;==>_FasmCallBinary





















;~ Func F()
;~ 	FasmAdd($Fasm, "use32") ;
;~ 	FasmAdd($Fasm, "push esi") ;
;~ 	FasmAdd($Fasm, "mov edi,[esp+8]") ;
;~ 	FasmAdd($Fasm, "mov esi,[esp+12]") ;
;~ 	FasmAdd($Fasm, "finit") ;

;~ 	FasmAdd($Fasm, "lodsd") ;
;~ 	FasmAdd($Fasm, "mov ebx,0xFFFF0000") ;
;~ 	FasmAdd($Fasm, "and ebx,eax") ;
;~ 	FasmAdd($Fasm, "shr ebx,16") ;

;~ 	FasmAdd($Fasm, "push dword[esp]") ;
;~ 	FasmAdd($Fasm, "add dword[esp],weiter") ;

;~ 	FasmAdd($Fasm, "func:") ;
;~ 	FasmAdd($Fasm, "mov edx,0xF0F0F0F0") ;
;~ 	FasmAdd($Fasm, "and dword[edi],edx") ;
;~ 	FasmAdd($Fasm, "mov cx,0xF0F0") ;
;~ 	FasmAdd($Fasm, "and cx,bx") ;
;~ 	FasmAdd($Fasm, "shr cx,4") ;
;~ 	FasmAdd($Fasm, "movzx edx,ch") ;
;~ 	FasmAdd($Fasm, "shl edx,16") ;
;~ 	FasmAdd($Fasm, "mov dl,cl") ;
;~ 	FasmAdd($Fasm, "mov cx,0x0F0F") ;
;~ 	FasmAdd($Fasm, "and cx,bx") ;
;~ 	FasmAdd($Fasm, "mov dh,ch") ;
;~ 	FasmAdd($Fasm, "shl edx,8") ;
;~ 	FasmAdd($Fasm, "mov dl,cl") ;
;~ 	FasmAdd($Fasm, "or dword[edi],edx") ;
;~ 	FasmAdd($Fasm, "ret") ;

;~ 	FasmAdd($Fasm, "weiter:") ;
;~ 	FasmAdd($Fasm, "add edi,4") ;
;~ 	FasmAdd($Fasm, "mov bx,ax") ;
;~ 	FasmAdd($Fasm, "mov eax,[esp]") ;
;~ 	FasmAdd($Fasm, "add eax,func") ;
;~ 	FasmAdd($Fasm, "call eax") ;
;~ 	FasmAdd($Fasm, "add edi,4") ;


;~ 	FasmAdd($Fasm, "pop eax") ;
;~ 	FasmAdd($Fasm, "movdqu xmm7,dqword[eax+datentrenner]") ;
;~ 	FasmAdd($Fasm, "movdqu xmm6,dqword[eax+datenloescher]") ;
;~ 	FasmAdd($Fasm, "movdqu xmm5,dqword[eax+datenshufindex]") ;
;~ 	FasmAdd($Fasm, "movdqu xmm4,dqword[eax+datenfree]") ;
;~ 	FasmAdd($Fasm, "movdqu xmm3,dqword[eax+datenfree2]") ;
;~ 	FasmAdd($Fasm, "mov ecx,[esi-4]") ;
;~ 	FasmAdd($Fasm, "mov ebx,0x07") ;
;~ 	FasmAdd($Fasm, "and ebx,ecx") ;
;~ 	FasmAdd($Fasm, "shr ecx,3") ;
;~ 	FasmAdd($Fasm, "or ecx,ecx") ;
;~ 	FasmAdd($Fasm, "jz afschleife") ;
;~ 	FasmAdd($Fasm, "schleife:") ;
;~ 	FasmAdd($Fasm, "movddup xmm0,qword[esi]") ;
;~ 	FasmAdd($Fasm, "pand xmm0,xmm7") ;
;~ 	FasmAdd($Fasm, "movdqu xmm1,dqword[edi]") ;
;~ 	FasmAdd($Fasm, "pand xmm1,xmm6") ;
;~ 	FasmAdd($Fasm, "movdqu xmm2,xmm0")
;~ 	FasmAdd($Fasm, "psrlq xmm2,4")
;~ 	FasmAdd($Fasm, "pand xmm2,xmm4")
;~ 	FasmAdd($Fasm, "pand xmm0,xmm3")
;~ 	FasmAdd($Fasm, "por xmm0,xmm2")
;~ 	FasmAdd($Fasm, "pshufb xmm0,xmm5") ;
;~ 	FasmAdd($Fasm, "por xmm0,xmm1") ;
;~ 	FasmAdd($Fasm, "movdqu dqword[edi],xmm0") ;
;~ 	FasmAdd($Fasm, "add edi,16") ;
;~ 	FasmAdd($Fasm, "add esi,8") ;
;~ 	FasmAdd($Fasm, "loop schleife") ;
;~ 	FasmAdd($Fasm, "afschleife:") ;
;~ 	FasmAdd($Fasm, "mov ecx,ebx") ;
;~ 	FasmAdd($Fasm, "or ecx,ecx") ;
;~ 	FasmAdd($Fasm, "jz afschleife2") ;
;~ 	FasmAdd($Fasm, "zweiteschleife:") ;
;~ 	FasmAdd($Fasm, "lodsb") ;
;~ 	FasmAdd($Fasm, "mov bl,0xF0") ;
;~ 	FasmAdd($Fasm, "and bl,al") ;
;~ 	FasmAdd($Fasm, "mov dl,0x0F") ;
;~ 	FasmAdd($Fasm, "and al,dl") ;
;~ 	FasmAdd($Fasm, "shr bl,4") ;
;~ 	FasmAdd($Fasm, "mov dx,0xF0F0") ;
;~ 	FasmAdd($Fasm, "and dx,[edi]") ;
;~ 	FasmAdd($Fasm, "or dh,bl") ;
;~ 	FasmAdd($Fasm, "or dl,al") ;
;~ 	FasmAdd($Fasm, "mov word[edi],dx") ;
;~ 	FasmAdd($Fasm, "add edi,2") ;
;~ 	FasmAdd($Fasm, "loop zweiteschleife") ;
;~ 	FasmAdd($Fasm, "afschleife2:") ;
;~ 	FasmAdd($Fasm, "ret") ;


;~ 	FasmAdd($Fasm, "datentrenner:") ;
;~ 	FasmAdd($Fasm, "dd 2 dup 0xF0F0F0F0") ;
;~ 	FasmAdd($Fasm, "dd 2 dup 0x0F0F0F0F") ;
;~ 	FasmAdd($Fasm, "datenloescher db 16 dup 0xF0") ;
;~ 	FasmAdd($Fasm, "datenshufindex dq 0x0F070E060D050C04,0x0B030A0209010800") ;
;~ 	FasmAdd($Fasm, "datenfree dq 0xFFFFFFFFFFFFFFFF,0x0000000000000000")
;~ 	FasmAdd($Fasm, "datenfree2 dq 0x0000000000000000,0xFFFFFFFFFFFFFFFF")
;~ EndFunc





;~ Func F2()
;~ 	FasmAdd($Fasm, "use32") ;
;~ 	FasmAdd($Fasm, "mov eax,esi") ;
;~ 	FasmAdd($Fasm, "mov esi,[esp+4]") ;
;~ 	FasmAdd($Fasm, "mov edi,[esp+8]") ;

;~ 	FasmAdd($Fasm, "finit") ;
;~ 	FasmAdd($Fasm, "add esi,8") ;

;~ 	FasmAdd($Fasm, "mov ecx,[edi]") ;
;~ 	FasmAdd($Fasm, "add edi,4") ;

;~ 	FasmAdd($Fasm, "mov ebx,0x07") ;
;~ 	FasmAdd($Fasm, "and ebx,ecx") ;
;~ 	FasmAdd($Fasm, "shr ecx,3") ;
;~ 	FasmAdd($Fasm, "or ecx,ecx") ;
;~ 	FasmAdd($Fasm, "jz afschleife") ;
;~ 	FasmAdd($Fasm, "movdqu xmm7,dqword[eax+datenand]") ;
;~ 	FasmAdd($Fasm, "movdqu xmm6,dqword[eax+datenshuf]") ;
;~ 	FasmAdd($Fasm, "schleife1:") ;
;~ 	FasmAdd($Fasm, "movdqu xmm0,dqword[esi]") ;
;~ 	FasmAdd($Fasm, "pand xmm0,xmm7") ;
;~ 	FasmAdd($Fasm, "pshufb xmm0,xmm6") ;
;~ 	FasmAdd($Fasm, "movdqu xmm1,xmm0") ;
;~ 	FasmAdd($Fasm, "psrldq xmm1,8") ;
;~ 	FasmAdd($Fasm, "psllq xmm1,4") ;
;~ 	FasmAdd($Fasm, "por xmm0,xmm1") ;
;~ 	FasmAdd($Fasm, "movq qword[edi],xmm0") ;
;~ 	FasmAdd($Fasm, "add esi,16") ;
;~ 	FasmAdd($Fasm, "add edi,8") ;
;~ 	FasmAdd($Fasm, "loop schleife1") ;
;~ 	FasmAdd($Fasm, "afschleife:") ;

;~ 	FasmAdd($Fasm, "mov ecx,ebx") ;
;~ 	FasmAdd($Fasm, "or ecx,ecx") ;
;~ 	FasmAdd($Fasm, "jz afschleife2") ;
;~ 	FasmAdd($Fasm, "schleife2:") ;
;~ 	FasmAdd($Fasm, "lodsw") ;
;~ 	FasmAdd($Fasm, "mov bx,0x0F0F") ;
;~ 	FasmAdd($Fasm, "and ax,bx") ;
;~ 	FasmAdd($Fasm, "shl ah,4") ;
;~ 	FasmAdd($Fasm, "or al,ah") ;
;~ 	FasmAdd($Fasm, "stosb") ;
;~ 	FasmAdd($Fasm, "loop schleife2") ;
;~ 	FasmAdd($Fasm, "afschleife2:") ;
;~ 	FasmAdd($Fasm, "ret") ;



;~ 	FasmAdd($Fasm, "datenand db 16 dup 0x0F") ;
;~ 	FasmAdd($Fasm, "datenshuf dq 0x070503010F0D0B09,0x060402000E0C0A08") ;
;~ EndFunc

