【问题标题】:Convert string in '\\x00\\x00\\x00' format to unsigned char array将 '\\x00\\x00\\x00' 格式的字符串转换为无符号字符数组
【发布时间】:2019-12-18 21:25:36
【问题描述】:

假设我有一个字符串:

std::string sc = "\\xfc\\xe8\\x82";

如何将 sc 字符串转换为等价的

 unsigned char buf[] = "\xfc\xe8\x82";

我正在尝试将包含 shellcode 的字符串转换为无符号字符数组。

我尝试了以下方法:

char buf[5120];
strncpy(buf, sc.c_str(), sizeof(buf));
buf[sizeof(buf) - 1] = 0;

这似乎将字符串存储到 char 数组中,我需要 char 数组来存储/表示字节。

当我打印时:

//example 1
unsigned char buf[] = "\xfc\xe8\x82";
printf("%s", buf);

控制台输出:

ⁿΦé

当我打印时:

//example 2
char buf[5120];
strncpy(buf, sc.c_str(), sizeof(buf));
buf[sizeof(buf) - 1] = 0;

控制台输出:

\xfc\xe8\x82

如何将 sc 字符串转换为无符号字符数组,以便在打印 sc 时产生与示例 1 相同的输出。

【问题讨论】:

  • 你为什么首先使用字符串?字符向量(或普通数组)就可以了。
  • 您能举个例子吗?我是 C++ 新手。
  • 为什么要数组?该字符串已经在后台使用了一个数组。如果您想要一个指向底层数组的指针,请使用.c_str()(只读)或.data()(读/写)。
  • @asrdelinx:您的第二个示例是完全有效的 C++。 (虽然unit8_tstd::byte 会比无符号字符“更好”)
  • 我将添加我试图提供更多上下文的内容。

标签: c++ string byte shellcode


【解决方案1】:

作为字符串的文字"\\xfc\\xe8\\x82" 使用“\”作为转义字符。 “\\”将减少为“\”。如你所料。因此,如果您打印给定的std::string,那么结果将是: \xfc\xe8\x82.

所以,您现在要做的是:创建一个包含这些十六进制值的 char 数组,在原始 std::string 中给出。

请注意:您的声明 char s[] = "\xfc\xe8\x82"; 将创建一个 C 样式的 char 数组,大小为 4 并包含:

s[0]=fc, s[1]=e8, s[2]=82, s[3]=0

在下面的示例中,我展示了 2 个转换建议。 1. 直接转换 2.使用C++标准算法

#include <string>
#include <iostream>
#include <iomanip>
#include <regex>
#include <vector>
#include <iterator>
#include <algorithm>


// Hex digit String
std::regex hexValue{R"(\\[xX]([0-9a-fA-F][0-9a-fA-F]))"};


int main ()
{   
    // Source string
    std::string s1 = "\\xfc\\xe8\\x82";
    std::cout << "s 1: " << s1 << "\n";


    // Proposal 1 ------------------------------------------------------

    // Target array
    unsigned char s2[3];

    // Convert bytes from strings
    for (int i=0; i<s1.size()/4; ++i ) {

        // Do conversion. Isolate substring, the convert
        s2[i] = std::strtoul(s1.substr(i*4+2,2).c_str(), nullptr,16);
        // Result is now in s2

        // Output value as tring and decimal value
        std::cout << s1.substr(i*4+2,2) << " -> " << std::hex << static_cast <unsigned short>(s2[i]) 
                  << " -> " << std::dec << static_cast <unsigned short>(s2[i]) << "\n";
    }

    // Proposal 2 ------------------------------------------------------

    // Get the tokens
    std::vector<std::string> vstr(std::sregex_token_iterator(s1.begin(),s1.end(),hexValue, 1), {});

    // Convert to unsigned int
    std::vector<unsigned int> vals{};

    std::transform(vstr.begin(), vstr.end(), std::back_inserter(vals), 
        [](std::string &s){ return static_cast<unsigned>(std::strtoul(s.c_str(), nullptr,16)); } );

    // Print output on std::cout
    std::copy(vals.begin(), vals.end(), std::ostream_iterator<unsigned>(std::cout,"\n"));

    return 0;
}

第二种解决方案将吃掉字符串中给出的任意数量的十六进制数字

【讨论】:

    猜你喜欢
    • 2022-08-04
    • 2013-05-12
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 1970-01-01
    相关资源
    最近更新 更多