memcpy分段错误。数据结构边界不对齐

时间:2016-05-07 20:22:55

标签: c debugging gdb wireshark memcpy

我正在尝试调试此错误但暂时无法执行此操作。我曾尝试使用memmove作为替代方案,但这也会导致分段错误。 此问题中代码的链接发布在 - http://pastebin.com/hiwV5G04

有人可以帮我理解我做错了什么吗?

//------------------------------------------------------------------------
// Somewhere in the main function, This is the piece of code I am executing
//------------------------------------------------------------------------
SslDecryptSession *ssl_session = malloc(sizeof(struct _SslDecryptSession ));
ssl_session->client_random.data = NULL;  //Make the stuff point somewhere. Else can use malloc also here. Not sure if this is a problem
ssl_session->server_random.data= NULL;
const u_char *payload;                  /* Packet payload */
//Case for client random
printf("Client Random ");
for (cs_id = 11; cs_id < 43; cs_id++){
printf("%hhX", payload[cs_id] );
}
printf("\n");
cs_id=11;
ssl_session->client_random.data_len=32;
// Segmentation fault here
memcpy(ssl_session->client_random.data, payload[cs_id], 32);

所涉及的结构的定义是 -

typedef struct _SslDecryptSession {
guchar _master_secret[SSL_MASTER_SECRET_LENGTH];
guchar _session_id[256];
guchar _client_random[32];
guchar _server_random[32];
StringInfo session_id;
StringInfo session_ticket;
StringInfo server_random;
StringInfo client_random;
StringInfo master_secret;
StringInfo handshake_data;
StringInfo pre_master_secret;
guchar _server_data_for_iv[24];
StringInfo server_data_for_iv;
guchar _client_data_for_iv[24];
StringInfo client_data_for_iv;

gint state;
SslCipherSuite cipher_suite;
SslDecoder *server;
SslDecoder *client;
SslDecoder *server_new;
SslDecoder *client_new;
gcry_sexp_t private_key;
StringInfo psk;
guint16 version_netorder;
 StringInfo app_data_segment;
    SslSession session;
} SslDecryptSession;


typedef struct _StringInfo {
    guchar  *data;         
    guint    data_len;  
   } StringInfo

gdb的输出是这个

b 1985    // Putting a break point at line 1985 in my source code. 
//Here this is eqvialent to line 83, that is "ssl_session->client_random.data_len=32;"
Breakpoint 1 at 0x403878: file Newversion.c, line 1985.
run       //run the code in gdb
At breakpoint 1 the following info is in the variables
p ssl_session
$1 = (SslDecryptSession *) 0x60fc50   // I put some data in ssl_session->version_netorder earlier. So it is not null here. Everything works fine here
p ssl_session->client_random.data
$2 = (guchar *) 0x0
p ssl_session->client_random.data_len
$3 = 32
step  // Execute 1 more line in the code
// I reach at the memcpy line and I get this error then
Breakpoint 1, got_packet (args=0x0, header=0x7fffffffe2c0, packet=0x7ffff6939086 "P=\345\203\376\177") at Newversion.c:1995
1995                memcpy(ssl_session->client_random.data, payload[cs_id], 32);
(gdb) 
(gdb) s
__memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:27
27  ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S: No such file or directory.
(gdb) 
28  in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb) 
29  in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb) 
30  in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb) 
31  in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb) 
32  in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb) 
33  in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb) 
34  in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb) 
35  in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
__memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:35
35  in ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S

3 个答案:

答案 0 :(得分:2)

对于代码来说,有很多事情似乎并不合适。有问题的一行是:

memcpy(ssl_session->client_random.data, &payload[cs_id], 32); // Note the & symbol

此行将复制有效负载[cs_id]在ssl_session-&gt; client_random.data指向的地址处指向的内容。这样做会占用32个字节。

您将有效负载的内容提供给memcpy而不是它的地址,因此您在编译时会收到警告。

你可能意味着像

const u_char payload[43];  // 43 is based on the example you provided
...
ssl_session->client_random.data = malloc(sizeof(u_char)*32); // Also based on your example
...
memcpy(ssl_session->client_random.data, &payload[cs_id], 32);

此外,您的代码中有一条注释,指出您不确定是否应该使用malloc。你这样做。

在您提供的代码片段中,未启动有效负载(因此,不可预测的值),并且使用NULL启动ssl_session-&gt; client_random.data。这意味着您尝试在地址0处写入,这肯定会引发段错误。此外,在写入地址0之前,您在内存中读取一个随机地址,这很可能也会引发异常。

要解决此问题,请确保您的操作系统在读取/写入之前为您提供了可用的内存空间。

{{1}}

希望这有帮助。

答案 1 :(得分:0)

违规代码是:

memcpy(ssl_session->client_random.data, payload[cs_id], 32);

payload定义为:

const u_char *payload;

您似乎memcpy的操作数2的类型不匹配,您不传递指针而是传递整数。编译器应该发出警告,并且不应忽略此类警告。

您的意思是使用memset()来初始化数据而不是memcpy()吗?

答案 2 :(得分:0)

1 - 你忘了分配内存。

2- memcpy(ssl_session-&gt; client_random.data,&amp; payload [cs_id],32 * sizeof(u_char)

    SslDecryptSession *ssl_session = malloc(sizeof(struct _SslDecryptSession ));
    ssl_session->client_random.data = NULL;  //Make the stuff point somewhere. Else can use malloc also here. Not sure if this is a problem
    ssl_session->server_random.data= NULL;

    const u_char *payload;                  /* Packet payload */
    //Case for client random

    printf("Client Random ");
    for (cs_id = 11; cs_id < 43; cs_id++){
            printf("%hhX", payload[cs_id] );
    }
    printf("\n");


    cs_id=11;
    ssl_session->client_random.data_len=32;
    guchar  *pData = malloc(32*sizeof(guchar));  
    ssl_session->client_random.data = pData;
    memcpy(ssl_session->client_random.data, &payload[cs_id], 32*sizeof(u_char);