@@ -646,7 +646,8 @@ void patch_data1(int pid, const char* patch_type_str, uint64_t addr, const char*
646646 }
647647 }
648648}
649-
649+ #define CHUNK_SIZE (16 * 1024 * 1024 )
650+ #define PATTERN_OVERLAP 1024 // Max expected pattern size
650651int Xml_ParseGamePatch (GamePatchInfo* info)
651652{
652653 uint32_t patch_lines = 0 ;
@@ -780,39 +781,115 @@ int Xml_ParseGamePatch(GamePatchInfo* info)
780781 }
781782 if (use_mask)
782783 {
783-
784- #if 0
785- module_info_t* mod = get_module_info(info->image_pid, info->ImageSelf);
786- if(!mod){
787- printf_notification("unable to get module info");
788- return 1;
789- }
790- #endif
791- g_module_base = info->image_base ;
792- g_module_size = info->image_size ;
793- #if 0
794- free(mod);
795- #endif
796- cheat_log (" g_module_base vaddr 0x%p" , g_module_base);
797- uint64_t jump_addr = 0 ;
798- uint32_t jump_size = 0 ;
799- const char * gameOffset = nullptr ;
800- if (startsWith (gameType, " mask_jump32" ))
801- {
802- const char * gameJumpTarget = GetXMLAttr (Line_node, " Target" );
803- const char * gameJumpSize = GetXMLAttr (Line_node, " Size" );
804- jump_addr = addr_real = (uint64_t )PatternScan (g_module_base, g_module_size, gameJumpTarget);
805- jump_size = strtoul (gameJumpSize, NULL , 10 );
806- cheat_log (" Target: 0x%lx jump size %u\n " , jump_addr, jump_size);
807- }
808- gameOffset = GetXMLAttr (Line_node, " Offset" );
809- cheat_log (" gameAddr %s" , gameAddr);
810- addr_real = (uint64_t )PatternScan (g_module_base, g_module_size, gameAddr);
811- if (!addr_real)
812- {
813- cheat_log (" Masked Address: %s not found\n " , gameAddr);
814- continue ;
815- }
784+ g_module_base = info->image_base ;
785+ g_module_size = info->image_size ;
786+
787+ cheat_log (" g_module_base vaddr 0x%p, size: 0x%lx" , g_module_base, g_module_size);
788+
789+ // Allocate buffer for chunks (with overlap space)
790+ char *chunk_buffer = (char *)malloc (CHUNK_SIZE + PATTERN_OVERLAP);
791+ cheat_log (" chunk_buffer: 0x%p" , chunk_buffer);
792+ if (!chunk_buffer) {
793+ cheat_log (" chunk_buffer is nullptr" );
794+ return false ;
795+ }
796+
797+ uint64_t jump_addr = 0 ;
798+ uint32_t jump_size = 0 ;
799+ const char * gameOffset = nullptr ;
800+ const char * gameJumpTarget = nullptr ;
801+ const char * gameJumpSize = nullptr ;
802+
803+ // Get pattern strings
804+ if (startsWith (gameType, " mask_jump32" )) {
805+ gameJumpTarget = GetXMLAttr (Line_node, " Target" );
806+ gameJumpSize = GetXMLAttr (Line_node, " Size" );
807+ jump_size = strtoul (gameJumpSize, NULL , 10 );
808+ }
809+ gameOffset = GetXMLAttr (Line_node, " Offset" );
810+ cheat_log (" gameAddr %s" , gameAddr);
811+
812+ bool found_main_pattern = false ;
813+ bool found_jump_pattern = false ;
814+ uint64_t overlap_size = 0 ;
815+
816+ // Scan through module in chunks
817+ for (uint64_t offset = 0 ; offset < g_module_size && (!found_main_pattern || !found_jump_pattern);
818+ offset += CHUNK_SIZE) {
819+
820+ uint64_t current_chunk_size = (offset + CHUNK_SIZE > g_module_size) ?
821+ (g_module_size - offset) : CHUNK_SIZE;
822+ uint64_t total_read_size = current_chunk_size + overlap_size;
823+
824+ // Move overlap data to beginning of buffer
825+ if (overlap_size > 0 && offset > 0 ) {
826+ memmove (chunk_buffer, chunk_buffer + CHUNK_SIZE, overlap_size);
827+ }
828+
829+ // Read new chunk data after the overlap
830+ if (dbg::read (info->image_pid ,
831+ (void *)((uint64_t )g_module_base + offset),
832+ chunk_buffer + overlap_size,
833+ current_chunk_size)) {
834+ cheat_log (" Failed to read chunk at offset 0x%lx" , offset);
835+ free (chunk_buffer);
836+ return false ;
837+ }
838+
839+ cheat_log (" Processing chunk: offset 0x%lx, size 0x%lx" , offset, current_chunk_size);
840+
841+ // Scan for main pattern if not found yet
842+ if (!found_main_pattern && gameAddr) {
843+ void * local_match = PatternScan (chunk_buffer, total_read_size, gameAddr);
844+ if (local_match) {
845+ // Calculate real address: base + chunk_offset + local_offset - overlap
846+ addr_real = (uint64_t )g_module_base +
847+ (offset - overlap_size) +
848+ ((char *)local_match - chunk_buffer);
849+ cheat_log (" Main pattern found at remote address: 0x%lx" , addr_real);
850+ found_main_pattern = true ;
851+ }
852+ }
853+
854+ // Scan for jump pattern if not found yet
855+ if (!found_jump_pattern && gameJumpTarget) {
856+ void * local_match = PatternScan (chunk_buffer, total_read_size, gameJumpTarget);
857+ if (local_match) {
858+ // Calculate real address: base + chunk_offset + local_offset - overlap
859+ jump_addr = (uint64_t )g_module_base +
860+ (offset - overlap_size) +
861+ ((char *)local_match - chunk_buffer);
862+ cheat_log (" Jump pattern found at remote address: 0x%lx" , addr_real);
863+ found_jump_pattern = true ;
864+ }
865+ }
866+
867+ // Setup overlap for next iteration (except on last chunk)
868+ if (offset + CHUNK_SIZE < g_module_size) {
869+ overlap_size = (current_chunk_size > PATTERN_OVERLAP) ?
870+ PATTERN_OVERLAP : current_chunk_size;
871+ } else {
872+ overlap_size = 0 ;
873+ }
874+ }
875+
876+ // Clean up
877+ free (chunk_buffer);
878+
879+ // Check results
880+ if (!found_main_pattern || !addr_real) {
881+ cheat_log (" Masked Address: %s not found\n " , gameAddr);
882+ return 1 ;
883+ }
884+
885+ if (gameJumpTarget && (!found_jump_pattern || !jump_addr)) {
886+ cheat_log (" Jump Target: %s not found\n " , gameJumpTarget);
887+ return 1 ;
888+ }
889+
890+ if (jump_addr) {
891+ cheat_log (" Target: 0x%lx jump size %u\n " , jump_addr, jump_size);
892+ }
816893 cheat_log (" Masked Address: 0x%lx\n " , addr_real);
817894 cheat_log (" Address: %s\n " , gameOffset);
818895 uint32_t real_offset = 0 ;
0 commit comments