Skip to content

Commit a951c41

Browse files
Update game_patch_xml.cpp
1 parent c75cc07 commit a951c41

File tree

1 file changed

+111
-34
lines changed

1 file changed

+111
-34
lines changed

Plugin_samples/itemzflow_xml_patches/source/game_patch_xml.cpp

Lines changed: 111 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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
650651
int 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

Comments
 (0)