通过指针值

时间:2016-06-16 11:19:58

标签: c++ c qt libvlc

将指针的值(即变量所在的地址)作为整数传递给由同一主应用程序加载的另一个库,然后创建指向该地址的指针并获取该值是否安全?

例如:

#define __STDC_FORMAT_MACROS
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
struct Book {
    char            title[50];
    char            subject[100];
    int             book_id;
};

void
DescribeBook(char *label, struct Book *someBook)
{
    printf("\n%s\n", label);
    printf("Book title : %s\n", someBook->title);
    printf("Book subject : %s\n", someBook->subject);
    printf("Book book_id : %d\n", someBook->book_id);
}

void mem_wipe(uint8_t *ptr, uint64_t len) {
  while(len--) {
    *(ptr++) = 0;
  }
}

void
SomewhereElse(char *addressAsString)
{
    struct Book     *myBook;
  //PRETEND THIS IS IN A DLL SOMEWHERE ELSE!!!
    uint64_t        idataptr;

    sscanf(addressAsString, "%" PRIu64, &idataptr);

    mem_wipe((uint8_t *)addressAsString, strlen(addressAsString));

    free(addressAsString);

    myBook = (struct Book *)idataptr;

    DescribeBook("AFTER", myBook);
    printf("Data Address (int): %"PRIu64"\n", idataptr);
    printf("Data Address (string): %s\n", addressAsString);

    strcpy(myBook->title, "Foo");
    strcpy(myBook->subject, "Bar");
    myBook->book_id = 7654321;

}
int
main(void)
{
    struct Book     myBook;
    uint8_t        *dataptr;
    char           *addressAsString;

    strcpy(myBook.title, "Hello");
    strcpy(myBook.subject, "World");
    myBook.book_id = 1234567;


    DescribeBook("BEFORE", &myBook);
    printf("Data Address (int): %"PRIu64"\n", (uint64_t)&myBook);

    dataptr = (uint8_t *) & myBook;
    asprintf(&addressAsString, "%" PRIu64, (uint64_t) dataptr);
    if (addressAsString == NULL) {
         fprintf(stderr, "Error in asprintf\n");
          return 1;
    }
    printf("Data Address (string): %s\n", addressAsString);

    SomewhereElse(addressAsString);

    DescribeBook("FINAL (modified)", &myBook);
    printf("Data Address (string after wipe): %s\n", addressAsString);
    return 0;
}

请注意,它在那里统一可运行,但假装SomewhereElse()实际上是一个完全独立的dll,而addressAsString是通过环境设置或其他东西传递的

具体来说 - 我的问题是&#34;地址是一个地址是一个地址&#34;,或者当内存在穿过该dll屏障时如何映射内容会发生变化,这样123!= 123(&#34;虚拟记忆&#34;&#34;分页&#34;我认为是相关术语,但我不太了解它们)

(实际用例通过qt-&gt; vlc-qt或qmlvlc(c ++)传递给libvlc(gnu99 c),并通过自定义过滤器设置发送指针值)

作为后续内容 - 让我们进一步假设我们想要以安全的方式在某个时刻擦除内存,并防止它通过优化进行可能的破坏。可以将这样的指针声明为volatile(我仍然没有100%清楚它是如何工作的 - 但是样本代码搜索安全擦除会导致这种情况吗?)

1 个答案:

答案 0 :(得分:2)

您无法将指针作为int传递,因为您不知道int是否足以容纳指针。您也不应该使用明确大小的整数,例如int64_t,因为它们会模糊您的意图。要将指针作为整数传递,您应该使用intptr_tuintptr_t。这些类型是专门提供的,以明确表达您的意图,并确保(void*)适合他们。

要安全擦除内存,您必须使用适当的API。在Windows上,这将是SecureZeroMemory,在最近的Unices上是memset_s。它不关心它获得什么样的指针,只要它是指向数据的指针。

相关问题