c++注入dll调用call

news2024/11/15 19:58:51

1.先写个我们要调用的函数

#include<iostream>
using namespace std;
void test(int a, int& b)
{
cout << a << b << endl;
b = a + b;
}

void main()
{
int a = 2;
int b=0;
test(a, b);
cout << b << endl;
system("pause");
}

这个我们写了一个很简单的函数,一个main函数和test函数。我们后面要通过动态注入dll调用这个test函数。

我们先运行一下。看看结果

20
2
请按任意键继续. . .

输入这个,看了没有任何问题。

2.写一个简单的dll

 switch (ul_reason_for_call)
  {
   case DLL_PROCESS_ATTACH: {
       MessageBox(GetForegroundWindow(), L"测试", L"成功注入", 1);          
  }
     
   case DLL_THREAD_ATTACH:
   case DLL_THREAD_DETACH:
   case DLL_PROCESS_DETACH:
       break;
  }

我们在vs2019创建一个dll文件,在DLL_PROCESS_ATTACH下面加一行语句。

MessageBox(GetForegroundWindow(), L"测试", L"成功注入", 1);  

这个是用来测试我们后面注入dll弹出的窗口。

3.写注入程序

#include<windows.h>
#include"tchar.h"
#include<stdio.h>
int get_id(LPCTSTR name) {
HWND hWnd = FindWindow(NULL,name);
if (hWnd == NULL){//如果无法获取句柄则报错
printf("无法获取窗口句柄,请检查进程是否存在!\n");
system("pause");
return -1;
}

DWORD pro_id;
GetWindowThreadProcessId(hWnd, &pro_id);//获取进程ID  
if(pro_id == 0){
printf("无法获取进程ID\n");
system("pause");
return 0;
}
printf("进程id: %d\n",pro_id);
//打开进程对象,并获取进程句柄
/*ANDLE hpro = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pro_id);
if (hpro == 0){
printf("无法获取进程句柄");
}
printf("进程句柄id: %d\n",hpro); */
return (int)pro_id;
}
BOOL InjectDll(LPCTSTR szDllPath, LPCTSTR name)
{
DWORD dwPID = (DWORD)get_id(name);
HANDLE hProcess = NULL, hThread = NULL;
HMODULE hMod = NULL;
LPVOID pRemoteBuf = NULL;
DWORD dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
LPTHREAD_START_ROUTINE pThreadProc;
//1.使用dwPID获取目标进程句柄
if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID))) {
_tprintf(L"OpenProcess(%d) failed!![%d]\n", dwPID, GetLastError());
return FALSE;
}
//2.在目标进程中分配szDllName大小的内存
pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize , MEM_COMMIT, PAGE_READWRITE);
//3.将myhack.dll路径写入分配的内存。
WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllPath, dwBufSize, NULL);
//4.获取LoadLibrary()API的地址
hMod = GetModuleHandle(L"kernel32.dll");
pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryW");
//5.在notepad中运行线程.
hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
//CloseHandle(hThread);
//CloseHandle(hProcess);

return TRUE;
}


int _tmain(int argc, TCHAR *argv[])
{
//injectdll
if (InjectDll(argv[1],argv[2]))
_tprintf(L"InjectDll(\"%s\") sucess!!!\n", argv[2]);
//MessageBox(NULL, TEXT("1"), TEXT("warn"), 0);
else
_tprintf(L"InjectDll(\"%s\") failed!!!\n", argv[2]);
//MessageBox(NULL, TEXT("2"), TEXT("warn"), 0);


}

这个程序的话,我是直接从网上拿的,拿过来改了一点,打包成exe,通过命令行进行调用。

4.测试注入

注入.exe 注入dll.dll test.exe

在命令行里面就这样进行调用。这个test.exe就是你程序的名字,你可以用vs2019的spy+=进行查看,就是你的程序标题

调用成功的话,会自动弹出这个。

5.完善dll程序

我们的目标是在dll调用到test.exe的test函数,这个dll还没有达到我们的目标,我们还需要继续完善。

我们想调用test函数,就必须知道这个函数在内存的地址,但是每次重启电脑,地址都是变化的。我们需要找到基址。这里我们改一下dll,让他输出程序的基址

switch (ul_reason_for_call)
  {
  case DLL_PROCESS_ATTACH: {
      MessageBox(GetForegroundWindow(), L"测试", L"成功注入", 1);          
        HMODULE hModule = GetModuleHandle(NULL);
          WCHAR wszhModule[MAX_PATH] = {0};
            swprintf_s(wszhModule, L"DLL里调用GetModuleHandle(NULL)获取到的地址为:0x%x", \
              (DWORD)hModule);
          MessageBoxW(0, wszhModule, L"提示", 0);
  }
     
  case DLL_THREAD_ATTACH:
  case DLL_THREAD_DETACH:
  case DLL_PROCESS_DETACH:
      break;
  }

我们重新生成,再次注入试试。

记住这个地址,后面我们需要这个地址。

我们打开x64dbg来进行调试。我们把生成的test.exe进行调试。这个自己写的代码找起来还是比较容易的

007919CF | C745 F4 02000000         | mov dword ptr ss:[ebp-C],2             |将2推入栈中
007919D6 | C745 E8 00000000         | mov dword ptr ss:[ebp-18],0             |将0推到栈中
007919DD | 8D45 E8                 | lea eax,dword ptr ss:[ebp-18]           |将0的地址放到eax里面
007919E0 | 50                       | push eax                               |将eax推入栈中
007919E1 | 8B4D F4                 | mov ecx,dword ptr ss:[ebp-C]           |将2给ecx
007919E4 | 51                       | push ecx                               |将ecx推入栈中
007919E5 | E8 F2F6FFFF             | call test.7910DC                       |这个就是test的call
007919EA | 83C4 08                 | add esp,8                               |还原堆栈

我们可以找到这个代码,我们找到call的地址7910dc。和之前的0x780000相减得到偏移0x110DC。有了这个偏移,我们后面就可以直接调用这个call了。

接下来,我们写一个函数

void zhu(DWORD baseaddr) {
  DWORD dwCallAddr = baseaddr + (DWORD)0x110DC;
  printf("%x\n", (int)dwCallAddr);
  int a = 2;
  int& r = a;
  __asm {
      push r
      push a
      call dwCallAddr
      add esp,8
  }
  printf("%d", r);
}

这个函数很简单,里面内嵌的汇编代码,用来调用test的call,首先我们申明一个a=2,和一个引用类型r。先push r,在push a。这个可以和上面拿到的汇编进行对比,这个是按照c语言的调用约定来的,这个push的顺序是不能变的哈,后面直接调用call。后面用add esp,8来还原堆栈。不然会报错。接下来就将zhu函数放到DLL_PROCESS_ATTACH下面进行调用

6.进行测试

将dll和注入exe,以及测试程序都放到同一个文件夹,dll和测试程序一定要同一个文件夹哦,然后打开cmd,输入命令。开始测试。不出意外的话,应该会弹出两个窗口,一个是注入成功窗口,一个是输出基址的窗口。接着输出结果也会变

20
2
请按任意键继续. . . 7910dc
22
4

会变成这样,可以看到我们顺利调用了这个test的test函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/508847.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

再鼎医药面临严重的监管和产品竞争风险

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 再鼎医药&#xff08;ZLAB&#xff09;是一家生物制药公司&#xff0c;致力于开发和商业化癌症和传染病的创新疗法。该公司的产品组合包括用于治疗卵巢癌的靶向药Zejula&#xff0c;用于治疗脑癌的Optune&#xff0c;用于治…

Eplan2022 复制已有的宏文件生成新的原理图宏文件

下图所示为wago的787-722稳压电源&#xff0c;我们可以从官网下载到相应的eplan宏文件并导入数据源库。但是能下载到eplan宏文件的只是少部分公司的部件。那么没有宏文件的部件该怎么办&#xff1f; 接下来以明纬开关电源 NDR-120-24为例&#xff0c;创建一个宏文件。选择【主数…

linux密码忘了?一招解决

目录 一、前言 二、进入编辑界面 三、单用户模式 四、修改密码 五、更新信息 六、退出 七、验证 一、前言 版本&#xff1a;centos7.9、VMware15.5 在我们学习linux运行级别的时候&#xff0c;面试题可能会出如何找回root密码&#xff0c;下面来详细的介绍一波&#xff…

Mysql索引+事务+存储引擎

索引 索引的概念 索引是一个排序的列表&#xff0c;在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址&#xff08;类似于C语言的链表通过指针指向数据记录的内存地址&#xff09;。 使用索引后可以不用扫描全表来定位某行的数据&#xff0c;而是先通过索引表找…

day29_jdbc

今日内容 零、 复习昨日 一、JDBC 二、登录 三、ORM 零、 复习昨日 DDL (针对结构,库,表,列,索引) 最重要建表语句 create table emp(empno int primary key auto_increment,ename varchar(10) not null,sal double(10,2) default 3000,hiredate date unique )DML 增删改 inser…

TIA博途中FC和FB的区别与应用

TIA博途中FC和FB的区别与应用 从程序运行过程的角度看,FC、FB的区别在于传递参数方式不同: FC:通过L堆栈区传递参数 FB:通过背景DB传递参数 FC与FB具有不同的特性:  FC自身不能存储过程状态  FB可以通过静态变量存储中间过程状态  FB可以包含调用其他的FB及其背景D…

【Go编程语言】流程控制

流程控制 文章目录 流程控制一、if 语句1.if 嵌套语句 二、switch 语句三、for 循环四、string 程序的流程控制结构一具有三种&#xff1a;顺序结构&#xff0c;选择结构&#xff0c;循环结构 顺序结构&#xff1a;从上到下&#xff0c;逐行执行。默认的逻辑 选择结构&#xf…

C4D云渲染平台哪家好?

Cinema 4d&#xff08;简称C4D&#xff09;作为CG业内一款人人皆知的三维制作软件&#xff0c;操作界面简单清爽是它的亮点之一。此外&#xff0c;具有建模、灯光、材质、绑定、动画、渲染等强大功能的C4D的应用范围也十分广泛&#xff0c;包括电商海报、时尚设计、影视后期、广…

Java系统环境变量配置

PATH环境变量 PATH环境变量用于保存一系列命令&#xff08;可执行程序&#xff09;的路径&#xff0c;每个路径之间以分号分隔。当在命令行窗口运行一个命令时&#xff0c;操作系统首先会在当前目录下查找是否存在该命令对应的可执行文件&#xff0c;如果未找到&#xff0c;操作…

最新一键将网站DEDECMS 迁移到 WordPress脚本

DEDECMS宣布开始对运营类网站收费了,一年5800元,如果不想付费,那就需要转到其他网站了,就是一个不错的选择。 最近大神wordpress果酱牛逼闪闪的Denis和几个程序员制作了一个转Wordpress的,有需要的可以去下载使用,完全免费! 经过几个夜晚通宵的努力,我们终于搞定了一键…

开发必备,开源 or 免费的 AI 编程助手

AI 大模型的火热&#xff0c;让开发圈近来如虎添翼&#xff0c;各种各样基于 AI 技术的开发者工具和新范式不断涌现&#xff0c;尤其是 Github 和 OpenAI 共同推出的 Copilot X &#xff0c;更是一骑绝尘。本文推荐一些开源 or 免费的 AI 编程工具&#xff0c;不妨试着用起来。…

基于stm32物联网开发板(1)

基于stm32物联网开发板(1) 本开发板采用了STM32F103RET6作为核心CPU&#xff0c;72MHZ工作频率&#xff0c;512KB flash&#xff0c;64KB Sram。本开发平台外设模块有ESP8266 WIFI模块、1.3寸LCD彩屏、SYN6288语音模块、MAX30102心率血氧传感器、AD8232心电图监测模块、BH1750环…

mysql的高级查询语句

1.本文前言 数据库是用来存储数据&#xff0c;更新&#xff0c;查询数据的工具&#xff0c;而查询数据是一个数据库最为核心的功能&#xff0c;数据库是用来承载信息&#xff0c;而信息是用来分析和查看的。所以掌握更为精细化的查询方式是很有必要的。本文将围绕数据的高级查…

Figma中文网?比Figma更懂你的设计网站!

一个比 Figma 更懂你的设计网站的 Figma 中文网 —— 即时设计是一个非常有用的设计资源平台&#xff0c;它提供了大量的免费设计素材&#xff0c;包括来自各大厂商的 UI 组件库、精美的模板、插画设计和矢量图标素材等等。设计师可以从中学习到大师的设计技巧和规范&#xff0…

Ubuntu18.04 下安装 MATLAB 2021a

1、MATLAB 软件获取 南开大学软件之家&#xff1a;http://ca.nankai.edu.cn&#xff0c;非南开大学校园IP无法登陆该平台。 点击浏览更多&#xff0c;找到 R2021a_Linux&#xff0c;开始下载&#xff0c;下载 R2021a_Linux.iso 镜像文件。 参考该网页下的个人版在线安装指南&a…

基于git的开发规范总结

文章目录 各分支命名规范gitee基本开发流程及定义gitflow工作流gitflow工作流常用分支主要工作流程命名规则gitflow工作流程图 Git分支开发管理策略主分支Master开发分支DevelopGit创建Develop分支的命令&#xff1a;将Develop分支发布到Master分支的命令&#xff1a; 临时性分…

【windows编程之对话框】对话框原理,对话框的创建

文章目录 引言一.对话框原理1.对话框的分类2.对话框的基本使用2.自定义对话框窗口消息处理函数 二.模式对话框- 1.创建对话框- 2.对话框的关闭- 3.对话框消息 三.模式对话框创建过程实践四.无模式对话框 引言 在本章节中我们来讲解Windows/Win32编程中对话框的原理和对话框的创…

Ajax请求,基于JSON的数据交换 实例

前端代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>发送Ajax GET请求 展示学生信息列表</title> <script type"text/javascript"> w…

camunda任务监听器如何使用

在Camunda工作流引擎中&#xff0c;任务监听器是一种机制&#xff0c;用于在业务任务执行期间捕获特定事件并执行相应的操作。它们可以帮助您实现一些重要的任务&#xff0c;例如&#xff1a; 1、记录或更新业务数据&#xff1a;当任务完成或取消时&#xff0c;您可以使用任务…

本地搭建wamp服务器并内网穿透实现无公网IP远程访问

文章目录 前言1.Wamp服务器搭建1.1 Wamp下载和安装1.2 Wamp网页测试 2. Cpolar内网穿透的安装和注册2.1 本地网页发布2.2 Cpolar云端设置2.3 Cpolar本地设置 3. 公网访问测试4. 结语 转载自cpolar极点云的文章&#xff1a;无公网IP&#xff1f;教你在外远程访问本地Wamp服务器「…