内存查看器

来源:互联网 发布:java调用外部程序 编辑:程序博客网 时间:2024/05/30 07:14

最近新到一个公司上班,所做的项目与网络通信有关,网络通信,必然涉及到收发网络包,为了检查我封装的包的数据是否正确,为了便于与通信方进行比对,我需要获得最终收发包的二进制数据。

这个通常有以下实现方式:
1、网络抓包,典型的做法是,根据通信网络设备的组网,在交换机建立port-mirroring,把运行抓包工具(Wireshark)的电脑练到这个镜像 口,把通过某些端口的网络包全抓下来进行分析;
2、平台提供了一个抓包的命令(可直接执行,不需要配置交换机什么的),但是它会把包的有效数据截断,只保留前面几个字节,因此只能看到有没有包,不能看到包的数据对不对;
3、我在代码的收发包处,以日志的形式打印出包的二进制数据。

我选的是方案3,因为,对方案1,一开始我还不知道怎么在交换机配port-mirroring(现在知道了,可以专门写篇文章介绍一下);对方案2,我不知道这是bug还是有意为之。我搜索了代码,没看到有类似的,看来只能自己实现了。

其实这个的本质就是以16进制的形式打印一段内存,就跟我们在调试时的Memory窗口,或者二进制阅读器看到的一样:
这里写图片描述
很自然的解决方案就是C++的ostringstream,唯一要处理的就是这个模块原来全是C代码,就需要在C中调用C++的东西,需要添加一个.cpp源文件,需要简单修改makefile(C/C++混合编程的makefile)。

这里我简单介绍C调用C++的实现,和如何打印二级制内存。

// C++文件,Util.cpp#include <sstream>  #include <string>  #include <iostream>  #include <iomanip>using namespace std;extern "C"  void XXX_ReadMemory(unsigned char * pucBuf, unsigned long ulLen);void XXX_ReadMemory(unsigned char * pucBuf, unsigned long ulLen){    if(pucBuf==NULL || ulLen<=0)        return;    std::ostringstream oss;    for(unsigned long i=0; i<ulLen; ++i)    {        oss<< std::hex << std::setw(2) <<std::setfill('0') <<(unsigned char)(*(pucBuf+i)) << " ";           }    std::cout<<oss.str()<<endl;     }// C文件,XXX_dosth.cextern void XXX_ReadMemory(unsigned char * pucBuf, unsigned long ulLen);void Print_Memory(){    XXX_ReadMemory((unsigned char* )pPackage, packageLen);}

这里Util.cpp文件由g++编译,extern “C”告诉g++编译器按照C的规则生成符号名称,按照不同调用规则,符号名称会有不同,这里是_XXX_ReadMemory(Windows下通过VS自带的工具dumpbin可以查看,Linux通过nm可以查看).
XXX_dosth.c文件由gcc编译,自然是按照C的规则生成和解析符号名称,所以只需声明extern,链接的时候,就通过_XXX_ReadMemory这个符号名称完成链接。

另外一种实现方式,还是用C语言,思路就是把每一个Byte的数据以十六进制字符串的形式写入到输出内存中(对应2个或多个字符),这样实现也挺简单:

void XXX_ReadMemory(unsigned char * pucInBuf, unsigned long ulInLen, char * pOutBuf, unsigned long ulOutLen){    //better set the pOutBuf to 0    if(pucInBuf==NULL || ulInLen<=0 || pOutBuf==NULL || ulOutLen<=0)        return;    char *pout = pOutBuf;    int nlen = ulOutLen - 1;    for(unsigned long i=0; i<ulInLen && nlen>3 ; ++i)    {        _snprintf_s(pout, nlen, 3, "%02x ", *(pucInBuf+i));        pout += 3;        nlen -= 3;    }    *(pOutBuf+ulOutLen-1) = '\0';}
0 0
原创粉丝点击