static void UninstallIATHook() { LOGGING_DEBUG(lg) << "IAT hook cleanup started."; pgWeIatHooker.release(); LOGGING_TRACE(lg) << "WE IAT hook cleaned."; pgStormIatHooker.release(); LOGGING_TRACE(lg) << "Storm.dll IAT hook cleaned."; LOGGING_DEBUG(lg) << "IAT hook cleanup completed."; }
/* * Broadcast Logging service ready indication to any Logging application * Each netlink message will have a message of type tAniMsgHdr inside. */ void wlan_logging_srv_nl_ready_indication(void) { struct sk_buff *skb = NULL; struct nlmsghdr *nlh; tAniNlHdr *wnl = NULL; int payload_len; int err; static int rate_limit; payload_len = sizeof(tAniHdr) + sizeof(wlan_logging_ready) + sizeof(wnl->radio); skb = dev_alloc_skb(NLMSG_SPACE(payload_len)); if (NULL == skb) { if (!rate_limit) { LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "NLINK: skb alloc fail %s", __func__); } rate_limit = 1; return; } rate_limit = 0; nlh = nlmsg_put(skb, 0, 0, ANI_NL_MSG_LOG, payload_len, NLM_F_REQUEST); if (NULL == nlh) { LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_put() failed for msg size[%d]", __func__, payload_len); kfree_skb(skb); return; } wnl = (tAniNlHdr *) nlh; wnl->radio = 0; wnl->wmsg.type = ANI_NL_MSG_READY_IND_TYPE; wnl->wmsg.length = sizeof(wlan_logging_ready); memcpy((char*)&wnl->wmsg + sizeof(tAniHdr), wlan_logging_ready, sizeof(wlan_logging_ready)); /* sender is in group 1<<0 */ NETLINK_CB(skb).dst_group = WLAN_NLINK_MCAST_GRP_ID; /*multicast the message to all listening processes*/ err = nl_srv_bcast(skb); if (err) { LOGGING_TRACE(VOS_TRACE_LEVEL_INFO_LOW, "NLINK: Ready Indication Send Fail %s, err %d", __func__, err); } return; }
static void InitInlineHook() { LOGGING_DEBUG(lg) << "Start installing inline hooks."; pgTrueWeGetSystemParameter = (uintptr_t)0x004D1DB0; LOGGING_TRACE(lg) << base::format("Found WeGetSystemParameter at 0x%08X.", pgTrueWeGetSystemParameter); INSTALL_INLINE_HOOK(WeGetSystemParameter); pgTrueWeVerifyMapCellsLimit = (uintptr_t)0x004E1EF0; LOGGING_TRACE(lg) << base::format("Found WeVerifyMapCellsLimit at 0x%08X.", pgTrueWeVerifyMapCellsLimit); uint32_t callOffset = *(uint32_t*)(pgTrueWeVerifyMapCellsLimit + 6); pgMapCellsGetUnknownGlobalFlag = pgTrueWeVerifyMapCellsLimit + callOffset + 10; LOGGING_TRACE(lg) << base::format("Found GetUnkownFlag at 0x%08X.", pgMapCellsGetUnknownGlobalFlag); pgWeVerifyMapCellsLimitPatcher.reset(new CMemoryPatch((void*)(pgTrueWeVerifyMapCellsLimit + 3), "\x90\x90", 2)); pgWeVerifyMapCellsLimitPatcher->patch(); INSTALL_INLINE_HOOK(WeVerifyMapCellsLimit); pgTrueWeTriggerNameCheck = (uintptr_t)0x005A4B40; LOGGING_TRACE(lg) << base::format("Found WeTriggerNameCheck at 0x%08X.", pgTrueWeTriggerNameCheck); INSTALL_INLINE_HOOK(WeTriggerNameCheck) pgTrueWeTriggerNameInputCharCheck = (uintptr_t)0x0042E390; LOGGING_TRACE(lg) << base::format("Found WeTriggerNameInputCharCheck at 0x%08X.", pgTrueWeTriggerNameInputCharCheck); pgWeTriggerNameInputCharCheckPatcher.reset(new CMemoryPatch( (void*)(pgTrueWeTriggerNameInputCharCheck + 3), "\x90\x90", 2) ); pgWeTriggerNameInputCharCheckPatcher->patch(); INSTALL_INLINE_HOOK(WeTriggerNameInputCharCheck); pgTrueWeSetWindowCaption = (uintptr_t)0x00433A00; LOGGING_TRACE(lg) << base::format("Found WeSetWindowCaption at 0x%08X.", pgTrueWeSetWindowCaption); INSTALL_INLINE_HOOK(WeSetWindowCaption); pgTrueWeSetMenuItem = (uintptr_t)0x0042AA10; LOGGING_TRACE(lg) << base::format("Found WeSetMenuItem at 0x%08X.", pgTrueWeSetMenuItem); INSTALL_INLINE_HOOK(WeSetMenuItem); pgTrueWeStringCompare = (uintptr_t)0x004D2D90; LOGGING_TRACE(lg) << base::format("Found WeStringCompare at 0x%08X.", pgTrueWeStringCompare); INSTALL_INLINE_HOOK(WeStringCompare); pgTrueWeTriggerEditorEditboxCopy = (uintptr_t)0x0071FE90; LOGGING_TRACE(lg) << base::format("Found TriggerEditorEditboxCopy at 0x%08X.", pgTrueWeTriggerEditorEditboxCopy); INSTALL_INLINE_HOOK(WeTriggerEditorEditboxCopy); pgTrueWeUtf8ToAnsi = (uintptr_t)0x00429CD0; LOGGING_TRACE(lg) << base::format("Found WeUtf8ToAnsi at 0x%08X.", pgTrueWeUtf8ToAnsi); INSTALL_INLINE_HOOK(WeUtf8ToAnsi); LOGGING_DEBUG(lg) << "Installing inline hooks complete."; }
/* Utility function to send a netlink message to an application * in user space */ static int wlan_send_sock_msg_to_app(tAniHdr *wmsg, int radio, int src_mod, int pid) { int err = -1; int payload_len; int tot_msg_len; tAniNlHdr *wnl = NULL; struct sk_buff *skb; struct nlmsghdr *nlh; int wmsg_length = wmsg->length; static int nlmsg_seq; if (radio < 0 || radio > ANI_MAX_RADIOS) { LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: invalid radio id [%d]", __func__, radio); return -EINVAL; } payload_len = wmsg_length + sizeof(wnl->radio); tot_msg_len = NLMSG_SPACE(payload_len); skb = dev_alloc_skb(tot_msg_len); if (skb == NULL) { LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: dev_alloc_skb() failed for msg size[%d]", __func__, tot_msg_len); return -ENOMEM; } nlh = nlmsg_put(skb, pid, nlmsg_seq++, src_mod, payload_len, NLM_F_REQUEST); if (NULL == nlh) { LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: nlmsg_put() failed for msg size[%d]", __func__, tot_msg_len); kfree_skb(skb); return -ENOMEM; } wnl = (tAniNlHdr *) nlh; wnl->radio = radio; memcpy(&wnl->wmsg, wmsg, wmsg_length); err = nl_srv_ucast(skb, pid, MSG_DONTWAIT); if (err) { LOGGING_TRACE(VOS_TRACE_LEVEL_INFO, "%s: Failed sending Msg Type [0x%X] to pid[%d]\n", __func__, wmsg->type, pid); } return err; }
/* * Process all the Netlink messages from Logger Socket app in user space */ static int wlan_logging_proc_sock_rx_msg(struct sk_buff *skb) { tAniNlHdr *wnl; int radio; int type; int ret; wnl = (tAniNlHdr *) skb->data; radio = wnl->radio; type = wnl->nlh.nlmsg_type; if (radio < 0 || radio > ANI_MAX_RADIOS) { LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: invalid radio id [%d]\n", __func__, radio); return -EINVAL; } if (gapp_pid != INVALID_PID) { if (wnl->nlh.nlmsg_pid > gapp_pid) { gapp_pid = wnl->nlh.nlmsg_pid; } spin_lock_bh(&gwlan_logging.spin_lock); if (gwlan_logging.pcur_node->filled_length) { wlan_queue_logmsg_for_app(); } spin_unlock_bh(&gwlan_logging.spin_lock); gwlan_logging.wakeEvent = TRUE; wake_up_interruptible(&gwlan_logging.wait_queue); } else { /* This is to set the default levels (WLAN logging * default values not the VOS trace default) when * logger app is registered for the first time. */ gapp_pid = wnl->nlh.nlmsg_pid; set_default_logtoapp_log_level(); } ret = wlan_send_sock_msg_to_app(&wnl->wmsg, 0, ANI_NL_MSG_LOG, wnl->nlh.nlmsg_pid); if (ret < 0) { LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "wlan_send_sock_msg_to_app: failed"); } return ret; }
HANDLE WINAPI DetourWeCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { std::string fileName(lpFileName); std::string_view fileExt(fileName.data() + fileName.size() - 4, 4); if (std::string_view(fileName.data() + fileName.size() - 14, 14) == "war3mapMap.blp") { if (dwCreationDisposition == OPEN_EXISTING) { LOGGING_TRACE(lg) << "WE is about to compile maps."; gIsInCompileProcess = true; } else { gIsInCompileProcess = false; } } else if (gIsInCompileProcess && (fileExt == ".w3x" || fileExt == ".w3m")) { try { fs::path p(fileName); //p = p.parent_path().remove_filename() / p.filename(); event_array[EVENT_SAVE_MAP]([&](lua_State* L, int idx){ lua_pushstring(L, "map_path"); lua_pushwstring(L, p.wstring()); lua_settable(L, idx); }); } catch (...) { } } return base::std_call<HANDLE>(pgTrueCreateFileA, lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); }
void NativeInit() { CPEMemoryFileInfo pm; CPEMemoryFileInfo::TSectionInfoResult result = pm.querySection(".text"); uintptr_t pWeTextSectionBase = result->get<0>(); uint32_t weTextSectionLength = result->get<1>(); LOGGING_DEBUG(lg) << "WE native function initialization begins."; fpgWeTemplateStringTranslate = MemoryPatternSearch((void *)pWeTextSectionBase, weTextSectionLength, &gWeTemplateStringTranslatePattern[0], sizeof(gWeTemplateStringTranslatePattern)); LOGGING_TRACE(lg) << base::format("Found WeTranlateTemplateString at 0x%08X.", fpgWeTemplateStringTranslate); fpgWeMessageShow = MemoryPatternSearch((void *)pWeTextSectionBase, weTextSectionLength, &gWeMessageShowPattern[0], sizeof(gWeMessageShowPattern)); LOGGING_TRACE(lg) << base::format("Found WeMessageShow at 0x%08X.", fpgWeMessageShow); LOGGING_DEBUG(lg) << "WE native function initialization finished."; }
void LuaRegisterEvent(lua_State *pState, EVENT_ID evenetid, bool ignore_error, luabind::object const& func) { LOGGING_TRACE(lg) << "RegisterEvent id: " << evenetid << " ignore: " << (ignore_error ? "true" : "false"); if (evenetid >= 0 && evenetid < EVENT_MAXIMUM) { event_array[evenetid].connect (std::bind(LuaOnSignal, pState, std::placeholders::_1, ignore_error, func)); } }
/** * send_flush_completion_to_user() - Indicate flush completion to the user * * This function is used to send the flush completion message to user space * * Return: None */ void send_flush_completion_to_user(void) { uint32_t is_fatal, indicator, reason_code; vos_get_log_completion(&is_fatal, &indicator, &reason_code); /* Error on purpose, so that it will get logged in the kmsg */ LOGGING_TRACE(VOS_TRACE_LEVEL_ERROR, "%s: Sending flush done to userspace", __func__); wlan_report_log_completion(is_fatal, indicator, reason_code); }
static bool InstallPatch(const char* name, uintptr_t address, uint8_t *patch, uint32_t patchLength) { bool ok = MemoryPatchAndVerify((void*)address, patch, patchLength); if (ok) { LOGGING_TRACE(lg) << base::format("Patch %s in 0x%08X success.", name, address); } else { LOGGING_ERROR(lg) << base::format("Patch %s in 0x%08X failed.", name, address); } return ok; }
static void InitPatches() { LOGGING_DEBUG(lg) << "Patches initialization started."; // Syntax check patch LOGGING_TRACE(lg) << "Installing syntax check patch"; INSTALL_PATCH(syntaxCheck); // Auto disable trigger patch LOGGING_TRACE(lg) << "Installing auto disable patch"; INSTALL_PATCH(autoDisable); // Enable trigger check patch LOGGING_TRACE(lg) << "Installing enable trigger check patch"; INSTALL_PATCH(enableTriggerCheck1); INSTALL_PATCH(enableTriggerCheck2); LOGGING_TRACE(lg) << "Installing doodad limit patch"; INSTALL_PATCH(doodadLimit); LOGGING_TRACE(lg) << "Installing unit/item limit patch"; INSTALL_PATCH(unitItemLimit); LOGGING_TRACE(lg) << "Installing editor multi-instance patch"; INSTALL_PATCH(editorInstanceCheck); LOGGING_TRACE(lg) << "Installing attack table patch"; base::win::pe_reader module(GetModuleHandleW(NULL)); #define WE_ADDRESS(ADDR) ((uintptr_t)(ADDR) - 0x00400000 + (uintptr_t)module.module()) enum ATTACK_TABLE { WESTRING_UE_ATTACKTYPE_SPELLS = 0, WESTRING_UE_ATTACKTYPE_NORMAL, WESTRING_UE_ATTACKTYPE_PIERCE, WESTRING_UE_ATTACKTYPE_SIEGE, WESTRING_UE_ATTACKTYPE_MAGIC, WESTRING_UE_ATTACKTYPE_CHAOS, WESTRING_UE_ATTACKTYPE_HERO, }; uintptr_t attack_table_string[] = { WE_ADDRESS(0x007DF394), WE_ADDRESS(0x007DF374), WE_ADDRESS(0x007DF354), WE_ADDRESS(0x007DF334), WE_ADDRESS(0x007DF314), WE_ADDRESS(0x007DF2F4), WE_ADDRESS(0x007DF2D8), }; uintptr_t ptr = WE_ADDRESS(0x00784488); base::hook::replace_pointer(ptr, attack_table_string[WESTRING_UE_ATTACKTYPE_NORMAL]); ptr += 4; base::hook::replace_pointer(ptr, attack_table_string[WESTRING_UE_ATTACKTYPE_PIERCE]); ptr += 4; base::hook::replace_pointer(ptr, attack_table_string[WESTRING_UE_ATTACKTYPE_SIEGE]); ptr += 4; base::hook::replace_pointer(ptr, attack_table_string[WESTRING_UE_ATTACKTYPE_MAGIC]); ptr += 4; base::hook::replace_pointer(ptr, attack_table_string[WESTRING_UE_ATTACKTYPE_CHAOS]); ptr += 4; base::hook::replace_pointer(ptr, attack_table_string[WESTRING_UE_ATTACKTYPE_SPELLS]); ptr += 4; base::hook::replace_pointer(ptr, attack_table_string[WESTRING_UE_ATTACKTYPE_HERO]); ptr += 4; #undef WE_ADDRESS LOGGING_DEBUG(lg) << "Patches initialization completed."; }
BOOL WINAPI DetourWeCreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { std::cmatch matcher; if (lpCommandLine && std::regex_match(lpCommandLine, matcher, gRegexCommandLine)) { fs::path currentWarcraftMap = base::path::get(base::path::DIR_EXE).remove_filename() / matcher.str(1); LOGGING_TRACE(lg) << "Executing map " << currentWarcraftMap.wstring(); if (gIsInCompileProcess) { LOGGING_TRACE(lg) << "Need to compile..."; int results = event_array[EVENT_SAVE_MAP]([&](lua_State* L, int idx){ lua_pushstring(L, "map_path"); lua_pushwstring(L, currentWarcraftMap.wstring()); lua_settable(L, idx); }); gIsInCompileProcess = false; if (results < 0) { LOGGING_TRACE(lg) << "Save failed. Abort testing."; memset(lpProcessInformation, 0, sizeof(PROCESS_INFORMATION)); return FALSE; } } else { LOGGING_TRACE(lg) << "No need to compile."; } int results = event_array[EVENT_TEST_MAP]([&](lua_State* L, int idx){ lua_pushstring(L, "map_path"); lua_pushwstring(L, currentWarcraftMap.wstring()); lua_settable(L, idx); if (lpApplicationName) { lua_pushstring(L, "application_name"); lua_pushastring(L, lpApplicationName); lua_settable(L, idx); } if (lpCommandLine) { lua_pushstring(L, "command_line"); lua_pushastring(L, lpCommandLine); lua_settable(L, idx); } }); return results >= 0; } else { // Retain original return base::std_call<BOOL>(pgTrueCreateProcessA, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation ); } }