//apiHook 函数钩子 namespace raw { class apiHook { ctor ( dllName, apiName,apiProto,callback ) { if( type(callback) == type.string ){ var tmp = apiProto; apiProto = callback; callback = tmp; }; this.apiProto = apiProto; try{ this.dll = ..raw.loadDll(dllName) this.hModule = this.dll.gethandle(); } if (!this.hModule) { error("找不到 " + dllName, 2); } this.pTargetFunction = GetProcAddress(this.hModule, apiName); if (!this.pTargetFunction ) { this.pTargetFunction = GetProcAddress(this.hModule, apiName + "A"); } if (!this.pTargetFunction ) { error("找不到指定的函数!", 2); } if( type(callback) == type.function ){ this.callback_c = ..raw.tostdcall(callback, apiProto,this); this.addrHookFunction = getPointerAddress(this.callback_c) } else { this.addrHookFunction = tonumber(callback); if( !this.addrHookFunction ) error("参数@4必须指定钩子函数",2); } ..table.gc( this,"unInstall" ); } install = function () { var jmpOpCodeLen = 5; var threadCmpOpCodeLen = 20; var addrTargetFunction = tonumber(this.pTargetFunction ); var addrProtect = prcsHook.protect(addrTargetFunction, 0x40/*_PAGE_EXECUTE_READWRITE*/, jmpOpCodeLen * 2); if (!addrProtect) { error("修改内存属性失败!", 2); } var restoreOpCode = prcsHook.readString(addrTargetFunction,jmpOpCodeLen * 2); this.restoreOpCodeSize,restoreOpCode = getHookSize( restoreOpCode,jmpOpCodeLen ); prcsHook.protect(addrTargetFunction,addrProtect, jmpOpCodeLen * 2); var addrTargetFunction = tonumber(this.pTargetFunction ); this.addrTrampoline = prcsHook.malloc( this.restoreOpCodeSize + jmpOpCodeLen,0x40/*_PAGE_EXECUTE_READWRITE*/) this.addrThreadCheck = prcsHook.malloc( threadCmpOpCodeLen + jmpOpCodeLen,0x40/*_PAGE_EXECUTE_READWRITE*/) prcsHook.write( this.addrThreadCheck, '\x50', //push eax '\xB8', { addr getTid = getPointerAddress(GetCurrentThreadId) }, //mov eax,getTid '\xFF\xD0', //call eax '\x3D', {INT tid = ..thread.getId() }, //cmp eax,tid '\x58', //pop eax '\x0F\x84',{ addr hookFunc = this.addrHookFunction - (this.addrThreadCheck + threadCmpOpCodeLen) }, //je hookFunc '\xE9', { addr orgFunc = this.addrTrampoline - (this.addrThreadCheck + threadCmpOpCodeLen + jmpOpCodeLen) } //jmp orgFunc ) prcsHook.write( this.addrTrampoline,restoreOpCode, '\xE9'/*JMP*/, { int jmpAddr = addrTargetFunction + this.restoreOpCodeSize - (this.addrTrampoline + this.restoreOpCodeSize + jmpOpCodeLen ) } ) this.callApi = ..raw.main.api(topointer(this.addrTrampoline), this.apiProto ); var addrProtect = prcsHook.protect(addrTargetFunction, 0x40/*_PAGE_EXECUTE_READWRITE*/,jmpOpCodeLen); prcsHook.write( addrTargetFunction, '\xE9'/*JMP*/, { int jmpAddr = this.addrThreadCheck - (addrTargetFunction + jmpOpCodeLen) } ) prcsHook.protect(addrTargetFunction,addrProtect, jmpOpCodeLen); return this; } unInstall = function () { if (! this.addrTrampoline ) { return; } var addrProtect = prcsHook.protect(tonumber(this.pTargetFunction), 0x40/*_PAGE_EXECUTE_READWRITE*/,this.restoreOpCodeSize); prcsHook.writeString(tonumber(this.pTargetFunction),topointer(this.addrTrampoline) ,this.restoreOpCodeSize ); prcsHook.protect(tonumber(this.pTargetFunction),addrProtect, this.restoreOpCodeSize); prcsHook.mfree( this.addrTrampoline ); prcsHook.mfree(this.addrThreadCheck); this.addrTrampoline = null; this.addrThreadCheck = null; } } } namespace raw.apiHook { import ..process; import ..raw.asm.opCode; getHookSize = ..raw.asm.opCode.getHookSize; prcsHook = ..process(); GetProcAddress = ::Kernel32.api("GetProcAddress","pointer(pointer hModule,string lpProcName)"); GetCurrentThreadId = ::Kernel32.api( "GetCurrentThreadId", "INT()") getPointerAddress = function(p){ return ..raw.convert( { pointer arg = p }, { addr ret } ).ret; } } /**intellisense() raw.apiHook = 安装到当前线程的API函数钩子,不是来自当然线程的调用忽略。\n多线程钩子请使用 thread.apiHook raw.apiHook(DLL文件名,API函数名,函数原型,钩子函数) = @.apiHook(\n "user32.dll",\n "GetCursorPos",\n "bool(pointer lpPoint )", \n function( lpPoint ){\n owner.callApi(lpPoint); \n \n raw.mixin( lpPoint,{\n int x = 123; \n int y = 456 \n } );\n \n __/*可选通过 owner.callApi 调用原始函数,\n结构体等回调时必须传为指针参数,\n可通过 raw.mixin 修改修结构而不改变指针地址*/\n return true;\n }\n).install(); raw.apiHook() = !raw_apihook. !raw_apihook.install() = 安装钩子\n!raw_apihook. !raw_apihook.unInstall() = 卸载钩子 getPointerAddress(.(指针) = 返回数值类型指针地址 end intellisense**/ //http://bbs.aardio.com/forum.php?mod=viewthread&tid=970