当前位置: 首页 > news >正文

使用API Monitor工具巧妙探测C++程序中监听某端口的模块

目录

1、问题说明

2、API Monitor工具介绍

2.1、API Monitor主要用途

2.2、如何使用API Monitor工具

3、使用API Monitor监测程序对bind函数的调用,定位启用2620端口的模块

3.1、为啥要监控socket API函数bind

3.2、编写演示代码进行说明

3.3、使用API Monitor进行监测 

4、使用API Monitor工具的注意事项

4.1、如何在Call Stack窗口中查看到更多的函数调用?

4.2、如果Start Monitoring失败怎么办?

5、最后


VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html       当我们没法确定软件中的某个端口是哪个模块启用时,可以使用API Monitor工具去监测软件中对相关socket函数的调用去搞清楚。本文将详细讲述如何使用API Monitor工具去监测对端口的启用情况。

1、问题说明

       最近在对我们的C++软件做安全测试,使用专用工具对软件使用的端口号进行扫描,发现有模块启用了2620端口,安全测试组的同事需要明确搞清楚这个端口是用来做什么的,但询问了多个开发组,都没人认领这个端口。

       后来想到可以尝试用API Monitor工具监测一下软件对socket API函数bind的调用(因为要开启监听端口,一般先要调用bind函数去绑定端口),如果能监测到记录,查看对应的函数调用堆栈就能确定是哪个模块启用了这个端口。

2、API Monitor工具介绍

2.1、API Monitor主要用途

        API Monitor可以用来监测程序对Windows系统API函数的调用,也可以监测对第三方dll库接口的调用。监测到函数调用时,可以查看到给函数传递的参数值,还可以查看当前函数调用所在线程的函数调用堆栈。

       使用该工具去窥探一些主流软件对系统API函数的调用情况,可以看到调用函数时传入的参数值,这样就能模仿一些主流软件去实现一些类似的功能。我们在项目中多次使用过这个方法,比如我们在处理安装包中创建桌面快捷方式时遇到的若干问题时就用过。

2.2、如何使用API Monitor工具

        API Monitor工具的主界面如下所示:

一般我们在使用该工具监控程序对API函数的调用时,首先在左边的函数列表中搜索到要监控的系统API函数,然后勾选上该函数。

       接着,在左下角的进程列表中找到要监测的目标进程,右键点击,在弹出的右键菜单中点击“Start Monitoring”开始监控该进程。如果目标程序在运行的过程中调用了被监控的函数,右上方的列表中就会显示对应的记录。选中某条记录时,可以查看调用目标函数时传入的参数值,还可以看到此时所在线程的函数调用堆栈。

       和Windbg类似的,开启对目标程序的监测有两种方式:

1)可以在左下方的进程列表中找到已经启动的目标进程,然后右键点击,在弹出的右键菜单中开启监控。
2)可以通过API Monitor去启动目标进程,点击主界面中的“Monitor New Process”,找到目标程序的路径,启动即可。这种方式适用于监测程序启动过程中的函数调用活动。

3、使用API Monitor监测程序对bind函数的调用,定位启用2620端口的模块

3.1、为啥要监控socket API函数bind

       一般负责网络通信的模块,无论是TCP还是UDP,底层最终调用的都是socket API函数。我们要监测哪个模块启用2620端口,一般监听端口时需要先调用bind函数绑定2620端口,所以我们监测对bind函数的调用即可。

       我们可以在MSDN上对bind函数说明页面中看到相关示例代码:

#ifndef UNICODE
#define UNICODE
#endif#define WIN32_LEAN_AND_MEAN#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")int main()
{// Declare some variablesWSADATA wsaData;int iResult = 0;            // used to return function results// the listening socket to be createdSOCKET ListenSocket = INVALID_SOCKET;// The socket address to be passed to bindsockaddr_in service;//----------------------// Initialize WinsockiResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (iResult != NO_ERROR) {printf("Error at WSAStartup()\n");return 1;}//----------------------// Create a SOCKET for listening for // incoming connection requestsListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (ListenSocket == INVALID_SOCKET) {printf("socket function failed with error: %u\n", WSAGetLastError());WSACleanup();return 1;}//----------------------// The sockaddr_in structure specifies the address family,// IP address, and port for the socket that is being bound.service.sin_family = AF_INET;service.sin_addr.s_addr = inet_addr("127.0.0.1");service.sin_port = htons(2620);//----------------------// Bind the socket.iResult = bind(ListenSocket, (SOCKADDR *) &service, sizeof (service));if (iResult == SOCKET_ERROR) {printf("bind failed with error %u\n", WSAGetLastError());closesocket(ListenSocket);WSACleanup();return 1;}elsewprintf("bind returned success\n");WSACleanup();return 0;
}

从上面代码可以看出,在调用bind函数时,传入的是sockaddr_in结构体对象地址,然后强转成SOCKADDR*。

对于Windows C++程序员,在使用系统API函数遇到问题时,要会到MSDN上查看函数声明、参数含义以及函数的remarks说明,这是基本的要求!

3.2、编写演示代码进行说明

       此处不便展示项目中的相关模块和接口,也为了方便日后的视频课程的讲解,我特意写了一些测试代码,来讲述整个问题的监测过程。

       我在测试程序启动时调用bind函数绑定2620端口号,相关代码如下所示:

    // Declare some variablesWSADATA wsaData;int iResult = 0;            // used to return function results// the listening socket to be createdSOCKET ListenSocket = INVALID_SOCKET;// The socket address to be passed to bindsockaddr_in service;//----------------------// Initialize WinsockiResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (iResult != NO_ERROR) {printf("Error at WSAStartup()\n");return 1;}//----------------------// Create a SOCKET for listening for // incoming connection requestsListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (ListenSocket == INVALID_SOCKET) {printf("socket function failed with error: %u\n", WSAGetLastError());WSACleanup();return 1;}//----------------------// The sockaddr_in structure specifies the address family,// IP address, and port for the socket that is being bound.service.sin_family = AF_INET;service.sin_addr.s_addr = inet_addr("127.0.0.1");service.sin_port = htons(2620);//----------------------// Bind the socket.iResult = bind(ListenSocket, (SOCKADDR *) &service, sizeof (service));

3.3、使用API Monitor进行监测 

       因为是在程序启动过程中绑定端口的,所以需要使用API Monitor工具启动目标程序,要从程序启动时就开始监控。

首先,在左边的函数列表中搜索到bind函数,因为可能很多函数名称中都包含bind子串,所以搜索时为了快速搜到目标函数,可以勾上“全字匹配”和“大小写匹配”。

        然后,点击“Monitor New Process”,找到目标程序的路径,启动程序并开始监测。程序在运行过程中调用了bind函数,就会显示出对应的记录(如果有多次调用,会有多个记录与之对应),如下所示:

在我们的项目软件中,实际上监测到了多条记录,我们如何确定哪条记录操作的端口号是2620呢?

       这时我们就需要查看调用bind函数时传入的参数了!选中某条记录时,Parameters窗口中就会显示调用该函数时传入的参数值,并且Call Stack窗口中会显示所在线程的函数调用堆栈。

       这个地方注意一下,Parameters窗口中显示的是SOCKADDR*指针,但我们在调用bind函数时传入的是sockaddr_in结构体对象数据,其中端口是设置到该结构体的sin_port字段中的,那么sin_port结构体和SOCKADDR结构体有什么的对应关系呢?我们可以在Visual Studio中go到这两个结构体的定义处,如下所示:

//
// Structure used to store most addresses.
//
typedef struct sockaddr {#if (_WIN32_WINNT < 0x0600)u_short sa_family;
#else ADDRESS_FAMILY sa_family;           // Address family.
#endif //(_WIN32_WINNT < 0x0600)CHAR sa_data[14];                   // Up to 14 bytes of direct address.
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
//
// IPv4 Socket address, Internet style
//typedef struct sockaddr_in {#if(_WIN32_WINNT < 0x0600)short   sin_family;    
#else //(_WIN32_WINNT < 0x0600)ADDRESS_FAMILY sin_family;
#endif //(_WIN32_WINNT < 0x0600)USHORT sin_port;IN_ADDR sin_addr;CHAR sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN;

这两个结构体的第一个字段都是sin_family,sockaddr_in结构体的第二个字段就是存放端口号的sin_port字段,所以在调用bind函数将sockaddr_in结构体对象地址强转成SOCKADDR对象地址,那么端口号实际上是对应到SOCKADDR结构体中的sa_data数组内存,端口号占两个字节,所以端口号值是存放在sa_data[0]和sa_data[1]内存中,所以我们在Parameters窗口中查看sa_data[0]和sa_data[1]内存中的值,看能否和2620端口号对应起来。

       我们可以使用Windows系统自带的计算器工具将十进制的2620转成16进制数据:

所以两个字节存放的数据为0x0A和0x3C,转换成10进制就是10和60,这样拿这两个值到Parameters窗口中比对,就能确定对应的条目了。

       确定对应的条目后,到Call Stack窗口中查看函数调用堆栈,就可以确定是哪个模块启动了2620端口了。

4、使用API Monitor工具的注意事项

4.1、如何在Call Stack窗口中查看到更多的函数调用?

        注意,API Monitor的函数调用堆栈窗口中默认只显示5行最近的函数调用,如果要显示更多的函数调用,需要到设置中去设置一下。具体的入口是,点击菜单栏中的Tools -> Options,在打开的设置窗口中,点击Monitoring按钮,显示对应的子页面,在页面中可以修改函数调用堆栈中显示的条目数目:

      此处注意一下,API Monitor工具不支持加载pdb文件,不像Process Explorer和Process Monitor那样支持加载pdb文件! 

4.2、如果Start Monitoring失败怎么办?

       如果在左下角的进程列表中右键点击目标进程,在弹出的右键菜单中点击“Start Monitoring”开始监控,结果报错,提示开启监控失败。可能是目标进程是以管理员权限运行的,而当前的API Monitor没有管理员权限运行,而是以标准用户权限运行的。因为目标进程的运行权限(管理员权限)与API Monitor(标准用户权限)不对等,所以在低权限的API Monitor中不能操作高权限的目标进程。

       解决办法是,关闭当前的API Monitor程序,然后右键以管理员权限重新启动API Monitor,即可开启对目标进程的监控了。

5、最后

       本例通过API Monitor去监控程序对bind函数的调用,去巧妙定位启用2620端口的模块。文中详细讲解了API Monitor定位问题的完整过程,希望能给大家提供一个借鉴或参考。

相关文章:

使用API Monitor工具巧妙探测C++程序中监听某端口的模块

目录 1、问题说明 2、API Monitor工具介绍 2.1、API Monitor主要用途 2.2、如何使用API Monitor工具 3、使用API Monitor监测程序对bind函数的调用&#xff0c;定位启用2620端口的模块 3.1、为啥要监控socket API函数bind 3.2、编写演示代码进行说明 3.3、使用API Moni…...

vue-grid-layout移动卡片到页面底部时页面滚动条跟随滚动

问题描述&#xff1a;默认情况下 vue-grid-layout 移动卡片到页面底部时页面滚动条并不会跟随卡片滚动。 问题解决&#xff1a; 在 grid-item中的move事件中&#xff0c;获取到当前移动的元素&#xff0c;并使用scrollIntoView方法来实现滚动条跟随。 代码如下&#xff1a; c…...

git查看自己所在的分支

很多时候可能大家不太想切换其他工具&#xff0c;又不知道自己是否在自己需要操作的分支 可以直接终端执行 git branch此时 他就会在终端将所有的本地分支输出出来 并特殊标注自己所在的分支 这样我们就可以进一步去做自己想要做的操作了 当然 随着各种编辑器的发展 这个命令…...

竞赛 基于视觉的身份证识别系统

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器视觉的身份证识别系统 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-sen…...

Redis的softMinEvictableIdleTimeMillis和minEvictableIdleTimeMillis参数

背景&#xff1a; Redis的softMinEvictableIdleTimeMillis&#xff0c;minEvictableIdleTimeMillis是一个令人疑惑两个参数&#xff0c;特别是当它和minIdle组合起来时就更难理解了&#xff0c;本文就来梳理下他们的之间的关系 softMinEvictableIdleTimeMillis&#xff0c;mi…...

向量数据库库Milvus Cloud2.3 的QA问题

1. Milvus 从 2.2.x 升级至 2.3.x 的最大变化是什么? 如果用一句话来总结,那就是使用的场景更加丰富了。具体可以从两个方面来体现,即部署环境和用户的使用感。 例如,从部署环境来看,Milvus 原来只支持 X86 架构的 CPU,版本升级后,不仅可以支持 GPU,还能够支持 ARM 架构…...

嵌入式 - 经典的有刷电机和先进的无刷电机

自从无刷直流电机诞生&#xff0c;“古老的”有刷电机就开始没落&#xff0c;但它依然是低成本应用的可靠选择&#xff0c;并且实现起来简单。 在有刷电机中&#xff0c;磁极方向的跳转是通过移动固定位置的接触点来完成的&#xff0c;该接触点在电机转子上与电触点相对连接。这…...

【力扣2154】将找到的值乘以 2

&#x1f451;专栏内容&#xff1a;力扣刷题⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录 一、题目描述二、题目分析 一、题目描述 题目链接&#xff1a;将找到的值乘以 2 给你一个整数数组 nums &#xff0c;另给…...

C++ —— 单机软件加入Licence许可权限流程(附详细流程图、详细代码已持续更新..)

单机版许可证简介 笼统的说:实现一个生成授权Lic文件应用程序(我们使用),生成的Lic文件给应用程序(客户使用)启动时读取一下对比加密后的字符串或自定义格式的密钥判断是否正确。 单机版许可证执行流程 第一级比对:发布的加密许可证文件,该加密许可证文件仅可用使用的软…...

Windows 下 MySQL 8.1.0 安装及配置图文指南,快速搭建实验学习环境

目录 下载 MySQL安装 MySQL配置 MySQL修改密码配置环境变量 卸载 MySQL开源项目微服务商城项目前后端分离项目 下载 MySQL 访问 MySQL 下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 下载 MySQL 时&#xff0c;你可以选择 ZIP 包或 MSI 安装&#xff1a; ZIP包…...

Linux内核顶层Makefile的make过程总结

一. Linux内核源码的make编译 本文对 Linux内核源码的 make时&#xff0c; 顶层Makefile所做的事进行总结。即总结一下 Linux内核源码的 make 过程。 本文续上一篇文章&#xff0c;地址如下&#xff1a; Linux内核顶层Makefile的make过程说明二_凌肖战的博客-CSDN博客 二.…...

C语言每日一题(9):跳水比赛猜名次

文章主题&#xff1a;跳水比赛猜名次&#x1f525;所属专栏&#xff1a;C语言每日一题&#x1f4d7;作者简介&#xff1a;每天不定时更新C语言的小白一枚&#xff0c;记录分享自己每天的所思所想&#x1f604;&#x1f3b6;个人主页&#xff1a;[₽]的个人主页&#x1f3c4;&am…...

L10 数据库

1&#xff0c; 数据库的安装 sudo dpkg -i *.deb 2, 数据库命令&#xff1a; 1&#xff09;系统命令 &#xff0c; 都以.开头 .exit .quit .table 查看表 .schema 查看表的结构 2&#xff09;sql语句&…...

前端面试:01.图中输入什么?

~~~~~~~~~~~~~ 先自行想一想&#xff0c;答案在~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~ 先自行想一想&#xff0c;答案在~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~ 先自行想一想&#xff0c;答案在~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~ 先自行想一想&#xff0c;答案在~~~~~~~~~~~~~~~~~ ~~~~~~~~…...

Oracle拉链表

目录 -- 准备一个拉链表 -- 2.将所有的数据 同步到拉链表中 TEST_TARGET中 --3. 源表的数据发生了变化 --4. 将新增和修改的数据同步到拉链表 -- 开链的过程 -- 判断源表和目标表的数据,不同数据插入 --5. 修改拉链表中失效的时间和状态(将原本的开链时间,改为当前时间)-- …...

Git 代理(Proxy) 配置

某些情况下,我们需要通过代理才能访问特定网络环境下的git资源,git支持代理配置, 支持 http(s), SOCKS4/SOCKS5. HTTP(S) HTTP 代理配置格式如下: git config --global http.proxy http://[proxy]:[port]实际环境下, 其实我们大多数情况下,并不需要全部git资源都需要通过代理…...

C++,对象赋值与对象拷贝的区别、深浅拷贝

在C中&#xff0c;对象赋值和对象拷贝是两个不同的操作&#xff0c;它们有明显的区别&#xff1a; 1. 对象赋值&#xff08;Object Assignment&#xff09;&#xff1a; - 对象赋值是指将一个已经存在的对象的值复制给另一个已经存在的对象。这通常通过赋值操作符&#xff08;…...

MATLAB实现相关性分析

目录 一.基本理论 二.两类相关系数的对比 三.相关系数的假设检验 四.MATLAB的相关操作 五.其他有关的一些列技巧 六.案例展示 七.实战操作 一.基本理论 所谓相关系数&#xff0c;本质上是来衡量两组数据的关系大小——对应呈现函数关心的两种变量&#xff0c;那么我们可以…...

MySQL索引看这篇就够了

能简单说一下索引的分类吗&#xff1f; 例如从基本使用使用的角度来讲&#xff1a; 主键索引: InnoDB 主键是默认的索引&#xff0c;数据列不允许重复&#xff0c;不允许为 NULL&#xff0c;一个表只能有一个主键。唯一索引: 数据列不允许重复&#xff0c;允许为 NULL 值&…...

无法从 /var/lib/rpm 打开软件包数据库

使用yum命令安装软件包时&#xff0c;报错“无法从 /var/lib/rpm 打开软件包数据库” 小白教程&#xff0c;一看就会&#xff0c;一做就成。 1.原因 是误操作导致 rpm 数据库损坏。&#xff08;/var/lib/rpm 目录下的文件被损坏&#xff09; 2.解决 当RPM 数据库发生损坏&a…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...