mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-12-24 20:24:13 +08:00
selen
This commit is contained in:
parent
70f5a26f30
commit
3d05e89edd
@ -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);
|
||||||
@ -31,4 +31,35 @@ bool Sprite::attach_function() {
|
|||||||
hp.offset=get_reg(regs::eax);
|
hp.offset=get_reg(regs::eax);
|
||||||
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();
|
||||||
|
}
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user