1
unsigned char* Data::getAddress(unsigned char* address)
{
    strcpy((char*)address, (char*)this->_address);
    return (unsigned char*)address;
}

int main()
{
    Data d;
    d.makealinkedlisthere();
    while (d)
    {
       unsigned char address[256];
       printf("0x%08x \r\n",d.getAddress(address));
       d = d.getNext();
    }
    return 0;
}

最初の 2 つを返します (これは同じですが、異なるはずです [デバッガーから確認できます]...)。その後、クラッシュします。

リンクされたリストを作成するだけです。保護されたメンバーData* _next... それらのチェーン。

unsigned char* は、返されるデータ構造のWindows 関数VirtualQueryEx部分からのものです。MEMORY_BASIC_INFORMATION

this->_address = (unsigned char*)meminfo->BaseAddress; // casted from void*

void* ですが、他のコードでは unsigned char* に変換されています。デバッガーでは、16 進数として表されていることがわかります。

D1: +    _address   0x7ffd5000 <Bad Ptr>    unsigned char * 
D1->_next:+  _address   0x7f6f0000 "áå•ú`©" unsigned char * 
D1->_next->_next+    _address   0x7ffb0000 " "  unsigned char *
4

1 に答える 1

2

MEMORY_BASIC_INFORMATION.Base Address は、文字列ではなくページ領域の場所であり、null で終了するという保証はありません。MSDN サイトからMEMORY_BASIC_INFORMATION 構造体を見ることができます

typedef struct _MEMORY_BASIC_INFORMATION {
  PVOID  BaseAddress;
  PVOID  AllocationBase;
  DWORD  AllocationProtect;
  SIZE_T RegionSize;
  DWORD  State;
  DWORD  Protect;
  DWORD  Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;

データをコピーするにはmemcpy、 size = 255` で a を使用する必要があります。

コードを振り返って、他に問題がなければ、次のように変更します。

PVOID Data::getAddress(PVOID address,size) {    
    memcpy((address, (void *)this->_address, size);
    address[size]=NULL;
    return address;
}
int main() {
    Data d;
    d.makealinkedlisthere();
    while (d) {
       unsigned char address[256];
       printf("Address: 0x%08x \n",d.getAddress((PVOID)address),sizeof(address));
       printf("Data: %s\n",(LPSTR)d.getAddress((PVOID)address),sizeof(address));
       d = d.getNext();
    }
    return 0;
}

動作するはずです

RegionSizeまた、保存する前に境界チェックを行っても安全memcpyです。

于 2012-04-15T19:21:58.540 に答える