AHK机器码生成器-v2.6
Posted: 28 May 2016, 21:26
最早从官网看到大神们在使用机器码(MCode)的时候,惊为天人,极为仰慕。
可惜一看介绍,需要先下载安装VC或者GCC,还有各种参数配置,总感觉很难,
因此很长时间都没有使用过。
后来慢慢尝试使用GCC,发现并不难,因为都是用命令行调用的,下载安装
GCC后根本不用配置,找到gcc.exe程序就可以在命令行使用了。
我推荐使用 TDM-GCC 64位版,可以在百度搜索 TDM-GCC 或在 官网 下载。
我成功地实现了自己写C语言代码并快速转化为机器码(MCode),真令人高兴。
比较了多种方法后,我把最简单的转化方式分享给大家,让大家也来使用机器码。
可惜一看介绍,需要先下载安装VC或者GCC,还有各种参数配置,总感觉很难,
因此很长时间都没有使用过。
后来慢慢尝试使用GCC,发现并不难,因为都是用命令行调用的,下载安装
GCC后根本不用配置,找到gcc.exe程序就可以在命令行使用了。
我推荐使用 TDM-GCC 64位版,可以在百度搜索 TDM-GCC 或在 官网 下载。
我成功地实现了自己写C语言代码并快速转化为机器码(MCode),真令人高兴。
比较了多种方法后,我把最简单的转化方式分享给大家,让大家也来使用机器码。
Code: Select all
;===========================================
; AHK机器码生成器-v2.6 By FeiYue
;
; 使用方法:
;
; 1、下载安装【TDM-GCC】的64位版到D盘的TDM-GCC-64目录,下载网址为:
; https://sourceforge.net/projects/tdm-gcc/files/latest/download
;
; 2、下载安装【TCC】的32位和64位版到AHK的TCC-32和TCC-64目录,下载网址为:
; https://bellard.org/tcc/
;
; 3、选择C代码后,按【 Alt+C 】热键生成 GCC 编译的机器码,
; 或者按【 Ctrl+Alt+C 】热键生成 TCC 编译的机器码
;
;===========================================
!c:: ; 选择C代码后用 GCC 编译
^!c:: ; 选择C代码后用 TCC 编译
Compile_Func() ; V1的热键函数必须有函数名
{
ClipSaved:=ClipboardAll, Clipboard:=""
Send % "{Ctrl Down}c{Ctrl Up}"
ClipWait, 3
s:=Clipboard, Clipboard:=ClipSaved
if (s="")
{
MsgBox, 4096, Tip, The contents of the copy are empty !
return
}
r:=[]
Loop 2
{
i:=A_Index-1
, hex:=(new MCodeClass).Tcc(s,i,A_ThisHotkey="!c").b64
, hex:=Trim(RegExReplace(hex,".{1,64}","`r`n . ""$0"""),"`r`n .")
, r[i]:="`r`n " (i?"x64:=":"x32:=") . StrReplace(hex,"/","@")
}
hex:=r[0] r[1] "`r`n MyFunc:=this.MCode(StrReplace((A_PtrSize=8?x64:x32),""@"",""/""))"
MsgBox, 4096, MCode has been generated! (32 + 64), % Clipboard:=hex
s:=hex:=r:=""
}
s:="
(
#include <windows.h>
int aaa() { return sizeof(WINDOWPLACEMENT); }
)"
MsgBox % DllCall((p:=new MCodeClass).Tcc(s).Ptr)
Class MCodeClass
{ ;// Class Begin
Tcc(s:="", win64:="", gcc:=1)
{
local
if (s="")
return
(win64="" && win64:=A_PtrSize=8)
if (gcc)
exe1:="D:\TDM-GCC-64\bin\gcc.exe"
else
exe1:=RegExReplace((!A_IsCompiled ? A_AhkPath : A_ScriptFullPath)
, "[^\\]+$", (win64 ? "TCC-64":"TCC-32") "\tcc.exe")
if !FileExist(exe1)
{
MsgBox, 4096, Tip, Can't Find %exe1% !
return
}
dir:=A_Temp, cpp:=dir "\~5.c", obj:=dir "\~5.obj", log:=dir "\~5.log"
For k,v in [cpp, obj, log]
Try FileDelete % v
FileAppend % StrReplace(s,"`r"), % cpp
Loop
{
Process, Exist, % RegExReplace(A_ComSpec,"^.*\\")
if !(pid:=ErrorLevel)
Break
Process, Close, % pid
Process, WaitClose, % pid, 3
}
size:=s:="", q:=Chr(34), arg:=(win64 ? " -m64 ":" -m32 ") " -O2 "
cmd:=q exe1 q " " arg " -c -o " q obj q " " q cpp q " 2>" q log q
RunWait % A_ComSpec " /c " q cmd q,, Hide
if FileExist(obj)
{
FileGetSize, size, % obj
FileRead, bin, % "*c " obj
}
Try FileRead, s, % log
For k,v in [cpp, obj, log]
Try FileDelete % v
if (!size || s)
{
MsgBox, 4096, Tip, % "C Compile Error`n`n" s
return
}
p:=&bin, hex:=""
if (NumGet(p+0,"uchar")=0x7f && StrGet(p+1,3,"CP0")="ELF")
{ ; TCC use ELF
r:=(NumGet(p+4,"char")=2?8:4), ptr:=(r=8?"uint64":"uint")
e_shoff:=NumGet(p+24+2*r,ptr)
e_shentsize:=NumGet(p+34+3*r,"ushort")
e_shstrndx:=NumGet(p+38+3*r,"ushort")
sh:=e_shoff+e_shstrndx*e_shentsize
str_offset:=NumGet(p+sh+8+2*r,ptr)
Loop % NumGet(p+36+3*r,"ushort")
{
sh:=e_shoff+(A_Index-1)*e_shentsize
name:=StrGet(p+str_offset+NumGet(p+sh,"uint"),8,"CP0")
offset:=NumGet(p+sh+8+2*r,ptr), size:=NumGet(p+sh+8+3*r,ptr)
if (name=".text") && (NumGet(p+sh+8,ptr) & 0x4)
&& ((hex:=this.bin2hex(p+offset,size,0))||1)
Break
}
}
else Loop % NumGet(p+2,"ushort") ; GCC use COFF
{
sh:=20+(A_Index-1)*40, name:=StrGet(p+sh,8,"CP0")
offset:=NumGet(p+sh+20,"uint"), size:=NumGet(p+sh+16,"uint")
if (name=".text") && (NumGet(p+sh+36,"uint") & 0x20)
&& ((hex:=this.bin2hex(p+offset,size,0))||1)
Break
}
if !hex
return
code:=this.MCode(hex), code.hex:=hex, code.b64:=this.bin2hex(p+offset,size,1)
return code
}
Buffer(size, FillByte:="")
{
local
buf:={}, buf.SetCapacity("_key", size), p:=buf.GetAddress("_key")
, (FillByte!="" && DllCall("RtlFillMemory","Ptr",p,"Ptr",size,"uchar",FillByte))
, buf.Ptr:=p, buf.Size:=size
return buf
}
MCode(hex)
{
local
flag:=((hex~="[^A-Fa-f\d\s]") ? 1:4), len:=0
Loop 2
if !DllCall("crypt32\CryptStringToBinary", "Str",hex, "uint",0, "uint",flag
, "Ptr",(A_Index=1?0:(p:=this.Buffer(len)).Ptr), "uint*",len, "Ptr",0, "Ptr",0)
return
if DllCall("VirtualProtect", "Ptr",p.Ptr, "Ptr",len, "uint",0x40, "uint*",0)
return p
}
bin2hex(addr, size, base64:=0)
{
local
flag:=(base64 ? 1:4)|0x40000000, len:=0
Loop 2
DllCall("crypt32\CryptBinaryToString", "Ptr",addr, "uint",size, "uint",flag
, "Ptr",(A_Index=1?0:(p:=this.Buffer(len*2)).Ptr), "uint*",len)
return RegExReplace(StrGet(p.Ptr, len), "\s+")
}
} ;// Class End