「■関数ポインタ」の編集履歴(バックアップ)一覧はこちら
「■関数ポインタ」(2009/05/31 (日) 17:29:51) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
*情報
作者名:しらたま
引用元:[[なでしこプログラム掲示板「代用関数ポインタ」>http://www.himanavi.net/cgi/nade-bbs/cbbs.cgi?mode=al2&namber=809&rev=&no=0]]
*概要
なでしこで関数ポインタを扱えるようにする。
*本体
●VirtualAlloc({参照渡し}lpAddress,dwSize,flAllocationType,flProtect)=DLL("kernel32.dll",
"LPVOID VirtualAlloc(
LPVOID lpAddress,
int dwSize,
DWORD flAllocationType,
DWORD flProtect
)")
●VirtualFree({参照渡し}lpAddress,dwSize,dwFreeType)=DLL("kernel32.dll",
"BOOL VirtualFree(
LPVOID lpAddress,
int dwSize,
DWORD dwFreeType
)")
●MoveMemory({参照渡し}d,{参照渡し}s,l)=DLL("kernel32.dll",
"VOID RtlMoveMemory(
LPVOID Destination,
LPVOID Source,
int Length
)")
●GetProcAddress(hModule,{参照渡し}lpProcName)=DLL("kernel32.dll",
"DWORD GetProcAddress(
HMODULE hModule, // DLL モジュールのハンドル
LPCSTR lpProcName // 関数名
)")
●GetModuleHandle({参照渡し}ModuleName) =DLL("kernel32.dll",
"HMODULE GetModuleHandleA(
LPCTSTR ModuleName
)")
!MEM_COMMIT=$1000
!MEM_RELEASE=$8000
!PAGE_EXECUTE_READWRITE=$40
!変数宣言が必要
それ待避用スタックとは配列
●それプッシュ
それ待避用スタックにそれを配列追加
●それポップ
Aとは整数
Aはそれ待避用スタックの配列要素数
それはそれ待避用スタック[A-1]
それ待避用スタックのA-1を配列削除
●AddBinary({参照渡し}target,value,size)
MoveMemory(target,POINTER(value),size)
target=target+size
!関数ポインタ既定イベント名=「前処理」
!nako_group_execポインタ=GetProcAddress(GetModuleHandle(「dnako.dll」),「nako_group_exec」)
■関数ポインタ
・{イベント}イベント
・{整数}ダミー関数
・{非公開}前処理~
F引数数 回
引数[回数-1]=0
MoveMemory(POINTER(引数[回数-1]),スタックアドレス+4+4*回数,4)
自身→イベント
・{配列}引数
・{非公開 整数}スタックアドレス
・{整数}返り値
・{非公開}F引数数
・引数数←引数数設定→引数数取得
・{非公開}引数数設定(V)~
それプッシュ
pcとは整数
もしダミー関数=0ならば
ダミー関数はVirtualAlloc(0,64,MEM_COMMIT,PAGE_EXECUTE_READWRITE)
pc=ダミー関数
AddBinary(pc,$55,1) //push ebp
AddBinary(pc,$EC8B,2) //mov ebp,esp
pc-ダミー関数という
AddBinary(pc,$BA,1)
pc-ダミー関数という
AddBinary(pc,POINTER(スタックアドレス),4) //mov edx,POINTER(スタックアドレス)
AddBinary(pc,$2A89,2) //mov dword ptr [edx],ebp
AddBinary(pc,$68,1)
AddBinary(pc,POINTER(関数ポインタ既定イベント名),4) //push char*
AddBinary(pc,$68,1)
AddBinary(pc,ADDR(自身),4) //push PHiValue
AddBinary(pc,$B8,1)
AddBinary(pc,nako_group_execポインタ,4)//mov eax,nako_group_execポインタ
AddBinary(pc,$D0FF,2) //call eax
AddBinary(pc,$058B,2)
AddBinary(pc,POINTER(返り値),4) //mov eax,POINTER(返り値)
AddBinary(pc,$5D,1) //pop edp
AddBinary(pc,$C2,1)
AddBinary(pc,V*4,2) //ret 8
#AddBinary(pc,$00,1)
F引数数はV
それポップ
・{非公開}引数数取得~
それはF引数数
・作る~
スタックアドレスは0
返り値は0
ダミー関数=0
F引数数は-1
・解放~
VirtualFree(ダミー関数,0,MEM_RELEASE)
*//サンプルプログラム
#実行テスト1(GDIオブジェクト(ペン)列挙)
●GetDesktopWindow()=DLL("user32.dll","HWND GetDesktopWindow()")
●GetDC(hwnd)=DLL("user32.dll",
"HDC GetDC(
HWND hwnd
)")
●ReleaseDC(w,d)=DLL("user32.dll",
"int ReleaseDC(
HWND hWnd,
HDC hDC
)")
●EnumObjects(hdc,nObjectType,lpObjectFunc,lParam)=DLL("gdi32.dll",
"int EnumObjects(
HDC hdc,
int nObjectType,
int lpObjectFunc,
int lParam
)")
!OBJ_PEN=1
ログとはメモ
そのレイアウトは「全体」
hdesktopとは整数
hdcとは整数
テストとは関数ポインタ
その引数数は2
そのイベントは~
バッファとは文字列
バッファに16を確保
表示バッファとは文字列
MoveMemory(バッファ,INT(自身→引数[0]),16)
バッファの1を「int」でバイナリ取得
それで条件分岐
0ならば、それは「実線」
1ならば、それは「破線」
2ならば、それは「点線」
3ならば、それは「一点鎖線」
4ならば、それは「二点鎖線」
5ならば、それは「非表示」
6ならば、それは「塗りつぶし」
表示バッファは「ペンタイプ:」&それ&改行
バッファの5を「int」でバイナリ取得
表示バッファは表示バッファ&「X:」&それ
バッファの9を「int」でバイナリ取得
表示バッファは表示バッファ&「 Y:」&それ&改行
バッファの13を「int」でバイナリ取得
表示バッファは表示バッファ&「RGB:」&HEX(それ)&改行
ログのテキストはログのテキスト&表示バッファ
自身→返り値は10
hdesktop=GetDesktopWindow()
hdc=GetDC(hdesktop)
EnumObjects(hdc,OBJ_PEN,テストのダミー関数,100)
いう
ReleaseDC(hdesktop,hdc)#*/
#実行テスト2(子ウィンドウ列挙)
●EnumChildWindows(hWndParent,lpEnumFunc,lParam) =DLL("user32.dll",
"BOOL EnumChildWindows(
HWND hWndParent,
LPWNDENUMPROC lpEnumFunc,
LPARAM lParam
)")
●GetWindowText(hWnd,{参照渡し}lpString,nMaxCount) =DLL("user32.dll",
"int GetWindowTextA(
HWND hWnd,
LPTSTR lpString,
int nMaxCount
)")
●GetDesktopWindow()=DLL("user32.dll","HWND GetDesktopWindow()")
ログとはメモ
そのレイアウトは「全体」
テストとは関数ポインタ
その引数数は2
そのイベントは~
バッファとは文字列
表示バッファとは文字列
バッファに128を確保
GetWindowText(自身→引数[0],バッファ,127)
バッファのそれ バイト左部分
表示バッファは自身→引数[0]&「,」&それ&改行
ログのテキストはログのテキスト&表示バッファ
自身→返り値は1
EnumChildWindows(GetDesktopWindow(),テストのダミー関数,0)
----
#comment()
----
*情報
作者名:しらたま
引用元:[[なでしこプログラム掲示板「代用関数ポインタ」>http://www.himanavi.net/cgi/nade-bbs/cbbs.cgi?mode=al2&namber=809&rev=&no=0]]
*概要
なでしこで関数ポインタを扱えるようにする。
*本体
●VirtualAlloc({参照渡し}lpAddress,dwSize,flAllocationType,flProtect)=DLL("kernel32.dll",
"LPVOID VirtualAlloc(
LPVOID lpAddress,
int dwSize,
DWORD flAllocationType,
DWORD flProtect
)")
●VirtualFree({参照渡し}lpAddress,dwSize,dwFreeType)=DLL("kernel32.dll",
"BOOL VirtualFree(
LPVOID lpAddress,
int dwSize,
DWORD dwFreeType
)")
●MoveMemory({参照渡し}d,{参照渡し}s,l)=DLL("kernel32.dll",
"VOID RtlMoveMemory(
LPVOID Destination,
LPVOID Source,
int Length
)")
●GetProcAddress(hModule,{参照渡し}lpProcName)=DLL("kernel32.dll",
"DWORD GetProcAddress(
HMODULE hModule, // DLL モジュールのハンドル
LPCSTR lpProcName // 関数名
)")
●GetModuleHandle({参照渡し}ModuleName) =DLL("kernel32.dll",
"HMODULE GetModuleHandleA(
LPCTSTR ModuleName
)")
!MEM_COMMIT=$1000
!MEM_RELEASE=$8000
!PAGE_EXECUTE_READWRITE=$40
!変数宣言が必要
それ待避用スタックとは配列
●それプッシュ
それ待避用スタックにそれを配列追加
●それポップ
Aとは整数
Aはそれ待避用スタックの配列要素数
それはそれ待避用スタック[A-1]
それ待避用スタックのA-1を配列削除
●AddBinary({参照渡し}target,value,size)
MoveMemory(target,POINTER(value),size)
target=target+size
!関数ポインタ既定イベント名=「前処理」
!nako_group_execポインタ=GetProcAddress(GetModuleHandle(「dnako.dll」),「nako_group_exec」)
■関数ポインタ
・{イベント}イベント
・{整数}ダミー関数
・{非公開}前処理~
F引数数 回
引数[回数-1]=0
MoveMemory(POINTER(引数[回数-1]),スタックアドレス+4+4*回数,4)
自身→イベント
・{配列}引数
・{非公開 整数}スタックアドレス
・{整数}返り値
・{非公開}F引数数
・引数数←引数数設定→引数数取得
・{非公開}引数数設定(V)~
それプッシュ
pcとは整数
もしダミー関数=0ならば
ダミー関数はVirtualAlloc(0,64,MEM_COMMIT,PAGE_EXECUTE_READWRITE)
pc=ダミー関数
AddBinary(pc,$55,1) //push ebp
AddBinary(pc,$EC8B,2) //mov ebp,esp
pc-ダミー関数という
AddBinary(pc,$BA,1)
pc-ダミー関数という
AddBinary(pc,POINTER(スタックアドレス),4) //mov edx,POINTER(スタックアドレス)
AddBinary(pc,$2A89,2) //mov dword ptr [edx],ebp
AddBinary(pc,$68,1)
AddBinary(pc,POINTER(関数ポインタ既定イベント名),4) //push char*
AddBinary(pc,$68,1)
AddBinary(pc,ADDR(自身),4) //push PHiValue
AddBinary(pc,$B8,1)
AddBinary(pc,nako_group_execポインタ,4)//mov eax,nako_group_execポインタ
AddBinary(pc,$D0FF,2) //call eax
AddBinary(pc,$058B,2)
AddBinary(pc,POINTER(返り値),4) //mov eax,POINTER(返り値)
AddBinary(pc,$5D,1) //pop edp
AddBinary(pc,$C2,1)
AddBinary(pc,V*4,2) //ret 8
#AddBinary(pc,$00,1)
F引数数はV
それポップ
・{非公開}引数数取得~
それはF引数数
・作る~
スタックアドレスは0
返り値は0
ダミー関数=0
F引数数は-1
・解放~
VirtualFree(ダミー関数,0,MEM_RELEASE)
*//サンプルプログラム
#実行テスト1(GDIオブジェクト(ペン)列挙)
●GetDesktopWindow()=DLL("user32.dll","HWND GetDesktopWindow()")
●GetDC(hwnd)=DLL("user32.dll",
"HDC GetDC(
HWND hwnd
)")
●ReleaseDC(w,d)=DLL("user32.dll",
"int ReleaseDC(
HWND hWnd,
HDC hDC
)")
●EnumObjects(hdc,nObjectType,lpObjectFunc,lParam)=DLL("gdi32.dll",
"int EnumObjects(
HDC hdc,
int nObjectType,
int lpObjectFunc,
int lParam
)")
!OBJ_PEN=1
ログとはメモ
そのレイアウトは「全体」
hdesktopとは整数
hdcとは整数
テストとは関数ポインタ
その引数数は2
そのイベントは~
バッファとは文字列
バッファに16を確保
表示バッファとは文字列
MoveMemory(バッファ,INT(自身→引数[0]),16)
バッファの1を「int」でバイナリ取得
それで条件分岐
0ならば、それは「実線」
1ならば、それは「破線」
2ならば、それは「点線」
3ならば、それは「一点鎖線」
4ならば、それは「二点鎖線」
5ならば、それは「非表示」
6ならば、それは「塗りつぶし」
表示バッファは「ペンタイプ:」&それ&改行
バッファの5を「int」でバイナリ取得
表示バッファは表示バッファ&「X:」&それ
バッファの9を「int」でバイナリ取得
表示バッファは表示バッファ&「 Y:」&それ&改行
バッファの13を「int」でバイナリ取得
表示バッファは表示バッファ&「RGB:」&HEX(それ)&改行
ログのテキストはログのテキスト&表示バッファ
自身→返り値は10
hdesktop=GetDesktopWindow()
hdc=GetDC(hdesktop)
EnumObjects(hdc,OBJ_PEN,テストのダミー関数,100)
いう
ReleaseDC(hdesktop,hdc)#*/
#実行テスト2(子ウィンドウ列挙)
●EnumChildWindows(hWndParent,lpEnumFunc,lParam) =DLL("user32.dll",
"BOOL EnumChildWindows(
HWND hWndParent,
LPWNDENUMPROC lpEnumFunc,
LPARAM lParam
)")
●GetWindowText(hWnd,{参照渡し}lpString,nMaxCount) =DLL("user32.dll",
"int GetWindowTextA(
HWND hWnd,
LPTSTR lpString,
int nMaxCount
)")
●GetDesktopWindow()=DLL("user32.dll","HWND GetDesktopWindow()")
ログとはメモ
そのレイアウトは「全体」
テストとは関数ポインタ
その引数数は2
そのイベントは~
バッファとは文字列
表示バッファとは文字列
バッファに128を確保
GetWindowText(自身→引数[0],バッファ,127)
バッファのそれ バイト左部分
表示バッファは自身→引数[0]&「,」&それ&改行
ログのテキストはログのテキスト&表示バッファ
自身→返り値は1
EnumChildWindows(GetDesktopWindow(),テストのダミー関数,0)
----
#comment()
----