C语言 将字节作为命令行参数传递给程序

wljmcqd8  于 2023-02-03  发布在  其他
关注(0)|答案(1)|浏览(110)

我试图利用缓冲区溢出漏洞。为此,我想将一个先前确定的地址(如\x00\x00\x41\xab\x00\xab)传递给程序,以便将其作为字节写入内存,而不是输入字符串的字节表示形式。请考虑以下示例:

Address I want to write as hex string: \x00\x00\x41\xab\x00\xab 

Memory before overflow: ab ab 00 00 aa 00  (these values could be arbitrary since its stack memory) 
Memory after overflow : 00 00 41 ab 00 ab

我尝试写入的缓冲区是通过以下方式访问的:

void overflow(char input[], end){
    for(int a = 0; a < end; ++a){
        char buffer[32];
        buffer[a] = input[a];
}

end的值由input的长度决定,溢出与我的问题无关,我的问题是:
如何将一个地址以任何形式(十六进制、字节串等)作为命令行参数传递给程序(通过argv[]),以便如上所示将其写入内存?
特别是,如何处理\x00字符?
我发现了this问题,不幸的是,它没有提供解决方案。注意,我并没有试图通过管道传输参数,因为程序不从标准输入中读取。

bq9c1y66

bq9c1y661#

我将输入作为文本字符串,如"000041ab00ab",然后编写一些简单的代码来进行转换。
比如:

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

unsigned char conv_char(char c)
{
        if (c >= '0' && c <= '9')
        {
            return c - '0';
        }
        
        if (c >= 'a' && c <= 'f')
        {
            return c - 'a' + 10;
        }
        
        exit(1);
}

void get_values(const char* str, unsigned char* values)
{
    if (strlen(str) != 12) exit(1);
    for (int i=0; i < 6; ++i)
    {
        values[i] = conv_char(str[2*i]);
        values[i] = values[i] << 4;
        values[i] = values[i] | conv_char(str[2*i + 1]);
    }
}

int main(int argc, char* argv[]) 
{
    if (argc != 2) exit(1);
    unsigned char values[6];
    get_values(argv[1], values);
    
    for (int i=0; i < 6; ++i)
    {
        printf("0x%02x ", values[i]);
    }    
    puts("");
    
    return 0;
}

prog 000041ab00ab的形式运行,得到以下输出:

0x00 0x00 0x41 0xab 0x00 0xab

相关问题