有些操作非要使用匯編語言不可,比如想獲取 CPU 的信息,必須用 CPUID 指令,但是64 位的微軟編譯器都不再允許內嵌匯編了,這可怎么辦呢?標准方法是使用 ASM 文件和 C文件進行混合編譯,但這種方法很麻煩,特別是只要嵌入一小段匯編的情況下。所以我的解決方法是,用軟件把匯編轉換成機器碼,然后直接執行機器碼。64 位匯編轉換機器碼的工具可以用我的 X64ASM_TO_X64BIN(http://www.vbasm.com/thread-5651-1-1.html)。先來說說如何使用 X64ASM_TO_X64BIN。要使用 X64ASM_TO_X64BIN 必須先下載MASM64 壓縮包(http://www.m5home.com/bbs/thread-5170-1-1.html)。下載完畢后,必須把此壓縮包解壓到 C 盤根目錄(即解壓完畢后 C 盤有個 MASM64 文件夾):其次,必須安裝好.NET FRAMEWORK 4(http://www.microsoft.com/zh-cn/download/details.aspx?id=17718),否則軟件無法運行。這兩步都配置好后,輸入匯編代碼,按下『Get BIN with C/C++ Style』按鈕,即可把匯編代碼轉換為機器碼(SHELLCODE):
接下來說說如何讓內嵌的匯編子程序有返回值以及給匯編子程序傳入參數。首先是使用 typedef 定義一下你的匯編子程序的原型,然后把機器碼復制到 NonPagedPool 里,最后直接把 NonPagedPool 的地址當作函數來 CALL。代碼示例如下(輸入四個數字相加,返回它們相加的值):
typedef UINT64 (__fastcall *SCFN)(UINT64,UINT64,UINT64,UINT64);
VOID test()
{
SCFN scfn;
UINT64 ret;
UCHAR strShellCode[14]="\x48\x03\xCA\x49\x03\xC8\x49\x03\xC9\x48\x8B\xC1\xC3";
/*
add rcx,rdx
add rcx,r8
add rcx,r9
mov rax,rcx
ret
*/
scfn=ExAllocatePool(NonPagedPool,14);
memcpy(scfn,strShellCode,14);
ret=scfn(11,22,33,44);
DbgPrint("[x64Drv] Inline ASM return: %lld",ret);
ExFreePool(scfn);
}
