2012-02-02 2 views
0

C++에서 C#으로 데이터를 전달하고 처리해야하는 프로그램이 있습니다. 이를 위해 구조체를 검색하여 바이트 배열로 변환 한 다음 다른 끝에 다시 변환했습니다. 그러나 메모리 덤프가 각 변수의 메모리 값이 동일 함을 나타내더라도 데이터를 다시 변환 할 때 데이터가 올바르지 않습니다.구조체를 전달하면 데이터가 손상됩니다.

BYTE * cpiBuffer = (BYTE*)calloc(_PublicKey->Length, sizeof(BYTE)); 
for(int i = 0; i < _PublicKey->Length; i++) 
    cpiBuffer[i] = _PublicKey[i]; 
PCERT_PUBLIC_KEY_INFO cpi = (PCERT_PUBLIC_KEY_INFO)cpiBuffer; 

이 그들을보고 :

array<Byte>^GetPublicKeyBlob(String^ContainerName) { 
    const TCHAR * tContainer = context->marshal_as<const TCHAR*>(ContainerName); 
    HCRYPTPROV hProv = NULL; 
    CryptAcquireContext(&hProv, tContainer, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET); 
    DWORD dwKeySize = 0; 
    CryptExportPublicKeyInfo(hProv, AT_SIGNATURE, X509_ASN_ENCODING, NULL, &dwKeySize); 
    PCERT_PUBLIC_KEY_INFO pbKey = (PCERT_PUBLIC_KEY_INFO)calloc(dwKeySize, sizeof(BYTE)); 
    CryptExportPublicKeyInfo(hProv, AT_SIGNATURE, X509_ASN_ENCODING, (PCERT_PUBLIC_KEY_INFO)pbKey, &dwKeySize); 
    array<Byte>^retVal = gcnew array<Byte>(dwKeySize); 
     for(int i = 0; i < dwKeySize; i++) 
      retVal[i] = ((BYTE*)pbKey)[i]; 

    free(pbKey); 
return retVal; 
} 

그런 다음 다른 쪽 끝에서, 나는 다음과 같은 코드로 다시 PCERT_PUBLIC_KEY_INFO 구조 변경 : 여기

는 값을 검색 할 수있는 코드 메모리 덤프에서 pbKey, retVal, _PublicKey, cpiBuffer 및 cpi는 모두 동일한 값을 갖습니다. 그러나 cpi를 구조체로 볼 때 Algorithm.pszObjId는 잘못된 메모리 위치를 가리키며 함수에서 사용하려고하면 실패합니다. 여기서 내가 뭘 잘못하고 있니?

+0

"Algorithm.pszObjId가 잘못된 메모리 위치를 가리키고 있음"이란 무엇을 의미합니까? 포인터입니까? –

+0

이것은 LPSTR입니다. 시계에서 구조를 확장하면 구조 안의 메모리 위치를 가리키는 반면 원래 값을 얻으면 구조 내의 위치를 ​​가리키고 있습니다. –

답변

0
typedef struct _CRYPT_ALGORITHM_IDENTIFIER { 
    LPSTR   pszObjId; 
    CRYPT_OBJID_BLOB Parameters; 
} CRYPT_ALGORITHM_IDENTIFIER, *PCRYPT_ALGORITHM_IDENTIFIER; 

pszObjId는 포인터이며, 내용은 메모리에 있습니다. PCERT_PUBLIC_KEY_INFO 구조체를 바이트 배열로 캐스팅하면 포인터의 값만 가져오고 포인터의 포인터는 가져 오지 않습니다.

사이드 노트에서 왜 TCHAR *로 마샬링하는지 모르겠다. 바이트를 원한다면 char * 또는 unsigned char *를 사용해야한다. UNICODE가 정의되면 TCHAR은 wchar_t가되고 약간의 어려움이있을 수 있습니다.

+0

TCHAR *는 습관의 힘입니다. 이것은 생산되지 않은 코드입니다. 캐스팅하지 않은 경우 원래 구조를 어떻게 다시 얻을 수 있습니까? –

+0

이 구조체가 어떻게 생성되는지, 문자열을 할당하는 사람과 누가 그것을 해제 할 책임이 있는지 모르기 때문에 나는 확실한 답을 얻지 못했습니다. 하지만 구조체, 멤버, 멤버 변수를 직렬화하는 방법을 알고, null로 끝나는 문자 배열이나 크기 접두어로 문자열을 serialize하는 방법을 알고있는 함수를 만들 수 있다고 생각합니다. –

+0

CryptExportPublicKeyInfo에 대한 첫 번째 호출은 CERT_PUBLIC_KEY_INFO 구조에 필요한 버퍼의 길이를 반환합니다. 그런 다음 해당 양의 메모리를 할당하고 함수를 다시 호출하면 데이터가 버퍼로 전달됩니다. –

관련 문제