1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Andy

Beiträge von Andy

  • Tutorial AutoIt und Assembler UPDATE 24. Oktober 2010 Verwendung von Autoitvariablen im Assemblercode

    • Andy
    • 11. August 2010 um 00:32
    Zitat

    Die Aufrufkonvention ist nicht mehr "stdcall" sondern "fastcall"

    na subba :thumbup: , im Prinzip ja eine schöne Sache. Auch daß die Floatingpoints direkt in die XMM-Register geschrieben werden, sehr fein. Da kann ich ja im nächsten Tutorialteil direkt mit dem alignen für die MMX-Register weitermachen^^. Lieber doch nicht...bestimmt wurden einige schon von dem REPNE SCASD-Monster im 2. Beispiel abgeschreckt....
    Morgen gibts den nächsten Teil, Variablen verwenden und bissl String-Management.
    Lasst mich nicht am ausgestreckten Arm verhungern, auf welchem Gebiet gibts Interesse?

  • UDF-Bibliothek

    • Andy
    • 10. August 2010 um 17:33
    Zitat

    Das Problem, das man einigen Benutzern was vorkauen muss besteht auch jetzt schon.
    Nur das man zusätzlich eventuell mit Fehlern zu kämpfen hat, die durch veraltete Versionen der UDFs entstehen.

    Sehr richtig, und genau deshalb solltest du mir mal die Frage beantworten:
    Wer soll die Zielgruppe sein, bzw. wer soll daraus den Nutzen ziehen?

    Beispiel Wikipedia oder jedes andere x-beliebige Wiki: Einige wenige reissen sich den Ar*** auf und klotzen richtig ran und stellen Informationen bereit, und die dröge Mehrheit ist nicht mal in der Lage, einen Suchbegriff fehlerfrei ins entsprechende Fensterchen zu tippen! Die meisten sind ja nicht mal in der Lage, in die Eingabezeile des Browsers ein g und dann den Suchbegriff einzugeben, bevor sie eine Frage stellen!

    Ist das etwa bei AutoIt anders? Würde nur eine einzige überflüssige Frage weniger in der SB gespammt, oder würde auch nur ein einziger überflüssiger Thread weniger erstellt werden, wenn es eine "perfekte" UDF-Bibliothek mit allen Schikanen gäbe?
    Ein Projekt in dieser Dimension kann (ähnlich wie die deutsche AutoIt-Hilfe) nur von jemandem mit extremer Motivation und unerschütterlichem Selbstkasteiungswillen betrieben werden. Wobei ich bei der dt. Hilfe noch den Nutzen für alle deutschen User sehe. Und genau das Verhältnis vom Nutzen zur reingesteckten Arbeit ist bei einer UDF-Bibliothek zweifelhaft.

    Zitat

    Für den Fall, dass es umgesetzt wird, muss außerdem entschieden werden unter welcher Lizenz die UDFs dann stehen.

    Wie soll das funktionieren? Wer sagt mir, von welcher Quelle der Lizenznehmer seine (meine) UDF geladen hat? Solange die UDF-Bibliothek nichts anderes ist als eine "Linkliste", kann man sich das Lizenzmodell getrost sparen. Das wäre nur dann sinnvoll, wenn exclusiv dort veröffentlicht würde.

  • UDF-Bibliothek

    • Andy
    • 10. August 2010 um 10:07
    Zitat

    Andy: Aber findest du nicht manchmal UDFs, wo du sagst "GEIL!!! Das brauch ich in meinem nächsten Script!

    Jein^^
    Diese Sahnestückchen habe ich dann aber auch kurz darauf auf meiner Platte, dort suche ich natürlich zuerst nach fertigen Lösungen.
    Allerdings benutze ich seltenst etwas "AS IS", will heissen, wenn ich etwas brauche, dann schaue ich zuerst, ob ich nicht ein ähnliches Werkzeug passend umbauen kann.
    Eine UDF ist für mich nur ein Pool, um Ideen von cleveren Programmierern zu erhalten. Da ich das ganze nur "hobbymäßig" betreibe, baue ich einfach bestehende Funktionen auf mein Problem um. Daher finden sich relativ selten "ursprüngliche" UDF´s in meinem Fundus! In fast allen habe ich etwas "herumgeschnitzt". Das halte ich aber auch nicht unbedingt für ein Problem, problematisch wird es erst dann, wenn die Namen dieser ursprünglichen UDF´s (bzw. die Funktionsnamen) beibehalten werden und Scripte weitergegeben werden, ohne diese "passenden" UDF´s beizulegen.

  • Nach Bild im Programmfenster (Webseite) suchen

    • Andy
    • 10. August 2010 um 09:41

    Also wenn es nur darum geht, such mal nach PushTheButton, dort hatte ich genau so etwas für meine Tochter gebastelt. Ging zwar nicht um ein Spiel, aber ein Bild (Button) automatisiert suchen und dort mit der Maus draufklicken war auch das Problem.
    Wenn ich mich nicht irre, wird nach Möglichkeit sogar gescrollt. Eine "neue" überarbeitete Version, welche die Prospeed.dll so gut wie überflüssig macht, ist in Arbeit. Wobei man sagen muss, daß die "langsame" AutoIt-Version ein Bild auf einem herkömmlichen Rechner mittlerweile im Millisekundenbereich findet.

  • Tutorial AutoIt und Assembler UPDATE 24. Oktober 2010 Verwendung von Autoitvariablen im Assemblercode

    • Andy
    • 10. August 2010 um 09:31

    @Mod´s,
    leider habe ich "verpennt", unter den obersten 3 Beiträgen noch einige von mir erstellte leere Postings als Platzhalter für weitere Beiträge zu reservieren. Das Tut steht ja erst am Anfang^^
    Ist es euch möglich, dort nachträglich Beitrage einzufügen?

  • UDF-Bibliothek

    • Andy
    • 10. August 2010 um 09:23

    Im Großen und Ganzen gebe ich dir Recht. Eine zentrale Anlaufstelle für UDF´s, unterteilt in Themengebiete, hätte was.
    Allerdings stellt sich mir, wie auch schon bei einigen anderen Projekten, die Frage nach der Zielgruppe!
    Derjenige, der in der Lage ist, mit einigen Stichworten sein Problem zu beschreiben, findet seine gesuchte UDF bereits jetzt in wenigen Sekunden. Wenn es eine "Spezialität" sein sollte, erst recht!
    Und für diese "Bibliothek" würde dasselbe gelten wie für alle anderen Hilfsmittel: Wer es am nötigsten bräuchte, nutzt es am wenigsten! Die meisten sind ja nicht einmal in der Lage, aus der exzellenten AutoIt-Hilfe Informationen zu bekommen, man muss ihnen die dort x-mal gezeigte und erklärte Anwendung eines Befehls für ihr eigenes Problem "umschreiben".
    Wie wird das dann bei einem UDF-Verzeichnis? Erst soll ein Programmierer die UDF "normgerecht" mit Kopf und Syntax erstellen und dann auch noch Beispiele schreiben, nur damit jemand, der zu faul (das andere passende Wort sage ich jetzt nicht) zum Suchen ist, eine Möglichkeit hat, sich NOCH einfacher mit der Arbeit anderer Leute zu schmücken?

  • Tutorial AutoIt und Assembler UPDATE 24. Oktober 2010 Verwendung von Autoitvariablen im Assemblercode

    • Andy
    • 9. August 2010 um 23:17

    Hi,
    dieses Tut ist heute bei einigen Kannen Kaffee aus meinen Fingern geflossen, aber ich habe noch einige weitere Ideen^^
    Einige Beispiele sind auch in Vorbereitung, wenn ihr Ideen habt, wäre ich für einen kleinen Stupser in eine bestimmte Richtung dankbar. Es ist immer schwer, sich etwas aus den Fingern zu saugen :D

    Zitat von AspirinJunkie

    und hoffe das dies meiner Optimierungsgier weitere Nahrung darbietet.

    Der Unterschied zwischen Assembler und Assembler fällt einem dann auf, wenn man sieht, was Spezialisten aus der Hardware herauskitzeln können. Ich habe einige PDF´s von AMD, die sich ausschliesslich mit der Optimierung befassen, da fragt man sich dann, ob die noch alle auf der Reihe haben, wenn bei einer 3Gigahertz-Maschine einzelne Takte eingespart werden.^^ Andererseits ist es irre, mit welch einfachen Mitteln man z.B. den Prozessorcache einsetzen kann und somit Programme um mehrere Faktoren beschleunigt.

    Zitat von Prog@ndy

    Wie ist das eigentlich mit CallWindowProc auf x64 (Falls man x64-Bytecode hat, ohne FASM)? Kann man da auch 4byte-int-Parameter statt dem 8byte Fenster-Handle und so verwenden? oder muss man dann den restlichen Platz "auffüllen", indem man weitere Paremeter einbaut?

    Gute Frage, in Ermangelung eines 64-Bit-Systems bin ich mir nicht so ganz sicher. Definitiv steht fest, daß bei 64Bit ausschliesslich 64Bit-Parameter übergeben werden. Das habe ich schon in einigen Beispielen gesehen. Das heisst, auch wenn du nur ein 8 Bit breites Byte als Parameter bräuchtest, musst du einen 64 Bit-Parameter verwenden, Handles und der gesamte andere Dreck, alles 64 Bit breit! Hat auch was Gutes, es gibt nur noch ein Datenformat^^
    Da im 64-bit-Modus der Prozessor auch ausschliesslich mit 64- bzw 128 Bit-Registern arbeitet, hat sich der "normale" 8088/8086 Assembler verabschiedet. Mein schöner Traum, 64-Bit sei eine "Erweiterung" wie bisher 8088 (8-Bit) -> 80286 (16 Bit) -> 80386 (32 Bit) -> 80486 .....64-Bitprozessor ist ausgeträumt. Im 64-Bit-Modus gibt es scheinbar keinen simultanen "80x86"-Kompatibilitätsmodus. Will z.B. heissen, das EAX-Register (32 Bit) besteht aus AH+AL, welches zu AX zusammengefasst ist, und 16 weitern Bits. Ich hatte mich schon darauf gefreut, einfach zu den 32 Bits dieses Registers 32 weitere zu bekommen und dieses sei dann das RAX-Register....aber Pustekuchen! RAX ist 64 Bit breit, und nicht weiter "unterteilt". :thumbdown:

    Alles andere als 64 Bit wird wohl in speziellen Umgebungen laufen müssen, DOS-Box lässt grüssen. Jag mal eine beliebige 64-bit-Datei durch einen Disassembler, also ich verstehe da nur noch Bahnhof^^

    /EDIT/ Eine Idee hätte ich noch:
    Mach doch mal einen CallWindowProc-Call ohne spezielle Parameter, also nur "INT64",dllstructgetptr($struct_mit_Bytecode), "INT64",0, "INT64",0, "INT64",0, "INT64",0)
    Dann schreib als Bytecode nur "0xC3" (das ist ein einfaches RET). Wenn dieser Call fehlerfrei ausgeführt wird, dann stimmt wenigstens das Format der Parameter. Dann muss man sich "nur noch" überlegen, wie man die Register mit den Parametern füllt. Leider weiss ich nicht, welches Register für die Rückgabe verantwortlich ist, aber da ist auf jeden Fall reichlich Platz zum Rumspielen :thumbup:

  • Tutorial AutoIt und Assembler UPDATE 24. Oktober 2010 Verwendung von Autoitvariablen im Assemblercode

    • Andy
    • 9. August 2010 um 21:43

    Beispiel_2: Pixelsuchen32, findet ein Pixel innerhalb einer Bitmap
    AutoIt-Funktion Pixelsuchen32($Pointer_auf_die_Bitmapdaten,$FarbePixel,$Größe_der_Bitmap,$Breite_der_Bitmap)

    Wir werden nun das allseits beliebte und bekannte Suchen nach 4 aufeinanderfolgenden Bytes im Hauptspeicher durchführen.
    Dazu wird eine 32Bit-Bitmap erstellt, und mit beliebigem Inhalt gefüllt. Ich fülle die Bitmap mit der AutoIt.exe...
    Um den Assemblerteil so einfach wie möglich zu gestalten, konzentrieren wir uns nur auf die reine Suche.
    Die Bitmap liegt bereits im Speicher und ist durch 2 Parameter bestimmt. Die Adresse des ersten Bytes und die Größe=Anzahl der Bytes.
    Ein "Pixel" ist 4 Byte groß und setzt sich aus den Farben Rot RR,Grün GG,Blau BB und dem Alphakanal AA für die Transparenz zusammen.
    Die Reihenfolge im Speicher lautet AABBGGRR

    Das Assemblerprogramm soll folgendes machen:
    Lade die Farbe in ein Prozessorregister (32Bit= 4 Byte)
    Lade die Startadresse der Bitmap in ein Zähl-Register.
    Vergleiche die 4 Bytes an dieser Speicheradresse mit den 4 Byte im Register (der gesuchten Farbe)
    Wenn die 4 Bytes im Speicher identisch sind mit den 4 Bytes im Register, gebe die Position des ersten Bytes im Speicher aus. Wenn nicht, erhöhe das Zähl-Register um 4 und vergleiche die nächsten 4 Bytes.
    Wiederhole so lange, bis das Ende der Bitmap erreicht ist.

    Im folgenden Script habe ich das Erstellen des Bytecodes in eine eigene Funktion MakeByteCode() ausgelagert, da dieser Vorgang natürlich nur ein einziges Mal beim Start des AutoIt-Scriptes erfolgen muss.
    Die AutoIt-Funktion Pixelsearch() habe ich als Vergleich eingefügt. Das ist natürlich unfair, da Pixelsearch() wesentlich komfortabler ist, und nicht nur mit 32Bit-Bitmaps arbeitet. Aber mit einer Handvoll Bytes in unserer Assembler-Funktion erreichen wir eine immerhin 15-20 mal schnellere Suche! Erweitert die Bitmap mal auf 10000x10000 Pixel, Pixelsearch steigt dann zwar aus, aber unser Assemblerprogramm findet tapfer das gesuchte Pixel...

    [autoit]

    ;Beispielscript PixelSuchen
    ;findet ein Pixel mit einer bestimmten Farbe innerhalb einer 32-Bit-Bitmap

    [/autoit][autoit][/autoit][autoit]

    #include <FASM.au3>
    #include <WinAPI.au3>

    [/autoit][autoit][/autoit][autoit]

    Opt("PixelCoordMode", 2) ;ausschliesslich für Pixelsearch()

    [/autoit][autoit][/autoit][autoit]

    Global $bytecode = MakeBytecode() ;den Assembler anweisen, den Bytecode zu erstellen
    ;wenn der Bytecode ausgetestet ist, dann kann man auch
    ;Global $bytecode ="0x8B7C24048B4424088B54240C8B5C241089D1F2AFB80000000083F900741383C10129CA89D0BA00000000F7F3C1E21001D0C3"
    ;schreiben und #include <FASM.au3> und die gesamte Funktion MakeBytecode() weglassen

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    local $ptr_Bitmap, $hbmp_Bitmap ;Pointer und Handle der Bitmap, Handle wird hier nicht gebraucht
    $iwidth = 1000 ;Breite und Höhe der Bitmap, probiert mal 10000x10000, das Pixel wird mit PixelSuche32() gefunden , aber Pixelsearch() steigt aus
    $iheight = 700 ;
    $hDC_Bitmap = _CreateNewBmp32($iwidth, $iheight, $ptr_Bitmap, $hbmp_Bitmap) ;leere 32Bit-Bitmap erstellen

    [/autoit][autoit][/autoit][autoit]

    ;wir füllen die Bitmap mit dem Inhalt der AutoIt.EXE
    $Struct = DllStructCreate("byte[" & $iwidth * $iheight * 4 & "]", $ptr_Bitmap) ;struct an der Position der Bitmap erstellen
    DllStructSetData($Struct, 1, StringLeft(StringToBinary(FileRead(@AutoItExe)), $iwidth * $iheight * 8)) ;und mit den Bytes der AutoIt.exe füllen

    [/autoit][autoit][/autoit][autoit]

    ;Pixel setzen an Position x=150 y=height-10 mit der Farbe 0xFFE199F0, das Pixel sollte im unteren linken Teil des schwarzen Feldes in der GUI zu sehen sein
    $col = 0xFFE199F0 ;gesuchte Farbe 0xAABBGGRR Alpha,Blau,Gruen,Rot
    $Struct2 = DllStructCreate("dword", $ptr_Bitmap + $iwidth * ($iheight-10) * 4 + 150 * 4) ;struct an Position des Pixels erzeugen
    DllStructSetData($Struct2, 1, $col ) ;AABBGGRR Alpha,Blau,Gruen,Rot Farbe in die Bitmap eintragen

    [/autoit][autoit][/autoit][autoit]

    ;GUI erstellen und anzeigen (wird nur für Pixelsearch() benötigt, PixelSuchen32() braucht kein aktives Fenster)
    $hgui = GUICreate("AutoIt.EXE visualisiert^^", $iwidth, $iheight) ;Gui erstellen
    $hDC_GUI = _WinAPI_GetDC($hgui) ;Device Context des Fensters
    GUISetState(@SW_SHOW, $hgui)
    _WinAPI_BitBlt($hDC_GUI, 0, 0, $iwidth, $iheight, $hDC_Bitmap, 0, 0, 0xCC0020) ;Bitmap in GUI darstellen 0xCC0020=SRCCOPY

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    $t=timerinit()
    $pos = PixelSuchen32($ptr_Bitmap, $col, $iwidth * $iheight , $iwidth) ;findet 0xAABBGGRR in einer Bitmap
    $m=timerdiff($t)

    [/autoit][autoit][/autoit][autoit]

    $t=timerinit()
    $a=pixelsearch(0,0,$iwidth,$iheight, dec(hex($col,6)),0,1,$hgui) ;pixelsearch findet 0xBBGGRR
    $f=timerdiff($t)

    [/autoit][autoit][/autoit][autoit]

    if $pos=0 Then ;falls EAX=0, dann wurde keine Übereinstimmung gefunden
    msgbox(0,"Pixel mit der Funktion PixelSuchen32()","nicht gefunden!")
    Else ;ansonsten
    msgbox(0,"Pixel mit PixelSuchen32() gefunden an","X= "&$pos[0]&@crlf&"Y= "&$pos[1]&@crlf&@crlf&stringformat("in %.2f Millisekunden wurden ",$m)&$pos[1]*$iwidth+$pos[0]&" Pixel verglichen, das"&@crlf&"sind "&int(($pos[1]*$iwidth+$pos[0])/$m/1000)&" Millionen Pixel pro Sekunde!")
    msgbox(0,"Pixel mit Pixelsearch() gefunden an","X= "&$a[0]&@crlf&"Y= "&$a[1]&@crlf&@crlf&stringformat("in %.2f Millisekunden",$f))
    endif

    [/autoit][autoit][/autoit][autoit]

    While GUIGetMsg() <> -3
    ;_WinAPI_BitBlt($hDC_GUI, 0, 0, $iwidth, $iheight, $hDC_Bitmap, 0, 0, $SRCCOPY) ;Bitmap in GUI darstellen
    WEnd
    _WinAPI_DeleteObject($hbmp_Bitmap) ;wurde zwar nicht benötigt, aber erstellt!
    exit

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func PixelSuchen32($ptr, $col, $Breite_x_Hoehe,$Breite) ;pointer auf die Bitmap, Farbe und Größe der Bitmap
    $tCodebuffer = DllStructCreate("byte[" & StringLen($bytecode) / 2 - 1 & "]") ;Speicher für den Bytecode reservieren
    DllStructSetData($tCodebuffer, 1, $bytecode) ;Bytecode in den Speicher schreiben
    $Ret = DllCall("user32.dll", "int", "CallWindowProcW", "ptr", DllStructGetPtr($tCodebuffer), "ptr", $ptr, "int", $col, "int", $Breite_x_Hoehe, "int", $Breite);bytecode aufrufen, rückgabe in a[0], Aufruf IMMER mit 4 Parametern!
    if $ret[0]=0 or @error then return 0 ;Pixel wurde nicht gefunden
    dim $koord[2]
    ;die oberen 16 Bit von EAX enthalten die x-Koordinate, die unteren 16 Bit enthalten die y-koordinate
    $koord[0]=BitShift($ret[0],16) ;x-Koordinate
    $koord[1]=Bitand($ret[0],0x0000FFFF);y-Koordinate
    return $koord
    EndFunc ;==>PixelSuchen32

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func MakeBytecode() ;aus dem Assemblercode einen Bytecode machen, den der Prozessor ausführen kann
    Local $Fasm = FasmInit() ;FASM initialisieren
    FasmReset($Fasm) ;FASM resetten

    [/autoit][autoit][/autoit][autoit]

    FasmAdd($Fasm, "use32") ;wir benutzen den 32-Bit Assembler
    FasmAdd($Fasm, "mov edi, [esp + 4]") ;ES:EDI = Pointer auf die Bitmap
    FasmAdd($Fasm, "mov eax, [esp + 8]") ;EAX = gesuchte Farbe
    FasmAdd($Fasm, "mov edx, [esp + 12]") ;EDX = Größe der Bitmap
    FasmAdd($Fasm, "mov ebx, [esp + 16]") ;EBX = Breite der Bitmap
    FasmAdd($Fasm, "mov ecx,edx") ;ECX ist der Zähler
    FasmAdd($Fasm, "REPNE SCASD") ;so lange ES:EDI mit EAX vergleichen, bis entweder
    ;- Speicherinhalt von ES:EDI und Register EAX identisch sind
    ;- oder ECX=0 ist, ECX wird immer um eins subtrahiert und EDI um ein DWORD(=4 Bytes) addiert
    ;Im Prinzip wird ein DWORD im angegebenen Speicherbereich gesucht
    ;For $ECX=$EDX to 0 Step -4
    ;If $EDI[$EDX-$ECX]=$EAX then exit ; gefunden
    ;Next
    FasmAdd($Fasm, "mov eax,0") ;EAX=0 Wir nehmen an, es wurde kein Pixel gefunden
    FasmAdd($Fasm, "cmp ecx,0") ;Compare(Vergleiche) ECX mit 0 , Ist ECX=0, dann wurde kein Pixel gefunden, die Zählschleife ist komplett durchgelaufen
    FasmAdd($Fasm, "JE Ende") ;Jump if Equal, springe zum ENDE-Label, wenn ECX=0
    FasmAdd($Fasm, "add ecx,1") ;ECX=ECX+1 gefundene Byte-Position des Pixels in der Bitmap
    FasmAdd($Fasm, "sub edx,ecx") ;EDX=EDX-ECX ECX zählt ja "rückwärts" bis auf 0
    FasmAdd($Fasm, "mov eax,edx") ;EAX=EDX Position des Pixels
    FasmAdd($Fasm, "mov edx,0") ;EDX auf Division vorbereiten
    FasmAdd($Fasm, "div ebx") ;EAX=int(eax/ebx) EDX=mod(eax,ebx) in EAX steht der ganzzahlige Quotient, in EDX der Rest
    FasmAdd($Fasm, "shl edx,16") ;EDX 16 Bits nach links schieben...
    FasmAdd($Fasm, "add eax,edx") ;...und zu EAX addieren in den oberen 16 Bit steht nun die Zeile, in den unteren 16 bit die Spalte des gefundenen Pixels
    FasmAdd($Fasm, "Ende:") ;Sprungmarke
    FasmAdd($Fasm, "ret") ;zurück zur aufrufenden Funktion

    [/autoit][autoit][/autoit][autoit]

    ;hier könnte man das Errorhandling einfügen aus der FASMDemo.au3

    [/autoit][autoit][/autoit][autoit]

    Local $bytecode = String(FasmGetBinary($Fasm)) ;bytecode erstellen
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $bytecode = ' & $bytecode & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    FasmExit($Fasm) ;FASM aus dem Speicher entfernen
    Return $bytecode
    EndFunc ;==>MakeBytecode

    [/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe $HDC und $ptr und handle auf die Bitmapdaten
    Local $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
    Local $tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
    DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
    DllStructSetData($tBMI, "Width", $iwidth)
    DllStructSetData($tBMI, "Height", -$iheight) ;minus =standard = bottomup
    DllStructSetData($tBMI, "Planes", 1)
    DllStructSetData($tBMI, "BitCount", 32) ;32 Bit = 4 Bytes => AABBGGRR
    Local $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 1, 'ptr*', 0, 'ptr', 0, 'uint', 0)
    $hbmp = $adib[0] ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
    $ptr = $adib[4] ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
    ;_arraydisplay($adib)
    _WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC
    Return $hcdc ;DC der Bitmap zurückgeben
    EndFunc ;==>_CreateNewBmp32

    [/autoit]
  • Tutorial AutoIt und Assembler UPDATE 24. Oktober 2010 Verwendung von Autoitvariablen im Assemblercode

    • Andy
    • 9. August 2010 um 21:42

    Beispiel_1: Addition von 2 Integer-Zahlen
    AutoIt-Funktion: AddierenInteger($int1, $int2) ;zwei Integer sollen addiert werden

    Die Übergabe von Funktionsparametern erfolgt in der Regel (wie auch bei DLL-Calls) über den Stack, welcher nur ein Teil des Arbeitsspeichers ist.
    Auf dem Stack wird bei einem Funktionsaufruf die Rücksprungadresse in das aufrufende Programm (z.B. Autoit) abgelegt, gefolgt von den übergebenen Parametern.
    Die Rücksprungadresse ist bei 32-Bit-Systemen 32-Bit groß, d.h. 4 Byte oder ein DWORD.
    Die Parameter sind so groß, wie sie im Funktionsaufruf definiert sind, also (INT) = (4 Byte) = (1 Dword), man kann natürlich auch 64 Bit große Parameter oder 1 Byte große Parameter übergeben.
    Wenn also die Funktion Test mit 2 Parametern aufgerufen wird, dann sieht der Stack beim Aufruf der Funktion also folgendermassen aus:


    • Stack: Inhalt:
      Speicheradresse_xxx+0 Byte Rücksprungadresse: (4 Byte groß)
      Speicheradresse_xxx+4 Byte 1. Parameter INTeger (4 Byte groß)
      Speicheradresse_xxx+8 Byte 2. Parameter INTeger (4 Byte)


    Um im Assembler auf den Stack zuzugreifen, benutzt man das Stackpointerregister ESP. (SP=StackPointer)
    ESP zeigt beim Start der Funktion immer auf die Rücksprungadresse!
    Um also mittels ESP auf den ersten Parameter zu zeigen, muss man die 4 Byte der Größe der Rücksprungadresse zur aktuellen Adresse hinzuzählen. Dabei weisen die rechteckigen Klammern auf den INHALT der Speicherstelle hin!
    ESP+4 ist also die Speicheradresse des 1. Parameters, [ESP+4] ist der INHALT an dieser Speicheradresse, also unser erster Parameter. Damit der Assembler weiß, wie viele Bytes er einlesen muss, schreibt man die "Anzahl" in Form eines Datenwortes vor die Klammer. Allerdings muss das nicht zwangsläufig sein, wenn der Assembler dem Ziel eine bestimmte Größe zuordnen kann!
    Den (4 Byte = 1 DWORD großen) Inhalt des ersten Parameters schreiben wir nun mittels des MOV-Befehls in ein Prozessorregister, beispielsweise EAX:

    Code
    ;In den Kommentaren versuche ich mit AutoIt-ähnlicher Syntax den Assemblerbefel zu verdeutlichen
    MOV EAX,DWORD[ESP+4]     ;EAX=[ESP+4]  Viele Assembler leiten aus der Größe des Zieles die Anzahl der Bytes ab, daher braucht man sie in diesem Fall nicht
    ;oder
    MOV EAX,[ESP+4]     ;EAX=[ESP+4]     EAX ist 4 Byte groß, also werden 4 Byte ab der Position des 1. Parameters=Stackpointers+4 Bytes eingelesen


    Sehr schön, nun steht der erste Parameter im EAX-Register, gleiches mit dem 2. Parameter, der soll ins EBX-Register

    Code
    MOV EBX,[ESP+8] ;EBX=[ESP+8]      EBX ist 4 Byte groß, also werden 4 Byte ab der Position des 2. Parameters=Stackpointers+8 Bytes eingelesen


    Das wars schon, nun sind die Prozessorregister gefüllt, und der Prozessor braucht den Befehl zur Addition

    Code
    ADD EAX,EBX     ;EAX = EAX + EBX


    Der Prozessor addiert die beiden Registerinhalte und schreibt das Ergebnis ins EAX-Register. Unsere Funktion ist fertig! Das Ergebnis wird vom aufrufenden Programm im EAX-Register erwartet.
    Nun muss man dem Assembler nur noch die Speicherstelle "zeigen" an der unsere Funktion aufgerufen wurde.
    Das ist nun die Rücksprungadresse, welche ja auch auf dem Stack steht.
    Der Stackpointer zeigt ja zur Zeit auf diese Rücksprungadresse! Aber was machen wir mit den Parametern auf dem Stack?
    Die müssen dort weg! Ansonsten würde in kürzester Zeit der Speicher überlaufen, weil jede Funktion ihren "Müll" im Speicher stehen ließe!
    Wir sagen also dem Assembler, er soll die beiden Parameter (2 Integer = 8 Byte) auf dem Stack löschen und an das aufrufende Programm zurückkehren.

    Code
    RET 8 ; 8 Byte(=die beiden Parameter) vom Stack löschen und kehre zum ausfrufenden Programm zurück, die Rücksprungadresse wird auch gelöscht.


    Das war´s schon^^

    Übrigens sind die meisten Assembler relativ genügsam im Bezug auf Groß- und Kleinschreibung.
    Man muss beachten, daß die Mehrzahl der Prozessorbefehle nur mit Kombinationen aus Registern und Speicherinhalten arbeiten.
    Ein ADD EAX,[ESP+8] hätte auch den 2. Parameter zum EAX-Register dazugezählt, aber ADD [ESP+4],[ESP+8] FUNKTIONIERT NICHT!
    Im ausführbaren AutoIt-FASM-Code sieht das nun so aus:

    [autoit]

    #include "FASM.au3"
    #include <array.au3> ;zur Anzeige des Rückgabe-Arrays

    [/autoit][autoit][/autoit][autoit]

    $Fasm = FasmInit() ;FASM initialisieren
    FasmReset($Fasm) ;FASM resetten
    ;*** hier beginnt der Assemblercode
    FasmAdd($Fasm, "use32") ;wir benutzen den 32-Bit Assembler
    FasmAdd($Fasm, "mov eax, [esp + 4]") ;erster Parameter ins EAX-Register, 4 Byte nach der Rücksprungadresse
    FasmAdd($Fasm, "mov ebx, [esp + 8]") ;zweiter Parameter ins EBX-Register
    FasmAdd($Fasm, "add eax, ebx") ;EAX = EAX + EBX
    FasmAdd($Fasm, "ret 8") ;8 Bytes vom Stack und zurück zur aufrufenden Funktion
    ;*** Ende des Assemblercodes
    ConsoleWrite(String(FasmGetBinary($Fasm))&@CRLF) ;Bytecode
    MsgBox(0,"Bytecode, der vom Assembler erstellt wurde:",String(FasmGetBinary($Fasm))) ;Bytecode anzeigen
    $Ret = MemoryFuncCall("int", FasmGetFuncPtr($Fasm), "int", 12, "int", 44) ;Bytecode aufrufen, nach dem Pointer auf den Code werden die Parameter zugewiesen. Rückgabe als Array!
    _arraydisplay($ret,"Ergebnis, Parameter1, Parameter2") ;Angezeigt werden das Ergebnis und die Übergabeparameter
    MsgBox(0, "Ergebnis", "12 + 44 = " & $Ret[0]) ;EAX steht in $ret[0]

    [/autoit][autoit][/autoit][autoit]

    FasmExit($Fasm) ;FASM aus dem Speicher entfernen

    [/autoit]

    Noch eine kurze Erklärung zum MemoryFuncCall().

    [autoit]

    MemoryFuncCall("Format_Rückgabeparameter", $Pointer_zur_Funktion,"Format_Parameter1",$Parameter1,"Format_Parameter2",$Parameter2, "Format_Parameter3",$Parameter3...uswusf)

    [/autoit]

    Wie man in der Ausgabe der ersten MessageBox sieht, erstellt der Assembler den Bytecode.
    Wie schon angedeutet, reicht dieser Bytecode für das Ausführen des Programms aus, man muss also den Assembler im fertigen Programm nicht mehr mitschleppen!

    Wie das funktioniert, sieht man nun hier:
    Der Speicher für den Bytecode wird reserviert, der Bytecode (kann aus der Console des Assemblerprogramm-Teils kopiert werden) wird dort eingetragen und Windows wird mit einem Funktionsaufruf (CallWindowProcW) angewiesen, diesen Code auszuführen.
    Allerdings gibt es bei dieser Methode einige Einschränkungen, so können maximal 4 Parameter (32Bit-Typen, also DWORD, INT, FLOAT usw.) übergeben werden. Um mehr Parameter zu übergeben, sollten diese in eine Struktur geschrieben, und dem Call nur der Pointer auf diese Struktur übergeben werden.
    Weiterhin übernimmt die CallWindowProcW-Funktion selbstständig alle "Aufräumarbeiten" auf dem Stack, das ist bei unserem Beispiel ziemlich schlecht, denn der RET 8 löscht schon 2 Parameter! Also was tun?
    Hier muss man sich nun entscheiden, entweder man startet seinen Bytecode mit dem vorgestellten MemoryFuncCall() und muss somit immer den kompletten Assembler bzw die Memory.AU3 "mitschleppen" oder man verwendet CallWindowProcW und kann im fertigen Programm auf die FASM.AU3 (Assembler) und die MEMORY.AU3 verzichten.

    Ich habe mich bei der Zusammenarbeit FASM/AutoIt für CallWindowProcW entschieden. Das eigentliche Assemblerprogramm bleibt identisch, aber da CallWindowProcW den Stack "aufräumt" muss man nur noch mit einem einfachen RET den Assemblercode abschliessen.
    Es ergibt sich also aus

    [autoit]

    #include <FASM.au3>
    #include <array.au3>

    [/autoit][autoit][/autoit][autoit]

    $Fasm = FasmInit() ;FASM initialisieren
    FasmReset($Fasm) ;FASM resetten
    FasmAdd($Fasm, "use32") ;wir benutzen den 32-Bit Assembler
    FasmAdd($Fasm, "mov eax, [esp + 4]") ;erster Parameter ins EAX-Register, 4 Byte nach der Rücksprungadresse
    FasmAdd($Fasm, "mov ebx, [esp + 8]") ;zweiter Parameter ins EBX-Register
    FasmAdd($Fasm, "add eax, ebx") ;EAX = EAX + EBX
    ;ein einfaches RET reicht nun
    FasmAdd($Fasm, "ret") ;zurück zur aufrufenden Funktion
    $bytecode=FasmGetBinary($Fasm)
    ConsoleWrite($bytecode&@CRLF) ;Bytecode per Copy/Paste in das nächste Script transferieren
    MsgBox(0,"Bytecode, der vom Assembler erstellt wurde:",String(FasmGetBinary($Fasm))) ;Bytecode anzeigen
    ;die folgenden 3 Zeilen ersetzen den MemoryFuncCall()
    $tCodebuffer=dllstructcreate("byte["&stringlen($Bytecode)/2-1&"]") ;Speicher für den Bytecode reservieren
    dllstructsetdata($tCodeBuffer,1,$Bytecode) ;Bytecode in den Speicher schreiben
    $Ret= DllCall("user32.dll", "int", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), "byte", 12, "int", 33, "int", 0, "int", 0);bytecode aufrufen, rückgabe in a[0], aufruf IMMER mit 4 Parametern!
    MsgBox(0,"Ergebnis",$Ret[2]&" + "&$Ret[3]&" = "&$Ret[0])

    [/autoit][autoit][/autoit][autoit]

    FasmExit($Fasm) ;FASM aus dem Speicher entfernen

    [/autoit]

    der ohne Assembler ausführbare AutoIt-Code:

    [autoit]

    $Bytecode="0x8B4424048B5C240801D8C3" ;wurde vom Assembler erstellt und im vorherigen Programm in die Console geschrieben
    $tCodebuffer=dllstructcreate("byte["&stringlen($Bytecode)/2-1&"]") ;Speicher für den Bytecode reservieren
    dllstructsetdata($tCodeBuffer,1,$Bytecode) ;Bytecode in den Speicher schreiben
    $Ret= DllCall("user32.dll", "int", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), "int", 12, "int", 33, "int", 0, "int", 0);bytecode aufrufen, rückgabe in a[0]
    MsgBox(0,"Ergebnis",$Ret[2]&" + "&$Ret[3]&" = "&$Ret[0])

    [/autoit]

    und als AutoIt-Funktion

    [autoit]

    ;an den Anfang des Programms
    $Bytecode = "0x8B4424048B5C240801D8C3" ;wurde vom Assembler erstellt
    $tCodebuffer = DllStructCreate("byte[" & StringLen($Bytecode) / 2 - 1 & "]") ;Speicher für den Bytecode reservieren
    DllStructSetData($tCodebuffer, 1, $Bytecode) ;Bytecode in den Speicher schreiben

    [/autoit][autoit][/autoit][autoit]

    $zahl1 = 1337
    $zahl2 = 3537
    $ergebnis = AddierenInteger($zahl1, $zahl2)
    MsgBox(0, "Ergebnis", $zahl1 & " + " & $zahl2 & " = " & $ergebnis)
    Exit

    [/autoit][autoit][/autoit][autoit]

    Func AddierenInteger($int1, $int2) ;addition zweier Integer
    $Ret = DllCall("user32.dll", "int", "CallWindowProcW", "ptr", DllStructGetPtr($tCodebuffer), "int", $int1, "int", $int2, "int", 0, "int", 0);bytecode aufrufen, rückgabe EAX in $ret[0]
    Return $Ret[0]
    EndFunc ;==>AddierenInteger

    [/autoit]


    Im Prinzip geht es also nur darum, den Bytecode zu erstellen! Nur nebenbei bemerkt, man kann ohne weiteres den Bytecode per

    [autoit]

    Filewrite("test.bin",binarytostring($bytecode))

    [/autoit]

    in eine Datei schreiben und diese dann mit einem Debugger/Disassembler bearbeiten...


    //EDIT//Die Rückgabe an AutoIt erfolgt abhängig vom Format des Datentyps des Dll-Calls!
    Es geht also um den rot markierten Teil des Aufrufs:
    $Ret = DllCall("user32.dll", "int", "CallWindowProcW", "ptr", DllStructGetPtr($tCodebuffer)

    • "int oder long ", es wird zurückgegeben, was im EAX-Register steht, bei Byte gilt z.B. der Inhalt des AL-Registers (unterster Teil von eax)
    • "float oder double", es wird zurückgegeben, was im ST0 des Floatingpointprozessors steht
    • "ptr" auch EAX, aber Ausgabe als 0xAABBCCDD also Hex
    • "str" in eax steht nun der Zeiger auf den Anfang des Strings!
  • Tutorial AutoIt und Assembler UPDATE 24. Oktober 2010 Verwendung von Autoitvariablen im Assemblercode

    • Andy
    • 9. August 2010 um 21:42

    Tutorial AutoIt und Assembler

    //EDIT 11/03/2011
    AssembleIt als Hilfsmittel für das Programmieren mit dem Embedded-FASM-Assembler nun inclusive Debugger!  Der Inhalt kann nicht angezeigt werden, da er nicht mehr verfügbar ist.

    //EDIT 19/10/2010
    _AssembleIt() etwas angepasst, bitte Beispiele beachten! LÄUFT NICHT mit den hier im Tut gezeigten ASM-codes, da _AssembleIt() nun den Stack selbst aufräumt! Daher ist als Rücksprung zu AutoIt NUR EIN EINFACHES RET nötig! Also kein RET 8, um 2 Integer vom Stack zu räumen! Die hier im Tut vorgestellten Beispiele sind natürlich lauffähig. Der Inhalt kann nicht angezeigt werden, da er nicht mehr verfügbar ist. (ohne Debugger)

    Die Anpassung der bisherigen Beispiele habe ich vor, ggf gibts von euch weitere Ideen, was und wie man das "Handling" weiter verbessern könnte.
    Links für Tutorials hinzugefügt im Abschnitt "Was muss ich an Vorwissen haben?"

    Beispiele:
    Beispiel_1: Addition von 2 Integer-Zahlen
    Beispiel_2: Pixelsuchen32, findet ein Pixel innerhalb einer Bitmap
    Beispiel_3 Verwenden eigener Variablennamen
    Einfache Schleifen, der LOOP
    Beispiel Stringbehandlung und Pointer auf AutoIt-Variablen
    Aufruf von "Funktionen" mit CALL-Befehl, Beispiel Rekursion Fakultät
    Beispiel Verwendung von Floatingpoint-Registern und ein Versuch, ein AutoIt-Script 1:1 in Assembler umzusetzen
    Optimierung von Code am Beispiel des Tunnelfluges
    Weitere Optimierung am "Tunnelflug" am Beispiel eines Arrays bzw. LookUpTabelle LUT
    Einsatz von SSE/SSE2 Befehlen am Beispiel Tunnelflug
    Beispiel für Übergabe und Rückgabe von Parametern an/von einer AutoItfunktion aus dem Assemblercode
    Beispiel um aus einer Assemblerfunktion eine DLL zu machen
    Verwendung von AutoIt-Variablen im Assemblercode NEU


    Edit BugFix:
    Fragen zum Thema bitte hier: Assembler Hilfe-Thread stellen.
    Bisher hier gestellte Fragen sind dorthin verschoben.


    Hallo zusammen,
    da schon mehrfach die Frage nach der Verbindung von einfach zu erstellenden AutoIt-Scripten und sehr schnellen und kleinen Assemblerprogramen auftrat, stelle ich in diesem Tutorial einige Möglichkeiten vor.

    Was ist ein Assembler?

    • Ein Assembler ist ein recht einfaches Programm, welches nichts weiter macht, als Befehle in vom Prozessor direkt verarbeitbare Mnemonics (Maschinensprache) umzuwandeln.


    Was muss ich an Vorwissen haben?

    • Ich werde hier keine "Einführung" in Prozessortechnik machen, wer also keine Ahnung hat, um was es bei Assembler eigentlich geht, und warum jemand ein Prozessorregister oder Speicher braucht, dem empfehle ich die einschlägigen Seiten im Internet. Zum Beispiel HIER oder hier und für "oldschool"-Usenetnutzer hier. Sehr schön auch diese Seite und diese, welche auch hier teilweise in deutsch übersetzt wurde!
      Mir geht es primär um die Frage, wie man Daten von AutoIt aus an das Maschinenspracheprogramm übergeben kann, und wie man Daten zurückbekommt.


    Assembler ist MegaOUT!

    • Für diejenigen, die meinen, Assembler gehöre zu den Dinosauriern, weil man auch objektorientiert mit Hilfe eines tonnenschweren Software-Supertankers ein 800 Megabyte großes "Hallo Welt" schreiben kann, sei gesagt, ja, macht das auch weiterhin! Es lebe die Zukunft!
      Allerdings verpasst man dann, einen kompletten Sudoku-Löser incl. Ein- und Ausgabe in 67 Byte (ja BYTE! ) vorgestellt zu bekommen...


    Was brauche ich?

    • Wer nun nicht völlig abgeschreckt ist, dem würde ich empfehlen, HIER die Datei FASM.zip, einen in AutoIt "integrierten" Assembler, herunterzuladen und auszupacken, und schon kann´s losgehen. Bitte beachten, daß die vorgestellten Programme nur als 32Bit-Kompilat laufen, weiterhin sollte das System so "clean" wie möglich sein, ein neu aufgesetztes BS in einer virtuellen Maschine bietet sich an, ist aber keine Voraussetztung. Ich habe sowohl mit XP/32 als auch mit WIN7/32 in Produktivumgebung keinerlei Probleme gehabt.
      Die im Programmpaket enthaltene FasmDemo.Au3 sollte ohne Probleme durchlaufen. Dann kanns losgehen...
      EDIT: AssembleIt als Hilfsmittel für das Programmieren mit dem Embedded-FASM-Assembler sollte das arbeiten mit dem Code vereinfachen.

    Wozu Assembler?

    • Nun ja, mit keiner anderen Sprache ist man dichter "im" und am Prozessor dran, clever programmiert, kann ein sehr kurzes Programm aus einigen Bytes hunderte Male schneller als ein AutoIt-Script arbeiten..
      Man benutzt also den Assembler dort, wo man große Geschwindigkeitsvorteile erreichen kann. Quasi nebenbei erfährt man einiges über Strukturen (Dllstructxxxxx) und den Aufruf von externen Funktionen z.B. aus DLL´s.
      Das Errorhandling habe ich in den folgenden Beispielen weggelassen, aber gerade bei Assembler rächt sich das SEHR SCHNELL!
      Ein einziges "fehlerhaftes" Bit in einem der Prozessorregister, und der Computer stürzt ab! Glücklicherweise sorgt der Protected Mode nur für eine Fehlermeldung^^


    Zunächst stellt sich die Frage, warum in AutoIt "integriert"?

    • Die Antwort ist relativ einfach, man hat EINE ausführbare Datei. Selbstverständlich ist es mit Assembler möglich, sehr einfach eine DLL zu erstellen, auch darauf werde ich natürlich eingehen!


    Wie kommen die Assemblerprogramme ins AutoIt?

    • Nun, ganz grob gesagt, reserviert AutoIt für den Assembler etwas Speicher, schreibt die aus dem Assemblercode erzeugten Maschinensprache-Befehle hinein, und springt aus dem AutoIt-Script in das Maschinespracheprogramm und nach der Abarbeitung der Befehle wird in das AutoIt-Script zurückgekehrt. Ähnlich einem DLL-Funktionsaufruf.
      Hat man erst einmal Mit Hilfe des Assemblers die Maschinesprache-Sequenz (im folgenden nenne ich das Bytecode) an Befehlen erstellt, ist der Funktions-Aufruf mit einigen Zeilen AutoIt-Code erledigt.
      Damit erübrigt sich auch ein Obfuscator, denn der "lesbare" Assemblercode wird nicht weiter benötigt!
      Aber dazu später, los gehts mit einigen Beispielen!

    Wir fangen damit an, einige einfache Funktionen zu erstellen. Die Eingabeparameter werden an die Assembler-Funktion übergeben, eine Berechnung wird ausgeführt und das Ergebnis wird an AutoIt zurückgegeben.
    Dazu werden von AutoIt die Parameter auf den "Stack" (Stapel von Bytes) "gepushed" (geschoben), und von dort mit dem Assemblerprogramm weiterverarbeitet. Die Rückgabe erfolgt im AX (EAX)-Register.
    Da wir meist im 32-Bit-Bereich arbeiten, verwende ich größtenteils die "großen" 32-Bit-Register (mit dem E-Präfix, bspw. EAX EBX ESP usw.), auch wenn das nicht immer notwendig sein sollte.
    Die Beispiele sind natürlich kommentiert, wer trotzdem etwas nicht versteht, immer fleissig Fragen!
    Eine 8088(286,386,486 usw)Befehlreferenz gibt es z.b. HIER oder HIER
    Nur keine Panik, die allermeisten Befehle im ersten Link sind Erweiterungen (MMX, SSE usw), die man nicht unbedingt braucht. 2-3 Handvoll Befehle reichen aus, um effektive Assemblerprogramme zu schreiben.

    Dateien

    _AssembleIt.zip 163,2 kB – 953 Downloads AssembleIt.zip 8,32 kB – 990 Downloads
  • Sprachsteuerung

    • Andy
    • 8. August 2010 um 12:58
    Zitat

    3.->Das Skript ermittelt einen Prozentwert der Ähnlichkeit der beiden Daten.

    Darin liegt deas "sprachenunabhängige" Problem! Zwei Dateien miteinander zu vergleichen ist die eine Sache, zwei Audiodateien zu vergleichen eine andere. Im WAV-Format kommt man sehr einfach an die rohen Audio-Daten, irgendwo hier im Forum schwirren Scripte von Wellengeneratoren u.ä. herum, die das Prinzip verdeutlichen.
    Ich würde für den Anfang jeweils 10x ein Wort aufnehmen, "Marmeladenglas", "Wellensittich", "Matsch", "Tasche", "Flasche" und die Wellen bzw Frequenzen (Verläufe) analysieren, und die "Problemlaute" finden. Wenn man in der Lage ist, einzelne Laute sicher zu trennen, dann ist der "Vergleich" relativ simpel

  • Variablenname hochzählen? ($variable1, $variable2,...)

    • Andy
    • 6. August 2010 um 15:28

    weiterhin gibts die Möglichkeit per EVAL() Variablen hochzuzählen

    [autoit]

    $var1=10
    $var2=20
    $var3="Test"
    $var4=True
    assign("var5","das ist eine Variable")

    [/autoit][autoit][/autoit][autoit]

    for $i=1 to 5
    msgbox(0,"$var"&$i,eval("var"&$i))
    next

    [/autoit]
  • GUI bei Fehler anzeigen

    • Andy
    • 5. August 2010 um 11:15

    Nach 5x durchlesen hab ich das Problem begriffen (glaube ich ^^)

    [autoit]

    Case $Button1
    if MsgBox(0, 'Testtitel', 'Klicke auf OK um zum Menü zu gelangen') = 1 Then
    ;hier kommt der Code hin der ausgeführt werden soll, wenn OK gedrückt wurde, also das Menü
    else
    ;hier kommt der Code hin, wenn auf EXIT (in der Msgbox) geklickt wird
    EndIf

    [/autoit][autoit][/autoit][autoit]

    ;was ich aber noch nicht verstanden habe, WANN soll
    ; #Hier kommt noch gaaaaaanz viel Code
    ;ausgeführt werden?

    [/autoit]

    oder etwa...

    [autoit]

    Case $Button1
    $a=_ funktion($var)
    if $a=1 or @error then ;es wurde ein Fehler in der Funktion gefunden
    ;Fehlerbehandlung
    else
    ;kein Fehler in der Funktion...
    endif
    endswitch

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _funktion($var)
    ;code oder abfrage der funktionsparameter
    ;es ist ein Fehler aufgetreten
    if @error or $var=1 then
    msgbox(0,"Fehler in Funktion _funktion()","Es wurde $var=1 angegeben!")
    return 1;kehrt zum Menü zurück, Funktion gibt 1 für fehler zurück, oder seterror() benutzen
    else
    ; #Hier kommt noch gaaaaaanz viel Code, im Falle, daß kein Fehler aufgetreten ist
    EndIf
    return 0 ;funktion gibt 0 im Erfolgsfall zurück, oder seterror() benutzen also return seterror(x,y,z)
    endfunc

    [/autoit]
  • Formular ausfüllen

    • Andy
    • 5. August 2010 um 10:32

    Füllt die Form aus....

    Spoiler anzeigen
    [autoit]

    #include <IE.au3>
    #include <array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $Url = "https://privatpaketservice.hlg.de/wps/portal/PRIPS_DEU"
    $oIE = _IECreate($Url, 0, 1, 1, 1)
    $Url2 = "Online-Paketschein"
    $test = _IELinkClickByText($oIE, $Url2) ;hier lag der Fehler

    [/autoit] [autoit][/autoit] [autoit]

    $oForm = _IEFormGetCollection($oIE, 0) ;Formulardaten
    $oFirma = _IEGetObjById($oForm, "absender(NACHNAME)") ;einzelne Felder

    [/autoit] [autoit][/autoit] [autoit]

    $Firma_Nachname = "Schmitt"
    _IEFormElementSetValue($oFirma, $Firma_Nachname)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;~ _IEAction($oAgree, "click")
    ;~ _IEFormSubmit($oForm)

    [/autoit]
  • Formular ausfüllen

    • Andy
    • 5. August 2010 um 10:01

    Dein Script funktioniert bei mir einwandfrei. Die Seite "Online-Paketschein" wird geladen und angezeigt.
    Funktioniert das bei dir im Internetz-Explodierer denn, wenn du "zu Fuß" auf der Seite navigierst?

    /EDIT/ hups, das scheint nicht das Problem zu sein^^
    Im Quellcode sind die Felder mit einem TabIndex versehen, ggf hilft das weiter....

  • Habt ihr eine G19?

    • Andy
    • 5. August 2010 um 09:48

    Dito! Ein "normales" sehr gutes Keyboard reicht in der Regel völlig aus.
    Für die Preisdifferenz zur G19 holt man sich da besser einen zusätzlichen 20-Zöller, da kann man dann auch von "Mehrwert" sprechen.
    Und wer auf die Tastatur-Macros beim Zocken angewiesen ist , der hat sowieso den Sinn des Spielens nicht begriffen...

  • verschlüsslung selbst schreiben

    • Andy
    • 5. August 2010 um 09:32

    Du hast ein Problem. Denn du hast KEIN Problem.
    Du brauchst garkeine Verschlüsselung. Denn wenn das anders wäre, hättest du dich mit dem Thema beschäftigt und einige sehr einfache Verfahren (wie schon von z.B. AutoBert gepostet) ausprobiert.
    Und da auch "die befehle und so dafür... check ich nicht" nichts anderes heissen soll, als dass dir Langweilig ist und jemand anderes sich hier die Finger wundschreiben soll, damit du dir ja keins der hunderten Beispiele allein hier im Forum im Quellcodes anschauen musst, vote ich mal für close. Konkrete Fragen sehen anders aus!
    Allerdings werden sich (wie üblich) wieder einige erbarmen und trotzdem schreiben. Dann tu ihnen einen Gefallen und versuche vor Abschicken deines 2-Zeilen-Postings wenigstens, einen konkreten Inhalt zu erstellen und auf die gegebenen Antworten einzugehen. Denn das ist wenigstens höflich...

  • Ist es möglich C++ Funktionen in *.dll -Datein mit AutoIT zu öffnen

    • Andy
    • 4. August 2010 um 19:11

    Wie wärs mal, die Suchfunktion zu benutzen? Threads zu diesem Thema sind reichlich vorhanden?
    Antwort auf deine Frage: Ja!

  • Informatik studieren

    • Andy
    • 3. August 2010 um 21:33
    Zitat

    Hier hört sich das fast schon so an, als ob diejenigen die in der Schule gut waren später totale Versager sind

    Schreib dich ein, bring 2-3 Semeser rum und dann antworte noch mal in diesem Thread! Aspirin-Junkie hats ziemlich auf den Punkt gebracht! Wenn es im Studium nicht "flutscht", dann hat man nicht viele Möglichkeiten. Und die absolut schlechteste ist, dann mit der Annahme "Ich hab doch 12+x Punkte in Mathe und Chemie, also kann mein Lernen sooo schlecht ja nicht sein" die Bachgasse runterzufahren. Exmatrikuliert => Studiengang für den weiteren Lebensweg gesperrt (ist das heute immer noch so?)
    Einen Tip würde ich noch geben: Lernen von den "vier bleibt hier"-Typen bzw auch von den besseren ^^. Dranhängen, Lerngemeinschaften bilden, "Mit den Augen stehlen" .
    Btw. ich habe die Erfahrung gemacht, daß eine Ausbildung/Lehre vor dem Studium alles andere als schädlich ist...

  • [abgeschlossen] µitLight August '10

    • Andy
    • 3. August 2010 um 21:16

    hmmmm, Verschlüsselung ist die eine Sache, habe gerade ein Beispielscript für Steganographie erstellt^^
    Aber für Verschlüsselungen fällt mir sicher auch noch was ein ^^

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™