AHK 机器码(MCode)的制作

许多实用脚本和封装函数, 可以让您编写脚本更加便捷高效
feiyue
Posts: 119
Joined: 08 Aug 2014, 04:08

AHK 机器码(MCode)的制作

Post by feiyue » 28 May 2016, 21:26

最早从官网看到大神们在使用机器码(MCode)的时候,惊为天人,极为仰慕。
可惜一看介绍,需要先下载安装VC或者GCC,还有各种参数配置,总感觉很难,
因此很长时间都没有使用过。

后来慢慢尝试使用GCC,发现并不难,因为都是用命令行调用的,下载安装
GCC后根本不用配置,找到gcc.exe程序就可以在命令行使用了。
我推荐使用 TDM-GCC 64位版,可以在百度搜索 TDM-GCC 或在 官网 下载。

我成功地实现了自己写C语言代码并快速转化为机器码(MCode),真令人高兴。
比较了多种方法后,我把最简单的转化方式分享给大家,让大家也来使用机器码。 :dance:


Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

Last edited by feiyue on 29 Aug 2018, 20:31, edited 30 times in total.
feiyue
Posts: 119
Joined: 08 Aug 2014, 04:08

Re: AutoHotkey 机器码(MCode)的制作

Post by feiyue » 28 May 2016, 21:49

再附上调用MCode需要的函数,这是基于官网中前辈们的函数修改的,感谢前辈们! :)

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

Last edited by feiyue on 28 Aug 2018, 16:30, edited 1 time in total.
tmplinshi
Posts: 1260
Joined: 01 Oct 2013, 14:57

Re: AHK 机器码(MCode)的制作

Post by tmplinshi » 28 May 2016, 23:48

赞!谢谢分享
feiyue
Posts: 119
Joined: 08 Aug 2014, 04:08

Re: AHK 机器码(MCode)的制作

Post by feiyue » 29 May 2016, 07:45

下面是一个AHK 应用 MCode 的简单例子,使用C语言返回 Hello World 字符串:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus

Last edited by feiyue on 28 Aug 2018, 16:32, edited 4 times in total.
kkss

Re: AHK 机器码(MCode)的制作

Post by kkss » 28 Jul 2017, 22:22

Thanks for feiyue
I solved this problem.^^
feiyue
Posts: 119
Joined: 08 Aug 2014, 04:08

Re: AHK 机器码(MCode)的制作

Post by feiyue » 25 Apr 2018, 23:24

更新到 v1.6 版,不再需要 objcopy.exe 程序。现在可以使用小巧便携的TinyCC代替GCC,但它在Win32系统上不能同时生成32位和64位版本。
Last edited by feiyue on 28 Aug 2018, 23:26, edited 1 time in total.
feiyue
Posts: 119
Joined: 08 Aug 2014, 04:08

Re: AHK 机器码(MCode)的制作

Post by feiyue » 28 Aug 2018, 10:54

利用TCC动态运行C语言代码的简单方式:
(必须在AHK目录下安装 “\TCC-64\tcc.exe” 和 “\TCC-32\tcc.exe”)

Code: Select all

;------------------------------------------
;  Using TCC to run C code  (By FeiYue)
;------------------------------------------

Goto, F1

F1::
Code=
(

char * __attribute__((stdcall)) hello(char * out) {
  char str[]="Hello World!";
  for (int i=0; str[i]!='\0'; i++)
    out[i]=str[i];
  return out;
}

)
VarsetCapacity(str,100,0)
MsgBox, 4096,, % StrGet(DllCall(c2f("hello",Code), "ptr",&str, "ptr"), "CP0")
return


;========== TCC Functions ==========


c2f(FuncName, C_Code="", Clear="") {
  static Address:=[]
  if (Clear)
  {
    if (addr:=Address[FuncName])
      DllCall("GlobalFree","ptr",addr)
    Address[FuncName]:=""
    return
  }
  if (addr:=Address[FuncName])
    return, addr
  if !(hex:=Tcc(C_Code, A_PtrSize=8))
    return
  if !(addr:=DllCall("GlobalAlloc","int",0,"ptr",len:=StrLen(hex)//2,"ptr"))
    return
  SetBatchLines, % "-1" (bch:=A_BatchLines)/0
  Loop, % len
    NumPut("0x" SubStr(hex,2*A_Index-1,2), addr+A_Index-1, "char")
  SetBatchLines, %bch%
  DllCall("VirtualProtect","ptr",addr,"ptr",len,"uint",0x40,"ptr*",0)
  Address[FuncName]:=addr
  return, addr
}

Tcc(s, win64=0)
{
  dir:=A_IsCompiled ? A_ScriptDir : RegExReplace(A_AhkPath,"\\[^\\]+$")
  tcc:=dir (win64 ? "\TCC-64\tcc.exe" : "\TCC-32\tcc.exe")
  IfNotExist, %tcc%
  {
    MsgBox, 4096, Tip, Can't Find %tcc% !
    return
  }
  ;-----------------------------
  add1=`n int _add1_() { return 0x11111111; } `n
  add2=`n int _add2_() { return 0x11111111; } `n
  add3=`n int _add3_() { return 0x11111111; } `n
  s:=StrReplace(add1 . add2 . s . add3, "`r")
  ;-----------------------------
  FileDelete, % cpp:=dir "\5.c"
  FileDelete, % obj:=dir "\5.obj"
  FileDelete, % log:=dir "\5.log"
  FileAppend, %s%, %cpp%
  killcmd(1)
  RunWait, %ComSpec% /c ""%tcc%" -c -o "%obj%" "%cpp%" 2>"%log%""
    ,, Hide
  killcmd(0)
  IfNotExist, %obj%
  {
    FileRead, s, %log%
    FileDelete, %cpp%
    FileDelete, %log%
    MsgBox, 4096, C Compile Error, %s%
    return
  }
  hex:=bin2hex(obj)
  ;-----------------------------
  re:="i)B811111111.{0,16}?C3"
  p1:=RegExMatch(hex,re,r), n:=StrLen(r)
  p2:=InStr(hex,r,0,p1+n), p3:=InStr(hex,r,0,0), i:=0
  Loop, % (p2-(p1+n))//2
    if SubStr(hex,p2-i-2,2)!=SubStr(hex,p1-i-2,2)
      Break
    else i+=2
  j:=InStr(hex,SubStr(hex,p2-i,2),0,p2+n)
  hex:=(p1 and p2 and p3>p2) ? SubStr(hex,j,p3-i-j) : ""
  ;-----------------------------
  FileDelete, %cpp%
  FileDelete, %obj%
  FileDelete, %log%
  return, hex
}

bin2hex(obj)
{
  VarSetCapacity(bin,1024), VarSetCapacity(bin,0)
  FileRead, bin, *c %obj%
  size:=VarSetCapacity(bin), p:=&bin
  VarSetCapacity(hex, (2*size+1)*(1+!!A_IsUnicode))
  SetBatchLines, % "-1" (bch:=A_BatchLines)/0
  SetFormat, IntegerFast, % "H" (fmt:=A_FormatInteger)/0
  Loop, %size%
    hex.=SubStr(0x100+(*p++),-1)
  SetFormat, IntegerFast, %fmt%
  SetBatchLines, %bch%
  return, hex
}

killcmd(onoff=1) {
  if (onoff=0)
    SetTimer, kill_cmd, Off
  else
  {
    Gosub, kill_cmd
    SetTimer, kill_cmd, -5000
  }
  return
  kill_cmd:
  SplitPath, ComSpec, cmd
  Loop, 10 {
    Process, Exist, %cmd%
    if (pid:=ErrorLevel)
      Process, Close, %pid%
    else Break
    Sleep, 500
  }
  return
}

;
Last edited by feiyue on 29 Aug 2018, 09:43, edited 5 times in total.
burque505
Posts: 571
Joined: 22 Jan 2017, 19:37

Re: AHK 机器码(MCode)的制作

Post by burque505 » 28 Aug 2018, 17:48

嗨,我收到以下错误:
---------------------------
C Compile Error
---------------------------
C:/Program Files/AutoHotkey/5.c:4: error: redefinition of '_AddFlag_'


---------------------------
OK
---------------------------
最好的祝福,
burque505
hitman
Posts: 8
Joined: 10 Aug 2014, 06:47

Re: AHK 机器码(MCode)的制作

Post by hitman » 06 Sep 2018, 10:02

感谢飞跃大神分享,希望飞跃大神再研究下ahk+lua的混合编程!
Post Reply

Return to “脚本函数”