This commit is contained in:
test123456654321 2024-10-27 22:09:44 +08:00
parent 8592939737
commit 623b208549
11 changed files with 1379 additions and 1343 deletions

View File

@ -175,15 +175,6 @@ bool isPauseKeyPressed()
{ {
return WinKey::isKeyControlPressed() || WinKey::isKeyShiftPressed() && !WinKey::isKeyReturnPressed(); return WinKey::isKeyControlPressed() || WinKey::isKeyShiftPressed() && !WinKey::isKeyReturnPressed();
} }
inline UINT64 djb2_n2(const unsigned char *str, size_t len, UINT64 hash = 5381)
{
int i = 0;
while (len--)
{
hash = ((hash << 5) + hash) + (*str++); // hash * 33 + c
}
return hash;
}
std::unordered_map<UINT64, std::wstring> translatecache; std::unordered_map<UINT64, std::wstring> translatecache;
bool check_is_thread_selected(const ThreadParam &tp) bool check_is_thread_selected(const ThreadParam &tp)
{ {
@ -200,7 +191,7 @@ bool check_embed_able(const ThreadParam &tp)
bool waitforevent(UINT32 timems, const ThreadParam &tp, const std::wstring &origin) bool waitforevent(UINT32 timems, const ThreadParam &tp, const std::wstring &origin)
{ {
char eventname[1000]; char eventname[1000];
sprintf(eventname, LUNA_EMBED_notify_event, GetCurrentProcessId(), djb2_n2((const unsigned char *)(origin.c_str()), origin.size() * 2)); sprintf(eventname, LUNA_EMBED_notify_event, GetCurrentProcessId(), simplehash::djb2_n2((const unsigned char *)(origin.c_str()), origin.size() * 2));
auto event = win_event(eventname); auto event = win_event(eventname);
while (timems) while (timems)
{ {

View File

@ -38,59 +38,10 @@ bool InsertEMEHook()
namespace namespace
{ {
// LRU template class, recv two type params: key & value
template <typename Key>
class LRUCache
{
private:
// cache capacity
size_t _capacity = 0;
// list _keys中key的指向位置
std::unordered_map<Key, typename std::list<Key>::iterator> _cache;
std::list<Key> _keys;
public:
// construct function
LRUCache(size_t size) : _capacity(size){};
bool contains(Key key)
{
auto it = _cache.find(key);
if (it == _cache.end())
{
return false;
}; // 返回默认值
_keys.splice(_keys.begin(), _keys, it->second);
return true;
}
void put(Key key)
{
auto it = _cache.find(key);
if (it != _cache.end())
{
_keys.splice(_keys.begin(), _keys, it->second);
return;
}
if (_keys.size() == _capacity)
{
Key oldKey = _keys.back();
_keys.pop_back();
_cache.erase(oldKey);
}
_keys.push_front(key);
_cache[key] = _keys.begin();
}
};
bool takeout() bool takeout()
{ {
//https://vndb.org/v6187 // https://vndb.org/v6187
//みちくさLoitering on the way // みちくさLoitering on the way
trigger_fun = [](LPVOID addr, hook_stack *stack) trigger_fun = [](LPVOID addr, hook_stack *stack)
{ {
@ -108,11 +59,8 @@ public:
hp.filter_fun = [](LPVOID data, size_t *size, HookParam *) hp.filter_fun = [](LPVOID data, size_t *size, HookParam *)
{ {
auto xx = std::string((char *)data, *size); auto xx = std::string((char *)data, *size);
static LRUCache<std::string> last(10); static lru_cache<std::string> last(10);
if (last.contains(xx)) return !last.touch(xx);
return false;
last.put(xx);
return true;
}; };
return NewHook(hp, "takeout"); return NewHook(hp, "takeout");
}; };

View File

@ -1,4 +1,4 @@
#include"LunaSoft.h" #include "LunaSoft.h"
/** jichi 12/27/2014 LunaSoft /** jichi 12/27/2014 LunaSoft
* Sample game: [141226] [LunaSoft] -- /hsn8@46C5EF * Sample game: [141226] [LunaSoft] -- /hsn8@46C5EF
* *
@ -55,7 +55,7 @@
*/ */
// Remove: \n\s* // Remove: \n\s*
// This is dangerous since \n could appear within SJIS // This is dangerous since \n could appear within SJIS
//static bool LunaSoftFilter(LPVOID data, size_t *size, HookParam *) // static bool LunaSoftFilter(LPVOID data, size_t *size, HookParam *)
//{ //{
// size_t len = *size; // size_t len = *size;
// char *str = reinterpret_cast<char *>(data), // char *str = reinterpret_cast<char *>(data),
@ -80,471 +80,450 @@
bool InsertLunaSoftHook() bool InsertLunaSoftHook()
{ {
const BYTE bytes[] = { const BYTE bytes[] = {
0xcc, // 0046c57e cc int3 0xcc, // 0046c57e cc int3
0xcc, // 0046c57f cc int3 0xcc, // 0046c57f cc int3
0x55, // 0046c580 55 push ebp ; jichi: text in arg1 0x55, // 0046c580 55 push ebp ; jichi: text in arg1
0x8b,0xec, // 0046c581 8bec mov ebp,esp 0x8b, 0xec, // 0046c581 8bec mov ebp,esp
0x83,0xec, 0x08, // 0046c583 83ec 08 sub esp,0x8 0x83, 0xec, 0x08, // 0046c583 83ec 08 sub esp,0x8
0x89,0x4d, 0xf8, // 0046c586 894d f8 mov dword ptr ss:[ebp-0x8],ecx 0x89, 0x4d, 0xf8, // 0046c586 894d f8 mov dword ptr ss:[ebp-0x8],ecx
0x8b,0x4d, 0xf8, // 0046c589 8b4d f8 mov ecx,dword ptr ss:[ebp-0x8] 0x8b, 0x4d, 0xf8, // 0046c589 8b4d f8 mov ecx,dword ptr ss:[ebp-0x8]
0x83,0xc1, 0x1c, // 0046c58c 83c1 1c add ecx,0x1c 0x83, 0xc1, 0x1c, // 0046c58c 83c1 1c add ecx,0x1c
0xe8 // 0046c58f e8 2cebf9ff call .0040b0c0 0xe8 // 0046c58f e8 2cebf9ff call .0040b0c0
};
enum
{
addr_offset = 2
}; };
enum { addr_offset = 2 };
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress); ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
//GROWL(addr); // GROWL(addr);
if (!addr) { if (!addr)
{
ConsoleOutput("LunaSoft: pattern not found"); ConsoleOutput("LunaSoft: pattern not found");
return false; return false;
} }
HookParam hp; HookParam hp;
hp.address = addr + addr_offset; hp.address = addr + addr_offset;
hp.offset =get_stack(1); hp.offset = get_stack(1);
hp.type = USING_STRING; hp.type = USING_STRING;
//hp.filter_fun = LunaSoftFilter; // remove \n // hp.filter_fun = LunaSoftFilter; // remove \n
ConsoleOutput("INSERT LunaSoft"); ConsoleOutput("INSERT LunaSoft");
return NewHook(hp, "LunaSoft"); return NewHook(hp, "LunaSoft");
// There are no GDI functions anyway // There are no GDI functions anyway
//ConsoleOutput("LunaSoft: disable GDI hooks"); // ConsoleOutput("LunaSoft: disable GDI hooks");
// //
} }
bool InsertXXkata(){ bool InsertXXkata()
//アイリスフィールド {
// アイリスフィールド
//素晴らしき国家の築き方 // 素晴らしき国家の築き方
//浮遊都市の作り方 // 浮遊都市の作り方
//正しい性奴隷の使い方 // 正しい性奴隷の使い方
//HSNc@0:user32.dll:wsprintfA // HSNc@0:user32.dll:wsprintfA
auto addr = GetProcAddress(GetModuleHandleW(L"user32.dll"),"wsprintfA"); auto addr = GetProcAddress(GetModuleHandleW(L"user32.dll"), "wsprintfA");
if (addr == 0)return false; if (addr == 0)
return false;
HookParam hp; HookParam hp;
hp.address=(uint64_t)addr ; hp.address = (uint64_t)addr;
hp.type=USING_STRING|NO_CONTEXT; hp.type = USING_STRING | NO_CONTEXT;
hp.offset=get_stack(3); hp.offset = get_stack(3);
hp.filter_fun = all_ascii_Filter; hp.filter_fun = all_ascii_Filter;
return NewHook(hp, "XXkata"); return NewHook(hp, "XXkata");
} }
namespace
{ // unnamed
namespace { // unnamed namespace ScenarioHook
namespace ScenarioHook {
namespace Private {
class DataCache // LRU policy, hashtable not used for simplicity
{ {
int capacity_; namespace Private
std::list<std::string> stack_; // priority stack
public:
explicit DataCache(int capacity = 100)
: capacity_(capacity) {} //{ stack_.reserve(capacity); }
bool contains(const std::string &data) const
{ return stack_.end() != std::find(stack_.begin(), stack_.end(), data); }
std::string retain(const std::string &data)
{ {
auto p = std::find(stack_.begin(), stack_.end(), data); lru_cache<std::string> cache_(100);
if (p == stack_.end()) {
if (stack_.size() == capacity_) /**
stack_.pop_back(); * Sample game: , scenario return address: 0x42f6dc
stack_.push_front(data); *
return data; * 0042F6C8 E8 335F0000 CALL lus004.00435600
} else { * 0042F6CD 8945 10 MOV DWORD PTR SS:[EBP+0x10],EAX
if (p != stack_.begin()) * 0042F6D0 8B55 10 MOV EDX,DWORD PTR SS:[EBP+0x10]
stack_.splice(stack_.begin(), stack_, p); * 0042F6D3 52 PUSH EDX
return *p; * 0042F6D4 8B4D EC MOV ECX,DWORD PTR SS:[EBP-0x14]
* 0042F6D7 E8 34850500 CALL lus004.00487C10
* 0042F6DC 8B45 10 MOV EAX,DWORD PTR SS:[EBP+0x10] ; jichi: retaddr
* 0042F6DF 50 PUSH EAX
* 0042F6E0 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+0x8]
* 0042F6E3 E8 785E0000 CALL lus004.00435560
* 0042F6E8 8945 10 MOV DWORD PTR SS:[EBP+0x10],EAX
* 0042F6EB E9 5E010000 JMP lus004.0042F84E
* 0042F6F0 8B4D 10 MOV ECX,DWORD PTR SS:[EBP+0x10]
*/
bool hookBefore(hook_stack *s, void *data1, size_t *len, uintptr_t *role)
{
auto text = (LPCSTR)s->stack[1]; // arg1
if (!text || !*text) // || Util::allAscii(text))
return 0;
std::string oldData = text;
if (cache_.exists(oldData))
return 0;
// 0042F6DC 8B45 10 MOV EAX,DWORD PTR SS:[EBP+0x10] ; jichi: retaddr
// 0042F6DF 50 PUSH EAX
ULONG retaddr = s->stack[0];
*role = Engine::OtherRole;
if (*(DWORD *)retaddr == 0x5010458b)
*role = Engine::ScenarioRole;
write_string_overwrite(data1, len, oldData);
return 1;
} }
void hookafter1(hook_stack *s, void *data1, size_t len)
{
static std::string newData;
newData = std::string((char *)data1, len);
newData = cache_.put(newData).first;
s->stack[1] = (ULONG)newData.c_str(); // arg1
}
} // namespace Private
/**
* Sample game:
*
* Debugging method: Hook to all function that accessing the text
* Until find ones that can get text modified.
*
* This is the first function accessing the text.
* It is used for text size allocation.
*
* 00487C0E CC INT3
* 00487C0F CC INT3
* 00487C10 55 PUSH EBP
* 00487C11 8BEC MOV EBP,ESP
* 00487C13 51 PUSH ECX
* 00487C14 894D FC MOV DWORD PTR SS:[EBP-0x4],ECX
* 00487C17 8B45 FC MOV EAX,DWORD PTR SS:[EBP-0x4]
* 00487C1A 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+0x8]
* 00487C1D 8988 AC020000 MOV DWORD PTR DS:[EAX+0x2AC],ECX
* 00487C23 8B55 FC MOV EDX,DWORD PTR SS:[EBP-0x4]
* 00487C26 D9EE FLDZ
* 00487C28 D99A B0020000 FSTP DWORD PTR DS:[EDX+0x2B0]
* 00487C2E 8B45 FC MOV EAX,DWORD PTR SS:[EBP-0x4]
* 00487C31 8B88 84000000 MOV ECX,DWORD PTR DS:[EAX+0x84]
* 00487C37 81E1 00000F00 AND ECX,0xF0000
* 00487C3D C1E9 10 SHR ECX,0x10
* 00487C40 83F9 02 CMP ECX,0x2
* 00487C43 75 21 JNZ SHORT .00487C66
* 00487C45 8B55 FC MOV EDX,DWORD PTR SS:[EBP-0x4]
* 00487C48 8B82 AC020000 MOV EAX,DWORD PTR DS:[EDX+0x2AC]
* 00487C4E 50 PUSH EAX
* 00487C4F 8B4D FC MOV ECX,DWORD PTR SS:[EBP-0x4]
* 00487C52 8B89 88000000 MOV ECX,DWORD PTR DS:[ECX+0x88]
* 00487C58 E8 0323FAFF CALL .00429F60
* 00487C5D 8B55 FC MOV EDX,DWORD PTR SS:[EBP-0x4]
* 00487C60 8982 B8020000 MOV DWORD PTR DS:[EDX+0x2B8],EAX
* 00487C66 8BE5 MOV ESP,EBP
* 00487C68 5D POP EBP
* 00487C69 C2 0400 RETN 0x4
* 00487C6C CC INT3
* 00487C6D CC INT3
* 00487C6E CC INT3
*
* This is the function where text is being painted.
*
* 0042B1EE CC INT3
* 0042B1EF CC INT3
* 0042B1F0 55 PUSH EBP
* 0042B1F1 8BEC MOV EBP,ESP
* 0042B1F3 81EC 44010000 SUB ESP,0x144
* 0042B1F9 898D E8FEFFFF MOV DWORD PTR SS:[EBP-0x118],ECX
* 0042B1FF 8B85 E8FEFFFF MOV EAX,DWORD PTR SS:[EBP-0x118]
* 0042B205 8378 24 00 CMP DWORD PTR DS:[EAX+0x24],0x0
* 0042B209 75 05 JNZ SHORT lus004.0042B210
* 0042B20B E9 2E070000 JMP lus004.0042B93E
* 0042B210 837D 08 00 CMP DWORD PTR SS:[EBP+0x8],0x0
* 0042B214 75 05 JNZ SHORT lus004.0042B21B
* 0042B216 E9 23070000 JMP lus004.0042B93E
* 0042B21B C785 FCFEFFFF 00>MOV DWORD PTR SS:[EBP-0x104],0x0
* 0042B225 C745 D0 00000000 MOV DWORD PTR SS:[EBP-0x30],0x0
* 0042B22C C785 40FFFFFF 00>MOV DWORD PTR SS:[EBP-0xC0],0x0
* 0042B236 8B4D 14 MOV ECX,DWORD PTR SS:[EBP+0x14]
* 0042B239 83E1 03 AND ECX,0x3
* 0042B23C 83F9 01 CMP ECX,0x1
* 0042B23F 75 07 JNZ SHORT lus004.0042B248
* 0042B241 D9EE FLDZ
* 0042B243 D95D 88 FSTP DWORD PTR SS:[EBP-0x78]
* 0042B246 EB 1B JMP SHORT lus004.0042B263
* 0042B248 8B55 14 MOV EDX,DWORD PTR SS:[EBP+0x14]
* 0042B24B 83E2 03 AND EDX,0x3
* 0042B24E 83FA 02 CMP EDX,0x2
* 0042B251 75 07 JNZ SHORT lus004.0042B25A
* 0042B253 D9E8 FLD1
* 0042B255 D95D 88 FSTP DWORD PTR SS:[EBP-0x78]
* 0042B258 EB 09 JMP SHORT lus004.0042B263
* 0042B25A D905 986A4E00 FLD DWORD PTR DS:[0x4E6A98]
* 0042B260 D95D 88 FSTP DWORD PTR SS:[EBP-0x78]
* 0042B263 8B45 14 MOV EAX,DWORD PTR SS:[EBP+0x14]
* 0042B266 83E0 0C AND EAX,0xC
* 0042B269 83F8 04 CMP EAX,0x4
* 0042B26C 75 07 JNZ SHORT lus004.0042B275
* 0042B26E D9EE FLDZ
* 0042B270 D95D AC FSTP DWORD PTR SS:[EBP-0x54]
* 0042B273 EB 1B JMP SHORT lus004.0042B290
* 0042B275 8B4D 14 MOV ECX,DWORD PTR SS:[EBP+0x14]
* 0042B278 83E1 0C AND ECX,0xC
* 0042B27B 83F9 08 CMP ECX,0x8
* 0042B27E 75 07 JNZ SHORT lus004.0042B287
* 0042B280 D9E8 FLD1
* 0042B282 D95D AC FSTP DWORD PTR SS:[EBP-0x54]
* 0042B285 EB 09 JMP SHORT lus004.0042B290
* 0042B287 D905 986A4E00 FLD DWORD PTR DS:[0x4E6A98]
* 0042B28D D95D AC FSTP DWORD PTR SS:[EBP-0x54]
* 0042B290 8B55 0C MOV EDX,DWORD PTR SS:[EBP+0xC]
* 0042B293 D942 30 FLD DWORD PTR DS:[EDX+0x30]
* 0042B296 D99D 74FFFFFF FSTP DWORD PTR SS:[EBP-0x8C]
* 0042B29C 8B45 0C MOV EAX,DWORD PTR SS:[EBP+0xC]
* 0042B29F D940 34 FLD DWORD PTR DS:[EAX+0x34]
* 0042B2A2 D99D 78FFFFFF FSTP DWORD PTR SS:[EBP-0x88]
* 0042B2A8 8B8D E8FEFFFF MOV ECX,DWORD PTR SS:[EBP-0x118]
* 0042B2AE 8B51 2C MOV EDX,DWORD PTR DS:[ECX+0x2C]
* 0042B2B1 8995 E0FEFFFF MOV DWORD PTR SS:[EBP-0x120],EDX
* 0042B2B7 C785 E4FEFFFF 00>MOV DWORD PTR SS:[EBP-0x11C],0x0
* 0042B2C1 DFAD E0FEFFFF FILD QWORD PTR SS:[EBP-0x120]
* 0042B2C7 DC0D 186A4E00 FMUL QWORD PTR DS:[0x4E6A18]
* 0042B2CD D99D 68FFFFFF FSTP DWORD PTR SS:[EBP-0x98]
* 0042B2D3 D9EE FLDZ
* 0042B2D5 D99D 6CFFFFFF FSTP DWORD PTR SS:[EBP-0x94]
* 0042B2DB D9EE FLDZ
* 0042B2DD D95D D4 FSTP DWORD PTR SS:[EBP-0x2C]
* 0042B2E0 8B85 E8FEFFFF MOV EAX,DWORD PTR SS:[EBP-0x118]
* 0042B2E6 8B48 2C MOV ECX,DWORD PTR DS:[EAX+0x2C]
* 0042B2E9 898D D8FEFFFF MOV DWORD PTR SS:[EBP-0x128],ECX
* 0042B2EF C785 DCFEFFFF 00>MOV DWORD PTR SS:[EBP-0x124],0x0
* 0042B2F9 DFAD D8FEFFFF FILD QWORD PTR SS:[EBP-0x128]
* 0042B2FF D95D D8 FSTP DWORD PTR SS:[EBP-0x28]
* 0042B302 8B55 0C MOV EDX,DWORD PTR SS:[EBP+0xC]
* 0042B305 52 PUSH EDX
* 0042B306 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-0x100]
* 0042B30C 50 PUSH EAX
* 0042B30D E8 3E6FFEFF CALL lus004.00412250
* 0042B312 83C4 04 ADD ESP,0x4
* 0042B315 D9E8 FLD1
* 0042B317 D91C24 FSTP DWORD PTR SS:[ESP]
* 0042B31A 51 PUSH ECX
* 0042B31B D9EE FLDZ
* 0042B31D D91C24 FSTP DWORD PTR SS:[ESP]
* 0042B320 51 PUSH ECX
* 0042B321 D9EE FLDZ
* 0042B323 D91C24 FSTP DWORD PTR SS:[ESP]
* 0042B326 51 PUSH ECX
* 0042B327 D9EE FLDZ
* ...
*
*
* 0012FC68 089E0060
* 0012FC6C 08AD9D00
* 0012FC70 01D66B60
* 0012FC74 00000000
* 0012FC78 0012FDD0
* 0012FC7C 00000000
* 0012FC80 /0012FDD0
* 0012FC84 |0042B43B RETURN to lus004.0042B43B from lus004.00429E50
* 0012FC88 |02C2AB18 ; jichi: text is here
* 0012FC8C |0012FCAC
* 0012FC90 |00000000
* 0012FC94 |0012FCC4
* 0012FC98 |6186B837 RETURN to d3d9.6186B837
* 0012FC9C |0029DFA0
* 0012FCA0 |0012FCAC
* 0012FCA4 |00000000
* 0012FCA8 |00000018
* 0012FCAC |00000000
* 0012FCB0 |00000018
* 0012FCB4 |00000000
* 0012FCB8 |01D66B60
* 0012FCBC |00000000
* 0012FCC0 |00000002
* 0012FCC4 |0012FD24
* 0012FCC8 |6186B774 RETURN to d3d9.6186B774
* 0012FCCC |00000000
* 0012FCD0 |3FA00000
* 0012FCD4 |00000000
* 0012FCD8 |00000000
* 0012FCDC |00000000
* 0012FCE0 |00000000
* 0012FCE4 |3FA00000
* 0012FCE8 |00000000
* 0012FCEC |00000000
* 0012FCF0 |00000000
* 0012FCF4 |00000000
* 0012FCF8 |3F800000
* 0012FCFC |00000000
* 0012FD00 |00000000
* 0012FD04 |00000000
* 0012FD08 |00000000
* 0012FD0C |3F800000
* 0012FD10 |00000000
* 0012FD14 |FF000000
* 0012FD18 |FF000000
* 0012FD1C |FF000000
* 0012FD20 |FF000000
* 0012FD24 |00000000
* 0012FD28 |0043E66F RETURN to lus004.0043E66F
* 0012FD2C |089E0060
* 0012FD30 |00000005
* 0012FD34 |01D670E0
* 0012FD38 |41700000
* 0012FD3C |00000000
* 0012FD40 |00000000
* 0012FD44 |42EC0000
* 0012FD48 |4413C000
* 0012FD4C |089E0060
* 0012FD50 |01CC7504
* 0012FD54 |00000000
* 0012FD58 |00000000
* 0012FD5C |08A3B600
* 0012FD60 |0012FD78
* 0012FD64 |6F5980B8 RETURN to prl_umdd.6F5980B8 from prl_umdd.6F597B05
* 0012FD68 |0029DFA0
* 0012FD6C |00000019
* 0012FD70 |00000008
* 0012FD74 |00000000
* 0012FD78 |089E0060
* 0012FD7C |00000000
* 0012FD80 |00000001
* 0012FD84 |01D1E670
* 0012FD88 |61845418 d3d9.61845418
* 0012FD8C |00000005
* 0012FD90 |00000000
* 0012FD94 |00000000
* 0012FD98 |00000010
* 0012FD9C |00000002
* 0012FDA0 |00000000
* 0012FDA4 |00000000
* 0012FDA8 |41F00000
* 0012FDAC |0012FDC8
* 0012FDB0 |00406E55 RETURN to lus004.00406E55 from lus004.0043EC70
* 0012FDB4 |00000000
* 0012FDB8 |00000001
* 0012FDBC |00000004
* 0012FDC0 |01D66BF0
* 0012FDC4 |01D1E670
* 0012FDC8 |0012FDE0
* 0012FDCC |00486701 RETURN to lus004.00486701 from lus004.00406E20
* 0012FDD0 ]0012FE4C
* 0012FDD4 |004871D7 RETURN to lus004.004871D7 from lus004.0042B1F0
* 0012FDD8 |02C2AB18 ; jichi: text is here
* 0012FDDC |0012FDFC
* 0012FDE0 |FF000000
* 0012FDE4 |00000005
* 0012FDE8 |3FC00000
* 0012FDEC |005039A8 lus004.005039A8
* 0012FDF0 |00252FDD
* 0012FDF4 |00000002
* 0012FDF8 |00000002
* 0012FDFC |3FA00000
* 0012FE00 |00000000
* 0012FE04 |00000000
* 0012FE08 |00000000
* 0012FE0C |00000000
* 0012FE10 |3FA00000
* 0012FE14 |00000000
* 0012FE18 |00000000
* 0012FE1C |00000000
* 0012FE20 |00000000
* 0012FE24 |3F800000
* 0012FE28 |00000000
* 0012FE2C |42EC0000
* 0012FE30 |4413C000
* 0012FE34 |00000000
* 0012FE38 |3F800000
* 0012FE3C |00000005
* 0012FE40 |00000004
* 0012FE44 |029101F0
* 0012FE48 |00000001
* 0012FE4C ]0012FE8C
* 0012FE50 |004851B8 RETURN to lus004.004851B8
* 0012FE54 |029101F0
* 0012FE58 |000000EF
* 0012FE5C |00000000
* 0012FE60 |000000EF
* 0012FE64 |000000EF
* 0012FE68 |000000EF
* 0012FE6C |01CB0B70
* 0012FE70 |FFFFFFFF
* 0012FE74 |00000000
* 0012FE78 |01D70270
* 0012FE7C |00000000
* 0012FE80 |000000EF
* 0012FE84 |000000C1
* 0012FE88 |029101F0
* 0012FE8C ]0012FEA0
* 0012FE90 |004B55FB RETURN to lus004.004B55FB from lus004.00485070
* 0012FE94 |00000000
* 0012FE98 |000000EF
* 0012FE9C |01DB7770 ASCII "XZN"
* 0012FEA0 ]0012FEAC
* 0012FEA4 |004AAD57 RETURN to lus004.004AAD57
* 0012FEA8 |01C70288
* 0012FEAC ]0012FEBC
* 0012FEB0 |004AB09C RETURN to lus004.004AB09C from lus004.004AACD0
* 0012FEB4 |01C70288
* 0012FEB8 |01000000
* 0012FEBC ]0012FEE0
* 0012FEC0 |004AC8F5 RETURN to lus004.004AC8F5 from lus004.004AB080
* 0012FEC4 |00BF0752
* 0012FEC8 |00000113
*/
bool attach(ULONG startAddress, ULONG stopAddress) // attach scenario
{
ULONG addr1, addr2;
{
const uint8_t bytes1[] = {
0x89, 0x88, 0xac, 0x02, 0x00, 0x00, // 00487c1d 8988 ac020000 mov dword ptr ds:[eax+0x2ac],ecx
0x8b, 0x55, 0xfc, // 00487c23 8b55 fc mov edx,dword ptr ss:[ebp-0x4]
0xd9, 0xee // 00487c26 d9ee fldz
};
addr1 = MemDbg::findBytes(bytes1, sizeof(bytes1), startAddress, stopAddress);
if (!addr1)
return false;
addr1 = MemDbg::findEnclosingAlignedFunction(addr1);
if (!addr1)
return false;
// addr1 = 0x00487c10;
}
{
const uint8_t bytes2[] = {
0x83, 0xe0, 0x0c, // 0042b266 83e0 0c and eax,0xc
0x83, 0xf8, 0x04, // 0042b269 83f8 04 cmp eax,0x4
0x75, 0x07, // 0042b26c 75 07 jnz short lus004.0042b275
0xd9, 0xee // 0042b26e d9ee fldz
};
addr2 = MemDbg::findBytes(bytes2, sizeof(bytes2), startAddress, stopAddress);
if (!addr2)
return false;
addr2 = MemDbg::findEnclosingAlignedFunction(addr2);
if (!addr2)
return false;
// addr2 = 0x0042b1f0;
}
HookParam hp;
hp.address = addr1;
hp.hook_before = Private::hookBefore;
hp.hook_after = Private::hookafter1;
hp.type = EMBED_ABLE | EMBED_DYNA_SJIS;
auto succ = NewHook(hp, "EMBEDLUNA");
hp.address = addr2;
succ |= NewHook(hp, "EMBEDLUNA");
return succ;
} }
}; } // namespace ScenarioHook
DataCache cache_; // this is used to make sure that same translation will have the same address
/**
* Sample game: , scenario return address: 0x42f6dc
*
* 0042F6C8 E8 335F0000 CALL lus004.00435600
* 0042F6CD 8945 10 MOV DWORD PTR SS:[EBP+0x10],EAX
* 0042F6D0 8B55 10 MOV EDX,DWORD PTR SS:[EBP+0x10]
* 0042F6D3 52 PUSH EDX
* 0042F6D4 8B4D EC MOV ECX,DWORD PTR SS:[EBP-0x14]
* 0042F6D7 E8 34850500 CALL lus004.00487C10
* 0042F6DC 8B45 10 MOV EAX,DWORD PTR SS:[EBP+0x10] ; jichi: retaddr
* 0042F6DF 50 PUSH EAX
* 0042F6E0 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+0x8]
* 0042F6E3 E8 785E0000 CALL lus004.00435560
* 0042F6E8 8945 10 MOV DWORD PTR SS:[EBP+0x10],EAX
* 0042F6EB E9 5E010000 JMP lus004.0042F84E
* 0042F6F0 8B4D 10 MOV ECX,DWORD PTR SS:[EBP+0x10]
*/
bool hookBefore(hook_stack*s,void* data1, size_t* len,uintptr_t*role)
{
auto text = (LPCSTR)s->stack[1]; // arg1
if (!text || !*text) // || Util::allAscii(text))
return 0;
std::string oldData = text;
if (cache_.contains(oldData))
return 0;
// 0042F6DC 8B45 10 MOV EAX,DWORD PTR SS:[EBP+0x10] ; jichi: retaddr
// 0042F6DF 50 PUSH EAX
ULONG retaddr = s->stack[0];
* role = Engine::OtherRole;
if (*(DWORD *)retaddr == 0x5010458b)
*role = Engine::ScenarioRole;
write_string_overwrite(data1,len,oldData);
return 1;
}
void hookafter1(hook_stack*s,void* data1, size_t len){
static std::string newData;
newData=std::string((char*)data1,len);
newData = cache_.retain(newData);
s->stack[1] = (ULONG)newData.c_str(); // arg1
}
} // namespace Private
/**
* Sample game:
*
* Debugging method: Hook to all function that accessing the text
* Until find ones that can get text modified.
*
* This is the first function accessing the text.
* It is used for text size allocation.
*
* 00487C0E CC INT3
* 00487C0F CC INT3
* 00487C10 55 PUSH EBP
* 00487C11 8BEC MOV EBP,ESP
* 00487C13 51 PUSH ECX
* 00487C14 894D FC MOV DWORD PTR SS:[EBP-0x4],ECX
* 00487C17 8B45 FC MOV EAX,DWORD PTR SS:[EBP-0x4]
* 00487C1A 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+0x8]
* 00487C1D 8988 AC020000 MOV DWORD PTR DS:[EAX+0x2AC],ECX
* 00487C23 8B55 FC MOV EDX,DWORD PTR SS:[EBP-0x4]
* 00487C26 D9EE FLDZ
* 00487C28 D99A B0020000 FSTP DWORD PTR DS:[EDX+0x2B0]
* 00487C2E 8B45 FC MOV EAX,DWORD PTR SS:[EBP-0x4]
* 00487C31 8B88 84000000 MOV ECX,DWORD PTR DS:[EAX+0x84]
* 00487C37 81E1 00000F00 AND ECX,0xF0000
* 00487C3D C1E9 10 SHR ECX,0x10
* 00487C40 83F9 02 CMP ECX,0x2
* 00487C43 75 21 JNZ SHORT .00487C66
* 00487C45 8B55 FC MOV EDX,DWORD PTR SS:[EBP-0x4]
* 00487C48 8B82 AC020000 MOV EAX,DWORD PTR DS:[EDX+0x2AC]
* 00487C4E 50 PUSH EAX
* 00487C4F 8B4D FC MOV ECX,DWORD PTR SS:[EBP-0x4]
* 00487C52 8B89 88000000 MOV ECX,DWORD PTR DS:[ECX+0x88]
* 00487C58 E8 0323FAFF CALL .00429F60
* 00487C5D 8B55 FC MOV EDX,DWORD PTR SS:[EBP-0x4]
* 00487C60 8982 B8020000 MOV DWORD PTR DS:[EDX+0x2B8],EAX
* 00487C66 8BE5 MOV ESP,EBP
* 00487C68 5D POP EBP
* 00487C69 C2 0400 RETN 0x4
* 00487C6C CC INT3
* 00487C6D CC INT3
* 00487C6E CC INT3
*
* This is the function where text is being painted.
*
* 0042B1EE CC INT3
* 0042B1EF CC INT3
* 0042B1F0 55 PUSH EBP
* 0042B1F1 8BEC MOV EBP,ESP
* 0042B1F3 81EC 44010000 SUB ESP,0x144
* 0042B1F9 898D E8FEFFFF MOV DWORD PTR SS:[EBP-0x118],ECX
* 0042B1FF 8B85 E8FEFFFF MOV EAX,DWORD PTR SS:[EBP-0x118]
* 0042B205 8378 24 00 CMP DWORD PTR DS:[EAX+0x24],0x0
* 0042B209 75 05 JNZ SHORT lus004.0042B210
* 0042B20B E9 2E070000 JMP lus004.0042B93E
* 0042B210 837D 08 00 CMP DWORD PTR SS:[EBP+0x8],0x0
* 0042B214 75 05 JNZ SHORT lus004.0042B21B
* 0042B216 E9 23070000 JMP lus004.0042B93E
* 0042B21B C785 FCFEFFFF 00>MOV DWORD PTR SS:[EBP-0x104],0x0
* 0042B225 C745 D0 00000000 MOV DWORD PTR SS:[EBP-0x30],0x0
* 0042B22C C785 40FFFFFF 00>MOV DWORD PTR SS:[EBP-0xC0],0x0
* 0042B236 8B4D 14 MOV ECX,DWORD PTR SS:[EBP+0x14]
* 0042B239 83E1 03 AND ECX,0x3
* 0042B23C 83F9 01 CMP ECX,0x1
* 0042B23F 75 07 JNZ SHORT lus004.0042B248
* 0042B241 D9EE FLDZ
* 0042B243 D95D 88 FSTP DWORD PTR SS:[EBP-0x78]
* 0042B246 EB 1B JMP SHORT lus004.0042B263
* 0042B248 8B55 14 MOV EDX,DWORD PTR SS:[EBP+0x14]
* 0042B24B 83E2 03 AND EDX,0x3
* 0042B24E 83FA 02 CMP EDX,0x2
* 0042B251 75 07 JNZ SHORT lus004.0042B25A
* 0042B253 D9E8 FLD1
* 0042B255 D95D 88 FSTP DWORD PTR SS:[EBP-0x78]
* 0042B258 EB 09 JMP SHORT lus004.0042B263
* 0042B25A D905 986A4E00 FLD DWORD PTR DS:[0x4E6A98]
* 0042B260 D95D 88 FSTP DWORD PTR SS:[EBP-0x78]
* 0042B263 8B45 14 MOV EAX,DWORD PTR SS:[EBP+0x14]
* 0042B266 83E0 0C AND EAX,0xC
* 0042B269 83F8 04 CMP EAX,0x4
* 0042B26C 75 07 JNZ SHORT lus004.0042B275
* 0042B26E D9EE FLDZ
* 0042B270 D95D AC FSTP DWORD PTR SS:[EBP-0x54]
* 0042B273 EB 1B JMP SHORT lus004.0042B290
* 0042B275 8B4D 14 MOV ECX,DWORD PTR SS:[EBP+0x14]
* 0042B278 83E1 0C AND ECX,0xC
* 0042B27B 83F9 08 CMP ECX,0x8
* 0042B27E 75 07 JNZ SHORT lus004.0042B287
* 0042B280 D9E8 FLD1
* 0042B282 D95D AC FSTP DWORD PTR SS:[EBP-0x54]
* 0042B285 EB 09 JMP SHORT lus004.0042B290
* 0042B287 D905 986A4E00 FLD DWORD PTR DS:[0x4E6A98]
* 0042B28D D95D AC FSTP DWORD PTR SS:[EBP-0x54]
* 0042B290 8B55 0C MOV EDX,DWORD PTR SS:[EBP+0xC]
* 0042B293 D942 30 FLD DWORD PTR DS:[EDX+0x30]
* 0042B296 D99D 74FFFFFF FSTP DWORD PTR SS:[EBP-0x8C]
* 0042B29C 8B45 0C MOV EAX,DWORD PTR SS:[EBP+0xC]
* 0042B29F D940 34 FLD DWORD PTR DS:[EAX+0x34]
* 0042B2A2 D99D 78FFFFFF FSTP DWORD PTR SS:[EBP-0x88]
* 0042B2A8 8B8D E8FEFFFF MOV ECX,DWORD PTR SS:[EBP-0x118]
* 0042B2AE 8B51 2C MOV EDX,DWORD PTR DS:[ECX+0x2C]
* 0042B2B1 8995 E0FEFFFF MOV DWORD PTR SS:[EBP-0x120],EDX
* 0042B2B7 C785 E4FEFFFF 00>MOV DWORD PTR SS:[EBP-0x11C],0x0
* 0042B2C1 DFAD E0FEFFFF FILD QWORD PTR SS:[EBP-0x120]
* 0042B2C7 DC0D 186A4E00 FMUL QWORD PTR DS:[0x4E6A18]
* 0042B2CD D99D 68FFFFFF FSTP DWORD PTR SS:[EBP-0x98]
* 0042B2D3 D9EE FLDZ
* 0042B2D5 D99D 6CFFFFFF FSTP DWORD PTR SS:[EBP-0x94]
* 0042B2DB D9EE FLDZ
* 0042B2DD D95D D4 FSTP DWORD PTR SS:[EBP-0x2C]
* 0042B2E0 8B85 E8FEFFFF MOV EAX,DWORD PTR SS:[EBP-0x118]
* 0042B2E6 8B48 2C MOV ECX,DWORD PTR DS:[EAX+0x2C]
* 0042B2E9 898D D8FEFFFF MOV DWORD PTR SS:[EBP-0x128],ECX
* 0042B2EF C785 DCFEFFFF 00>MOV DWORD PTR SS:[EBP-0x124],0x0
* 0042B2F9 DFAD D8FEFFFF FILD QWORD PTR SS:[EBP-0x128]
* 0042B2FF D95D D8 FSTP DWORD PTR SS:[EBP-0x28]
* 0042B302 8B55 0C MOV EDX,DWORD PTR SS:[EBP+0xC]
* 0042B305 52 PUSH EDX
* 0042B306 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-0x100]
* 0042B30C 50 PUSH EAX
* 0042B30D E8 3E6FFEFF CALL lus004.00412250
* 0042B312 83C4 04 ADD ESP,0x4
* 0042B315 D9E8 FLD1
* 0042B317 D91C24 FSTP DWORD PTR SS:[ESP]
* 0042B31A 51 PUSH ECX
* 0042B31B D9EE FLDZ
* 0042B31D D91C24 FSTP DWORD PTR SS:[ESP]
* 0042B320 51 PUSH ECX
* 0042B321 D9EE FLDZ
* 0042B323 D91C24 FSTP DWORD PTR SS:[ESP]
* 0042B326 51 PUSH ECX
* 0042B327 D9EE FLDZ
* ...
*
*
* 0012FC68 089E0060
* 0012FC6C 08AD9D00
* 0012FC70 01D66B60
* 0012FC74 00000000
* 0012FC78 0012FDD0
* 0012FC7C 00000000
* 0012FC80 /0012FDD0
* 0012FC84 |0042B43B RETURN to lus004.0042B43B from lus004.00429E50
* 0012FC88 |02C2AB18 ; jichi: text is here
* 0012FC8C |0012FCAC
* 0012FC90 |00000000
* 0012FC94 |0012FCC4
* 0012FC98 |6186B837 RETURN to d3d9.6186B837
* 0012FC9C |0029DFA0
* 0012FCA0 |0012FCAC
* 0012FCA4 |00000000
* 0012FCA8 |00000018
* 0012FCAC |00000000
* 0012FCB0 |00000018
* 0012FCB4 |00000000
* 0012FCB8 |01D66B60
* 0012FCBC |00000000
* 0012FCC0 |00000002
* 0012FCC4 |0012FD24
* 0012FCC8 |6186B774 RETURN to d3d9.6186B774
* 0012FCCC |00000000
* 0012FCD0 |3FA00000
* 0012FCD4 |00000000
* 0012FCD8 |00000000
* 0012FCDC |00000000
* 0012FCE0 |00000000
* 0012FCE4 |3FA00000
* 0012FCE8 |00000000
* 0012FCEC |00000000
* 0012FCF0 |00000000
* 0012FCF4 |00000000
* 0012FCF8 |3F800000
* 0012FCFC |00000000
* 0012FD00 |00000000
* 0012FD04 |00000000
* 0012FD08 |00000000
* 0012FD0C |3F800000
* 0012FD10 |00000000
* 0012FD14 |FF000000
* 0012FD18 |FF000000
* 0012FD1C |FF000000
* 0012FD20 |FF000000
* 0012FD24 |00000000
* 0012FD28 |0043E66F RETURN to lus004.0043E66F
* 0012FD2C |089E0060
* 0012FD30 |00000005
* 0012FD34 |01D670E0
* 0012FD38 |41700000
* 0012FD3C |00000000
* 0012FD40 |00000000
* 0012FD44 |42EC0000
* 0012FD48 |4413C000
* 0012FD4C |089E0060
* 0012FD50 |01CC7504
* 0012FD54 |00000000
* 0012FD58 |00000000
* 0012FD5C |08A3B600
* 0012FD60 |0012FD78
* 0012FD64 |6F5980B8 RETURN to prl_umdd.6F5980B8 from prl_umdd.6F597B05
* 0012FD68 |0029DFA0
* 0012FD6C |00000019
* 0012FD70 |00000008
* 0012FD74 |00000000
* 0012FD78 |089E0060
* 0012FD7C |00000000
* 0012FD80 |00000001
* 0012FD84 |01D1E670
* 0012FD88 |61845418 d3d9.61845418
* 0012FD8C |00000005
* 0012FD90 |00000000
* 0012FD94 |00000000
* 0012FD98 |00000010
* 0012FD9C |00000002
* 0012FDA0 |00000000
* 0012FDA4 |00000000
* 0012FDA8 |41F00000
* 0012FDAC |0012FDC8
* 0012FDB0 |00406E55 RETURN to lus004.00406E55 from lus004.0043EC70
* 0012FDB4 |00000000
* 0012FDB8 |00000001
* 0012FDBC |00000004
* 0012FDC0 |01D66BF0
* 0012FDC4 |01D1E670
* 0012FDC8 |0012FDE0
* 0012FDCC |00486701 RETURN to lus004.00486701 from lus004.00406E20
* 0012FDD0 ]0012FE4C
* 0012FDD4 |004871D7 RETURN to lus004.004871D7 from lus004.0042B1F0
* 0012FDD8 |02C2AB18 ; jichi: text is here
* 0012FDDC |0012FDFC
* 0012FDE0 |FF000000
* 0012FDE4 |00000005
* 0012FDE8 |3FC00000
* 0012FDEC |005039A8 lus004.005039A8
* 0012FDF0 |00252FDD
* 0012FDF4 |00000002
* 0012FDF8 |00000002
* 0012FDFC |3FA00000
* 0012FE00 |00000000
* 0012FE04 |00000000
* 0012FE08 |00000000
* 0012FE0C |00000000
* 0012FE10 |3FA00000
* 0012FE14 |00000000
* 0012FE18 |00000000
* 0012FE1C |00000000
* 0012FE20 |00000000
* 0012FE24 |3F800000
* 0012FE28 |00000000
* 0012FE2C |42EC0000
* 0012FE30 |4413C000
* 0012FE34 |00000000
* 0012FE38 |3F800000
* 0012FE3C |00000005
* 0012FE40 |00000004
* 0012FE44 |029101F0
* 0012FE48 |00000001
* 0012FE4C ]0012FE8C
* 0012FE50 |004851B8 RETURN to lus004.004851B8
* 0012FE54 |029101F0
* 0012FE58 |000000EF
* 0012FE5C |00000000
* 0012FE60 |000000EF
* 0012FE64 |000000EF
* 0012FE68 |000000EF
* 0012FE6C |01CB0B70
* 0012FE70 |FFFFFFFF
* 0012FE74 |00000000
* 0012FE78 |01D70270
* 0012FE7C |00000000
* 0012FE80 |000000EF
* 0012FE84 |000000C1
* 0012FE88 |029101F0
* 0012FE8C ]0012FEA0
* 0012FE90 |004B55FB RETURN to lus004.004B55FB from lus004.00485070
* 0012FE94 |00000000
* 0012FE98 |000000EF
* 0012FE9C |01DB7770 ASCII "XZN"
* 0012FEA0 ]0012FEAC
* 0012FEA4 |004AAD57 RETURN to lus004.004AAD57
* 0012FEA8 |01C70288
* 0012FEAC ]0012FEBC
* 0012FEB0 |004AB09C RETURN to lus004.004AB09C from lus004.004AACD0
* 0012FEB4 |01C70288
* 0012FEB8 |01000000
* 0012FEBC ]0012FEE0
* 0012FEC0 |004AC8F5 RETURN to lus004.004AC8F5 from lus004.004AB080
* 0012FEC4 |00BF0752
* 0012FEC8 |00000113
*/
bool attach(ULONG startAddress, ULONG stopAddress) // attach scenario
{
ULONG addr1, addr2;
{
const uint8_t bytes1[] = {
0x89,0x88, 0xac,0x02,0x00,0x00, // 00487c1d 8988 ac020000 mov dword ptr ds:[eax+0x2ac],ecx
0x8b,0x55, 0xfc, // 00487c23 8b55 fc mov edx,dword ptr ss:[ebp-0x4]
0xd9,0xee // 00487c26 d9ee fldz
};
addr1 = MemDbg::findBytes(bytes1, sizeof(bytes1), startAddress, stopAddress);
if (!addr1)
return false;
addr1 = MemDbg::findEnclosingAlignedFunction(addr1);
if (!addr1)
return false;
//addr1 = 0x00487c10;
}
{
const uint8_t bytes2[] = {
0x83,0xe0, 0x0c, // 0042b266 83e0 0c and eax,0xc
0x83,0xf8, 0x04, // 0042b269 83f8 04 cmp eax,0x4
0x75, 0x07, // 0042b26c 75 07 jnz short lus004.0042b275
0xd9,0xee // 0042b26e d9ee fldz
};
addr2 = MemDbg::findBytes(bytes2, sizeof(bytes2), startAddress, stopAddress);
if (!addr2)
return false;
addr2 = MemDbg::findEnclosingAlignedFunction(addr2);
if (!addr2)
return false;
//addr2 = 0x0042b1f0;
}
HookParam hp;
hp.address=addr1;
hp.hook_before=Private::hookBefore;
hp.hook_after=Private::hookafter1;
hp.type=EMBED_ABLE|EMBED_DYNA_SJIS;
auto succ=NewHook(hp,"EMBEDLUNA");
hp.address=addr2;
succ|=NewHook(hp,"EMBEDLUNA");
return succ;
}
} // namespace ScenarioHook
} // unnamed namespace } // unnamed namespace
bool LunaSoft::attach_function()
{
bool b1 = InsertLunaSoftHook();
bool LunaSoft::attach_function() { bool b2 = InsertXXkata();
bool embed = ScenarioHook::attach(processStartAddress, processStopAddress);
bool b1= InsertLunaSoftHook(); return b1 || b2 || embed;
bool b2=InsertXXkata();
bool embed=ScenarioHook::attach(processStartAddress, processStopAddress);
return b1||b2||embed;
} }

View File

@ -954,25 +954,7 @@ struct TextArgument // first argument of the scenario hook
&& !::strstr(text, "\x81\x5e"); // "" && !::strstr(text, "\x81\x5e"); // ""
} }
}; };
enum : UINT64 { djb2_hash0 = 5381 };
inline UINT64 djb2(const UINT8 *str, UINT64 hash = djb2_hash0)
{
UINT8 c;
while ((c = *str++))
hash = ((hash << 5) + hash) + c; // hash * 33 + c
return hash;
}inline UINT64 djb2_n2(const char* str, size_t len, UINT64 hash = djb2_hash0)
{
while (len--)
hash = ((hash << 5) + hash) + (*str++); // hash * 33 + c
return hash;
}
inline UINT64 hashByteArraySTD(const std::string& b, UINT64 h = djb2_hash0)
{
return djb2_n2(b.c_str(), b.size(), h);
}
inline UINT64 hashCharArray(const void *lp)
{ return djb2(reinterpret_cast<const UINT8 *>(lp)); }
namespace ScenarioHook { namespace ScenarioHook {
namespace Private { namespace Private {
@ -1049,7 +1031,7 @@ namespace Private {
arg->size = data_.size() + 1; arg->size = data_.size() + 1;
arg->capacity = arg->size; arg->capacity = arg->size;
hashes_.insert(hashCharArray(arg->text)); hashes_.insert(simplehash::hashCharArray(arg->text));
} }
bool hookBefore(hook_stack*s,void* data, size_t* len1,uintptr_t*role) bool hookBefore(hook_stack*s,void* data, size_t* len1,uintptr_t*role)
{ {
@ -1072,7 +1054,7 @@ namespace Private {
return false; return false;
auto arg = (TextArgument *)s->stack[0]; // arg1 auto arg = (TextArgument *)s->stack[0]; // arg1
if (!arg || !arg->isValid() if (!arg || !arg->isValid()
|| hashes_.find(hashCharArray(arg->text)) != hashes_.end()) || hashes_.find(simplehash::hashCharArray(arg->text)) != hashes_.end())
return false; return false;
if (arg->size < 0xf && split > 0 && !isOtherText(arg->text)) if (arg->size < 0xf && split > 0 && !isOtherText(arg->text))
return false; return false;

File diff suppressed because it is too large Load Diff

View File

@ -1772,6 +1772,48 @@ namespace
return write_string_overwrite(data, len, s); return write_string_overwrite(data, len, s);
} }
bool F010005F00E036000_1(void *data, size_t *len, HookParam *hp)
{
static lru_cache<std::string> cache(5);
static std::string last;
auto s = std::string((char *)data, *len);
if (endWith(last, s))
{
last = s;
return false;
}
if (cache.touch(s))
{
last = s;
return false;
}
last = s;
return write_string_overwrite(data, len, s);
}
bool F010005F00E036000(void *data, size_t *len, HookParam *hp)
{
if (!F010005F00E036000_1(data, len, hp))
return false;
static std::string last;
auto s = std::string((char *)data, *len);
auto parse = [](std::string &s)
{
strReplace(s, u8"", u8"");
strReplace(s, u8"", u8"");
strReplace(s, u8"", u8"");
return s;
};
if (startWith(s, last))
{
write_string_overwrite(data, len, parse(s.substr(last.size(), s.size() - last.size())));
last = s;
return true;
}
last = s;
return write_string_overwrite(data, len, parse(s));
}
bool F0100FC2019346000(void *data, size_t *len, HookParam *hp) bool F0100FC2019346000(void *data, size_t *len, HookParam *hp)
{ {
StringFilter((char *)data, len, "#n", 2); StringFilter((char *)data, len, "#n", 2);
@ -3143,6 +3185,8 @@ namespace
{0x801f67c0, {CODEC_UTF32, 1, 0, 0, F01007FD00DB20000, "01007FD00DB20000", "1.0.0"}}, {0x801f67c0, {CODEC_UTF32, 1, 0, 0, F01007FD00DB20000, "01007FD00DB20000", "1.0.0"}},
{0x802a76c0, {CODEC_UTF32, 0, 0, 0, F01007FD00DB20000, "01007FD00DB20000", "1.0.0"}}, {0x802a76c0, {CODEC_UTF32, 0, 0, 0, F01007FD00DB20000, "01007FD00DB20000", "1.0.0"}},
{0x8031fc80, {CODEC_UTF32, 1, 0, 0, F01007FD00DB20000, "01007FD00DB20000", "1.0.0"}}, {0x8031fc80, {CODEC_UTF32, 1, 0, 0, F01007FD00DB20000, "01007FD00DB20000", "1.0.0"}},
// 真 流行り神1・2パック
{0x80072720, {CODEC_UTF8, 1, 0, 0, F010005F00E036000, "010005F00E036000", "1.0.0"}},
// 真流行り神3 // 真流行り神3
{0x80082F70, {0, 0xb, 0, TF0100AA1013B96000, 0, "0100AA1013B96000", nullptr}}, //"1.0.0", "1.0.1" {0x80082F70, {0, 0xb, 0, TF0100AA1013B96000, 0, "0100AA1013B96000", nullptr}}, //"1.0.0", "1.0.1"

View File

@ -164,15 +164,6 @@ C_LUNA_API void Luna_useembed(DWORD pid, uint64_t address, uint64_t ctx1, uint64
} }
} }
inline UINT64 djb2_n2(const unsigned char *str, size_t len, UINT64 hash = 5381)
{
int i = 0;
while (len--)
{
hash = ((hash << 5) + hash) + (*str++); // hash * 33 + c
}
return hash;
}
C_LUNA_API void Luna_embedcallback(DWORD pid, LPCWSTR text, LPCWSTR trans) C_LUNA_API void Luna_embedcallback(DWORD pid, LPCWSTR text, LPCWSTR trans)
{ {
auto sm = Host::GetEmbedSharedMem(pid); auto sm = Host::GetEmbedSharedMem(pid);
@ -180,7 +171,7 @@ C_LUNA_API void Luna_embedcallback(DWORD pid, LPCWSTR text, LPCWSTR trans)
return; return;
wcsncpy(sm->text, trans, ARRAYSIZE(sm->text)); wcsncpy(sm->text, trans, ARRAYSIZE(sm->text));
char eventname[1000]; char eventname[1000];
sprintf(eventname, LUNA_EMBED_notify_event, pid, djb2_n2((const unsigned char *)(text), wcslen(text) * 2)); sprintf(eventname, LUNA_EMBED_notify_event, pid, simplehash::djb2_n2((const unsigned char *)(text), wcslen(text) * 2));
win_event event1(eventname); win_event event1(eventname);
event1.signal(true); event1.signal(true);
} }

89
include/lrucache.hpp Normal file
View File

@ -0,0 +1,89 @@
/*
* File: lrucache.hpp
* Author: Alexander Ponomarev
*
* Created on June 20, 2013, 5:09 PM
*/
#ifndef _LRUCACHE_HPP_INCLUDED_
#define _LRUCACHE_HPP_INCLUDED_
#include <unordered_map>
#include <list>
#include <cstddef>
#include <stdexcept>
template <typename key_t, typename value_t = int>
class lru_cache
{
public:
typedef typename std::pair<key_t, value_t> key_value_pair_t;
typedef typename std::list<key_value_pair_t>::iterator list_iterator_t;
lru_cache(size_t max_size) : _max_size(max_size)
{
}
const key_value_pair_t &put(const key_t &key, const value_t &&value = {})
{
auto it = _cache_items_map.find(key);
_cache_items_list.emplace_front(key_value_pair_t(key, value));
if (it != _cache_items_map.end())
{
_cache_items_list.erase(it->second);
_cache_items_map.erase(it);
}
_cache_items_map[key] = _cache_items_list.begin();
if (_cache_items_map.size() > _max_size)
{
auto last = _cache_items_list.end();
last--;
_cache_items_map.erase(last->first);
_cache_items_list.pop_back();
}
return *_cache_items_list.begin();
}
const value_t &get(const key_t &key)
{
auto it = _cache_items_map.find(key);
if (it == _cache_items_map.end())
{
throw std::range_error("There is no such key in cache");
}
else
{
_cache_items_list.splice(_cache_items_list.begin(), _cache_items_list, it->second);
return it->second->second;
}
}
bool exists(const key_t &key) const
{
return _cache_items_map.find(key) != _cache_items_map.end();
}
bool touch(const key_t &key)
{
try
{
auto _ = get(key);
return true;
}
catch (...)
{
put(key);
return false;
}
}
size_t size() const
{
return _cache_items_map.size();
}
private:
std::list<key_value_pair_t> _cache_items_list;
std::unordered_map<key_t, list_iterator_t> _cache_items_map;
size_t _max_size;
};
#endif /* _LRUCACHE_HPP_INCLUDED_ */

View File

@ -42,3 +42,4 @@
#include "hookcode.h" #include "hookcode.h"
#include "texthook.h" #include "texthook.h"
#include "winevent.hpp" #include "winevent.hpp"
#include "lrucache.hpp"

View File

@ -51,7 +51,7 @@ inline std::vector<StringT> strSplit_impl(const StringT &s, const StringT &delim
template <class StringT> template <class StringT>
inline bool endWith_impl(const StringT &s, const StringT &s2) inline bool endWith_impl(const StringT &s, const StringT &s2)
{ {
if ((s.size() >= s2.size()) && (s.substr(s.size() - s2.size(), s2.size()) == s2)) if (s2.size() && (s.size() >= s2.size()) && (s.substr(s.size() - s2.size(), s2.size()) == s2))
{ {
return true; return true;
} }
@ -61,7 +61,7 @@ inline bool endWith_impl(const StringT &s, const StringT &s2)
template <class StringT> template <class StringT>
inline bool startWith_impl(const StringT &s, const StringT &s2) inline bool startWith_impl(const StringT &s, const StringT &s2)
{ {
if ((s.size() >= s2.size()) && (s.substr(0, s2.size()) == s2)) if (s2.size() && (s.size() >= s2.size()) && (s.substr(0, s2.size()) == s2))
{ {
return true; return true;
} }
@ -215,7 +215,7 @@ size_t u32strlen(uint32_t *data)
return s; return s;
} }
std::string wcasta(const std::wstring& x) std::string wcasta(const std::wstring &x)
{ {
std::string xx; std::string xx;
for (auto c : x) for (auto c : x)
@ -223,7 +223,7 @@ std::string wcasta(const std::wstring& x)
return xx; return xx;
} }
std::wstring acastw(const std::string& x) std::wstring acastw(const std::string &x)
{ {
std::wstring xx; std::wstring xx;
for (auto c : x) for (auto c : x)

View File

@ -142,3 +142,31 @@ struct SafeFptr
return ptr(std::forward<Args>(args)...); return ptr(std::forward<Args>(args)...);
} }
}; };
namespace simplehash
{
enum : UINT64
{
djb2_hash0 = 5381
};
inline UINT64 djb2(const UINT8 *str, UINT64 hash = djb2_hash0)
{
UINT8 c;
while ((c = *str++))
hash = ((hash << 5) + hash) + c; // hash * 33 + c
return hash;
}
inline UINT64 djb2_n2(const unsigned char *str, size_t len, UINT64 hash = djb2_hash0)
{
while (len--)
hash = ((hash << 5) + hash) + (*str++); // hash * 33 + c
return hash;
}
inline UINT64 hashByteArraySTD(const std::string &b, UINT64 h = djb2_hash0)
{
return djb2_n2((const unsigned char *)b.c_str(), b.size(), h);
}
inline UINT64 hashCharArray(const void *lp)
{
return djb2(reinterpret_cast<const UINT8 *>(lp));
}
}