免责声明:以下内容仅供学习使用
本文的工具成品下载见githubmythwarehelper仓库,附加资源也在内
已完成功能:杀死极域,获取极域安装路径,从注册表破解极域密码,重启极域,挂起极域,恢复极域,解除极域全屏窗口限制
搜索极域进程
极域主进程
极域的进程由StudentMain.exe
启动,因此,只需要使用CreateToolhelp32Snapshot
创建快照,遍历所有进程的所有模块,找到其中可执行文件为StudentMain.exe
那一个进程即可。
以下是代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| struct Jiyu { DWORD id; char filepath[260]; BOOL flag; } jiyu;
Jiyu ModuleIsAble(DWORD ProcessPid, LPCSTR Modulename) { Jiyu tj; if (Modulename[0] == '\0') { tj.flag = FALSE; return tj; } MODULEENTRY32 me; me.dwSize = sizeof(MODULEENTRY32); HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessPid); if (Module32First(hSnapshot, &me)) { do { if (!strcmp(Modulename, me.szModule)) { CloseHandle(hSnapshot); strcpy(tj.filepath, me.szExePath); tj.id = ProcessPid; tj.flag = TRUE; return tj; } } while (Module32Next(hSnapshot, &me)); } CloseHandle(hSnapshot); tj.flag = FALSE; return tj; }
Jiyu GetProcessPidFromFilename(LPCSTR Filename) { Jiyu tj; if (Filename[0] == '\0') { tj.flag = FALSE; return tj; } PROCESSENTRY32 te; te.dwSize = sizeof(PROCESSENTRY32); HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (Process32First(hSnapshot, &te)) { do { HANDLE temphandle = OpenProcess(PROCESS_ALL_ACCESS, false, te.th32ProcessID); tj = ModuleIsAble(te.th32ProcessID, Filename); if (tj.flag == TRUE) { CloseHandle(hSnapshot); return tj; } CloseHandle(temphandle); } while (Process32Next(hSnapshot, &te)); } tj.flag = FALSE; return tj; }
|
极域广播窗口
极域广播窗口是一个窗体,窗体标题固定为“屏幕广播”,因此可以直接使用FindWindow(LPCSTR lpClassName,LPCSTR lpWindowName)
函数来获取进程句柄,在第二个参数处填入窗体名即可
1 2 3 4 5 6 7 8 9
| HWND Class = FindWindowW(NULL, L"屏幕广播"); if (Class != NULL) { GetWindowThreadProcessId(Class, &pid); HANDlE ClassHandle = OpenThread(THREAD_ALL_ACCESS, false, GetMainThreadFromId(pid)); } else { }
|
获取极域安装路径(用来在杀死极域后重启)
极域安装路径存储在系统注册表SOFTWARE\\WOW6432Node\\TopDomain\\e-Learning Class Standard\\1.00\\TargetDirectory
以下为获取函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| UINT GetMythwarePathFromRegedit(char *str) { HKEY retKey; char tstr[200] = "SOFTWARE\\WOW6432Node\\TopDomain\\e-Learning Class Standard\\1.00"; DWORD dwDisposition = REG_OPENED_EXISTING_KEY; LONG ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, tstr, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &retKey, &dwDisposition); if (ret != ERROR_SUCCESS) { return FALSE; } BYTE tByte[MAX_PATH * 2 + 1]; DWORD nSize = MAX_PATH * 2 + 1; int sum = 0; ret = RegQueryValueEx(retKey, "TargetDirectory", NULL, NULL, tByte, &nSize); if (ret == ERROR_SUCCESS) { for (int i = 0; i < int(nSize); i += 1) { *(str + sum) = tByte[i]; if (*(str + sum++) == '\\') { *(str + sum++) = '\\'; } } return TRUE; } return FALSE; }
|
杀死极域进程
taskkill
在命令行中输入
taskkill /f /im studentmain.exe
即可杀死极域进程,但有时候会失效
ntsd
ntsd是一个用户态进程调试工具,从Windows 2000就开始被附随在System32目录下。它能够结束除System、smss.exe、csrss.exe、lsass.exe及各种rootkit程序外所有的程序。但在Windows Vista及以上版本的Windows中不含ntsd, 必须手动下载至电脑中才可使用。——百度百科
在命令行中输入
./ntsd.exe -c q -pn studentmain.exe
即可杀死极域进程,目前博主没有遇到失效的情况
如需下载ntsd.exe可访问我的mythwarehelper仓库
挂起和恢复极域进程
再不使用外部DLL的情况下,C++没有原生的挂起和回复进程的函数,因此不能白嫖 挂起进程只能自己实现,进程由线程构成,因此如果挂起了一个进程的每一个线程,就相当于是挂起了这个进程。挂起线程可使用SuspendThread
,恢复线程可使用ResumeThread
以下是代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
VOID SuspendProcess(DWORD dwProcessID, BOOL fSuspend) { HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, dwProcessID);
if (hSnapshot != INVALID_HANDLE_VALUE) {
THREADENTRY32 te = {sizeof(te)}; BOOL fOk = Thread32First(hSnapshot, &te); for (; fOk; fOk = Thread32Next(hSnapshot, &te)) { if (te.th32OwnerProcessID == dwProcessID) { HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID);
if (hThread != NULL) { if (fSuspend) { SuspendThread(hThread); } else { ResumeThread(hThread); } } CloseHandle(hThread); } } CloseHandle(hSnapshot); } }
|
解除全屏按钮限制
极域的广播窗口有一个全屏切换按钮,在强制全屏时会设置为无法使用,变成灰色,Windows的按钮即为控件,交互式控件有两个状态,一个是可用,一个是不可用,可以通过调用EnableWindow
函数来设置此类控件的状态,也可以借此设置全屏切换按钮的状态,在老师设置按钮为不可用时,调用此函数设置按钮为可用,就可以自行退出全屏了
以下是代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| BOOL CALLBACK EnumChildWindowsProc(HWND hwndChild, LPARAM lParam) { HMENU hmenu = GetMenu(hwndChild); if (LOWORD(hmenu) == 1004) { if (!IsWindowEnabled(hwndChild)) { EnableWindow(hwndChild, TRUE); } else { EnableWindow(hwndChild, FALSE); } return FALSE; } return TRUE; }
|
破解极域密码
极域的密码存储在系统注册表SOFTWARE\\TopDomain\\e-Learning Class\\Student
极域的密码在部分版本中使用明文存储,但新版都是存储的密文
解密代码来源
解密分析视频
以下是破解代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| BOOL GetMythwarePasswordFromRegedit(char *str) { HKEY retKey; BYTE retKeyVal[MAX_PATH * 10] = { 0 }; DWORD nSize = MAX_PATH * 10; LONG ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\TopDomain\\e-Learning Class\\Student", 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &retKey); if (ret != ERROR_SUCCESS) { return FALSE; } ret = RegQueryValueExA(retKey, "knock1", NULL, NULL, (LPBYTE)retKeyVal, &nSize); RegCloseKey(retKey); if (ret != ERROR_SUCCESS) { return FALSE; } for (int i = 0; i < int(nSize); i += 4) { retKeyVal[i + 0] = (retKeyVal[i + 0] ^ 0x50 ^ 0x45); retKeyVal[i + 1] = (retKeyVal[i + 1] ^ 0x43 ^ 0x4c); retKeyVal[i + 2] = (retKeyVal[i + 2] ^ 0x4c ^ 0x43); retKeyVal[i + 3] = (retKeyVal[i + 3] ^ 0x45 ^ 0x50); } for (int i = 0; i < int(nSize); i += 1) { printf("%x ", retKeyVal[i]); if (i % 8 == 0) puts(""); } int sum = 0; for (int i = 0; i < int(nSize); i += 1) { if (retKeyVal[i + 1] == 0) { *(str + sum) = retKeyVal[i]; sum++; if (retKeyVal[i] == 0) break; } } return TRUE; }
|