static void lua_code_exec (Package *pkg) { static lua_State *L = 0; xmono::LuaExecRsp rsp; xmono::LuaExecReq req; MonoThread *thread = mono_thread_attach (mono_domain_get_by_id (0)); do { if (L == 0 && !(L = lua_env_new ())) { rsp.set_level (xmono::LuaExecRsp::err); rsp.set_message ("create a lua_State err."); break; } std::string str((char*)pkg->body, pkg->all_len - sizeof (Package)); //Fixme : 修复头部all_len是总长的问题 if (!req.ParseFromString (str)) { LOGD ("xmono::LuaExecReq ParseFromString err!"); return; } if (luaL_dostring (L, req.lua_code ().c_str ())) { rsp.set_level (xmono::LuaExecRsp::err); rsp.set_message (lua_tostring (L, -1)); break; } rsp.set_level (xmono::LuaExecRsp::debug); rsp.set_message ("exec the lua string ok."); } while (0); mono_thread_detach (thread); std::string out; rsp.SerializeToString (&out); ecmd_send (XMONO_ID_LUA_EXEC_RSP, (uint8_t const*)out.c_str (), out.size ()); return; }
~MonoAttachment() { if (thread) { mono_thread_detach(thread); thread = nullptr; } }
CPipeServer::~CPipeServer(void) { if (attached) { mono_thread_detach(mono_selfthread); attached=FALSE; } }
void detach_current_thread() { ERR_FAIL_COND(!GDMono::get_singleton()->is_runtime_initialized()); MonoThread *mono_thread = mono_thread_current(); ERR_FAIL_NULL(mono_thread); mono_thread_detach(mono_thread); }
static void replace_method (Package *pkg) { xmono::ReplaceMethodReq req; xmono::ReplaceMethodRsp rsp; std::string str((char*)pkg->body, pkg->all_len - sizeof (Package)); if (!req.ParseFromString (str)) { LOGD ("xmono::ReplaceMethodReq ParseFromString err!"); return; } std::string err; void *p, *old_p; uint8_t *code; int code_size; MonoMethodHeader *mh; MonoThread *thread; MonoMethod *new_method; MonoDomain *domain; MonoMethod * method = get_method_with_token (req.image_name ().c_str (), req.method_token ()); if (!method) { rsp.set_err (false); rsp.set_msg (helper_last_err ()); goto replace_method_end; } domain = mono_domain_get_by_id (req.domain_id ()); if (!domain) { rsp.set_err (false); rsp.set_msg ("can not get the domain from id"); goto replace_method_end; } mh = mono_method_get_header (method); if (req.ex_size () != mono_method_header_get_num_clauses (mh)) { rsp.set_err (false); rsp.set_msg ("ex size != mono_method_header_clauses size!"); goto replace_method_end; } for (int i = 0; i < req.ex_size (); i++) { xmono::ReplaceMethodReq_ExceptionClause const &e = req.ex (i); void *iter = 0; MonoExceptionClause *clauses = &mh->clauses[i]; MonoExceptionClause *old_e = (MonoExceptionClause*)iter; old_e->try_offset = e.try_offset (); old_e->try_len = e.try_len (); old_e->handler_offset = e.handler_offset (); old_e->handler_len = e.handler_len (); } code = new uint8_t[req.new_code ().size ()]; memcpy (code, req.new_code ().c_str (), req.new_code ().size ()); mh->code = code; mh->code_size = req.new_code ().size (); thread = mono_thread_attach (domain); /*128 是一个估计值, 在未来可能不稳定, 但当前只能如此*/ new_method = (MonoMethod*)calloc (128, 1); /*这个地方用malloc优于用new*/ memcpy (new_method, method, 128); pthread_mutex_lock (&replace_mutex); replace_method_dict[new_method] = true; pthread_mutex_unlock (&replace_mutex); p = mono_compile_method (new_method); memcpy (hooked_method_dict[method]->specific_hook + 4, &p, 4); pthread_mutex_lock (&hooked_mutex); old_p = mono_jit_info_get_code_start (hooked_method_dict[method]->jinfo); pthread_mutex_unlock (&hooked_mutex); mono_thread_detach (thread); LOGD ("compile method, new ptr : %p, old ptr : %p", p, old_p); rsp.set_err (true); rsp.set_msg ("replace_method successful."); replace_method_end: std::string out; rsp.SerializeToString (&out); ecmd_send (XMONO_ID_REPLACE_METHOD_RSP, (uint8_t const*)out.c_str (), out.size ()); return; }
void CPipeServer::Start(void) { BYTE command; while (TRUE) { CreatePipeandWaitForconnect(); try { while (TRUE) { command=ReadByte(); switch(command) { case MONOCMD_INITMONO: InitMono(); break; case MONOCMD_OBJECT_GETCLASS: Object_GetClass(); break; case MONOCMD_ENUMDOMAINS: EnumDomains(); break; case MONOCMD_SETCURRENTDOMAIN: SetCurrentDomain(); break; case MONOCMD_ENUMASSEMBLIES: EnumAssemblies(); break; case MONOCMD_GETIMAGEFROMASSEMBLY: GetImageFromAssembly(); break; case MONOCMD_GETIMAGENAME: GetImageName(); break; case MONOCMD_ENUMCLASSESINIMAGE: EnumClassesInImage(); break; case MONOCMD_ENUMFIELDSINCLASS: EnumFieldsInClass(); break; case MONOCMD_ENUMMETHODSINCLASS: EnumMethodsInClass(); break; case MONOCMD_COMPILEMETHOD: CompileMethod(); break; case MONOCMD_GETMETHODHEADER: GetMethodHeader(); break; case MONOCMD_GETMETHODHEADER_CODE: GetILCode(); break; case MONOCMD_LOOKUPRVA: RvaMap(); break; case MONOCMD_GETJITINFO: GetJitInfo(); break; case MONOCMD_FINDCLASS: FindClass(); break; case MONOCMD_FINDMETHOD: FindMethod(); break; case MONOCMD_GETMETHODNAME: GetMethodName(); break; case MONOCMD_GETMETHODCLASS: GetMethodClass(); break; case MONOCMD_GETCLASSNAME: GetKlassName(); break; case MONOCMD_GETCLASSNAMESPACE: GetClassNamespace(); break; case MONOCMD_FREEMETHOD: FreeMethod(); break; case MONOCMD_TERMINATE: return; case MONOCMD_DISASSEMBLE: DisassembleMethod(); break; case MONOCMD_GETMETHODSIGNATURE: GetMethodSignature(); break; case MONOCMD_GETPARENTCLASS: GetParentClass(); break; case MONOCMD_GETSTATICFIELDADDRESSFROMCLASS: GetStaticFieldAddressFromClass(); break; } } } catch (char *e) { //Pipe error, or something else that wasn't caught. Exit the connection and start over OutputDebugStringA("Pipe error:\n"); OutputDebugStringA(e); if (attached) { mono_thread_detach(mono_selfthread); attached=FALSE; } } catch (...) { OutputDebugStringA("Unexpected pipe error\n"); if (attached) { mono_thread_detach(mono_selfthread); attached=FALSE; } } } }