mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-10-22 23:18:16 +08:00
dmmdrc
This commit is contained in:
parent
2219e3a7e1
commit
ade8f24169
@ -1,86 +1,156 @@
|
|||||||
#include"Nitroplus.h"
|
#include "Nitroplus.h"
|
||||||
|
|
||||||
|
|
||||||
bool InsertNitroplusHook()
|
bool InsertNitroplusHook()
|
||||||
{
|
{
|
||||||
const BYTE bytes[] = {0xb0, 0x74, 0x53};
|
const BYTE bytes[] = {0xb0, 0x74, 0x53};
|
||||||
DWORD addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
DWORD addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
||||||
if (!addr) {
|
if (!addr)
|
||||||
ConsoleOutput("Nitroplus: pattern not exist");
|
{
|
||||||
return false;
|
ConsoleOutput("Nitroplus: pattern not exist");
|
||||||
}
|
return false;
|
||||||
enum : WORD { sub_esp = 0xec83 }; // caller pattern: sub esp = 0x83,0xec
|
}
|
||||||
BYTE b = *(BYTE *)(addr + 3) & 3;
|
enum : WORD
|
||||||
while (*(WORD *)addr != sub_esp)
|
{
|
||||||
addr--;
|
sub_esp = 0xec83
|
||||||
HookParam hp;
|
}; // caller pattern: sub esp = 0x83,0xec
|
||||||
hp.address = addr;
|
BYTE b = *(BYTE *)(addr + 3) & 3;
|
||||||
hp.offset = -0x14+ (b << 2);
|
while (*(WORD *)addr != sub_esp)
|
||||||
hp.type = CODEC_ANSI_BE;
|
addr--;
|
||||||
ConsoleOutput("INSERT Nitroplus");
|
HookParam hp;
|
||||||
return NewHook(hp, "Nitroplus");
|
hp.address = addr;
|
||||||
//RegisterEngineType(ENGINE_Nitroplus);
|
hp.offset = -0x14 + (b << 2);
|
||||||
|
hp.type = CODEC_ANSI_BE;
|
||||||
|
ConsoleOutput("INSERT Nitroplus");
|
||||||
|
return NewHook(hp, "Nitroplus");
|
||||||
|
// RegisterEngineType(ENGINE_Nitroplus);
|
||||||
}
|
}
|
||||||
bool InsertNitroplus2Hook() {
|
bool InsertNitroplus2Hook()
|
||||||
|
{
|
||||||
/*
|
|
||||||
* Sample games:
|
/*
|
||||||
* https://vndb.org/v428
|
* Sample games:
|
||||||
*/
|
* https://vndb.org/v428
|
||||||
|
*/
|
||||||
BYTE bytes[] = {
|
BYTE bytes[] = {
|
||||||
0x8D, 0xB4, 0x29, XX4, // lea esi,[ecx+ebp+0000415C]
|
0x8D, 0xB4, 0x29, XX4, // lea esi,[ecx+ebp+0000415C]
|
||||||
0x74, 0x20, // je Django.exe+6126E
|
0x74, 0x20, // je Django.exe+6126E
|
||||||
0x8D, 0xBC, 0xBD, XX4, // lea edi,[ebp+edi*4+0006410C]
|
0x8D, 0xBC, 0xBD, XX4, // lea edi,[ebp+edi*4+0006410C]
|
||||||
0x8B, 0x56, 0xB0, // mov edx,[esi-50]
|
0x8B, 0x56, 0xB0, // mov edx,[esi-50]
|
||||||
0xE8, XX4 // call Django.exe+51150 << hook here
|
0xE8, XX4 // call Django.exe+51150 << hook here
|
||||||
|
};
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
addr_offset = sizeof(bytes) - 5
|
||||||
};
|
};
|
||||||
enum { addr_offset = sizeof(bytes) - 5 };
|
|
||||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
|
||||||
if (!addr) {
|
if (!addr)
|
||||||
|
{
|
||||||
ConsoleOutput("Nitroplus2: pattern not found");
|
ConsoleOutput("Nitroplus2: pattern not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
hp.address = addr + addr_offset;
|
hp.address = addr + addr_offset;
|
||||||
hp.offset=get_reg(regs::edx);
|
hp.offset = get_reg(regs::edx);
|
||||||
hp.type = CODEC_ANSI_BE;
|
hp.type = CODEC_ANSI_BE;
|
||||||
return NewHook(hp, "Nitroplus2");
|
return NewHook(hp, "Nitroplus2");
|
||||||
}
|
}
|
||||||
bool Nitroplus::attach_function() {
|
namespace
|
||||||
|
{
|
||||||
return InsertNitroplusHook()||InsertNitroplus2Hook();
|
// DRAMAtical Murder re:connect 普及版
|
||||||
}
|
// https://vndb.org/v10895
|
||||||
|
bool dmmdrc()
|
||||||
|
{
|
||||||
|
// BYTE sig[]={
|
||||||
|
// 0xc7,0x04,0x24,0x24,0x53,0x59,0x53,//$SYS
|
||||||
|
// 0xc7,0x44,0x24,0x04,0x54,0x45,0x4d,0x5f,//TEM_
|
||||||
|
// 0xc7,0x44,0x24,0x08,0x6c,0x61,0x73,0x74,//last
|
||||||
|
// 0xc7,0x44,0x24,0x0c,0x5f,0x74,0x65,0x78,//_tex
|
||||||
|
// };
|
||||||
|
BYTE sig[] = {
|
||||||
|
0x8d, 0x89, XX4,
|
||||||
|
0x8b, 0xc2,
|
||||||
|
0xc1, 0xe8, 0x08,
|
||||||
|
0x88, 0x01,
|
||||||
|
0x88, 0x51, 0x01,
|
||||||
|
0xc6, 0x41, 0x02, 0x00};
|
||||||
|
ULONG addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
|
||||||
|
if (!addr)
|
||||||
|
return false;
|
||||||
|
HookParam hp;
|
||||||
|
hp.address = *(DWORD *)(addr + 2);
|
||||||
|
hp.type = DIRECT_READ;
|
||||||
|
auto succ = NewHook(hp, "dmmdrc");
|
||||||
|
|
||||||
|
BYTE sig2[] = {
|
||||||
|
//clang-format off
|
||||||
|
0x68, 0x00, 0x02, 0x00, 0x00,
|
||||||
|
0xba, XX4,
|
||||||
|
0xe8, XX4,
|
||||||
|
//clang-format on
|
||||||
|
};
|
||||||
|
memcpy(sig2 + 6, (void *)(addr + 2), 4);
|
||||||
|
addr = MemDbg::findBytes(sig2, sizeof(sig2), addr, addr + 0x100);
|
||||||
|
if (addr)
|
||||||
|
{
|
||||||
|
HookParam hp;
|
||||||
|
hp.address = addr + sizeof(sig2);
|
||||||
|
hp.type = USING_STRING;
|
||||||
|
hp.user_value = 0;
|
||||||
|
hp.text_fun = [](hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
|
||||||
|
{
|
||||||
|
*data = stack->edx;
|
||||||
|
auto l = strlen((char *)*data);
|
||||||
|
if (hp->user_value > l)
|
||||||
|
hp->user_value = 0;
|
||||||
|
*data += hp->user_value;
|
||||||
|
*len = l - hp->user_value;
|
||||||
|
hp->user_value = l;
|
||||||
|
};
|
||||||
|
succ |= NewHook(hp, "dmmdrc2");
|
||||||
|
}
|
||||||
|
return succ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool Nitroplus::attach_function()
|
||||||
|
{
|
||||||
|
|
||||||
|
return InsertNitroplusHook() || InsertNitroplus2Hook() || dmmdrc();
|
||||||
|
}
|
||||||
|
|
||||||
bool NitroplusSysFilter(LPVOID data, size_t *size, HookParam *)
|
bool NitroplusSysFilter(LPVOID data, size_t *size, HookParam *)
|
||||||
{
|
{
|
||||||
auto text = reinterpret_cast<LPSTR>(data);
|
auto text = reinterpret_cast<LPSTR>(data);
|
||||||
auto len = reinterpret_cast<size_t *>(size);
|
auto len = reinterpret_cast<size_t *>(size);
|
||||||
|
|
||||||
if (*len <= 2) return false;
|
if (*len <= 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
StringFilter(text, len, "\x81@", 2);
|
StringFilter(text, len, "\x81@", 2);
|
||||||
CharReplacer(text, len, '\r', ' ');
|
CharReplacer(text, len, '\r', ' ');
|
||||||
if (cpp_strnstr(text, "<", *len)) {
|
if (cpp_strnstr(text, "<", *len))
|
||||||
StringFilterBetween(text, len, "<", 1, ">", 1);
|
{
|
||||||
}
|
StringFilterBetween(text, len, "<", 1, ">", 1);
|
||||||
while (*len>1 && ::isspace(*text)) {
|
}
|
||||||
::memmove(text, text+1, --(*len));
|
while (*len > 1 && ::isspace(*text))
|
||||||
}
|
{
|
||||||
|
::memmove(text, text + 1, --(*len));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InsertNitroplusSysHook() {
|
bool InsertNitroplusSysHook()
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sample games:
|
* Sample games:
|
||||||
* https://vndb.org/r76679
|
* https://vndb.org/r76679
|
||||||
*/
|
*/
|
||||||
const BYTE bytes[] = {
|
const BYTE bytes[] = {
|
||||||
0x0F, 0x84, XX4, // je system.dll+5B8CA <- hook here
|
0x0F, 0x84, XX4, // je system.dll+5B8CA <- hook here
|
||||||
0xEB, 0x04, // jmp system.dll+5A791
|
0xEB, 0x04, // jmp system.dll+5A791
|
||||||
0x8B, 0x44, 0x24, 0x20, // mov eax,[esp+20]
|
0x8B, 0x44, 0x24, 0x20, // mov eax,[esp+20]
|
||||||
0x8B, 0x4C, 0x24, 0x24 // mov ecx,[esp+24]
|
0x8B, 0x4C, 0x24, 0x24 // mov ecx,[esp+24]
|
||||||
};
|
};
|
||||||
|
|
||||||
HMODULE module = GetModuleHandleW(L"system.dll");
|
HMODULE module = GetModuleHandleW(L"system.dll");
|
||||||
@ -91,11 +161,12 @@ bool InsertNitroplusSysHook() {
|
|||||||
|
|
||||||
HookParam hp;
|
HookParam hp;
|
||||||
hp.address = addr;
|
hp.address = addr;
|
||||||
hp.offset=get_reg(regs::eax);
|
hp.offset = get_reg(regs::eax);
|
||||||
hp.type = USING_STRING;
|
hp.type = USING_STRING;
|
||||||
hp.filter_fun = NitroplusSysFilter;
|
hp.filter_fun = NitroplusSysFilter;
|
||||||
return NewHook(hp, "NitroplusSystem");
|
return NewHook(hp, "NitroplusSystem");
|
||||||
}
|
}
|
||||||
bool Nitroplusplus::attach_function(){
|
bool Nitroplusplus::attach_function()
|
||||||
return InsertNitroplusSysHook();
|
{
|
||||||
|
return InsertNitroplusSysHook();
|
||||||
}
|
}
|
@ -358,23 +358,50 @@ void SearchForHooks(SearchParam spUser)
|
|||||||
for (auto& addr : addresses1 = Util::SearchMemory(sp.pattern, sp.length, PAGE_EXECUTE, sp.minAddress, sp.maxAddress))
|
for (auto& addr : addresses1 = Util::SearchMemory(sp.pattern, sp.length, PAGE_EXECUTE, sp.minAddress, sp.maxAddress))
|
||||||
addr += sp.offset;
|
addr += sp.offset;
|
||||||
}
|
}
|
||||||
else if(sp.search_method==1){
|
else if(sp.search_method==1){
|
||||||
for(uintptr_t addr=sp.minAddress;addr<sp.maxAddress;addr++){
|
auto checklength=3;
|
||||||
if(IsBadReadPtr((void*)addr,0x1000)){
|
auto checker=[checklength](DWORD k){
|
||||||
addr+=0x1000-1;
|
if (k == 0xcccccccc
|
||||||
|
|| k == 0x90909090
|
||||||
|
|| k == 0xccccccc3
|
||||||
|
|| k == 0x909090c3
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
DWORD t = k & 0xff0000ff;
|
||||||
|
if (t == 0xcc0000c2 || t == 0x900000c2)
|
||||||
|
return true;
|
||||||
|
if(checklength==4)return false;
|
||||||
|
k >>= 8;
|
||||||
|
if (k == 0xccccc3 || k == 0x9090c3)
|
||||||
|
return true;
|
||||||
|
if(checklength==3)return false;
|
||||||
|
// t = k & 0xff;
|
||||||
|
// if (t == 0xc2)
|
||||||
|
// return true;
|
||||||
|
k >>= 8;
|
||||||
|
if (k == 0xccc3 || k == 0x90c3)
|
||||||
|
return true;
|
||||||
|
if(checklength==2)return false;
|
||||||
|
k >>= 8;
|
||||||
|
if (k == 0xc3)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
for(uintptr_t addr=sp.minAddress& ~0xf;addr<sp.maxAddress;addr+=0x10){
|
||||||
|
if(IsBadReadPtr((void*)(addr-0x10),0x110)){
|
||||||
|
addr+=0x100-0x10;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(((*(DWORD*)addr)==0xCCCCCCCC)||((*(DWORD*)addr)==0x90909090)){
|
auto need=checker(*(DWORD *)(addr-4));
|
||||||
if(((*(BYTE*)(addr+4))!=0xCC)&&(*(BYTE*)(addr+4))!=0x90){
|
if (need)
|
||||||
addresses1.push_back(addr+4);
|
addresses1.push_back(addr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(sp.search_method==2){
|
else if(sp.search_method==2){
|
||||||
for(uintptr_t addr=sp.minAddress;addr<sp.maxAddress;addr++){
|
for(uintptr_t addr=sp.minAddress;addr<sp.maxAddress;addr++){
|
||||||
if(IsBadReadPtr((void*)addr,0x1000)){
|
if(IsBadReadPtr((void*)addr,0x100)){
|
||||||
addr+=0x1000-1;
|
addr+=0x100-1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(((*(BYTE*)addr)==0xe8)){
|
if(((*(BYTE*)addr)==0xe8)){
|
||||||
|
Loading…
Reference in New Issue
Block a user