1
0
mirror of https://github.com/pumpitupdev/pumptools.git synced 2025-01-18 23:34:03 +01:00

hasp + f2: Add missing hasp API method, fixes f2 hanging profile load

f2 was hanging on loading a profile from usb because a hasp API call
was missing that needed to be hooked. Stub the missing call and
return what the game expects there.

This also works with prime because prime is not using that function
anymore.
This commit is contained in:
icex2 2021-02-01 22:10:12 +01:00
parent b14751a362
commit abbee9291b
3 changed files with 56 additions and 0 deletions

View File

@ -17,12 +17,24 @@ static const uint8_t patch_hasp_id_sig[] = {
0xC7, 0x44, 0x24, 0x10
};
static const uint8_t patch_hasp_get_session_info_sig[] = {
0x55, 0x57, 0x56, 0x53,
0x83, 0xEC, 0x3C, 0xE8,
0x00, 0x00, 0x00, 0x00,
0x5B, 0x81, 0xC3, 0x98,
0xA2, 0x10, 0x00, 0xBE,
0x09, 0x00, 0x00, 0x00,
0x8B, 0x7C, 0x24, 0x50,
0x8B, 0x44, 0x24, 0x54
};
void patch_hasp_init(const uint8_t* key_data, size_t len)
{
void* func_api_login;
void* func_api_logout;
void* func_api_decrypt;
void* func_api_getid;
void* func_api_get_session_info;
func_api_login = util_patch_find_signiture(patch_hasp_login_sig,
sizeof(patch_hasp_login_sig), -16, (void*) 0x80c0000, (void*) 0x80f0000,
@ -52,10 +64,27 @@ void patch_hasp_init(const uint8_t* key_data, size_t len)
log_debug("ApiGetid at %p", func_api_getid);
func_api_get_session_info = util_patch_find_signiture(
patch_hasp_get_session_info_sig,
sizeof(patch_hasp_get_session_info_sig),
0,
(void*) 0x8060000,
(void*) 0x80F0000,
16);
if (!func_api_get_session_info) {
log_error("Could not find ApiGetSessionInfo address");
return;
}
log_debug("ApiGetSessionInfo at %p", func_api_get_session_info);
util_patch_function((uintptr_t) func_api_login, sec_hasp_api_login);
util_patch_function((uintptr_t) func_api_logout, sec_hasp_api_logout);
util_patch_function((uintptr_t) func_api_decrypt, sec_hasp_api_decrypt);
util_patch_function((uintptr_t) func_api_getid, sec_hasp_api_getid);
util_patch_function((uintptr_t) func_api_get_session_info,
sec_hasp_api_get_session_info);
sec_hasp_init(key_data, len);

View File

@ -18,6 +18,7 @@ struct sec_hasp_key_table {
/* static const uint32_t sec_hasp_features[] = {2, 3001}; */
static const uint32_t sec_hasp_key_id = 0xDEADBEEF;
static struct sec_hasp_key_table sec_hasp_keys;
static uint32_t sec_hasp_buffer_leak_count;
void sec_hasp_init(const uint8_t* key_data, size_t len)
{
@ -57,6 +58,30 @@ unsigned int sec_hasp_api_getid(void)
return sec_hasp_key_id;
}
int sec_hasp_api_get_session_info(int handle, const char* format, char** info)
{
log_debug("get session info, handle 0x%X, format %s", handle, format);
// The string to be returned should be in some XML format. However, the
// game is just using strstr to check for the following substring
// Furthermore, memory leaking the returned *info buffer as well as not
// knowing if other versions are actually freeing this using the correct
// free method of the hasp API.
// Since this function is not called a lot, i guess letting it leak is the
// most pragmatic solution. Let's keep track of that anyway and print
// some warnings once we reach quite a number of leaked buffers to not
// lose visibility if something bad ever happens
*info = util_str_dup("p id 322376503"); // 0x13371337
// Assuming the above buffers with alignment and some metadata needs
// ~32 bytes -> 1 MB = 32768 -> ~10 MB = 327680
if (++sec_hasp_buffer_leak_count >= 327680) {
log_warn("Memory leakage for unmanaged buffer exceeds 10 MB");
}
return 0;
}
int sec_hasp_api_decrypt(int handle, void* buffer, size_t length)
{
char* buf;

View File

@ -30,6 +30,8 @@ int sec_hasp_api_logout(int handle);
unsigned int sec_hasp_api_getid(void);
int sec_hasp_api_get_session_info(int handle, const char* format, char** info);
int sec_hasp_api_decrypt(int handle, void* buffer, size_t length);
#endif