forked from Popn_Tools/popnhax
poc favorite
This commit is contained in:
parent
2dcc503eca
commit
badd6535b3
@ -19,6 +19,14 @@
|
||||
#include "minhook/hde32.h"
|
||||
#include "minhook/include/MinHook.h"
|
||||
|
||||
void (*add_song_in_list)();
|
||||
//game code takes array start address from offset 0xC and the address after the list end from offset 0x10
|
||||
typedef struct songlist_s {
|
||||
uint32_t dummy[3];
|
||||
uint32_t array_start;
|
||||
uint32_t array_end;
|
||||
} songlist_t;
|
||||
|
||||
bool g_subcategmode = false;
|
||||
uint32_t g_min_id = 4000;
|
||||
uint32_t g_max_id = 0;
|
||||
@ -34,6 +42,30 @@ uint32_t tmp_size = 0;
|
||||
uint32_t tmp_categ_ptr = 0;
|
||||
uint32_t tmp_songlist_ptr = 0;
|
||||
|
||||
uint32_t* favorites;
|
||||
uint32_t favorites_addr = (uint32_t)&favorites;
|
||||
uint32_t favorites_count = 0;
|
||||
songlist_t favorites_struct;
|
||||
uint32_t favorites_struct_addr = (uint32_t)&favorites_struct;
|
||||
|
||||
//this replaces the category handling function ( add_song_in_list is a subroutine called by the game )
|
||||
void (*real_categ_favorite)();
|
||||
void categ_inject_favorites()
|
||||
{
|
||||
__asm("push ecx\n");
|
||||
__asm("push edx\n");
|
||||
favorites_struct.array_start = (uint32_t)favorites;
|
||||
favorites_struct.array_end = (uint32_t)&(favorites[favorites_count]);
|
||||
__asm("pop edx\n");
|
||||
__asm("pop ecx\n");
|
||||
__asm("push ecx\n");
|
||||
__asm("push _favorites_struct_addr\n");
|
||||
__asm("lea eax, dword ptr [ecx+0x24]\n");
|
||||
__asm("call [_add_song_in_list]\n");
|
||||
__asm("pop ecx\n");
|
||||
__asm("ret\n"); //because we patch inside the function
|
||||
}
|
||||
|
||||
#define SIMPLE_CATEG_ALLOC 1
|
||||
|
||||
#if SIMPLE_CATEG_ALLOC == 1
|
||||
@ -44,11 +76,7 @@ uint32_t songlist[4096] = {0};
|
||||
uint32_t songlist_addr = (uint32_t)&songlist;
|
||||
uint32_t songlist_count = 0;
|
||||
|
||||
struct songlist_struct_s {
|
||||
uint32_t dummy[3];
|
||||
uint32_t array_start;
|
||||
uint32_t array_end;
|
||||
} songlist_struct;
|
||||
songlist_t songlist_struct;
|
||||
uint32_t songlist_struct_addr = (uint32_t)&songlist_struct;
|
||||
|
||||
typedef struct {
|
||||
@ -101,17 +129,16 @@ static subcategory_s* get_subcateg(char *title)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void (*add_song_in_list)();
|
||||
void (*categ_inject_songlist)();
|
||||
|
||||
struct songlist_struct_s *new_song_list = NULL;
|
||||
songlist_t *new_song_list = NULL;
|
||||
void get_subcateg_size_impl()
|
||||
{
|
||||
__asm("push edx\n");
|
||||
__asm("mov _idx, eax\n");
|
||||
|
||||
tmp_size = subcategories[idx].size;
|
||||
new_song_list = (struct songlist_struct_s*) songlist_struct_addr;
|
||||
new_song_list = (songlist_t*) songlist_struct_addr;
|
||||
new_song_list->array_start = (uint32_t)&(subcategories[idx].songlist[0]);
|
||||
new_song_list->array_end = (uint32_t)&(subcategories[idx].songlist[tmp_size]);
|
||||
|
||||
@ -138,7 +165,7 @@ void hook_event_categ_generation()
|
||||
if ( (uint32_t)subcategories[i].name == tmp_str_addr )
|
||||
{
|
||||
tmp_size = subcategories[i].size;
|
||||
new_song_list = (struct songlist_struct_s*) songlist_struct_addr;
|
||||
new_song_list = (songlist_t*) songlist_struct_addr;
|
||||
new_song_list->array_start = (uint32_t)&(subcategories[i].songlist[0]);
|
||||
new_song_list->array_end = (uint32_t)&(subcategories[i].songlist[tmp_size]);
|
||||
break;
|
||||
@ -465,6 +492,45 @@ static bool patch_custom_highlight(const char *game_dll_fn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool patch_favorite_categ(const char *game_dll_fn) {
|
||||
|
||||
DWORD dllSize = 0;
|
||||
char *data = getDllData(game_dll_fn, &dllSize);
|
||||
|
||||
if (add_song_in_list == NULL) {
|
||||
int64_t pattern_offset = search(data, dllSize, "\x8B\x4D\x10\x8B\x5D\x0C\x8B\xF1", 8, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: custom_favorites: cannot find add_song_in_list function\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
//I need to call this subfunction from my hook
|
||||
add_song_in_list = (void (*)())(data + pattern_offset - 0x12);
|
||||
}
|
||||
|
||||
// patch category handling jumptable to add our processing
|
||||
{
|
||||
int64_t pattern_offset = search(data, dllSize, "\x83\xF8\x10\x77\x75\xFF\x24\x85", 8, 0);
|
||||
if (pattern_offset == -1) {
|
||||
LOG("popnhax: custom_favorites: cannot find category jump table\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
//uint64_t patch_addr = (int64_t)data + pattern_offset + 0x05 + 0x5A; //call to function when categ is favorites
|
||||
|
||||
|
||||
|
||||
uint64_t function_call_addr = (int64_t)(data + pattern_offset + 0x05 + 0x5A);
|
||||
uint32_t function_offset = *((uint32_t*)(function_call_addr +0x01));
|
||||
uint64_t function_addr = function_call_addr+5+function_offset;
|
||||
|
||||
MH_CreateHook((LPVOID)function_addr, (LPVOID)categ_inject_favorites,
|
||||
(void **)&real_categ_favorite);
|
||||
}
|
||||
LOG("popnhax: custom_favorites: favorite category handling replaced\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool patch_custom_categ(const char *game_dll_fn) {
|
||||
|
||||
DWORD dllSize = 0;
|
||||
@ -681,6 +747,31 @@ static void load_databases() {
|
||||
LOG("\n");
|
||||
}
|
||||
|
||||
bool load_favorites(){
|
||||
FILE *file = fopen("data_mods\\default.fav", "rb");
|
||||
|
||||
if (file == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char line[32];
|
||||
|
||||
while (fgets(line, sizeof(line), file)) {
|
||||
/* note that fgets don't strip the terminating \n, checking its
|
||||
presence would allow to handle lines longer that sizeof(line) */
|
||||
int songid = strtol(line, NULL, 10);
|
||||
if ( songid != 0 )
|
||||
{
|
||||
favorites = (uint32_t *) realloc(favorites, sizeof(uint32_t)*(favorites_count+5));
|
||||
favorites[favorites_count++] = songid | 0x00060000; // game wants this otherwise only easy difficulty will appear
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
LOG("added %d songs to favorites\n",favorites_count);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool patch_custom_categs(const char *dllFilename, uint8_t mode, uint16_t min, uint16_t max)
|
||||
{
|
||||
g_min_id = min;
|
||||
@ -696,5 +787,8 @@ bool patch_custom_categs(const char *dllFilename, uint8_t mode, uint16_t min, ui
|
||||
|
||||
patch_custom_highlight(dllFilename);
|
||||
|
||||
load_favorites();
|
||||
patch_favorite_categ(dllFilename);
|
||||
|
||||
return patch_custom_categ(dllFilename);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user