3
0
mirror of https://github.com/CrazyRedMachine/popnhax.git synced 2024-11-23 22:00:57 +01:00

extended_debug

This commit is contained in:
CrazyRedMachine 2024-10-02 21:17:09 +02:00
parent 6a667eb65a
commit 5202badfe8
12 changed files with 588 additions and 512 deletions

View File

@ -5,8 +5,6 @@
#include "SearchFile.h"
#include "util/search.h"
#include "util/log.h"
#include "util/patch.h"
@ -16,9 +14,6 @@
#include "imports/avs.h"
#include "xmlhelper.h"
#include "minhook/hde32.h"
#include "minhook/include/MinHook.h"
#include "custom_categs.h"
extern const char* g_game_dll_fn;
@ -97,7 +92,7 @@ bool patch_ex_attract(uint16_t target_bpm)
char *data = getDllData(g_game_dll_fn, &dllSize);
{
int64_t pattern_offset = search(data, dllSize, "\x81\xE7\x01\x00\x00\x80\x79\x05\x4F", 9, 0);
int64_t pattern_offset = _search(data, dllSize, "\x81\xE7\x01\x00\x00\x80\x79\x05\x4F", 9, 0);
if (pattern_offset == -1) {
LOG("popnhax: attract_ex: cannot find attract mode song info\n");
return false;
@ -105,14 +100,14 @@ bool patch_ex_attract(uint16_t target_bpm)
uint64_t patch_addr = (int64_t)data + pattern_offset;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_ex_attract,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_ex_attract,
(void **)&real_attract);
}
if ( target_bpm != 0 )
{
g_attract_target_bpm = target_bpm;
int64_t pattern_offset = search(data, dllSize, "\x43\x83\xC1\x0C\x83\xEF\x01\x75", 8, 0);
int64_t pattern_offset = _search(data, dllSize, "\x43\x83\xC1\x0C\x83\xEF\x01\x75", 8, 0);
if (pattern_offset == -1) {
LOG("WARNING: attract_ex: cannot find chart prepare function (cannot set target bpm)\n");
return true;
@ -120,7 +115,7 @@ bool patch_ex_attract(uint16_t target_bpm)
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x0A;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_ex_attract_hispeed,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_ex_attract_hispeed,
(void **)&real_chart_prepare);
LOG("popnhax: attract mode will play EX charts at %u bpm\n", target_bpm);
@ -137,7 +132,7 @@ bool patch_full_attract()
char *data = getDllData(g_game_dll_fn, &dllSize);
{
int64_t pattern_offset = search(data, dllSize, "\xB8\xD0\x07\x00\x00\x66\xA3", 7, 0);
int64_t pattern_offset = _search(data, dllSize, "\xB8\xD0\x07\x00\x00\x66\xA3", 7, 0);
if (pattern_offset == -1) {
LOG("popnhax: attract_full: cannot find attract mode timer set function\n");
return false;
@ -230,7 +225,7 @@ bool patch_attract_interactive()
/* retrieve autoplay marker address */
{
int64_t pattern_offset = search(data, dllSize, "\x33\xC4\x89\x44\x24\x0C\x56\x57\x53\xE8", 10, 0);
int64_t pattern_offset = _search(data, dllSize, "\x33\xC4\x89\x44\x24\x0C\x56\x57\x53\xE8", 10, 0);
if (pattern_offset == -1) {
LOG("popnhax: attract_interactive: cannot find set autoplay marker function call\n");
return false;
@ -246,7 +241,7 @@ bool patch_attract_interactive()
/* retrieve attract demo marker address */
{
int64_t pattern_offset = search(data, dllSize, "\x00\x00\x88\x46\x18\x88\x46", 7, 0);
int64_t pattern_offset = _search(data, dllSize, "\x00\x00\x88\x46\x18\x88\x46", 7, 0);
if (pattern_offset == -1) {
LOG("popnhax: attract_interactive: cannot find get songinfozone function call\n");
return false;
@ -254,19 +249,19 @@ bool patch_attract_interactive()
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x02;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_retrieve_attractmarker,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_retrieve_attractmarker,
(void **)&real_rearm_marker);
}
/* enable interactive mode on button press (except red) */
{
int64_t pattern_offset = wildcard_search(data, dllSize, "\xCC\xCC\x53\x32\xDB\xE8????\x84\xC0\x74\x78", 14, 0);
int64_t pattern_offset = _wildcard_search(data, dllSize, "\xCC\xCC\x53\x32\xDB\xE8????\x84\xC0\x74\x78", 14, 0);
if (pattern_offset == -1) {
LOG("popnhax: attract_interactive: cannot find attract mode demo loop function\n");
return false;
}
int64_t pattern_offset2 = search(data, dllSize-pattern_offset, "\x6A\x10\xE8", 3, pattern_offset);
int64_t pattern_offset2 = _search(data, dllSize-pattern_offset, "\x6A\x10\xE8", 3, pattern_offset);
if (pattern_offset2 == -1) {
LOG("popnhax: attract_interactive: cannot find isButtonPressed function\n");
return false;
@ -276,13 +271,13 @@ bool patch_attract_interactive()
g_is_button_pressed_fn = patch_addr2+5+function_offset;
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x02;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_attract_inter,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_attract_inter,
(void **)&real_attract_inter);
}
/* disable interactive mode after a while without button press */
{
int64_t pattern_offset = search(data, dllSize, "\x3D\x58\x02\x00\x00\x7C", 6, 0);
int64_t pattern_offset = _search(data, dllSize, "\x3D\x58\x02\x00\x00\x7C", 6, 0);
if (pattern_offset == -1) {
LOG("popnhax: attract_interactive: cannot find retire handling\n");
return false;
@ -290,13 +285,13 @@ bool patch_attract_interactive()
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x07;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_attract_inter_rearm,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_attract_inter_rearm,
(void **)&real_retire_handling);
}
/* fix end of song crash */
{
int64_t pattern_offset = search(data, dllSize, "\xB8\xD0\x07\x00\x00\x66\xA3", 7, 0);
int64_t pattern_offset = _search(data, dllSize, "\xB8\xD0\x07\x00\x00\x66\xA3", 7, 0);
if (pattern_offset == -1) {
LOG("popnhax: attract_full: cannot find attract mode timer set function\n");
return false;
@ -306,13 +301,13 @@ bool patch_attract_interactive()
uint8_t new_pattern[8] = "\x66\x83\x05\x00\x00\x00\x00";
memcpy(new_pattern+3, &timer_addr, 4);
pattern_offset = search(data, dllSize, (const char *)new_pattern, 7, 0);
pattern_offset = _search(data, dllSize, (const char *)new_pattern, 7, 0);
if (pattern_offset == -1) {
LOG("popnhax: attract_interactive: cannot find attract mode timer set function\n");
return false;
}
int64_t pattern_offset2 = search(data, dllSize-pattern_offset, "\x66\x85\xC0\x74", 4, pattern_offset);
int64_t pattern_offset2 = _search(data, dllSize-pattern_offset, "\x66\x85\xC0\x74", 4, pattern_offset);
if (pattern_offset2 == -1) {
LOG("popnhax: attract_interactive: cannot find end of song handling function\n");
return false;
@ -320,13 +315,13 @@ bool patch_attract_interactive()
uint64_t patch_addr = (int64_t)data + pattern_offset2 + 0x05;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_attract_inter_songend_rearm,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_attract_inter_songend_rearm,
(void **)&real_songend_handling);
}
/* fix crash when pressing test button during interactive mode */
{
int64_t pattern_offset = search(data, dllSize, "\x83\xC4\x04\x84\xC0\x74\x75\x38\x1D", 9, 0);
int64_t pattern_offset = _search(data, dllSize, "\x83\xC4\x04\x84\xC0\x74\x75\x38\x1D", 9, 0);
if (pattern_offset == -1) {
LOG("popnhax: attract_interactive: cannot find test button handling\n");
return false;
@ -334,7 +329,7 @@ bool patch_attract_interactive()
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x07;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_attract_inter_rearm_test,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_attract_inter_rearm_test,
(void **)&real_test_handling);
}
@ -370,7 +365,7 @@ bool patch_attract_lights()
/* retrieve pressed button bitfield address */
{
int64_t pattern_offset = search(data, dllSize, "\x25\xFF\x0F\x00\x00\x5D\xC3\xCC\xCC\xCC\xCC\x55\x8B\xEC\x0F\xB6\x05", 17, 0);
int64_t pattern_offset = _search(data, dllSize, "\x25\xFF\x0F\x00\x00\x5D\xC3\xCC\xCC\xCC\xCC\x55\x8B\xEC\x0F\xB6\x05", 17, 0);
if (pattern_offset == -1) {
LOG("popnhax: attract_lights: cannot find button bitfield address\n");
return false;
@ -383,7 +378,7 @@ bool patch_attract_lights()
/* hook autoplay button trigger to force corresponding button lamps */
{
int64_t pattern_offset = search(data, dllSize, "\x66\xC1\xE0\x08\x0F\xB7\xC8\x83\xC9\x02\x51", 11, 0);
int64_t pattern_offset = _search(data, dllSize, "\x66\xC1\xE0\x08\x0F\xB7\xC8\x83\xC9\x02\x51", 11, 0);
if (pattern_offset == -1) {
LOG("popnhax: attract_lights: cannot find autopress button handling\n");
return false;
@ -391,7 +386,7 @@ bool patch_attract_lights()
uint64_t patch_addr = (int64_t)data + pattern_offset;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_attract_autoplay,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_attract_autoplay,
(void **)&real_autoplay_handling);
}

View File

@ -82,6 +82,7 @@ struct popnhax_config {
bool survival_spicy;
bool translation_debug;
uint16_t time_rate;
bool extended_debug;
};
bool config_process(const char *filepath); // take care of updating .xml/.opt files if needed

View File

@ -5,8 +5,6 @@
#include "SearchFile.h"
#include "util/search.h"
#include "util/log.h"
#include "util/patch.h"
@ -16,9 +14,6 @@
#include "imports/avs.h"
#include "xmlhelper.h"
#include "minhook/hde32.h"
#include "minhook/include/MinHook.h"
#include "custom_categs.h"
#define F_OK 0
@ -657,9 +652,9 @@ static bool patch_custom_track_format(const char *game_dll_fn) {
//hook format string for song/genre name
{
int64_t pattern_offset = search(data, dllSize, "\x83\xC4\x08\x8B\x44\x24\x50\x50\x68", 9, 0);
int64_t pattern_offset = _search(data, dllSize, "\x83\xC4\x08\x8B\x44\x24\x50\x50\x68", 9, 0);
if (pattern_offset == -1) {
pattern_offset = search(data, dllSize, "\x83\xC4\x08\x8B\x44\x24\x4C\x50\x68", 9, 0); //usaneko
pattern_offset = _search(data, dllSize, "\x83\xC4\x08\x8B\x44\x24\x4C\x50\x68", 9, 0); //usaneko
if (pattern_offset == -1) {
LOG("popnhax: custom_track_title_format: cannot find song/genre print function\n");
return false;
@ -668,13 +663,13 @@ static bool patch_custom_track_format(const char *game_dll_fn) {
uint64_t patch_addr = (int64_t)data + pattern_offset - 0x07;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_song_printf,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_song_printf,
(void **)&real_song_printf);
}
//hook format string for artist
{
int64_t pattern_offset = search(data, dllSize, "\x83\xC4\x08\x33\xFF\x8B\x43\x0C\x8B\x70\x04\x83\xC0\x04", 14, 0);
int64_t pattern_offset = _search(data, dllSize, "\x83\xC4\x08\x33\xFF\x8B\x43\x0C\x8B\x70\x04\x83\xC0\x04", 14, 0);
if (pattern_offset == -1) {
LOG("popnhax: custom_track_title_format: cannot find artist print function\n");
return false;
@ -682,7 +677,7 @@ static bool patch_custom_track_format(const char *game_dll_fn) {
uint64_t patch_addr = (int64_t)data + pattern_offset - 0x07;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_artist_printf,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_artist_printf,
(void **)&real_artist_printf);
}
@ -748,7 +743,7 @@ static bool patch_favorite_categ(const char *game_dll_fn, bool with_numpad9_patc
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);
int64_t pattern_offset = _search(data, dllSize, "\x8B\x4D\x10\x8B\x5D\x0C\x8B\xF1", 8, 0);
if (pattern_offset == -1) {
LOG("popnhax: local_favorites: cannot find add_song_in_list function\n");
return false;
@ -760,9 +755,9 @@ static bool patch_favorite_categ(const char *game_dll_fn, bool with_numpad9_patc
// 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);
int64_t pattern_offset = _search(data, dllSize, "\x83\xF8\x10\x77\x75\xFF\x24\x85", 8, 0);
if (pattern_offset == -1) {
pattern_offset = search(data, dllSize, "\x83\xF8\x11\x77\x7C\xFF\x24\x85", 8, 0); // jam&fizz
pattern_offset = _search(data, dllSize, "\x83\xF8\x11\x77\x7C\xFF\x24\x85", 8, 0); // jam&fizz
if (pattern_offset == -1) {
LOG("popnhax: local_favorites: cannot find category jump table\n");
return false;
@ -773,13 +768,13 @@ static bool patch_favorite_categ(const char *game_dll_fn, bool with_numpad9_patc
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,
_MH_CreateHook((LPVOID)function_addr, (LPVOID)categ_inject_favorites,
(void **)&real_categ_favorite);
}
//only active in normal mode
{
int64_t pattern_offset = search(data, dllSize, "\x83\xC4\x0C\x33\xC0\xC3\xCC\xCC\xCC\xCC\xE8", 11, 0);
int64_t pattern_offset = _search(data, dllSize, "\x83\xC4\x0C\x33\xC0\xC3\xCC\xCC\xCC\xCC\xE8", 11, 0);
if (pattern_offset == -1) {
LOG("popnhax: local_favorites: cannot find is_normal_mode function, fallback to best effort (active in all modes)\n");
}
@ -792,7 +787,7 @@ static bool patch_favorite_categ(const char *game_dll_fn, bool with_numpad9_patc
//categ_inject_favorites will need to force "logged in" status (for result screen)
{
//this is the same function used in score challenge patch, checking if we're logged in... but now we just directly retrieve the address
int64_t pattern_offset = search(data, dllSize, "\x8B\x01\x8B\x50\x14\xFF\xE2\xC3\xCC\xCC\xCC\xCC", 12, 0);
int64_t pattern_offset = _search(data, dllSize, "\x8B\x01\x8B\x50\x14\xFF\xE2\xC3\xCC\xCC\xCC\xCC", 12, 0);
if (pattern_offset == -1) {
LOG("popnhax: local_favorites: cannot find check if logged function\n");
return false;
@ -802,7 +797,7 @@ static bool patch_favorite_categ(const char *game_dll_fn, bool with_numpad9_patc
}
//I need to remove the fake "logged in" status on credit end to prevent a crash
{
int64_t pattern_offset = search(data, dllSize, "\x84\xC0\x74\x07\xBB\x01\x00\x00\x00\xEB\x02\x33\xDB", 13, 0);
int64_t pattern_offset = _search(data, dllSize, "\x84\xC0\x74\x07\xBB\x01\x00\x00\x00\xEB\x02\x33\xDB", 13, 0);
if (pattern_offset == -1) {
LOG("popnhax: local_favorites: cannot find end of credit check if logged function\n");
return false;
@ -810,20 +805,20 @@ static bool patch_favorite_categ(const char *game_dll_fn, bool with_numpad9_patc
uint64_t patch_addr = (int64_t)data + pattern_offset - 0x05;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_remove_fake_login,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_remove_fake_login,
(void **)&real_remove_fake_login);
}
//hook result screen to replace 3 functions
{
int64_t first_loc = search(data, dllSize, "\xBF\x07\x00\x00\x00\xC6\x85", 7, 0);
int64_t first_loc = _search(data, dllSize, "\xBF\x07\x00\x00\x00\xC6\x85", 7, 0);
if (first_loc == -1) {
LOG("popnhax: local_favorites: cannot find result screen function\n");
return false;
}
//song is in favorite
int64_t second_loc = search(data, 1000, "\x8B\xC8\xE8", 3, first_loc);
int64_t second_loc = _search(data, 1000, "\x8B\xC8\xE8", 3, first_loc);
if (second_loc == -1) {
LOG("popnhax: local_favorites: cannot retrieve is song in favorites call\n");
return false;
@ -831,11 +826,11 @@ static bool patch_favorite_categ(const char *game_dll_fn, bool with_numpad9_patc
uint64_t function_call_addr = (int64_t)(data + second_loc + 0x02);
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)hook_song_is_in_favorite,
_MH_CreateHook((LPVOID)function_addr, (LPVOID)hook_song_is_in_favorite,
(void **)&real_song_is_in_favorite);
//remove from favorites
int64_t third_loc = search(data, 1000, "\x6A\x01\x6A\x00\x68", 5, second_loc);
int64_t third_loc = _search(data, 1000, "\x6A\x01\x6A\x00\x68", 5, second_loc);
if (third_loc == -1) {
LOG("popnhax: local_favorites: cannot retrieve remove from favorites call\n");
return false;
@ -843,11 +838,11 @@ static bool patch_favorite_categ(const char *game_dll_fn, bool with_numpad9_patc
uint64_t function2_call_addr = (int64_t)(data + third_loc - 0x05);
uint32_t function2_offset = *((uint32_t*)(function2_call_addr +0x01));
uint64_t function2_addr = function2_call_addr+5+function2_offset;
MH_CreateHook((LPVOID)function2_addr, (LPVOID)hook_remove_from_favorite,
_MH_CreateHook((LPVOID)function2_addr, (LPVOID)hook_remove_from_favorite,
(void **)&real_remove_from_favorite);
//add to favorites
int64_t fourth_loc = search(data, 1000, "\x6A\x01\x6A\x00\x68", 5, third_loc+2);
int64_t fourth_loc = _search(data, 1000, "\x6A\x01\x6A\x00\x68", 5, third_loc+2);
if (fourth_loc == -1) {
LOG("popnhax: local_favorites: cannot retrieve add to favorites call\n");
return false;
@ -855,14 +850,14 @@ static bool patch_favorite_categ(const char *game_dll_fn, bool with_numpad9_patc
uint64_t function3_call_addr = (int64_t)(data + fourth_loc - 0x05);
uint32_t function3_offset = *((uint32_t*)(function3_call_addr +0x01));
uint64_t function3_addr = function3_call_addr+5+function3_offset;
MH_CreateHook((LPVOID)function3_addr, (LPVOID)hook_add_to_favorite,
_MH_CreateHook((LPVOID)function3_addr, (LPVOID)hook_add_to_favorite,
(void **)&real_add_to_favorite);
}
//(202310+) I need to prevent the numpad9 option in song select when fake logged in to prevent a possible softlock
if (with_numpad9_patch)
{
int64_t first_loc = search(data, dllSize, "\x0F\xB6\xC8\x51\x56\x8B\xCD\xE8", 8, 0);
int64_t first_loc = _search(data, dllSize, "\x0F\xB6\xC8\x51\x56\x8B\xCD\xE8", 8, 0);
if (first_loc == -1) {
LOG("WARNING: local_favorites: cannot find song select screen function, do NOT press 9 on song select\n");
goto local_favorite_ok;
@ -871,7 +866,7 @@ static bool patch_favorite_categ(const char *game_dll_fn, bool with_numpad9_patc
uint64_t function_call_addr = (int64_t)(data + first_loc - 0x05);
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)hook_check_event_boosts,
_MH_CreateHook((LPVOID)function_addr, (LPVOID)hook_check_event_boosts,
(void **)&real_check_event_boosts);
}
@ -912,7 +907,7 @@ static bool patch_custom_categ(const char *game_dll_fn, uint16_t min_id) {
//patch format string for any category above 16 (prevent crash)
{
int64_t pattern_offset = search(data, dllSize, "\x6A\xFF\x8B\xCB\xFF\xD2\x50", 7, 0);
int64_t pattern_offset = _search(data, dllSize, "\x6A\xFF\x8B\xCB\xFF\xD2\x50", 7, 0);
if (pattern_offset == -1) {
LOG("popnhax: custom_categ: cannot find category title format string function\n");
return false;
@ -921,17 +916,17 @@ static bool patch_custom_categ(const char *game_dll_fn, uint16_t min_id) {
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x07;
real_categ_printf_call = (void (*)())(patch_addr + 0x08);
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_categ_title_printf,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_categ_title_printf,
(void **)&real_categ_title_printf);
}
// 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);
int64_t pattern_offset = _search(data, dllSize, "\x83\xF8\x10\x77\x75\xFF\x24\x85", 8, 0);
uint8_t jump_size = 0x75; //as seen in pattern
if (pattern_offset == -1) {
jump_size = 0x7C; //as seen in pattern
pattern_offset = search(data, dllSize, "\x83\xF8\x11\x77\x7C\xFF\x24\x85", 8, 0); // jam&fizz
pattern_offset = _search(data, dllSize, "\x83\xF8\x11\x77\x7C\xFF\x24\x85", 8, 0); // jam&fizz
if (pattern_offset == -1) {
LOG("popnhax: custom_categ: cannot find category jump table\n");
return false;
@ -940,7 +935,7 @@ static bool patch_custom_categ(const char *game_dll_fn, uint16_t min_id) {
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x05 + jump_size; //hook at the end of jump table
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_categ_listing,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_categ_listing,
(void **)&real_categ_listing);
if (g_subcategmode)
@ -959,7 +954,7 @@ static bool patch_custom_categ(const char *game_dll_fn, uint16_t min_id) {
uint64_t patch_addr_2 = (int64_t)reimpl_func_2_generate_event_category + 80;
//need to inject correct memory zone after generation as well
MH_CreateHook((LPVOID)patch_addr_2, (LPVOID)hook_event_categ_generation,
_MH_CreateHook((LPVOID)patch_addr_2, (LPVOID)hook_event_categ_generation,
(void **)&real_event_categ_generation);
}
}
@ -971,7 +966,7 @@ static bool patch_custom_categ(const char *game_dll_fn, uint16_t min_id) {
}
else
{
int64_t pattern_offset = search(data, dllSize, "\x8B\x4D\x10\x8B\x5D\x0C\x8B\xF1", 8, 0);
int64_t pattern_offset = _search(data, dllSize, "\x8B\x4D\x10\x8B\x5D\x0C\x8B\xF1", 8, 0);
if (pattern_offset == -1) {
LOG("popnhax: custom_categ: cannot find add_song_in_list function\n");
return false;
@ -987,7 +982,7 @@ static bool patch_custom_categ(const char *game_dll_fn, uint16_t min_id) {
if (!g_subcategmode)
{
{
int64_t pattern_offset = search(data, dllSize, "\x00\x8B\x56\x04\x0F\xB7\x02\xE8", 8, 0);
int64_t pattern_offset = _search(data, dllSize, "\x00\x8B\x56\x04\x0F\xB7\x02\xE8", 8, 0);
if (pattern_offset == -1) {
LOG("popnhax: custom_categ: cannot find songlist processing table\n");
return false;
@ -995,13 +990,13 @@ static bool patch_custom_categ(const char *game_dll_fn, uint16_t min_id) {
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x07;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_categ_build_songlist,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_categ_build_songlist,
(void **)&real_categ_build_songlist);
}
//force rearm songlist creation so that it keeps working
{
int64_t pattern_offset = search(data, dllSize, "\xB8\x12\x00\x00\x00\xBA\x2B\x00\x00\x00\x89\x44\x24", 13, 0);
int64_t pattern_offset = _search(data, dllSize, "\xB8\x12\x00\x00\x00\xBA\x2B\x00\x00\x00\x89\x44\x24", 13, 0);
if (pattern_offset == -1) {
LOG("popnhax: custom_categ: cannot find category generation function\n");
return false;
@ -1009,7 +1004,7 @@ static bool patch_custom_categ(const char *game_dll_fn, uint16_t min_id) {
uint64_t patch_addr = (int64_t)data + pattern_offset;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_categ_reinit_songlist,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_categ_reinit_songlist,
(void **)&real_categ_reinit_songlist);
}
}
@ -1051,7 +1046,7 @@ static bool patch_custom_categ(const char *game_dll_fn, uint16_t min_id) {
//add the new name
uint64_t patch_addr = (int64_t)data + pattern_offset;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_get_categ_name,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_get_categ_name,
(void **)&real_get_categ_name);
}
@ -1078,7 +1073,7 @@ static bool patch_custom_categ(const char *game_dll_fn, uint16_t min_id) {
//add the new icon name
uint64_t patch_addr = (int64_t)data + pattern_offset;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_get_icon_name,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_get_icon_name,
(void **)&real_get_icon_name);
}
@ -1143,7 +1138,7 @@ bool patch_exclude(const char *game_dll_fn)
char *data = getDllData(game_dll_fn, &dllSize);
{
int64_t pattern_offset = search(data, dllSize, "\x8B\xF8\x83\xC4\x08\x85\xFF\x7E\x42", 9, 0);
int64_t pattern_offset = _search(data, dllSize, "\x8B\xF8\x83\xC4\x08\x85\xFF\x7E\x42", 9, 0);
if (pattern_offset == -1) {
LOG("popnhax: custom_exclude_from_level: cannot find songlist processing table\n");
return false;
@ -1151,7 +1146,7 @@ bool patch_exclude(const char *game_dll_fn)
uint64_t patch_addr = (int64_t)(data + pattern_offset);
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_after_getlevel,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_after_getlevel,
(void **)&real_after_getlevel);
}

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,6 @@
#include "util/bst.h"
#include "util/log.h"
#include "util/patch.h"
#include "util/search.h"
#include "libdisasm/libdis.h"
#include "omnimix_patch.h"

View File

@ -9,8 +9,6 @@
#include "util/jsmn.h"
#include "util/jsmn-find.h"
#include "util/search.h"
#include "util/log.h"
#include "util/patch.h"
@ -18,9 +16,6 @@
#include "libcurl/curl/curl.h"
#include "minhook/hde32.h"
#include "minhook/include/MinHook.h"
#define DEBUG_CURL 0
#if DEBUG_CURL == 1
@ -1065,10 +1060,10 @@ bool patch_tachi_rivals(const char *dllFilename, bool scorehook)
/* retrieve get_rivals_ptr() */
{
int64_t pattern_offset = search(data, dllSize, "\x0F\xB6\x8E\x38\x02\x00\x00", 7, 0);
int64_t pattern_offset = _search(data, dllSize, "\x0F\xB6\x8E\x38\x02\x00\x00", 7, 0);
if (pattern_offset == -1)
{
pattern_offset = search(data, dllSize, "\x0F\xB6\x89\x38\x02\x00\x00", 7, 0); // usaneko/peace
pattern_offset = _search(data, dllSize, "\x0F\xB6\x89\x38\x02\x00\x00", 7, 0); // usaneko/peace
if (pattern_offset == -1) {
LOG("popnhax: tachi rivals: cannot find get_rivals_ptr function\n");
return false;
@ -1081,7 +1076,7 @@ bool patch_tachi_rivals(const char *dllFilename, bool scorehook)
/* retrieve rival_entry_size */
{
int64_t pattern_offset = search(data, dllSize, "\x8B\xE5\x5D\xC2\x08\x00\x69\xDB", 8, 0);
int64_t pattern_offset = _search(data, dllSize, "\x8B\xE5\x5D\xC2\x08\x00\x69\xDB", 8, 0);
if (pattern_offset == -1)
{
LOG("popnhax: tachi rivals: cannot find rival entry size\n");
@ -1093,7 +1088,7 @@ bool patch_tachi_rivals(const char *dllFilename, bool scorehook)
/* retrieve offset where g_rival_count should be written */
{
int64_t pattern_offset = search(data, dllSize, "\x66\x83\xF8\xFF\x75\x07\x66\xFF\x87", 9, 0);
int64_t pattern_offset = _search(data, dllSize, "\x66\x83\xF8\xFF\x75\x07\x66\xFF\x87", 9, 0);
if (pattern_offset == -1)
{
LOG("popnhax: tachi rivals: cannot find rival entry size\n");
@ -1105,7 +1100,7 @@ bool patch_tachi_rivals(const char *dllFilename, bool scorehook)
/* retrieve write_rival_score */
{
int64_t pattern_offset = search(data, dllSize, "\x66\x8B\x0A\x50\x8A\x42\x04\xE8", 8, 0);
int64_t pattern_offset = _search(data, dllSize, "\x66\x8B\x0A\x50\x8A\x42\x04\xE8", 8, 0);
if (pattern_offset == -1)
{
LOG("popnhax: tachi rivals: cannot find rival entry size\n");
@ -1118,7 +1113,7 @@ bool patch_tachi_rivals(const char *dllFilename, bool scorehook)
/* hook credit end to reset "need to load conf" marker, if scorehook didn't already install it */
if ( !scorehook ) {
{ // same as in local favorites patch / score challenge / score hook
int64_t pattern_offset = search(data, dllSize, "\x8B\x01\x8B\x50\x14\xFF\xE2\xC3\xCC\xCC\xCC\xCC", 12, 0);
int64_t pattern_offset = _search(data, dllSize, "\x8B\x01\x8B\x50\x14\xFF\xE2\xC3\xCC\xCC\xCC\xCC", 12, 0);
if (pattern_offset == -1) {
LOG("popnhax: tachi rivals: cannot find check if logged function\n");
return false;
@ -1127,16 +1122,16 @@ bool patch_tachi_rivals(const char *dllFilename, bool scorehook)
}
{
int64_t pattern_offset = search(data, dllSize, "\x33\xC0\x89\x87\x18\x02\x00\x00\x89", 9, 0);
int64_t pattern_offset = _search(data, dllSize, "\x33\xC0\x89\x87\x18\x02\x00\x00\x89", 9, 0);
if (pattern_offset == -1) {
pattern_offset = search(data, dllSize, "\x33\xC0\x89\x86\x18\x02\x00\x00\x89", 9, 0); // usaneko/peace
pattern_offset = _search(data, dllSize, "\x33\xC0\x89\x86\x18\x02\x00\x00\x89", 9, 0); // usaneko/peace
if (pattern_offset == -1) {
LOG("popnhax: tachi rivals: cannot find end of credit check if logged function\n");
return false;
}
}
uint64_t patch_addr = (int64_t)data + pattern_offset;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_end_of_credit,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_end_of_credit,
(void **)&real_end_of_credit);
}
@ -1144,7 +1139,7 @@ bool patch_tachi_rivals(const char *dllFilename, bool scorehook)
/* hook after mode select logged in check */
{
int64_t pattern_offset = search(data, dllSize, "\x8B\xE5\x5D\xC3\x8B\xC6\xE8", 7, 0);
int64_t pattern_offset = _search(data, dllSize, "\x8B\xE5\x5D\xC3\x8B\xC6\xE8", 7, 0);
if (pattern_offset == -1)
{
@ -1153,7 +1148,7 @@ bool patch_tachi_rivals(const char *dllFilename, bool scorehook)
}
uint64_t patch_addr = (int64_t)data + pattern_offset + 11;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_mode_select_rival_inject,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_mode_select_rival_inject,
(void **)&real_mode_select);
}
@ -1187,7 +1182,7 @@ bool patch_tachi_scorehook(const char *dllFilename, bool pfree, bool hidden_is_o
/* retrieve song struct size */
{
int64_t pattern_offset = search(data, dllSize, "\x8B\x74\x24\x14\x0F\xB6\xC0", 7, 0);
int64_t pattern_offset = _search(data, dllSize, "\x8B\x74\x24\x14\x0F\xB6\xC0", 7, 0);
if (pattern_offset == -1) {
LOG("popnhax: tachi scorehook: cannot retrieve score zone offset computation function\n");
return false;
@ -1200,7 +1195,7 @@ bool patch_tachi_scorehook(const char *dllFilename, bool pfree, bool hidden_is_o
/* player data address (for friendid retrieval), same as local favorite patch */
{
//this is the same function used in score challenge patch, checking if we're logged in... but now we just directly retrieve the address
int64_t pattern_offset = search(data, dllSize, "\x8B\x01\x8B\x50\x14\xFF\xE2\xC3\xCC\xCC\xCC\xCC", 12, 0);
int64_t pattern_offset = _search(data, dllSize, "\x8B\x01\x8B\x50\x14\xFF\xE2\xC3\xCC\xCC\xCC\xCC", 12, 0);
if (pattern_offset == -1) {
LOG("popnhax: tachi scorehook: cannot find check if logged function\n");
return false;
@ -1210,9 +1205,9 @@ bool patch_tachi_scorehook(const char *dllFilename, bool pfree, bool hidden_is_o
}
/* hook credit end to reset "need to load conf" marker */
{
int64_t pattern_offset = search(data, dllSize, "\x33\xC0\x89\x87\x18\x02\x00\x00\x89", 9, 0);
int64_t pattern_offset = _search(data, dllSize, "\x33\xC0\x89\x87\x18\x02\x00\x00\x89", 9, 0);
if (pattern_offset == -1) {
pattern_offset = search(data, dllSize, "\x33\xC0\x89\x86\x18\x02\x00\x00\x89", 9, 0); // usaneko/peace
pattern_offset = _search(data, dllSize, "\x33\xC0\x89\x86\x18\x02\x00\x00\x89", 9, 0); // usaneko/peace
if (pattern_offset == -1) {
LOG("popnhax: tachi scorehook: cannot find end of credit check if logged function\n");
return false;
@ -1221,13 +1216,13 @@ bool patch_tachi_scorehook(const char *dllFilename, bool pfree, bool hidden_is_o
uint64_t patch_addr = (int64_t)data + pattern_offset;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_end_of_credit,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_end_of_credit,
(void **)&real_end_of_credit);
}
/* hook medal calculation */
{
int64_t pattern_offset = search(data, dllSize, "\x89\x84\x24\x68\x02\x00\x00\x8D\x44\x24\x20", 11, 0);
int64_t pattern_offset = _search(data, dllSize, "\x89\x84\x24\x68\x02\x00\x00\x8D\x44\x24\x20", 11, 0);
if (pattern_offset == -1) {
LOG("popnhax: tachi hook: cannot retrieve medal handling function\n");
@ -1235,13 +1230,13 @@ bool patch_tachi_scorehook(const char *dllFilename, bool pfree, bool hidden_is_o
}
uint64_t patch_addr = (int64_t)data + pattern_offset + 0x13;
MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_medal_commit,
_MH_CreateHook((LPVOID)patch_addr, (LPVOID)hook_medal_commit,
(void **)&real_medal_commit);
}
if (!pfree) //pfree already retrieves this info
{
int64_t pattern_offset = search(data, dllSize, "\x83\xC4\x0C\x33\xC0\xC3\xCC\xCC\xCC\xCC\xE8", 11, 0);
int64_t pattern_offset = _search(data, dllSize, "\x83\xC4\x0C\x33\xC0\xC3\xCC\xCC\xCC\xCC\xE8", 11, 0);
if (pattern_offset == -1) {
LOG("popnhax: tachi score hook: cannot find is_normal_mode function, fallback to best effort (active in all modes)\n");
}

View File

@ -3,8 +3,6 @@
#include <io.h>
#include <windows.h>
#include "util/search.h"
#include "util/log.h"
#include "util/patch.h"
@ -23,7 +21,7 @@ bool patch_sjis(const char *dllFilename, const char *find, uint8_t find_size, in
uint64_t patch_addr;
bool valid_sjis = false;
do {
*offset = search(data, dllSize-*offset, find, find_size, *offset);
*offset = _search(data, dllSize-*offset, find, find_size, *offset);
if (*offset == -1) {
*offset = offset_orig;
return false;

View File

@ -3,7 +3,6 @@ libs += util
srcpp_util := \
bst.cc \
membuf.cc \
search.cc \
cmdline.cc \
patch.cc \
crc32.cc \

View File

@ -3,9 +3,125 @@
#include <psapi.h>
// clang-format on
#include "util/search.h"
#include "util/log.h"
#include "libdisasm/libdis.h"
#include "patch.h"
#define LINE_SIZE 512
#define NO_OF_CHARS 256
// A utility function to get maximum of two integers
static int max(int a, int b) {
return (a > b) ? a : b;
}
// The preprocessing function for Boyer Moore's bad character heuristic
static void badCharHeuristic(const unsigned char *str, int size, int* badchar, bool wildcards) {
int i;
// Initialize all occurrences as -1
for (i = 0; i < NO_OF_CHARS; i++)
badchar[i] = -1;
// Fill the actual value of last occurrence of a character
if (wildcards)
{
int lastwildcard = -1;
for (i = 0; i < size; i++)
{
if (str[i] != '?')
badchar[(int) str[i]] = i;
else
lastwildcard = i;
}
for (i = 0; i < NO_OF_CHARS; i++)
{
if ( badchar[i] < lastwildcard )
badchar[i] = lastwildcard;
}
} else {
for (i = 0; i < size; i++)
badchar[(int) str[i]] = i;
}
}
#define DEBUG_SEARCH 0
int _search_ex(unsigned char *haystack, size_t haystack_size, const unsigned char *needle, size_t needle_size, int orig_offset, bool wildcards, int debug) {
int badchar[NO_OF_CHARS];
badCharHeuristic(needle, needle_size, badchar, wildcards);
int64_t s = 0; // s is shift of the pattern with respect to text
while (s <= (haystack_size - needle_size)) {
int j = needle_size - 1;
if (debug == 2)
{
LOG("--------------------------------\n");
LOG("txt...");
for (size_t i = 0; i < needle_size; i++)
{
LOG("%02x ", haystack[orig_offset+s+i]);
}
LOG("\n");
LOG("pat...");
for (size_t i = 0; i < needle_size; i++)
{
if (wildcards && needle[i] == '?')
LOG("** ");
else
LOG("%02x ", needle[i]);
}
LOG("\n");
}
if ( wildcards )
{
while (j >= 0 && ( needle[j] == '?' || needle[j] == haystack[orig_offset + s + j]) )
j--;
} else {
while (j >= 0 && ( needle[j] == haystack[orig_offset + s + j]) )
j--;
}
if (j < 0) {
if (debug)
LOG("found string at offset %llx!\n", orig_offset +s);
return orig_offset + s;
}
else
{
s += max(1, j - badchar[(int)haystack[orig_offset + s + j]]);
if (debug)
LOG("mismatch at pos %d, new offset %llx\n\n", j, orig_offset+s);
}
}
return -1;
}
int search(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset) {
int res = _search_ex((unsigned char*) haystack, haystack_size, (const unsigned char *)needle, needle_size, orig_offset, false, 0);
return res;
}
int wildcard_search(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset) {
int res = _search_ex((unsigned char*) haystack, haystack_size, (const unsigned char *)needle, needle_size, orig_offset, true, 0);
return res;
}
int search_debug(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset) {
int res = _search_ex((unsigned char*) haystack, haystack_size, (const unsigned char *)needle, needle_size, orig_offset, false, 2);
return res;
}
int wildcard_search_debug(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset) {
int res = _search_ex((unsigned char*) haystack, haystack_size, (const unsigned char *)needle, needle_size, orig_offset, true, 2);
return res;
}
void patch_memory(uint64_t patch_addr, char *data, size_t len) {
DWORD old_prot;
VirtualProtect((LPVOID)patch_addr, len, PAGE_EXECUTE_READWRITE, &old_prot);
@ -33,7 +149,7 @@ bool rva_to_offset(const char *dllFilename, uint32_t rva, uint32_t *offset)
uintptr_t baseAddr = (uintptr_t)GetModuleHandle(dllFilename);
IMAGE_DOS_HEADER * pDosHdr = (IMAGE_DOS_HEADER *) baseAddr;
IMAGE_NT_HEADERS * pNtHdr = (IMAGE_NT_HEADERS *) (baseAddr + pDosHdr->e_lfanew);
int i;
WORD wSections;
PIMAGE_SECTION_HEADER pSectionHdr;
@ -47,7 +163,7 @@ bool rva_to_offset(const char *dllFilename, uint32_t rva, uint32_t *offset)
rva -= pSectionHdr -> VirtualAddress;
rva += pSectionHdr -> PointerToRawData;
*offset = rva;
return true;
return true;
}
pSectionHdr++;
}
@ -59,7 +175,7 @@ bool offset_to_rva(const char *dllFilename, uint32_t offset, uint32_t *rva)
uintptr_t baseAddr = (uintptr_t)GetModuleHandle(dllFilename);
IMAGE_DOS_HEADER * pDosHdr = (IMAGE_DOS_HEADER *) baseAddr;
IMAGE_NT_HEADERS * pNtHdr = (IMAGE_NT_HEADERS *) (baseAddr + pDosHdr->e_lfanew);
int i;
WORD wSections;
PIMAGE_SECTION_HEADER pSectionHdr;
@ -73,7 +189,7 @@ bool offset_to_rva(const char *dllFilename, uint32_t offset, uint32_t *rva)
offset -= pSectionHdr -> PointerToRawData;
offset += pSectionHdr -> VirtualAddress;
*rva = offset;
*rva = offset;
return true;
}
@ -88,7 +204,7 @@ void find_and_patch_string(const char *dllFilename, const char *input_string, co
char *data = getDllData(dllFilename, &dllSize);
while (1) {
int64_t pattern_offset = search(data, dllSize, input_string, strlen(input_string), 0);
int64_t pattern_offset = _search(data, dllSize, input_string, strlen(input_string), 0);
if (pattern_offset == -1) {
break;
}
@ -105,7 +221,7 @@ int64_t find_and_patch_hex(const char *dllFilename, const char *find, uint8_t fi
DWORD dllSize = 0;
char *data = getDllData(dllFilename, &dllSize);
int64_t pattern_offset = search(data, dllSize, find, find_size, 0);
int64_t pattern_offset = _search(data, dllSize, find, find_size, 0);
if (pattern_offset == -1) {
return 0;
}
@ -139,4 +255,88 @@ int64_t find_and_patch_hex(const char *dllFilename, const char *find, uint8_t fi
return pattern_offset;
}
}
void log_cb(x86_insn_t *insn, void *arg)
{
char line[LINE_SIZE]; /* buffer of line to print */
x86_format_insn(insn, line, LINE_SIZE, intel_syntax);
LOG("%s\n", line);
}
MH_STATUS WINAPI patch_debug_MH_CreateHook(LPVOID patch_addr, LPVOID hook_function, LPVOID* real_function){
LOG("--- hooking function over this code ---\n");
x86_init(opt_none, NULL, NULL);
x86_disasm_range( (unsigned char *)patch_addr, 0, 0, 50, log_cb, NULL );
/*
int size = x86_disasm((unsigned char*)buf, dllSize, 0, ((uint32_t)(hook_addrs[i])-(uint32_t)buf+delta), &insn);
if ( size ) {
x86_format_insn(&insn, line, LINE_SIZE, intel_syntax);
membuf_printf(membuf, "\t\t<!-- %s -->\n", line);
x86_oplist_free(&insn);
}
*/
x86_cleanup();
LOG("------\n");
return MH_CreateHook(patch_addr, hook_function, real_function);
}
int patch_debug_search(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset)
{
LOG("--- Looking for pattern ");
for (size_t i = 0; i<needle_size; i++)
{
LOG("\\x%.02X", (unsigned char)needle[i]);
}
LOG("---\n");
int found = search(haystack, haystack_size, needle, needle_size, orig_offset);
if ( found != -1 )
{
LOG("--- found pattern at this code ---\n");
x86_init(opt_none, NULL, NULL);
x86_disasm_range( (unsigned char*)(haystack+found), 0, 0, 50, log_cb, NULL );
x86_cleanup();
LOG("------\n");
}
else
{
LOG("--- pattern not found ---\n");
}
return found;
}
int patch_debug_wildcard_search(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset)
{
LOG("--- Looking for wildcard pattern ");
for (size_t i = 0; i<needle_size; i++)
{
LOG("\\x%.02X", (unsigned char)needle[i]);
}
LOG("---\n");
int found = wildcard_search(haystack, haystack_size, needle, needle_size, orig_offset);
if ( found != -1 )
{
LOG("--- found wildcard pattern at this code ---\n");
x86_init(opt_none, NULL, NULL);
x86_disasm_range((unsigned char*)(haystack+found), 0, 0, 50, log_cb, NULL );
x86_cleanup();
LOG("\n");
}
else
{
LOG("--- wildcard pattern not found ---\n");
}
return found;
}
fn_search _search = search;
fn_wildcard_search _wildcard_search = wildcard_search;
fn_MH_CreateHook _MH_CreateHook = MH_CreateHook;
void enable_extended_debug()
{
_search = patch_debug_search;
_wildcard_search = patch_debug_wildcard_search;
_MH_CreateHook = patch_debug_MH_CreateHook;
}

View File

@ -5,8 +5,19 @@
#include <stddef.h>
#include <stdint.h>
#include "minhook/hde32.h"
#include "minhook/include/MinHook.h"
typedef unsigned long DWORD;
typedef int(*fn_search)(char*,size_t,const char*,size_t,size_t);
typedef int(*fn_wildcard_search)(char*,size_t,const char*,size_t,size_t);
typedef MH_STATUS(*fn_MH_CreateHook)(LPVOID,LPVOID,LPVOID*) WINAPI;
extern fn_search _search;
extern fn_wildcard_search _wildcard_search;
extern fn_MH_CreateHook _MH_CreateHook;
char *getDllData(const char *dllFilename, DWORD *dllSize);
bool rva_to_offset(const char *dllFilename, uint32_t rva, uint32_t *offset);
@ -17,4 +28,11 @@ void patch_memory(uint64_t patch_addr, char *data, size_t len);
int64_t find_and_patch_hex(const char *dllFilename, const char *find, uint8_t find_size, int64_t shift, const char *replace, uint8_t replace_size);
void find_and_patch_string(const char *dllFilename, const char *input_string, const char *new_string);
int search(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset);
int search_debug(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset);
int wildcard_search(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset);
int wildcard_search_debug(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset);
void enable_extended_debug();
#endif

View File

@ -1,118 +0,0 @@
#include <memory.h>
#include <stdint.h>
#include <cstdio>
#include "util/log.h"
#define NO_OF_CHARS 256
// A utility function to get maximum of two integers
static int max(int a, int b) {
return (a > b) ? a : b;
}
// The preprocessing function for Boyer Moore's bad character heuristic
static void badCharHeuristic(const unsigned char *str, int size, int* badchar, bool wildcards) {
int i;
// Initialize all occurrences as -1
for (i = 0; i < NO_OF_CHARS; i++)
badchar[i] = -1;
// Fill the actual value of last occurrence of a character
if (wildcards)
{
int lastwildcard = -1;
for (i = 0; i < size; i++)
{
if (str[i] != '?')
badchar[(int) str[i]] = i;
else
lastwildcard = i;
}
for (i = 0; i < NO_OF_CHARS; i++)
{
if ( badchar[i] < lastwildcard )
badchar[i] = lastwildcard;
}
} else {
for (i = 0; i < size; i++)
badchar[(int) str[i]] = i;
}
}
#define DEBUG_SEARCH 0
int _search(unsigned char *haystack, size_t haystack_size, const unsigned char *needle, size_t needle_size, int orig_offset, bool wildcards, int debug) {
int badchar[NO_OF_CHARS];
badCharHeuristic(needle, needle_size, badchar, wildcards);
int64_t s = 0; // s is shift of the pattern with respect to text
while (s <= (haystack_size - needle_size)) {
int j = needle_size - 1;
if (debug == 2)
{
LOG("--------------------------------\n");
LOG("txt...");
for (size_t i = 0; i < needle_size; i++)
{
LOG("%02x ", haystack[orig_offset+s+i]);
}
LOG("\n");
LOG("pat...");
for (size_t i = 0; i < needle_size; i++)
{
if (wildcards && needle[i] == '?')
LOG("** ");
else
LOG("%02x ", needle[i]);
}
LOG("\n");
}
if ( wildcards )
{
while (j >= 0 && ( needle[j] == '?' || needle[j] == haystack[orig_offset + s + j]) )
j--;
} else {
while (j >= 0 && ( needle[j] == haystack[orig_offset + s + j]) )
j--;
}
if (j < 0) {
if (debug)
LOG("found string at offset %llx!\n", orig_offset +s);
return orig_offset + s;
}
else
{
s += max(1, j - badchar[(int)haystack[orig_offset + s + j]]);
if (debug)
LOG("mismatch at pos %d, new offset %llx\n\n", j, orig_offset+s);
}
}
return -1;
}
int search(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset) {
int res = _search((unsigned char*) haystack, haystack_size, (const unsigned char *)needle, needle_size, orig_offset, false, 0);
return res;
}
int wildcard_search(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset) {
int res = _search((unsigned char*) haystack, haystack_size, (const unsigned char *)needle, needle_size, orig_offset, true, 0);
return res;
}
int search_debug(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset) {
int res = _search((unsigned char*) haystack, haystack_size, (const unsigned char *)needle, needle_size, orig_offset, false, 2);
return res;
}
int wildcard_search_debug(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset) {
int res = _search((unsigned char*) haystack, haystack_size, (const unsigned char *)needle, needle_size, orig_offset, true, 2);
return res;
}

View File

@ -1,9 +0,0 @@
#ifndef __SEARCH_H__
#define __SEARCH_H__
int search(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset);
int search_debug(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset);
int wildcard_search(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset);
int wildcard_search_debug(char *haystack, size_t haystack_size, const char *needle, size_t needle_size, size_t orig_offset);
#endif