hook — Может ли malloc вызвать сбой при обходе функции в C ++ для копирования строки данных из ExtTextOut в целевом процессе?

Я пытаюсь сделать обход, используя MSDN Detours 3.0 для регистрации текста, нарисованного ExtTextOut () от стороннего программного обеспечения. Я создал DLL, которую я вставляю в целевое программное обеспечение. Обходя ExtTextOut, я пытаюсь скопировать строку, отправленную методу, и прочитать текст в текстовый файл в измененном формате. Поскольку входной строкой является UTF-16, и меня интересует только сохранение символов ASCII ниже 127, я сделал для этого некоторую логику.

Проблема, однако, в том, что моя программа дает сбой через некоторое время после того, как она введена в цель. Я подозреваю, что это может иметь какое-то отношение к функция malloc.

Если я использую malloc, чтобы найти память в процессе, могу ли я гарантировать, что это не отменит память в целевом процессе? Если бы это было так, как я могу создать функцию, чтобы убедиться, что мой malloc не будет мешать целевому процессу.

Код:

BOOL WINAPI Mine_ExtTextOut(HDC hdc, int X, int Y, UINT options, RECT* lprc, LPCWSTR text, UINT cbCount, INT* lpSpacingValues)
{

//
if(reinterpret_cast<const char*>(text)[0] == '>'){

//wstring_convert<codecvt_utf8_utf16<wchar_t>,wchar_t> convert;
//string utf8_string = convert.to_bytes(text);
//int n = utf8_string.length();

int n = cbCount;

char *buffer = (char*) malloc (n+1);
char *bufferCopy = (char*) malloc (n+1);

for (int i=0; i<n; i++){
if((long) text[i] > 127){
buffer[i] = ' ';
continue;
}
buffer[i]= (char) text[i];
}
buffer[n]='\0';bool wasBlank = false;
int ix = 0;
for(int i = 0; i<n; ++i){
if(buffer[i] == ' '){
if(wasBlank || i < 2) continue;
bufferCopy[ix++] = buffer[i];
wasBlank = true;
continue;
}
wasBlank = false;
if(buffer[i] == '>') continue;
bufferCopy[ix++] = buffer[i];
}
bufferCopy[ix]='\0';

ofstream myFile;
myFile.open("C:\\temp\\textHooking\\textHook\\example2.txt", ios::app);
if(buffer[0] == '>'){
//myFile.write(reinterpret_cast<const char*>(text), cbCount*sizeof(*text));
myFile.write(bufferCopy, ix*sizeof(*bufferCopy));
myFile << endl;
}

free(buffer);
free(bufferCopy);

}
BOOL rv = Real_ExtTextOut(hdc, X, Y, options, lprc, text, cbCount, lpSpacingValues);
return rv;
}

2

Решение

cbCount параметр ExtTextOut() выражается в персонажи, но входной параметр malloc() выражается в байтов. Вы подключаете версию Unicode ExtTextOut() (ака ExtTextOutW()), где sizeof(WCHAR) составляет 2 байта. Вы пытаетесь обработать входную строку как Ansi, а это не так, и вы не учитываете суррогаты UTF-16.

Чтобы сделать то, что вы пытаетесь, вам нужно сначала декодировать данные UTF-16 в кодовые точки Unicode, прежде чем решить, какие из них сохранить, например:

BOOL WINAPI Mine_ExtTextOut(HDC hdc, int X, int Y, UINT options, RECT* lprc, LPCWSTR text, UINT cbCount, INT* lpSpacingValues)
{
if ((cbCount > 0) && (text != NULL) && (text[0] == L'>'))
{
// worse case, every UTF-16 character is ASCII and will be kept,
// so allocate enough memory for at least that many characters
std::string buffer(cbCount);
std::string bufferCopy(cbCount);

int ix1 = 0;
for (UINT i = 0; i < cbCount;)
{
ULONG c;

// is it a UTF-16 high surrogate?
if ((text[i] >= 0xD800) && (text[i] <= 0xDBFF))
{
// is it at the end of the string?
if ((i+1) == cbCount)
{
// malformed surrogate
break;
}

// is it followed by a UTF-16 low surrogate?
if ((text[i+1] < 0xDC00) || (text[i+1] > 0xDFFF))
{
// malformed surrogate
break;
}

// decode the surrogate and skip past it
c = ((ULONG(text[i] - 0xD800) << 10) | ULONG(text[i+1] - 0xDC00)) + 0x10000;
i += 2;
}

// is it a UTF-16 low surrogate?
else if (text[i] >= 0xDC00) && (text[i] <= 0xDFFF))
{
// malformed surrogate
break;
}

// must be a non-surrogated character
else
{
c = (ULONG) text[i];
++i;
}

// keep it?
if( c > 127 )
buffer[ix1] = ' ';
else
buffer[ix1] = (char) c;

++ix1;
}

bool wasBlank = false;
int ix2 = 0;
for(int i = 0; i < ix1; ++i)
{
if (buffer[i] == ' ')
{
if (wasBlank || (i < 2)) continue;
bufferCopy[ix2++] = buffer[i];
wasBlank = true;
continue;
}
wasBlank = false;
if (buffer[i] == '>') continue;
bufferCopy[ix2++] = buffer[i];
}

ofstream myFile;
myFile.open("C:\\temp\\textHooking\\textHook\\example2.txt", ios::app);
if (myFile)
{
myFile.write(bufferCopy.c_str(), ix2);
myFile << endl;
}
}

return Real_ExtTextOut(hdc, X, Y, options, lprc, text, cbCount, lpSpacingValues);
}
5

Другие решения

Основываясь на комментариях, вот несколько вещей, которые вы можете сделать, чтобы попытаться сузить это:

Замените malloc: вместо этого используйте buffer= (char *)GlobalAlloc(GPTR, n+1); а также GlobalFree(buffer), Это позволит убедиться, что это не проблема с несколькими библиотеками c-runtime.

В качестве альтернативы, чтобы убедиться, что нет ситуаций, в которых вы выходите за пределы выделенных буферов, попробуйте распределить malloc намного больше, например, buffer= malloc(n+1024); и посмотрим, решит ли это проблему. Если это произойдет, вам придется прочесать свой код, если вы выйдете за пределы допустимых смещений в буферах.

Аналогичным подходом (для тестирования) будет использование стековых версий буфера, которые длиннее, чем ожидаемый ввод, например char buffer[1024]; и используйте их как буферы malloc (конечно, не освобождайте их) и посмотрите, какая разница.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector