首页
社区
课程
招聘
[原创]托管和非托管联手打造DONET灰色按钮克星
发表于: 2007-12-6 21:20 9556

[原创]托管和非托管联手打造DONET灰色按钮克星

2007-12-6 21:20
9556
标 题: 【原创】托管和非托管联手打造DONET灰色按钮克星
作 者: tease
时 间: 2007-12-16,21:18
链 接: http://bbs.pediy.com/showthread.php?p=388652

      这是我发表在《黑客防线》07年12月杂志上的文章,这里网络上面的首发。
    “灰色按钮克星”是一款不错的软件,可以激活灰掉的按钮,有时无形中可以达到破解的目的。但是如果你用它去激活在DONET平台的软件的时候,你会发现没有任何作用。我想可能是DONET平台自身的特点造成的吧。那么如何激活DONET平台上的软件呢?在阅读本文核心内容前,我想说说我是如何想到并一步一步实现的。
我们在C#编程中想让一个Panel中的所有控件都灰掉是怎么做得呢?不会是根据每个控件的name来一个一个灰掉吧,如果控件很多,岂不是要写很多条语句。我们最简单的写法莫过于此:
foreach(Control control in panel1.Controls)
{
   control.Enable = false;
}
反之如果想让每个控件激活,那么把它的Enable设置为true就行了。于是我突发奇想,如果让这段代码在其他已运行的DONET软件上面执行那么不就可以实现按钮的激活了吗。那么如何在其他DONET软件上面执行这段代码呢?——聪明的你肯定也想到了,对!就是进程注入!!!
   众所周知,在非托管编程中:当进程注入成功后,软件会自动执行dll文件中的DllMain函数里面的内容。那么托管dll文件的DllMain函数在哪儿?带着这样的疑问我做了实验,将C#写的dll文件注入到其他进程后却根本没法执行。(由于本人能力有限,还不知道怎么去执行托管dll的入口点函数,望高手指点)失望之后,我就冷静下来思考了一下,既然C#不行那么我们可以尝试使用VC++.NET啊!因为它可以同时进行托管和非托管的混合编程,说不定可以实现我们的目的^_^。
   拿出VS2005,新建一个VC++.net的Win32项目,在“应用程序类型”中选择Dll 如图1所示:

一步一步下来后就会生成这个项目。然后记得设置该项目的属性让其支持托管代码并添加引用System 和System.Windows.Forms 的命名空间。如图2和图3所示:


首先我尝试在DllMain函数中加入以下代码:
::System::Windows::Forms::MessageBox::Show("hello");
编译发现报错:
“System::Windows::Forms::MessageBox”: 托管类型或托管函数不能用于非托管函数。
我再次尝试写一个全新的纯托管函数:
void HelloWord()
{
        ::System::Windows::Forms::MessageBox::Show("hello");
}
当我把这个函数放在
#ifdef _MANAGED
#pragma managed(pop)
#endif
代码段下面的时候编译通过了!!
那么我该如何去调用这个函数呢?如果在DllMain中直接去调用仍然会出现“托管类型或托管函数不能用于非托管函数”的编译错误。最终我想到了C++的导出函数。
extern "C" _declspec(dllexport) void HelloWord()
{
        ::System::Windows::Forms::MessageBox::Show("hello");
}
编译通过!!我迫不及待的使用Stud_PE 来查看这个生成的dll文件,惊喜地发现,导出函数已经存在了。如图4所示:

好的,有这个导出函数就足够了,这就意味着我们可以通过非托管代码来调用这个托管代码的函数了。聪明的你也肯定想到了向其他进程注入托管代码的办法了。我们一起来设想一下步骤:
1、用VC++.net 写一个有导出函数的dll项目,该导出函数包括托管代码,该托管代码的作用就是用于激活DONET的按钮。
2、写一个非托管的Dll,在这个Dll文件的DLLMain函数中调用第1步中的导出函数。
3、编写一个WinForm程序,将第2步生成的Dll文件注入到DONET程序中去。
不知道大家有没有被我绕晕了,还是用代码来说明问题吧:

第1步的实现:
前文中我说过使用在C#中可以使用foreach循环达到使按钮激活的方法,那么我们现在用VC++.net来实现:顺便再增加一个可以显示隐藏按钮的功能。
    private: void EnableControl(Control ^ctl)
                 {                         
                         for each (Control ^control in ctl->Controls)
                                 {
                                         if(checkBoxIsShowHidden->Checked)
                                                 if(!control->Visible) control->Visible =true;
                                         if(!control->Enabled) control->Enabled =true;
                                 }
                 }
    只要在合适的位置调用这个方法就行了。(参见附件)
但是有一个问题:这个dll一但进入目标程序后就不停地把所有按钮都激活了,可能会影响软件的正常使用。于是我采用了比较笨的办法,就是在这个dll中新建了一个Form,再加两个按钮让用户选择是激活还是不激活。当然还有其他的一些细节问题,我自认为都不是本文重点部分,有兴趣地同志可以看看附件中的源代码。

第2步的实现:
   为了突出说明非托管可以调用前面写的托管函数,我们使用VC++6.0来写这个非托管项目,打开VC++6.0 新建一个dll项目如图5所示:

写一个函数类似于此:
DWORD WINAPI LoadCSDll(LPVOID lpParam)
{
    HMODULE hand = LoadLibraryA("LoadCSDll.dll"); //这个dll为前面我们vc.net编译的。
                if(hand == NULL)
                {
                        ::MessageBoxA(NULL,"无法载入动态连接库","error",MB_ICONERROR);
                        return NULL;
                }
                typedef HRESULT (*GetDll)();
                GetDll pFunc;
                pFunc = (GetDll)::GetProcAddress(hand,"LoadDoNet");
                if ( pFunc != NULL )
                {
                        (*pFunc)();
                }
}
在DllMain中加一个线程操作免得注入后把主程序卡死:
switch(ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
                CreateThread(NULL,NULL,LoadCSDll,NULL,NULL,NULL);
                break;
        case DLL_THREAD_ATTACH:
                break;       
        case DLL_THREAD_DETACH:
                break;
        case DLL_PROCESS_DETACH:
                break;
        }       
        return TRUE;
第3步的实现:
线程注入操作已经被高手们研究“烂”了,随便“摆渡”一下肯定会有很多不同语言写的模板代码。由于不是本文的重点部分,所以就不班门弄斧了。还是一起来看看我写的程序吧:

如图6所示,我的这款软件名字叫做《超级灰色按钮克星》,当然也包括了WIN32平台的灰色按钮激活的功能,不过我新增加了一个“显示隐藏控件”的功能,其实就是调用:
IsWindowVisible(hwnd) 和ShowWindow(hwnd,SW_SHOW)这个两个API就可以了。没有什么技术含量^_^。
这个软件的用法很简单,只要在“箭靶”上按住鼠标左键不动,将其“箭靶”拖动到目标程序就可以了。
我还是来说说DONET平台的激活使用吧:
1、        把平台选择切换到DONET平台。
2、        拖动“箭靶”到需要激活的程序上(附件提供测试程序)如图7所示:

3、        如果使用“是否显示隐藏控件”功能,那么点击checkbox后请将鼠标再次移回需要显示隐藏控件的窗体即可(本例为Form1)如图8所示

注入到进程后主要就是通过鼠标位置来确定需要激活或显示控件了。具体代码请参考附件源码。还有一点要注意一下:开起杀毒软件的主动防御功能,可能会影响到我的注入操作。如果有疑问或异议欢迎给我发送电子邮件共同讨论:chengchencici@163.com
   
本文程序在WinXP SP2 + NET2.0 + VS2005 + VC6.0编译测试通过!
最后本文感谢:pediy.com的老大们及论坛上那些无私奉献的人们。

超级灰色按钮克星下载: SuperEnable.rar
核心Code: code.part01.rar code.part02.rar code.part03.rar code.part04.rar
测试程序: testForm.rar

[课程]FART 脱壳王!加量不加价!FART作者讲授!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
2
很猥琐的说...希望LZ分享一下投稿的经验.
需要和编辑 私通否 ?
2007-12-7 02:20
0
雪    币: 93
活跃值: (11)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
直接把稿件(包括图片、软件、文章、源码 全部打包)发到指定邮箱就可以了,网上说只需要等1~3个工作日便会有回复,可是我登了5天才有回复结果。
2007-12-7 10:01
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
4
看来偶人品的确不好.
发了N年了 既没有给我回复说采用也没有说不采用~~~ 发了N次,换了N个邮箱,想了N个杂志.
2007-12-9 14:11
0
游客
登录 | 注册 方可回帖
返回
//