免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5006 | 回复: 0
打印 上一主题 下一主题

软件玩隐身――API破尽网管软件 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-17 09:10 |只看该作者 |倒序浏览
为了达到免费上网的目地,对付网吧管理软件几乎使用的都是一个方法,就是结束它的进程。但是我们有没有想过,还有没有更好的办法?况且这样阻断了网管程序客户端与服务端的通讯,网管也是很容易发现的!\r\n  咦,有办法了!大家都知道老板键吧,当Office中老板独特的嗓音(脚步声,呼吸声)响起之时,手无寸铁的白领MM一瞬间一键隐藏了自己正在浏览的网站界面和应用程序界面……隐藏窗口也就是本文的思路――隐藏网吧管理软件的客户端会员登录窗口。\r\n\r\n单窗口的隐藏 \r\nWindows API函数ShowWindow可以实现对单个窗口的隐藏\r\n.DLL命令 ShowWindow, , \"user32\", \"ShowWindow\"\r\n.参数 hand, 整数型, , 注明:窗口句柄,要向这个窗口应用由nCmdShow指定的命令。\r\n.参数 nCmdShow, 整数型, , 为窗口指定可视性方面的一个命令,0为隐藏\r\n.DLL命令 判断窗口可见性_, 逻辑型, \"user32\", \"IsWindowVisible\", , \r\n.参数 窗口句柄, 整数型, , hand,要测试的那个窗口的句柄\r\n\r\n要隐藏窗口,我们必须知道这个窗口的句柄,用API函数GetForegroudWindow可以取得前台窗口的句柄,最后调用。\r\nShowWindow (GetForegroudWindow(), 0)可以隐藏前台窗口的句柄,在网管程序的会员登录窗口出现时运行该程序,就可以隐藏它。\r\n  在实际应用中,我们可以先正常上机,然后运行该程序。我们给程序再加个定时执行的功能(用时钟控制)假设定为10秒。然后我选择“结账下机”,10秒后程序就对在最前面的会员登录窗口进行隐藏,从而绕过了网管程序。\r\n  这种方法对一些单窗口的网管程序效果很好,如旧版的万象。那么有没有对应非单窗口网管程序的办法呢?当然有,思路还是一样的,只不过这里的窗口是关联窗口而已!\r\n\r\n必杀计,破尽网管软件\r\n\r\n  有些网吧会员登录窗口不只一个窗口,而是多个关联窗口,关联窗口的隐藏起来有点麻烦,我们可以对全部窗口进行隐藏,这里用API函数EnumWindows枚举所有窗口:\r\n     .DLL命令 EnumWindows, 逻辑型, , \"EnumWindows\"\r\n   .参数 枚举过程, 子程序指针\r\n   .参数 参数, 整数型\r\n调用部分这样写:EnumWindows (&枚举父窗口过程, 0)。我们可以在“枚举父窗口过程”这个回调函数里逐一调用ShowWindow对每个窗口进行隐藏,这样我们的程序运行后就可以对全部的窗口进行隐藏(包括桌面窗口),代码如下:\r\n\r\n\r\n.子程序 枚举父窗口过程, 逻辑型,\r\n.参数 窗口句柄, 整数型\r\n.如果真 (判断窗口可见性_ (窗口句柄))\r\nShowWindow (窗口句柄, 0)\r\n返回 (真)\r\n.如果真结束\r\n返回 (假)\r\n  \r\n  \r\n  在实际操作中,我们还要找回被隐藏的桌面(其实大多数的网管软件都对用户桌面和任务栏进行隐藏),可以用API函数FindWindow找到桌面窗口的句柄\r\n  小提示:其实易语言带的“应用接口支持库”里有这方面的命令,也非常方便好用,但从技术上的角度来说,不够透明。\r\n  这里我选择了用纯API来实现这些功能。\r\n  \r\n  .DLL命令 FindWindow, 整数型, \"user32.dll\", \"FindWindowA\", , FindWindow,寻找窗口列表中第一个符合指定条件的顶级窗口\r\n   .参数 窗口类名, 文本型, , lpClassName,\r\n   .参数 窗口文本, 文本型, , lpWindowName \r\n  \r\n  \r\n  然后调用ShowWindow对它们进行还原,代码如下:\r\n  \r\n\r\n  .子程序 找回桌面, 逻辑型\r\n  .局部变量 桌面图标句柄, 整数型\r\n  .局部变量 任务栏句柄, 整数型\r\n  桌面图标句柄 = FindWindow (“Progman”, 字符 (0))\r\n  任务栏句柄 = FindWindow (“Shell_TrayWnd”, 字符 (0))\r\n  .如果真 (桌面图标句柄 = 0 或 任务栏句柄 = 0)\r\n   返回 (假)\r\n  .如果真结束\r\n  ShowWindow (桌面图标句柄, 5) \' 显示桌面\r\n  ShowWindow (任务栏句柄, 5) \' 显示任务栏\r\n  返回 (真)\r\n一般情况下,我们的鼠标也被限制了,所以这个限制也是要取消的,用API函数ClipCursor就可以办到:\r\n  .DLL命令 解除鼠标限制, 整数型, \"user32\", \"ClipCursor\"\r\n   .参数 lpRect, 整数型, 传址, RECT,指定一个矩形,用像素屏幕坐标系统表示。鼠标指针必须在这个区域内运动,如果传递0,就是解除鼠标限制\r\n  \r\n调用时可以这样写:ClipCursor(0)\r\n实际运用中遇到的问题\r\nOk,技术问题解决了,我们来看看实际运用。不过先不忙,我以前也当过网管,好像网管程序还可以这样选择下机后的动作:\r\n<1>只锁定,不做任何动作\r\n<2>锁定并结束所有正在运行的任务\r\n<3>关机或重启\r\n  我们前面所说的,只是针对第1种情况,大多数网吧也都是这样设置的。但也有例外,我们如果遇到了第2种或第3种情况该怎么办呢?\r\n  \r\nAPI HOOK技术的应用\r\n所谓道高一尺,魔高一丈,我们还是有办法的!对于第2种情况,我们只要简单地把程序的窗口名设为空即可,这样我们的程序在下机后会照常运行!\r\n  对于第3种情况就有点麻烦了,有什么办法不结束网管程序的进程而能不让它关机呢? 好像黑防以前有篇文章提到过的,我翻翻看……\r\n  找了半天终于发现了,2005第5期有一篇文章“妙不可言—挂接ExitWindowsEX”。作者是用的改写IAT导入表法来挂接ExitWindowsEX的,我按上面的方法试了半天,不过却没有成功。\r\n  小知识:易程序是通过调用易核心支持库的代码来实现功能的,也就是说它属于伪代码,当然会失败。\r\n  只好放弃这种方法,改用那篇文章提到的另一种方法:陷阱法(改写内存地址JMP法)。\r\n  正好那期有篇“通过HOOK API隐藏自身(一)”的文章用的就是这个方法来HOOK API的。赶紧再好好看看,黑防的文章果然篇篇精华,可以百看不厌的。\r\n  那篇文章写得非常详细,详细到连我这个不懂C,不懂E文的人都能看个明白(实际上我只是看懂了几个关键的API调用),上网查查相关API资料,在易里面比划比划,程序也就出来了:HOOK API的技术,说起来也不复杂,就是改变程序流程的技术。在CPU的指令里,有几条指令可以改变程序的流程:JMP,CALL,INT,RET,RETF,IRET, RETN等指令。理论上只要改变API入口和出口的任何机器码,都可以HOOK。\r\n当然,系统是不允许我们随便修改内存中的机器码的,我们要想修改,必须先去掉代码页面的保护属性,用API函数VirtualProtectEx可以修改页面保护属性:\r\n\r\n.DLL命令 修改页面虚拟保护, 逻辑型, \"kernel32\", \"VirtualProtectEx\"\r\n.参数 hProcess, 整数型, , 对象的进程句柄,可以使用函数 OpenProcess() 返回。\r\n.参数 lpAddress, 整数型, , 虚拟信息.BaseAddress\r\n.参数 dwSize, 整数型, , 修改虚拟保护的长度.\r\n.参数 flNewProtect, 整数型, , 修改类型,#PAGE_EXECUTE_READWRITE 64为可读写模式\r\n  .参数 lpflOldProtect, 整数型, 传址, 虚拟信息.Protect\r\n  \r\n  在修改之前,我们还需要先知道有关页面的信息,这通过VirtualQueryEx来实现:\r\n  \r\n  .DLL命令 返回页面虚拟信息, 整数型, \"kernel32\", \"VirtualQueryEx\"\r\n   .参数 hProcess, 整数型, , 对象的进程句柄,可以使用函数 OpenProcess() 返回。\r\n   .参数 lpAddress, 整数型, , 对象指针地址\r\n   .参数 lpBuffer, 虚拟信息, , 返回的虚拟信息\r\n   .参数 dwLength, 整数型, , 信息长度,已知 28 \r\n   在修改了页面保护属性为可读写模式后,就可以用API函数WriteProcessMemory来改写内存字节了,我们只要改写了实现关机的API 函数ExitWindowsEx的入口点,让它直接返回或跳到别的地方执行就可以达到关机失效的目地。代码如下:\r\n\r\n  .子程序 修改API首地址, 逻辑型\r\n  .参数 Process, 整数型, , 目标进程句柄\r\n  .参数 Papi, 整数型, , 要修改的API函数地址\r\n  .参数 type, 字节集, , 要改写的内容,字节集\r\n  .局部变量 mbi, 虚拟信息\r\n  .局部变量 结果, 逻辑型\r\n  .局部变量 MyAPI, 整数型\r\n  .局部变量 Ptype, 字节集\r\n如果真 (Papi = 0)\r\n   返回 (假)\r\n  .如果真结束\r\n  .如果真 (返回虚拟信息 (Process, Papi, mbi, 28) = 0)\r\n   返回 (假)\r\n  .如果真结束\r\n  .如果真 (修改虚拟保护 (Process, mbi.BaseAddress, 取字节集长度 (type) + 1, #PAGE_EXECUTE_READWRITE, mbi.Protect) = 假)\r\n   返回 (假)\r\n  .如果真结束\r\n  结果 = 写内存字节 (Process, Papi, type, 取字节集长度 (type), 0)\r\n  修改虚拟保护 (Process, mbi.BaseAddress, 取字节集长度 (type) + 1, #PAGE_EXECUTE_READ, mbi.Protect) \' 改回只读模式 \r\n  返回 (结果) \r\n  \r\n   \r\n   通过API函数GetProcAddress和GetModuleHandle很容易得到API函数ExitWindowsEx的入口地址,如下面的代码:. \r\n   \r\nAPI=GetProcAddress(GetModuleHandle(\"user32.dll\"),\"ExitWindowsEx\")\r\n  \r\nAPI_BAK = 指针到字节集 (API, 2) \'为了以后可以还原,我们先备份一下\r\n\'用OpenProcess打开其他进程前先提升进程权限,这样可以打开几乎所有的非内核程序\r\n提升进程权限 () \'这个模块在光盘里,为了节省版面,我就不写出来了 \r\n\r\n我们通过以下几个API就可以举出系统所有进程,得到它们的进程ID\r\n1.CreateToolhelp32Snapshot,创建进程快照\r\n2.Process32First,开始进程快照 \r\n3.Process32Next, 继续进程快照 \r\n代码如下:\r\n\r\n.子程序 刷新进程信息\r\n.参数 进程信息输出, 进程信息输出, 数组\r\n.局部变量 临时变量, 整数型\r\n.局部变量 临时变量B, 整数型\r\n.局部变量 线程基本优先级, 整数型, , \"0\"\r\n.局部变量 临时进程信息, 进程信息输出\r\n临时变量 = 创建进程快照 (2, 0)\r\n临时进程信息.结构大小 = 296\r\n临时变量B = 开始进程快照 (临时变量, 临时进程信息)\r\n.判断循环首 (临时变量B ≠ 0)\r\n加入成员 (进程信息输出, 临时进程信息)\r\n临时变量B = 继续进程快照 (临时变量, 临时进程信息)\r\n.判断循环尾 ()\r\n关闭内核对象 (临时变量)\r\n我们这里只需要关机无效,不需要实现其它功能,可以直接在ExitWindowsEx的入口地址写入一个返回指令{195},使它后面的代码无法执行就可以了, 继续看代码:\r\n.子程序 HOOK_API\r\n.参数 是否HOOK, 逻辑型, , 真,表示HOOK,假,表示还原\r\n.局部变量 i, 整数型\r\n.局部变量 进程信息, 进程信息\r\n.局部变量 进程句柄, 整数型\r\n刷新进程信息 (进程信息) \'见上面的子程序\r\n.计次循环首 (取数组成员数 (进程信息), i)\r\n进程句柄 = 打开进程 (#PROCESS_ALL_ACCESS, 0, 进程信息 .进程标识) \' 注 : #PROCESS_ALL_ACCESS=2035711 \r\n.如果 (是否HOOK)\r\n修改API首地址 (进程句柄, API, { 195,1 }) \' 写入指令retn 1\r\n.否则\r\n修改API首地址 (进程句柄, API, API_BAK) \' 还原API \r\n\r\n关闭内核对象 (进程句柄)\r\n.计次循环尾 () \r\n最后我们通过调用HOOK_API(真)就可以挂钩ExitWindowsEx,调用HOOK_API (假)就可以还原ExitWindowsEx,继续看代码:\r\n.如果 (选择框_挂钩API.标题 = “挂钩API”)\r\nHOOK_API (真)\r\n选择框_挂钩API.标题 = “还原”\r\n信息框 (“恭喜,挂钩ExitWindowsEx成功,你现在不能关闭系统了,不信你可以试试!”, 64, )\r\n.否则\r\nHOOK_API (假)\r\n选择框_挂钩API.标题 = “挂钩API”\r\n信息框 (“提示:还原ExitWindowsEx成功,你现在可以关闭系统了!”, 48, “提示”) \r\n\r\n\r\n全文补充和总结\r\n在隐藏窗口时的“枚举父窗口过程”中,我们还可以加些其它功能,例如我们可以根据窗口句柄得到进程名称,用API函数GetWindowThreadProcessId和GetModuleFileNameEx就可以办到,从而可以对指定进程名的所有窗口进行隐藏,我们也可以通过API函数EnumChildWindows枚举子窗口,然后在它的回调函数里用API函数EnableWindow激活窗口,从而激活灰色按钮的作用等。\r\n\r\n一些具体细节我就不罗嗦了,源码里有非常详细的注解,大家可以查看。你如果还是个易语言新手,可以参看一下黑防4期的一篇易教学。我相信你看了以后很多问题都可以弄明白的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP