对XX电子教室4.0的分析及编程处理

这仅仅是本人无聊至极做出的分析,至于编程,本人也只是小小菜鸟,如有不当请大牛指正,自当万分感激。
由于微机课总是被老师的一节课的长篇大论占用完,所以感到心中不服,特此找来了这个软件来把玩,看看能不能写出一个内存补丁,实现屏幕广播窗口化并且不使鼠标键盘被锁定。然而出师不利,找个样本太困难,网上几乎没有,总算找到,在虚拟机里面安装的时候却蓝屏很多次……(解决方法:在系统盘根目录下找到BOOT.INIWindows XP)这个文件,而后修改第一条启动路径其中的参数noexecuteexecute)。我安装了两个虚拟机,一个安装学生端一个安装教师端,为了能够互相通信,使用了桥接网络的方式。

 

载入OD
这种软件,向来无壳,所以,直接拿来就分析。看一眼入口点,VC6特征如此明显,而加载的模块列表中也有MFC运行库,所以,明显的,MFC编写的程序。(如图)
对XX电子教室4.0的分析及编程处理
对XX电子教室4.0的分析及编程处理
就算再不确定,查找一下所有模块间的调用,一眼看出……
寻找可操控点
 
这里,我直接去看了看教师端,发现设置里面有两个比较有趣的选项:(如图)
对XX电子教室4.0的分析及编程处理
对XX电子教室4.0的分析及编程处理
 
    这样,补丁的地方就显而易见了,它既然有这个选项,那么就说明,学生端在执行这条命令的时候,一定会有一个判断,对教师机是否选中这个选项的判断,所以,有了以下两种思路:
1.截获封包,自己处理其中的数据后再让学生端处理
2.直接修改学生端对应的反汇编代码,实现暴力**修改
由于本人才疏学浅,无法胜任第一项工作,只好去实现第二种思路,况且,第一种思路编出来的程序,难道不需要一直运行着?本人没做过,的确是不知道。
开始分析

 

    既然已经有了可以操控的地方,那么就应该开始分析。首先,要知道从何下端,在何修改。那么,在何处下端可以找到关键点?我认为消息循环处理处是一个不错的选择。寻找消息循环处理的代码有很多种方法,在此我只说适用于此软件的一种方法,那就是在置顶窗口的函数处下断。
 
    如何知道它使用了哪个置顶窗口的API?必须了解的是,这个软件窗口是本来不在前台的,要被设置到前台去,所以只能使用SetForegroundWindow,因此下断SetForegroundWindow,而后开始在教师端开始控制……
 
    果然断了下来,不过断下来的地方正和我意,居然是消息循环处理的地方……既然如此,那么开始劳动……单步走,看看要到哪个CALL里面去。(如图)
对XX电子教室4.0的分析及编程处理
对XX电子教室4.0的分析及编程处理

 

跟了几步就到了,由于虚拟机没有安装中文输入法,英语水平也很差,于是乎使用了拼音,各位大神不要见怪。跟入CALL,通过不同设置的对比,得到两个关键跳转的地方。
004149EA75 04           jnzshort StudentE.004149F0
00414AC80F85 85000000   jnz StudentE.00414B53
这两个跳转如果全部NOP掉,那么就会变成窗口。那么,鼠标键盘锁在什么地方?继续向下走。(如图)
对XX电子教室4.0的分析及编程处理
对XX电子教室4.0的分析及编程处理

 

得来全不费功夫,感谢作者,你起名起的太诗情画意了,完美!不过,这难道不是一个良好的编程习惯么?跟入,处理,将实现代码前的跳转全部处理掉,作出记录,然后,屏幕广播到此收工!
再在教师机处通过使用的功能,将其他的CALL的功能也摸清,结果如图。
对XX电子教室4.0的分析及编程处理
对XX电子教室4.0的分析及编程处理
感觉整个人生都美妙了许多,不禁飘然若仙~~~
编程处理
 
如果是那些大牛们,自然是使用WIN32API啊、汇编啊、什么什么什么,然而,我等小菜,也就只能使用MFC来写了,因为……感觉界面实在难做本意又不是来做界面的至于易语言~感觉用起来太难受,想了想还是算了
于是乎,开始了无聊的编程~那么,关于编程我就不多做说明了,反正是一个内存补丁,没有多少技术含量。由于以前分析极域电子教室2.0的时候发现它HOOKOpenProcess这个API,所以……直接去调用Ntdll.dll里面的ZwOpenProcsss……貌似4.0版本没有HOOK……两个需要用到的结构体定义如下:

 

[C++] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
typedef struct _CLIENT_ID
{
        HANDLE UniqueProcess;
        HANDLE UniqueThread;
}CLIENT_ID, *PCLIENT_ID;
typedef struct _OBJECT_ATTRIBUTES
{
        ULONG Length;
        HANDLE RootDirectory;
        PVOID ObjectName;
        ULONG Attritubes;
        PVOID SecurityDescriptor;
        PVOID SecurityQualityOfService;
}OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

 

    接着,定义这个函数参数
[C++] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
#define OUT
#define IN
typedef  DWORD(__stdcall *ZWOPENPROCESS)(
        OUT PHANDLE ProcessHandle,
        IN ACCESS_MASK DesiredAccess,
        IN POBJECT_ATTRIBUTES ObejectAttributes,
        IN PCLIENT_ID PClient_Id
        );

 

    再后来,在程序中的调用如下:
[C++] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
bool MyOpenProcess(OUT PHANDLE ProcessHandle)
{
        HMODULE hModule = ::GetModuleHandle(L"ntdll.dll");
        if (hModule == NULL)
                return FALSE;
        ZWOPENPROCESS ZwOpenProcess = (ZWOPENPROCESS)GetProcAddress(hModule, "ZwOpenProcess");
        if (ZwOpenProcess == NULL)
                return FALSE;
        CLIENT_ID ClientID;
        ClientID.UniqueProcess = (HANDLE)PID; //UniqueProcess可以接受PID
        ClientID.UniqueThread = 0;
        OBJECT_ATTRIBUTES oa;
        oa.Length = sizeof(oa);
        oa.RootDirectory = 0;
        oa.ObjectName = 0;
        oa.Attritubes = 0;
        oa.SecurityDescriptor = 0;
        oa.SecurityQualityOfService = 0;
        NTSTATUS status = ZwOpenProcess(ProcessHandle, PROCESS_ALL_ACCESS, &oa, &ClientID);
        if (status == STATUS_INVALID_PARAMETER)
        {
                ::MessageBox(0, L"参数错误!请检查PID!", L"警告:",0);
                return FALSE;
        }
        return TRUE;
}

 

因为要获取PID,而枚举又太麻烦,于是做个编辑框让用户自己输入PID好了……还有一个需要注意的地方就是在写入补丁的时候,字节码反过来写……
例如:
int Data1 = 0x73EB;

 

后记

 

就是这么多了,我这样的小菜有错误在所难免,请各位大神指正
这个软件的破解我没有去研究,毕竟~我研究它干嘛~
补丁在WindowsXP上测试通过,在此我写死了地址,有ASLR的童鞋请自行处理
老铁资源,提供商业网站源码、微擎破解版、付费收费培训视频特价。
老铁资源 » 对XX电子教室4.0的分析及编程处理

提供最优质的资源集合

立即查看 了解详情