Skip to content

Commit

Permalink
Merge pull request #38 from apple1417/master
Browse files Browse the repository at this point in the history
Explictly deal with result of failing sigscans
  • Loading branch information
apple1417 authored Aug 10, 2024
2 parents 790d128 + 979b2fc commit 640634f
Show file tree
Hide file tree
Showing 18 changed files with 166 additions and 104 deletions.
9 changes: 8 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## v1.2.0 (Upcoming)
## v1.2.0
- When an exception occurs during a hook, now mention what function it was under, to make debugging
easier.

Expand Down Expand Up @@ -59,6 +59,13 @@
[91e3fcd5](https://github.com/bl-sdk/unrealsdk/commit/91e3fcd5),
[8ec285fc](https://github.com/bl-sdk/unrealsdk/commit/8ec285fc)

- Tweaked `Pattern::sigscan` to more explicitly deal with sigscans failing. Existing code will have
to be updated to either call `sigscan_nullable` (if failing is ok), or to pass a name to use in
case of error (if throwing is ok).

[7135bdf3](https://github.com/bl-sdk/unrealsdk/commit/7135bdf3),
[b849b0e8](https://github.com/bl-sdk/unrealsdk/commit/91e3fcd5)

- Made the `UnrealPointer` constructor explicit.

[26a47713](https://github.com/bl-sdk/unrealsdk/commit/26a47713)
Expand Down
2 changes: 1 addition & 1 deletion libs/fmt
Submodule fmt updated 184 files
2 changes: 1 addition & 1 deletion libs/minhook
4 changes: 2 additions & 2 deletions src/unrealsdk/game/bl2/bl2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const constinit Pattern<23> FNAME_INIT_SIG{
}

void BL2Hook::find_fname_init(void) {
this->fname_init_ptr = FNAME_INIT_SIG.sigscan<void*>();
this->fname_init_ptr = FNAME_INIT_SIG.sigscan_nullable<void*>();
LOG(MISC, "FName::Init: {:p}", this->fname_init_ptr);
}

Expand Down Expand Up @@ -96,7 +96,7 @@ const constinit Pattern<9> FFRAME_STEP_SIG{
} // namespace

void BL2Hook::find_fframe_step(void) {
fframe_step_ptr = FFRAME_STEP_SIG.sigscan<fframe_step_func>();
fframe_step_ptr = FFRAME_STEP_SIG.sigscan_nullable<fframe_step_func>();
LOG(MISC, "FFrame::Step: {:p}", reinterpret_cast<void*>(fframe_step_ptr));
}
void BL2Hook::fframe_step(FFrame* frame, UObject* obj, void* param) const {
Expand Down
24 changes: 11 additions & 13 deletions src/unrealsdk/game/bl2/globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,16 @@ namespace {
GObjects gobjects_wrapper{};

const constinit Pattern<17> GOBJECTS_SIG{
"8B 0D ????????" // mov ecx, [Borderlands2.exe+1682BD0]
"8B 04 ??" // mov eax, [ecx+esi*4]
"8B 40 ??" // mov eax, [eax+08]
"25 00020000" // and eax, 00000200
,
2};
"8B 0D {????????}" // mov ecx, [Borderlands2.exe+1682BD0]
"8B 04 ??" // mov eax, [ecx+esi*4]
"8B 40 ??" // mov eax, [eax+08]
"25 00020000" // and eax, 00000200
};

} // namespace

void BL2Hook::find_gobjects(void) {
auto gobjects_ptr = read_offset<GObjects::internal_type>(GOBJECTS_SIG.sigscan());
auto gobjects_ptr = read_offset<GObjects::internal_type>(GOBJECTS_SIG.sigscan_nullable());
LOG(MISC, "GObjects: {:p}", reinterpret_cast<void*>(gobjects_ptr));

gobjects_wrapper = GObjects(gobjects_ptr);
Expand All @@ -42,16 +41,15 @@ namespace {
GNames gnames_wrapper{};

const constinit Pattern<10> GNAMES_SIG{
"A3 ????????" // mov [BorderlandsPreSequel.exe+1520214], eax
"8B 45 ??" // mov eax, [ebp+10]
"89 03" // mov [ebx], eax
,
1};
"A3 {????????}" // mov [BorderlandsPreSequel.exe+1520214], eax
"8B 45 ??" // mov eax, [ebp+10]
"89 03" // mov [ebx], eax
};

} // namespace

void BL2Hook::find_gnames(void) {
auto gnames_ptr = read_offset<GNames::internal_type>(GNAMES_SIG.sigscan());
auto gnames_ptr = read_offset<GNames::internal_type>(GNAMES_SIG.sigscan_nullable());
LOG(MISC, "GNames: {:p}", reinterpret_cast<void*>(gnames_ptr));

gnames_wrapper = GNames(gnames_ptr);
Expand Down
6 changes: 3 additions & 3 deletions src/unrealsdk/game/bl2/hexedits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const constinit Pattern<15> ARRAY_LIMIT_MESSAGE{
} // namespace

void BL2Hook::hexedit_set_command(void) {
auto set_command = SET_COMMAND_SIG.sigscan<uint8_t*>();
auto set_command = SET_COMMAND_SIG.sigscan_nullable<uint8_t*>();
if (set_command == nullptr) {
LOG(ERROR, "Couldn't find set command signature");
} else {
Expand All @@ -55,7 +55,7 @@ void BL2Hook::hexedit_set_command(void) {
}

void BL2Hook::hexedit_array_limit(void) {
auto array_limit = ARRAY_LIMIT_SIG.sigscan<uint8_t*>();
auto array_limit = ARRAY_LIMIT_SIG.sigscan_nullable<uint8_t*>();
if (array_limit == nullptr) {
LOG(ERROR, "Couldn't find array limit signature");
} else {
Expand All @@ -69,7 +69,7 @@ void BL2Hook::hexedit_array_limit(void) {
}

void BL2Hook::hexedit_array_limit_message(void) const {
auto array_limit_msg = ARRAY_LIMIT_MESSAGE.sigscan<uint8_t*>();
auto array_limit_msg = ARRAY_LIMIT_MESSAGE.sigscan_nullable<uint8_t*>();
if (array_limit_msg == nullptr) {
LOG(ERROR, "Couldn't find array limit message signature");
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/unrealsdk/game/bl2/hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ bool locking(void) {
} // namespace

void BL2Hook::hook_process_event(void) {
detour(PROCESS_EVENT_SIG.sigscan(), locking() ? locking_process_event_hook : process_event_hook,
detour(PROCESS_EVENT_SIG, locking() ? locking_process_event_hook : process_event_hook,
&process_event_ptr, "ProcessEvent");
}

Expand Down Expand Up @@ -232,7 +232,7 @@ static_assert(std::is_same_v<decltype(&call_function_hook), call_function_func>,
} // namespace

void BL2Hook::hook_call_function(void) {
detour(CALL_FUNCTION_SIG.sigscan(), call_function_hook, &call_function_ptr, "CallFunction");
detour(CALL_FUNCTION_SIG, call_function_hook, &call_function_ptr, "CallFunction");
}

} // namespace unrealsdk::game
Expand Down
11 changes: 6 additions & 5 deletions src/unrealsdk/game/bl2/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,16 @@ struct FMalloc {
FMalloc* gmalloc;

const constinit Pattern<8> GMALLOC_PATTERN{
"89 35 ????????" // mov [Borderlands2.GDebugger+A95C], esi
"FF D7" // call edi
,
2};
"89 35 {????????}" // mov [Borderlands2.GDebugger+A95C], esi
"FF D7" // call edi
};

} // namespace

void BL2Hook::find_gmalloc(void) {
gmalloc = *read_offset<FMalloc**>(GMALLOC_PATTERN.sigscan());
// Using plain `sigscan` since there's an extra level of indirection here, want to make sure to
// print an error before we potentially dereference it
gmalloc = *read_offset<FMalloc**>(GMALLOC_PATTERN.sigscan("GMalloc"));
LOG(MISC, "GMalloc: {:p}", reinterpret_cast<void*>(gmalloc));
}
void* BL2Hook::u_malloc(size_t len) const {
Expand Down
8 changes: 4 additions & 4 deletions src/unrealsdk/game/bl2/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const constinit Pattern<49> CONSTRUCT_OBJECT_PATTERN{
} // namespace

void BL2Hook::find_construct_object(void) {
construct_obj_ptr = CONSTRUCT_OBJECT_PATTERN.sigscan<construct_obj_func>();
construct_obj_ptr = CONSTRUCT_OBJECT_PATTERN.sigscan_nullable<construct_obj_func>();
LOG(MISC, "StaticConstructObject: {:p}", reinterpret_cast<void*>(construct_obj_ptr));
}

Expand Down Expand Up @@ -106,7 +106,7 @@ const constinit Pattern<15> GET_PATH_NAME_PATTERN{
};

void BL2Hook::find_get_path_name(void) {
get_path_name_ptr = GET_PATH_NAME_PATTERN.sigscan<get_path_name_func>();
get_path_name_ptr = GET_PATH_NAME_PATTERN.sigscan_nullable<get_path_name_func>();
LOG(MISC, "GetPathName: {:p}", reinterpret_cast<void*>(get_path_name_ptr));
}

Expand Down Expand Up @@ -156,7 +156,7 @@ const constinit Pattern<56> STATIC_FIND_OBJECT_PATTERN{
} // namespace

void BL2Hook::find_static_find_object(void) {
static_find_object_ptr = STATIC_FIND_OBJECT_PATTERN.sigscan<static_find_object_func>();
static_find_object_ptr = STATIC_FIND_OBJECT_PATTERN.sigscan_nullable<static_find_object_func>();
LOG(MISC, "StaticFindObject: {:p}", reinterpret_cast<void*>(static_find_object_ptr));
}

Expand Down Expand Up @@ -196,7 +196,7 @@ const constinit Pattern<46> LOAD_PACKAGE_PATTERN{
} // namespace

void BL2Hook::find_load_package(void) {
load_package_ptr = LOAD_PACKAGE_PATTERN.sigscan<load_package_func>();
load_package_ptr = LOAD_PACKAGE_PATTERN.sigscan_nullable<load_package_func>();
LOG(MISC, "LoadPackage: {:p}", reinterpret_cast<void*>(load_package_ptr));
}

Expand Down
6 changes: 3 additions & 3 deletions src/unrealsdk/game/bl3/bl3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const constinit Pattern<15> FNAME_INIT_PATTERN{
} // namespace

void BL3Hook::find_fname_init(void) {
fname_init_ptr = FNAME_INIT_PATTERN.sigscan<fname_init_func>();
fname_init_ptr = FNAME_INIT_PATTERN.sigscan_nullable<fname_init_func>();
LOG(MISC, "FName::Init: {:p}", reinterpret_cast<void*>(fname_init_ptr));
}

Expand All @@ -83,7 +83,7 @@ const constinit Pattern<10> FFRAME_STEP_SIG{
} // namespace

void BL3Hook::find_fframe_step(void) {
fframe_step_ptr = FFRAME_STEP_SIG.sigscan<fframe_step_func>();
fframe_step_ptr = FFRAME_STEP_SIG.sigscan_nullable<fframe_step_func>();
LOG(MISC, "FFrame::Step: {:p}", reinterpret_cast<void*>(fframe_step_ptr));
}
void BL3Hook::fframe_step(FFrame* frame, UObject* obj, void* param) const {
Expand Down Expand Up @@ -145,7 +145,7 @@ const constinit Pattern<131> FTEXT_AS_CULTURE_INVARIANT_PATTERN{

void BL3Hook::find_ftext_as_culture_invariant(void) {
ftext_as_culture_invariant_ptr =
FTEXT_AS_CULTURE_INVARIANT_PATTERN.sigscan<ftext_as_culture_invariant_func>();
FTEXT_AS_CULTURE_INVARIANT_PATTERN.sigscan_nullable<ftext_as_culture_invariant_func>();
LOG(MISC, "FText::AsCultureInvariant: {:p}", reinterpret_cast<void*>(fname_init_ptr));
}

Expand Down
34 changes: 17 additions & 17 deletions src/unrealsdk/game/bl3/globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,16 @@ namespace {
GObjects gobjects_wrapper{};

const constinit Pattern<26> GOBJECTS_SIG{
"48 8D 0D ????????" // lea rcx, [Borderlands3.exe+69EBDA0]
"C6 05 ???????? 01" // mov byte ptr [Borderlands3.exe+69EA290], 01
"E8 ????????" // call Borderlands3.exe+17854D0
"C6 05 ???????? 01" // mov byte ptr [Borderlands3.exe+64B78E0], 01
,
3};
"48 8D 0D {????????}" // lea rcx, [Borderlands3.exe+69EBDA0]
"C6 05 ???????? 01" // mov byte ptr [Borderlands3.exe+69EA290], 01
"E8 ????????" // call Borderlands3.exe+17854D0
"C6 05 ???????? 01" // mov byte ptr [Borderlands3.exe+64B78E0], 01
};

} // namespace

void BL3Hook::find_gobjects(void) {
auto gobjects_ptr = read_offset<GObjects::internal_type>(GOBJECTS_SIG.sigscan());
auto gobjects_ptr = read_offset<GObjects::internal_type>(GOBJECTS_SIG.sigscan_nullable());
LOG(MISC, "GObjects: {:p}", reinterpret_cast<void*>(gobjects_ptr));

gobjects_wrapper = GObjects(gobjects_ptr);
Expand All @@ -42,20 +41,21 @@ namespace {
GNames gnames_wrapper{};

const constinit Pattern<27> GNAMES_SIG{
"E8 ????????" // call Borderlands3.exe+3DDBB7C
"48 8B C3" // mov rax, rbx
"48 89 1D ????????" // mov [Borderlands3.exe+69E71E8], rbx
"48 8B 5C 24 ??" // mov rbx, [rsp+20]
"48 83 C4 28" // add rsp, 28
"C3" // ret
"33 DB" // xor ebx, ebx
,
11};
"E8 ????????" // call Borderlands3.exe+3DDBB7C
"48 8B C3" // mov rax, rbx
"48 89 1D {????????}" // mov [Borderlands3.exe+69E71E8], rbx
"48 8B 5C 24 ??" // mov rbx, [rsp+20]
"48 83 C4 28" // add rsp, 28
"C3" // ret
"33 DB" // xor ebx, ebx
};

} // namespace

void BL3Hook::find_gnames(void) {
auto gnames_ptr = *read_offset<GNames::internal_type*>(GNAMES_SIG.sigscan());
// Using plain `sigscan` since there's an extra level of indirection here, want to make sure to
// print an error before we potentially dereference it
auto gnames_ptr = *read_offset<GNames::internal_type*>(GNAMES_SIG.sigscan("GNames"));
LOG(MISC, "GNames: {:p}", reinterpret_cast<void*>(gnames_ptr));

gnames_wrapper = GNames(gnames_ptr);
Expand Down
5 changes: 2 additions & 3 deletions src/unrealsdk/game/bl3/hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ bool locking(void) {
}

void BL3Hook::hook_process_event(void) {
detour(PROCESS_EVENT_SIG.sigscan(), locking() ? locking_process_event_hook : process_event_hook,
detour(PROCESS_EVENT_SIG, locking() ? locking_process_event_hook : process_event_hook,
&process_event_ptr, "ProcessEvent");
}

Expand Down Expand Up @@ -133,7 +133,6 @@ const constinit Pattern<20> CALL_FUNCTION_SIG{
"41 56" // push r14
"41 57" // push r15
"48 81 EC 28010000" // sub rsp, 00000128

};

} // namespace
Expand Down Expand Up @@ -214,7 +213,7 @@ static_assert(std::is_same_v<decltype(call_function_hook), call_function_func>,
"call_function signature is incorrect");

void BL3Hook::hook_call_function(void) {
detour(CALL_FUNCTION_SIG.sigscan(), call_function_hook, &call_function_ptr, "CallFunction");
detour(CALL_FUNCTION_SIG, call_function_hook, &call_function_ptr, "CallFunction");
}

} // namespace unrealsdk::game
Expand Down
6 changes: 3 additions & 3 deletions src/unrealsdk/game/bl3/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ const constinit Pattern<20> FREE_PATTERN{
} // namespace

void BL3Hook::find_gmalloc(void) {
fmemory_malloc_ptr = MALLOC_PATTERN.sigscan<fmemory_malloc_func>();
fmemory_realloc_ptr = REALLOC_PATTERN.sigscan<fmemory_realloc_func>();
fmemory_free_ptr = FREE_PATTERN.sigscan<fmemory_free_func>();
fmemory_malloc_ptr = MALLOC_PATTERN.sigscan_nullable<fmemory_malloc_func>();
fmemory_realloc_ptr = REALLOC_PATTERN.sigscan_nullable<fmemory_realloc_func>();
fmemory_free_ptr = FREE_PATTERN.sigscan_nullable<fmemory_free_func>();

LOG(MISC, "FMemory::Malloc: {:p}", reinterpret_cast<void*>(fmemory_malloc_ptr));
LOG(MISC, "FMemory::Realloc: {:p}", reinterpret_cast<void*>(fmemory_realloc_ptr));
Expand Down
9 changes: 5 additions & 4 deletions src/unrealsdk/game/bl3/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const constinit Pattern<55> CONSTRUCT_OBJECT_PATTERN{
} // namespace

void BL3Hook::find_construct_object(void) {
construct_obj_ptr = CONSTRUCT_OBJECT_PATTERN.sigscan<construct_obj_func>();
construct_obj_ptr = CONSTRUCT_OBJECT_PATTERN.sigscan_nullable<construct_obj_func>();
LOG(MISC, "StaticConstructObject: {:p}", reinterpret_cast<void*>(construct_obj_ptr));
}

Expand Down Expand Up @@ -84,7 +84,7 @@ const constinit Pattern<21> GET_PATH_NAME_PATTERN{
} // namespace

void BL3Hook::find_get_path_name(void) {
get_path_name_ptr = GET_PATH_NAME_PATTERN.sigscan<get_path_name_func>();
get_path_name_ptr = GET_PATH_NAME_PATTERN.sigscan_nullable<get_path_name_func>();
LOG(MISC, "GetPathName: {:p}", reinterpret_cast<void*>(get_path_name_ptr));
}

Expand Down Expand Up @@ -120,7 +120,8 @@ const constexpr intptr_t ANY_PACKAGE = -1;
} // namespace

void BL3Hook::find_static_find_object(void) {
static_find_object_ptr = STATIC_FIND_OBJECT_PATTERN.sigscan<static_find_object_safe_func>();
static_find_object_ptr =
STATIC_FIND_OBJECT_PATTERN.sigscan_nullable<static_find_object_safe_func>();
LOG(MISC, "StaticFindObjectSafe: {:p}", reinterpret_cast<void*>(static_find_object_ptr));
}

Expand Down Expand Up @@ -152,7 +153,7 @@ const constinit Pattern<16> LOAD_PACKAGE_PATTERN{
} // namespace

void BL3Hook::find_load_package(void) {
load_package_ptr = LOAD_PACKAGE_PATTERN.sigscan<load_package_func>();
load_package_ptr = LOAD_PACKAGE_PATTERN.sigscan_nullable<load_package_func>();
LOG(MISC, "LoadPackage: {:p}", reinterpret_cast<void*>(load_package_ptr));
}

Expand Down
2 changes: 1 addition & 1 deletion src/unrealsdk/game/tps/hexedits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const constinit Pattern<11> ARRAY_LIMIT_MESSAGE{
} // namespace

void TPSHook::hexedit_array_limit_message(void) const {
auto array_limit_msg = ARRAY_LIMIT_MESSAGE.sigscan<uint8_t*>();
auto array_limit_msg = ARRAY_LIMIT_MESSAGE.sigscan_nullable<uint8_t*>();
if (array_limit_msg == nullptr) {
LOG(ERROR, "Couldn't find array limit message signature");
} else {
Expand Down
9 changes: 9 additions & 0 deletions src/unrealsdk/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ bool detour(uintptr_t addr, void* detour_func, void** original_func, std::string
}
#else
bool detour(uintptr_t addr, void* detour_func, void** original_func, std::string_view name) {
if (addr == 0) {
LOG(ERROR, "Detour for {} was passed a null address!", name);
return false;
}

MH_STATUS status = MH_OK;

status = MH_CreateHook(reinterpret_cast<LPVOID>(addr), detour_func, original_func);
Expand Down Expand Up @@ -114,6 +119,10 @@ UNREALSDK_CAPI(bool,
#endif

uintptr_t read_offset(uintptr_t address) {
if (address == 0) {
LOG(ERROR, "Attempted to read a null offset!");
return 0;
}
#ifdef ARCH_X64
return address + *reinterpret_cast<int32_t*>(address) + 4;
#else
Expand Down
Loading

0 comments on commit 640634f

Please sign in to comment.