本文内容仅供学习,不得用于商业用途,使用本工具造成的任何后果与本软件及其作者无关!
本软件最新版是1.2。传送门
使用说明
源码也在内!
下载:https://wwt.lanzoub.com/b00pu06li
密码:bbzl
GitHub:https://github.com/BengbuGuards/MythwareToolkit/
GitHub上的版本库持续更新中,欢迎星标以追踪更新!
任务栏托盘图标
直接点击关闭按钮或最小化时大图标从任务栏隐藏,会藏到任务栏托盘
快捷键
Alt+C双击杀掉当前进程,Alt+W最小化顶层窗口(也可以把鼠标移动到屏幕左上角,移动到右上角可关闭窗口,默认关闭此功能),Alt+B唤起主窗口
下面是原理
杀掉极域进程
大多数工具都用了ntsd或taskkill来杀进程,不过容易被封杀(机房助手已经禁用了,映像劫持)。去除控制使用的方法,具体是暴力杀线程(即下方方法)或者清零ntdll基址(强制卸载ntdll模块,代码中存在,但是没有使用)。为什么不用最简单的TerminateProcess()
?请看:
这个函数被极域hook了(其实准确地说它hook的发挥作用的函数是NtOpenProcess()
,SSDT Hook,无论哪个程序调用都被它拦),如果结束的是极域的进程,就拦截。其实有个简单的办法:
#define KILL_FORCE 1
#define KILL_DEFAULT 2
//用杀掉每个线程的方法解决某些进程hook住了TerminateProcess()的问题
bool KillProcess(DWORD dwProcessID, int way) {
if (way == KILL_FORCE) {
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessID);
if (hSnapshot != INVALID_HANDLE_VALUE) {
bool rtn = false;
THREADENTRY32 te = {sizeof(te)};
BOOL fOk = Thread32First(hSnapshot, &te);
for (; fOk; fOk = Thread32Next(hSnapshot, &te)) {
if (te.th32OwnerProcessID == dwProcessID) {
HANDLE hThread = OpenThread(THREAD_TERMINATE, FALSE, te.th32ThreadID);
if (TerminateThread(hThread, 0)) rtn = true;
CloseHandle(hThread);
}
}
CloseHandle(hSnapshot);
return rtn;
}
return false;
} else if (way == KILL_DEFAULT) {
//默认方法,稳定安全
HANDLE handle = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessID);
WINBOOL sta = TerminateProcess(handle, 0);
CloseHandle(handle);
return sta;
}
return false;
}
如果把进程看作一个团伙,那么线程就是团伙的成员,如果把每个成员都干掉了,那么这个团伙就也完蛋了。极域并没有hookTerminateThread()
,所以用这种办法来干掉进程。
有些反极域软件声称是驱动级杀进程,其实没这个必要,又不是终止杀毒软件,用驱动开销太大了。
挂起(即冻结)/恢复极域
原理详见win32 判断进程状态(挂起/运行中)、用API挂起/恢复进程。挂起极域后,老师那里显示的屏幕被冻结,固定画面,时间长一些可能会掉线。
破解密码
这里用的是这个文章的算法,原算法位于https://github.com/MuliMuri/Mythware/blob/master/Test/Program.cs,由此博文作者改写:(更新中)极域破解分析(杀死和重启,挂起和恢复,解除全屏按钮限制,解除键盘锁,获取极域安装路径,极域密码破解)
杀掉学生机房管理助手
机房助手有两个进程,prozs.exe
和jfglzs.exe
,其中prozs.exe
的名字是随机的,每天都不一样,具体看我的文章:
最新支持7.2!用C++干掉讨厌的学生机房管理助手
全网首发!逆向分析学生机房管理助手7.4随机进程名算法
逆向分析学生机房管理助手7.5随机进程名算法
逆向分析学生机房管理助手7.8随机进程名算法
这里支持7.8,7.5、7.4、7.2和7.1以下版本,还有更古老的,名字是固定的(是哪几个进程看这里:【去除控制】对学生机房管理助手6.8的分析与突破(链接已失效)),估计也没有什么机房还用这么老的版本,就不做支持了
char version[6];//考虑极端值如6.9.5
HKEY retKey;
LONG ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\WOW6432Node\\ZM软件工作室\\学生机房管理助手", 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &retKey);
DWORD size = sizeof(version);
RegQueryValueEx(retKey, "Version", NULL, NULL, (LPBYTE)&version, &size);
RegCloseKey(retKey);
if (ret != ERROR_SUCCESS) {
SetWindowText(TxOut, "执行失败,可能未安装学生机房管理助手");
break;
}
//取时间用于计算prozs.exe的随机进程名
SYSTEMTIME time;
GetLocalTime(&time);
int n3 = time.wMonth + time.wDay;
int n4, n5, n6;
DWORD prozsPid;
if (version[0] == '7' &&(version[2] == '5' || version[2] == '8')) {
//以下为7.5、7.8版本逻辑
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (Process32First(hSnapshot, &pe)) {
do {
//筛选长度为10(7.5)或大于等于4(7.8)的进程名(不包含末尾“.exe”)
size_t uImageLength = strlen(pe.szExeFile);
if ((version[2] == '5')?(uImageLength == 14):(uImageLength >= 8)) {
//遍历字符
for (size_t j = 0; ((version[2] == '5')?(j < 10):(j < uImageLength - 4)); j++) {
char n7 = pe.szExeFile[j];
//符不符合d-m之间
if (!(n7 >= 100 && n7 <= 109))goto IL_226;
}
//就是你!
sLog += pe.szExeFile;
prozsPid = pe.th32ProcessID;
break;
}
IL_226:;
} while (Process32Next(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
} else if (version[0] == '7' && version[2] == '4') {
//以下为7.4版本逻辑
char c1, c2, c3, c4;
n3 = time.wMonth * time.wDay, n4 = n3 % 7, n5 = n3 % 5, n6 = n3 % 3;
int n = n3 % 9;
if (n3 % 2 == 0) {
c1 = 108 + n4, c2 = 75 + n, c3 = 98 + n5, c4 = 65 + n6;
} else {
c1 = 98 + n, c2 = 65 + n4, c3 = 108 + n5, c4 = 75 + n6;
}
char c[5] = {c1, c2, c3, c4, '\0'};
prozsPid = GetProcessIDFromName(strcat(c, ".exe"));
} else if (version[0] == '7' && version[2] == '2') {
char c1, c2, c3, c4;
//以下为7.2版本逻辑
n4 = n3 % 7, n5 = n3 % 9, n6 = n3 % 5;
if (n3 % 2 != 0) {
c1 = 103 + n5, c2 = 111 + n4, c3 = 107 + n6, c4 = 48 + n4;
} else {
c1 = 97 + n4, c2 = 109 + n5, c3 = 101 + n6, c4 = 48 + n5;
}
char c[5] = {c1, c2, c3, c4, '\0'};
prozsPid = GetProcessIDFromName(strcat(c, ".exe"));
} else {
//以下为7.2版本之前的逻辑
n4 = n3 % 3 + 3, n5 = n3 % 4 + 4;
char c[4] = {'p'};
if (n3 % 2 != 0)
c[1] = n4 + 102, c[2] = n5 + 98;
else
c[1] = n4 + 99, c[2] = n5 + 106;
prozsPid = GetProcessIDFromName(strcat(c, ".exe"));
}
KillProcess(prozsPid, KILL_DEFAULT);
KillProcess(GetProcessIDFromName("jfglzs.exe"), KILL_DEFAULT);
//停止zmserv服务防止关机
SC_HANDLE sc = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
SC_HANDLE zm = OpenService(sc, TEXT("zmserv"), SERVICE_STOP);
SERVICE_STATUS ss = {};
ControlService(zm, SERVICE_CONTROL_STOP, &ss);
CloseServiceHandle(sc);
CloseServiceHandle(zm);
不过有个问题:在半夜12点前启动机房助手,过了12点再启动本程序,算出的进程名为新一天的。解决办法也不难:重启电脑,或者临时改系统时间为机房助手启动时的时间,在这个时间杀掉进程即可。
解除一些系统工具的禁用和重启资源管理器
原理是改注册表键值,详见此文:改注册表实现解禁部分系统功能。失败的话,用管理员权限运行,也有可能是杀毒软件拦截。
重启资源管理器的办法,我最初是先终止explorer.exe再命令行启动,但是后来发现一个简单的办法:
HWND hwnd = FindWindow("Shell_TrayWnd", NULL);//有这个类名的窗口一定隶属于explorer.exe
DWORD pid;
GetWindowThreadProcessId(hwnd, &pid);//反查出窗口PID
if (pid == 0 || hwnd == NULL) { //资源管理器没在运行
WinExec("explorer.exe", SW_SHOW);//先直接运行,系统检测到explorer.exe是系统权限会自动重启它以降权(否则权限被继承,出现奇妙问题)
return;
//pid = GetProcessIDFromName("explorer.exe");
}
HANDLE handle = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
TerminateProcess(handle, 2);//退出码为2
CloseHandle(handle);
Shell_TrayWnd
这个窗口类名属于任务栏,任务栏又属于explorer.exe,用这个办法,可以得到explorer.exe的pid而无需用进程快照Toolhelp32
遍历进程。退出码为2,终止进程后,系统认为它异常崩溃了,经过复杂的调用,最终winlogon.exe(Windows 登录应用程序)会自动重启它。
需要说明的是,解除USB的限制是改了机房助手的注册表,防止蓝屏,而不是改系统的注册表键值(机房助手也说明了嘛,非注册表法)
黑屏或者全屏广播怎么办(最小化和关闭窗口)
用Timer
每秒计时,然后判断鼠标是否在屏幕左上角,如果在,就弹出提示框,可以最小化当前窗口
实现:(写在Timer
的事件中)
//写在程序前面定义处!
POINT p;
//检测鼠标左上角事件
GetCursorPos(&p);
if (p.x == 0 && p.y == 0) {
HWND topHwnd = GetForegroundWindow();
if (MessageBox(hwnd,"检测到了鼠标位置变化!是否最小化置顶窗口?", "实时监测", MB_YESNO | MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TOPMOST) == IDYES) {
ShowWindow(topHwnd, SW_MINIMIZE);
}
}
这样,控制窗口就最小化到任务栏了,可以随时恢复。
如下方法可以关闭窗口
选择“关闭”:
PostMessage(topHwnd,WM_CLOSE,0,0);//异步
这里是向窗口发送了关闭消息,就是按下Alt+F4的效果。有些窗口拦截此消息,这样的话就无效了。至于为什么要用PostMessage()
而不是SendMessage()
呢?前者只是把消息放进队列里就返回了,而后者则等消息处理完,返回结果才继续,在此期间会堵塞执行。例如,使用后者向桌面发送消息,会弹出关闭Windows的窗口,此时发送者程序将会无响应,直到用户对弹出窗口作出操作,前者则不会。
选择“强制关闭”(对UWP窗口无效):
//创建一个透明零大小的父窗口
HWND hParent = CreateWindowEx(0, WC_STATIC/*头文件commctrl.h*/, "", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
//将目标窗口设为子窗口
SetParent(topHwnd, hParent);
//关闭父窗口,子窗口也将一并销毁
PostMessage(hParent, WM_CLOSE, 0, 0);
若是目标窗口拦截WM_CLOSE
消息,前面的方法就无效了,而这个可以。为什么?如果窗口没拦截WM_CLOSE
,就会调用DefWindowProc()
,这个函数对WM_CLOSE
的处理是调用DestroyWindow()
,它负责销毁窗口、删除计时器、销毁子窗口和发送WM_DESTROY
消息等操作,但是必须要在窗口所处的线程调用它才行,否则返回ERROR_ACCESS_DENIED
拒绝访问。
但是它有个bug,它会销毁子窗口,而不管这个子窗口是否属于调用线程,那么我们自己新建一个窗口,把目标窗口设为它的子窗口,然后销毁我们新建的窗口,子窗口也就一并销毁。SetParent()
这个函数虽然文档说是同一个线程才行,但是实际上没有这种限制,就给了我们可乘之机。
广播窗口化
很多其他博客都说用SetWindowLong()
设置极域广播窗口样式来显示菜单栏,把广播和全屏时的样式记下来调用即可。事实上,这样做确实可以显示工具条来,但是一旦你尝试拖动边边调整大小,它会不屈地尝试填满屏幕。也就是说,在全屏状态下,哪怕你用各种办法调整了它的大小,它也会复原,这种方法无效!
有些时候,极域窗口化广播时会显示一个工具条,其中一个按钮是全屏按钮,可以自如在全屏与窗口之间切换。而全屏广播时它会不见,并且就算你弄出来了,它也是灰色的,禁用状态。用spy++查看广播窗口,可以发现工具条没有消失,只是沉底了而已,并且全屏按钮的控件ID是1004
。
我们知道,当点击一个控件后,会发送WM_COMMAND
消息给窗口,其中的wParam
参数包含了动作(高位)与ID(低位)信息。极域是MFC程序,也是这样子的。那么,我们就可以模拟点击,发送消息给它,它会以为全屏按钮可用并照做,就能实现广播窗口化。再发送一次就能复原。代码:
//获取广播窗口句柄
HWND bdCst = FindWindow(NULL, "屏幕广播");
//模拟点击
PostMessage(bdCst, WM_COMMAND, WPARAM((BM_CLICK << 16) | 1004), NULL);
解断网限制
极域的断网分多种,有完全不能上网(右下角图标有感叹号)、白/黑名单(没有感叹号,但是出现“该网页已被阻止!”,实现这些极域也是各有分工,既有驱动,也有网关服务。那么通过反编译和其他分析(【干货最多】逆向分析学生机房管理助手7.8随机进程名算法、极域U盘、网络、键盘限制,还没写完),我们的思路就是想欺骗驱动,然后杀了网关服务及其守护进程,再干脆干掉驱动。
//以下代码依然不稳定!!!
//发送终止指令
HANDLE hNetFilter = CreateFile("\\\\.\\TDNetFilter", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if(!GetLastError()){
DeviceIoControl(hNetFilter, 0x120014, NULL, 0, NULL, 0, NULL, 0);
CloseHandle(hNetFilter);
}
//杀掉网关服务及其守护进程
KillProcess(GetProcessIDFromName("MasterHelper.exe"),KILL_DEFAULT);
KillProcess(GetProcessIDFromName("GATESRV.exe"),KILL_DEFAULT);
//停止网络过滤驱动
SC_HANDLE sc = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
SC_HANDLE hFilt = OpenService(sc, "TDNetFilter", SERVICE_STOP | DELETE);
SERVICE_STATUS ss = {};
ControlService(hFilt, SERVICE_CONTROL_STOP, &ss);
DeleteService(hFilt);
CloseServiceHandle(sc);
CloseServiceHandle(hFilt);
解禁USB
详见此博客。
解键盘锁
解锁方法参考了https://www.52pojie.cn/thread-542884-1-1.html,表示感谢
具体分析参见对极域64位禁止终止进程、键盘锁定的分析
极域会有键盘锁,也是Hook。Hook有个特点就是后来居上,你先Hook,我再Hook,那最后优先生效的就是我的。那就好办,覆盖它就好!不过极域定时锁键盘,所以要循环。
HHOOK kbdHook;
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam){
return FALSE;
}
DWORD WINAPI KeyHookThreadProc(LPVOID lpParameter) {
while (true) {
kbdHook = (HHOOK)SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)HookProc, GetModuleHandle(NULL), 0);
Sleep(25);
UnhookWindowsHookEx(kbdHook);
}
return 0;
}
为了随时开启和关闭,新建一个线程,不用就挂起,需要就恢复。原文没有Sleep()
延时,吃CPU,加上延时25ms即可。
可能会出现解锁后,大多数按键可以正常使用,但是Ctrl+Alt+Delete无法使用的情况,这是因为WH_KEYBOARD_LL
这个系统hook没法拦住这三个键,极域就装了个底层的键盘驱动来拦截,这个在应用层很难恢复,想卸载它,还比较麻烦。
而最终的解决方案便是欺骗这个键盘驱动,如下所示:(控制码可通过IDA Pro反编译得到)
//打开符号链接
HANDLE hDevice = CreateFile("\\\\.\\TDKeybd", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (!GetLastError()) {
BOOL bEnable = TRUE;
//发送控制代码
DeviceIoControl(hDevice, 0x220000, &bEnable, 4, NULL, 0, NULL, NULL));
CloseHandle(hDevice);
}
另外一个软件JiYuTrainer(破解极域电子教室,老师再也控制不了我了!极域电子教室防控制)给极域注入了dll不让它锁键盘,算是治根了。
启动置顶任务管理器
好多软件都有类似功能,但是都是启动后自己循环调用SetWindowPos()
置顶它,其实这与它自带的置顶功能是不同的,win10/11的任务管理器勾选“置于顶层”后,可以覆盖住大多数窗口(包括极域还有绝大多数软件,当然也包括你自己置顶的窗口)因为它们都不是一个Z序段了。其实它用了一个未文档化的函数CreateWindowInBand()
,这个函数只有微软自己的程序才能用。如果我们要置顶任务管理器,可行的方法就是模拟勾选“置于顶层”。
用spy++可以得到“置于顶层”这个菜单项的ID:0x7704
(Windows 10),向任务管理器发送WM_COMMAND
,wParam就填这个ID,任务管理器就会觉得你勾选了它,会自动置顶。(当然如果已经置顶,它就会取消置顶,所以我们必须事先判断勾选没,没勾选才发送。)
//判断有没有启动
HWND h=FindWindow("TaskManagerWindow", NULL);
if(!h){
//如果还没有就先启动
WinExec("taskmgr", SW_SHOW);
do{
//等待窗口创建完成
Sleep(50);
h=FindWindow("TaskManagerWindow", NULL);
}while(!h);
}
//获取菜单,取得勾选状态
HMENU hm = GetMenu(h);
MENUITEMINFO mii = {sizeof(MENUITEMINFO), MIIM_STATE};
GetMenuItemInfo(hm, 0x7704, FALSE, &mii);
//如果未勾选就模拟勾选
if(!(mii.fState & MFS_CHECKED))
PostMessage(h, WM_COMMAND, 0x7704, 0);
顺便说说
这个程序是win32程序,无需易语言或MFC,用Dev C++就可以打开开发,方便大家学习哈。编译环境选择高版本的MinGW GCC即可。
附录1:学生机房管理助手的软件黑名单(9.0版本)
进程名包含这些词就会蓝屏(加粗的名字不仅匹配进程名,还匹配窗口名):
vmware、VirtualBox、Virtual PC、虚拟机、电子教室、ProcView、IceSword、Procmast.exe、ProcessManager.exe、rstray.exe、PFW.exe、FTCleaner.exe、Wsyscheck.exe、XueTr.exe、prom.exe、ProcessX.exe、pchunter、Killer.exe、procmgr.exe、ProcessHacker.exe、killcontrol、PowerTool32.exe、360taskmgr、YtWinAst、KVFWMain.exe、ECQ-PS.exe、SnipeSword、procexp、MsgFlood.exe、ProcessOVER、procdeal、桌面、任务、进程、Prayaya、dexpot.exe、vdeskman.exe、mdesk.exe、virtualdesk、multideskt.exe、VirDsk.exe、IDesktop.exe、YtMDesk.exe、coon.exe、zmqh.exe、DexpotProPortable.exe、Desktops.exe、wisedesktop.exe、DESKTOP.exe、Vdesktop.exe、MagicDesktop.exe、multidesktop.exe、 v13(这个有特别关照,在蓝屏窗口加载时还会自动杀掉带有这个名字的进程)、RegWX64.exe、QQPCNetFlow.exe、BDMANetLimiter.exe、netmon.exe、360netman.exe、HelloTeacher.exe、EHacker.exe、PowerTool64.exe、zydesk.exe、perfmon.exe、吾爱破解、极域、prcview.exe、processlasso.exe、netfuke.exe、去除控制、课堂狂欢器、课堂工具、fuckmythware、SpecialSet.exe、JiYuTrainer.exe、skieskiller、WindowsKernelExplorer.exe、msconfig.exe。当然也包括我们的尊贵的任务管理器啦!文章来源:https://www.toymoban.com/news/detail-463735.html
附录2:在线根据明文生成学生机房管理助手密码(7.2以上)
访问这个网站,在代码运行窗口输入如下内容,便可生成密文,将密文写入注册表HKEY_CURRENT_USER\Software:n(REG_SZ),机房助手密码将会被立即更改:(也可以本地运行)文章来源地址https://www.toymoban.com/news/detail-463735.html
// 代码来自学生机房管理助手9.0 set.exe,逆向、整理:小流汗黄豆
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;
public class Program
{
public static void Main()
{
// 更改这里的内容
string string_3 = "12345678";
// Class6.smethod_0()
string value = "C:\\WINDOWS";
string s = value.Substring(0, 8);
string s2 = value.Substring(1, 8);
DESCryptoServiceProvider descryptoServiceProvider = new DESCryptoServiceProvider();
descryptoServiceProvider.Key = Encoding.UTF8.GetBytes(s);
descryptoServiceProvider.IV = Encoding.UTF8.GetBytes(s2);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, descryptoServiceProvider.CreateEncryptor(), CryptoStreamMode.Write);
StreamWriter streamWriter = new StreamWriter(cryptoStream);
streamWriter.Write(string_3);
streamWriter.Flush();
cryptoStream.FlushFinalBlock();
memoryStream.Flush();
string string_4 = Convert.ToBase64String(memoryStream.GetBuffer(), 0, checked((int)memoryStream.Length));
// Class6.smethod_3()
StringBuilder stringBuilder = new StringBuilder();
for(int i = 0; i < string_4.Length; i++)
stringBuilder.Append((char)(string_4[i] - 10));
string_3 = stringBuilder.ToString();
// Class6.smethod_2()
MD5CryptoServiceProvider md5CryptoServiceProvider = new MD5CryptoServiceProvider();
byte[] array2 = md5CryptoServiceProvider.ComputeHash(Encoding.Default.GetBytes(string_3));
stringBuilder.Clear();
for (int i = 0; i < array2.Length; i++)
stringBuilder.Append(array2[i].ToString("x2"));
string str = stringBuilder.ToString().Substring(10);
Console.WriteLine(str);
}
}
// 期望输出:8a29cc29f5951530ac69f4
到了这里,关于【1.1,已适配机房助手7.5】更新中!淦翻极域、机房助手的超强软件,附代码思路的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!