MCode tutorial

Hilfreiche Erklärungen und Tipps zum Lernen von Autohotkey

Moderator: jNizM

User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

MCode tutorial

03 Oct 2013, 10:01

Dies hier ist ein Tutorial nach dem ich selber gesucht hab.
Man braucht stunden um die Probleme zu entdecken und eine Lösung zu finden :shock:
Dies ist der Grund warum ich hier ein Tutorial machen werde, damit ihr alle wisst was MCode ist und es verstehen könnt. :D

Zuerst werde ich beschreiben was es ist und wofür man es nutzt
Danach sehen wir uns ein paar praktische Beispiele an.
Während wir dass machen werde ich euch über die Probleme von MCode erzählen. :shock:

1.Einführung:Was ist MCode?
MCode ist kompilierter Code. Zum Beispiel: wenn man ein C++ Programm schreibt wird diese art von Code automatisch erstellt.
AHK Scripts sind das genaue gegenteil von kompilierten Code. In einem AHK script schaut sich der Interpreter den momentanen Code an und führt danach den entsprechenden Code aus.
In einer Kompilierten Sprache wird solcher Code direkt produziert.
Die CPU ist dann direkt in der Lage diesen Code zu lesen.
MCode ist diese Art von Code innerhalb eines AHK scripts.
Man kann diesen Code per DllCall ausführen lassen.

z.B. der Beispiel Code des Compilers den ich benutze:
2,x86:aipYww==,x64:uCoAAADD
Dies ist eine Funktion die immer 42 zurückgeben wird (Die Antwort auf alle Fragen und alles.).

1. Einführung:Was kann man mit MCode besser machen als mit AHK?
MCode ist einer der vielen Wege um die Geschwindigkeit deines Scripts/Programms zu erhöhen.
Ganz besonders wenn man mit sehr vielen Daten arbeitet die verarbeitet werden müssen.
Z.B. kann man so Bild effekte für GDI+-Bilder schreiben.
MCode gibt dir ausserdem die Möglichkeit auf einem sehr niedrigen Level zu programmieren (Assembly).

1. Einführung:Hört sich gut an. Was sind die Voraussetzungen?
1. Wissen über C++ und DllCalls C++ and DllCalls:
Wenn du denkst du hast keine Ahnung von DllCalls dann kannst du es vergessen.
Man kann ein richtig gutes C++ tutorial hier finden (auf Englisch)
http://www.cplusplus.com/doc/tutorial/

2. Einen Compiler:
Den Compiler den ich benutze kann man hier finden:
http://bentschi.no-ip.org/mcode/

Ich werde jeden Vorschlag hinzufügen.


3. Eine MCode Funktion:
Ich benutze diese:

Code: Select all

MCode(mcode)
{
  static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
  if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
    return
  if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
    return
  p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
  if (c="x64")
    DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
  if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
    return p
  DllCall("GlobalFree", "ptr", p)
}
Recommends AHK Studio
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: MCode tutorial

03 Oct 2013, 10:08

2. Beispiele
Nachdem du die Funktion zu deinem stdlib Ordner hinzugefügt hast kannst du anfangen die ersten Funktionen zu Programmieren.
Der Beispiel Code des Compilers ist dieser:

Code: Select all

int MyFunction()
{
  return 42;
}
Wie ich bereits gesagt habe gibt die Funktion immer nur 42 zurück.
Wenn man nun den Create Machine Code Button drückt wird MCode wie dieser entstehen:

Code: Select all

MyFunction := MCode("2,x86:uCoAAADD,x64:uCoAAADD")
Du kannst diesen Code zu deinem Script hinzufügen:
Benutz DllCall um die Funktion auszuführen.

Code: Select all

MyFunction := MCode("2,x86:uCoAAADD,x64:uCoAAADD")
Msgbox % DllCall(MyFunction,"cdecl")
Man muss die cdecl Aufrufsonvention verwenden da diese standard bei C++ ist.

Jetzt aber mal eine Kompliziertere Funktion
Sie sucht nach dem Ende eines Strings: Dem 0-Zeichen:

Code: Select all

int stringlen(char *str)
{
  int i=0;
  for (; str[i]!=0; i++);
  return i;
}
Das Ergebnis ist der folgende Code:

Code: Select all

stringlen := MCode("2,x86:i0wkBDPAOAF0B0CAPAgAdfnD,x64:M8A4AXQKSP/B/8CAOQB19vPD")
MsgBox, % DllCall(stringlen, "astr", "test","cdecl")
Jetzt eine noch kompliziertere Funktion:

Code: Select all

unsigned int MyFunction(unsigned int a,unsigned int b)
{
if (a>0)  
return MyFunction(a-1,b*a);
else
return b;
}
Diese Funktion berechnet die Fakultät der Nummer a.
Um dies zu erreichen ruft sich die Funktion immer wieder selber auf.
Jetzt der AHK Code:

Code: Select all

MyFunction := MCode("2,x86:i0wkBItEJAiFyXQKjWQkAA+vwUl1+sM=,x64:hcl0Bw+v0f/JdfmLwsM=")
Msgbox % DllCall(MyFunction,"int",3,"int",1,"cdecl")
Das Ergebnis von 3 Fakultät ist 6 wie erwatrtet.

Aber man muss zuviel tippen. Eigentlich braucht man diesen Teil garnicht: ,"int",1,"cdecl") Wir können uns ja mal in MCode eine Caller funktion schreiben die diesen Teil übernimmt.
Um die stdcall Konvention zu benutzen (Welche die standart Konvention für DllCall ist) muss man ein _stdcall vor der Funktion schreiben
Danach wird der code so aussehen:

Code: Select all

unsigned int MyFunction(unsigned int a,unsigned int b)
{
if (a>0)  
return MyFunction(a-1,b*a);
else
return b;
}

unsigned int _stdcall MyFunctionCaller(unsigned int a)
{
return MyFunction(a,1);
}
Compiliert ist es das folgende:

Code: Select all

MyFunction := MCode("2,x86:i0wkBItEJAiFyXQKjWQkAA+vwUl1+sM=,x64:hcl0Bw+v0f/JdfmLwsM=")
MyFunctionCaller := MCode("
(LTrim Join
2,x86:i0QkBIXAdA5QSFDoAAAAAIPECMIEALgBAAAAwgQA,x64:i9GFyXQH/8npAAAAALgBAAAAww==
)")
Msgbox % DllCall(MyFunctionCaller,"uint",3)
Aber die Messagebox ist leer. :o
Nein wir haben keinen Fehler gemacht. Das Problem heißt MCode:
OK Stellen wir uns vor du hättest ein AHK script, musst aber alle funktionen über ihre Position aufrufen: (e.g. call Zeichen nr. 144.).
Hier startet deine Funktion: bei Zeichen 144.
Jetzt stellen wir uns vor was passieren würde wenn man vor Zeichen 144 noch mehr Zeichen hinzufügt:
Deine Funktion würde sich nach hinten verschieben z.B. um 20 Zeichen.
Wenn man nicht die start zeichen nummer der Funktion ändert wird man ein anderes Ergebnis haben als das erwartete Ergebnis.
Funktions aufrufe in kompiliertem C++ sind ähnlich:
Eine Funktion wird aufgerufen in dem man die Startadresse des Speicherbereichs angibt in dem die Funtkion liegt.
Aber die Funktion wird erst hinzugefügt nach dem ganzen AHK Zeug hinzugefügt.
D.h. ruft man etwas völlig anderes auf, was dann auch zu Fehlern führt.
Du kannst dir auch die Addresse anzeigen lassen die der Compiler erwartet hat:
(Note: Nicht für 64 bit PCs)

Code: Select all

/*
unsigned int MyFunction(unsigned int a,unsigned int b)
{
if (a>0)  
return MyFunction(a-1,b*a);
else
return b;
}
unsigned int MyFunctionaddress()
{
return (unsigned int)(&MyFunction);
}
*/
MyFunction := MCode("2,x86:i0wkBItEJAiFyXQKjWQkAA+vwUl1+sM=,x64:hcl0Bw+v0f/JdfmLwsM=")
MyFunctionaddress := MCode("2,x86:uAAAAADD,x64:SI0FAAAAAMM=")
Msgbox % "The expected Address of the function is :" DllCall(MyFunctionaddress)
Msgbox % "The actual address of the function is :" MyFunction
Also kann man auf normalen Wege keine Funktionen aufrufen :evil:
Also was machen wir jetzt :?:
Die Antwort ist Funktionspointer. :!:...:?:
Funktionspointer sind hier Dokumentiert:
http://www.cplusplus.com/doc/tutorial/pointers/
Bitte lest es euch durch bevor ihr weiterlest.

Um unsere Funktion in MCode also ordentlich aufzurufen müssen wir den Pointer zu der Startadresse an die aufrufende Funktion übergeben:

Code: Select all

unsigned int MyFunction(unsigned int a,unsigned int b)
{
if (a>0)  
return MyFunction(a-1,b*a);
else
return b;
}

unsigned int _stdcall MyFunctionCaller(unsigned int a,unsigned int(*MyFunction)(unsigned int,unsigned int) )
{
return (*MyFunction)(a,1);
}
Results in:

Code: Select all

MyFunction := MCode("2,x86:i0wkBItEJAiFyXQKjWQkAA+vwUl1+sM=,x64:hcl0Bw+v0f/JdfmLwsM=")
MyFunctionCaller := MCode("2,x86:i0QkBGoBUP9UJBCDxAjCCAA=,x64:SIvCugEAAABI/+A=")
Wenn wir die neue Funktion jetzt aufrufen müssen wir als zusätzlichen Parameter den Funktionspointer übergeben.

Code: Select all

MyFunction := MCode("2,x86:i0wkBItEJAiFyXQKjWQkAA+vwUl1+sM=,x64:hcl0Bw+v0f/JdfmLwsM=")
MyFunctionCaller := MCode("2,x86:i0QkBGoBUP9UJBCDxAjCCAA=,x64:SIvCugEAAABI/+A=")
Msgbox % DllCall(MyFunctionCaller,"uint", 3,"UPtr",MyFunction)
MyFunction enthält exakt diesen Wert.
Und jetzt gibt die Message box auch den richtigen Wert zurück.

Ausserdem gibt es andere Dinge die in MCode nicht funktionieren werden:
  1. Statische Variablen
  2. Und Objekt Funktionen aufrufen(thiscall konvention)
  3. Manchmal auch der aufruf der eigenen Funktion
  4. Auch vorher festhelegte Floats können Probleme verursachen, da sie eher an einer bestimmten adresse gespeichert, als im code gespeichert werden.
3. Wie erstelle ich einen MCode generator?
MCode also Machine Code ist an sich nichts anderes als eine compilierte Funktion. Bei .exe sowie .dll Dateien findet man meistens jede Menge Zusatzinfos wie z.B. wo die Funtionen starten ihre Namen Querverweise etc..
Beim MCode fehlen diese Infos aber völlig. Es sind wirklich nur Instruktionen die vom Prozessor direkt ausgeführt werden. Daher auch die oben genannten Limitationen.
Um aus normalen Code zu erhalten gibt es verschiedenste Vorgehensweisen. Was sie alle verbindet ist der Fakt, dass man einen Compiler braucht, welcher einem die Instruktionen erstellt.
Abhängig vom Compiler geht dies auf Unterschiedlichem Wege:

Für C++:
gcc/MS_VS:
Die beiden bekanntesten Compiler für C/C++ sind garantiert der Microsoft Visual Studio Compiler und die kostenfreie, aber nicht schlechtere, Alternative dem GNU compiler.
Bei beiden kann man netter Weise eine ähnliche Vorgehensweise. Man kann diese garantiert für viele Compiler benutzen.
Man sagt dafür dem compiler über eine Flag (die ich grade nicht parat habe), dass er ein sogenanntes Assembly listing erzeugen soll.
Dabei entsteht eine Datei welche die Assembly Instruktionen, ihr Offset, den Namen eines Labels, sowie ihre Übersetzung im Binärcode der CPU im Hexadezimalformat enthält.
Das Offset ist für uns unwichtig. Die Assembly Instruktion im Textformat auch. Was wir brauchen sind die Labels sowie der Binärcode.
Die Labels markieren den Anfang sowie das Ende einer Funktion. So findet man ein Label, welches den Namen einer Funktion die wir aus dem Listing extrahieren wollen enthält.
Alle Instruktionen von diesem Label bis zum nächsten Label gehören zu unserer Funktion.
Wir müsen nun nur noch alle Binärcodes der Instruktionen unserer Funktion auslesen und wir haben die Daten die wir benötigen um den MCode dieser Funktion zu erzeugen.
Dazu müssen wir dann den Hexadezimalcode zusammenfügen und mit einer Funktion dafür sorgen ,dass er geladen wird.
Recommends AHK Studio
User avatar
joedf
Posts: 8937
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: MCode tutorial

02 Dec 2013, 15:20

ich find das interessant dass, du hast mehr auf deutsch geschrieben als in der Englischer version... ;)
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: MCode tutorial

02 Dec 2013, 15:23

Im Englischen Teil habe ich genau so viel geschrieben.
Den Post hab ich bloß versehentlich gelöscht.
Recommends AHK Studio
User avatar
joedf
Posts: 8937
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: MCode tutorial

02 Dec 2013, 16:26

Ahh... :P
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: MCode tutorial

07 Mar 2014, 02:29

http://bentschi.no-ip.org/mcode/ ist down...
haben wir eine alternative die online ist?
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: MCode tutorial

07 Mar 2014, 04:02

Nein die gibt es leider nicht.
Ich selber hab es noch nicht hin bekommen, dass Micro$ VC++ es in 64 bit kompiliert.
Ich habe mir die SDKs runtergeladen so wie M$ es mir gesagt hat, konnte danach jedoch immer noch nicht in 64 bit kompilieren.
Recommends AHK Studio
User avatar
joedf
Posts: 8937
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: MCode tutorial

07 Mar 2014, 18:30

ist da ein weg wo ich kann das mit GCC machen? oder mit Win7 SDK?
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: MCode tutorial

08 Mar 2014, 02:39

Ja sowas lässt sich auch damit machen .
Generell mit jedem Compiler der ein Assembly Listing ausgeben kann.
Aus diesen Assembly Listing werden dann die benötigten Informationen ausgelesen.
Recommends AHK Studio
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: MCode tutorial

21 Oct 2014, 01:44

Habt ihr euch mal angeschaut wie die von AutoIt das ganze bewerkstelligen?

Beispiele:
MD5,SHA1,CRC32,RC4,BASE64,XXTEA machine code version
AutoIt Machine Code Algorithm Collection
BinaryCall UDF - Write Subroutines In C, Call In AutoIt
The Embedded Flat Assembler (FASM) UDF
AutoIt Inline Assembly UDF
Embed DLLs in script and call functions from memory

Vlt ist ja was interessantes für euch dabei um es für AutoHotkey zur Verfügung zu stellen.
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: MCode tutorial

14 Oct 2015, 09:19

Is Bentschi noch erreichbar oder hast du den Online-Kompiler zum Laufen gebracht nnnik?
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: MCode tutorial

15 Oct 2015, 02:29

Ich weiß nicht wie es mit Bentschi aussieht, aber das ganze ist auf einem privaten Rechner über ein DDNS Verweis gehostet.
Es kann sein, dass er einfach persöhnliche Gründe hatte es abzustellen.

Ich persöhnlich habe Probleme ein ddns einzurichten und auch Probleme damit MS_VS auf 64 bit umzustellen.
Jedoch könnten wir eventuell nachfragen ob wir eine Weiterleitung über ahkscript.org oder Autohotkey.com bekommen wir müssten uns bloß einen ersatz compiler für MS_VS suchen und den dann bei irgendwem installieren.
Recommends AHK Studio
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: MCode tutorial

04 Nov 2015, 04:03

Kannst du dann wenigstens hinzufügen wie man von einem C++ Code auf den MCode kommt?
Vielleicht anhand des aktuellen Visual Studios (z.B. Visual Studio Community 2013 / 2015*)

*kostenlos
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: MCode tutorial

04 Nov 2015, 10:48

Ja kann ich machen.
Recommends AHK Studio
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: MCode tutorial

05 Nov 2015, 01:58

Wäre cool, danke =)
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: MCode tutorial

15 Nov 2015, 05:45

Hab ich hinzugefügt.
Recommends AHK Studio
just me
Posts: 9406
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: MCode tutorial

15 Nov 2015, 16:28

nnnik wrote:Man sagt dafür dem compiler über eine Flag (die ich grade nicht parat habe), dass er ein sogenanntes Assembly listing erzeugen soll.
Würdest Du bitte noch einmal versuchen, Dich zu erinnern?
nnnik wrote:Das Offset ist für uns unwichtig. Die Assembly Instruktion im Textformat auch. Was wir brauchen sind die Labels sowie der Binärcode.
Könntest Du dafür als Beispiel einen Auszug aus einem Listing posten?
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: MCode tutorial

28 Jan 2016, 05:06

Hier tut sich nichts mehr?
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: MCode tutorial

28 Jan 2016, 14:32

Nein ehrlich gesagt nichts mehr.
Ich habe die flag zwar schon rausgesucht, aber kann keinen File mehr generieren, da ich kein Visual C++ habe.
https://msdn.microsoft.com/en-us/library/367y26c6.aspx
Recommends AHK Studio
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: MCode tutorial

16 Jun 2017, 02:28

Huhu nnnik...
gibt es irgendwelche updates?

Vlt. ne Bilderstrecke oder ein kleines yt-video das zeigt wie ich von c++ code (VS) zu meinem generierten mcode komme?

Wie muss ich (z.B.) MinGW einrichten damit ich mcode generieren kann?

Würde gerne damit mal ein bisschen testen und rumspielen.

Alternativ ein ahk-script, dass wie Wege von einer cpp datei in mcode übernimmt?
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile

Return to “Tutorials”

Who is online

Users browsing this forum: No registered users and 16 guests