Форум программистов, компьютерный форум CyberForum.ru

Найти UTF-16 строку в бинарном файле - C++

Восстановить пароль Регистрация
 
caldwell
0 / 0 / 0
Регистрация: 12.06.2014
Сообщений: 17
25.06.2014, 11:38     Найти UTF-16 строку в бинарном файле #1
Здравствуйте,

Есть вот такая процедура для поиска и замены строк в бинарном файле. Применяю ее на обычном PE-файле. Проблема в том, что строки она не находит, хотя аналогичный вариант с narrow char работает прекрасно.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void scrambleWide(const char *filename, const char key) 
{
    std::wfstream ifs(filename, ios::binary|ios::out|ios::in);
    if(!ifs.is_open())
    {
        printf("Unable to open file in wide mode...\n");
        return;
    }
 
    ifs.imbue(std::locale(ifs.getloc(), new std::codecvt_utf8<wchar_t>));
 
    std::wstring str((std::istreambuf_iterator<wchar_t>(ifs)), std::istreambuf_iterator<wchar_t>());
 
    std::wsmatch matches;
    std::wregex rgx (L"(START_MARK)(.*?)(END_MARK)");
    std::wstring fullMatch, stringMatch;
    size_t appendSize;
 
    while (std::regex_search (str,matches,rgx)) {
        printf("Found match: %s at position: %d...", matches[2].str().c_str(), matches.position(2));
 
        fullMatch = matches[0].str(); 
        stringMatch = matches[2].str();
        appendSize = fullMatch.size() - stringMatch.size(); 
 
        stringMatch.append(appendSize, L'\0');
 
        ifs.seekp(matches.position(0));
        ifs.write(stringMatch.c_str(), stringMatch.size());
 
        printf("replaced\n");
 
        str = matches.suffix().str();
    }
    ifs.close();
}
Как ее переделать для поддержки widechar? Я думаю проблемы с локалью, но какую поставить не могу понять.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nmcf
4281 / 3712 / 1247
Регистрация: 14.04.2014
Сообщений: 14,516
25.06.2014, 17:00     Найти UTF-16 строку в бинарном файле #2
Может дело просто в том, что неизвестно, где начинается строка и соответственно откуда раскодировку начинать. Ты же не в текстовом файле ищешь.
caldwell
0 / 0 / 0
Регистрация: 12.06.2014
Сообщений: 17
25.06.2014, 23:19  [ТС]     Найти UTF-16 строку в бинарном файле #3
Да нет, вряд ли. Вот такая же функция, только для обычного char, работает нормально. Тут еще строка ксорится перед возвратом на место, но это не принципиально.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
bool scramble(const char *filename, const char key) 
{
    printf("Running in narrow char mode...\n");
    std::fstream ifs(filename, ios::binary|ios::out|ios::in);
    std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
 
    std::smatch matches;
    std::regex rgx ("(START_MARK)(.*?)(END_MARK)");
    std::string fullMatch, stringMatch;
    size_t appendSize;
 
    bool somethingFound = false;
 
    if (std::regex_search (str,matches,rgx)) {
        somethingFound = true;
        fullMatch = matches[0].str(); 
        stringMatch = matches[2].str();
        appendSize = fullMatch.size() - stringMatch.size(); 
 
        for(size_t i = 0; i < stringMatch.size(); i++)
        {
            stringMatch[i] ^= key;
        }
 
        stringMatch.append(appendSize, '\0');
 
        printf("Found string: %s at position: %d\n", stringMatch.c_str(), matches.position(0));
 
        ifs.seekp(matches.position(0));
        ifs.write(stringMatch.c_str(), stringMatch.size());
    }
 
    ifs.close();
 
    return somethingFound;
};
IIARTEMII
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
Завершенные тесты: 1
25.06.2014, 23:56     Найти UTF-16 строку в бинарном файле #4
Не имею привычки работать с wchar_t и std-аналогами функций для него, но может быть это связано с тем, что wchar_t занимает 2 байта и вы читаете в бинарном формате по два байта вместо одного? char работает небось потому, что строка запилена в PE-файле побайтово, а wchar_t аналог ищет по "двубайтово". Пересмотрите или поправьте меня, может и бред пишу
nmcf
4281 / 3712 / 1247
Регистрация: 14.04.2014
Сообщений: 14,516
26.06.2014, 08:12     Найти UTF-16 строку в бинарном файле #5
Ну так обычный char однобайтный, поэтому где бы строка не находилась, её можно найти, потому что куда ни ткни в ней, какую-то часть с любого места прочитаешь, а с двухбайтными надо ещё правильно попасть на начало пары. Как это можно сделать, если файл бинарный и неизвестно, где там вообще строки? С utf8 ещё сложнее, там тоже надо знать где начало, чтобы серии правильно потом декодировались. Не думаю, что regex сам может всё это сделать. Он рассчитан на строки, а не на кучу бинарных данных, в которых, может быть, есть строки и неизвестно где.
caldwell
0 / 0 / 0
Регистрация: 12.06.2014
Сообщений: 17
26.06.2014, 11:23  [ТС]     Найти UTF-16 строку в бинарном файле #6
Вы оба правы, в UTF-16 используется два байта на символ. И нужно правильный формат указать, что бы читались символы wchar_t. Только я не могу понять как это сделать.

У fstream есть метод imbue, который позволяет модифицировать поток под подходящую локаль. Пробовал например так, но не вкатило.
C++
1
ifs.imbue(std::locale(ifs.getloc(), new std::codecvt_utf16<wchar_t>));
Я пытаюсь модифицировать обычный PE-файл. Насколько я понимаю, там UTF-16LE внутри, но как это знание использовать ума не приложу.
IIARTEMII
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
Завершенные тесты: 1
26.06.2014, 14:01     Найти UTF-16 строку в бинарном файле #7
У меня парочка вопросов:
1) строки известны?
2) уверены, что UTF-16LE? как там кодируется число 0xAABB? (или приведите пример на известных вам данных)
Собственно это и не важно. Расширение стандартной кодировки до "двубайтовой" может происходить добавлением нулевого байта после (LE) или перед (BE) каждым байтом, после чего применяете ваш алгоритм с wchar_t к полученному массиву байт. Если стандартные средства с этим не справляются, пишите свои - заведите буфер и скопируйте туда все байты файла, после чего расширьте его, добавив нулевые байты в зависимости от вашей кодировки (лучше LE, конечно).
Оговорочка: добавление нулевого байта делается для латинских символов, для кириллицы там немного по-другому.
И ещё по поводу LE/BE - BOM там есть?
Прочитайте первые два байта, если там 0xfeff, то это big-endian, если наоборот, то little-endian, если там что-то другое, то скорее всего используется стандартный little-endian =)
caldwell
0 / 0 / 0
Регистрация: 12.06.2014
Сообщений: 17
26.06.2014, 14:23  [ТС]     Найти UTF-16 строку в бинарном файле #8
Что б было понятно, я пробую вот такой способ шифрования http://stackoverflow.com/a/7625156.

Это тестовый файл, строки известны. Вот пример строки в файле:

Найти UTF-16 строку в бинарном файле

Very wide string: 56 00 65 00 72 00 79 00 20 00 77 00 69 00 64 00 65 00 20 00 73 00 74 00 72 00 69 00 6E 00 67 00 - судя по тому, что вы написали, это LE.

Вначале файла стандартные MZ "0x4D 0x5A", т.е. BOM нет.
IIARTEMII
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
Завершенные тесты: 1
26.06.2014, 15:51     Найти UTF-16 строку в бинарном файле #9
Подождите секундочку... А с чего вы решили, что ваш алгоритм не находит строки? Вы добавили в свой код с wchar_t следующий код:
C++
1
2
3
4
for(size_t i = 0; i < stringMatch.size(); i++)
        {
            stringMatch[i] ^= key;
        }
? Только поправочку на 2 байта сделайте, если там это не применяется автоматически
caldwell
0 / 0 / 0
Регистрация: 12.06.2014
Сообщений: 17
26.06.2014, 20:48  [ТС]     Найти UTF-16 строку в бинарном файле #10
Да нет, это ж просто xor с заданным ключом. До него не доходит выполнение. Регэксп не обнаруживает строчку. Если str предварительно инициализировать чем-нибудь подходящим, типа:

C++
1
std::wstring str (L"bla-bla-bla MARK_BEGINsomewidestringMARK_END bla-bla");
тогда норм все работает, но это, ясное дело, не содержимое файла.
nmcf
4281 / 3712 / 1247
Регистрация: 14.04.2014
Сообщений: 14,516
26.06.2014, 21:03     Найти UTF-16 строку в бинарном файле #11
Создай текстовый файл utf16 с нужной строкой и проверь на нём.
caldwell
0 / 0 / 0
Регистрация: 12.06.2014
Сообщений: 17
28.06.2014, 16:12  [ТС]     Найти UTF-16 строку в бинарном файле #12
nmcf, ну так я на нем и проверяю.

Ребят, спасибо за проявленный интерес, но тема больше не актуальна.
IIARTEMII
20 / 20 / 3
Регистрация: 14.06.2012
Сообщений: 95
Завершенные тесты: 1
28.06.2014, 16:13     Найти UTF-16 строку в бинарном файле #13
Проблему-то решил? отпишись где собака зарыта)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.06.2014, 20:00     Найти UTF-16 строку в бинарном файле
Еще ссылки по теме:

C++ Поиск в бинарном файле
УТПФ в бинарном файле C++
C++ Сортировка структуры в бинарном файле

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
caldwell
0 / 0 / 0
Регистрация: 12.06.2014
Сообщений: 17
28.06.2014, 20:00  [ТС]     Найти UTF-16 строку в бинарном файле #14
IIARTEMII, нет, не решил. Потребность пропала.
Yandex
Объявления
28.06.2014, 20:00     Найти UTF-16 строку в бинарном файле
Ответ Создать тему
Опции темы

Текущее время: 12:54. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru