当前位置: 首页 > 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…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...