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
|
* **[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`
|
* 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) {
|
for (size_t i = 0; i < sections.count; ++i) {
|
||||||
auto section = sections.ptr[i];
|
auto section = sections.ptr[i];
|
||||||
MEMORY_BASIC_INFORMATION mbi{};
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
size = mbi.RegionSize; // actual section size in mem
|
size = mbi.RegionSize; // actual section size in mem
|
||||||
|
@ -13,15 +13,18 @@ typedef struct SnrUnit {
|
|||||||
|
|
||||||
typedef struct SnrDetails {
|
typedef struct SnrDetails {
|
||||||
std::string detection_patt{};
|
std::string detection_patt{};
|
||||||
|
bool change_mem_access = false;
|
||||||
std::vector<SnrUnit_t> snr_units{};
|
std::vector<SnrUnit_t> snr_units{};
|
||||||
} SnrDetails_t;
|
} SnrDetails_t;
|
||||||
|
|
||||||
// x64
|
// x64
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
const std::vector<SnrDetails> snr_patts {
|
static const std::vector<SnrDetails> snr_patts {
|
||||||
{
|
{
|
||||||
// detection_patt
|
// detection_patt
|
||||||
"FF 94 24 ?? ?? ?? ?? 88 44 24 ?? 0F BE 44 24 ?? 83 ?? 30 74 ?? E9",
|
"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
|
// snr_units
|
||||||
{
|
{
|
||||||
// patt 1 is a bunch of checks for registry + files validity (including custom DOS stub)
|
// patt 1 is a bunch of checks for registry + files validity (including custom DOS stub)
|
||||||
@ -40,6 +43,8 @@ typedef struct SnrDetails {
|
|||||||
{
|
{
|
||||||
// detection_patt
|
// detection_patt
|
||||||
"FF D? 44 0F B6 ?? 3C 30 0F 85",
|
"FF D? 44 0F B6 ?? 3C 30 0F 85",
|
||||||
|
// change memory pages access to r/w/e
|
||||||
|
false,
|
||||||
// snr_units
|
// snr_units
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@ -55,10 +60,12 @@ typedef struct SnrDetails {
|
|||||||
// x32
|
// x32
|
||||||
#if !defined(_WIN64)
|
#if !defined(_WIN64)
|
||||||
|
|
||||||
const std::vector<SnrDetails> snr_patts {
|
static const std::vector<SnrDetails> snr_patts {
|
||||||
{
|
{
|
||||||
// detection_patt
|
// detection_patt
|
||||||
"FF 95 ?? ?? ?? ?? 88 45 ?? 0F BE 4D ?? 83 ?? 30 74 ?? E9",
|
"FF 95 ?? ?? ?? ?? 88 45 ?? 0F BE 4D ?? 83 ?? 30 74 ?? E9",
|
||||||
|
// change memory pages access to r/w/e
|
||||||
|
false,
|
||||||
// snr_units
|
// snr_units
|
||||||
{
|
{
|
||||||
// patt 1 is a bunch of checks for registry + files validity (including custom DOS stub)
|
// patt 1 is a bunch of checks for registry + files validity (including custom DOS stub)
|
||||||
@ -77,18 +84,26 @@ typedef struct SnrDetails {
|
|||||||
{
|
{
|
||||||
// detection_patt
|
// detection_patt
|
||||||
"FF 95 ?? ?? ?? ?? 89 85 ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 89 ?? ?? ?? ?? ?? 8B ?? ?? 89 ?? ?? ?? ?? ?? 83 A5 ?? ?? ?? ?? ?? EB",
|
"FF 95 ?? ?? ?? ?? 89 85 ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 89 ?? ?? ?? ?? ?? 8B ?? ?? 89 ?? ?? ?? ?? ?? 83 A5 ?? ?? ?? ?? ?? EB",
|
||||||
|
// change memory pages access to r/w/e
|
||||||
|
true,
|
||||||
// snr_units
|
// snr_units
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"F6 C? 02 0F 85 ?? ?? ?? ?? 5? FF ?? 6?",
|
"F6 C? 02 0F 85 ?? ?? ?? ?? 5? FF ?? 6?",
|
||||||
"?? ?? ?? 90 E9 00 03",
|
"?? ?? ?? 90 E9 00 03",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"F6 C? 02 89 ?? ?? ?? ?? ?? A3 ?? ?? ?? ?? 0F 85",
|
||||||
|
"?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 90 E9 00 03 00 00",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
// detection_patt
|
// detection_patt
|
||||||
"FF D? 88 45 ?? 3C 30 0F 85 ?? ?? ?? ?? B8 4D 5A",
|
"FF D? 88 45 ?? 3C 30 0F 85 ?? ?? ?? ?? B8 4D 5A",
|
||||||
|
// change memory pages access to r/w/e
|
||||||
|
false,
|
||||||
// snr_units
|
// snr_units
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@ -106,15 +121,45 @@ typedef struct SnrDetails {
|
|||||||
|
|
||||||
#endif // _WIN64
|
#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 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_base = nullptr;
|
||||||
static uint8_t *bind_addr_end = nullptr;
|
static uint8_t *bind_addr_end = nullptr;
|
||||||
|
|
||||||
bool restore_win32_apis();
|
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)
|
static void patch_if_possible(void *ret_addr)
|
||||||
{
|
{
|
||||||
if (!ret_addr) return;
|
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;
|
if (!page_details.BaseAddress || page_details.AllocationProtect != PAGE_READWRITE) return;
|
||||||
|
|
||||||
bool anything_found = false;
|
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(
|
auto mem = pe_helpers::search_memory(
|
||||||
(uint8_t *)page_details.BaseAddress,
|
(uint8_t *)page_details.BaseAddress,
|
||||||
page_details.RegionSize,
|
page_details.RegionSize,
|
||||||
@ -144,6 +189,7 @@ static void patch_if_possible(void *ret_addr)
|
|||||||
|
|
||||||
if (anything_found) {
|
if (anything_found) {
|
||||||
restore_win32_apis();
|
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);
|
// 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()
|
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
|
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{};
|
MEMORY_BASIC_INFORMATION mbi{};
|
||||||
if (!VirtualQuery((LPVOID)bind_addr_base, &mbi, sizeof(mbi))) return false;
|
if (!VirtualQuery((LPVOID)bind_addr_base, &mbi, sizeof(mbi))) return false;
|
||||||
|
|
||||||
bind_addr_end = bind_addr_base + mbi.RegionSize;
|
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
|
if (addrOfEntry < bind_addr_base || addrOfEntry >= bind_addr_end) return false; // entry addr is not inside .bind
|
||||||
|
|
||||||
for (const auto &patt : snr_patts) {
|
for (const auto &patt : snr_patts) {
|
||||||
@ -257,7 +303,7 @@ bool stubdrm::patch()
|
|||||||
patt.detection_patt);
|
patt.detection_patt);
|
||||||
|
|
||||||
if (mem) {
|
if (mem) {
|
||||||
current_snr_units = &patt.snr_units;
|
current_snr_details = &patt - &snr_patts[0];
|
||||||
return redirect_win32_apis();
|
return redirect_win32_apis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user