2011-06-15 73 views
2

所以我想從文件中加載一組彙編指令,並執行這些指令。內聯ASM跳轉到新內存

OR

我想從一個文件(non-EXE)再次裝入已編譯的機器代碼

我的想法:

到目前爲止,我已經瞭解了足夠聯彙編到輕鬆處理c/C++變量。

asm volatile (
    "mov  %1, %%ecx;" // yes unnecessary, I know 
    "add  %2, %%ecx;" // I know they're already loaded in a register 
    "mov  %%ecx ,%0 ;"// just demonstrating what I've learned 
    :"=r"(address) 
    :"r"(address),"r"(offset) 
    :"%ecx" 
); 

我已經開始學習操作碼了,並且已經獲得了一些x86手冊。我(有點)瞭解硬件在基本層面的工作原理。

我知道我可以用fstream將C++加載到內存中,我想知道是否有辦法從該空間執行內存,或者如果它在內存的非可執行部分或其他東西。

原因:

目前,有幾個原因,我想這樣做。我希望爲我的程序創建一個基本的加密,這是一個運行程序的簡單密鑰。雖然我可以輕鬆加密和解密實際的代碼,但我希望程序在每次運行時都不加密,並且永遠不會存儲在硬盤上。我知道有幾個問題,但我非常有興趣這樣做。

最後的問題:

我可以在ASM執行從內存空間的機器代碼的程序從C++?

是asm必需的嗎?

是否有其他方式來更有效地完成這個任務,如果是這樣,那些是什麼方法呢?

我也讀了一些DLL注入爲我做鼠標共享程序(兩臺計算機彼此相鄰,都具有顯示器,但是你只有一個鼠標/鍵盤。我想知道在那裏我可以在主題找到一些好的資源?谷歌一直樂於助人,但我感興趣的是也許有些IRC頻道或類似的東西。不管怎麼說,感謝您的閱讀!

+0

真的有一個問題太多的問題。 – 2011-06-15 15:27:57

回答

6

這聽起來像是你有種想一些x86彙編在一個單獨的文件中的一些JIT編譯?

我可能誤會了,當你說「記憶空間」,你的封裝非常寬泛的術語。我假設你並不是說你想用一組特定的程序集編譯它,但是能夠在運行時交換程序集指令?

有過以下Dynamically generating and executing x86 code

讀你會看到

#include <stdio.h> 
#include <stdint.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/mman.h> 

int main(int argc, char *argv[]) { 
    uint8_t *buf = mmap(NULL, 1000, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 

    buf[0] = 0xb8; 
    uint32_t u32 = 42; 
    memcpy(buf + 1, &u32, 4); 
    buf[5] = 0xc3; 

    if (mprotect(buf, 1000, PROT_EXEC | PROT_READ) < 0) { 
     fprintf(stderr, "mprotect failed: %s\n", strerror(errno)); 
     return 1; 
    } 
    int (*ptr)(void) = (int (*)(void)) buf; 

    printf("return is %d\n", ptr()); 

    return 0; } 

這裏要爲緩衝分配內存。將指令放入緩衝區,然後從分配的內存創建一個函數指針。注意內存也受到保護。

閱讀文章以獲得更好的理解,它也給你一些與Windows相同的東西。

+0

+1簡單的指導!作爲將來的參考,由於API不可移植,因此Windows上的「等效」內存保護過程首先調用['VirtualAlloc()'](http://msdn.microsoft.com/zh-cn/library/aa366887 (VS.85).aspx)並使用[內存保護常量](http://msdn.microsoft.com/en-us/library/aa366786(VS.85).aspx)是必需的。 WOW !! – 2011-06-15 16:08:10

+0

那很完美!謝謝!! – ultifinitus 2011-06-15 18:24:53

2

如果要加載代碼數據,然後執行它,那麼你可能需要將包含代碼的內存標記爲可執行文件(這是由於大多數現代操作系統中的安全功能,以防止各種漏洞)在Linux,Mac OS X,您可以使用mprotect,但它聽起來像e您可能正在使用Windows(?),所以在這種情況下,您需要找到相應的API。

而且沒有你不需要使用ASM存儲這一點 - 你可以使用C或C++函數指針。

+0

您可以使用常規函數指針* iff *代碼實際上是一個函數*和*您100%確定調用約定(在Windows上)。 – 2011-06-15 16:08:19