挂海论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
 友情提示:文字/图片广告均非网站意见,请担保交易勿直接付款,由此产生的责任自负
游戏交易就上寄售网-专注稳定-诚信赢天下玩游戏来117游戏网(H5不下载也能玩手游传奇,吃鸡,竞技都有)天下盾/国内/免实名/免备案CDN无视一切CC/DD攻击
→入驻S9企业发卡网各种全黑号辅助群:475351077 ██【我要租此广告位】██.
.. .
查看: 2341|回复: 2
打印 上一主题 下一主题

[交流] 通过调试寄存器不修改代码实现bt功能

[复制链接]
4中级会员
320/600

320

积分

110

主题

4

听众
已帮网友解决0 个问题
好评
0
贡献
210
海币
2940
交易币
0
跳转到指定楼层
楼主
发表于 2015-2-10 00:24:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
提醒:若下载的软件是收费的"请不要付款",可能是骗子,请立即联系本站举报,执意要付款被骗后本站概不负责。(任何交易请走第三方中介,请勿直接付款交易以免被骗!切记).

友情提示:文字/图片广告均非本站意见,请担保交易勿直接付款,由此产生的责任自负!!!↑↑


通过调试寄存器不修改代码实现bt功能

下面以封包截取的代码来说明实现bt功能的原理。其中好些地方我用的也不熟练,复杂了,高手就不用看了。主要是会影响些速度,尤其是我的本本,开时间长了就死机.


首先分析要中断的位置

    .text:00588F78 mov    ecx, [esp+30h+arg_0]
    .text:00588F7C push    esi            ; size_t
    .text:00588F7D push    ecx            ; void *
    .text:00588F7E push    eax            ; void *
    .text:00588F7F call    ds:memmove

上面是发包函数里的部分代码,其中00588F7D位置ecx存储封包数据地址,00588F7C位置esi存储封包大小。
如果在此处将程序中断,并将所需数据读取出来,目的就达到了。

对于变态功能,以空中漫步为例:

    .text:00461792 mov    eax, [ecx+5E0h]
    .text:00461798 fild    [esp+10h+var_8]
    .text:0046179C cmp    eax, ebx
    .text:0046179E fmul    ds:flt_85EC2C
    .text:004617A4 fstp    [esp+10h+arg_0]
    .text:004617A8 jz      short loc_461828

修改004617A8处的跳转就可以空中漫步,如果在0046179C处中断,然后修改eax或者ebx的值,也可以实现相应功能但不需要修改指令(注意跳转过后要记得恢复寄存器的值,隐藏建筑和跳跃飞天也可以这样实现)。


下面是封包截取的实现过程,修改一下即可实现bt功能。

1.CreateProcess或者FindWindow或者W美进程ID(dwW2iProcessId)

2.调试进程DebugActiveProcess(dwW2iProcessId)

3.进入调试循环体等待调试事件产生WaitForDebugEvent(&DebugEv, 10)

4.接收到CREATE_PROCESS_DEBUG_EVENT事件时,对全部线程设立断点。
(我可能复杂了,用CREATE_THRAD_DEBUG_EVENT事件可能简单些,刚会用就不错了呵呵,开始我只在主线程里设置了断点,死活断不下来)

下面是设置断点的方法,使用GetThreadContext和SetThreadContext函数
对于bt功能,修改寄存器的值,也通过这两个函数来实现。

    HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, ThreadInfo.th32ThreadID);
    SuspendThread(hThread);

    CONTEXT Regs = {0};
    Regs.ContextFlags = CONTEXT_DEBUG_REGISTERS; //CONTEXT_DEBUG
    ::GetThreadContext(hThread, &Regs);

    Regs.Dr0 = W2I_SENDCALL_ADDR1; //中断地址
    Regs.Dr7 = BREAK_DR7_FLAG; //0x401启用dr0断点

    ::SetThreadContext(hThread, &Regs);

    ResumeThread(hThread);
    CloseHandle(hThread);

5.当在所需地址处中断时,来进行我们真正的功能操作,读取数据或者设置数据,同时设置数据改回处的断点。

    ReadProcessMemory(hW2iProcess, (void*)Regs.Ecx, buf, len, &len);

6.当在数据改回处中断时,将寄存器值恢复,并设置修改处断点(其实可以一起设置好,但是要占用两个dr寄存器。dr寄存器一共4个,所以节省下只用一个,这样最多也只可以实现4个中断功能,不知道说清楚没)

7.当W美进程结束时,响应EXIT_PROCESS_DEBUG_EVENT事件,也退出。

注意每次中断时要用ContinueDebugEvent(DebugEv.dwProcessId, DebugEv.dwThreadId, dwContinueStatus)继续。

这就是整个过程,其实修改代码也不一定不防封。个人理解游戏协议分为两大类,封包是其实现,一类是正常的游戏所需数据,一类是防止 的检测协议。(始终要记得,网络游戏,服务器所需的一切数据必是通过网络来传输,必是通过封包来运载。)如果是检测协议,就回复一个正常结果的检测包,必能防封,所以说脱机挂是最难封的,因为这建立在全部协议破解的基础上。想当初传神和赤月挂,因为技术上无法封杀,只好派人去抓程序员了。

不修改代码也不一定防封,反调试的技术也很多,具体我还不清楚呵呵。



下面是截包程序的代码:


#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <conio.h>

#define W2I_WINDOW_TITLE TEXT("Element Client")
#define W2I_WINDOW_CLASS TEXT("ElementClient Window")

//#define W2I_WINDOW_TITLE NULL
//#define W2I_WINDOW_CLASS TEXT("Notepad")

#define W2I_SENDCALL      0x00588EF0

#define W2I_SENDCALL_ADDR1      (W2I_SENDCALL+0x8E)
#define W2I_SENDCALL_ADDR2      (W2I_SENDCALL+0x8F)

#define BREAK_DR7_FLAG          0x401

int main(int argc, char* argv[])
{
    HANDLE hW2iProcess;
    DWORD dwW2iProcessId;
    HWND hW2iWnd;
    DWORD Count = 0;


    //查找窗口,并且获取窗口进程线程ID
    hW2iWnd = ::FindWindow(W2I_WINDOW_CLASS, W2I_WINDOW_TITLE);

    if( hW2iWnd>0 && ::GetWindowThreadProcessId(hW2iWnd, &dwW2iProcessId)
        && dwW2iProcessId && ( hW2iProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwW2iProcessId) )  
        && DebugActiveProcess(dwW2iProcessId) )
    {
        DEBUG_EVENT DebugEv;
        DWORD dwContinueStatus;

        while(TRUE)
        {
            if(WaitForDebugEvent(&DebugEv, 10))
            {
                dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;

                switch(DebugEv.dwDebugEventCode)
                {
                case EXCEPTION_DEBUG_EVENT:
                    {
                        if((DWORD)DebugEv.u.Exception.ExceptionRecord.ExceptionAddress==W2I_SENDCALL_ADDR1)
                        {
                            HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, DebugEv.dwThreadId);
                            SuspendThread(hThread);

                            CONTEXT Regs = {0};
                            Regs.ContextFlags = CONTEXT_DEBUG_REGISTERS|CONTEXT_INTEGER;
                            ::GetThreadContext(hThread, &Regs);

                            Regs.Dr0 = W2I_SENDCALL_ADDR2;
                            Regs.Dr7 = BREAK_DR7_FLAG;

                            printf("%d\n", Count++);
                            //Regs.Esi - len
                            //Regs.Ecx - buf
                            BYTE buf[1024];
                            SIZE_T len = (Regs.Esi<512 ? Regs.Esi : 512);
                            if( ReadProcessMemory(hW2iProcess, (void*)Regs.Ecx, buf, len, &len) )
                            {
                                FILE * fp = fopen("Cap.txt", "a+");
                                for(SIZE_T i=0; i<len; i++)
                                {
                                    printf("%02X ", buf);
                                    if(fp)
                                        fprintf(fp, "%02X ", buf);
                                }
                                printf("\n\n");
                                if(fp)
                                {
                                    fprintf(fp, "\n\n");
                                    fclose(fp);
                                }
                            }

                            ::SetThreadContext(hThread, &Regs);

                            ResumeThread(hThread);
                            CloseHandle(hThread);
                        }

                        if((DWORD)DebugEv.u.Exception.ExceptionRecord.ExceptionAddress==W2I_SENDCALL_ADDR2)
                        {
                            HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, DebugEv.dwThreadId);
                            SuspendThread(hThread);

                            CONTEXT Regs = {0};
                            Regs.ContextFlags = CONTEXT_DEBUG_REGISTERS; //CONTEXT_DEBUG
                            ::GetThreadContext(hThread, &Regs);

                            Regs.Dr0 = W2I_SENDCALL_ADDR1;
                            Regs.Dr7 = BREAK_DR7_FLAG;

                            ::SetThreadContext(hThread, &Regs);

                            ResumeThread(hThread);
                            CloseHandle(hThread);
                        }

                        dwContinueStatus = DBG_CONTINUE;
                        break;
                    }

                case CREATE_PROCESS_DEBUG_EVENT:
                    {
                        HANDLE hSnapshot = NULL;
                        THREADENTRY32 ThreadInfo = { sizeof(THREADENTRY32) };

                        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL);
                        if(hSnapshot>0)
                        {
                            if(Thread32First(hSnapshot, &ThreadInfo))
                            {
                                do {
                                    if(ThreadInfo.th32OwnerProcessID==dwW2iProcessId)
                                    {
                                        //printf("%08x %08x\n", ThreadInfo.th32ThreadID, ThreadInfo.th32OwnerProcessID);

                                        HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, ThreadInfo.th32ThreadID);
                                        SuspendThread(hThread);

                                        CONTEXT Regs = {0};
                                        Regs.ContextFlags = CONTEXT_DEBUG_REGISTERS; //CONTEXT_DEBUG
                                        ::GetThreadContext(hThread, &Regs);

                                        Regs.Dr0 = W2I_SENDCALL_ADDR1;
                                        Regs.Dr7 = BREAK_DR7_FLAG;

                                        ::SetThreadContext(hThread, &Regs);

                                        ResumeThread(hThread);
                                        CloseHandle(hThread);
                                    }
                                } while(Thread32Next(hSnapshot, &ThreadInfo));
                            }
                            CloseHandle(hSnapshot);
                        }


                        printf("附加到W美进程成功!\n截获文件将保存到Cap.txt\n\n");

                        break;
                    }

                case EXIT_PROCESS_DEBUG_EVENT:
                    {
                        return 0;
                        break;
                    }
                }

                ContinueDebugEvent(DebugEv.dwProcessId, DebugEv.dwThreadId, dwContinueStatus);
            }
        }
    }
    else
    {
        printf("附加到W美进程失败!\n\n");
    }

    printf("\n按任意键退出!\n");
    getch();

    return 0;
}



联系我时,请说是在 挂海论坛 上看到的,谢谢!



上一篇:发一个 验证码识别技术帖
下一篇:反调试技巧总结-原理和实现
免责声明:
1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关。一切关于该内容及资源商业行为与www.52ghai.com无关。

2、本站提供的一切资源内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。

3、本站信息来自第三方用户,非本站自制,版权归原作者享有,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

4、如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵犯你版权的,请邮件与我们联系删除(邮箱:[email protected]),本站将立即改正。

8资深会员
1320/1800

1320

积分

286

主题

35

听众
已帮网友解决0 个问题
好评
11
贡献
1034
海币
3726
交易币
5
沙发
发表于 2015-2-19 00:26:24 | 只看该作者
我是个凑数的。。。

0

积分

0

主题

0

听众
已帮网友解决0 个问题
好评
0
贡献
0
海币
304
交易币
0
板凳
发表于 2015-7-21 04:42:28 | 只看该作者
看帖回帖,楼主辛苦了!       
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

免责声明|Archiver|手机版|小黑屋|挂海论坛

GMT+8, 2024-5-19 20:55 , Processed in 0.434153 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.2

本站资源来自互联网用户收集发布,如有侵权请邮件与我们联系处理。xhzlw@foxmail.com

快速回复 返回顶部 返回列表