浙江螃蟹 发表于 2015-8-6 23:22

部份QQ华夏霸主破解补丁的代码,给有兴趣的人看看吧;

本帖最后由 浙江螃蟹 于 2015-8-6 23:28 编辑

本人在本论坛发了几次QQ华夏霸主挂的破解程序,看到好多坛友都在向我索要破解思路或视频,由于本人比较懒,不想写什么文档或录视频,干脆把破解补丁的关键代码放出,给各位有兴趣的坛友们研究吧,大神请口下留情;(本人的补丁程序是在VC6.0下写的,这个补丁的原理就是对霸主程序脱売,然后注入DLL,然后IATHOOK)




本人写的霸主外挂的破解补丁由二个文件组成,一个patchdll.dll(此文件需要注入到霸主程序中),一个bzlaunch.exe(主要是把前面的DLL注入霸主程序用的)


这里开始是patchdll中的关键代码
// patchdll.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "patchdll.h"
#include "wininet.h"
#include"function.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//下面是全局变量
typedef bool (WINAPI * My)(HINTERNET hFile,LPVOID lpBuffer,DWORD dwNumberOfBytesToRead,LPDWORD lpdwNumberOfBytesRead);
My lpoldinternetreadfile=NULL;

//
//      Note!
//
//                If this DLL is dynamically linked against the MFC
//                DLLs, any functions exported from this DLL which
//                call into MFC must have the AFX_MANAGE_STATE macro
//                added at the very beginning of the function.
//
//                For example:
//
//                extern "C" BOOL PASCAL EXPORT ExportedFunction()
//                {
//                        AFX_MANAGE_STATE(AfxGetStaticModuleState());
//                        // normal function body here
//                }
//
//                It is very important that this macro appear in each
//                function, prior to any calls into MFC.This means that
//                it must appear as the first statement within the
//                function, even before any object variable declarations
//                as their constructors may generate calls into the MFC
//                DLL.
//
//                Please see MFC Technical Notes 33 and 58 for additional
//                details.
//

/////////////////////////////////////////////////////////////////////////////
// CPatchdllApp

BEGIN_MESSAGE_MAP(CPatchdllApp, CWinApp)
      //{{AFX_MSG_MAP(CPatchdllApp)
                // NOTE - the ClassWizard will add and remove mapping macros here.
                //    DO NOT EDIT what you see in these blocks of generated code!
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPatchdllApp construction

CPatchdllApp::CPatchdllApp()
{
      // TODO: add construction code here,
      // Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CPatchdllApp object

CPatchdllApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CPatchdllApp initialization

BOOL CPatchdllApp::InitInstance()
{
      if (!AfxSocketInit())
      {
                AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
                return FALSE;
      }
      HMODULE hmod=LoadLibrary("wininet.dll");
      lpoldinternetreadfile=GetProcAddress(hmod,"InternetReadFile");
      IATHook(""wininet.dll,"InternetReadFile",MyInternetReadFile);
      return TRUE;
}

LPCSTR A()
{
      char * str="测试函数A。";
      return str;
}
LPCSTR B()
{
      char * str="测试函数B。";
      return str;
}
LPCSTR C()
{
      char * str="测试函数C。";
      return str;
}
/************************************************************************/
/* 函数说明:对DLL加载前进行EAT HOOK指定函数                                    
/* 参    数:DLL模块句柄、HOOK的导出函数名、HOOK后的代{过}{滤}理函数地址、是否采用名称查找                                 
/* 返 回 值:成功返回真实的导出函数地址,否则返回NULL   
/* By:浙江螃蟹   2015.08.04                              
/************************************************************************/
LPVOID __stdcall EATHook(HMODULE hMod,char *szApiName,LPVOID lpHookRoutine,BOOL byname)
{
      LPVOID lpOldAddr = NULL;
      PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
      PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)((DWORD)hMod + pDosHdr->e_lfanew);
      PIMAGE_EXPORT_DIRECTORY pExpDir = (PIMAGE_EXPORT_DIRECTORY)((DWORD)hMod + pNtHdr->OptionalHeader.DataDirectory.VirtualAddress);
      WORD *pwOrds = (WORD*)((DWORD)hMod + pExpDir->AddressOfNameOrdinals);
      DWORD *pdwRvas = (DWORD*)((DWORD)hMod + pExpDir->AddressOfFunctions);
      DWORD *pdwNames = (DWORD*)((DWORD)hMod + pExpDir->AddressOfNames);
      if(byname) //采用函数名进行EAT HOOK处理程序块
      {
                int i = 0;
                char *pszApiName = NULL;
                for (i=0;i<pExpDir->NumberOfNames;i++)
                {
                        pszApiName = (char *)((DWORD)hMod + pdwNames);
                        if ((pszApiName!=NULL)&&(_stricmp(szApiName,pszApiName) == 0 ))
                              {
                                        DWORD dwOldProtect;
                                        pdwRvas=pdwRvas+pwOrds;
                                        lpOldAddr = (LPVOID)((DWORD)hMod+(*pdwRvas));
                                        DWORD dwDelta = (DWORD)lpHookRoutine - (DWORD)hMod;
                                        VirtualProtectEx(GetCurrentProcess(),pdwRvas,sizeof(DWORD),PAGE_READWRITE,&dwOldProtect);
                                        *pdwRvas = dwDelta;
                                        break;
                              }
                }
                return lpOldAddr;
      }
      else//采用序号调用的EAT HOOK处理程序块
      {
                return NULL;
      }
}
/*EAT HOOK后的代{过}{滤}理函数示例
int __stdcall HookMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType)
{
      return OldMessageBoxA(hWnd,lpText,"EAT Hook 测试用",uType);
}
*/



/************************************************************************/
/* 函数说明:对程序进行IAT HOOK指定函数                                    
/* 参    数:DLL模块名称、HOOK的导出函数名、HOOK后的代{过}{滤}理函数地址                                 
/* 返 回 值:成功返回TRUE,否则返回FALSE
/* By:浙江螃蟹   2015.08.04                              
/************************************************************************/
BOOL __stdcall IATHook(LPCSTR pDLLName,LPCSTR pszApiname, PDWORD pNewAddr)
{      
      HMODULE hModule=NULL;
      PIMAGE_DOS_HEADER pIMAGE_DOS_HEADER=NULL;
      PIMAGE_NT_HEADERS pNTHeader=NULL;
      PIMAGE_OPTIONAL_HEADER32 pOptionalHeader=NULL;
      PIMAGE_DATA_DIRECTORY DataDirectory=NULL;
      PIMAGE_IMPORT_DESCRIPTOR pImportHeader=NULL;
      PIMAGE_IMPORT_DESCRIPTOR pDllModule=NULL;
      LPSTR pModuleLabel=NULL;
      PIMAGE_THUNK_DATA pThunkData=NULL;
      DWORD OldProtect;
      LPVOID lpaddr;

      HMODULE hmod=GetModuleHandleA(pDLLName);
      PDWORD pOldAddr=(PDWORD)GetProcAddress(hmod,pszApiname);

      hModule=GetModuleHandle(NULL);
      pIMAGE_DOS_HEADER=(PIMAGE_DOS_HEADER)hModule;

      if(pIMAGE_DOS_HEADER->e_magic==IMAGE_DOS_SIGNATURE)
      {
                pNTHeader=(PIMAGE_NT_HEADERS)((DWORD)pIMAGE_DOS_HEADER+(DWORD)pIMAGE_DOS_HEADER->e_lfanew);
                if (pNTHeader->Signature==IMAGE_NT_SIGNATURE)
                {
                        pOptionalHeader=(PIMAGE_OPTIONAL_HEADER32)&(pNTHeader->OptionalHeader);
                        DataDirectory=pOptionalHeader->DataDirectory;
                        pImportHeader=(PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hModule+DataDirectory.VirtualAddress);
                }
                else
                        return FALSE;
      }
      else
                return FALSE;
      while(pImportHeader->Name!=NULL)
      {
                pModuleLabel=(LPSTR)((DWORD)hModule+(DWORD)pImportHeader->Name);
                if(*pModuleLabel==*pDLLName)
                {
                        pDllModule=pImportHeader;
                        pThunkData=(PIMAGE_THUNK_DATA)((DWORD)hModule+(DWORD)pDllModule->FirstThunk);
                        while(pThunkData->u1.Function!=NULL)
                        {
                              if(pOldAddr==(PVOID)pThunkData->u1.Function)
                              {
                                        MEMORY_BASIC_INFORMATIONmbi;
                                        lpaddr=&pThunkData->u1.Function;
                                        VirtualQuery(lpaddr,&mbi,sizeof(mbi));
                                        VirtualProtect(lpaddr,sizeof(PDWORD),PAGE_READWRITE,&OldProtect);
                                        WriteProcessMemory(GetCurrentProcess(),lpaddr,&pNewAddr, sizeof(PDWORD), NULL);
                                        VirtualProtect(&pThunkData->u1.Function,sizeof(PDWORD),OldProtect,&OldProtect);
                                        return TRUE;
                              }
                              else
                                        pThunkData++;
                        }
                }
                pImportHeader++;
      }
      return FALSE;
}



//*EAT HOOK后的代{过}{滤}理函数
bool WINAPI MyInternetReadFile(HINTERNET hFile,LPVOID lpBuffer,DWORD dwNumberOfBytesToRead,LPDWORD lpdwNumberOfBytesRead)
{
      bool bl=lpoldinternetreadfile(hFile,lpBuffer,dwNumberOfBytesToRead,lpdwNumberOfBytesRead);
      if(*lpdwNumberOfBytesRead!=0)
      {
      modify(lpBuffer,lpdwNumberOfBytesRead);
      }
      return bl;
}


//下面是BZlaunch.cpp文件
// bzlaunchDlg.cpp : implementation file
//

#include "stdafx.h"
#include "bzlaunch.h"
#include "bzlaunchDlg.h"
#include "function.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CBzlaunchDlg dialog

CBzlaunchDlg::CBzlaunchDlg(CWnd* pParent /*=NULL*/)
      : CDialog(CBzlaunchDlg::IDD, pParent)
{
      //{{AFX_DATA_INIT(CBzlaunchDlg)
                // NOTE: the ClassWizard will add member initialization here
      //}}AFX_DATA_INIT
      // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
      m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CBzlaunchDlg::DoDataExchange(CDataExchange* pDX)
{
      CDialog::DoDataExchange(pDX);
      //{{AFX_DATA_MAP(CBzlaunchDlg)
                // NOTE: the ClassWizard will add DDX and DDV calls here
      //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CBzlaunchDlg, CDialog)
      //{{AFX_MSG_MAP(CBzlaunchDlg)
      ON_WM_PAINT()
      ON_WM_QUERYDRAGICON()
      ON_BN_CLICKED(IDC_STARTUP, OnStartup)
      ON_WM_CLOSE()
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBzlaunchDlg message handlers

BOOL CBzlaunchDlg::OnInitDialog()
{
      CDialog::OnInitDialog();

      // Set the icon for this dialog.The framework does this automatically
      //when the application's main window is not a dialog
      SetIcon(m_hIcon, TRUE);                        // Set big icon
      SetIcon(m_hIcon, FALSE);                // Set small icon
      
      // TODO: Add extra initialization here
      
      return TRUE;// return TRUEunless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//to draw the icon.For MFC applications using the document/view model,
//this is automatically done for you by the framework.

void CBzlaunchDlg::OnPaint()
{
      if (IsIconic())
      {
                CPaintDC dc(this); // device context for painting

                SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

                // Center icon in client rectangle
                int cxIcon = GetSystemMetrics(SM_CXICON);
                int cyIcon = GetSystemMetrics(SM_CYICON);
                CRect rect;
                GetClientRect(&rect);
                int x = (rect.Width() - cxIcon + 1) / 2;
                int y = (rect.Height() - cyIcon + 1) / 2;

                // Draw the icon
                dc.DrawIcon(x, y, m_hIcon);
      }
      else
      {
                CDialog::OnPaint();
      }
}

// The system calls this to obtain the cursor to display while the user drags
//the minimized window.
HCURSOR CBzlaunchDlg::OnQueryDragIcon()
{
      return (HCURSOR) m_hIcon;
}

void CBzlaunchDlg::OnStartup()
{
      // TODO: Add your control notification handler code here
      start();
}

void CBzlaunchDlg::OnClose()
{
      // TODO: Add your message handler code here and/or call default
      //::MessageBox(NULL,"窗口退出提示。","提示",NULL);


      CDialog::OnClose();
}


//下面是function.cpp文件,为了给各位坛友方便使用破解补丁,特地把霸主的原版程序(霸主.exe)、原版DLL(data.dll)、还有我上面写的补丁DLL(patchdll.dll)作为自定义资源封到bzlaunch.exe中,此程序运行过程是先释放三个自定义资源,然后运行霸主.exe,然后把补丁DLL注入进去,之后bzlaunch.exe会后台定时检测霸主程序是否在运行,如果用户游戏结束了关闭了霸主程序窗口,则bzlaunch.exe会自动清除他释放出来的三个文件,保持系统清洁;

#include "stdafx.h"
#include "BZlaunch.h"
#include "function.h"

/************************************************************************/
/* 函数说明:释放资源中某类型的文件                                    
/* 参    数:新文件名、资源ID、资源类型                                 
/* 返 回 值:成功返回TRUE,否则返回FALSE   
/* By:浙江螃蟹   2015.08.01                              
/************************************************************************/
BOOL ReleaseRes(CString strFileName,WORD wResID,CString strFileType)
{
DWORD dwWrite=0;
HANDLEhFile = CreateFile(strFileName, GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if ( hFile == INVALID_HANDLE_VALUE )
{
      return FALSE;
}
HRSRC   hrsc =FindResource(NULL, MAKEINTRESOURCE(wResID), strFileType);
HGLOBAL hG = LoadResource(NULL, hrsc);
DWORD   dwSize = SizeofResource( NULL,hrsc);
WriteFile(hFile,hG,dwSize,&dwWrite,NULL);   
CloseHandle( hFile );
return TRUE;
}

BOOL start()
{
CString str_temppath;
TCHAR strpath;
GetTempPath(MAX_PATH,strpath);
Sleep(100);
str_temppath.Format("%s%s",strpath,"data.dll");
if(!ReleaseRes(str_temppath,(WORD)IDR_DATADLL,"myres"))
      return FALSE;
str_temppath.Format("%s%s",strpath,"patchdll.dll");
if(!ReleaseRes(str_temppath,(WORD)IDR_PATCHDLL,"myres"))
      return FALSE;
str_temppath.Format("%s%s",strpath,"霸主.exe");
//if(!ReleaseRes(str_temppath,(WORD)IDR_BZEXE,"myres"))
if(!ReleaseRes(str_temppath,(WORD)IDR_BZEXE,"myres"))
      return FALSE;
STARTUPINFO si = {0};
si.cb = sizeof(si);
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESHOWWINDOW;

PROCESS_INFORMATION pi = {0};
if(!CreateProcess(NULL,str_temppath.GetBuffer(0), NULL, NULL, FALSE, CREATE_SUSPENDED, NULL,strpath, &si, &pi))
      return FALSE;
str_temppath.Format("%s%s",strpath,"patchdll.dll");
TCHAR *strfilename;
strfilename=str_temppath.GetBuffer(0);
typedef VOID (APIENTRY *PAPCFUNC)(DWORD dwParam);
typedef DWORD (WINAPI *APC)(PAPCFUNC pfnAPC,HANDLE hThread,DWORD dwData);
HMODULE hmod=GetModuleHandle("kernel32.dll");
APC APCFUN=(APC)GetProcAddress(hmod,"QueueUserAPC");

PVOID param = VirtualAllocEx(pi.hProcess,NULL, str_temppath.GetLength(), MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE) ;

if (param != NULL)
{
   DWORD dwRet ;
   if (WriteProcessMemory(pi.hProcess, param, (LPVOID)str_temppath.GetBuffer(0), str_temppath.GetLength(), &dwRet))
   {
      DWORD dwstat=APCFUN((PAPCFUNC)LoadLibraryA,pi.hThread,(DWORD)param);
   }
}
ResumeThread(pi.hThread);


do
{
      Sleep(500);
} while(checkisrun("助手"));
exitprogram();
return TRUE;
}

BOOL checkisrun(LPCTSTR wndcaptionname)
{
      HWND hwndbz=FindWindow(NULL,wndcaptionname);
      if(!hwndbz)
                return FALSE;
      return TRUE;
}

VOID exitprogram()
{
CString str_temppath;
TCHAR strpath;
GetTempPath(MAX_PATH,strpath);
str_temppath.Format("%s%s",strpath,"data.dll");
remove(str_temppath.GetBuffer(0));
str_temppath.Format("%s%s",strpath,"patchdll.dll");
remove(str_temppath.GetBuffer(0));
str_temppath.Format("%s%s",strpath,"霸主.exe");
remove(str_temppath.GetBuffer(0));
//::MessageBox(NULL,"未找到霸主程序窗口,自动退出提示。","提示",NULL);
}






浙江螃蟹 发表于 2015-8-7 10:17

封神之剑 发表于 2015-8-7 09:44
有最新可用的破解外挂成品吗?

http://www.52pojie.cn/thread-396963-1-1.html请参考这个贴子。

浙江螃蟹 发表于 2015-8-8 09:09

q348114971 发表于 2015-8-7 21:38
还遇到TMD壳脱不掉。

那你应该找个简单的来搞他呀,TMD和VMP我都觉的挺变态的。

wangdong123 发表于 2015-8-6 23:25

感谢楼主的思路分享{:1_912:}

2909094965 发表于 2015-8-6 23:30

看不懂,不过还是谢谢分享

homn888 发表于 2015-8-7 09:39

看不懂 不过还是要谢谢你

封神之剑 发表于 2015-8-7 09:44

有最新可用的破解外挂成品吗?

homn888 发表于 2015-8-7 11:08

真心看不懂希望多个视频 拜托{:17_1089:}

q348114971 发表于 2015-8-7 17:02

{:1_900:}思路是出来了,楼主威武。

浙江螃蟹 发表于 2015-8-7 17:19

q348114971 发表于 2015-8-7 17:02
思路是出来了,楼主威武。

你有思路了?希望你写的破解补丁也能共享我一下哦。

小人国历险记 发表于 2015-8-7 18:37

新手上路,不知道从哪里开始了,下了看看{:301_994:}
页: [1] 2 3
查看完整版本: 部份QQ华夏霸主破解补丁的代码,给有兴趣的人看看吧;