C語言如何執行buf中的代碼?
能在 buf中寫一段代碼,讓程序執行么,比如
char szBuf[1024]={0}; strcpy(szBuf, "stricmp("1","2");");怎麼調用 szBuf ,才能實現和下面一樣的效果int k = stricmp("1","2");可以計算出表達式
首先你的內存要有可執行許可權,然後你把一個函數的機器碼完整地寫進去,最後把這個內存強制轉換成一個函數指針就可以執行了。至於參數和結果是如何被彙編語言訪問的,這跟你使用什麼編譯器、以及函數指針類型的calling convention都有關係,你需要了解這所有的細節。
VirtualProtect function (Windows)
Memory Protection Constants (Windows)PAGE_EXECUTEhttp://www.cppblog.com/vczh/archive/2009/02/22/74622.htmlstrcpy(szBuf, "stricmp("1","2");");
這裡的szBuf只是保存了字元串值而已,並不是可執行的代碼,從代碼到可執行的二進位指令需要編譯,亦或者通過解釋執行.需要調用C編譯器或解釋器.
若要直接執行Buffer裡面的代碼必須是二進位指令.這裡提供一種可直接執行題主給的stricmp的例子:x86
char szBuf[] = "x8bx44x24x04x8bx5cx24x08x0fxbex08x85xc9x74x0fx0fxbex13x85xd2x74x08x3bxcax75x04x40x43xebxeax0fxbex08x0fxbex13x2bxcax8bxc1xc3";
調用:
int(*_stricmp)(char[], char[]) = (int(*)(char[], char[]))szBuf;
printf("%d",_stricmp("str1", "str2"));
前提是szBuf的內存為可執行,Windows下使用VirtualProtectEx修改,Linux下使用mmap修改該內存位置為可執行.
Windows下的例子:#include &
#include &
char szBuf[] = "x8bx44x24x04x8bx5cx24x08x0fxbex08x85xc9x74x0fx0fxbex13x85xd2x74x08x3bxcax75x04x40x43xebxeax0fxbex08x0fxbex13x2bxcax8bxc1xc3";
int main()
{
int(*_stricmp)(char[], char[]) = (int(*)(char[], char[]))szBuf;
DWORD OldProtect;
VirtualProtectEx(GetCurrentProcess(),
szBuf, sizeof(szBuf),
PAGE_EXECUTE_READWRITE,
OldProtect);
printf("%d",_stricmp("str1", "str2"));
VirtualProtectEx(GetCurrentProcess(),
szBuf, sizeof(szBuf),
OldProtect,
NULL);
return 0;
}
szBuf里的代碼對應的彙編如下:
mov eax, [esp+0x04]
mov ebx, [esp+0x08]
__loop :
movsx ecx, byte ptr[eax]
test ecx, ecx
je __exit
movsx edx, byte ptr[ebx]
test edx, edx
je __exit
cmp ecx, edx
jne __exit
inc eax
inc ebx
jmp __loop
__exit :
movsx ecx, byte ptr [eax]
movsx edx, byte ptr [ebx]
sub ecx, edx
mov eax, ecx
ret
LZ可以下載一下tcc的源碼,它有這種on the fly的執行方式的。
如果出現不可執行錯誤(像輪子哥提到的那樣),就VirtualProtect一下。先用這個VirtualProtect函數,這個函數會改變段描述符裡面的屬性,這樣把棧變成可執行的。然後char shellcode[]="反彙編機器碼";_asm
{push shellcode
ret}謝邀,題主你要的是直接執行源碼,相當於要有一個C的eval函數。有一個簡單的版本可以參考:rswier/c4 · GitHub
我覺得無法實現,除非程序自帶c語言解釋器,或者給編譯器加上這個功能,
首先~你得先實現一個簡單的c語言解釋器,將你寫入buffer的字元串解釋成彙編位元組碼,而恰好你這內存要擁有可執行許可權,請參考輪子哥答案,再,要用到api的話,要修復程序偏移,也就是重定位能識別到api地址,這個可以參考shellcode技術。
其實現在有一個挺好的東西,就是tiny c的實現,可以buffer執行代碼,當然,要是Windows api,貌似tiny c沒做支持。
bufferoverflow shellcode
把字元串寫到文件里,然後用解釋器行不?
雙引號裡面的字元串常量,需要先編譯成機器能看懂的二進位碼吧??
題主的問題讓我想起了緩衝區溢出攻擊
這不就是shellcode么,知道shellcode怎麼寫,就明白了。手機碼字,看個意思就好:
char buf[] = "xxxx";
typedef int (func_t*)(const char*, const char*);
func_t f = (func_t)(long)buf;
int rv = (*f)(str1, str2);
至於buf裡頭的東西,用對應的機器碼填充即可。
當然數據段可能不能執行,有些編譯選項需要調一下,或者自己改變可執行的屬性。可以參考ATL的Thunk實現,必須調用操作系統提供的API,和語言無關。
推薦閱讀:
※怎樣才是一個基本水平的c++程序員?
※C++11中用{}初始化,有等於號和沒等於號的區別是什麼?
※聲明多個指針時,為什麼實際只有第一個是指針?
※cpp 如何 debug memory leak?
※C++中類的構造函數,成員變數是在初始化列表初始化還是在函數體中進行賦值?