diff --git a/popnhax/custom_categs.cc b/popnhax/custom_categs.cc index 7ffdd7e..b4d56d2 100644 --- a/popnhax/custom_categs.cc +++ b/popnhax/custom_categs.cc @@ -46,7 +46,7 @@ static bool subcateg_has_songid(uint32_t songid, subcategory_s* subcateg) static void add_song_to_subcateg(uint32_t songid, subcategory_s* subcateg) { - if ( songid >= 3000 && !subcateg_has_songid(songid, subcateg) ) + if ( songid >= 4000 && !subcateg_has_songid(songid, subcateg) ) { subcateg->songlist = (uint32_t *) realloc(subcateg->songlist, sizeof(uint32_t)*(++subcateg->size)); subcateg->songlist[subcateg->size-1] = songid; @@ -69,6 +69,12 @@ const char *g_categname = "Custom Tracks"; const char *g_categicon = "cate_13"; const char *g_categformat = "[ol:4][olc:d92f0d]%s"; +char *g_string_addr; +uint8_t idx = 0; +uint32_t tmp_size = 0; +uint32_t tmp_categ_ptr = 0; +uint32_t tmp_songlist_ptr = 0; + uint32_t songlist[4096] = {0}; uint32_t songlist_addr = (uint32_t)&songlist; uint32_t songlist_count = 0; @@ -78,26 +84,34 @@ struct songlist_struct_s { uint32_t array_start; uint32_t array_end; } songlist_struct; - uint32_t songlist_struct_addr = (uint32_t)&songlist_struct; void (*add_song_in_list)(); void (*categ_inject_songlist)(); - +struct songlist_struct_s *new_song_list = NULL; void get_subcateg_size_impl() { - __asm("mov eax, 0"); + __asm("push edx\n"); + __asm("mov _idx, eax\n"); + tmp_size = subcategories[idx-2].size; +// tmp_categ_ptr = (uint32_t)&(subcategories[idx]); +// tmp_songlist_ptr = (uint32_t)&(subcategories[idx].songlist); +// new_song_list = (struct songlist_struct_s*) songlist_struct_addr; + new_song_list = (struct songlist_struct_s*) calloc(1, sizeof(struct songlist_struct_s)); + new_song_list->array_start = (uint32_t)&(subcategories[idx-2].songlist[0]); + new_song_list->array_end = (uint32_t)&(subcategories[idx-2].songlist[tmp_size]); + __asm("mov eax, [_tmp_size]"); + __asm("mov ecx, _new_song_list"); + __asm("pop edx\n"); } -char *g_string_addr; -uint8_t idx = 0; void get_subcateg_name_impl() { __asm("push ecx\n"); __asm("push edx\n"); __asm("mov _idx, eax\n"); - g_string_addr = subcategories[idx].name; + g_string_addr = subcategories[idx-2].name; __asm("mov eax, _g_string_addr"); __asm("pop edx\n"); __asm("pop ecx\n"); @@ -105,7 +119,7 @@ void get_subcateg_name_impl() uint32_t reimpl_value_1; uint32_t reimpl_value_2; -void (*get_subcateg_size)();// = &get_subcateg_size_impl; +void (*get_subcateg_size)() = &get_subcateg_size_impl; void (*get_subcateg_name)() = &get_subcateg_name_impl; void (*reimpl_func_1)(); void (*reimpl_func_2)(); @@ -137,6 +151,7 @@ void categ_inject_songlist_reimpl() __asm("mov dword ptr fs:[0], eax\n"); __asm("mov ebp, dword ptr [esp+0x34]\n"); __asm("xor ebx, ebx\n"); +__asm("mov ebx, 2\n"); __asm("mov dword ptr ss:[esp+0x34], ebx\n"); __asm("subcateg_loop:\n"); __asm("mov ecx, dword ptr ss:[ebp+0x08]\n"); @@ -216,7 +231,13 @@ void categ_inject_songlist_reimpl() __asm("next_iter:\n"); __asm("inc ebx\n"); __asm("mov dword ptr ss:[esp+0x34], ebx\n"); - __asm("cmp ebx, [_subcateg_count]\n"); + + __asm("push ecx"); + __asm("mov ecx, [_subcateg_count]\n"); + __asm("add ecx, 2\n"); + __asm("cmp ebx, ecx\n"); + __asm("pop ecx"); + __asm("jb subcateg_loop\n"); __asm("mov ecx, dword ptr ss:[esp+0x24]\n"); __asm("mov dword ptr fs:[0], ecx\n"); @@ -243,10 +264,13 @@ void categ_inject_songlist_impl() __asm("pop ecx\n"); } +bool mask_applied = false; + void (*real_categ_reinit_songlist)(); void hook_categ_reinit_songlist() { songlist_count = 0; + mask_applied = false; real_categ_reinit_songlist(); } @@ -269,6 +293,76 @@ void hook_categ_build_songlist() real_categ_build_songlist(); } +uint32_t songid_mask = 0; +void apply_mask_to_all() +{ + __asm("push eax"); + __asm("mov eax, [ebx]"); + __asm("mov _songid_mask, eax"); + __asm("pop eax"); + songid_mask &= 0xFFFF0000; + for (uint32_t i = 0; i < subcateg_count; i++) + { + for (uint32_t j = 0; j < subcategories[i].size; j++) + { + subcategories[i].songlist[j] |= songid_mask; + } + } +} + + +//cherche dans toutes mes categ où est la song que je veux +//et renvoie un pointeur dessus dans eax +uint32_t *return_value; +void put_song_addr_in_eax() +{ + for (uint32_t i = 0; i < subcateg_count; i++) + { + for (uint32_t j = 0; j < subcategories[i].size; j++) + { + if (subcategories[i].songlist[j] == (songid_mask&0xFFFF)) + { + return_value = &(subcategories[i].songlist[j]); + __asm("mov eax, [_return_value]"); + return; + } + } + } +} + +void hook_subcateg_adjust_songlist() +{ +#if 1 + __asm("cmp eax, 0xFA0\n"); + __asm("jb skip_mask\n"); + + __asm("push eax"); + __asm("push ebx"); + __asm("push ecx"); + __asm("push edx"); + + __asm("push eax"); + __asm("mov eax, [ebx]"); + __asm("mov _songid_mask, eax"); + __asm("pop eax"); +//songid_mask contient le uint32_t complet + put_song_addr_in_eax(); +__asm("mov ebx, _songid_mask"); +__asm("mov [eax], ebx"); + + __asm("pop edx"); + __asm("pop ecx"); + __asm("pop ebx"); + __asm("pop eax"); +#else + __asm("cmp byte ptr [_mask_applied], 0\n"); + __asm("jne skip_mask\n"); + apply_mask_to_all(); + mask_applied = true; +#endif + __asm("skip_mask:\n"); + real_categ_build_songlist(); +} void (*real_categ_printf_call)(); void (*real_categ_title_printf)(); @@ -339,7 +433,7 @@ static bool patch_custom_categ_simple(const char *game_dll_fn) { reimpl_func_3 = (void (*)())( *((uint32_t*)(function_addr +0xBC)) + (uint32_t)(function_addr +0x04 +0xBC) ); reimpl_func_4 = (void (*)())( *((uint32_t*)(function_addr +0xD1)) + (uint32_t)(function_addr +0x04 +0xD1) ); - get_subcateg_size = (void (*)())( *((uint32_t*)(function_addr +0x37)) + (uint32_t)(function_addr +0x04 +0x37) ); + //get_subcateg_size = (void (*)())( *((uint32_t*)(function_addr +0x37)) + (uint32_t)(function_addr +0x04 +0x37) ); //get_subcateg_name = (void (*)())( *((uint32_t*)(function_addr +0x63)) + (uint32_t)(function_addr +0x04 +0x63) ); MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_categ_listing, @@ -386,8 +480,16 @@ static bool patch_custom_categ_simple(const char *game_dll_fn) { uint64_t patch_addr = (int64_t)data + pattern_offset + 0x07; - MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_categ_build_songlist, + if (g_subcategmode) + { + MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_subcateg_adjust_songlist, (void **)&real_categ_build_songlist); + } + else + { + MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_categ_build_songlist, + (void **)&real_categ_build_songlist); + } } //create new song list