前方施工篇
因为篇幅较长,较难施工,可能你会遇到灾难现场,请带好安全帽。
入坟篇
拙著篇
前序
在我初中的时候,当时电脑课对于我这个内宿生来说很重要,毕竟就只能周末回去,能玩一点算一点qaq。然后老师讲的大部分内容自己都会,不想听了就私底下打算怎么脱离电子极域教室的控制。
想不到现在到了大学,想不到学校还是在用这个,正好重新整活。
2020年12月21日00:03:45更新
开源地址
主程序:DLL还没写完呢,急什么23333.
指导思想
通过注入DLL对控制流程进行HOOK,达到改变程序的控制流程甚至监控。
准备工作
极域电子教室2016豪华版(软件自行百度)
吾爱破解专用版Ollydbg
注意:由于2012年版本的极域电子教室使用了内核保护,用了原版的OD在线挂载的时候可能会出现拒绝访问,请留意。
IAT Hook
咕咕咕
current time:2020年12月21日00:11:01
status:咕咕咕咕咕咕
Inline Hook
Inline Hook原理
通过Inline Hook改变程序流程,将API代码的前5个字节修改为JMP xxxxxx 指令来钩取API(xxxxxx是要跳转到Hook函数的内存地址)。
调用执行被钩取的API时,JMP xxxxxx指令被执行,转而跳转至指定的Hook函数处理后再调用AIP(或者直接返回),这样达到了拦截修改的目的。
Inline Hook实现
大部分程序被编译连接后为个进制文件。在二进制文件中,代码部分都是CPU可以用来执行的机器码,机器码和汇编指令又是一一对应的。
Inine Hook是在程序中嵌入jmp汇编指令后跳转到流程处继续执行的,jmp 指令的用法是jmp目的地址。
在汇编指令中,jmp后面跟随的参数是要跳转的“目的地址”。用OD随便打开一个程序,并且修改它的某条指令为jmp指令。
跳转的目的为一个任意地址,如图所示。
所以说我们需要改写AIP函数上的地址开始的5个字节,替换成我们的jmp指令跳转到我们的函数。
我们先从鼠标键盘锁定拦截介绍。鼠标键盘锁定其实去调用一个叫SetWindowsHook的一个AIP进行锁定。
(由于SetWindowsHookEx存在两个版本:SetWindowsHookExA和SetWindowsHookExW,假如你要兼容全部版本的极域电子教室话也可以对着两个函数处理。)
该函数声明如下:
HHOOK SetWindowsHookExA(
int idHook,
HOOKPROC lpfn,
HINSTANCE hmod,
DWORD dwThreadId
);
改函数上idHook
表示要安装钩子的类型,可以按安装WH_MOUSE类型钩子,监视鼠标消息或进行拦截;同样,安装WH_KEYBOAED类型钩子,键盘鼠标消息进行拦截。
所以说我们目的是Hook这个AIP。(感觉我是在以Hook制Hook)
我们先看看汇编是怎样调用SetWindowsHookEx的。
在OD里面选择开始→附加,选择极域电子教室的主进程student.exe
后选择确定。
由于我们不知道该程序会先调用那个函数,所以先设置一个在SetWindowsHookExA和SetWindowsHookExW函数断点,然后让教师端黑屏(或者屏幕广播)后查看OD。
提醒一下:假如你要进行黑屏操作的话你得需要在OD的窗口设置为总先在前,不然......黑屏的时候你就没办法回到OD了,GG。
可以看到,OD显示在SetWindowsHookExA断下。
前3行汇编代码如下:
76A56CDC 8BFF mov edi,edi
76A56CDE 55 push ebp
76A56CDF 8BEC mov ebp,esp
刚好是5个字节,5个字节可以做一个JMP指令。假如不是5字节的话,剩下的字节会转换为其他汇编代码,这样程序执行的时候会出现各种问题。如修改后突然多出现了一行push ebp,这样会导致堆栈不平衡从而程序运行时崩溃。
前堆栈信息如下:
0012A4CC 100029E9 /CALL 到 SetWindowsHookExA 来自 libTDMas.100029E7
0012A4D0 0000000E |HookType = 14.
0012A4D4 10001590 |Hookproc = libTDMas.10001590
0012A4D8 10000000 |hModule = 10000000 (libTDMas)
0012A4DC 00000000 \ThreadID = 0x0
堆栈信息看出函数HookType变量赋予了14,对应WH_MOUSE。
注:微软开发文档下对SetWindowsHookExA函数HookType变量解释是:当该变量赋予了14应该对应的是WH_MOUSE_LL(低级鼠标输入事件)。虽然都是拦截鼠标信息也没什么区别,但是WH_MOUSE_LL可以拦截可以截获整个系统所有模块的鼠标事件。毕竟比较给力嘛~~~
然后,就可以随手一发暴力插入JMP指令了?
并不是,在运行时我们已经破坏了SetWindowsHookExA
函数的头部部分,也就是替换掉的那个部分。导致我们想再回去调用SetWindowsHookExA
时候发现程序崩溃了。
所以我们要这样写代码:
//我们自己的SetWindowsHookExA,每调用SetWindowsHookExA都要跳到MySetWindowsHookExA来处理
void HHOOK
MySetWindowsHookExA(
int idHook,
HOOKPROC lpfn,
HINSTANCE hmod,
DWORD dwThreadId)
{
if(idHook==14);
}
注意:1、假如你要进行内联汇编的话,里面不能含有编译器自动添加的代码,所以在MySetWindowsHookExA
头部要加上_declspec(naked)
。
2、在一些版本的编译器,编译出的debug版本每执行一个函数都要来验证堆栈的。所以看你怎么平衡堆栈了,我也可以举个例子:vs2010的debug版本每执行一个函数都要 cmp esi,esp 来验证堆栈的。所以还要加一句push esi 和pop esi。