简体   繁体   English

C:将收到的Winsock数据包保存为十六进制文件

[英]C: save received Winsock packet to file as hex

I need to do what most packet monitoring programs do (Wireshark, tcpdump, etc.). 我需要执行大多数数据包监视程序(Wireshark,tcpdump等)的操作。 When data is received through Winsock, I just need to convert the packet to a hex representation and save it to file. 通过Winsock接收数据时,我只需要将数据包转换为十六进制表示形式并将其保存到文件中即可。

The data is just a simple char array. 数据只是一个简单的char数组。

I've tried lots of things like sprintf but with no luck. 我尝试了很多类似sprintf的方法,但是没有运气。 I also don't want to use itoa since it's not standard C from what I've learned. 我也不想使用itoa,因为它不是我所学的标准C语言。

Example: 例:

If the packet contains "test", then it should be dumped to file as "74 65 73 74". 如果数据包包含“测试”,则应将其转储为文件“ 74 65 73 74”。

I can do all of the file handling stuff, and the Winsock code is working, I guess I just need to write a function to convert a char array to a hex representation, and I can't seem to get it. 我可以完成所有文件处理工作,并且Winsock代码可以正常工作,我想我只需要编写一个函数就可以将char数组转换为十六进制表示形式,但似乎无法实现。

Perhaps you should show what you have tried since printf() and its variants is by far the simplest solution. 也许您应该展示出printf()及其变体是迄今为止最简单的解决方案。

int emit_hex( FILE* file, const char* data, size_t len )
{
    int length = 0 ;
    size_t i ;

    for( i = 0; i < len; i++ )
    {
        length += fprintf( file, "%2.2X", (unsigned)pkt[i] ) ;
        if( i < len - 1)
        {
            length += fprintf( " " ) ;
        }
    }

    return length ;
}

slightly more advanced function: 稍微高级一些的功能:


#include <stdio.h>
#include <string.h>
#include <error.h>

void dump(FILE* pFile, const char* szData, unsigned long ulSize)
{
  const char* pBuff = szData;
  unsigned long i = 0;
  unsigned long j = 0;

  for(i = 0; i < ulSize; i += 0x10)
  {
    if((i % 0x10) == 0)
      fprintf(pFile, "\n0x%8p   ", (i + szData));

    for(j = 0; ((i + j) < ulSize) && (j < 0x10); j++)
      fprintf(pFile, "%.2x ", (unsigned char)pBuff[i+j]);

    for(; j < 0x10; j++)
      fprintf(pFile, "   ");

    fprintf(pFile, "  ");

    for(j = 0; ((i + j) < ulSize) && (j < 0x10); j++)
      fprintf(pFile, "%c", (unsigned char)pBuff[i+j] > ' ' ? pBuff[i+j] : '.');
  }
  fprintf(pFile, "\n\n");
  fflush(pFile);
}


int main()
{
  FILE* pFile = fopen("dump.txt", "wt+");
  if (!pFile)
  {
    perror("error while opening file");
    return 1;
  }

  const char* szData = "1234567890qwertyuiop"; // received data
  unsigned long ulSize = (unsigned long)strlen(szData); // data length just for example

  dump(pFile, szData, ulSize);
  fclose(pFile);
}

output format (pointer, hex, char): 输出格式(指针,十六进制,字符):


0x0x400a9c   31 32 33 34 35 36 37 38 39 30 71 77 65 72 74 79   1234567890qwerty
0x0x400aac   75 69 6f 70                                       uiop

sprintf uses the %x conversion for hex, so you'd typically use something like this: sprintf%x转换用于十六进制,因此您通常会使用以下内容:

cvt2hex(unsigned len, char const *input, char *output) { 
    int i;
    for (i=0; i<len; i++)
        sprintf(output+i*3, "%2.2x ", input[i]);
}

Of course, output needs to point to enough memory to hold the converted data. 当然, output需要指向足够的内存来保存转换后的数据。 You'll typically want to insert a new-line after every 16 or 32 bytes, or somewhere in that vicinity. 通常,您通常希望在每16或32个字节之后或附近的某个位置插入换行符。

另一种方法是对char(hh)使用长度修饰符:

printf("%hhx", c);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM