forked from Popn_Tools/popnhax
wip patch gen
This commit is contained in:
parent
3d8d6a83ad
commit
4c0000870e
@ -1,29 +1,19 @@
|
|||||||
libs += libdisasm
|
libs += libdisasm
|
||||||
|
|
||||||
|
cflags += -w
|
||||||
|
|
||||||
src_libdisasm := \
|
src_libdisasm := \
|
||||||
ia32_implicit.c \
|
ia32_implicit.c \
|
||||||
ia32_implicit.h \
|
|
||||||
ia32_insn.c \
|
ia32_insn.c \
|
||||||
ia32_insn.h \
|
|
||||||
ia32_invariant.c \
|
ia32_invariant.c \
|
||||||
ia32_invariant.h \
|
|
||||||
ia32_modrm.c \
|
ia32_modrm.c \
|
||||||
ia32_modrm.h \
|
|
||||||
ia32_opcode_tables.c \
|
ia32_opcode_tables.c \
|
||||||
ia32_opcode_tables.h \
|
|
||||||
ia32_operand.c \
|
ia32_operand.c \
|
||||||
ia32_operand.h \
|
|
||||||
ia32_reg.c \
|
ia32_reg.c \
|
||||||
ia32_reg.h \
|
|
||||||
ia32_settings.c \
|
ia32_settings.c \
|
||||||
ia32_settings.h \
|
|
||||||
libdis.h \
|
|
||||||
qword.h \
|
|
||||||
x86_disasm.c \
|
x86_disasm.c \
|
||||||
x86_format.c \
|
x86_format.c \
|
||||||
x86_imm.c \
|
x86_imm.c \
|
||||||
x86_imm.h \
|
|
||||||
x86_insn.c \
|
x86_insn.c \
|
||||||
x86_misc.c \
|
x86_misc.c \
|
||||||
x86_operand_list.c \
|
x86_operand_list.c
|
||||||
x86_operand_list.h
|
|
@ -8,7 +8,8 @@ ldflags_popnhax := \
|
|||||||
|
|
||||||
libs_popnhax := \
|
libs_popnhax := \
|
||||||
util \
|
util \
|
||||||
minhook
|
minhook \
|
||||||
|
libdisasm
|
||||||
|
|
||||||
srcpp_popnhax := \
|
srcpp_popnhax := \
|
||||||
dllmain.cc \
|
dllmain.cc \
|
||||||
|
@ -7861,6 +7861,8 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
|||||||
if (force_no_omni)
|
if (force_no_omni)
|
||||||
config.patch_db = false;
|
config.patch_db = false;
|
||||||
|
|
||||||
|
make_omnimix_patch(g_game_dll_fn);
|
||||||
|
|
||||||
bool datecode_auto = (strcmp(config.force_datecode, "auto") == 0);
|
bool datecode_auto = (strcmp(config.force_datecode, "auto") == 0);
|
||||||
|
|
||||||
if (!config.disable_multiboot)
|
if (!config.disable_multiboot)
|
||||||
|
300
popnhax/omnimix_patch.cc
Normal file
300
popnhax/omnimix_patch.cc
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <io.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "util/bst.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
#include "util/patch.h"
|
||||||
|
#include "util/search.h"
|
||||||
|
#include "libdisasm/libdis.h"
|
||||||
|
|
||||||
|
#include "omnimix_patch.h"
|
||||||
|
|
||||||
|
#define LINE_SIZE 512
|
||||||
|
|
||||||
|
|
||||||
|
#define MUSIC_IDX 0
|
||||||
|
#define CHART_IDX 1
|
||||||
|
#define STYLE_IDX 2
|
||||||
|
#define FLAVOR_IDX 3
|
||||||
|
#define CHARA_IDX 4
|
||||||
|
#define NUM_IDX 5
|
||||||
|
|
||||||
|
bst_t *g_xref_bst = NULL;
|
||||||
|
|
||||||
|
typedef struct table_s {
|
||||||
|
char *name;
|
||||||
|
uint32_t *addr;
|
||||||
|
uint32_t size; // size of one entry
|
||||||
|
uint32_t limit; // number of entries
|
||||||
|
} table_t;
|
||||||
|
|
||||||
|
table_t g_tables[NUM_IDX];
|
||||||
|
|
||||||
|
uint32_t *find_binary(char *data, DWORD dllSize, const char *search_pattern, uint32_t search_size, uint32_t search_head, int8_t search_idx)
|
||||||
|
{
|
||||||
|
//fprintf(stderr, "find binary %.*s\n", search_size, search_pattern);
|
||||||
|
uint32_t *ea = 0;
|
||||||
|
int8_t found = -1;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int64_t pattern_offset = search(data, dllSize -((uint32_t) ea)-1, search_pattern, search_size, ((uint32_t) ea)+1);
|
||||||
|
|
||||||
|
if (pattern_offset == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ea = (uint32_t *) (pattern_offset + search_head);
|
||||||
|
found++;
|
||||||
|
|
||||||
|
if (found != search_idx)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return (uint32_t *) ((int64_t) data + (int64_t) ea);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t *find_binary_xref(char *data, DWORD dllSize, const char *search_pattern, uint32_t search_size, uint32_t search_head, int8_t search_idx, int8_t xref_search_idx)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t* ea = find_binary(data, dllSize, search_pattern, search_size, search_head, search_idx);
|
||||||
|
|
||||||
|
if (ea == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char *as_hex = (char *) &ea;
|
||||||
|
|
||||||
|
ea = find_binary(data, dllSize, as_hex, 4, 0, xref_search_idx);
|
||||||
|
|
||||||
|
return ea;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t get_table_size_by_xref(char *data, DWORD dllSize, uint32_t *ea, uint32_t entry_size)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "get table size by xref\n");
|
||||||
|
uint32_t *orig_ea = ea;
|
||||||
|
// Skip 10 entries because why not. We're looking for the end anyway
|
||||||
|
ea = (uint32_t*)((uint32_t)ea+(entry_size*10));
|
||||||
|
|
||||||
|
fprintf(stderr, "orig ea %p, entry size %u, ea %p\n", orig_ea, entry_size, ea);
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
while (!found)
|
||||||
|
{
|
||||||
|
uint32_t *as_int = (uint32_t*)&ea;
|
||||||
|
//fprintf(stderr, "looking for xref to %0X\n", *as_int);
|
||||||
|
|
||||||
|
if ( bst_search(g_xref_bst, *as_int) != NULL )
|
||||||
|
{
|
||||||
|
found=true;
|
||||||
|
}
|
||||||
|
/* uint32_t *xref = find_binary(data, dllSize, as_hex, 4, 0, 0);
|
||||||
|
if ( xref != NULL )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "found at addr %p\n", xref);
|
||||||
|
if ( xref != (uint32_t*)0x10169236 )
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "bad offset\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if (!found)
|
||||||
|
ea = (uint32_t*)((uint32_t)ea+entry_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "found value %u (ea = %p, orig_ea = %p, entry size = %u)\n", ((((uint32_t)ea)-((uint32_t)orig_ea))/entry_size), ea, orig_ea, entry_size);
|
||||||
|
return (((uint32_t)ea)-((uint32_t)orig_ea))/entry_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
def get_table_size_by_xref(ea, entry_size):
|
||||||
|
# Skip 10 entries because why not. We're looking for the end anyway
|
||||||
|
orig_ea = ea
|
||||||
|
ea += entry_size * 10
|
||||||
|
|
||||||
|
found_end = False
|
||||||
|
while not found_end:
|
||||||
|
for xref_idx, xref in enumerate(idautils.XrefsTo(ea)):
|
||||||
|
found_end = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not found_end:
|
||||||
|
ea += entry_size
|
||||||
|
|
||||||
|
return (ea - orig_ea) // entry_size
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void print_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);
|
||||||
|
fprintf(stderr,"%s\n", line);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_xref_to_bst(uint32_t addr)
|
||||||
|
{
|
||||||
|
if ( bst_search(g_xref_bst, addr) == NULL )
|
||||||
|
{
|
||||||
|
//LOG("added addr %0X to BST\n", addr);
|
||||||
|
g_xref_bst = bst_insert(g_xref_bst, addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_xref(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);
|
||||||
|
//LOG("it has %u operands\n", insn->operand_count);
|
||||||
|
|
||||||
|
uint32_t addr = x86_get_address(insn);
|
||||||
|
if ( addr != 0 )
|
||||||
|
{
|
||||||
|
add_xref_to_bst(addr);
|
||||||
|
//LOG("found ref to %0X at ea %0X\n", addr, insn->addr);
|
||||||
|
//fprintf(stderr, "\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// doesn't have an address directly
|
||||||
|
x86_op_t *op = x86_operand_1st(insn);
|
||||||
|
if ( op != NULL && op->type == op_expression )
|
||||||
|
{
|
||||||
|
x86_ea_t exp = op->data.expression;
|
||||||
|
// LOG("(expression) disp is %0X\n", exp.disp);
|
||||||
|
add_xref_to_bst(exp.disp);
|
||||||
|
}
|
||||||
|
|
||||||
|
op = x86_operand_2nd(insn);
|
||||||
|
if ( op != NULL && op->type == op_expression )
|
||||||
|
{
|
||||||
|
x86_ea_t exp = op->data.expression;
|
||||||
|
// LOG("(expression) disp is %0X\n", exp.disp);
|
||||||
|
add_xref_to_bst(exp.disp);
|
||||||
|
}
|
||||||
|
|
||||||
|
op = x86_operand_3rd(insn);
|
||||||
|
if ( op != NULL && op->type == op_expression )
|
||||||
|
{
|
||||||
|
x86_ea_t exp = op->data.expression;
|
||||||
|
// LOG("(expression) disp is %0X\n", exp.disp);
|
||||||
|
add_xref_to_bst(exp.disp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* bst_search(g_xref_bst, idx) == NULL */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool make_omnimix_patch(const char *dllFilename){
|
||||||
|
|
||||||
|
DWORD dllSize = 0;
|
||||||
|
char *buf = getDllData(dllFilename, &dllSize);
|
||||||
|
/*
|
||||||
|
const char *dummy_buf = "\x8b\x0c\x95\xfc\x28\x32\x10";
|
||||||
|
DWORD dummy_size = 7;
|
||||||
|
*/
|
||||||
|
/* build instruction table indexed by parameter */
|
||||||
|
LOG("START DISASSEMBLY\n");
|
||||||
|
|
||||||
|
x86_init(opt_none, NULL, NULL);
|
||||||
|
|
||||||
|
unsigned int num_insn = x86_disasm_range( (unsigned char *)buf, (uint32_t) buf, 0, dllSize, &add_xref, NULL);
|
||||||
|
|
||||||
|
LOG("parsed %u instructions\n", num_insn);
|
||||||
|
LOG("END DISASSEMBLY\n");
|
||||||
|
|
||||||
|
x86_cleanup();
|
||||||
|
/* instruction table is done */
|
||||||
|
|
||||||
|
LOG("<?xml version='1.0' encoding='shift-jis'?>\n");
|
||||||
|
LOG("<patches target=\"20xxxxxx00\">\n");
|
||||||
|
|
||||||
|
/* init tables */
|
||||||
|
g_tables[MUSIC_IDX].name = strdup("music");
|
||||||
|
g_tables[CHART_IDX].name = strdup("chart");
|
||||||
|
g_tables[STYLE_IDX].name = strdup("style");
|
||||||
|
g_tables[FLAVOR_IDX].name = strdup("flavor");
|
||||||
|
g_tables[CHARA_IDX].name = strdup("chara");
|
||||||
|
|
||||||
|
// These all reference the first entry in their respective tables
|
||||||
|
g_tables[MUSIC_IDX].addr = find_binary_xref(buf, dllSize, "\x00\x83\x7C\x83\x62\x83\x76\x83\x58\x00", 10, 1, 0, 0);
|
||||||
|
g_tables[CHART_IDX].addr = find_binary_xref(buf, dllSize, "\x00\x70\x6F\x70\x6E\x31\x00\x00", 8, 1, 0, 1);
|
||||||
|
g_tables[STYLE_IDX].addr = find_binary(buf, dllSize, "\x01\x00\x00\x00\xFF\x54\x0C\x00\x1A\x00\x00\x00\x11\x00\x00\x00", 16, 0, 2);
|
||||||
|
g_tables[FLAVOR_IDX].addr = find_binary(buf, dllSize, "\x00\x82\xBB\x82\xEA\x82\xA2\x82\xAF\x81\x5B\x00\x00\x00\x82\xA4\x82", 17, 1, 0);
|
||||||
|
g_tables[CHARA_IDX].addr = find_binary_xref(buf, dllSize, "\x00\x62\x61\x6D\x62\x5F\x31\x61\x00", 9, 1, 0, 0);
|
||||||
|
|
||||||
|
fprintf(stderr, "buffer addresses ok\n");
|
||||||
|
// Modify the entry sizes as required
|
||||||
|
g_tables[MUSIC_IDX].size = 0xAC;
|
||||||
|
g_tables[CHART_IDX].size = 0x20; // Probably won't change?
|
||||||
|
g_tables[STYLE_IDX].size = 0x10; // Unlikely to change
|
||||||
|
g_tables[FLAVOR_IDX].size = 0x60;
|
||||||
|
g_tables[CHARA_IDX].size = 0x4C;
|
||||||
|
|
||||||
|
// buffer_addr + (buffer_entry_size * limit) should give you the very end of the array (after the last entry)
|
||||||
|
g_tables[MUSIC_IDX].limit = get_table_size_by_xref(buf, dllSize, g_tables[MUSIC_IDX].addr, g_tables[MUSIC_IDX].size);
|
||||||
|
g_tables[CHART_IDX].limit = get_table_size_by_xref(buf, dllSize, g_tables[CHART_IDX].addr, g_tables[CHART_IDX].size);
|
||||||
|
g_tables[STYLE_IDX].limit = get_table_size_by_xref(buf, dllSize, g_tables[STYLE_IDX].addr, g_tables[STYLE_IDX].size);
|
||||||
|
g_tables[FLAVOR_IDX].limit = get_table_size_by_xref(buf, dllSize, g_tables[FLAVOR_IDX].addr, g_tables[FLAVOR_IDX].size);
|
||||||
|
g_tables[CHARA_IDX].limit = get_table_size_by_xref(buf, dllSize, g_tables[CHARA_IDX].addr, g_tables[CHARA_IDX].size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
# Modify the entry sizes as required
|
||||||
|
buffer_addrs = [
|
||||||
|
# entry type, table address, entry size
|
||||||
|
[MUSIC_IDX, music_table_addr, 0xac],
|
||||||
|
[CHART_IDX, chart_table_addr, 0x20], # Probably won't change?
|
||||||
|
[STYLE_IDX, style_table_addr, 0x10], # Unlikely to change
|
||||||
|
[FLAVOR_IDX, flavor_table_addr, 0x60],
|
||||||
|
[CHARA_IDX, chara_table_addr, 0x4C],
|
||||||
|
]
|
||||||
|
|
||||||
|
limit_info_list = [
|
||||||
|
# buffer_addr + (buffer_entry_size * limit) should give you the very end of the array (after the last entry)
|
||||||
|
[MUSIC_IDX, get_table_size_by_xref(*buffer_addrs[MUSIC_IDX][1:])],
|
||||||
|
[CHART_IDX, get_table_size_by_xref(*buffer_addrs[CHART_IDX][1:])],
|
||||||
|
[STYLE_IDX, get_table_size_by_xref(*buffer_addrs[STYLE_IDX][1:])],
|
||||||
|
[FLAVOR_IDX, get_table_size_by_xref(*buffer_addrs[FLAVOR_IDX][1:])],
|
||||||
|
[CHARA_IDX, get_table_size_by_xref(*buffer_addrs[CHARA_IDX][1:])],
|
||||||
|
]
|
||||||
|
|
||||||
|
for limit_info in limit_info_list:
|
||||||
|
patch_target, limit_value = limit_info
|
||||||
|
if TARGETS[patch_target] == "music":
|
||||||
|
music_limit = limit_value
|
||||||
|
LOG("\t\t<%s __type=\"u32\">%d</%s>\n", TARGETS[patch_target], limit_value, TARGETS[patch_target]);
|
||||||
|
LOG("\t</limits>\n");
|
||||||
|
*/
|
||||||
|
|
||||||
|
LOG("\t<limits>\n");
|
||||||
|
for (int i=0; i < NUM_IDX; i++)
|
||||||
|
{
|
||||||
|
//patch_target, buffer_addr, entry_size = buffer_info
|
||||||
|
LOG("\t\t<%s __type=\"u32\">%d</%s>\n", g_tables[i].name, g_tables[i].limit, g_tables[i].name);
|
||||||
|
}
|
||||||
|
LOG("\t</limits>\n");
|
||||||
|
|
||||||
|
LOG("\t<buffer_base_addrs>\n");
|
||||||
|
for (int i=0; i < NUM_IDX; i++)
|
||||||
|
{
|
||||||
|
//patch_target, buffer_addr, entry_size = buffer_info
|
||||||
|
LOG("\t\t<%s __type=\"str\">0x%p</%s>\n", g_tables[i].name, g_tables[i].addr, g_tables[i].name);
|
||||||
|
}
|
||||||
|
LOG("\t</buffer_base_addrs>\n");
|
||||||
|
|
||||||
|
|
||||||
|
getchar();
|
||||||
|
exit(0);
|
||||||
|
return false;
|
||||||
|
}
|
6
popnhax/omnimix_patch.h
Normal file
6
popnhax/omnimix_patch.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef __OMNIMIX_PATCH_H__
|
||||||
|
#define __OMNIMIX_PATCH_H__
|
||||||
|
|
||||||
|
bool make_omnimix_patch(const char *dllFilename);
|
||||||
|
|
||||||
|
#endif
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef __BST_H__
|
#ifndef __BST_H__
|
||||||
#define __BST_H__
|
#define __BST_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct bst_s
|
typedef struct bst_s
|
||||||
{
|
{
|
||||||
uint32_t data;
|
uint32_t data;
|
||||||
|
Loading…
Reference in New Issue
Block a user