日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows下动态加载可执行代码原理简述

發布時間:2024/4/14 windows 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows下动态加载可执行代码原理简述 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

xiaotie同學比較蛋疼,問C#里面能不能動態加載SIMD的匯編代碼。C#我不知道,反正c/c++下面這事情很好做。順手花了幾個小時寫了個例子和這篇博客。

總的來說,windows下要動態加載binary的話,基本上分以下幾步。

1. 首先要得到可執行代碼的binary。 無論是在程序里面編譯也好,或者從什么地方讀出來,或者用戶手把手的敲進去。

2. 為這些binary分配一段具有可執行屬性的內存。這是因為有Data Execution Prevention的存在,一般用malloc和new分配的內存頁面不具有可執行這個屬性,一旦執行就會產生STATUS_ACCESS_VIOLATION的異常。

3. 下一步就是要跳轉到這段內存上去執行了,可能要寫一些匯編指令,在調用的過程中要注意棧是否平衡。

基本上就是這三點了,下面來看具體的代碼:

第一步,拿到可執行的binary。這里我寫了一個用SIMD指令的fastercopy函數,然后編譯以后把它的二進制代碼寫成一個數組。

int emitcode[] =
{
0x83ec8b55,0x565340ec,0x0c758b57,0x8b087d8b,
0x348d104d,0xcf3c8dce,0x6f0fd9f7,0x6f0fce04,
0x0f08ce4c,0x10ce546f,0xce5c6f0f,0x646f0f18,
0x6f0f20ce,0x0f28ce6c,0x30ce746f,0xce7c6f0f,
0x04e70f38,0x4ce70fcf,0xe70f08cf,0x0f10cf54,
0x18cf5ce7,0xcf64e70f,0x6ce70f20,0xe70f28cf,
0x0f30cf74,0x38cf7ce7,0x7508c183,0xf8ae0fad,
0x5e5f770f,0x5de58b5b,0xccccccc3};

fastercopy函數是這樣寫的

View Code void fastercopy(void* dst, void* src, int len)
{
__asm {
mov esi, [src]
// source array
mov edi, [dst] // destination array
mov ecx, [len] // number of QWORDS (8 bytes)

lea esi, [esi
+ecx*8] // end of source
lea edi, [edi+ecx*8] // end of destination
neg ecx // use a negative offset
copyloop:
movq mm0, qword ptr[esi
+ecx*8]
movq mm1, qword ptr[esi
+ecx*8+8]
movq mm2, qword ptr[esi
+ecx*8+16]
movq mm3, qword ptr[esi
+ecx*8+24]
movq mm4, qword ptr[esi
+ecx*8+32]
movq mm5, qword ptr[esi
+ecx*8+40]
movq mm6, qword ptr[esi
+ecx*8+48]
movq mm7, qword ptr[esi
+ecx*8+56]
movntq qword ptr[edi
+ecx*8], mm0
movntq qword ptr[edi
+ecx*8+8], mm1
movntq qword ptr[edi
+ecx*8+16], mm2
movntq qword ptr[edi
+ecx*8+24], mm3
movntq qword ptr[edi
+ecx*8+32], mm4
movntq qword ptr[edi
+ecx*8+40], mm5
movntq qword ptr[edi
+ecx*8+48], mm6
movntq qword ptr[edi
+ecx*8+56], mm7
add ecx,
8
jnz copyloop
sfence
// flush write buffer
emms
}
}

第二步,分配內存了。這里調用的是VirtualAlloc這個windows函數。在最后一個參數指定PAGE_EXECUTE_READWRITE屬性。

void* address = NULL;
address
= VirtualAlloc(NULL,
sizeof(emitcode),
MEM_COMMIT
|MEM_RESERVE,
PAGE_EXECUTE_READWRITE);

memcpy(address,emitcode,
sizeof(emitcode));

  

第三步,調用這個存在address中的代碼。

可以自己寫匯編代碼調用:

__asm {
push 20h
mov eax,dword ptr [src]
push eax
mov ecx,dword ptr [dst]
push ecx
mov ecx, dword ptr [address]
call ecx
add esp,0Ch
}

也可以使用函數指針來調用,反正知道函數的原型是啥。

typedef void (*FASTCALL)(void* dst, void* src, int len);
FASTCALL fastcall;
fastcall
= (FASTCALL)address;
fastcall(dst2,src,
64/2);

這些實驗是在Win7+VS2010 debug版本做的

如果園子們在其他環境下做不出來,概不負責。

如果在Win7+VS2010也做不出來,也概不負責。

工程文件打包下載在這里(http://files.cnblogs.com/aoaoblogs/EmitSIMD.7z)

據說博客要配圖才有說服力,七夕到了,送些福利給QS們

  

轉載于:https://www.cnblogs.com/aoaoblogs/archive/2011/08/04/2127143.html

總結

以上是生活随笔為你收集整理的Windows下动态加载可执行代码原理简述的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。