diff --git a/Dockerfile b/Dockerfile.build similarity index 100% rename from Dockerfile rename to Dockerfile.build diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 00000000..00c51086 --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,21 @@ +FROM --platform=amd64 debian:11.6-slim@sha256:f7d141c1ec6af549958a7a2543365a7829c2cdc4476308ec2e182f8a7c59b519 + +LABEL description="Development environment for bemanitools" + +# mingw-w64-gcc has 32-bit and 64-bit toolchains +RUN apt-get update && apt-get install -y --no-install-recommends \ + mingw-w64 \ + mingw-w64-common \ + make \ + zip \ + git \ + clang-format \ + python3-pip \ + && rm -rf /var/lib/apt/lists/* + +RUN pip3 install mdformat + +RUN mkdir /bemanitools +WORKDIR /bemanitools + +ENV SHELL /bin/bash \ No newline at end of file diff --git a/GNUmakefile b/GNUmakefile index 83289629..9aef0b1b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -13,8 +13,10 @@ BUILDDIR ?= build builddir_docker := $(BUILDDIR)/docker -docker_container_name := "bemanitools-build" -docker_image_name := "bemanitools-build:latest" +docker_build_container_name := "bemanitools-build" +docker_build_image_name := "bemanitools-build:latest" +docker_dev_container_name := "bemanitools-dev" +docker_dev_image_name := "bemanitools-dev:latest" depdir := $(BUILDDIR)/dep objdir := $(BUILDDIR)/obj @@ -41,6 +43,7 @@ FORCE: .PHONY: \ build-docker \ +dev-docker \ clean \ code-format \ doc-format \ @@ -89,21 +92,38 @@ version: $(V)echo "$(gitrev)" > version build-docker: - $(V)docker rm -f $(docker_container_name) 2> /dev/null || true + $(V)docker rm -f $(docker_build_container_name) 2> /dev/null || true $(V)docker \ build \ - -t $(docker_image_name) \ - -f Dockerfile \ + -t $(docker_build_image_name) \ + -f Dockerfile.build \ . $(V)docker \ run \ --volume $(shell pwd):/bemanitools \ - --name $(docker_container_name) \ - $(docker_image_name) + --name $(docker_build_container_name) \ + $(docker_build_image_name) + +dev-docker: + $(V)docker rm -f $(docker_dev_container_name) 2> /dev/null || true + $(V)docker \ + build \ + -t $(docker_dev_image_name) \ + -f Dockerfile.dev \ + . + $(V)docker \ + run \ + --interactive \ + --tty \ + --volume $(shell pwd):/bemanitools \ + --name $(docker_dev_container_name) \ + $(docker_dev_image_name) clean-docker: - $(V)docker rm -f $(docker_container_name) || true - $(V)docker image rm -f $(docker_image_name) || true + $(V)docker rm -f $(docker_dev_container_name) || true + $(V)docker image rm -f $(docker_dev_image_name) || true + $(V)docker rm -f $(docker_build_container_name) || true + $(V)docker image rm -f $(docker_build_image_name) || true $(V)rm -rf $(BUILDDIR) # diff --git a/Module.mk b/Module.mk index 2a948a8d..35e690dd 100644 --- a/Module.mk +++ b/Module.mk @@ -710,6 +710,8 @@ $(zipdir)/ddr-14-to-18.zip: \ build/bin/indep-32/eamio.dll \ build/bin/indep-32/geninput.dll \ dist/ddr/config.bat \ + dist/ddr/gamestart-17.bat \ + dist/ddr/gamestart-18.bat \ dist/ddr/gamestart-14.bat \ dist/ddr/gamestart-15.bat \ dist/ddr/gamestart-16.bat \ @@ -728,6 +730,8 @@ $(zipdir)/ddr-16-to-18-x64.zip: \ build/bin/indep-64/eamio.dll \ build/bin/indep-64/geninput.dll \ dist/ddr/config.bat \ + dist/ddr/gamestart-17.bat \ + dist/ddr/gamestart-18.bat \ dist/ddr/gamestart-16.bat \ dist/ddr/gamestart-17.bat \ dist/ddr/gamestart-18.bat \ diff --git a/src/imports/avs.h b/src/imports/avs.h index a2d439ec..9dce5beb 100644 --- a/src/imports/avs.h +++ b/src/imports/avs.h @@ -220,6 +220,9 @@ void property_file_write(struct property *prop, const char *path); int property_set_flag(struct property *prop, int flags, int mask); void property_destroy(struct property *prop); +avs_error property_get_error(struct property *prop); +struct property *property_clear_error(struct property *prop); + int property_psmap_import( struct property *prop, struct property_node *root, diff --git a/src/imports/import_32_0_avs.def b/src/imports/import_32_0_avs.def index 273e5be8..9632ecb4 100644 --- a/src/imports/import_32_0_avs.def +++ b/src/imports/import_32_0_avs.def @@ -25,6 +25,8 @@ EXPORTS property_destroy property_file_write property_insert_read + property_clear_error + property_get_error property_mem_write property_read_query_memsize property_search diff --git a/src/imports/import_32_1002_avs.def b/src/imports/import_32_1002_avs.def index e2ff5ae5..cc4ee29c 100644 --- a/src/imports/import_32_1002_avs.def +++ b/src/imports/import_32_1002_avs.def @@ -28,6 +28,8 @@ EXPORTS property_destroy property_file_write property_insert_read + property_clear_error + property_get_error property_mem_write property_read_query_memsize property_search diff --git a/src/imports/import_32_1101_avs.def b/src/imports/import_32_1101_avs.def index 10c59e4f..776dc712 100644 --- a/src/imports/import_32_1101_avs.def +++ b/src/imports/import_32_1101_avs.def @@ -26,6 +26,8 @@ EXPORTS property_desc_to_buffer @246 NONAME property_destroy @247 NONAME property_insert_read @255 NONAME + property_clear_error @573 NONAME + property_get_error @573 NONAME property_node_create @266 NONAME property_node_datasize @267 NONAME property_node_name @274 NONAME diff --git a/src/imports/import_32_1304_avs.def b/src/imports/import_32_1304_avs.def index f83d5a5f..18dad23a 100644 --- a/src/imports/import_32_1304_avs.def +++ b/src/imports/import_32_1304_avs.def @@ -25,6 +25,8 @@ EXPORTS property_desc_to_buffer @201 NONAME property_destroy @264 NONAME property_insert_read @23 NONAME + property_clear_error @573 NONAME + property_get_error @573 NONAME property_node_create @316 NONAME property_node_datasize @249 NONAME property_node_name @255 NONAME diff --git a/src/imports/import_32_1306_avs.def b/src/imports/import_32_1306_avs.def index f963ec88..f6deed72 100644 --- a/src/imports/import_32_1306_avs.def +++ b/src/imports/import_32_1306_avs.def @@ -25,6 +25,8 @@ EXPORTS property_desc_to_buffer @201 NONAME == XC058ba50000cd property_destroy @264 NONAME == XC058ba500010f property_insert_read @23 NONAME == XC058ba5000016 + property_clear_error @573 NONAME + property_get_error @573 NONAME property_node_create @316 NONAME == XC058ba5000143 property_node_datasize @249 NONAME == XC058ba5000100 property_node_name @255 NONAME == XC058ba5000106 diff --git a/src/imports/import_32_1403_avs.def b/src/imports/import_32_1403_avs.def index de171c12..716d0817 100644 --- a/src/imports/import_32_1403_avs.def +++ b/src/imports/import_32_1403_avs.def @@ -24,6 +24,8 @@ EXPORTS property_desc_to_buffer @131 NONAME property_destroy @130 NONAME property_insert_read @133 NONAME + property_clear_error @573 NONAME + property_get_error @573 NONAME property_node_name @573 NONAME == property_node_read @573 NONAME == property_node_remove @148 NONAME diff --git a/src/imports/import_32_1508_avs.def b/src/imports/import_32_1508_avs.def index d1625126..504a303f 100644 --- a/src/imports/import_32_1508_avs.def +++ b/src/imports/import_32_1508_avs.def @@ -26,6 +26,8 @@ EXPORTS property_desc_to_buffer @129 NONAME property_destroy @128 NONAME property_insert_read @131 NONAME + property_clear_error @573 NONAME + property_get_error @573 NONAME property_node_create @145 NONAME property_node_name @150 NONAME property_node_read @154 NONAME == XCd229cc0000f3 diff --git a/src/imports/import_32_1601_avs.def b/src/imports/import_32_1601_avs.def index 74332d48..286806bf 100644 --- a/src/imports/import_32_1601_avs.def +++ b/src/imports/import_32_1601_avs.def @@ -19,6 +19,8 @@ EXPORTS property_destroy @125 NONAME property_desc_to_buffer @126 NONAME property_insert_read @128 NONAME + property_clear_error @573 NONAME + property_get_error @573 NONAME property_search @141 NONAME property_node_create @142 NONAME property_node_name @147 NONAME == XCnbrep7000092 diff --git a/src/imports/import_32_1603_avs.def b/src/imports/import_32_1603_avs.def index 21f55c1e..93fd07d2 100644 --- a/src/imports/import_32_1603_avs.def +++ b/src/imports/import_32_1603_avs.def @@ -19,6 +19,8 @@ EXPORTS property_destroy @146 NONAME property_desc_to_buffer @147 NONAME property_insert_read @149 NONAME + property_clear_error @158 NONAME == XCnbrep700009d + property_get_error @159 NONAME == XCnbrep700009e property_search @162 NONAME property_node_create @163 NONAME property_node_name @168 NONAME == XCnbrep70000a7 diff --git a/src/imports/import_32_1700_avs.def b/src/imports/import_32_1700_avs.def index 7dc4eaa8..f01bc391 100644 --- a/src/imports/import_32_1700_avs.def +++ b/src/imports/import_32_1700_avs.def @@ -21,6 +21,8 @@ EXPORTS property_destroy @146 NONAME property_desc_to_buffer @147 NONAME property_insert_read @149 NONAME + property_clear_error @158 NONAME == XCgsqzn000009d + property_get_error @159 NONAME == XCgsqzn000009e property_search @162 NONAME property_node_create @163 NONAME property_node_name @168 NONAME == XCgsqzn00000a7 diff --git a/src/imports/import_32_803_avs.def b/src/imports/import_32_803_avs.def index 37f2b3e6..9340dad5 100644 --- a/src/imports/import_32_803_avs.def +++ b/src/imports/import_32_803_avs.def @@ -25,6 +25,8 @@ EXPORTS property_destroy property_file_write property_insert_read + property_clear_error + property_get_error property_mem_write property_read_query_memsize property_search diff --git a/src/imports/import_64_1508_avs.def b/src/imports/import_64_1508_avs.def index 6aeaba1d..1a93e7e5 100644 --- a/src/imports/import_64_1508_avs.def +++ b/src/imports/import_64_1508_avs.def @@ -26,6 +26,8 @@ EXPORTS property_desc_to_buffer @129 NONAME property_destroy @128 NONAME property_insert_read @131 NONAME + property_clear_error @573 NONAME + property_get_error @573 NONAME property_node_create @145 NONAME property_node_name @150 NONAME property_node_read @154 NONAME == XCd229cc0000f3 diff --git a/src/imports/import_64_1509_avs.def b/src/imports/import_64_1509_avs.def index fde35d65..a596513a 100644 --- a/src/imports/import_64_1509_avs.def +++ b/src/imports/import_64_1509_avs.def @@ -26,6 +26,8 @@ EXPORTS property_desc_to_buffer @129 NONAME property_destroy @128 NONAME property_insert_read @131 NONAME + property_clear_error @573 NONAME + property_get_error @573 NONAME property_node_create @145 NONAME property_node_name @573 NONAME == property_node_read @573 NONAME == diff --git a/src/imports/import_64_1601_avs.def b/src/imports/import_64_1601_avs.def index 418395f7..960fb947 100644 --- a/src/imports/import_64_1601_avs.def +++ b/src/imports/import_64_1601_avs.def @@ -19,6 +19,8 @@ EXPORTS property_destroy @125 NONAME property_desc_to_buffer @126 NONAME property_insert_read @128 NONAME + property_clear_error @573 NONAME + property_get_error @573 NONAME property_search @141 NONAME property_node_create @142 NONAME property_node_name @147 NONAME == XCnbrep7000092 diff --git a/src/imports/import_64_1603_avs.def b/src/imports/import_64_1603_avs.def index b106ab1b..14f42b7b 100644 --- a/src/imports/import_64_1603_avs.def +++ b/src/imports/import_64_1603_avs.def @@ -19,12 +19,14 @@ EXPORTS property_destroy @146 NONAME property_desc_to_buffer @147 NONAME property_insert_read @149 NONAME + property_clear_error @158 NONAME == XCnbrep700009d + property_get_error @159 NONAME == XCnbrep700009e property_search @162 NONAME property_node_create @163 NONAME property_node_name @168 NONAME == XCnbrep70000a7 property_node_remove @164 NONAME property_node_type @169 NONAME == XCnbrep70000a8 - property_node_clone @165 NONAME + property_node_clone @165 NONAME == XCnbrep70000a4 property_node_traversal @167 NONAME property_node_refdata @166 NONAME == XCnbrep70000a5 property_node_datasize @171 NONAME == XCnbrep70000aa diff --git a/src/imports/import_64_1700_avs.def b/src/imports/import_64_1700_avs.def index 8cddba8a..3e456b50 100644 --- a/src/imports/import_64_1700_avs.def +++ b/src/imports/import_64_1700_avs.def @@ -21,6 +21,8 @@ EXPORTS property_destroy @146 NONAME property_desc_to_buffer @147 NONAME property_insert_read @149 NONAME + property_clear_error @158 NONAME == XCgsqzn000009d + property_get_error @159 NONAME == XCgsqzn000009e property_search @162 NONAME property_node_create @163 NONAME property_node_name @168 NONAME == XCgsqzn00000a7 diff --git a/src/main/hook/table.c b/src/main/hook/table.c index ed67b3b6..067ea75f 100644 --- a/src/main/hook/table.c +++ b/src/main/hook/table.c @@ -15,12 +15,21 @@ static const size_t apiset_prefix_len = sizeof(apiset_prefix) - 1; static void hook_table_apply_to_all( const char *depname, const struct hook_symbol *syms, size_t nsyms); +static void hook_table_revert_to_all( + const char *depname, const struct hook_symbol *syms, size_t nsyms); + static void hook_table_apply_to_iid( HMODULE target, const pe_iid_t *iid, const struct hook_symbol *syms, size_t nsyms); +static void hook_table_revert_to_iid( + HMODULE target, + const pe_iid_t *iid, + const struct hook_symbol *syms, + size_t nsyms); + static bool hook_table_match_module( HMODULE target, const char *iid_name, const char *depname); @@ -44,6 +53,23 @@ static void hook_table_apply_to_all( } } +static void hook_table_revert_to_all( + const char *depname, const struct hook_symbol *syms, size_t nsyms) +{ + const peb_dll_t *dll; + HMODULE pe; + + for (dll = peb_dll_get_first(); dll != NULL; dll = peb_dll_get_next(dll)) { + pe = peb_dll_get_base(dll); + + if (pe == NULL) { + continue; /* ?? Happens sometimes. */ + } + + hook_table_revert(pe, depname, syms, nsyms); + } +} + void hook_table_apply( HMODULE target, const char *depname, @@ -73,6 +99,35 @@ void hook_table_apply( } } +void hook_table_revert( + HMODULE target, + const char *depname, + const struct hook_symbol *syms, + size_t nsyms) +{ + const pe_iid_t *iid; + const char *iid_name; + + assert(depname != NULL); + assert(syms != NULL || nsyms == 0); + + if (target == NULL) { + /* Call out, which will then call us back repeatedly. Awkward, but + viewed from the outside it's good for usability. */ + + hook_table_revert_to_all(depname, syms, nsyms); + } else { + for (iid = pe_iid_get_first(target); iid != NULL; + iid = pe_iid_get_next(target, iid)) { + iid_name = pe_iid_get_name(target, iid); + + if (hook_table_match_module(target, iid_name, depname)) { + hook_table_revert_to_iid(target, iid, syms, nsyms); + } + } + } +} + static void hook_table_apply_to_iid( HMODULE target, const pe_iid_t *iid, @@ -101,6 +156,33 @@ static void hook_table_apply_to_iid( } } +static void hook_table_revert_to_iid( + HMODULE target, + const pe_iid_t *iid, + const struct hook_symbol *syms, + size_t nsyms) +{ + struct pe_iat_entry iate; + size_t i; + size_t j; + const struct hook_symbol *sym; + + i = 0; + + while (pe_iid_get_iat_entry(target, iid, i++, &iate) == S_OK) { + for (j = 0; j < nsyms; j++) { + sym = &syms[j]; + + if (hook_table_match_proc(&iate, sym)) { + // Only revert-able if the original pointer was stored previously + if (sym->link != NULL && *sym->link != NULL) { + pe_patch(iate.ppointer, sym->link, sizeof(*sym->link)); + } + } + } + } +} + static bool hook_table_match_module( HMODULE target, const char *iid_name, const char *depname) {