specify null length

This commit is contained in:
Akash Mozumdar 2019-03-27 23:35:22 -04:00
parent c6b7c6ba22
commit e8607e576d
6 changed files with 43 additions and 14 deletions

View File

@ -58,7 +58,10 @@ void TextThread::Flush()
std::vector<std::wstring> sentences; std::vector<std::wstring> sentences;
queuedSentences->swap(sentences); queuedSentences->swap(sentences);
for (auto& sentence : sentences) for (auto& sentence : sentences)
{
sentence.erase(std::remove(sentence.begin(), sentence.end(), L'\0'));
if (Output(*this, sentence)) storage->append(sentence); if (Output(*this, sentence)) storage->append(sentence);
}
std::scoped_lock lock(bufferMutex); std::scoped_lock lock(bufferMutex);
if (buffer.empty()) return; if (buffer.empty()) return;

View File

@ -27,6 +27,13 @@ namespace
} }
RCode.erase(0, 1); RCode.erase(0, 1);
// [null_length<]
if (std::regex_search(RCode, match, std::wregex(L"^([0-9]+)<")))
{
hp.null_length = std::stoi(match[1]);
RCode.erase(0, match[0].length());
}
// [codepage#] // [codepage#]
if (std::regex_search(RCode, match, std::wregex(L"^([0-9]+)#"))) if (std::regex_search(RCode, match, std::wregex(L"^([0-9]+)#")))
{ {
@ -104,6 +111,13 @@ namespace
} }
HCode.erase(0, 1); HCode.erase(0, 1);
// [null_length<]
if ((hp.type & USING_STRING) && std::regex_search(HCode, match, std::wregex(L"^([0-9]+)<")))
{
hp.null_length = std::stoi(match[1]);
HCode.erase(0, match[0].length());
}
// [N] // [N]
if (HCode[0] == L'N') if (HCode[0] == L'N')
{ {
@ -181,10 +195,12 @@ namespace
if (hp.type & USING_UNICODE) if (hp.type & USING_UNICODE)
{ {
RCode << "Q"; RCode << "Q";
if (hp.null_length != 0) RCode << hp.null_length << "<";
} }
else else
{ {
RCode << "S"; RCode << "S";
if (hp.null_length != 0) RCode << hp.null_length << "<";
if (hp.codepage != 0) RCode << hp.codepage << "#"; if (hp.codepage != 0) RCode << hp.codepage << "#";
} }
@ -213,6 +229,9 @@ namespace
else if (hp.type & BIG_ENDIAN) HCode << "A"; else if (hp.type & BIG_ENDIAN) HCode << "A";
else HCode << "B"; else HCode << "B";
} }
if (hp.null_length != 0) HCode << hp.null_length << "<";
if (hp.type & NO_CONTEXT) HCode << "N"; if (hp.type & NO_CONTEXT) HCode << "N";
if (hp.text_fun || hp.filter_fun || hp.hook_fun) HCode << "X"; // no AGTH equivalent if (hp.text_fun || hp.filter_fun || hp.hook_fun) HCode << "X"; // no AGTH equivalent
@ -287,7 +306,8 @@ namespace Util
std::optional<std::wstring> StringToWideString(const std::string& text, UINT encoding) std::optional<std::wstring> StringToWideString(const std::string& text, UINT encoding)
{ {
std::vector<wchar_t> buffer(text.size() + 1); std::vector<wchar_t> buffer(text.size() + 1);
if (MultiByteToWideChar(encoding, 0, text.c_str(), -1, buffer.data(), buffer.size())) return buffer.data(); if (int length = MultiByteToWideChar(encoding, 0, text.c_str(), text.size() + 1, buffer.data(), buffer.size()))
return std::wstring(buffer.data(), length - 1);
return {}; return {};
} }

View File

@ -29,7 +29,8 @@ struct HookParam
int offset, // offset of the data in the memory int offset, // offset of the data in the memory
index, // deref_offset1 index, // deref_offset1
split, // offset of the split character split, // offset of the split character
split_index; // deref_offset2 split_index, // deref_offset2
null_length;
union union
{ {
wchar_t module[MAX_MODULE_SIZE]; wchar_t module[MAX_MODULE_SIZE];

View File

@ -21,15 +21,16 @@ const char* CODE_INFODUMP = u8R"(Search for text
S[codepage#]text S[codepage#]text
OR OR
Enter read code Enter read code
R{S|Q|V}[codepage#][*deref_offset]@addr R{S|Q|V}[null_length<][codepage#][*deref_offset]@addr
OR OR
Enter hook code Enter hook code
H{A|B|W|S|Q|V}[N][codepage#]data_offset[*deref_offset1][:split_offset[*deref_offset2]]@addr[:module[:func]] H{A|B|W|S|Q|V}[null_length<][N][codepage#]data_offset[*deref_offset1][:split_offset[*deref_offset2]]@addr[:module[:func]]
All numbers except codepage in hexadecimal All numbers except codepage in hexadecimal
Default codepage is 932 (Shift-JIS) but this can be changed in settings Default codepage is 932 (Shift-JIS) but this can be changed in settings
A/B: codepage char little/big endian A/B: codepage char little/big endian
W: UTF-16 char W: UTF-16 char
S/Q/V: codepage/UTF-16/UTF-8 string S/Q/V: codepage/UTF-16/UTF-8 string
null_length: length of null terminator used for string
Negatives for data/split offset refer to registers Negatives for data/split offset refer to registers
-4 for EAX, -8 for ECX, -C for EDX, -10 for EBX, -14 for ESP, -18 for EBP, -1C for ESI, -20 for EDI -4 for EAX, -8 for ECX, -C for EDX, -10 for EBX, -14 for ESP, -18 for EBP, -1C for ESI, -20 for EDI
* means dereference pointer+deref_offset)"; * means dereference pointer+deref_offset)";

View File

@ -229,14 +229,14 @@ DWORD WINAPI TextHook::Reader(LPVOID hookPtr)
{ {
TextHook* This = (TextHook*)hookPtr; TextHook* This = (TextHook*)hookPtr;
BYTE buffer[TEXT_BUFFER_SIZE] = {}; BYTE buffer[TEXT_BUFFER_SIZE] = {};
int changeCount = 0, dataLen = 0; int changeCount = 0, dataLen = 1;
__try __try
{ {
uint64_t currentAddress = This->address; uint64_t currentAddress = This->address;
while (WaitForSingleObject(This->readerEvent, 500) == WAIT_TIMEOUT) while (WaitForSingleObject(This->readerEvent, 500) == WAIT_TIMEOUT)
{ {
if (This->hp.type & DATA_INDIRECT) currentAddress = *(uintptr_t*)This->address + This->hp.index; if (This->hp.type & DATA_INDIRECT) currentAddress = *(uintptr_t*)This->address + This->hp.index;
if (memcmp(buffer, (void*)currentAddress, dataLen + 2) == 0) if (memcmp(buffer, (void*)currentAddress, dataLen) == 0)
{ {
changeCount = 0; changeCount = 0;
continue; continue;
@ -248,10 +248,8 @@ DWORD WINAPI TextHook::Reader(LPVOID hookPtr)
break; break;
} }
if (This->hp.type & USING_UNICODE) dataLen = wcslen((wchar_t*)currentAddress) * 2; dataLen = min(This->HookStrlen((BYTE*)currentAddress), TEXT_BUFFER_SIZE);
else dataLen = strlen((char*)currentAddress); memcpy(buffer, (void*)currentAddress, dataLen);
if (dataLen > TEXT_BUFFER_SIZE - 2) dataLen = TEXT_BUFFER_SIZE - 2;
memcpy(buffer, (void*)currentAddress, dataLen + 2);
TextOutput({ GetCurrentProcessId(), This->address, 0, 0 }, buffer, dataLen); TextOutput({ GetCurrentProcessId(), This->address, 0, 0 }, buffer, dataLen);
} }
} }
@ -308,10 +306,7 @@ int TextHook::GetLength(uintptr_t base, uintptr_t in)
break; break;
//len == -1 then continue to case 0. //len == -1 then continue to case 0.
case 0: case 0:
if (hp.type & USING_UNICODE) len = HookStrlen((BYTE*)in);
len = wcslen((const wchar_t *)in) << 1;
else
len = strlen((const char *)in);
break; break;
case 1: case 1:
if (hp.type & USING_UNICODE) if (hp.type & USING_UNICODE)
@ -328,4 +323,12 @@ int TextHook::GetLength(uintptr_t base, uintptr_t in)
return max(0, len); return max(0, len);
} }
int TextHook::HookStrlen(BYTE* data)
{
BYTE* orig = data;
for (int nullsRemaining = hp.null_length ? hp.null_length : hp.type & USING_UNICODE ? 2 : 1; nullsRemaining >= 0; ++data)
if (*data == 0) nullsRemaining -= 1;
return data - orig;
}
// EOF // EOF

View File

@ -34,6 +34,7 @@ private:
bool InsertReadCode(); bool InsertReadCode();
void Send(uintptr_t dwDatabase); void Send(uintptr_t dwDatabase);
int GetLength(uintptr_t base, uintptr_t in); // jichi 12/25/2013: Return 0 if failed int GetLength(uintptr_t base, uintptr_t in); // jichi 12/25/2013: Return 0 if failed
int HookStrlen(BYTE* data);
void RemoveHookCode(); void RemoveHookCode();
void RemoveReadCode(); void RemoveReadCode();