ja, wie schon geschrieben, der " AUTOIT-Assembler" bekommt es nicht auf die Reihe, einen LOOP mit "nach vorne" gerichteter Adresse auszuführen (bei deinem Autoit-Assembler Zeile 17) . D.h. dort ist irgendetwas im Code suboptimal/buggy. Also muß man sich behelfen und "zu Fuß" den Loop emulieren, also ecx decrementieren, auf Zeroflag testen und abhängig davon jumpen.
Was allerdings ohne weiteres funktionieren sollte, ist per irgendeinem Assembler den BYTECODE zu generieren und diesen dann auszuführen. Die Übergabeparameter müssen dann natürlich im bytecode per Hex(Binary($parameter)) ersetzt werden!
Beiträge von Andy
-
-
Hi UEZ,
ähnlich war mein Versuch anfangs auch, allerdings bekam ich permanent Fehlermeldungen. Also habe ich den Binärstring in eine Datei geschrieben und diese mit dem Debugger IDA eingelesen. So fand ich heraus, daß der "AutoIt-Assembler" keine Vorwärts-Sprünge beim LOOP-Befehl auflösen kann!
[autoit]
Das heisst,AsmAdd($Asm, " loop $+4" ) ;2C loop @start2
[/autoit]
AsmAdd($Asm, " jmp $+E" ) ;2E jmp @ende"
AsmAdd($Asm, "start2: ")funktioniert nicht!
Also habe ich die Zeilen mit
[autoit]AsmAdd($Asm, "dec ecx"); ;ecx = ecx -1
[/autoit]
AsmAdd($Asm, "jecxz $+F"); ;Jump to target , if ECX is Zeroangepasst, und nu gehts^^
Am meisten hat mich fasziniert, Programme direkt aus dem Speicher auszuführen. Man spart also den (im Vergleich zur Laufzeit der Funktion) extrem langsamen DLL-Aufruf. Ich habe leider von C nicht sonderlich viel Ahnung, vielleicht gäbe es eine Möglichkeit, "kompilierten" C-code direkt in den Speicher einzupflanzen (wie in meinem 1. Assemblerbeispiel). Dann bräuchte man die Umwege über den Assembler auch nicht mehr zu machen....
-
Hi,
Lockfile ist NICHT dazu da, um allen Programmen den Zugriff auf die gelockte Datei zu verwehren!Folgendes Script als LockFile1.exe kompilieren und starten, es legt eine Datei "Test.dat" an, bei der Teile der Datei gelockt werden. Trotzdem kann man mit z.B. Notepad die Datei ganz normal lesend öffnen!
Spoiler anzeigen
[autoit]#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
[/autoit] [autoit][/autoit] [autoit]
#AutoIt3Wrapper_outfile=lockfile1.exe
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <WinAPI.au3>$file = "test.dat"
[/autoit] [autoit][/autoit] [autoit]
$a = FileDelete($file)
FileWriteLine($file, "Zeile1") ;8 Zeichen
FileWriteLine($file, "Zeile2") ;8 Zeichen
FileWriteLine($file, "Zeile3") ;8 Zeichen$size = FileGetSize($file) ;dateigröße
[/autoit] [autoit][/autoit] [autoit]$hfile = _WinAPI_CreateFile($file, 2, 2, 2) ;bestehende öffnen, lesen, share=lesen
[/autoit] [autoit][/autoit] [autoit]$offset_low = 9 ;anfang lock
[/autoit] [autoit][/autoit] [autoit]
$offset_high = 0
$lenght_lock_low = 6 ;länge lock
$lenght_lock_high = 0$call = DllCall("Kernel32.dll", "bool", "LockFile", "hwnd", $hfile, "dword", $offset_low, "dword", $offset_high, "dword", $lenght_lock_low, "dword", $lenght_lock_high)
[/autoit] [autoit][/autoit] [autoit]
If @error Or (Not IsArray($call)) Then
MsgBox(0, 0, "Fehler beim Dateizugriff")
Else
If $call[0] <> 0 Then
MsgBox(0, "Erfolg= " & $call[0], "Datei(bereich) erfolgreich gelockt, filehandle=" & $call[1])
Else
MsgBox(0, "Erfolg= " & $call[0], "Fehler beim Dateizugriff, filehandle=" & $call[1])
EndIf
EndIfDo
[/autoit]
Until GUIGetMsg() = -3Nun einfach die LockFile1.exe nochmal starten, man bekommt eine Fehlermeldung (bezüglich LOCK), aber gleichzeitig das richtige Filehandle!
Nun folgendes Script starten um die gelockten Bereiche innerhalb der Datei anzuzeigen:
Spoiler anzeigen
[autoit]#include <WinAPI.au3>
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Local $nbytes, $string = "",$file = "test.dat"
[/autoit] [autoit][/autoit] [autoit]$hfile = _WinAPI_CreateFile($file, 2, 2, 2) ;bestehende Datei öffnen, lesen, share=lesen
[/autoit] [autoit][/autoit] [autoit]$size = FileGetSize($file) ;dateigröße
[/autoit] [autoit][/autoit] [autoit]$tBuffer = DllStructCreate("byte[1]") ;puffer für die zu lesenden Daten, hier zur einzelne Zeichen
[/autoit] [autoit][/autoit] [autoit]For $i = 0 To $size-1 ;alle Zeichen in der Datei
[/autoit] [autoit][/autoit] [autoit]_WinAPI_SetFilePointer($hfile, $i) ;Pointer auf Zeichen setzen
[/autoit] [autoit][/autoit] [autoit]
$erfolg = _WinAPI_ReadFile($hfile, DllStructGetPtr($tBuffer), 1, $nbytes) ;Zeichen lesenIf $erfolg Then
[/autoit] [autoit][/autoit] [autoit]
$sText = BinaryToString(DllStructGetData($tBuffer, 1)) ;Zeichen lesen
Else
$sText = "" ;kein Zeichen
EndIf$string &= "Position: " & $i & " lock= " & Not ($erfolg) & " Zeichen=" & $sText & @CRLF ;Ausgabestring
[/autoit] [autoit][/autoit] [autoit]Next
[/autoit] [autoit][/autoit] [autoit]
MsgBox(0, "Anzeige gelockter Zeichen", $string)_WinAPI_CloseHandle($hfile)
[/autoit]Man sieht, daß die gelockten Zeichen nicht zu lesen sind!
Nun im Script Lockfile1 die folgenden Zeilen austauschen und als Lockfile2.exe kompilieren und starten.
[autoit]$offset_low = 2 ;anfang lock
[/autoit]
$offset_high = 0
$lenght_lock_low = 3 ;länge lock
$lenght_lock_high = 0
In der Test.dat werden nun ZUSÄTZLICH die Zeichen von 2-5 gelockt. Das kann man mit Anzeigescript feststellen. Trotzdem kann Notepad alle Zeilen lesen!LockFile bringt also nur etwas, um z.B. bei einer Datenbankanwendung den Lesezugriff der Clients zu sperren, wenn in der offenen Datenbank Schreibzugriffe stattfinden.
Um die Test.dat auch wieder zu entlocken sollten nun genug Informationen da sein.

-
Hi zusammen,
da es ja auch zwei Möglichkeiten gibt, Assembler direkt in AutoIt einzubinden, war ich mal so frei und habe die freundlicherweise schon von RAPTOR-ONE im Assemblercode vorgestellte Fibonaccifunktion "AutoItkompatibel" gemacht.Die erste Variante benötigt keinerlei Includes, im Prinzip wird der Bytecode in den Speicher geschrieben und per Funktion dort aufgerufen. Man könnte das Script noch etwas "tunen", aber ich habe es der Übersichtlichkeit wegen so gemacht....
Die Zeiten sind kein Witz, ich vermute, daß die AutoIt-Timer einfach an die Grenzen kommen. Die Berechnung der Zahl (egal welche^^) erfolgt auf meinem Rechner in ca. zwei hundertstel Millisekunden
Da ist vom speed her nicht mehr viel zu verbessern denke ich
Spoiler anzeigen
[autoit];idea by trancexx
[/autoit] [autoit][/autoit] [autoit]
;Assemblerscript by RAPTOR-ONE
;binary translated and hardcoded by AndyLocal $tCodeBuffer = DllStructCreate("byte[512]") ;Speicher für den assemblercode belegen
[/autoit] [autoit][/autoit] [autoit]$g=0 ;timestamp merken
[/autoit] [autoit][/autoit] [autoit]
for $i=1 to 46 ;die Fibonaccizahlen von 1-46DllStructSetData($tCodeBuffer, 1, "0x558BECC7C1"& Hex(Binary($i))& _ ;bytecode "hardcoded"
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
"C7C001000000C7C30100000081F902000000761A81E90200000003C38BD02BD349E30D03C28BD82BDA67E2EEEB028BC15DC3")$t=timerinit() ;timestamp merken
[/autoit] [autoit][/autoit] [autoit]
$a= DllCall("user32.dll", "int", "CallWindowProcW", _ ;bytecode aufrufen, rückgabe in a[0]
"ptr", dllstructgetptr($tCodeBuffer), _
"int", 0, _
"int", 0, _
"int", 0, _
"int", 0)
$x=timerdiff($t)
$g+=$x
consolewrite ("Die "&$i&". Fibonaccizahl lautet "&$a[0] &" Berechnungszeit: "&$x & " ms"&@CRLF )
nextConsoleWrite( @CRLF & "Gesamtzeit: "&$g&" ms" & @CRLF )
[/autoit]Für die 2. Variante benötigt man die Asm.AU3
Der Inhalt kann nicht angezeigt werden, da er nicht mehr verfügbar ist.
Allerdings ist jetzt auch der Code wesentlich lesbarer. Da bei jedem Aufruf der Funktion der komplette Assembler gestartet werden muss, ist diese Variante nur sinnvoll, wenn es nicht auf die letzte hunderttausenstel Sekunde ankommt...
Ich habe die Mnemonics in Bytecode übersetzt, jetzt sieht man auch, woher der beim Beispiel 1 kommt^^Spoiler anzeigen
[autoit]#include <ASM.au3>
[/autoit] [autoit][/autoit] [autoit]Global $Asm = AsmInit() ;Assembler initialisieren
[/autoit] [autoit][/autoit] [autoit]
Local $g=0 ;gesamtzeitfor $i=1 to 45 ;Fibonaccizahlen von 1-45
[/autoit] [autoit][/autoit] [autoit]
$t=timerinit()
$a=fibonacci($i)
$x=timerdiff($t)
$g+=$x ;gesamtzeit
consolewrite ("Die "&$i&". Fibonaccizahl lautet "&$a &" Berechnungszeit: "&$x & " ms"&@CRLF )
nextConsoleWrite( @CRLF & "Gesamtzeit: "&$g&" ms" & @CRLF )
[/autoit] [autoit][/autoit] [autoit]AsmExit($Asm) ;asmobjekt freigeben
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
ExitFunc Fibonacci($fibo)
[/autoit] [autoit][/autoit] [autoit]
; Demo 1: Using Parameters
AsmReset($Asm)AsmAdd($Asm, "push ebp");55
[/autoit] [autoit][/autoit] [autoit]
AsmAdd($Asm, "mov ebp, esp");8B EC
AsmAdd($Asm, "mov ecx, [ebp + 08]");8B 8D XXXXXXXX ;übergebener parameter
AsmAdd($Asm, "mov eax, 1");C7 C0 01000000
AsmAdd($Asm, "mov ebx, 1");C7 C3 01000000
AsmAdd($Asm, "cmp ecx, 2");81 F9 02000000
AsmAdd($Asm, "jbe $+1C");76 1A ;jbe @ende
AsmAdd($Asm, "sub ecx, 2");81 E9 02000000
AsmAdd($Asm, "start:")
AsmAdd($Asm, "add eax, ebx");03 C3 ;// fn2(ax) = fn1(ax) + fn(bx)
AsmAdd($Asm, "mov edx, eax");8B D0 ;// fn2(cx) = fn2(ax)
AsmAdd($Asm, "sub edx, ebx");2B D3 ;// fn1(dx) = fn2(dx) - fn(bx)AsmAdd($Asm, "dec ecx"); ;loop @startx
[/autoit] [autoit][/autoit] [autoit]
AsmAdd($Asm, "jecxz $+F"); ;loop @startx
AsmAdd($Asm, "startx:")
AsmAdd($Asm, "add eax, edx");03 C2 ;// fn2(ax) = fn1(ax) + fn(dx)
AsmAdd($Asm, "mov ebx, eax");8B D8 ;// fn2(bx) = fn2(ax)
AsmAdd($Asm, "sub ebx, edx");2B DA ;// fn1(bx) = fn2(bx) - fn(dx)
AsmAdd($Asm, "loop @start");67 E2 EE
AsmAdd($Asm, "jmp $+4") ;EB 02 ;jmp @ende")
AsmAdd($Asm, "endek2:")
AsmAdd($Asm, "mov eax, ecx");8B C1
AsmAdd($Asm, "ende:")
AsmAdd($Asm, "pop ebp");5D
AsmAdd($Asm, "retn 4") ;C2 0400;ConsoleWrite(String(AsmGetBinary($Asm)) & @CRLF) ;zeigt den bytecode
[/autoit] [autoit][/autoit] [autoit]$Ret = MemoryFuncCall("int", AsmGetPtr($Asm), "int", $fibo)
[/autoit] [autoit][/autoit] [autoit][/autoit]
return $ret[0]
EndFunc -
DragnDrop wird bei AutoIt idR nur mit Dateinamen unterstützt. Um Text von einer in die andere Anwendung zu bringen muss man bissl improvisieren...
Rudimentäres Drag&Drop-Script für Text:
Adressen würde ich per *.csv (Kommasepariert) speichern, dann kannst du die so gut wie überall importierenSpoiler anzeigen
[autoit]#include <GUIConstantsEx.au3>
[/autoit] [autoit][/autoit] [autoit]
#include <Misc.au3>
#include <WindowsConstants.au3>$filename="adressdaten.csv"
[/autoit] [autoit][/autoit] [autoit]$gui = GUICreate("Adressen", 556, 300, 192, 124, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST, $WS_EX_WINDOWEDGE))
[/autoit] [autoit][/autoit] [autoit]
$Input1 = GUICtrlCreateInput("", 128, 24, 129, 21)
$Input2 = GUICtrlCreateInput("", 128, 64, 129, 21)
$Input3 = GUICtrlCreateInput("", 128, 104, 129, 21)
$Input4 = GUICtrlCreateInput("", 128, 144, 129, 21)
$Input5 = GUICtrlCreateInput("", 128, 184, 129, 21)
$Label1 = GUICtrlCreateLabel("Name", 16, 24, 56, 17)
$Label2 = GUICtrlCreateLabel("Vorname", 16, 64, 46, 17)
$Label3 = GUICtrlCreateLabel("Straße", 16, 104, 35, 17)
$Label4 = GUICtrlCreateLabel("PLZ", 16, 144, 24, 17)
$Label5 = GUICtrlCreateLabel("Ort", 16, 184, 18, 17)
$Label6 = GUICtrlCreateLabel("Mit der Maus Text markieren und per Drag/Drop in die Inputfelder ziehen ", 288, 24, 163, 57)
$button_save = GUICtrlCreateButton("Daten Speichern", 300, 80, 100, 40)GUISetState(@SW_SHOW)
[/autoit] [autoit][/autoit] [autoit]While 1
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
$msg=GUIGetMsg()
switch $msg
case -3 ;ende
Exit
case $button_save ;
_savedata()
endswitchIf _IsPressed(01) Then ;linke maustaste gedrückt
[/autoit] [autoit][/autoit] [autoit]
If WinActive("") <> $gui Then
ToolTip("Markieren und mit Drag&Drop ins Inputfeld ziehen")
Sleep(50)
Send("^{INS}") ;text kopieren
While _IsPressed(01) ;solange wie die Maus gedrückt ist ....
Sleep(10)
WEnd
Local $a = GUIGetCursorInfo($gui) ;mausposition der abfragen
Switch $a[4]
Case $Input1 To $Input5 ;wenn über einem input in der gui
MouseClick("left") ;focus Input
Send("^v") ;reinkopieren
EndSwitch
EndIf
EndIfWEnd
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]func _savedata()
[/autoit] [autoit][/autoit] [autoit]
local $data=""
for $i=1 to 5 ;alle inputfelder
$data&=GUICtrlRead(eval("input"&$i))&","
NextFilewriteline($filename,stringtrimright($data,1))
[/autoit]
endfunc -
Hallo Griesbrei,
in der Regel ist das hier kein "schreibt mir mal ein Script"-Forum. Wir geben sehr gerne Hilfestellung, auch absoluten Anfängern. Aus deinen bisherigen Postinngs konnte ich bisher herauslesen, daß du allerdings nicht die Absicht hast, in die Programmierung mit AutoIt einzusteigen. Macht nix, wenigstens hast du ordentlich gefragt^^Um die oben genannten Scripte laufen zu lassen, brauchst du eigentlich AutoIt als "Übersetzer". Aber um dir zu ersparen die komplette Entwicklungsumgebung zu installieren, hänge ich die schon fertig kompilierten Scripte als ausführbare Datei an. AUSNAHMSWEISE, denn kompilierte (ausführbare) Programme werden in diesem Forum normalerweise nicht angeboten!
Der Inhalt kann nicht angezeigt werden, da er nicht mehr verfügbar ist. Wenn du jetzt noch sagst, in welchem Stadion man dich hören kann, sind hoffentlich alle happy!
-
hast du die Funktion überhaupt mit den Parametern aufgerufen?
[autoit]_INetSmtpMailCom($s_FromAddress, $s_ToAddress, $s_SmtpServer, $s_Subject, $as_Body, $s_FromName = "", $s_Username = "", $s_Password = "", $s_AttachFiles = "", $s_CcAddress = "", $s_BccAddress = "", $s_Importance = "Normal", $IPPort = 25, $ssl = 0)
[/autoit] -
Hi,
nachdem du BugFix´ens Tutkomplett durchgearbeitet und VERINNERLICHT hast (einfach 2x durchlesen hilft leider nicht), finden sich alleine in Windows ca 40-50tausend Funktionen, die du damit bearbeiten kannst. Das meiste findet sich auf MSDN, aber lange nicht alles...
Ein Einstieg findet sich HIER
Um dir direkt die Illusion zu nehmen, das ist Lesestoff für JAHRE! Manchmal findet sich beim Stöbern die ein- oder andere nützliche Funktion, aber meistens (und das geht nicht nur mir so) ist es die Suche nach der Stecknadel im Heuhaufen. Oder man fragt jemanden anderen...
-
die komplette "Select"-Anweisung innerhalb der Funktion, also
[autoit]Select
[/autoit]
Case $iHuman > $iKI
$iWin = 1
Case $iHuman < $iKI
$iWin = -1
Case Else
$iWin = 0
EndSelectkann man auch mit einer Zeile
[autoit]$iwin=1-2*($iHuman < $iKI)-($iHuman = $iKI)
[/autoit]ersetzen...
-
Zitat
Einzeilige If-Anweisungen machen alles extrem langsam.
Bevor ich eine Switch und eine Select-Anweisung implementiere, ein Array dazu und reichlich Gehirnschmalz (hehe, denn das ist Voraussetzung), bleib ich bei meinen 3 Zeilen code

-
Hallo!
[autoit]
Wenn du jeden Ausdruck mit IF prüfst, brauchst du das ELSEIF nicht.
[/autoit]
If $playerHuman > $playerKI Then $Message = "Du hast gewonnen!"
If $playerHuman < $playerKI Then $Message = "Der Computer hat gewonnen!"
If $playerHuman = $playerKI Then $Message = "Unentschieden!" -
so gehts....
[autoit]
[/autoit][autoit][/autoit][autoit]
$file="datei.bat"$hfile=fileopen($file,1) ;Datei zum SCHREIBEN öffnen (lock)
[/autoit][autoit][/autoit][autoit]
Local $n = FileSetPos($hFile, 0, 0) ;pointer an den Anfang der Datei=0 oder an irgendeine Position innerhalb der datei$data=fileread($hfile) ;daten ab dem pointer lesen
[/autoit][autoit][/autoit][autoit]
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $data = ' & $data & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Consoledo
[/autoit][autoit][/autoit][autoit]
until guigetmsg()=-3fileclose($hfile)
[/autoit] -
Zitat
Aha Fileopen verwendet vermutlich die Funktion Fileopen
RISCHDIIIIISCH!^^
Man sollte testen ob in der "neuen" AutoIt-Version das Lesen/Schreiben-Flag von FileOpen() nicht schon die Datei lockt! Beim Schreiben ist die Datei m.W. schon von Windows aus für den Zugriff gesperrt....Workaround:
File locken, indem man sie mit fileopen($datei,1) öffnet. Datei "offen lassen"...
Wenn man Daten lesen möchte, Datei schließen und mit fileopen($datei,0) die Daten lesen, anschließend sofort wieder locken..../EDIT/ so ganz ist der Alzheimer noch nicht fortgeschritten^^ Ich wußte doch, da war was...
ZitatChanged: It is now possible to read from files opened for writing.
aus der History 3.3.2.0
Leider funktioniert das bei mir nicht, eine zum Schreiben geöffnete Datei verursacht beim Lesen einen Fehler... -
nuts
funktioniert so nicht, da der in der dll benötigte Filehandle nicht der ist, den AutoIt zurückgibt!
Beschreibung aus http://msdn.microsoft.com/en-us/library/aa365202(VS.85).aspx :ZitatThe file handle must have been created with the GENERIC_READ or GENERIC_WRITE access right.
Das heißt konkret, daß das Filehandle mit den anderen API-Funktionen (dll-Aufrufen) ermittelt werden muß. Habe hier zzt. nur Produktivmaschinen und
Was ich nicht verstehe ist, was an
[autoit]_WinAPI_CreateFile()
[/autoit]so kompliziert ist. Im Beispiel in der Hilfe sind mehrere Anwendungen zum Schreiben/Lesen/Bearbeiten der Datei aufgeführt. Und ob man mit Fileread/Filewrite oder mit den dort beschriebene Methoden macht ist doch egal...
-
Hi,
[autoit]
du kannst mit_WinAPI_CreateFile()
[/autoit]die Datei öffnen um sie exclusiv nur für dein script bearbeitbar zu machen.
[autoit]
also z.B.$hFile=_WinAPI_CreateFile("datei.dat",2 (datei öffnen), 2 (lesen erlauben) + 4 (schreiben erlauben))
[/autoit]s. auch Beispiel in der Hilfe
-
Feine Sache

Bekommt von mir auf der Suchtfaktorskala eine 9/10
Anzeigefehler habe ich jetzt keine festgestellt (XP) -
-
ups, hatte fehler in der formel...ist jetzt berichtigt
-
Hi,
zur Multiplikation großer Zahlen bietet sich die bigint.udf hier aus dem Forum an, war irgendwann in grauer Vorzeit Ziel eines µIt.Die Lösung für b^e mod m habe ich mal in eine Funktion gebracht:
Spoiler anzeigen
[autoit][/autoit] [autoit][/autoit] [autoit]$b=30
[/autoit] [autoit][/autoit] [autoit]
$e=23
$m=87$mod=_multiplemodulo($b,$e,$m) ;b^e mod m
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $mod = ' & $mod & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Consolefunc _multiplemodulo($base,$exp,$mod) ;b^e mod m
[/autoit] [autoit][/autoit] [autoit][/autoit]
$c=1
for $i=1 to $exp
$c=mod($c*$base,$mod)
next
return $c
endfunc -
Zitat
leider bekomme ich bei keiner ein vernünftiges ergebnis als ausgabe
Die Funktionen geben die Daten in einem Array zurück, was allerdings auch in den Beschreibungen/Funktionsheadern steht.
[autoit]
Beispiel zur Anzeige der Daten:
[/autoit]
$pfad=@scriptdir
$dateien = _RecursiveFileListToArray($pfad, '', 1)
_arraydisplay($dateien)