This commit is contained in:
恍兮惚兮 2024-03-04 13:30:31 +08:00
parent 70f5a26f30
commit 3d05e89edd
4 changed files with 50 additions and 19 deletions

View File

@ -1,6 +1,6 @@
#include"Sprite.h" #include"Sprite.h"
bool Sprite::attach_function() { bool Sprite_attach_function() {
//恋と選挙とチョコレート //恋と選挙とチョコレート
auto m=GetModuleHandle(L"dirapi.dll"); auto m=GetModuleHandle(L"dirapi.dll");
auto [minAddress, maxAddress] = Util::QueryModuleLimits(m); auto [minAddress, maxAddress] = Util::QueryModuleLimits(m);
@ -32,3 +32,34 @@ bool Sprite::attach_function() {
hp.type = USING_STRING; hp.type = USING_STRING;
return NewHook(hp, "Sprite"); return NewHook(hp, "Sprite");
} }
namespace{
bool _h1(){
//https://vndb.org/v1714
//[Selen]はらみこ
auto FlashAssetx32=GetModuleHandleW(L"Flash Asset.x32");
if(FlashAssetx32==0)return false;
auto [s,e]=Util::QueryModuleLimits(FlashAssetx32);
const BYTE bytes[] = {
0x56,0x57,0x6a,0xff,
0xff,0x75,0x08,//ebp+8
0x53,
0x68,0xe4,0x04,0x00,0x00,
0xff,0x15,XX4//MultiByteToWideChar
};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), s, e);
if(addr==0)return false;
HookParam hp;
hp.address = addr+sizeof(bytes);//不知道从哪jump到call MultiByteToWideChar的
hp.offset=get_stack(5);
hp.type = USING_STRING;
hp.filter_fun=[](LPVOID data, size_t *size, HookParam *)->bool
{
static int idx=0;
return (idx++)%2;
};
return NewHook(hp, "Selen");
}
}
bool Sprite::attach_function() {
return Sprite_attach_function()|_h1();
}

View File

@ -165,7 +165,7 @@ void Send(char** stack, uintptr_t address)
} }
} }
std::vector<uint64_t> GetFunctions(uintptr_t module) std::vector<uintptr_t> GetFunctions(uintptr_t module)
{ {
if (!module) return {}; if (!module) return {};
IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)module; IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)module;
@ -175,14 +175,14 @@ std::vector<uint64_t> GetFunctions(uintptr_t module)
DWORD exportAddress = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; DWORD exportAddress = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
if (!exportAddress) return {}; if (!exportAddress) return {};
IMAGE_EXPORT_DIRECTORY* exportDirectory = (IMAGE_EXPORT_DIRECTORY*)(module + exportAddress); IMAGE_EXPORT_DIRECTORY* exportDirectory = (IMAGE_EXPORT_DIRECTORY*)(module + exportAddress);
std::vector<uint64_t> functions; std::vector<uintptr_t> functions;
for (int i = 0; i < exportDirectory->NumberOfNames; ++i) for (int i = 0; i < exportDirectory->NumberOfNames; ++i)
//char* funcName = (char*)(module + *(DWORD*)(module + exportDirectory->AddressOfNames + i * sizeof(DWORD))); //char* funcName = (char*)(module + *(DWORD*)(module + exportDirectory->AddressOfNames + i * sizeof(DWORD)));
functions.push_back(module + *(DWORD*)(module + exportDirectory->AddressOfFunctions + functions.push_back(module + *(DWORD*)(module + exportDirectory->AddressOfFunctions +
sizeof(DWORD) * *(WORD*)(module + exportDirectory->AddressOfNameOrdinals + i * sizeof(WORD)))); sizeof(DWORD) * *(WORD*)(module + exportDirectory->AddressOfNameOrdinals + i * sizeof(WORD))));
return functions; return functions;
} }
void mergevector(std::vector<uint64_t> &v1,std::vector<uint64_t> &v2){ void mergevector(std::vector<uintptr_t> &v1,std::vector<uintptr_t> &v2){
for(auto addr:v2){ for(auto addr:v2){
auto it = std::find(v1.begin(), v1.end(), addr); auto it = std::find(v1.begin(), v1.end(), addr);
if (it == v1.end()) { if (it == v1.end()) {
@ -206,7 +206,7 @@ void SearchForHooks(SearchParam spUser)
catch (std::bad_alloc) { ConsoleOutput(SearchForHooks_ERROR, sp.maxRecords /= 2); } catch (std::bad_alloc) { ConsoleOutput(SearchForHooks_ERROR, sp.maxRecords /= 2); }
while (!records && sp.maxRecords); while (!records && sp.maxRecords);
std::vector<uint64_t> addresses; std::vector<uintptr_t> addresses;
if (*sp.boundaryModule) { if (*sp.boundaryModule) {
auto [minaddr,maxaddr]=Util::QueryModuleLimits(GetModuleHandleW(sp.boundaryModule)); auto [minaddr,maxaddr]=Util::QueryModuleLimits(GetModuleHandleW(sp.boundaryModule));
if(sp.address_method==0){ if(sp.address_method==0){
@ -225,7 +225,7 @@ void SearchForHooks(SearchParam spUser)
auto _addresses = GetFunctions((uintptr_t)GetModuleHandleW(sp.boundaryModule)); auto _addresses = GetFunctions((uintptr_t)GetModuleHandleW(sp.boundaryModule));
mergevector(addresses,_addresses); mergevector(addresses,_addresses);
} }
std::vector<uint64_t> addresses1; std::vector<uintptr_t> addresses1;
if(sp.search_method==0){ if(sp.search_method==0){
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;
@ -254,11 +254,11 @@ void SearchForHooks(SearchParam spUser)
mergevector(addresses,addresses1); mergevector(addresses,addresses1);
auto limits = Util::QueryModuleLimits(GetModuleHandleW(LUNA_HOOK_DLL)); auto limits = Util::QueryModuleLimits(GetModuleHandleW(LUNA_HOOK_DLL));
addresses.erase(std::remove_if(addresses.begin(), addresses.end(), [&](uint64_t addr) { return addr > limits.first && addr < limits.second; }), addresses.end()); addresses.erase(std::remove_if(addresses.begin(), addresses.end(), [&](auto addr) { return addr > limits.first && addr < limits.second; }), addresses.end());
auto trampolines = (decltype(trampoline)*)VirtualAlloc(NULL, sizeof(trampoline) * addresses.size(), MEM_COMMIT, PAGE_READWRITE); auto trampolines = (decltype(trampoline)*)VirtualAlloc(NULL, sizeof(trampoline) * addresses.size(), MEM_COMMIT, PAGE_READWRITE);
VirtualProtect(trampolines, addresses.size() * sizeof(trampoline), PAGE_EXECUTE_READWRITE, DUMMY); VirtualProtect(trampolines, addresses.size() * sizeof(trampoline), PAGE_EXECUTE_READWRITE, DUMMY);
std::vector<uint64_t>mherroridx; std::vector<uintptr_t>mherroridx;
for (int i = 0; i < addresses.size(); ++i) for (int i = 0; i < addresses.size(); ++i)
{ {
void* original; void* original;
@ -319,7 +319,7 @@ void SearchForText(wchar_t* text, UINT codepage)
if (strlen(utf8Text) < 4 || ((codepage!=CP_UTF8)&&(strlen(codepageText) < 4)) || wcslen(text) < 4) return ConsoleOutput(NOT_ENOUGH_TEXT); if (strlen(utf8Text) < 4 || ((codepage!=CP_UTF8)&&(strlen(codepageText) < 4)) || wcslen(text) < 4) return ConsoleOutput(NOT_ENOUGH_TEXT);
ConsoleOutput(HOOK_SEARCH_STARTING); ConsoleOutput(HOOK_SEARCH_STARTING);
auto GenerateHooks = [&](std::vector<uint64_t> addresses, HookParamType type) auto GenerateHooks = [&](std::vector<uintptr_t> addresses, HookParamType type)
{ {
for (auto addr : addresses) for (auto addr : addresses)
{ {

View File

@ -273,7 +273,7 @@ bool SearchResourceString(LPCWSTR str)
return false; return false;
} }
std::pair<uint64_t, uint64_t> QueryModuleLimits(HMODULE module,uintptr_t addition,DWORD protect) std::pair<uintptr_t, uintptr_t> QueryModuleLimits(HMODULE module,uintptr_t addition,DWORD protect)
{ {
uintptr_t moduleStartAddress = (uintptr_t)module + addition; uintptr_t moduleStartAddress = (uintptr_t)module + addition;
uintptr_t moduleStopAddress = moduleStartAddress; uintptr_t moduleStopAddress = moduleStartAddress;
@ -287,11 +287,11 @@ std::pair<uint64_t, uint64_t> QueryModuleLimits(HMODULE module,uintptr_t additio
return { moduleStartAddress, moduleStopAddress }; return { moduleStartAddress, moduleStopAddress };
} }
std::vector<uint64_t> SearchMemory(const void* bytes, short length, DWORD protect, uintptr_t minAddr, uintptr_t maxAddr) std::vector<uintptr_t> SearchMemory(const void* bytes, short length, DWORD protect, uintptr_t minAddr, uintptr_t maxAddr)
{ {
SYSTEM_INFO systemInfo; SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo); GetNativeSystemInfo(&systemInfo);
std::vector<std::pair<uint64_t, uint64_t>> validMemory; std::vector<std::pair<uintptr_t, uintptr_t>> validMemory;
for (BYTE* probe = NULL; probe < systemInfo.lpMaximumApplicationAddress;) for (BYTE* probe = NULL; probe < systemInfo.lpMaximumApplicationAddress;)
{ {
MEMORY_BASIC_INFORMATION info = {}; MEMORY_BASIC_INFORMATION info = {};
@ -302,15 +302,15 @@ std::vector<uint64_t> SearchMemory(const void* bytes, short length, DWORD protec
} }
else else
{ {
if ((uint64_t)info.BaseAddress + info.RegionSize >= minAddr && info.Protect >= protect && !(info.Protect & PAGE_GUARD)) if ((uintptr_t)info.BaseAddress + info.RegionSize >= minAddr && info.Protect >= protect && !(info.Protect & PAGE_GUARD))
validMemory.push_back({ (uint64_t)info.BaseAddress, info.RegionSize }); validMemory.push_back({ (uintptr_t)info.BaseAddress, info.RegionSize });
probe += info.RegionSize; probe += info.RegionSize;
} }
} }
std::vector<uint64_t> ret; std::vector<uintptr_t> ret;
for (auto memory : validMemory) for (auto memory : validMemory)
for (uint64_t addr = max(memory.first, minAddr); true;) for (uintptr_t addr = max(memory.first, minAddr); true;)
if (addr < maxAddr && (addr = SafeSearchMemory(addr, memory.first + memory.second, (const BYTE*)bytes, length))) if (addr < maxAddr && (addr = SafeSearchMemory(addr, memory.first + memory.second, (const BYTE*)bytes, length)))
ret.push_back(addr++); ret.push_back(addr++);
else break; else break;

View File

@ -38,8 +38,8 @@ bool CheckFile(LPCWSTR name);
bool SearchResourceString(LPCWSTR str); bool SearchResourceString(LPCWSTR str);
std::pair<uint64_t, uint64_t> QueryModuleLimits(HMODULE module,uintptr_t addition=0x1000,DWORD protect=PAGE_EXECUTE); std::pair<uintptr_t, uintptr_t> QueryModuleLimits(HMODULE module,uintptr_t addition=0x1000,DWORD protect=PAGE_EXECUTE);
std::vector<uint64_t> SearchMemory(const void* bytes, short length, DWORD protect = PAGE_EXECUTE, uintptr_t minAddr = 0, uintptr_t maxAddr = -1ULL); std::vector<uintptr_t> SearchMemory(const void* bytes, short length, DWORD protect = PAGE_EXECUTE, uintptr_t minAddr = 0, uintptr_t maxAddr = -1ULL);
uintptr_t FindFunction(const char* function); uintptr_t FindFunction(const char* function);
} // namespace Util } // namespace Util