forked from Public-Mirror/Textractor
specify null length
This commit is contained in:
parent
c6b7c6ba22
commit
e8607e576d
@ -58,7 +58,10 @@ void TextThread::Flush()
|
||||
std::vector<std::wstring> sentences;
|
||||
queuedSentences->swap(sentences);
|
||||
for (auto& sentence : sentences)
|
||||
{
|
||||
sentence.erase(std::remove(sentence.begin(), sentence.end(), L'\0'));
|
||||
if (Output(*this, sentence)) storage->append(sentence);
|
||||
}
|
||||
|
||||
std::scoped_lock lock(bufferMutex);
|
||||
if (buffer.empty()) return;
|
||||
|
@ -27,6 +27,13 @@ namespace
|
||||
}
|
||||
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#]
|
||||
if (std::regex_search(RCode, match, std::wregex(L"^([0-9]+)#")))
|
||||
{
|
||||
@ -104,6 +111,13 @@ namespace
|
||||
}
|
||||
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]
|
||||
if (HCode[0] == L'N')
|
||||
{
|
||||
@ -181,10 +195,12 @@ namespace
|
||||
if (hp.type & USING_UNICODE)
|
||||
{
|
||||
RCode << "Q";
|
||||
if (hp.null_length != 0) RCode << hp.null_length << "<";
|
||||
}
|
||||
else
|
||||
{
|
||||
RCode << "S";
|
||||
if (hp.null_length != 0) RCode << hp.null_length << "<";
|
||||
if (hp.codepage != 0) RCode << hp.codepage << "#";
|
||||
}
|
||||
|
||||
@ -213,6 +229,9 @@ namespace
|
||||
else if (hp.type & BIG_ENDIAN) HCode << "A";
|
||||
else HCode << "B";
|
||||
}
|
||||
|
||||
if (hp.null_length != 0) HCode << hp.null_length << "<";
|
||||
|
||||
if (hp.type & NO_CONTEXT) HCode << "N";
|
||||
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::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 {};
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,8 @@ struct HookParam
|
||||
int offset, // offset of the data in the memory
|
||||
index, // deref_offset1
|
||||
split, // offset of the split character
|
||||
split_index; // deref_offset2
|
||||
split_index, // deref_offset2
|
||||
null_length;
|
||||
union
|
||||
{
|
||||
wchar_t module[MAX_MODULE_SIZE];
|
||||
|
5
text.cpp
5
text.cpp
@ -21,15 +21,16 @@ const char* CODE_INFODUMP = u8R"(Search for text
|
||||
S[codepage#]text
|
||||
OR
|
||||
Enter read code
|
||||
R{S|Q|V}[codepage#][*deref_offset]@addr
|
||||
R{S|Q|V}[null_length<][codepage#][*deref_offset]@addr
|
||||
OR
|
||||
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
|
||||
Default codepage is 932 (Shift-JIS) but this can be changed in settings
|
||||
A/B: codepage char little/big endian
|
||||
W: UTF-16 char
|
||||
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
|
||||
-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)";
|
||||
|
@ -229,14 +229,14 @@ DWORD WINAPI TextHook::Reader(LPVOID hookPtr)
|
||||
{
|
||||
TextHook* This = (TextHook*)hookPtr;
|
||||
BYTE buffer[TEXT_BUFFER_SIZE] = {};
|
||||
int changeCount = 0, dataLen = 0;
|
||||
int changeCount = 0, dataLen = 1;
|
||||
__try
|
||||
{
|
||||
uint64_t currentAddress = This->address;
|
||||
while (WaitForSingleObject(This->readerEvent, 500) == WAIT_TIMEOUT)
|
||||
{
|
||||
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;
|
||||
continue;
|
||||
@ -248,10 +248,8 @@ DWORD WINAPI TextHook::Reader(LPVOID hookPtr)
|
||||
break;
|
||||
}
|
||||
|
||||
if (This->hp.type & USING_UNICODE) dataLen = wcslen((wchar_t*)currentAddress) * 2;
|
||||
else dataLen = strlen((char*)currentAddress);
|
||||
if (dataLen > TEXT_BUFFER_SIZE - 2) dataLen = TEXT_BUFFER_SIZE - 2;
|
||||
memcpy(buffer, (void*)currentAddress, dataLen + 2);
|
||||
dataLen = min(This->HookStrlen((BYTE*)currentAddress), TEXT_BUFFER_SIZE);
|
||||
memcpy(buffer, (void*)currentAddress, dataLen);
|
||||
TextOutput({ GetCurrentProcessId(), This->address, 0, 0 }, buffer, dataLen);
|
||||
}
|
||||
}
|
||||
@ -308,10 +306,7 @@ int TextHook::GetLength(uintptr_t base, uintptr_t in)
|
||||
break;
|
||||
//len == -1 then continue to case 0.
|
||||
case 0:
|
||||
if (hp.type & USING_UNICODE)
|
||||
len = wcslen((const wchar_t *)in) << 1;
|
||||
else
|
||||
len = strlen((const char *)in);
|
||||
len = HookStrlen((BYTE*)in);
|
||||
break;
|
||||
case 1:
|
||||
if (hp.type & USING_UNICODE)
|
||||
@ -328,4 +323,12 @@ int TextHook::GetLength(uintptr_t base, uintptr_t in)
|
||||
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
|
||||
|
@ -34,6 +34,7 @@ private:
|
||||
bool InsertReadCode();
|
||||
void Send(uintptr_t dwDatabase);
|
||||
int GetLength(uintptr_t base, uintptr_t in); // jichi 12/25/2013: Return 0 if failed
|
||||
int HookStrlen(BYTE* data);
|
||||
void RemoveHookCode();
|
||||
void RemoveReadCode();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user