2017-10-18 1 views
0

Chrome에서 비밀번호를 가져 오는 복구 앱을 쓰고 있습니다. 그것은 GUI를 가지고 있으므로 SQLConnection과 SQLQuery를 모두 사용하는 SQLite 래퍼를 사용했습니다. 여기 내 코드 싹둑입니다 : 뭔가 내 널 (NULL) 종료와 잘못된 것처럼이 동작을 제외하고CryptUnprotectData가있는 RAD Studio CreateBlobStream이 추가 문자를 반환하는 이유는 무엇입니까?

//Create our blob stream 
TStream *Stream2 = SQLQuery1->CreateBlobStream(SQLQuery1->FieldByName("password_value"), bmRead); 
//Get our blob size 
int size = Stream2->Size; 
//Create our buffer 
char* pbDataInput = new char[size+1]; 
//Adding null terminator to buffer 
memset(pbDataInput, 0x00, sizeof(char)*(size+1)); 
//Write to our buffer 
Stream2->ReadBuffer(pbDataInput, size); 
DWORD cbDataInput = size; 

DataOut.pbData = pbDataInput; 
DataOut.cbData = cbDataInput; 

LPWSTR pDescrOut = NULL; 
//Decrypt password 
CryptUnprotectData(&DataOut, 
     &pDescrOut, 
     NULL, 
     NULL, 
     NULL, 
     0, 
     &DataVerify); 

//Output password 
UnicodeString password = (UnicodeString)(char*)DataVerify.pbData; 
passwordgrid->Cells[2][i] = password; 

출력 데이터는, 잘 보인다. 여기 출력은 모든 라인의 모습입니다 : 내가 읽은

Output Data With Extra Chars at end of Password

CryptUnprotectData에 대한

윈도우 문서 :

https://msdn.microsoft.com/en-us/library/windows/desktop/aa382377.aspx

CreateBlobStream에 대한

엠바 카데로 문서 :

http://docwiki.embarcadero.com/Libraries/en/Data.DB.TDataSet.CreateBlobStream

memset 함수 :

http://www.cplusplus.com/reference/cstring/memset/

답변

1

귀하의 읽기 및 해독 통화 원시 바이트에서 작동 만, 그들은 문자열에 대한 아무것도 모르는, 그리고 그들에 대해 걱정하지 않는다. 당신이 pbDataInput에 추가되는 널 (NULL) 종료는 사용되지 않습니다, 그래서 그것을 제거 :

//Get our blob size 
int size = Stream2->Size; 
//Create our buffer 
char* pbDataInput = new char[size]; 
//Write to our buffer 
Stream2->ReadBuffer(pbDataInput, size); 
DWORD cbDataInput = size; 
... 
delete[] pbDataInput; 
delete Stream2; 

를 이제, 당신이 char*-pbData을 캐스팅 password-pbData를 할당 할 때 UnicodeString 생성자가 같은 데이터를 해석 있도록 null로 종료되는 ANSI 문자열을 사용하고 시스템 기본 ANSI 코드 페이지를 사용하여 UTF-16으로 변환합니다. 이는 비 ASCII 문자에 대해 잠재적으로 손실이있는 변환입니다. 그게 네가 정말로 원하는거야? 해독 된 출력이 이미 켜져있는 경우, 다른 한편으로

UnicodeString password((char*)DataVerify.pbData, DataVerify.cbData); 

: 해독 된 데이터가 실제로 null이 종료되지 않은 경우

그렇다면, 그리고, 당신은 UnicodeString 생성자에 문자 수를 지정해야 NOT NULL이 종료되는 경우,

UnicodeString password = (wchar_t*)DataVerify.pbData; 

을 또는 : UTF-16 대신 wchar_t*pbData 캐스팅 할 필요가

UnicodeString password((wchar_t*)DataVerify.pbData, DataVerify.cbData/sizeof(wchar_t)); 
+0

고마워, 널 머리말에 널 터미네이터와 관련이있다. 당신의 대답을 upvoting. –

관련 문제