托管和非托管联精密管手打造DONET灰色按钮克星

钢管 星徽2号 评论

“灰色按钮克星”是一款不错的软件,可以激活灰掉的按钮,有时无形中可以达到破解的目的。但是如果你用它去激活在DONET平台的软件的时候,你会发现没有任何作用。 “灰色按钮克星”是一款不错的软件,可以激活灰掉的按钮,有时无形中可以达到破解的目的。

  “灰色按钮克星”是一款不错的软件,可以激活灰掉的按钮,有时无形中可以达到破解的目的。但是如果你用它去激活在DONET平台的软件的时候,你会发现没有任何作用。

  “灰色按钮克星”是一款不错的软件,可以激活灰掉的按钮,有时无形中可以达到破解的目的。但是如果你用它去激活在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)

  只要在合适的位置调用这个方法就行了。(参见附件)

  但是有一个问题:这个dll一但进入目标程序后就不停地把所有按钮都激活了,可能会影响软件的正常使用。于是我采用了比较笨的办法,就是在这个dll中新建了一个Form,再加两个按钮让用户选择是激活还是不激活。当然还有其他的一些细节问题,我自认为都不是本文重点部分,有兴趣地同志可以看看附件中的源代码。

  第2步的实现:

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

  写一个函数类似于此:

  DWORD WINAPI LoadCSDll(LPVOID lpm)

  HMODULE hand =LoadLibraryA("LoadCSDll.dll");//这个dll为前面我们vc.net编译的。

  ::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所示

喜欢 (0) or 分享 (0)
发表我的评论
取消评论

表情

您的回复是我们的动力!

  • 昵称 (必填)
  • 验证码 点击我更换图片

网友最新评论