皮肤工具——SkinMagic for VC2008改良版

来源:互联网 发布:linux mysql启动失败 编辑:程序博客网 时间:2024/04/28 22:08

前言:

之前用Appface做VC皮肤,觉得很好用,但是该工具有试用期。由于此前学过逆向破解,后来就尝试破解软件,才发现其实是DLL里面加密了,惭愧无法破解,据说网上也无人破解。于是就改用了skinMagic,这个版本是2.2.1.1的,已被大牛破解,因此可以放心使用。

 

这个skinMagic包含了SkinMagicLib.h,SkinMagicLib.lib,SkinMagic.dll,通过静态库辅助方式导入动态库,这里出现了一个问题,就是SkinMagicLib.lib好像是VC6.0做的,于是上面的方法在VC6下面巨爽,VC2008却出现连接问题。

看来在VC2008下面就只有用动态导入dll了。这个是小问题。

 

一 修改skinMagic方法:

在SkinMagicLib.h头文件中的最后一个#endif前面添加了一个类Class MagicSkin,然后定义需要使用的相关函数。

代码如下。

 

#ifdef __cplusplus
class MagicSkin
{
public:
 typedef int   (__stdcall *MAGICSKIN_INIT)( HINSTANCE hInstance, LPCTSTR lpApplication,
  LPCTSTR lpReserved1,LPCTSTR lpReserved2 );
 typedef void   (__stdcall *MAGICSKIN_EXIT)();
 typedef int   (__stdcall *MAGICSKIN_LOADSKINFILE)( char* lpSkinFile );
 typedef int   (__stdcall *MAGICSKIN_LOADSKINRESOURCE)( HMODULE hModule, char* lpSkinName ,char* lpType );
 typedef int   (__stdcall *MAGICSKIN_SETWIND)( HWND hWnd, char* lpSkinName );
 typedef int   (__stdcall *MAGICSKIN_SETDLG)( char* szSkinName );
 
#ifdef _UNICODE
 MagicSkin(LPCTSTR DllPath = L"SkinMagic.dll")
#else
 MagicSkin(LPCTSTR DllPath = "SkinMagic.dll")
#endif
 {
  m_bValid = FALSE;
  m_hDll = NULL;
  bInitSkinMagicLib = NULL;
  bExitSkinMagicLib = NULL;
  bLoadSkinFile = NULL;
  bLoadSkinFromResource = NULL;
  bSetWindowSkin = NULL;
  bSetDialogSkin = NULL;
  Init(DllPath);
 };
 ~MagicSkin(){ Release(); };
 BOOL Init(LPCTSTR DllPath)
 {
  if(m_hDll && m_bValid) return TRUE;
  m_hDll = ::LoadLibrary(DllPath);
  if(m_hDll == NULL)  return FALSE ;

  bInitSkinMagicLib = (MAGICSKIN_INIT) GetProcAddress(m_hDll, "InitSkinMagicLib");
  if(!bInitSkinMagicLib)     return FALSE;

  bExitSkinMagicLib = (MAGICSKIN_EXIT) GetProcAddress(m_hDll, "ExitSkinMagicLib");
  if(!bExitSkinMagicLib)     return FALSE;

  bLoadSkinFile = (MAGICSKIN_LOADSKINFILE) GetProcAddress(m_hDll, "LoadSkinFile");
  if(!bLoadSkinFile)     return FALSE;

  bLoadSkinFromResource = (MAGICSKIN_LOADSKINRESOURCE) GetProcAddress(m_hDll, "LoadSkinFromResource");
  if(!bLoadSkinFromResource)     return FALSE;

  bSetWindowSkin = (MAGICSKIN_SETWIND) GetProcAddress(m_hDll, "SetWindowSkin");
  if(!bSetWindowSkin)     return FALSE;

  bSetDialogSkin = (MAGICSKIN_SETDLG) GetProcAddress(m_hDll, "SetDialogSkin");
  if(!bSetDialogSkin)     return FALSE;
 
  m_bValid = TRUE;
  return TRUE;
 };

 int InitSkin(HINSTANCE hInstance, LPCTSTR lpApplication, LPCTSTR lpReserved1,LPCTSTR lpReserved2)
 {
  return bInitSkinMagicLib(hInstance, lpApplication, lpReserved1, lpReserved2);
 };

 void ExitSkin()
 {
  bExitSkinMagicLib();
 };

 int LoadSkin(char* lpSkinFile)
 {
  return bLoadSkinFile(lpSkinFile);
 };

 int LoadSkin(HMODULE hModule, char* lpSkinName, char* lpType)
 {
  return bLoadSkinFromResource( hModule,lpSkinName,lpType );
 };

 int SetWindow(HWND hWnd, char* lpSkinName)
 {
  return bSetWindowSkin(hWnd,lpSkinName);
 };

 int SetDlg(char* lpSkinName)
 {
  return bSetDialogSkin(lpSkinName);
 };

private:
 BOOL m_bValid;
 HMODULE m_hDll;

 MAGICSKIN_INIT   bInitSkinMagicLib;
 MAGICSKIN_EXIT   bExitSkinMagicLib;
 MAGICSKIN_LOADSKINFILE   bLoadSkinFile;
 MAGICSKIN_LOADSKINRESOURCE bLoadSkinFromResource;
 MAGICSKIN_SETWIND bSetWindowSkin;
 MAGICSKIN_SETDLG  bSetDialogSkin;

protected:
 void Release()
 {
  try{ 
   if(m_hDll)
   {
    FreeLibrary(m_hDll);
    m_hDll = NULL;
    m_bValid = false;
    bInitSkinMagicLib = NULL;
    bExitSkinMagicLib= NULL;
    bLoadSkinFile = NULL;
    bLoadSkinFromResource = NULL;
    bSetWindowSkin = NULL;
    bSetDialogSkin = NULL;
    
   }
  }catch(...){}
 };
 
};

#endif //_cplusplus

二 使用方法

1. cpp中添加头文件#include "SkinMagicLib.h"
2. 定义全局的MagicSkin m_skin;
3. 在InitInstance中添加下面的代码
BOOL CTestMagicSkinApp::InitInstance()
{
 VERIFY( 1 == m_skin.InitSkin(AfxGetInstanceHandle(), NULL, NULL, NULL));
 WCHAR Tpath[256];
 memset(Tpath,0,256);
 GetModuleFileName(NULL,Tpath,256);
 USES_CONVERSION;
 char* path = W2A(Tpath);
 char * p = strrchr(path,'//') ;
 if(!p) return FALSE ;
 strcpy(p,"
///0/0");
 strcat(path,"corona.smf");
 VERIFY( 1 == m_skin.LoadSkin(path));
//************星号区域为MFC代码******************
 INITCOMMONCONTROLSEX InitCtrls;
 InitCtrls.dwSize = sizeof(InitCtrls);
 // 将它设置为包括所有要在应用程序中使用的
 // 公共控件类。
 InitCtrls.dwICC = ICC_WIN95_CLASSES;
 InitCommonControlsEx(&InitCtrls);

 CWinApp::InitInstance();

 ....................
 ....................
 ....................

 m_pMainWnd->ShowWindow(SW_SHOW);
 m_pMainWnd->UpdateWindow();
//********************************
 VERIFY( 1 == m_skin.SetWindow( m_pMainWnd->m_hWnd , "MainFrame" ));
 VERIFY( 1 == m_skin.SetDlg( "Dialog" ) );
 // 仅当具有后缀时才调用 DragAcceptFiles
 //  在 SDI 应用程序中,这应在 ProcessShellCommand 之后发生
 return TRUE;
}
4.在ExitInstance中添加下面代码
int CTestMagicSkinApp::ExitInstance()
{
 // TODO: Add your specialized code here and/or call the base class
 m_skin.ExitSkin();
 return CWinApp::ExitInstance();
}
5.VC6中也适用,只是GetModuleFileName可以直接赋值char数组
 char path[256];
 memset(path,0,256);
 GetModuleFileName(NULL,path,256);
 char * p = strrchr(path,'//') ;
 if(!p) return FALSE ;
 strcpy(p,"
///0/0");
 strcat(path,"corona.smf");
6.SkinMagicLib.h头文件放置工程目录下,SkinMagic.dll在exe相同目录下。皮肤也放在exe相同目录,也可以更改皮肤的path路径。

7.对于SkinMagicLib中声明了很多LPCTSTR类型,在VC6下没问题,在VC2008下感觉用起来一堆问题,于是我就把部分相关的改成了char *类型。

 

三、导入资源方式的问题

1. 有人跟我说不知道怎么用LoadSkin(HMODULE hModule, char* lpSkinName, char* lpType)。

这个其实是导入资源方式,将smf皮肤文件导入到资源中,选择全部文件,导入后设资源名为SKINTYPE,改资源ID为"IDR_SKINTYPE1",一定要有这个引号。

然后LoadSkin(AfxGetInstanceHandle(),"IDR_SKINTYPE1","SKINTYPE");就行了。

2. 后来我又发现一个问题,就是在VC6下LoadSkin资源是没问题,VC2008下又是无法更换皮肤,几经调查发现在VC2008下面导入资源后会在resource.h中有这么一句定义:#define IDR_SKINTYPE1    132

这就是关键了,skinMagic 的DLL中查资源是通过char*来查的,这个被定义成了数字,虽然我们引用的时候是"IDR_SKINTYPE1”,但还是发生了冲突。

解决方法:

1)将资源该名为"IDR_SKINTYPE2",注意一定要有引号。

2)也可以把#define IDR_SKINTYPE1    132这行注释掉。

 

 

以上内容及修改后的skinMagic我已上传到资源里面,有兴趣可以下载。

http://download.csdn.net/source/2889406