mirror of
https://github.com/Detanup01/gbe_fork.git
synced 2024-11-27 05:04:01 +08:00
updated stub drm patterns (for v2) and added a workaround for older variants
This commit is contained in:
parent
648c19fd99
commit
16a241599f
@ -1,4 +1,5 @@
|
||||
* **[detiam]** fix linking errors when build on archlinux
|
||||
* for windows: updated stub drm patterns and added a workaround for older variants
|
||||
* added missing example file `disable_lobby_creation.txt` in `steam_settings` folder + updated release `README`
|
||||
|
||||
---
|
||||
|
@ -462,7 +462,7 @@ size_t pe_helpers::get_current_exe_mem_size()
|
||||
for (size_t i = 0; i < sections.count; ++i) {
|
||||
auto section = sections.ptr[i];
|
||||
MEMORY_BASIC_INFORMATION mbi{};
|
||||
if (!VirtualQuery((LPVOID)((uint8_t *)hmod + section.VirtualAddress), &mbi, sizeof(mbi))) {
|
||||
if (!VirtualQuery((LPCVOID)((uint8_t *)hmod + section.VirtualAddress), &mbi, sizeof(mbi))) {
|
||||
return 0;
|
||||
}
|
||||
size = mbi.RegionSize; // actual section size in mem
|
||||
|
@ -13,15 +13,18 @@ typedef struct SnrUnit {
|
||||
|
||||
typedef struct SnrDetails {
|
||||
std::string detection_patt{};
|
||||
bool change_mem_access = false;
|
||||
std::vector<SnrUnit_t> snr_units{};
|
||||
} SnrDetails_t;
|
||||
|
||||
// x64
|
||||
#if defined(_WIN64)
|
||||
const std::vector<SnrDetails> snr_patts {
|
||||
static const std::vector<SnrDetails> snr_patts {
|
||||
{
|
||||
// detection_patt
|
||||
"FF 94 24 ?? ?? ?? ?? 88 44 24 ?? 0F BE 44 24 ?? 83 ?? 30 74 ?? E9",
|
||||
// change memory pages access to r/w/e
|
||||
false,
|
||||
// snr_units
|
||||
{
|
||||
// patt 1 is a bunch of checks for registry + files validity (including custom DOS stub)
|
||||
@ -40,6 +43,8 @@ typedef struct SnrDetails {
|
||||
{
|
||||
// detection_patt
|
||||
"FF D? 44 0F B6 ?? 3C 30 0F 85",
|
||||
// change memory pages access to r/w/e
|
||||
false,
|
||||
// snr_units
|
||||
{
|
||||
{
|
||||
@ -55,10 +60,12 @@ typedef struct SnrDetails {
|
||||
// x32
|
||||
#if !defined(_WIN64)
|
||||
|
||||
const std::vector<SnrDetails> snr_patts {
|
||||
static const std::vector<SnrDetails> snr_patts {
|
||||
{
|
||||
// detection_patt
|
||||
"FF 95 ?? ?? ?? ?? 88 45 ?? 0F BE 4D ?? 83 ?? 30 74 ?? E9",
|
||||
// change memory pages access to r/w/e
|
||||
false,
|
||||
// snr_units
|
||||
{
|
||||
// patt 1 is a bunch of checks for registry + files validity (including custom DOS stub)
|
||||
@ -77,18 +84,26 @@ typedef struct SnrDetails {
|
||||
{
|
||||
// detection_patt
|
||||
"FF 95 ?? ?? ?? ?? 89 85 ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 89 ?? ?? ?? ?? ?? 8B ?? ?? 89 ?? ?? ?? ?? ?? 83 A5 ?? ?? ?? ?? ?? EB",
|
||||
// change memory pages access to r/w/e
|
||||
true,
|
||||
// snr_units
|
||||
{
|
||||
{
|
||||
"F6 C? 02 0F 85 ?? ?? ?? ?? 5? FF ?? 6?",
|
||||
"?? ?? ?? 90 E9 00 03",
|
||||
},
|
||||
{
|
||||
"F6 C? 02 89 ?? ?? ?? ?? ?? A3 ?? ?? ?? ?? 0F 85",
|
||||
"?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 90 E9 00 03 00 00",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
// detection_patt
|
||||
"FF D? 88 45 ?? 3C 30 0F 85 ?? ?? ?? ?? B8 4D 5A",
|
||||
// change memory pages access to r/w/e
|
||||
false,
|
||||
// snr_units
|
||||
{
|
||||
{
|
||||
@ -106,15 +121,45 @@ typedef struct SnrDetails {
|
||||
|
||||
#endif // _WIN64
|
||||
|
||||
const std::vector<SnrUnit_t> *current_snr_units = nullptr;
|
||||
|
||||
static size_t current_snr_details = static_cast<size_t>(-1);
|
||||
|
||||
static std::recursive_mutex mtx_win32_api{};
|
||||
static uint8_t *proc_addr_base = (uint8_t *)GetModuleHandleW(NULL);
|
||||
static uint8_t *exe_addr_base = (uint8_t *)GetModuleHandleW(NULL);
|
||||
static uint8_t *bind_addr_base = nullptr;
|
||||
static uint8_t *bind_addr_end = nullptr;
|
||||
|
||||
bool restore_win32_apis();
|
||||
|
||||
// stub v2 needs manual change for .text, section must have write access
|
||||
static void change_mem_pages_access()
|
||||
{
|
||||
auto sections = pe_helpers::get_section_headers((HMODULE)exe_addr_base);
|
||||
if (!sections.count) return;
|
||||
|
||||
for (size_t i = 0; i < sections.count; ++i) {
|
||||
auto section = sections.ptr[i];
|
||||
uint8_t *section_base_addr = exe_addr_base + section.VirtualAddress;
|
||||
MEMORY_BASIC_INFORMATION mbi{};
|
||||
constexpr const static auto ANY_EXECUTE_RIGHT = PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY;
|
||||
if (VirtualQuery((LPCVOID)section_base_addr, &mbi, sizeof(mbi)) && // function succeeded
|
||||
(mbi.Protect & ANY_EXECUTE_RIGHT)) { // this page (not entire section) has execute rights
|
||||
DWORD current_protection = 0;
|
||||
auto res = VirtualProtect(section_base_addr, mbi.RegionSize, PAGE_EXECUTE_READWRITE, ¤t_protection);
|
||||
// if (!res) {
|
||||
// MessageBoxA(
|
||||
// nullptr,
|
||||
// (std::string("Failed to change access of page '") + (char *)section.Name + "' ").c_str(),
|
||||
// "Failed",
|
||||
// MB_OK
|
||||
// );
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void patch_if_possible(void *ret_addr)
|
||||
{
|
||||
if (!ret_addr) return;
|
||||
@ -123,7 +168,7 @@ static void patch_if_possible(void *ret_addr)
|
||||
if (!page_details.BaseAddress || page_details.AllocationProtect != PAGE_READWRITE) return;
|
||||
|
||||
bool anything_found = false;
|
||||
for (const auto &snr_unit : *current_snr_units) {
|
||||
for (const auto &snr_unit : snr_patts[current_snr_details].snr_units) {
|
||||
auto mem = pe_helpers::search_memory(
|
||||
(uint8_t *)page_details.BaseAddress,
|
||||
page_details.RegionSize,
|
||||
@ -144,6 +189,7 @@ static void patch_if_possible(void *ret_addr)
|
||||
|
||||
if (anything_found) {
|
||||
restore_win32_apis();
|
||||
if (snr_patts[current_snr_details].change_mem_access) change_mem_pages_access();
|
||||
}
|
||||
|
||||
// MessageBoxA(NULL, ("ret addr = " + std::to_string((size_t)ret_addr)).c_str(), "Patched", MB_OK);
|
||||
@ -239,15 +285,15 @@ static bool restore_win32_apis()
|
||||
|
||||
bool stubdrm::patch()
|
||||
{
|
||||
auto bind_section = pe_helpers::get_section_header_with_name(((HMODULE)proc_addr_base), ".bind");
|
||||
auto bind_section = pe_helpers::get_section_header_with_name(((HMODULE)exe_addr_base), ".bind");
|
||||
if (!bind_section) return false; // we don't have .bind section
|
||||
|
||||
bind_addr_base = proc_addr_base + bind_section->VirtualAddress;
|
||||
bind_addr_base = exe_addr_base + bind_section->VirtualAddress;
|
||||
MEMORY_BASIC_INFORMATION mbi{};
|
||||
if (!VirtualQuery((LPVOID)bind_addr_base, &mbi, sizeof(mbi))) return false;
|
||||
|
||||
bind_addr_end = bind_addr_base + mbi.RegionSize;
|
||||
auto addrOfEntry = proc_addr_base + pe_helpers::get_optional_header((HMODULE)proc_addr_base)->AddressOfEntryPoint;
|
||||
auto addrOfEntry = exe_addr_base + pe_helpers::get_optional_header((HMODULE)exe_addr_base)->AddressOfEntryPoint;
|
||||
if (addrOfEntry < bind_addr_base || addrOfEntry >= bind_addr_end) return false; // entry addr is not inside .bind
|
||||
|
||||
for (const auto &patt : snr_patts) {
|
||||
@ -257,7 +303,7 @@ bool stubdrm::patch()
|
||||
patt.detection_patt);
|
||||
|
||||
if (mem) {
|
||||
current_snr_units = &patt.snr_units;
|
||||
current_snr_details = &patt - &snr_patts[0];
|
||||
return redirect_win32_apis();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user