看流星社区

 找回密码
 注册账号
查看: 3460|回复: 9

vc远程注入CALL问题,小弟困惑了好几天了,高手来帮帮我啊

[复制链接]

该用户从未签到

发表于 2011-3-24 10:36:59 | 显示全部楼层 |阅读模式
程序运行后.........游戏就会报错.........  

1:函数不带参数注入的话,不会有任何问题,比如:攻击CALL,打坐CALL  
2:函数带参数时,游戏就会出错,比如选怪CALL  

我用的是DLL注入  

//-------------------------------------------要注入的参数类别------------------------------------------
typedef struct ParamData
{
    DWORD Param1;
    DWORD Param2;
}ParamData,*Paramp;

//-----------------------------------------------选怪CALL---------------------------------------------------
void xuancall(LPVOID lParam)
{
ParamData *lp;
    lp=(ParamData*)lParam;
    DWORD ID=lp->Param1;
DWORD master;
master=0x5E2A2A0+4*ID;
_asm
{
   mov edi,dword ptr [master]
   mov ebp,0x12cd3c
   mov eax,dword ptr [edi]
   push 0
   push 1
   push 44d
   mov ecx,edi
   call dword ptr [eax+4]
   mov edx,dword ptr [0x5e33ee0]
   mov ecx,dword ptr [edi+0xc]
   mov dword ptr [edx+0x1a30],ecx
   mov eax,dword ptr [ebp+0xc]
   mov cl,byte ptr [0x49f23d1]
   mov esi,eax
   mov esi,dword ptr [ebp+8]
   mov ecx,dword ptr [master]
   mov edx,dword ptr [ecx+8]
   mov eax,dword ptr [ecx]
   push 0
   push 0
   push 420
   call dword ptr [eax+4]
}
}

//---------------------------------------注入部分-------------------------------------------
BOOL InsertDll(void *pfunc,DWORD dwID,DWORD Param1=0,DWORD Param2=0)
{
LPVOID ThreadAdd;
LPVOID ParamAddr;
HANDLE h_process=NULL;
ParamData pdata;
pdata.Param1=Param1;
pdata.Param2=Param2;
h_process=::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION | PROCESS_VM_WRITE,FALSE,dwID);
if(h_process==NULL)
{
  ::MessageBox(NULL,("打开进程失败!"),("提示"),MB_OK);
  return FALSE;
}
ThreadAdd=::VirtualAllocEx(h_process,NULL,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
ParamAddr=::VirtualAllocEx(h_process,NULL,sizeof(ParamData),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if(!ThreadAdd)
{
  ::MessageBox(NULL,("申请空间失败!"),("提示"),MB_OK);
  return FALSE;
}
::WriteProcessMemory(h_process,ThreadAdd,pfunc,4096,NULL);
::WriteProcessMemory(h_process,ParamAddr,&pdata,sizeof(pdata),NULL);
HANDLE h_thread=::CreateRemoteThread(h_process,NULL,0,(LPTHREAD_START_ROUTINE)ThreadAdd,ParamAddr,0,NULL);
if(!h_thread)
{
  ::MessageBox(NULL,("远程注入失败!"),("提示"),MB_OK);
  return FALSE;
}
::WaitForSingleObject(h_thread,INFINITE);
::VirtualFreeEx(h_process,ThreadAdd,4096,MEM_RELEASE);  
::VirtualFreeEx(h_process,ParamAddr,sizeof(ParamData),MEM_RELEASE);
::CloseHandle(h_thread);
::CloseHandle(h_process);
return TRUE;
}

//------------------------------------------------调用部分-------------------------------------------
InsertDll(xuancall,g_ProcessID,guaiwu);            //guaiwu是传入的怪物ID

有一点要说一下,就是不带参数CALL能成功调用
如:InsertDll(hitcall,g_ProcessID);                       



还有我用VC调试去更,发现是HANDLE h_thread=::CreateRemoteThread(h_process,NULL,0,(LPTHREAD_START_ROUTINE)ThreadAdd,ParamAddr,0,NULL);一句过不去


请高手们帮帮小弟我~~~吧!

该用户从未签到

发表于 2011-3-24 10:37:52 | 显示全部楼层
首先你汇编内没加
pushad
popad
再次。你有阅读过 调用约定 吗?
如果没有请到百度看2篇文章继续写挂

该用户从未签到

发表于 2011-3-24 10:45:07 | 显示全部楼层
顶一!vc 代码难搞,少部份可以。
发包的就不行(包是正确的),也是CreateRemoteThread的问题。

该用户从未签到

发表于 2011-3-24 10:45:17 | 显示全部楼层
代码真看不出哪里错了 楼主可以先不要用程序实现call的功能  可以先弹出一个简单的对话框逐步调试一下
另外问一句楼主是什么游戏?

该用户从未签到

 楼主| 发表于 2011-3-24 10:45:49 | 显示全部楼层
是《热血江湖》选怪的CALL
就是琢磨了半天还是想不通~~~~

哪位高手能指点下为什么到了HANDLE h_thread=::CreateRemoteThread(h_process,NULL,0,(LPTHREAD_START_ROUTINE)ThreadAdd,ParamAddr,0,NULL);

就会卡起啊!!!!

该用户从未签到

发表于 2011-3-24 10:46:21 | 显示全部楼层
LZ不确定你的代码是怎么回事,还是学ManGo说的在代码中加N个::MessageBox(NULL,"1","",0);
然后一步一步看,执行到哪了
还有我发现你汇编中push参数部分不是用16进制值的。在CALL工具中是不需要0x表示,但是VC中是需要的

该用户从未签到

 楼主| 发表于 2011-3-24 10:46:46 | 显示全部楼层
小弟我~把现在保护的PUSHAD和POPAD加进去了
也把LS高手所说的问题PUSH里部分参数问题也改了
但问题还是存在,传递参数时会在CreateRemoteThread那卡住
无参数CALL可以正常运行

该用户从未签到

发表于 2011-3-24 10:47:20 | 显示全部楼层
首先观察到楼主的ThreadProc的函数原型不对,按CreateRemoteThreadProc的定义,这个参数应该是一个

DWORD WINAPI ThreadProc(
  LPVOID lpParameter   // thread data
);
的函数指针。

其中最重要的是WINAPI调用方式定义,它明确指出这个函数应该自己释放参数堆栈空间。
而楼主定义的函数原型是
void  ThreadProc(
  LPVOID lpParameter   // thread data
);

编译器默认为C调用方式,由调用方释放参数堆栈空间。

这样线程函数返回后无法回到预期的调用环境。崩溃是必然的。

再次,楼主又用VC调试此创建过程。注意到楼主在函数带有参数和内部局部变量的情况下,并没有用__declspec(naked)禁止Debug版本自动产生的堆栈检测代码。因此调试必定是‘雪上加霜’。

该用户从未签到

 楼主| 发表于 2011-3-24 10:52:14 | 显示全部楼层
LS的高手~~~~
小弟我把传递的函数修改后
如下:
static DWORD WINAPI xuancall(LPVOID Param)
{
    ParamData *lp;
    lp=(ParamData*)Param;
    DWORD m_id=lp->Param3;
    _asm
    {
            pushad
            mov edi,dword ptr [m_id]
            mov ebp,0x12cd3c
            mov eax,dword ptr [edi]
            push 0
            push 0x1
            push 0x44d
            mov ecx,edi
            call dword ptr [eax+0x4]
            mov edx,dword ptr [0x5e33ee0]
            mov ecx,dword ptr [edi+0xc]
            mov dword ptr [edx+0x1a30],ecx
            mov eax,dword ptr [ebp+0xc]
            mov cl,byte ptr [0x49f23d1]
            mov esi,eax
            mov esi,dword ptr [ebp+0x8]
            mov ecx,dword ptr [m_id]
            mov edx,dword ptr [ecx+0x8]
            mov eax,dword ptr [ecx]
            push 0
            push 0
            push 0x420
            call dword ptr [eax+0x4]
            popad
    }

    return 0;
}

然后生成Release的文件,但问题依然还是存在!
传入有参数函数的时候,还是卡在CreateRemoteThreadProc那了

该用户从未签到

发表于 2011-3-24 10:59:55 | 显示全部楼层
你的第一版和第二版的汇编代码改动太大.所以我无法判断你的汇编代码的有效性。只能就一般的流程做下分析:

以第一版的代码为例:
master=0x5E2A2A0+4*ID;                   //ID是你传进来的参数,应该是怪物的数组索引值。0x5e2a2a0应该是怪物基址(只看作用,不考虑 正确性。正确行是靠你用OD跟踪时来发现的)                     
_asm  
{   
   mov edi,dword ptr [master]             //计算出的怪物对象地址放入EDI保存
   mov ebp,0x12cd3c                           //搞不懂虾米意思,ebp寄存器是有特殊用途的,而且最要命的是前面并没有推入堆栈保存。  
   mov eax,dword ptr [edi]                   //pvtable
   push 0                                                //参数入栈
   push 1                                                //同上
   push 44d                                           //同上
   mov ecx,edi                                       //this ptr
   call dword ptr [eax+4]                      //调用怪物对象的方法
   mov edx,dword ptr [0x5e33ee0]    //后面寻址用
   mov ecx,dword ptr [edi+0xc]          //怪物的某个属性值放入ecx
   mov dword ptr [edx+0x1a30],ecx   //根据上面的意思,就是把调用怪物方法后,怪物某个发生变化的属性存入[[0x5e33ee0+0]x1a30]这个地址  
   mov eax,dword ptr [ebp+0xc]         //无语
   mov cl,byte ptr [0x49f23d1]             //无语
   mov esi,eax                                        //无语
   mov esi,dword ptr [ebp+8]              //连同上面三句,没有任何作用。和上面的 mov ebp,0x12cd3c 一样,估计是楼主从源代码环境中‘硬’搬来的
   mov ecx,dword ptr [master]          //怪物对象指针放入ecx,同 mov ecx,edi  
   mov edx,dword ptr [ecx+8]           //对象某属性放入edx,估计下面的调用函数中会用到。
   mov eax,dword ptr [ecx]                //pvtable
   push 0                                             //参数入栈
   push 0                                             //参数入栈
   push 420                                        //参数入栈
   call dword ptr [eax+4]                  //调用对象方法。
}   

综上分析,这个CALL主要靠两个call dword ptr [eax+4]来完成。建议楼主把原代码吃透。不要生拉硬套。

如果上面的代码是可信的。可以简化如下:

__declspec(naked) DWORD  SelectCall(LPVOID lParam)                    //告诉编译器,自己处理栈桢码
{
__asm
   {        
    push ebp                                                                                                     //栈基址入栈
    mov  esp,esp                                                                                             //保存栈顶指针                        
    push esi                                                                                                      //保存关键寄存器
    push edi                                                                                                     //保存关键寄存器
     
    mov  eax,dword ptr[ebp + 8]                                                                   //eax = lPamam
    mov  eax,[eax]                                                                                           //eax = (ParamData*)lParam -> Param1  
    shl  eax,2                                                                                                   //ID*4
    add  eax,0x5e2a2a0                                                                               // eax =  0x5e2a2a0 +  ID * 4

    mov  edi,dword ptr[eax]     
    mov  eax,dword ptr[edi]

    push 0
    push 1
    push 44d
    mov  ecx,edi
    call dword ptr[eax+4]

    mov  edx,dword ptr[0x5e33ee0]
    mov  ecx,dword ptr[edi+0xc]
    mov  dword ptr[edx+0x1a30],ecx
         
    mov  ecx,edi
    mov  eax,dword ptr[ecx]

    push 0
    push 0
    push 420
    call dword ptr[eax+4]
     
    pop edi                                                                                                //还原现场
    pop esi                                                                                                //还原现场
    mov esp,ebp                                                                                     //还原现场
    retn 4                                                                                                  // 清理参数入栈空间(模仿__stdcall)
   }     
}
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-29 01:09

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

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