一种注入进程,获得完全操控的方法之二

计算机视觉-全景图像拼接中的特征匹配与优化策略 本文深入探讨了计算机视觉中全景图像拼接的核心技术,重点解析了特征匹配后的关键优化策略。通过SIFT特征提取、RANSAC算法剔除误匹配,并结合APAP算法应对视差与鬼影问题,详细阐述了从基础对齐到无缝融合的完整流程,为开发者实现高质量全景拼接提供了实用指南。 阅读详情
看到了我的之一,我想大家会很清楚,因为这个方法的最大的BUG就是在回调函数之后来处理,如果前面已经处理了,
那么我们就无法处理了。而且又要修改系统DLL,比较不完美。我最近又发现了两种方法:
  一、修改RegisterClassA:
  相对前面的方法来说,这个方法很好用,因为,我们可以很容易把回掉函数改掉。类似如下代码:
//---------------------------------------------------------------------------
int CMuGame::InitRegClass()
{  
  //获取模块句柄:
  HINSTANCE hModule=::GetModuleHandle("User32.dll");
  //获取原始函数地址:
  fpsRegisterClassA=(REGWINCLASS)::GetProcAddress(hModule,"RegisterClassA");

  //获取当前内存块的保护类型:
  MEMORY_BASIC_INFORMATION _base;
  ::VirtualQuery((LPVOID)((DWORD)hModule+0x1000),&_base,sizeof(MEMORY_BASIC_INFORMATION));

  //处理为读写类型:
  ::VirtualProtect(_base.BaseAddress,_base.RegionSize,PAGE_READWRITE,&_base.Protect);

  //获得导出表的地址和大小:
  DWORD   dwExportSize=NULL;
  PDWORD  pdwExportAddr=NULL;

  appfun.Load(hModule);
  appfun.GetExportTable(&dwExportSize,&pdwExportAddr);

  //查找RegisterClassA函数地址:
  for(DWORD i=0;i<dwExportSize;i++,pdwExportAddr++)
  {
    if((*pdwExportAddr+(DWORD)hModule)==(DWORD)fpsRegisterClassA)
    {
      //计算跳转地址:
      DWORD  dword=(DWORD)fpnRegisterClassA-(DWORD)fpsRegisterClassA;
    
      //声明结构对象:
      _ASM_JMP _jmp;
      _jmp._01cmd =0xE9;
      memcpy((PDWORD)_jmp._02dat,&dword,4);
      memcpy((LPVOID)((DWORD)fpsRegisterClassA-5),&_jmp,5);

      //修改导出表地址:
      DWORD  dwAddr=*pdwExportAddr-5;
      memcpy(pdwExportAddr,&dwAddr,4);

      break;
    }
  }

  //处理完成后,恢复保护类型:
  DWORD dwProctect=NULL;
  ::VirtualProtect(_base.BaseAddress,_base.RegionSize,_base.Protect,&dwProctect);
  return NULL;
}
//----------------------------------------------------------------------------



  当然,我们可以修改IAT表来实现,但是我们大家都明白,IAT表很不确定,有的程序还没有IAT表,我们必须找个通用
的方法,那就是直接把User32.dll的导出表修改掉,因此,我们让程序正常调用RegisterClassA这个之后,千万没想到的是,现
在的导处API函数的地址已经被修改,而在中途转到我们的DLL中,然后再回到真正的函数地址入口:

//-----------------------------------------------------------------------------

ATOM WINAPI fpnRegisterClassA(WNDCLASS *lpWndClass)
{
  //替换"XX"窗口的回调函数:
  if(lstrcmp(lpWndClass->lpszClassName,"XX")==0) //如果是我们要替换的窗口,就替换,不是就不替换
  {
    fpsWndProc=lpWndClass->lpfnWndProc;
    lpWndClass->lpfnWndProc=fpnWndProc;
  }
  ATOM  atom=fpsRegisterClassA(lpWndClass);
  return atom;
}

LRESULT CALLBACK fpnWndProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
{
  switch(message)
  {
  case WM_INITDIALOG:
    {
      //保存窗口句柄:
      theApp.game.hWnd=hDlg;
      //修改标题,方便我们调用:
      ::SetWindowText(hDlg,_T("[PhantomNet] XX"));  //我们把标题修改掉,方便通信,可以不修改的。
      break;
    }
  case WM_CMD:   //自定义命令:
    {
      if((DWORD)wParam==0x01){PostQuitMessage(0);} //收到命令,我们直接用API让程序结束。
      if((DWORD)wParam==0x02){}   //……什么操作都可以
      break;
    }
  default:{break;}
  }
  //转到游戏的回调函数:
  return fpsWndProc(hDlg,message,wParam,lParam);
}


//----------------------------------------------------------------------------------------


上面的代码就是实现修改RegisterClassA注册类,来转到我们的回调函数的。我们的回调函数,是在真正的回调函数
之前就被执行的,我们可以截获部分消息,让真正的回调函数收不到,因为,我们事先已经替它处理了事件。这样就避免了部
分消息收不到,但是这样的方法,是在程序没有启动,而随程序启动而加载……,我们就没办法对现有的进程进行操作。


  二、直接替换回调函数:
  怎么能直接替换呢?很多朋友都会想改这个改那个,实际KS给我们4个函数来让我们做这个工作。但是局限在同一进程,
//----------------------------------------------
GetClassLong(HWND hWnd,int Index);
GetWindowLong(HWND hWnd,int Index);
SetClassLong(HWND hWnd,int nIndex,LONG dwNewLong);
SetWindowLong(HWND hWnd,int nIndex,LONG dwNewLong);
//----------------------------------------------
  有必要对这两类函数做说明,GetClassLong和SetClassLong在RegisterClassA这个函数运行时才起作用,而GetWindowLong
和SetWindowLong在CreateWindowA后才有作用。我们完全可以不用CreateRemoteThread这个来触发,我们的程序。我们在替换回调
函数时可以在其他进程对目标进程处理,我们只需要把程序写入到目标进程,我们没必要专门去创建一条线程来加载DLL,我们直接
把它写进去后,再让某个消息来触发加载。那样就会隐蔽点,这里简要说一下,为了安全期间不贴代码了。

//--------------------------------------------------

int CMgMuAssistantApp::LoadMain()
{
  //初始化SOCKET:
  if (!AfxSocketInit())
  {
    AfxMessageBox("Error InitSocket!");
  }
  //查找窗口是否存在:
  pWnd=CWnd::FindWindow(NULL,"XX");
  if(pWnd!=NULL)
  {
    //由于窗口有可能在创建前被找到,所以我们完善期间不用GetWindowLong,
    //保存原始窗口回调函数:
    fpsWndProc=(WNDPROC)::GetClassLong(pWnd->m_hWnd,GCL_WNDPROC);

    //由于SetClassLong只在注册类时起作用,我们必须用SetWindowLong;
    //修改回调函数:
    ::SetWindowLong(pWnd->m_hWnd,GWL_WNDPROC,(LONG)fpnWndProc);  

    //修改Socket函数:
    hooksocket.InitHookApi(::GetModuleHandle(NULL),0x00376000,0x0568);

    //装载OpenGL:
    PDWORD pdwAddr=(PDWORD)((DWORD)::GetModuleHandle(NULL)+0x00375A00);
    *pdwAddr=(DWORD)fpnRender;
    pdwAddr  =(PDWORD)((DWORD)::GetModuleHandle(NULL)+0x002B5E69);
    *pdwAddr=(DWORD)((DWORD)::GetModuleHandle(NULL)+0x00375A00);
  }

  return 0;
}

//---------------------------------------------------
  上面的代码是我针对某个游戏做的,由于游戏是基于OpenGL的,所以我就把OpenGL的Render修改下来,来处理我的代码
比如,我们要用到程序内部函数:

//-----------------------------------------------------------
//原程序是如下的调用方法:
00664B75  |.  50            push    eax
00664B76  |.  8D55 8C       lea     edx, dword ptr [ebp-74]
00664B79  |.  52            push    edx
00664B7A  |.  A1 181E9E07   mov     eax, dword ptr [79E1E18]
00664B7F  |.  83C0 14       add     eax, 14
00664B82  |.  50            push    eax
00664B83  |.  8B0D 141E9E07 mov     ecx, dword ptr [79E1E14]
00664B89  |.  83C1 23       add     ecx, 23
00664B8C  |.  51            push    ecx
00664B8D  |.  E8 8E7CF2FF   call    0058C820

//我把它做成C函数调用,这样我们就可以直接用这个函数来调用程序内部函数了:
int CMgMuAssistantApp::SetMainText(int x,int y,LPSTR str,int unk1,int unk2,int unk3)
{
  ShowText=(MAINTEXT)0x0058C820;
  ShowText(x,y,str,unk1,unk2,unk3);
  return 0;
}

//---------------------------------------------------------------------


下面是我的回调函数,我们发现我们再发送命令给目标程序时,目标程序就乖乖的按我们说的做,让它放那,它就放那,让
它返回什么,它就乖乖返回什么,我们可以设置更多的命令来对程序操作:
//--------------------------------------------------------------------
LRESULT CALLBACK fpnWndProc(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
{
  //保存窗口句柄:
  theApp.game.hWnd=hDlg;

  switch(message)
  {
  case WM_INITDIALOG:{break;}
  case WM_PAINT:{break;}
  case WM_CMD:
    {
      if((DWORD)wParam==0x01){PostQuitMessage(0);}
      //返回的是主程序句柄:
      if((DWORD)wParam==0x02){
        //保存主程序句柄:
        theApp.m_hWndMainApp=(HWND)lParam;
        //返回游戏句柄:
        ::SendMessage(theApp.m_hWndMainApp,WM_CMD,0x02,(LPARAM)hDlg);
      }
      if((DWORD)wParam==0x08){
        //连接主程序,这里我创建了SOCKET来网络传输数据:
        theApp.m_uPortMainApp=(UINT)lParam;
        pClient=new CClient;
        pClient->Close();
        pClient->Create();
        if(lstrcmp(theApp.m_strAddrMainApp,"")==0)
        {
          //获取主机地址:
          char hostname[MAX_PATH]={0};
          ::gethostname(hostname,MAX_PATH);
          hostent *addr=::gethostbyname(hostname);
          theApp.m_strAddrMainApp=inet_ntoa(*(struct in_addr *)addr->h_addr_list[0]);
        }
        if(pClient->Connect(theApp.m_strAddrMainApp,theApp.m_uPortMainApp)==FALSE)
        {
          ::SendMessage(theApp.m_hWndMainApp,WM_CMD,0x08,(LPARAM)-1);
        }else{::SendMessage(theApp.m_hWndMainApp,WM_CMD,0x08,(LPARAM)1);}
      }
      if((DWORD)wParam==0x10){    
        //修改标题,方便我们调用:
        ::SetWindowText(hDlg,_T("[MG] MU"));
      }
      if((DWORD)wParam==0x11){
        CRect rect;
        //获取窗口矩形:
        ::GetWindowRect(hDlg,&rect);
        //移动窗口:
        ::MoveWindow(hDlg,LOWORD(lParam),HIWORD(lParam),rect.Width(),rect.Height(),TRUE);
      }
      return TRUE; //直接返回,不让游戏回调处理,这个是我们的命令机密不能让程序知道:
    }
  case WM_COPYDATA:  //我们替我们的目标程序处理进程间通信消息,为了方便点:)
    {
      //wParam:窗口句柄
      //lParam:数据
      theApp.OnCopyData(CWnd::FromHandle((HWND)wParam),(COPYDATASTRUCT*)lParam); return TRUE;
    }
  default:{break;}
  }
  //转到游戏的回调函数:
  return fpsWndProc(hDlg,message,wParam,lParam);
}

//-----------------------------------------------------------------------------------------------

  实际这回是在上回的基础而来的,我们总结一下就知道,当我们完全操作了回调函数时,一个应用程序就几乎成了你
手中的蛋糕,想怎么样吃就怎么样吃:).KS在进程的通信和相互性上没做多少,我们很多时候都要用CreateRemoteThread这个
函数来做DLL的加载,实际不用它的方法还是有很多的,只是没有被人发现而已,同过前面的说明,我想大家都会明白了,怎么
样把一个程序完全操控,但是回过头来一想,如果我们对一个进程做了完全操作,我们可以再用这个进程操作其它的进程,那么
会是烦琐点,但是是件很让人恐怖的事。前面的这个回调函数处理的事情很少,因为,我没把它做的有多强,我不想把它做多强
实际,当一个进程的回调函数交给你来处理,那么我们就可以做很多我们想做的事。当我们将DLL放入某个进程时,我们就可以
调用它的任意一个函数,来为我们工作,我们只需要做影射,把我们要调用的函数和地址影射到我们的DLL中,然后再加工~~~~


:)^^^^

【WRF工具】WRF Domain Wizard第一期:软件下载及安装 【WRF工具介绍】WRF Domain Wizard-确定模拟区域 阅读详情

相关推荐

01_MySQL下载、安装与配置(以MySQL8.0.31版本为例)

1.点击下载好的mysql安装包 进入到mysql installer界面。2.选择MySQL Servers选项 一直下拉。

4821

SetWindowLong和SetClassLongh函数关于索引GWL_WNDPROC,GCL_WNDPROC的区别

个人看法,如有雷同,纯属巧合!!!SetWindowLong:The SetWindowLong function changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window m

coolmousewife的专栏 5814

全栈开发指南:从前端到后端的全面掌握

全栈开发人员(Full Stack Developer)是指能够处理前端和后端开发工作的开发人员。他们需要掌握各种技术和工具,能够独立完成从需求分析、设计、开发到部署的整个流程。这篇博客将详细介绍全栈开发涉及的各个方面,为您提供从入门到进阶的指导。

Where there is a will, there is a way ! 3454

Win32 API 列表5 (格式有点乱)

西安邮电学院 徐兆元1201 SetBoundsRect 控制相邻矩形重叠  Yes Yes Yes1202 SetBrushOrgEx 设置当前刷子的起点  No Yes Yes1203 SetCapture 设置鼠标捕获 "    函数功能:该函数在属于当前线程的指定窗口里设置鼠标捕获。一旦窗口捕获了鼠标,所有鼠标输入都针对该窗口,无论光标是否在窗口的边界内。同一时刻只能有一个窗口捕获鼠标

FLxyzsby的专栏 1万+

告别复杂配置:利用原生DDNS实现IPv6直连群晖的极简指南

本文详细介绍了如何利用原生DDNS实现IPv6直连群晖NAS的极简方法,告别复杂配置。从检查IPv6网络环境、路由器防火墙设置到群晖DDNS配置,一步步指导用户完成设置,并分享移动网络下的使用体验和安全防护建议,帮助用户轻松实现远程访问。

weixin_30918633的博客 414

ISO15118-20协议测试实战:用Efficient XML库验证26条命令编解码(附完整代码)

本文分享了ISO15118-20协议测试实战经验,重点探讨了使用Efficient XML库对26条命令进行EXI编解码验证的过程。通过搭建测试环境、编写自动化程序并与官方工具链进行交叉比对,文章深入分析了4条命令编码结果不一致的原因,并提供了完整的排查思路与C代码示例,旨在帮助开发者确保电动汽车充电通信的协议一致性。

weixin_29284657的博客 110

SetClassLong

SetClassLong   函数功能:该函数替换在额外类存储空间的指定偏移地址的32位长整型值,或替换指定窗口所属类的WNDCLASSEX结构。  函数原型:DWORD SetClassLong(HWND hWnd,int nlndex,LONG dwNewLong);  参数:  hWnd:窗口句柄及间接给出的窗口所属的类。  nlndex:指定

laurensky的专栏 1411

【Python爬虫】爬取企业专利信息

本来是个美好的周末的,但是周五晚上领导给了一个公司名称的Excel,让把这些公司的专利信息爬取下来。本文记录了爬取企业专利信息的心酸过程。码字不易,喜欢请点赞!!! 一、找寻目标网页 在接到这个任务之后,我的内心是拒绝的。但是又不能不干。因此首先我需要先找到有公司专利信息的地方。在一番查找和问了问朋友之后,我知道中国专利网、国家知识产权网、Incopat、天眼查、企查查这些网站上面都有企业的专利...

Asher117的博客 2万+

C++的回调函数

回调函数主要在“回”字,和正常的函数调用方式不太一样。正常的函数由开发者自己定义返回类型以及传入的参数,并且也是由开发者自己调用,而回调函数功能其实也是由开发者自己实现,但是返回类型以及入参则由注册回调的函数来决定(若是自己编写则可以自定义注册函数,由他人提供则只能根据接口实现),而且调用方也不是开发者,而是注册方决定。整个过程也就是一个“回”字,开发者将自己的函数指针交给对方,这是“去”,而对方则在适当的时候调用这个函数,也可以将一些开发者需要的数据传回来,这便是来回了。

QtCompany的博客 589

基于SAGE算法的宽带信道参数估计算法的MATLAB仿真

本文将介绍如何使用MATLAB进行SAGE算法的仿真,以便更好地理解和应用该算法。SAGE算法是一种基于最大期望(Expectation-Maximization)方法的迭代估计算法,用于估计未知的参数。在宽带信道参数估计中,SAGE算法通过迭代优化来估计信道的传输函数。总结起来,本文介绍了如何使用MATLAB进行基于SAGE算法的宽带信道参数提取算法的仿真。通过以上步骤,我们可以得到估计的信道响应,并与真实信道响应进行比较。此外,SAGE算法还可以与其他信道估计算法相结合,以提高估计的准确性和性能。

CodeRoarX的博客 1076

AI Agent的数据安全与隐私保护措施

AI Agent(人工智能代理)作为一种能够感知环境、做出决策并采取行动的智能实体,在现代社会的各个领域中得到了广泛的应用,如智能客服、自动驾驶、金融风险评估等。随着其应用的不断拓展,AI Agent处理和存储的数据量急剧增加,这些数据包含了大量的个人敏感信息和商业机密。因此,确保AI Agent的数据安全与隐私保护变得至关重要。本文的目的在于全面探讨AI Agent的数据安全与隐私保护措施,涵盖从数据的采集、存储、处理到传输的整个生命周期。

AGI×大数据,开启智能时代的认知跃迁;解码AGI,赋能数据驱动的智能革命。 2870

【转】 提升tomcat服务器性能的七条经验

在线上环境中我们是采用了tomcat作为Web服务器,它的处理性能直接关系到用户体验,在平时的工作和学习中,归纳出以下七种调优经验。 1. 服务器资源 服务器所能提供CPU、内存、硬盘的性能对处理能力有决定性影响。 (1) 对于高并发情况下会有大量的运算,那么CPU的速度会直接影响到处理速度。 (2) 内存在大量数据处理的...

167

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

(转)提升tomcat服务器性能的七条经验

在线上环境中我们是采用了tomcat作为Web服务器,它的处理性能直接关系到用户体验,在平时的工作和学习中,归纳出以下七种调优经验。 1. 服务器资源 服务器所能提供CPU、内存、硬盘的性能对处理能力有决定性影响。 (1) 对于高并发情况下会有大量的运算,那么CPU的速度会直接影响到处理速度。 (2) 内存在大量数据处理的情况下,将会有较大的内存容量需求,可以用-X...

大道至简 227

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

(转)提升tomcat服务器性能的七条经验

在线上环境中我们是采用了tomcat作为Web服务器,它的处理性能直接关系到用户体验,在平时的工作和学习中,归纳出以下七种调优经验。 1. 服务器资源 服务器所能提供CPU、内存、硬盘的性能对处理能力有决定性影响。 (1) 对于高并发情况下会有大量的运算,那么CPU的速度会直接影响到处理速度。 (2) 内存在大量数据处理的情况下,将会有较大的内存容量需求,可以用...

nully1的博客 161

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

提升tomcat服务器性能的七条经验

1. 服务器资源     服务器所能提供CPU、内存、硬盘的性能对处理能力有决定性影响。     (1) 对于高并发情况下会有大量的运算,那么CPU的速度会直接影响到处理速度。     (2) 内存在大量数据处理的情况下,将会有较大的内存容量需求,可以用-Xmx -Xms -XX:MaxPermSize等参数对内存不同功能块进行划分。我们之前就遇到过内存分配不足,导致虚拟机一直处于ful

jayxu无捷之径的博客 7431

提升tomcat服务器性能的七条经验(Get !)

我就这样傻傻的看着你 1.服务器资源 服务器所能提供CPU、内存、硬盘的性能对处理能力有决定性影响。 (1)对于高并发情况下会有大量的运算,那么CPU的速度会直接影响到处理速度。 (2)内存在大量数据处理的情况下,将会有较大的内存容量需求,可以用-Xmx-Xms-XX:MaxPermSize等参数对内存不同功能块进行划分。我们之前就遇到过内存分配不足,导致虚拟机一直处于ful...

爱吃早餐的程序员 169

提升tomcat服务器性能的经验

在线上环境中我们是采用了tomcat作为Web服务器,它的处理性能直接关系到用户体验,在平时的工作和学习中,归纳出以下七种调优经验。 1. 服务器资源 服务器所能提供CPU、内存、硬盘的性能对处理能力有决定性影响。 (1) 对于高并发情况下会有大量的运算,那么CPU的速度会直接影响到处理...

chiqulao5770的博客 91

提升Tomcat服务器性能的七条经验

在线上环境中我们是采用了tomcat作为Web服务器,它的处理性能直接关系到用户体验,在平时的工作和学习中,归纳出以下七种调优经验。 1. 服务器资源     服务器所能提供CPU、内存、硬盘的性能对处理能力有决定性影响。     (1) 对于高并发情况下会有大量的运算,那么CPU的速度会直接影响到处理速度。     (2) 内存在大量数据处理的情况下,将会有较大的内存容量需求,可以用-X

EngQio的专栏 545
上一篇: inline hook和IDT hook结合
下一篇: NT内核下的inline hook
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值