MCode4GCC -- C/C++ to MCode Generator

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
joedf
Posts: 8940
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

MCode4GCC -- C/C++ to MCode Generator

20 Sep 2014, 21:09

MCode4GCC

MCode4GCC is an MCode generator using the GCC Compiler.
More about MCode here : http://ahkscript.org/boards/viewtopic.php?f=7&t=32
Info & downloads here: https://github.com/joedf/MCode4GCC

Image

Questions?
Don't be shy to post your questions. Just ask away!

Credits
Special thanks to IsNull, fincs, Laszlo, SKAN, Bentschi and kon
Written by joedf ([email protected])
Released under the [MIT License](http://opensource.org/licenses/MIT)

Information and Downloads here : https://github.com/joedf/MCode4GCC
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]
Elduke

Re: MCode4GCC -- C/C++ to MCode Generator

24 Oct 2014, 13:49

dumb question... is visual c++ needed?
kon
Posts: 1756
Joined: 29 Sep 2013, 17:11

Re: MCode4GCC -- C/C++ to MCode Generator

24 Oct 2014, 14:07

Elduke wrote:dumb question... is visual c++ needed?
Nope! :D
GCC is an open source compiler. You just need GCC and an editor of your choosing.
Setting Up GCC on this script's GitHub page lists some of the recommended distributions.
User avatar
fincs
Posts: 527
Joined: 30 Sep 2013, 14:17
Location: Seville, Spain
Contact:

Re: MCode4GCC -- C/C++ to MCode Generator

24 Oct 2014, 15:36

I use TDM-GCC. The 'normal' one just loves to link in dependencies to all sorts of hefty runtime DLLs.
fincs
Windows 11 Pro (Version 22H2) | AMD Ryzen 7 3700X with 32 GB of RAM | AutoHotkey v2.0.0 + v1.1.36.02
Get SciTE4AutoHotkey v3.1.0 - [My project list]
User avatar
Relayer
Posts: 160
Joined: 30 Sep 2013, 13:09
Location: Delaware, USA

Re: MCode4GCC -- C/C++ to MCode Generator

24 Oct 2014, 15:42

Is there a repository of MCode functions with docs? I'd be interested in previous work since I'm not that proficient at writing my own C code.

Relayer
Sam_
Posts: 146
Joined: 20 Mar 2014, 20:24

Re: MCode4GCC -- C/C++ to MCode Generator

14 Nov 2014, 20:24

I'm not a c++ programmer, but there are a couple MCode functions from the old forum that I need x64 version for, so I decided to give this a try. I think I got everything set up correctly as I successfully got the test TheAnswerToEverything() function to compile to MCode. I added it as a function in my script and it works. Now I try compiling the Bin2Hex and Hex2Bin functions, and I am getting errors like:
SOURCEFILE:1:14: error: unknown type name 'UInt8'
void Bin2Hex(UInt8 *hex, UInt8 *bin, Int32 len) { // in hex room for 2*len+1 bytes
^
SOURCEFILE:1:26: error: unknown type name 'UInt8'
void Bin2Hex(UInt8 *hex, UInt8 *bin, Int32 len) { // in hex room for 2*len+1 bytes
^
SOURCEFILE:1:38: error: unknown type name 'Int32'
void Bin2Hex(UInt8 *hex, UInt8 *bin, Int32 len) { // in hex room for 2*len+1 bytes
^
What is happening here? Do I need to adjust the jargon of the data types or something?

For convenience, these are the two functions I need MCode for:

Code: Select all

void Bin2Hex(UInt8 *hex, UInt8 *bin, Int32 len) { // in hex room for 2*len+1 bytes
   Int32 i; UInt8 c, d;
   for (i=0; i<len; ++i) {
        c = *(bin++);
        d = c >> 4;
        *(hex++) = d+48 + (7 & -(d>9));
        d = c & 15;
        *(hex++) = d+48 + (7 & -(d>9));
    }
    *hex = 0;
}

void Hex2Bin(UInt8 *bin, UInt8 *hex) { // in bin room for ceil(strlen(hex)/2) bytes 
   UInt8 b, c, d;
   for(;;) {
      c = *hex++; if (c == 0) break;
      b = c >> 6;
      *bin = ((c & 15) + b + (b << 3)) << 4;
      d = *hex++; if (d == 0) break;
      b = d >> 6;
      *bin++ |= (d & 15) + b + (b << 3);
   }
Sam_
Posts: 146
Joined: 20 Mar 2014, 20:24

Re: MCode4GCC -- C/C++ to MCode Generator

18 Nov 2014, 04:37

Thank you both! I have now gotten both functions to compile nicely, and everything works great in the ANSI build of AHK_L, less so in the Unicode builds. Here is my original test script:

Code: Select all

GenerateMCodeFunctions()
data:=""
HexRead(A_ScriptFullPath,data,4,0)
	MsgBox "%data%"
HexWrite(A_ScriptDir "\!HexWrite.bin",data,4,0)
	MsgBox "%data%"
ExitApp


GenerateMCodeFunctions(){
	Global
	_Bin2Hex:=MCode("2,x86:VVdWU4tEJByLbCQUi1QkGIXAflGLfCQciekB1410JgCDwgEPtkL/icPA6wSA+wmJ3g+Xw4PgD/fbg8ECg+MHjVweMIhZ/jwJicMPl8D32IPgBzn6jUQDMIhB/3XDi0QkHI1sRQDGRQAAW15fXcOQkA==,x64:U0iD7EAPKTQkDyl8JBBEDylEJCBEDylMJDBFhcAPjpwBAABJY8BMjQxBTDnKQQ+TwUgB0Eg5wQ+TwEEIwQ+EnQEAAEGD+A8PhpMBAABFicFmD+/JQcHpBGYPbz0AAAAARYnKMcBFMdtmD281EAAAAEHB4gRmD28tIAAAAGYPbyUwAAAAZkQPbwVAAAAA8w9vFAJBg8MBZg9v2mYPYNlmD2/DZg9v2mZBD9vQZg9x0ARmRA9vyGYPaNlmD3HTBGZED2jLZg9gw2YPb9hmQQ9gwWZBD2jZZkQPb8hmD2DDZkQPaMtmQQ9gwWZED2/JZg9v2GYP2MZmD3TBZg/832YP38VmRA/4yGZBD2/BZkQPb8lmD9vEZg/82GYPb8JmD/zXZg/YxmYPdMFmD9/FZkQP+MhmQQ9vwWYP28RmD/zQZg9vw2YPaNpmD2DC8w9/XEEQ8w9/BEFIg8AQRTnLD4Ir////RYnTTo0MWUkB00U50HRFSYPDAUEPtkP/icPA6wSA+wkPl8KD4A9Jg8EC99qD4geNVBMwQYhR/jwJicIPl8BBg8IB99iD4AdFOdCNRAIwQYhB/3+7QY1Y/0iNTFkCxgEADyg0JA8ofCQQRA8oRCQgRA8oTCQwSIPEQFvDDx8AQY1Y/0mJyYnYTI1cAgFmkEiDwgFED7ZS/0SJ0MDoBDwJQQ+XwEGD4g9Jg8ECQffYQYPgB0KNRAAwQYhB/kGA+gkPl8D32IPgB0w52kGNRAIwQYhB/3W564GQkJCQkJCQMDAwMDAwMDAwMDAwMDAwMAkJCQkJCQkJCQkJCQkJCQkBAQEBAQEBAQEBAQEBAQEBBwcHBwcHBwcHBwcHBwcHBw8PDw8PDw8PDw8PDw8PDw8=")
	_Hex2Bin:=MCode("2,x86:V1ZTi0wkFIt8JBAPthmE23RaidiD4w/A6AYBw40Ew8HgBIgHjVkCD7ZJAYTJdR/rO4nIg+EPwOgGg8MCAcGNBMHB4ASIBw+2S/+EyXQeicqD4Q/A6gaDxwGJ1gHxjQzxCcGIT/8PtguEyXXFW15fww==,x64:RA+2AkWEwHRtRYnBQYPgD0HA6QZDjQQBTI1CAkKNBMjB4ASIAQ+2UgGE0nUn60mQQYnRg+IPSYPAAkHA6QZCjQQKQo0EyMHgBIgBQQ+2UP+E0nQiQYnRg+IPSIPBAUHA6QZEAcpCjRTKCcKIUf9BD7YQhNJ1uvPD88OQkJCQkJA=")
}

HexRead(file,ByRef data,n=0,offset=0){
	close:="", bin:=""
	If !IsObject(file){
		close:=1
		file:=FileOpen(file,"r-d")
		}
	file.Seek(offset)
	If (n=0)
		n:=file.Length	; If n=0 then all bytes will be read!!!
	NumRead:=file.RawRead(bin,n)
	Bin2Hex(data,&bin,NumRead)
	If (close=1)
		file.Close()
	Return NumRead
}

HexWrite(file,ByRef data,n=0,offset=0){
	close:="", bin:=""
	Hex2Bin(bin,data)
	If !IsObject(file){
		close:=1
		file:=FileOpen(file,"w-d")
		}
	file.Seek(offset)
	NumWritten:=file.RawWrite(bin,n)	; If n=0 then no bytes will be written!!!
	If (close=1)
		file.Close()
	Return NumWritten
}

Bin2Hex(ByRef hex,addr,len){
	VarSetCapacity(hex,(2*len+1))
	Global _Bin2Hex
	DllCall(_Bin2Hex,"UInt",&hex,"UInt",addr,"UInt",len,"CDECL")
	Return VarSetCapacity(hex,-1)//2
}

Hex2Bin(ByRef bin,ByRef hex){
	VarSetCapacity(bin,0)
	VarSetCapacity(bin,(StrLen(hex)+1)//2)
	Global _Hex2Bin
	DllCall(_Hex2Bin,"UInt",&bin,"UInt",&hex,"CDECL")
	Return (StrLen(hex)+1)//2
}

MCode(mcode){
	Static e:={1:4, 2:1}, c:=(A_PtrSize=8)?"x64":"x86"
	s:="", op:=""
	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)
}
Notice that it works as expected in the ANSI build of AHK_L, but the hex data is not displayed properly in Unicode builds. This can be remedied by:

Code: Select all

Bin2Hex(ByRef hex,addr,len){
	VarSetCapacity(hex,(2*len+1)*(A_IsUnicode?2:1))
	Global _Bin2Hex
	DllCall(_Bin2Hex,"UInt",&hex,"UInt",addr,"UInt",len,"CDECL")
	If (A_IsUnicode=1)
		hex:=StrGet(&hex,len*(A_IsUnicode?2:1),"cp0") ; Without this, it only works properly in the AHK_L ANSI build
	Return VarSetCapacity(hex,-1)//2
}
But now the hex data is not properly converted back to binary (in Unicode builds of AHK_L) and so is not written back to the file properly. My problem is I can't figure out how to undo the codepage manipulation:

Code: Select all

Hex2Bin(ByRef bin,ByRef hex){
	VarSetCapacity(bin,0)
	;~ VarSetCapacity(bin,((StrLen(hex)+1)//2)/(A_IsUnicode?2:1))
	VarSetCapacity(bin,(StrLen(hex)+1)//2)
	If (A_IsUnicode=1){
		; Some way to undo the Unicode compatability stuff
		}
	Global _Hex2Bin
	DllCall(_Hex2Bin,"UInt",&bin,"UInt",&hex,"CDECL")
	Return (StrLen(hex)+1)//2
}
I apologize if this is straying too far off topic, but if anyone can help me out, I'd really appreciate it!
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: MCode4GCC -- C/C++ to MCode Generator

21 Nov 2014, 02:43

TDM-GCC wrote:>>>>> USAGE NOTES

*** 32-bit or 64-bit compilation ***

In this edition of TDM-GCC, you can use "-m32" and "-m64" to control whether
32-bit or 64-bit binaries are generated. By default (if neither -m32 nor -m64 is
specified), 64-bit binaries will be generated. In a 64-bit binary, all pointer
math is 64-bit by default, and the built-in "size_t" and "ptrdiff_t" types are
64 bits in size (some other types are larger also). Additionally, the following
preprocessor definitions will be in effect:
* #define _WIN64 1 (also WIN64, __WIN64, and __WIN64__)
* #define __MINGW64__ 1
* #define __x86_64 1 (also __x86_64__)
* #define __amd64 1 (also __amd64__)
Be sure to use "-m32" or "-m64" at both the compile stage and the link stage.
Just saying :)
Recommends AHK Studio
sancarn
Posts: 224
Joined: 01 Mar 2016, 14:52

Re: MCode4GCC -- C/C++ to MCode Generator

08 Aug 2017, 04:05

I'm not certain how this works but it might be nice if it were to optionally use an online compiler like e.g. I have a compile-and-execute script here for C code.

This means you wouldn't have to download and install a compiler. Which is nice because in some cases (like the office) people cannot easily install software.

...Some time later...

Actually, after some investigating I made another AHK Script which compiles the code and downloads the file (because it seems you use the file in your code). See Github
User avatar
joedf
Posts: 8940
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: MCode4GCC -- C/C++ to MCode Generator

08 Aug 2017, 09:24

I guess you could but you don't really want to "compile" it per se. You want the assembly w/ opcodes which is done with "-Wa,-aln"... You would need something like objdump or another decompiler/disassembler.
I saw this https://github.com/yegord/snowman
but opcodes are not given :/
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]
sancarn
Posts: 224
Joined: 01 Mar 2016, 14:52

Re: MCode4GCC -- C/C++ to MCode Generator

08 Aug 2017, 10:13

joedf wrote:I guess you could but you don't really want to "compile" it per se. You want the assembly w/ opcodes which is done with "-Wa,-aln"... You would need something like objdump or another decompiler/disassembler.
I saw this https://github.com/yegord/snowman
but opcodes are not given :/
Ah... Would this do the trick?
User avatar
joedf
Posts: 8940
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: MCode4GCC -- C/C++ to MCode Generator

08 Aug 2017, 10:52

I saw this also... it crases sometimes.. :/ http://www.backerstreet.com/rec/rec.htm
The website you gave could work, I saw there's a button to show the opcodes.
It seems it can be extracted as something like this <div class="opcodes" title="ff 25 02 0c 20 00">
For the example you gave me, I got this:

Code: Select all

<div class="opcodes" title="ff 25 02 0c 20 00">
<div class="opcodes" title="66 90">
<div class="opcodes" title="55">
<div class="opcodes" title="48 89 e5">
<div class="opcodes" title="89 7d fc">
<div class="opcodes" title="8b 45 fc">
<div class="opcodes" title="0f af 45 fc">
<div class="opcodes" title="5d">
<div class="opcodes" title="c3">
<div class="opcodes" title="55">
<div class="opcodes" title="48 89 e5">
<div class="opcodes" title="b8 00 00 00 00">
<div class="opcodes" title="5d">
<div class="opcodes" title="c3">
<div class="opcodes" title="66 2e 0f 1f 84 00 00 00 00 00">
which simplified gives this
ff25020c20006690554889e5897dfc8b45fc0faf45fc5dc3554889e5b8000000005dc3662e0f1f840000000000
Could not get it to work :/
even with the junk removed 554889e5897dfc8b45fc0faf45fc5dc3 to VUiJ5Yl9/ItF/A+vRfxdww==...

So I tried the compiler with a return 42 function (from the tutorial https://autohotkey.com/boards/viewtopic.php?f=7&t=32):

Code: Select all

int MyFunction()
{
  return 42;
}
554889e5b82a0000005dc3554889e5b8000000005dc30f1f00 becomes VUiJ5bgqAAAAXcNVSInluAAAAABdww8fAA==
junk removed
554889e5b82a0000005dc3 becomes VUiJ5bgqAAAAXcM=
works well...
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
joedf
Posts: 8940
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: MCode4GCC -- C/C++ to MCode Generator

08 Aug 2017, 10:57

it could work, but this is wayyy out there...
If you're doing mcode, I strongly recommend doing it on a pc where you have more control.
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]
sancarn
Posts: 224
Joined: 01 Mar 2016, 14:52

Re: MCode4GCC -- C/C++ to MCode Generator

08 Aug 2017, 11:12

joedf wrote:it could work, but this is wayyy out there...
If you're doing mcode, I strongly recommend doing it on a pc where you have more control.
Out there? Out where? :P

But quite it is a 'round-about' way to do it. And I do agree that using a web compiler does lose control, but it'd be a nice option, imo (in the sense that it's better than nothing). I will try to integrate this into the compiler. If I can't, alas. :P

Edit, Via HTTP requests we get the following data:

Code: Select all

{
  "code": 0,
  "stdout": [
    
  ],
  "stderr": [
    
  ],
  "okToCache": true,
  "hasOptOutput": false,
  "asm": [
    {
      "text": ".plt.got:",
      "source": null
    },
    {
      "opcodes": ["ff","25","02","0c","20","00"],
      "address": 4195312,
      "text": " jmp QWORD PTR [rip+0x200c02] # 600ff8 <_DYNAMIC+0x200>",
      "source": null,
      "links": [
        {
          "offset": 32,
          "length": 6,
          "to": 6295544
        }
      ]
    },
    {
      "opcodes": ["66","90"],
      "address": 4195318,
      "text": " xchg ax,ax",
      "source": null,
      "links": null
    },
    {
      "text": "square(int):",
      "source": null
    },
    {
      "opcodes": ["55"],
	  "address": 4195543,
      "text": " push rbp",
      "source": 2,
      "links": null
    },
    {
      "opcodes": ["48","89","e5"],
      "address": 4195544,
      "text": " mov rbp,rsp",
      "source": 2,
      "links": null
    },
    {
      "opcodes": ["89","7d","fc"],
      "address": 4195547,
      "text": " mov DWORD PTR [rbp-0x4],edi",
      "source": 2,
      "links": null
    },
    {
      "opcodes": ["83","45","fc","01"],
      "address": 4195550,
      "text": " add DWORD PTR [rbp-0x4],0x1",
      "source": 3,
      "links": null
    },
    {
      "opcodes": ["8b","45","fc"],
      "address": 4195554,
      "text": " mov eax,DWORD PTR [rbp-0x4]",
      "source": 4,
      "links": null
    },
    {
      "opcodes": ["0f","af","45","fc"],
      "address": 4195557,
      "text": " imul eax,DWORD PTR [rbp-0x4]",
      "source": 4,
      "links": null
    },
    {
      "opcodes": ["5d"],
      "address": 4195561,
      "text": " pop rbp",
      "source": 5,
      "links": null
    },
    {
      "opcodes": ["c3"],
      "address": 4195562,
      "text": " ret ",
      "source": 5,
      "links": null
    },
    {
      "text": "main:",
      "source": null
    },
    {
      "opcodes": ["55"],
      "address": 4195563,
      "text": " push rbp",
      "source": 6,
      "links": null
    },
    {
      "opcodes": ["48","89","e5"],
      "address": 4195564,
      "text": " mov rbp,rsp",
      "source": 6,
      "links": null
    },
    {
      "opcodes": ["b8","00","00","00","00"],
      "address": 4195567,
      "text": " mov eax,0x0",
      "source": 6,
      "links": null
    },
    {
      "opcodes": ["5d"],
      "address": 4195572,
      "text": " pop rbp",
      "source": 6,
      "links": null
    },
    {
      "opcodes": ["c3"],
      "address": 4195573,
      "text": " ret ",
      "source": 6,
      "links": null
    },
    {
      "opcodes": ["66","2e","0f","1f","84","00","00","00","00","00"],
      "address": 4195574,
      "text": " nop WORD PTR cs:[rax+rax*1+0x0]",
      "source": 6,
      "links": null
    }
  ]
}
which seems very manageable... It also seems the payload is JSON also.

Code: Select all

{"source":"// Type your code here, or load an example.\nint square(int num) {\n    num = num + 1;\n    return num * num;\n}","compiler":"g71","options":{"userArguments":"","compilerOptions":{},"filters":{"binary":true,"labels":true,"directives":true,"commentOnly":true,"trim":true,"intel":true}}}
And for future reference the Request headers:

Code: Select all

Content-Type:application/json
Request URL:https://godbolt.org/api/compiler/g71/compile
Request Method:POST
Last edited by sancarn on 08 Aug 2017, 11:38, edited 1 time in total.
User avatar
joedf
Posts: 8940
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: MCode4GCC -- C/C++ to MCode Generator

08 Aug 2017, 11:34

Sure no problemo! Would be very cool, I meant simply that the output is not "guaranteed" working. :(
If you do get it working that would be great! :+1:
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]
sancarn
Posts: 224
Joined: 01 Mar 2016, 14:52

Re: MCode4GCC -- C/C++ to MCode Generator

08 Aug 2017, 11:45

Btw what do you mean by 'with the junk removed' ? As in, how do you know what is junk and what isn't?
User avatar
joedf
Posts: 8940
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: MCode4GCC -- C/C++ to MCode Generator

08 Aug 2017, 12:05

Oh very cool! Didn't know that had an API. This is much more promising hhaha
Junk I meant is the other parts that are not part of the function for the default example of square(), it's everything before it and everything after the ret.
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]

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 111 guests