UWSCにできないことはない?
先日からフックだのなんだのと考えてた上に、stuncloudさんの構造体に関する扱いを見つけて、、、閃いてしまった、、、。
UWSCでできないと思い込んでいた、ある手法が可能なことを。
DEF_DLLが何回でもできるのも盲点でした。
UWSCで構造体がもうあんまり怖くないmodule | たっぷす庵
とりあえず見て欲しい
実行しても良いですけど、なんてことはありません。
Win32APIのMessageBoxが表示されるだけ。
、、、表示されるだけ、、、このすごさを判ってくれる人、どれだけいるだろう?
もちろん、こんなことしなくてもMessageBoxは表示できる。
そうなんですけどねー。
Asm.uws
OPTION EXPLICIT IFB GET_UWSC_NAME = "Asm.uws" THEN // return (DWORD)p->MessageBox(p->hWnd, &p->text + p->lstrlen(&p->text) + 1, &p->text, p->type); DIM addr = Asm.Set("Vot0JAiLTgyLFo1GEFFQUP/Si04Ii1YEjUQwEVBR/9JewgQA") DIM paraSize = 64, para = Asm.Alloc(paraSize), i = 0 IFB addr > 0 AND para > 0 THEN i = i + Asm.SetDword(para + i, Asm.GetProcAddress(Asm.hK32, "lstrlenA")) // p->lstrlen i = i + Asm.SetDword(para + i, Asm.GetProcAddress(Asm.hU32, "MessageBoxA")) // p->MessageBox i = i + Asm.SetDword(para + i, 0) // p->hWnd i = i + Asm.SetDword(para + i, 1) // p->type i = i + Asm.SetString(para + i, "苦労の割には") // p->text i = i + 1 // captionとの区切り。Asm.Allocはゼロクリアされている i = i + Asm.SetString(para + i, "MessageBoxが出るだけ") PRINT Asm.Run(addr, para, i) + " " + i //Asm.Dump(para, paraSize) // 解放 Asm.Free(para) Asm.Free(addr) ENDIF ENDIF MODULE Asm DEF_DLL GetLastError(): DWORD: kernel32 DEF_DLL VirtualAlloc(DWORD, DWORD, DWORD, DWORD): DWORD: kernel32 DEF_DLL VirtualFree(DWORD, DWORD, DWORD): bool: kernel32 DEF_DLL GetModuleHandleA(string): DWORD: kernel32 DEF_DLL GetProcAddress(DWORD, string): DWORD: kernel32 DEF_DLL CreateThread(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD): DWORD: kernel32 DEF_DLL WaitForSingleObject(DWORD, DWORD): DWORD: kernel32 DEF_DLL CloseHandle(DWORD): bool: kernel32 DEF_DLL GetExitCodeThread(DWORD, var DWORD): bool: kernel32 DEF_DLL CryptStringToBinaryA(string,DWORD,DWORD,var BYTE[],var DWORD,DWORD,var DWORD): bool: crypt32 PUBLIC hK32 PUBLIC hU32 PROCEDURE Asm hk32 = GetModuleHandleA("kernel32") hU32 = GetModuleHandleA("user32") FEND FUNCTION Set(code) DIM size = 0, flags = 6 RESULT = FALSE IFB CryptStringToBinaryA(code, 0, flags, NULL, size, 0, flags) AND size > 0 THEN DIM data[size-1] IFB CryptStringToBinaryA(code, 0, flags, data, size, 0, flags) THEN RESULT = VirtualAlloc(0, size, $1000, $40) ENDIF ENDIF IF RESULT THEN SetByte(RESULT, data) FEND FUNCTION Alloc(size) RESULT = VirtualAlloc(0, size, $1000, $4) FEND FUNCTION Free(addr) RESULT = VirtualFree(addr, 0, $8000) FEND // 戻りはtypeによって異なる // type=0 : スレッド終了コード // type=1 : スレッド終了コード取得失敗エラーコード // type=258 : スレッドハンドル // type=他 : その他エラーコード FUNCTION Run(addr, para, var type, timeout=$7FFFFFFF) DIM hThread = CreateThread(0, 0, addr, para, 0, 0), res = 0 RESULT = GetLastError() type = 258 IF timeout >= 0 THEN type = WaitForSingleObject(hThread, timeout) SELECT type CASE 0 IFB GetExitCodeThread(hThread, res) THEN RESULT = res ELSE type = 1 RESULT = GetLastError() ENDIF CloseHandle(hThread) CASE 258 RESULT = hThread SELEND FEND FUNCTION SetByte(p, data[]) DEF_DLL RtlMoveMemory(DWORD, BYTE[], DWORD): kernel32 RESULT = LENGTH(data) RtlMoveMemory(p, data, RESULT) FEND FUNCTION SetDword(p, data) DEF_DLL RtlMoveMemory(DWORD, var DWORD, DWORD): kernel32 RESULT = 4 RtlMoveMemory(p, data, RESULT) FEND FUNCTION SetString(p, data) DEF_DLL RtlMoveMemory(DWORD, string, DWORD): kernel32 RESULT = LENGTHB(data) RtlMoveMemory(p, data, RESULT) FEND FUNCTION GetDword(p) DEF_DLL RtlMoveMemory(var DWORD, DWORD, DWORD): kernel32 RESULT = 0 RtlMoveMemory(RESULT, p, 4) FEND PROCEDURE Dump(addr, size) DEF_DLL RtlMoveMemory(BYTE[], DWORD, DWORD): kernel32 DIM data[size], i, buf = "", bufa = "" RtlMoveMemory(data, addr, size) FOR i = 0 TO size - 1 buf = buf + FORMAT(data[i], 3, -1) IFB data[i] >= $20 AND data[i] < $7F THEN bufa = bufa + CHR(data[i]) ELSE bufa = bufa + "." ENDIF IFB i MOD 16 = 15 THEN PRINT buf + " " + bufa buf = "" bufa = "" ENDIF NEXT IF LENGTH(buf) THEN PRINT buf + FORMAT(" ", 49 - LENGTH(buf)) + bufa FEND ENDMODULE
MessageBox表示するだけなのに100行オーバーとか。
アホの極み。
解説
Asm.Setしているのは、だいたい以下のネイティブコードをBase64エンコードしたもの。
return (DWORD)p->MessageBox(p->hWnd, &p->text + p->lstrlen(&p->text) + 1, &p->text, p->type);
、、、だめだ、、、自主規制しようと思ったけど、あまりの嬉しさに書いてしまえ!
どうせスクリプトは載せたのだし、スクリプトキディではまだ何もできまい。
ネイティブコードを作るのも簡単じゃなす。
すごいのは、Asm.Run(いやホントにすごいのはUWSC)
CreateThreadしちゃってます。
CreateThreadできるってことは、、、関数ポインターがある、ということ。
関数ポインターがある、ということは、、、CallBack処理ができるということ。
SetWindowLongでウインドウのサブクラス化ができるということ。
DLLなしでFUKIDASIをカラフルにできるということ!(まだそれか!)
さらに言うならば、、、他のプロセスにコードインジェクションすることすらできるということ。
お、恐るべしUWSC。
ま、当たり前だよねー。
ポインターが使えるんだから、コードが書いてあれば関数ポインター。
頭が固かった、ということか。
技術力が少し上がった気がする。
stuncloudさんに乗せられて、FUKIDASI多色化を考えたおかげ。
でも、Win32APIはいつまで持つのだろうか。
追記 20120705
GetDword関数があった方が便利なことが多いので、追加。