diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f2dd0f04 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.exe +/lib +/build +Env.ld +*.o +nop \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9e77f723 --- /dev/null +++ b/Makefile @@ -0,0 +1,140 @@ +ifeq ($(OS),Windows_NT) + detected_OS := Windows +else + detected_OS := $(shell sh -c 'uname -s 2>/dev/null || echo not') +endif + +ifeq ($(detected_OS),Windows) + obj_type = i386pe + mkdir = mkdir $(subst /,\,$(1)) > nop 2>&1 || (exit 0) + rm = $(wordlist 2,65535,$(foreach FILE,$(subst /,\,$(1)),& del $(FILE) > nop 2>&1)) || (exit 0) + rmdir = rmdir $(subst /,\,$(1)) > nop 2>&1 || (exit 0) + echo = echo $(1) +else + obj_type = elf_i386 + mkdir = mkdir -p $(1) + rm = rm $(1) > /dev/null 2>&1 || true + rmdir = rmdir $(1) > /dev/null 2>&1 || true + echo = echo "$(1)" +endif + +ifeq ($(detected_OS),Windows) +WINAPI = -lmingw32 -lkernel32 -lm -ldxguid -ldxerr8 -luser32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lgdi32 -lcomdlg32 -lwinspool +WINAPI+= -lcomctl32 -luuid -lrpcrt4 -ladvapi32 -lwsock32 -lshlwapi -lversion -lwinpthread -ldbghelp -lpthread +endif + +OBJS = ./*cpp +HEADS = ./patcher/binPatcher.hpp +PREP = -include $(HEADS) +CC = g++ + +ASTYLE = aStyle + +#LIBRARY_PATHS specifies the additional library paths we'll need +LIBRARY_PATHS = -L ./lib + +INCLUDE_PATHS = -I ./boost_lib -I . + +align_size = 0x100 +align_data = 0x1000 +align_rdata = 0x1000 +align_bss = 0x1000 +align_idata = 0x1000 + +#OBJ_NAME specifies the name of our exectuable +OBJ_NAME = FaPatcher.exe + +#COMPILER_FLAGS specifies the additional compilation options we're using +# -w suppresses all warnings +# -Wl,-subsystem,windows gets rid of the console window +COMPILER_FLAGS = -static -w -DOBJ_NAME='"$(OBJ_NAME)"' -O3 -s + +#LINKER_FLAGS specifies the libraries we're linking against +LINKER_FLAGS = -static-libgcc -static-libstdc++ + +LOCAL_LIBS = -lpatcher -lfilesystem -lsystem -lpebliss -lasmjit + +#-oformat -Ttext=0x006B8FB9 +#echo align_size = $(align_size)';' > Env.ld + +align: + echo align_size = $(align_size)';' > Env.ld + +peLib: + $(MAKE) all -C ./pe_lib + +boostLib: + $(MAKE) all -C ./boost_lib/filesystem + $(MAKE) all -C ./boost_lib/system + +patcherLib: + $(MAKE) all OBJ_NAME=$(OBJ_NAME) -C ./patcher + +asmjitLib: + $(MAKE) all -C ./asmjit_lib + +cleanall: + $(MAKE) clean -C ./boost_lib/filesystem + $(MAKE) clean -C ./boost_lib/system + $(MAKE) clean -C ./pe_lib + $(MAKE) clean -C ./asmjit_lib + $(MAKE) clean -C ./patcher + rm -Rf ./build + +cleanbuild: + rm -Rf ./build + +directories: + $(call mkdir, /build) + $(call mkdir, /preprocessor) + +ext_sector: + $(MAKE) all_individual -C ./sections + $(MAKE) link -C ./sections + +_hooks: + $(MAKE) all OBJ_NAME=$(OBJ_NAME_) OBJS=$(OBJS) -C ./hooks + +_fast_hooks: + $(MAKE) fast_compile -C ./hooks + +ext_gpp_link: + $(call echo, align_data = $(align_data)';' > Env.ld) + $(call echo, align_rdata = $(align_rdata)';' >> Env.ld) + $(call echo, align_bss = $(align_bss)';' >> Env.ld) + $(call echo, align_idata = $(align_idata)';' >> Env.ld) + echo align_data = $(align_data)';' > Env.ld + echo align_rdata = $(align_rdata)';' >> Env.ld + echo align_bss = $(align_bss)';' >> Env.ld + echo align_idata = $(align_idata)';' >> Env.ld + ld -T ./linker/sectionLinker.ld -static -m $(obj_type) $(PRIME_NAME) -o $(TMP_NAME) + +hook_gpp_link: + $(call echo, align_size = $(align_size)';' > Env.ld) + echo align_size = $(align_size)';' > Env.ld + ld -T ./linker/hookLinker.ld -static -m $(obj_type) $(PRIME_NAME) -o $(TMP_NAME) + +rip_out_binary: + objcopy --strip-all -O binary -R .eh_fram $(TMP_NAME) $(PRIME_NAME) + +pre_comp_h: + $(CC) -w $(INCLUDE_PATHS) $(HEADS) + +#This is the target that compiles our executable +all : peLib boostLib asmjitLib patcherLib + $(CC) $(OBJS) $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) $(LINKER_FLAGS) $(LOCAL_LIBS) -o $(OBJ_NAME) + @echo ./FaPatcher built successfully. + +allwin : peLib boostLib asmjitLib patcherLib + $(CC) $(OBJS) $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) $(LINKER_FLAGS) $(LOCAL_LIBS) $(WINAPI) -o $(OBJ_NAME) + @echo ./FaPatcher built successfully. + +format: + $(ASTYLE) --style=allman --indent=tab --recursive ./*.cpp, *.h, *.hpp + +clean_f: + find . -type f -name '*.orig' -delete + +clean_g: + find . -type f -name '*.gch' -delete + diff --git a/ReadMe.md b/ReadMe.md index 8b137891..2283c9aa 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -1 +1,10 @@ +# FA Binary Patches Repository + +This are some binary patches for Supreme Commander Forged Alliance. + +To apply them build or get the pacther itself from here + +https://github.com/FAETHER/FA_Patcher + +This are just the patch files for this game. I decided to separate them from patcher source code. diff --git a/hooks/Makefile b/hooks/Makefile new file mode 100644 index 00000000..f23fe759 --- /dev/null +++ b/hooks/Makefile @@ -0,0 +1,52 @@ +ifeq ($(OS),Windows_NT) + detected_OS := Windows +else + detected_OS := $(shell sh -c 'uname -s 2>/dev/null || echo not') +endif + +SRCS=$(wildcard *.cpp) + +FASTOBJS=$(SRCS:.cpp=.o) + +PROGS = $(patsubst %.cpp,../build/%.o,$(SRCS)) + +#CC specifies which compiler we're using +CC = g++ +#INCLUDE_PATHS specifies the additional include paths we'll need +#INCLUDE_PATHS = -I ./SDL2-2.0.8/i686-w64-mingw32/include/ + +#LIBRARY_PATHS specifies the additional library paths we'll need +#LIBRARY_PATHS = -L ./lib + +LINKER_FLAGS = -I. -m32 -O0 -ffreestanding -fpermissive -fno-exceptions -fno-asynchronous-unwind-tables -c -w -Wextra -masm=intel -ffunction-sections -fdata-sections -Wl,--gc-sections + +#COMPILER_FLAGS specifies the additional compilation options we're using +# -w suppresses all warnings +# -Wl,-subsystem,windows gets rid of the console window +ifeq ($(detected_OS),Windows) +COMPILER_FLAGS = -fleading-underscore +endif + +#LINKER_FLAGS specifies the libraries we're linking against +#-ffunction-sections -fdata-sections + +#-ffreestanding = freestanding enviroment + +#-nostartfiles similar to -c but has linker enabled + +ASSEMBLER_FLAGS = -c -ffreestanding -fpermissive -fno-exceptions -fno-asynchronous-unwind-tables + +#BOOST = -lboost_filesystem-mgw63-mt-d-x32-1_67 -lboost_thread-mgw63-mt-d-x32-1_67 -lboost_regex-mgw63-mt-d-x32-1_67 -lboost_system-mgw63-mt-d-x32-1_67 + +fast_compile: $(PROGS) +../build/%.o: %.cpp + $(CC) $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) $(LINKER_FLAGS) -o $@ $< + +all : + $(CC) $(OBJS) $(HEADS) $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) $(LINKER_FLAGS) $(BOOST) -o $(OBJ_NAME) + +genAssembly: + $(CC) $(OBJS) $(HEADS) $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) $(LINKER_FLAGS) $(BOOST) -S $(OBJ_NAME) + +assemble: + $(CC) ./*s $(HEADS) $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) $(ASSEMBLER_FLAGS) $(BOOST) -o $(OBJ_NAME) diff --git a/hooks/README.md b/hooks/README.md new file mode 100644 index 00000000..2ec53bf4 --- /dev/null +++ b/hooks/README.md @@ -0,0 +1,9 @@ +This folder contains the hooks that overwrite at specific offset. + +Files with .cpp are compiled by g++. Files with .jh are just data interpreted, + +originally created by asmjit assembler. + +Files with any other extensions are considered to be not used by default, and its up to the + +user to decide if they are wanted. \ No newline at end of file diff --git a/hooks/_IssueMove.txt b/hooks/_IssueMove.txt new file mode 100644 index 00000000..687d5383 --- /dev/null +++ b/hooks/_IssueMove.txt @@ -0,0 +1,16 @@ +//HOOK OnMotionTurnEventChange ROffset = 0x002F2670 + +#include +#include "../preprocessor/define.h" +#include "../preprocessor/macro.h" + +__asm__ +( + ".equ by_pass_address,"QU(dec_IssueMove)"-0x006F2670 \n" +); + +__asm__ volatile +( + "call . + by_pass_address \n" + ".align 128, 0x0 \n" +); diff --git a/hooks/hook_OnMotionTurnEvent.cpp b/hooks/hook_OnMotionTurnEvent.cpp new file mode 100644 index 00000000..6e6c2d40 --- /dev/null +++ b/hooks/hook_OnMotionTurnEvent.cpp @@ -0,0 +1,17 @@ +//HOOK OnMotionTurnEventChange ROffset = 0x2B8FB9 + +//org 0x006B8FB9 +#include + +//int by_pass_address asm("address") = 0x006B8FE0; + +__asm__ +( + ".equ by_pass_address,0x006B8FE0-0x006B8FB9 \n" +); + +__asm__ __volatile__ +( + "jmp . + by_pass_address \n" + ".align 128, 0x0 \n" +); diff --git a/hooks/hook_OnMotionTurnEvent2.cpp b/hooks/hook_OnMotionTurnEvent2.cpp new file mode 100644 index 00000000..4c9a6534 --- /dev/null +++ b/hooks/hook_OnMotionTurnEvent2.cpp @@ -0,0 +1,20 @@ +//HOOK OnMotionTurnEventChange2 ROffset = 0x2B953F + +//org 0x006B953F + +#include + +__asm__ +( + ".equ by_pass_address,0x006B9567-0x006B953F \n" +); + +__asm__ __volatile__ +( + "jmp . + by_pass_address \n" + ".align 128, 0x0 \n" +); + + + + diff --git a/hooks/hook_OnMotionTurnEvent3.cpp b/hooks/hook_OnMotionTurnEvent3.cpp new file mode 100644 index 00000000..735ab10d --- /dev/null +++ b/hooks/hook_OnMotionTurnEvent3.cpp @@ -0,0 +1,24 @@ +//HOOK OnMotionTurnEventChange2 ROffset = 0x2BFF2C + +//org 0x006BFF2C + +#include + +__asm__ +( + ".equ by_pass_address,0x006BFF55-0x006BFF2C \n" +); + +__asm__ __volatile__ +( + "jmp . + by_pass_address \n" + ".align 128, 0x0 \n" +); + + + + + + + + diff --git a/hooks/hook_Walls.cpp b/hooks/hook_Walls.cpp new file mode 100644 index 00000000..5276c521 --- /dev/null +++ b/hooks/hook_Walls.cpp @@ -0,0 +1,15 @@ +//HOOK WallSelection ROffset = 0x00465EC2 +#include + +__asm__ volatile +( + "nop \n" + "nop \n" + "nop \n" + "nop \n" + "nop \n" + "nop \n" + ".align 128, 0x0 \n" +); + + diff --git a/hooks/hook_aiinitattack.cpp b/hooks/hook_aiinitattack.cpp new file mode 100644 index 00000000..be02e5c6 --- /dev/null +++ b/hooks/hook_aiinitattack.cpp @@ -0,0 +1,22 @@ +//HOOK _aiinitattack compare with a null. ROffset = 0x80B4C2 + +#include + +//address on the left is the current instruction position. +//on the right, address is the final position. +__asm__ +( + ".equ end_func_goto_thread_validation,0x00C0B4C5-0x005F3B99 \n" + ".equ by_pass_address,0x00C0B4D1-0x005F39FD \n" +); + +__asm__ __volatile__ +( + "cmp ecx,0 \n" + "je . - end_func_goto_thread_validation \n" + "mov edx,dword ptr [ecx] \n" + "lea eax,dword ptr [ebp+0x60] \n" + "push eax \n" + "jmp . - by_pass_address \n" + ".align 128, 0x0 \n" +); diff --git a/hooks/hook_aiinitattack_jmp.cpp b/hooks/hook_aiinitattack_jmp.cpp new file mode 100644 index 00000000..d2236e62 --- /dev/null +++ b/hooks/hook_aiinitattack_jmp.cpp @@ -0,0 +1,16 @@ +//HOOK _aiinitattack prevents a crash when a target is in range but null is encountered. ROffset = 0x1F39F7 + +//org 0x005F39F7 +#include + +__asm__ +( + ".equ by_pass_address,0x00C0B4C2-0x005F39F7 \n" +); + +__asm__ __volatile__ +( + "jmp . + by_pass_address \n" + "nop \n" + ".align 128, 0x0 \n" +); diff --git a/hooks/jitH_AILuaFunc.jh b/hooks/jitH_AILuaFunc.jh new file mode 100644 index 00000000..cd7f6037 --- /dev/null +++ b/hooks/jitH_AILuaFunc.jh @@ -0,0 +1,10 @@ +--base=C0B4F0 +--offs=80B4F0 +--arch=x86 +Δ +cmp ecx, 0 ; 83F900 +je 7126220 ; 0F84D307ACFF +lea edx, dword [esp+40] ; 8D542428 +mov dword [esp+80], eax ; 89442450 +jmp 7126094 ; E94807ACFF +BYTES:83F9000F84D307ACFF8D54242889442450E94807ACFF diff --git a/hooks/jitH_AILuaFuncJmp.jh b/hooks/jitH_AILuaFuncJmp.jh new file mode 100644 index 00000000..c65028ac --- /dev/null +++ b/hooks/jitH_AILuaFuncJmp.jh @@ -0,0 +1,5 @@ +--base=6CBC46 +--offs=2CBC46 +--arch=x86 +jmp 12629232 ; E9A5F85300 +BYTES:E9A5F85300 diff --git a/hooks/jitH_OnmotionTurnEvent.jh b/hooks/jitH_OnmotionTurnEvent.jh new file mode 100644 index 00000000..33e69bd5 --- /dev/null +++ b/hooks/jitH_OnmotionTurnEvent.jh @@ -0,0 +1,6 @@ +--baseVA=6B8FB9 +--offs=2B8FB9 +--arch=x86 + +short jmp 7049184 ; EB25 +BYTES:EB25 diff --git a/hooks/jitH_OnmotionTurnEvent2.jh b/hooks/jitH_OnmotionTurnEvent2.jh new file mode 100644 index 00000000..a82916cb --- /dev/null +++ b/hooks/jitH_OnmotionTurnEvent2.jh @@ -0,0 +1,6 @@ +--baseVA=6B953F +--offs=2B953F +--arch=x86 + +short jmp 7050599 ; EB26 +BYTES:EB26 diff --git a/hooks/jitH_OnmotionTurnEvent3.jh b/hooks/jitH_OnmotionTurnEvent3.jh new file mode 100644 index 00000000..40c3dc00 --- /dev/null +++ b/hooks/jitH_OnmotionTurnEvent3.jh @@ -0,0 +1,6 @@ +--baseVA=6BFF2C +--offs=2BFF2C +--arch=x86 + +short jmp 7077717 ; EB27 +BYTES:EB27 diff --git a/hooks/jitH_RingRanges1.jh b/hooks/jitH_RingRanges1.jh new file mode 100644 index 00000000..03861110 --- /dev/null +++ b/hooks/jitH_RingRanges1.jh @@ -0,0 +1,6 @@ +--baseVA=896022 +--offs=496022 +--arch=x86 + +jmp 12629381 ; E95E553700 +BYTES:E95E553700 \ No newline at end of file diff --git a/hooks/jitH_RingRanges2.jh b/hooks/jitH_RingRanges2.jh new file mode 100644 index 00000000..8f3da9e2 --- /dev/null +++ b/hooks/jitH_RingRanges2.jh @@ -0,0 +1,6 @@ +--baseVA=896031 +--offs=496031 +--arch=x86 + +jmp 12629319 ; E911553700 +BYTES:E911553700 \ No newline at end of file diff --git a/hooks/jitH_RingRanges3.jh b/hooks/jitH_RingRanges3.jh new file mode 100644 index 00000000..c4a85fbf --- /dev/null +++ b/hooks/jitH_RingRanges3.jh @@ -0,0 +1,11 @@ +--baseVA=C0B585 +--offs=80B585 +--arch=x86 + +sub esp, 16424 ; 81EC28400000 +mov dword [esp], 0 ; C7042400000000 +add esp, 16424 ; 81C428400000 +mov eax, dword [eax] ; 8B00 +cmp eax, dword [esi+4] ; 3B4604 +jmp 9003047 ; E985AAC8FF +BYTES:81EC28400000C704240000000081C4284000008B003B4604E985AAC8FF \ No newline at end of file diff --git a/hooks/jitH_RingRanges4.jh b/hooks/jitH_RingRanges4.jh new file mode 100644 index 00000000..f6268b39 --- /dev/null +++ b/hooks/jitH_RingRanges4.jh @@ -0,0 +1,11 @@ +--baseVA=C0B547 +--offs=80B547 +--arch=x86 + +sub esp, 16424 ; 81EC28400000 +add dword [esp], 1 ; 83042401 +add esp, 16424 ; 81C428400000 +mov eax, dword [eax+16] ; 8B4010 +test eax, eax ; 85C0 +jmp 9003062 ; E9D5AAC8FF +BYTES:81EC284000008304240181C4284000008B401085C0E9D5AAC8FF \ No newline at end of file diff --git a/hooks/jitH_RingRanges5.jh b/hooks/jitH_RingRanges5.jh new file mode 100644 index 00000000..c4a5769c --- /dev/null +++ b/hooks/jitH_RingRanges5.jh @@ -0,0 +1,6 @@ +--baseVA=7EF198 +--offs=3EF198 +--arch=x86 + +jmp 12630643 ; E9D6C84100 +BYTES:E9D6C84100 \ No newline at end of file diff --git a/hooks/jitH_RingRanges6.jh b/hooks/jitH_RingRanges6.jh new file mode 100644 index 00000000..9a5f8756 --- /dev/null +++ b/hooks/jitH_RingRanges6.jh @@ -0,0 +1,17 @@ +--baseVA=C0BA73 +--offs=80BA73 +--arch=x86 + +cmp dword [esp-16488], 0 ; 83BC2498BFFFFF00 +short jne 12630668 ; 7507 +mov dword [esp-16488], ebx ; 899C2498BFFFFF +mov eax, dword [esp-16496] ; 8B842490BFFFFF +shl eax, 3 ; C1E003 +mov ecx, dword [esp-16488] ; 8B8C2498BFFFFF +lea edx, [esp+16] ; 8D542410 +mov esi, ebp ; 8BF5 +add eax, ecx ; 03C1 +cmp ebx, eax ; 3BD8 +jge 8319390 ; 0F8DF936BEFF +jmp 8319395 ; E9F936BEFF +BYTES:83BC2498BFFFFF007507899C2498BFFFFF8B842490BFFFFFC1E0038B8C2498BFFFFF8D5424108BF503C13BD80F8DF936BEFFE9F936BEFF \ No newline at end of file diff --git a/hooks/jitH_RingRanges7.jh b/hooks/jitH_RingRanges7.jh new file mode 100644 index 00000000..5dcd8808 --- /dev/null +++ b/hooks/jitH_RingRanges7.jh @@ -0,0 +1,7 @@ +--baseVA=7EF0FA +--offs=3EF0FA +--arch=x86 + +jmp 12630462 ; E9BFC84100 +nop ; 90 +BYTES:E9BFC8410090 \ No newline at end of file diff --git a/hooks/jitH_RingRanges8.jh b/hooks/jitH_RingRanges8.jh new file mode 100644 index 00000000..04a0e531 --- /dev/null +++ b/hooks/jitH_RingRanges8.jh @@ -0,0 +1,9 @@ +--baseVA=C0B9BE +--offs=80B9BE +--arch=x86 + +mov eax, dword [esp+40] ; 3E8B442428 +mov ebx, dword [eax] ; 8B18 +mov dword [esp-16488], ebx ; 899C2498BFFFFF +jmp 8319232 ; E92F37BEFF +BYTES:3E8B4424288B18899C2498BFFFFFE92F37BEFF \ No newline at end of file diff --git a/hooks/jitH_aiinitattack.jh b/hooks/jitH_aiinitattack.jh new file mode 100644 index 00000000..4074bafa --- /dev/null +++ b/hooks/jitH_aiinitattack.jh @@ -0,0 +1,11 @@ +--baseVA=C0B4C2 +--offs=80B4C2 +--arch=x86 + +cmp ecx, 0 ; 83F900 +je 6241177 ; 0F84CE869EFF +mov edx, dword [ecx] ; 8B11 +lea eax, dword [ebp+96] ; 8D4560 +push eax ; 50 +jmp 16071165 ; E927859EFF +BYTES:83F9000F84CE869EFF8B118D456050E927859EFF diff --git a/hooks/jitH_aiinitattackJmp.jh b/hooks/jitH_aiinitattackJmp.jh new file mode 100644 index 00000000..77736f03 --- /dev/null +++ b/hooks/jitH_aiinitattackJmp.jh @@ -0,0 +1,7 @@ +--baseVA=5F39F7 +--offs=1F39F7 +--arch=x86 + +jmp 12629186 ; E9C67A6100 +nop ; 90 +BYTES:E9C67A610090 diff --git a/linker/hookLinker.ld b/linker/hookLinker.ld new file mode 100644 index 00000000..da8a8447 --- /dev/null +++ b/linker/hookLinker.ld @@ -0,0 +1,25 @@ + +INCLUDE Env.ld + +/*MEMORY +{ + rom (rx) : ORIGIN = 0x006B8FB9, LENGTH = 0x1000 +}*/ + +/* Binary sections */ +SECTIONS +{ + . = 0x00000000; + + .text BLOCK(align_size): + { + *(.ext) + *(.text) + } + + .rdata BLOCK(align_size): + { + *(.rdata) + } + +} \ No newline at end of file diff --git a/linker/sectionLinker.ld b/linker/sectionLinker.ld new file mode 100644 index 00000000..d4ee5fbb --- /dev/null +++ b/linker/sectionLinker.ld @@ -0,0 +1,43 @@ +/* Entry point; at the very start of the binary */ +/*ENTRY(_ext_lua_LoadSavedGameHook)*/ + +INCLUDE Env.ld + +MEMORY +{ + rom (rwx) : ORIGIN = 0x128D000, LENGTH = 0x500000 +} + +/* Binary sections 0x01672161 */ +SECTIONS +{ + /* '.' is the location counter. It counts locations. */ + . = 0x128D000; + + /* Code */ + .text BLOCK(align_data): + { + *(.exxt) + *(.text) + } > rom + + .data BLOCK(align_data): + { + *(.data) + } > rom + + .rdata BLOCK(align_rdata): + { + KEEP(*(.rdata)) + } > rom + + .bss BLOCK(align_bss): + { + *(.bss) + } > rom + + .idata BLOCK(align_idata): + { + *(.idata) + } > rom +} \ No newline at end of file diff --git a/preprocessor/.gitignore b/preprocessor/.gitignore new file mode 100644 index 00000000..75b3f101 --- /dev/null +++ b/preprocessor/.gitignore @@ -0,0 +1,2 @@ +x64dbg.asm +x64dbg.gas \ No newline at end of file diff --git a/preprocessor/define.h b/preprocessor/define.h new file mode 100644 index 00000000..7d5050fd --- /dev/null +++ b/preprocessor/define.h @@ -0,0 +1,13 @@ +#define GFT__cmp_pointers 0x128d000 +#define GFT__sub_57FE30 0x128d170 +#define GFT__sub_582EB0 0x128d360 +#define GFT__sub_57DDD0 0x128d3c0 +#define GFT__Validate_IssueCommand 0x128d4e0 +#define GFT__IssueMove 0x128d700 +#define GFT__LuaPlus_LuaObject_LuaObject 0x128d9a0 +#define GFT__sub_5796A0 0x128d9d0 +#define GFT__Moho_SSTICommandIssueData_SSTICommandIssueData 0x128da20 +#define print_hello_world 0x128db00 +#define dec_IssueMove 0x128db20 +#define GFT__Push_Coordinates 0x128db30 +#define GFT__nanTest 0x128dba0 diff --git a/preprocessor/macro.h b/preprocessor/macro.h new file mode 100644 index 00000000..a81e48fb --- /dev/null +++ b/preprocessor/macro.h @@ -0,0 +1,2 @@ +#define QUAUX(X) #X +#define QU(X) QUAUX(X) diff --git a/sections/Get_Lua_Coordinates_State.nop b/sections/Get_Lua_Coordinates_State.nop new file mode 100644 index 00000000..8cc9090f --- /dev/null +++ b/sections/Get_Lua_Coordinates_State.nop @@ -0,0 +1,88 @@ +#include "include/global_func_table.h" +#include "include/funcDefs.h" + +funcDefs FD1; + +//----- (006EEF60) -------------------------------------------------------- +//int __usercall sub_6EEF60@(int a1@, double a2@, int *a3, int a4, int *a5, signed int a6) +//----- (102C99F0) -------------------------------------------------------- +int GFT::Get_Lua_Coordinates_State(int a1, struct LuaState *a2, int a3, struct lua_State **a4, int a5) +{ + int v5; // eax + int v6; // edi + int v7; // ecx + LuaPlus::LuaObject *v9; // eax + const char *v10; // eax + int v11; // ebx + int v12; // ebx + int v13; // edi + int v14; // eax + float v15; // ST1C_4 + float v16; // ST20_4 + double v17; // st7 + int v18; // [esp+14h] [ebp-38h] + int v19; // [esp+18h] [ebp-34h] + int v20; // [esp+1Ch] [ebp-30h] + int v21; // [esp+20h] [ebp-2Ch] + int v22; // [esp+24h] [ebp-28h] + int v23; // [esp+28h] [ebp-24h] + char v24; // [esp+2Ch] [ebp-20h] + int v25; // [esp+48h] [ebp-4h] + + if ( LuaPlus::LuaStackObject::IsNil((LuaPlus::LuaStackObject *)&a4) ) + { + *(_DWORD *)a1 = 0; + *(_DWORD *)(a1 + 4) = 0; + *(_DWORD *)(a1 + 8) = 0; + } + else + { + LuaPlus::LuaObject::LuaObject((LuaPlus::LuaObject *)&v24, (const struct LuaPlus::LuaStackObject *)&a4); + v25 = 0; + v5 = sub_101D0420((const struct LuaPlus::LuaObject *)&v24); + v25 = -1; + v6 = v5; + LuaPlus::LuaObject::~LuaObject((LuaPlus::LuaObject *)&v24); + if ( v6 ) + { + sub_10167D10(v7, v6, a1); + return a1; + } + if ( lua_type(*a4, a5) != 5 || LuaPlus::LuaStackObject::GetCount((LuaPlus::LuaStackObject *)&a4) != 3 ) + { + v9 = (LuaPlus::LuaObject *)LuaPlus::LuaObject::LuaObject( + (LuaPlus::LuaObject *)&v24, + (const struct LuaPlus::LuaStackObject *)&a4); + v25 = 1; + v10 = LuaPlus::LuaObject::TypeName(v9); + LuaPlus::LuaState::Error(a2, "Invalid target set in %s; expected an entity or a Vec3 but got a %s", a3, v10); + v25 = -1; + LuaPlus::LuaObject::~LuaObject((LuaPlus::LuaObject *)&v24); + } + lua_rawgeti(*a4, a5, 3); + v11 = (int)a4; + v23 = lua_gettop(*a4); + v22 = v11; + lua_rawgeti(*a4, a5, 2); + v12 = (int)a4; + v21 = lua_gettop(*a4); + v20 = v12; + lua_rawgeti(*a4, a5, 1); + v13 = (int)a4; + v14 = lua_gettop(*a4); + v18 = v13; + v19 = v14; + v15 = LuaPlus::LuaStackObject::GetNumber((LuaPlus::LuaStackObject *)&v18); + v16 = LuaPlus::LuaStackObject::GetNumber((LuaPlus::LuaStackObject *)&v20); + v17 = LuaPlus::LuaStackObject::GetNumber((LuaPlus::LuaStackObject *)&v22); + *(_DWORD *)a1 = 2; + *(float *)(a1 + 12) = v15; + *(float *)(a1 + 16) = v16; + *(_DWORD *)(a1 + 4) = 0; + *(_DWORD *)(a1 + 8) = 0; + *(float *)(a1 + 20) = v17; + } + *(_BYTE *)(a1 + 28) = 0; + *(_DWORD *)(a1 + 24) = -1; + return a1; +} diff --git a/sections/IssueMove.cpp b/sections/IssueMove.cpp new file mode 100644 index 00000000..24cff9ef --- /dev/null +++ b/sections/IssueMove.cpp @@ -0,0 +1,255 @@ +#include "include/funcDefs.h" +#include "include/global_func_table.h" +#include + + +int dword_10B83A4 = 0x010B83A4; + +funcDefs Fd; +GFT gft; + +//----- (006F26D0) -------------------------------------------------------- +int GFT::IssueMove() +{ + register int eax asm("eax"); + register int esp asm("esp"); + register int ecx asm("ecx"); + register int edx asm("edx"); + register int ebx asm("ebx"); + register int esi asm("esi"); + register int edi asm("edi"); + __asm__ + ( + "pop ebx \n " + "pop esi \n " + "pop edi \n " + "push ebp \n " + "mov ebp,esp \n " + "and esp,0xFFFFFFF8 \n " + "mov eax,dword ptr [fs:0x0] \n " + "push 0xFFFFFFFF \n " + "push 0xBB5873 \n " + "push eax \n " + "mov dword ptr [fs:0x0],esp \n " + "mov eax,dword ptr [ebx] \n " + "sub esp,0x11C \n " + "push esi \n " + "mov esi,dword ptr [0x10B83A4] \n " + "push edi \n " + ); + Fd.lua_gettop(eax); + __asm__ ( + "add esp,0x4 \n " + "cmp eax,0x2 \n " + "je label1 \n " + ); + Fd.LuaState__Error(ebx, (char*)"%s\n expected %d args, but got %d", esi, 2, eax); + __asm__ ( + "add esp,0x14 \n " + "label1: \n" + "lea ecx,dword ptr [esp+0x18] \n " + "mov edx,ecx \n " + "lea eax,dword ptr [esp+0x30] \n " + "mov dword ptr [esp+0x1C],ecx \n " + "mov dword ptr [esp+0x18],edx \n " + "mov ecx,eax \n " + "lea edx,dword ptr [esp+0x40] \n " + "mov dword ptr [esp+0x20],eax \n " + "mov dword ptr [esp+0x24],ecx \n " + "mov dword ptr [esp+0x28],edx \n " + "mov dword ptr [esp+0x2C],eax \n " + "push 0xE2ED00 \n " + "push ebx \n " + "lea ecx,dword ptr [esp+0x18] \n " + "push ecx \n " + "lea edx,dword ptr [esp+0x74] \n " + "mov dword ptr [esp+0x138],0 \n " + "push edx \n " + "mov dword ptr [esp+0x20],ebx \n " + "mov dword ptr [esp+0x24],1 \n " + "call 7274048 \n " + ); + __asm__ ( + "lea ecx,dword ptr [esp+0x28] \n " + "push 0x1 \n " + "push ecx \n " + "mov edi,eax \n " + "mov byte ptr [esp+0x144],1 \n " + "call 7273712 \n " + ); + //Fd.Validate_IssueCommand(edi, ecx, 1); + __asm__ ( + "mov byte ptr [esp+0x144],0 \n " + "mov byte ptr [esp+0x27],al \n " + "mov eax,dword ptr [esp+0x88] \n " + "add esp,0x18 \n " + "cmp eax,dword ptr [esp+0x7C] \n " + "je label3 \n " + ); + Fd.j_shi_delete_0(eax); + __asm__ ( + "add esp,0x4 \n " + "label3: \n" + "cmp byte ptr [esp+0xF],0 \n " + "mov edx,dword ptr [esp+0x68] \n " + "mov eax,dword ptr [esp+0x6C] \n " + "mov dword ptr [edx+0x4],eax \n " + "mov ecx,dword ptr [esp+0x6C] \n " + "mov edx,dword ptr [esp+0x68] \n " + "mov dword ptr [ecx],edx \n " + "je label2 \n " + "sub esp,0x8 \n " + "mov eax,esp \n " + "mov dword ptr [esp+0x18],esp \n " + "push 0xE2ED00 \n " + "push ebx \n " + "lea edi,dword ptr [esp+0x78] \n " + "mov dword ptr [eax],ebx \n " + "mov dword ptr [eax+0x4],2 \n " + ); + //Fd.Get_Lua_Coordinates_State(,(int)"IssueMove",ebx,2); + __asm__ ( + "call 7274336 \n " + "mov ecx,eax \n " + "add esp,0x10 \n " + "lea eax,dword ptr [esp+0x40] \n " + ); + __asm__ ( + "call 6174672 \n " + "mov eax,dword ptr [esp+0x44] \n " + "movss xmm0,dword ptr [esp+0x48] \n " + "mov edi,dword ptr [esp+0x40] \n " + "movss dword ptr [esp+0x5C],xmm0 \n " + "movss xmm0,dword ptr [esp+0x4C] \n " + "mov dword ptr [esp+0x58],eax \n " + "mov eax,dword ptr [esp+0x6C] \n " + "test eax,eax \n " + "movss dword ptr [esp+0x60],xmm0 \n " + "movss xmm0,dword ptr [esp+0x50] \n " + "mov dword ptr [esp+0x54],edi \n " + "movss dword ptr [esp+0x64],xmm0 \n " + "je label4 \n " + "lea ecx,dword ptr [esp+0x6C] \n " + "cmp dword ptr [eax],ecx \n " + "je label5 \n " + "lea ecx,dword ptr [ecx] \n " + "label6:" + "mov eax,dword ptr [eax] \n " + "add eax,0x4 \n " + "lea edx,dword ptr [esp+0x6C] \n " + "cmp dword ptr [eax],edx \n " + "jne label6 \n " + "label5:" + "mov ecx,dword ptr [esp+0x70] \n " + "mov dword ptr [eax],ecx \n " + "label4:" + "lea esi,dword ptr [esp+0x5C] \n " + ); + __asm__ ( + "call 5662704 \n " + "test al,al \n " + "je label7 \n " + "test edi,edi \n " + "jne label8 \n " + "label7:" + "push 0xE2ED0C \n " + "push ebx \n " + ); + __asm__ ( + "call 9490896 \n " + "add esp,0x8 \n " + "label8:" + "lea edx,dword ptr [esp+0x90] \n " + "push edx \n " + "mov ecx,0x2 \n " + ); + __asm__ ( + "call 5584208 \n " + "mov esi,eax \n " + "mov byte ptr [esp+0x12C],2 \n " + "mov eax,dword ptr [esp+0x44] \n " + "movss xmm0,dword ptr [esp+0x48] \n " + "mov dword ptr [esi+0x10],edi \n " + "mov dword ptr [esi+0x14],eax \n " + "mov eax,dword ptr [ebx] \n " + "movss dword ptr [esi+0x18],xmm0 \n " + "movss xmm0,dword ptr [esp+0x4C] \n " + "movss dword ptr [esi+0x1C],xmm0 \n " + "movss xmm0,dword ptr [esp+0x50] \n " + "push eax \n " + "movss dword ptr [esi+0x20],xmm0 \n " + ); + __asm__ ( + "call 9588816 \n " + "add esp,0x4 \n " + "push 0x0 \n " + "push esi \n " + "push eax \n " + "lea edx,dword ptr [esp+0x24] \n " + ); + __asm__ ( + "call 7283392 \n " + "add esp,0xC \n " + "lea ecx,dword ptr [esp+0x90] \n " + "push ecx \n " + "mov esi,eax \n " + "mov byte ptr [esp+0x130],0 \n " + ); + __asm__ ( + "call 5749680 \n " + "test esi,esi \n " + "je label2 \n " + "push ebx \n " + "lea edx,dword ptr [esp+0x14] \n " + "push edx \n " + "lea ecx,dword ptr [esi+0x20] \n " + ); + __asm__ ( + "call 9473408 \n " + "lea esi,dword ptr [esp+0x18] \n " + ); + __asm__ ( + "call 5744288 \n " + "jmp label9 \n " + "label2:" + "mov eax,dword ptr [ebx] \n " + "push eax \n " + ); + __asm__ ( + "call 9493760 \n " + "mov ecx,dword ptr [ebx] \n " + "add esp,0x4 \n " + "push ecx \n " + ); + __asm__ ( + "call 9491856 \n " + "mov eax,dword ptr [esp+0x24] \n " + "add esp,0x4 \n " + "cmp eax,dword ptr [esp+0x2C] \n " + "je label10 \n " + "push eax \n " + ); + __asm__ ( + "call 11023682 \n " + "add esp,0x4 \n " + "label10:" + "mov edx,dword ptr [esp+0x18] \n " + "mov eax,dword ptr [esp+0x1C] \n " + "mov dword ptr [edx+0x4],eax \n " + "mov ecx,dword ptr [esp+0x1C] \n " + "mov edx,dword ptr [esp+0x18] \n " + "mov dword ptr [ecx],edx \n " + "label9:" + ); + __asm__ ( + "mov ecx,dword ptr [esp+0x124] \n " + "pop edi \n " + "mov eax,0x1 \n " + "mov dword ptr [fs:0x0],ecx \n " + "pop esi \n " + "mov esp,ebp \n " + "pop ebp \n " + "ret \n " + ); + +} diff --git a/sections/Makefile b/sections/Makefile new file mode 100644 index 00000000..cddd3b2e --- /dev/null +++ b/sections/Makefile @@ -0,0 +1,58 @@ +ifeq ($(OS),Windows_NT) + detected_OS := Windows +else + detected_OS := $(shell sh -c 'uname -s 2>/dev/null || echo not') +endif + +#OBJS specifies which files to compile as part of the project +SRCS=$(wildcard *.cpp) + +OBJS=$(SRCS:.cpp=.o) +LINK_OBJS:= $(addprefix ../build/,$(OBJS)) + +PROGS = $(patsubst %.cpp,../build/%.o,$(SRCS)) + +#HEADS = funcDef.h + +#CC specifies which compiler we're using +CC = g++ +#INCLUDE_PATHS specifies the additional include paths we'll need +#INCLUDE_PATHS = -I ./SDL2-2.0.8/i686-w64-mingw32/include/ + +#LIBRARY_PATHS specifies the additional library paths we'll need +LIBRARY_PATHS = -L ../lib + +#COMPILER_FLAGS specifies the additional compilation options we're using +# -w suppresses all warnings +# -Wl,-subsystem,windows gets rid of the console window +ifeq ($(detected_OS),Windows) +COMPILER_FLAGS = -fleading-underscore +LD_FLAGS = --image-base 0x128D000 +else +LD_FLAGS = -Ttext-segment 0x128D000 -m elf_i386 +endif + +#LINKER_FLAGS specifies the libraries we're linking against + +#STD = -static-libgcc -static-libstdc++ + +LINKER_FLAGS = -I. -m32 -O3 -fno-exceptions -fno-asynchronous-unwind-tables -Wall -w -fpermissive -Wextra -masm=intel + +#this flag ensures that gcc compiler uses 'push' instructions for functions parameters. +FUNC_CALL_PARAMS_FLAGS = -mpush-args -mno-accumulate-outgoing-args -mno-stack-arg-probe + +#BOOST = -lboost_thread-mgw63-mt-d-x32-1_67 -lboost_regex-mgw63-mt-d-x32-1_67 -lboost_system-mgw63-mt-d-x32-1_67 + +OUTPUT = ../build/ext_sector.o + +#This is the target that compiles our executable +all_individual : $(PROGS) +../build/%.o: %.cpp + $(CC) -c $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) $(FUNC_CALL_PARAMS_FLAGS) $(STD) $(LINKER_FLAGS) $(BOOST) -o $@ $< + +all : + $(CC) $(HEADS) -c $(INCLUDE_PATHS) $(LIBRARY_PATHS) $(COMPILER_FLAGS) $(STD) $(LINKER_FLAGS) $(BOOST) -o $(OUTPUT) ext_sector.cpp + +# --image-base. only windows ld supports this. It marks the starting virtual address of the file built. +link: + ld $(LD_FLAGS) -Map ../build/mapfile.map -o ../build/exxt_sector.o $(LINK_OBJS) diff --git a/sections/Push_Coordinates.cpp b/sections/Push_Coordinates.cpp new file mode 100644 index 00000000..515a3915 --- /dev/null +++ b/sections/Push_Coordinates.cpp @@ -0,0 +1,48 @@ +#include "include/global_func_table.h" +#include "include/funcDefs.h" + +//funcDefs FD; + +//----- (005E27D0) -------------------------------------------------------- +//int __usercall sub_5E27D0@(int result@, int a2@) +int GFT::Push_Coordinates(int result, int a2) +{ + int v2; // edx + int v3; // ecx + int v4; // ecx + + if ( *(_DWORD *)a2 == 1 ) + { + v2 = *(_DWORD *)(a2 + 4); + if ( v2 && v2 != 4 ) + { + v3 = *(_DWORD *)(a2 + 4); + if ( v3 ) + v4 = *(_DWORD *)(v3 - 4 + 104); + else + // v4 = MEMORY[0x68]; + *(_DWORD *)result = 1; + *(_DWORD *)(result + 4) = v4; + goto LABEL_13; + } + *(_DWORD *)result = 1; + } + else + { + if ( *(_DWORD *)a2 == 2 ) + { + *(_DWORD *)result = 2; + *(_DWORD *)(result + 4) = -268435456; + *(float *)(result + 8) = *(float *)(a2 + 12); + *(float *)(result + 12) = *(float *)(a2 + 16); + *(float *)(result + 16) = *(float *)(a2 + 20); + return result; + } + *(_DWORD *)result = 0; + } + *(_DWORD *)(result + 4) = -268435456; +LABEL_13: + //*(_QWORD *)(result + 12) = 0i64; + *(_DWORD *)(result + 8) = 0; + return result; +} diff --git a/sections/README.md b/sections/README.md new file mode 100644 index 00000000..1d99bc3f --- /dev/null +++ b/sections/README.md @@ -0,0 +1,5 @@ +When we need to allocate more memory for code or load the library. + +Really anything. The pacther creates a section on the target exe and links + +whatever c++ source code on that memory. Later we can write it out. \ No newline at end of file diff --git a/sections/Validate_IssueCommand.cpp b/sections/Validate_IssueCommand.cpp new file mode 100644 index 00000000..3f19f41c --- /dev/null +++ b/sections/Validate_IssueCommand.cpp @@ -0,0 +1,228 @@ +#include "include/global_func_table.h" +#include "include/funcDefs.h" + +funcDefs FD; + +//_DWORD *__usercall sub_581270@(_DWORD *result@, _DWORD *a2@, _DWORD *a3@) +_DWORD* GFT::cmp_pointers(_DWORD *result, _DWORD *a2, _DWORD *a3) +{ + for ( ; a3 != a2; ++result ) + { + if ( result ) + { + *result = *a3; + ++a3; + } + } + return result; +} + +//int __fastcall sub_5811A0(_DWORD *a1, int a2, int a3, _DWORD *a4, _DWORD *a5) +__attribute__((fastcall)) int GFT::sub_5811A0(_DWORD *a1, int a2, int a3, _DWORD *a4, _DWORD *a5) +{ + _DWORD *v5; // edi + int v6; // esi + _DWORD *v7; // eax + _DWORD *v8; // ebx + _DWORD *v9; // ecx + _DWORD *v10; // eax + _DWORD *v11; // eax + _DWORD *v12; // edi + _DWORD *i; // eax + _DWORD *v14; // eax + int result; // eax + int v16; // [esp+0h] [ebp-20h] + _DWORD *v17; // [esp+Ch] [ebp-14h] + int *v18; // [esp+10h] [ebp-10h] + int v19; // [esp+1Ch] [ebp-4h] + + v5 = a1; + v18 = &v16; + v6 = a2; + v7 = (_DWORD *)FD.j_shi_new_0(4 * a3); + v8 = v7; + v19 = 0; + v9 = *(_DWORD **)v6; + v17 = v7; + v10 = cmp_pointers(v7, v5, v9); + v11 = cmp_pointers(v10, a5, a4); + v12 = cmp_pointers(v11, *(_DWORD **)(v6 + 4), v5); + for ( i = *(_DWORD **)v6; i != *(_DWORD **)(v6 + 4); ++i ) + ; + v14 = *(_DWORD **)(v6 + 12); + if ( *(_DWORD **)v6 == v14 ) + *v14 = *(_DWORD *)(v6 + 8); + else + FD.j_shi_delete_0(*(_DWORD **)v6); + result = a3; + *(_DWORD *)(v6 + 4) = v12; + *(_DWORD *)v6 = v8; + *(_DWORD *)(v6 + 8) = &v8[a3]; + return result; +} + +//_DWORD *__stdcall sub_57FE30(int a1, void *a2, void *Src, int a4) +_DWORD* GFT::sub_57FE30(int a1, void *a2, void *Src, int a4) +{ + _DWORD *v4; // esi + int v5; // ebx + unsigned int v6; // eax + unsigned int v7; // ecx + unsigned int v8; // ecx + _DWORD *result; // eax + int v10; // eax + _DWORD *v11; // eax + int v12; // ebx + int v13; // edi + int v14; // edi + + v4 = *(_DWORD *)(a1 + 4); + v5 = (a4 - (signed int)Src) >> 2; + v6 = v5 + ((*(_DWORD *)(a1 + 4) - *(_DWORD *)a1) >> 2); + v7 = (*(_DWORD *)(a1 + 8) - *(_DWORD *)a1) >> 2; + if ( v6 <= v7 ) + { + v10 = 4 * v5; + if ( (char *)a2 + 4 * v5 <= v4 ) + { + v13 = (int)&v4[-v10]; + result = cmp_pointers(v4, v4, &v4[-v10]); + v14 = (v13 - (signed int)a2) >> 2; + *(_DWORD *)(a1 + 4) = result; + if ( v14 > 0 ) + result = (_DWORD *)FD.memmove_s(&v4[-4 * v14], 4 * v14, a2, 4 * v14); + if ( v5 > 0 ) + result = (_DWORD *)FD.memmove_s(a2, 4 * v5, Src, 4 * v5); + } + else + { + v11 = cmp_pointers(v4, (_DWORD *)a4, (_DWORD *)Src + ((v4 - (_DWORD *)a2) >> 2)); + *(_DWORD *)(a1 + 4) = v11; + result = cmp_pointers(v11, v4, a2); + v12 = 4 * ((v4 - (_DWORD *)a2) >> 2) >> 2; + *(_DWORD *)(a1 + 4) = result; + if ( v12 > 0 ) + result = (_DWORD *)FD.memmove_s(&v4[-4 * v12], 4 * v12, Src, 4 * v12); + } + } + else + { + v8 = 2 * v7; + if ( v6 < v8 ) + v6 = v8; + result = (_DWORD *)sub_5811A0(a2, a1, v6, Src, (_DWORD *)a4); + } + return result; +} + +//----- (10174AD0) -------------------------------------------------------- +//----- (00582EB0) -------------------------------------------------------- +//int __usercall sub_582EB0@(int *a1@, int a2@, int a3@) +int GFT::sub_582EB0(int *a1, int a2, int a3) +{ + int v3; // esi + int v4; // ecx + int v5; // edi + int v6; // eax + int v7; // edx + + v3 = a2; + v4 = (a3 - a2) >> 2; + if ( v4 > 0 ) + { + v5 = *a1; + do + { + v6 = v4 / 2; + if ( v5 ) + v7 = v5 + 8; + else + v7 = 0; + if ( *(_DWORD *)(*(_DWORD *)(v3 + 4 * v6) + 104) >= *(_DWORD *)(v7 + 104) ) + { + v4 /= 2; + } + else + { + v3 += 4 * v6 + 4; + v4 += -1 - v6; + } + } + while ( v4 > 0 ); + } + return v3; +} + +//int __userpurge sub_57DDD0@(int a1@, int a2@, int Src, int a4) +int GFT::sub_57DDD0(int a1, int a2, int Src, int a4) +{ + int v4; // esi + _DWORD *v5; // ebp + int v6; // edi + _DWORD *v7; // eax + int v8; // edx + int result; // eax + int v10; // esi + + v4 = *(_DWORD *)(a1 + 12); + v5 = (_DWORD *)(a1 + 8); + v6 = *(_DWORD *)(a1 + 8); + v7 = (_DWORD *)sub_582EB0(&Src, v6, v4); + if ( v7 == (_DWORD *)v4 || (!Src ? (v8 = 0) : (v8 = Src + 8), *v7 != v8) ) + { + v10 = ((signed int)v7 - v6) >> 2; + if ( Src ) + Src += 8; + else + Src = 0; + sub_57FE30((int)v5, v7, &Src, (int)&a4); + *(_DWORD *)a2 = *v5 + 4 * v10; + *(_BYTE *)(a2 + 4) = 1; + result = a2; + } + else + { + *(_DWORD *)a2 = v7; + *(_BYTE *)(a2 + 4) = 0; + result = a2; + } + return result; +} + +//----- (006EECF0) -------------------------------------------------------- +//BOOL __usercall sub_6EECF0@(int a1@, int a2, int a3) +bool GFT::Validate_IssueCommand(int a1, int a2, int a3) +{ + _DWORD *i; // esi + int v4; // ecx + int v5; // eax + int v6; // ecx + int v7; // ecx + int v8; // eax + int v10; // [esp+0h] [ebp-1Ch] + char v11; // [esp+10h] [ebp-Ch] + + for ( i = *(_DWORD **)(a1 + 8); i != *(_DWORD **)(a1 + 12); ++i ) + { + if ( *i ) + v4 = *i - 8; + else + v4 = 0; + if ( a3 & *(_DWORD *)((*(int (**)(void))(*(_DWORD *)v4 + 64))() + 96) ) + { + if ( !(a3 & 0x19) && !(a3 & 0x2000) + || (!*i ? (v5 = 0) : (v5 = *i - 8), + (v6 = *(_DWORD *)(v5 + 1348)) == 0 + || !(*(unsigned __int8 (**)(void))(*(_DWORD *)v6 + 4))() + || (!*i ? (v7 = 0) : (v7 = *i - 8), (*(unsigned __int8 (**)(void))(*(_DWORD *)v7 + 48))())) ) + { + if ( *i ) + v8 = *i - 8; + else + v8 = 0; + sub_57DDD0(a2, (int)&v11, v8, v10); + } + } + } + return *(_DWORD *)(a2 + 8) != *(_DWORD *)(a2 + 12); +} diff --git a/sections/ext_sector.cpp b/sections/ext_sector.cpp new file mode 100644 index 00000000..115a8694 --- /dev/null +++ b/sections/ext_sector.cpp @@ -0,0 +1,40 @@ + +#include "include/moho.h" +#include "include/funcDefs.h" +#include +#include "include/global_func_table.h" +/* #include +#include +#include +#include +#include +#include +#include */ + +// New unit categories. +//const char* sCQUEMOV = "CQUEMOV"; +//const char* sSTAYONWATSUR = "STAYONWATSUR"; +// ForgedAlliance.exe addresses. + +funcDefs fd; +GFT Gft; +register int eax asm("eax"); + +void print_hello_world() +{ + fd.Logf("Hello World!"); +} + +int dec_IssueMove() +{ + return Gft.IssueMove(); +} + +/* void Thread__() +{ + hw HW; + boost::thread worker(boost::bind(&hw::print_hello_world, &HW)); + worker.join(); +} + +int main(){} */ diff --git a/sections/include/funcDefs.h b/sections/include/funcDefs.h new file mode 100644 index 00000000..01394228 --- /dev/null +++ b/sections/include/funcDefs.h @@ -0,0 +1,133 @@ +#include "global.h" +#include "typeDefs.h" +#include "moho.h" +#include + +//((int (*)(const char* fmt, ...))_Logf)("Hello World!"); //direct call example +/* typedef void __Logf(const char* fmt, ...); + __Logf* Logf = reinterpret_cast<__Logf*>(_Logf); */ + +//required functions that have not been reversed yet. + +class funcDefs +{ +public: + + typedef void __Logf(const char* fmt, ...); + __Logf *Logf = (__Logf*)(_Logf); + + typedef void __LuaState__Error(LuaState *a1, char *a2, ...); + __LuaState__Error *LuaState__Error = (__LuaState__Error*)(_LuaState__Error); + + typedef int __lua_gettop(int a1); + __lua_gettop *lua_gettop = (__lua_gettop*)(_lua_gettop); + + typedef __attribute__((cdecl)) _DWORD *__Eval_Lua_Object(int *a1, const struct LuaStackObject *a2, LuaState *a3, int a4); + __Eval_Lua_Object *Eval_Lua_Object = (__Eval_Lua_Object*)(_Eval_Lua_Object); + + typedef bool __Validate_IssueCommand(int a1, int a2, int a3); + __Validate_IssueCommand *Validate_IssueCommand = (__Validate_IssueCommand*)(_Validate_IssueCommand); + + typedef __attribute__((thiscall)) int __Get_Lua_Coordinates_State(int a1, LuaState *a2, int a4, lua_State **a5, int a6); + __Get_Lua_Coordinates_State *Get_Lua_Coordinates_State = (__Get_Lua_Coordinates_State*)(_Get_Lua_Coordinates_State); + + typedef int __Push_Coordinates(int result, int a2); + __Push_Coordinates *Push_Coordinates = (__Push_Coordinates*)(_Push_Coordinates); + + typedef int __Moho_UNIT_IssueCommand(int a1, int a2, Moho__SSTICommandIssueData *a3, char a4); + __Moho_UNIT_IssueCommand *Moho_UNIT_IssueCommand = (__Moho_UNIT_IssueCommand*)(_Moho_UNIT_IssueCommand); + + typedef int __Moho_SSTICommandIssueData_SSTICommandIssueData(_DWORD *_this, int a2); + __Moho_SSTICommandIssueData_SSTICommandIssueData *Moho_SSTICommandIssueData_SSTICommandIssueData = (__Moho_SSTICommandIssueData_SSTICommandIssueData*)(_Moho_SSTICommandIssueData_SSTICommandIssueData); + + typedef int __attribute__((stdcall)) __Moho_SSTICommandIssueData_Destructor_SSTICommandIssueData(int a1); + __Moho_SSTICommandIssueData_Destructor_SSTICommandIssueData *Moho_SSTICommandIssueData_Destructor_SSTICommandIssueData = + (__Moho_SSTICommandIssueData_Destructor_SSTICommandIssueData*)(_Moho_SSTICommandIssueData_Destructor_SSTICommandIssueData); + + typedef uint32 *__LuaPlus_LuaState_PushNil(int a1); + __LuaPlus_LuaState_PushNil *LuaPlus_LuaState_PushNil = (__LuaPlus_LuaState_PushNil*)(_LuaPlus_LuaState_PushNil); + + typedef _DWORD *__LuaPlus_LuaObject_PushStack(_DWORD *_this, _DWORD *a2, lua_State **a3); + __LuaPlus_LuaObject_PushStack *LuaPlus_LuaObject_PushStack = (__LuaPlus_LuaObject_PushStack*)(_LuaPlus_LuaObject_PushStack); + + //extern functions: + //MSVCR80.dll + typedef __attribute__((cdecl)) int __memmove_s(void *Dst, size_t DstSize, const void *Src, size_t MaxCount); + __memmove_s *memmove_s = (__memmove_s*)(_memmove_s); + + typedef __attribute__((cdecl)) int __lua_getglobaluserdata(int a1); + __lua_getglobaluserdata *lua_getglobaluserdata = (__lua_getglobaluserdata*)(_lua_getglobaluserdata); + + //shsmp.dll + typedef void __j_shi_delete_0(int a1); + __j_shi_delete_0 *j_shi_delete_0 = (__j_shi_delete_0*)(_j_shi_delete_0); + + typedef int __j_shi_new_0(int a1); + __j_shi_new_0 *j_shi_new_0 = (__j_shi_new_0*)(_j_shi_new_0); + + + volatile int __Push_Coordinatesw(int r, int a2) + { + int result; + __asm volatile( + "mov ecx, %[a2] \n\t" //point to the structure + "mov eax, %[r] \n\t" + "call %[func]\n\t" + : "=a" (result) + : [func] "m" (_Push_Coordinates), [r] "r" (r), [a2] "r" (a2) + : "memory" + ); + return result; + } + + volatile bool __Validate_IssueCommandw(int a1, int a2, int a3) + { + int result; + __asm volatile( + "push %[a3] \n\t" + "push %[a2] \n\t" + "mov edi, %[a1] \n\t" + "call %[func]\n\t" + : "=a" (result) + : [func] "m" (_Validate_IssueCommand), [a1] "r" (a1), [a2] "r" (a2), [a3] "r" (a3) + : "memory" + ); + return result; + } + + volatile int __Get_Lua_Coordinates_Statew(int a1, LuaState *a2, int a4, lua_State **a5, int a6) + { + register int result asm("eax"); + __asm volatile( + "push %[a6] \n\t" + "push %[a5] \n\t" + "push %[a4] \n\t" + "push %[a2] \n\t" + //"mov st(0), %[a2] \n\t" + "mov edi, %[a1] \n\t" + "call %[func]\n\t" + : "=a" (result) + : [func] "m" (_Get_Lua_Coordinates_State), [a1] "r" (a1), [a2] "r" (a2), [a4] "r" (a4), [a5] "r" (a5), [a6] "r" (a6) + : "memory" + ); + return result; + } + + volatile int Moho_UNIT_IssueCommandw(int a1, int a2, Moho__SSTICommandIssueData *a3, int a4) + { + int result; + __asm volatile( + "push %[a4] \n\t" + "push %[a3] \n\t" + "push %[a2] \n\t" + "mov edx,%[a1] \n\t" + "call %[func]\n\t" + : "=a" (result) + : [func] "m" (_Moho_UNIT_IssueCommand), [a1] "r" (a1), [a2] "r" (a2), [a3] "r" (a3), [a4] "r" (a4) + : "memory" + ); + return result; + + } + +}; diff --git a/sections/include/global.h b/sections/include/global.h new file mode 100644 index 00000000..a4f6d99d --- /dev/null +++ b/sections/include/global.h @@ -0,0 +1,95 @@ +#pragma once +//LuaPlus +const int LuaState__CastState = 0x90A510; // LuaState* (lua_state*) +const int _LuaState__Error = 0x90C1D0; // (LuaState*, fmt, args...) +const int _CastState_LuaState_LuaPlus__SAPAV12_PAUlua_State___Z = 0x90A510; +const int __0LuaObject_LuaPlus__QAE_ABVLuaStackObject_1__Z = 0x908A70; +const int __1LuaObject_LuaPlus__QAE_XZ = 0x9075D0; +const int LuaObject_GetString = 0x907A90; + +// struct LuaStackObject +// { +// // 0x8 bytes +// LuaState* state; +// int stack_index; +// }; + +const int LuaStackObject__GetBoolean = 0x415560; + +const int lua_pushnumber = 0x90CD40; //(lua_state*, float) +const int _lua_pushbool = 0x90CF80; //(lua_state*, bool) + +const int _AssignClientIndex_CLobby_Moho__AAEXHVStrArg_gpg__AAIAAH_Z = 0x7C4E80; +const int _AssignCommandSource_CLobby_Moho__AAEIHHAAV_$vector_USSTICommandSource_Moho__V_$allocator_USSTICommandSource_Moho___std___std__AAI_ = 0x7C4F60; + +const int lua_cast_CLobby_ = 0x7CB7E0; + +const int Moho__NET_MakeNATTraversal_ = 0x7BC5F0; //(LuaObject* rvo, LuaState*) +const int LuaObject_PushStack = 0x907D80; //(LuaStackObject* rvo, LuaState*) +const int _Eval_Lua_Object = 0x6EEE40; +const int _LuaPlus_LuaState_PushNil = 0x0090CD00; +const int _LuaPlus_LuaObject_PushStack = 0x00907D80; +const int _lua_getglobaluserdata = 0x00924050; + +// Returned object is probably an iterator of sorts_ +// It is 0x10 bytes. +const int Moho__BVSet_Add = 0x6E5660; //void* __stdcall (void* this, void* rvo, int setItem) +const int Moho__Set__Add = 0x4036A0; //void *__stdcall (void *this, void *rvo, int setItem) + + +// Utils +const int _lua_tostring__YAPBDPAUlua_State__H_Z = 0x90CA90; +const int _lua_tostring = 0x90CA90; +const int _lua_tonumber = 0x90C9F0; +const int _lua_toboolean = 0x90CA40; +const int __imp_atoi = 0xA835CE; + +const int __ftol2_sse = 0xA89CC0; + +const int _lua_gettop = 0x90C590; //(lua_state*) + +const int __stricmp = 0xAA549E; //int (const char*, const char*) + +//const int Logf = 0x937CB0; +const int _Logf = 0x937CB0; +const int _Validate_IssueCommand = 0x006EECF0; +const int _j_shi_delete_0 = 0x00A82542; +const int _j_shi_new_0 = 0x00A82130; +const int _Get_Lua_Coordinates_State = 0x006EEF60; +const int _Push_Coordinates = 0x005E27D0; +const int _Moho_UNIT_IssueCommand = 0x006F12C0; +const int _Moho_SSTICommandIssueData_Destructor_SSTICommandIssueData = 0x0057ABB0; + +// Globals + +const int g_STIDriver = 0x10C4F50; +const int g_SWldSessionInfo = 0x10C4F58; +const int g_CWldSession = 0x10A6470; +const int _g_CWldSession = 0x10A6470; + +const int _g_Sim = 0x10A63F0; + +// String const +const int s_FACTORY = 0xE19824; +const int s_EXPERIMENTAL = 0xE204B8; + +// Int const + +//Adress const +const int _CannotQueCommandInConstruct = 0x006EFB0E; +const int _CanQueCommandInConstruct = 0x006EFAF8; +const int _NeitherInCategoryInConstruct = 0x006EFACE; +const int _EndCalculateNoRushTimerVariable = 0x006FF3D6; + +// c Symbols + +const int _CheckCategory = 0x00405550; +const int _CheckCategory_sub_func = 0x004059E0; +const int _GetCatCmpResult = 0x0067B050; +const int _exit_STAYONWATSUR_check = 0x0062ADEE; +const int _exit_STAYONWATSUR_NoMatch = 0x0062ADEC; +const int _Moho_SSTICommandIssueData_SSTICommandIssueData = 0x00552550; + +//extern functions: +//MSVCR80.dll +const int _memmove_s = 0x00A824E7; diff --git a/sections/include/global_func_table.h b/sections/include/global_func_table.h new file mode 100644 index 00000000..18b95e79 --- /dev/null +++ b/sections/include/global_func_table.h @@ -0,0 +1,50 @@ +// emit reversed functions for later use. +#include "typeDefs.h" +#include "moho.h" + +class GFT +{ +public: + int IssueMove(); + + //nantest.cpp---------------------------------------------------- + bool nanTest(float *a1); + //--------------------------------------------------------------- + + //setCoordsArray.cpp--------------------------------------------- + _DWORD* LuaPlus_LuaObject_LuaObject(_DWORD *_this); + _DWORD* Moho_SSTICommandIssueData_SSTICommandIssueData(_DWORD* _this, int a2); + int sub_5796A0(_DWORD *a1); + //--------------------------------------------------------------- + + //Validate_IssueCommand.cpp-------------------------------------- + int sub_57DDD0(int a1, int a2, int Src, int a4); + _DWORD* sub_57FE30(int a1, void *a2, void *Src, int a4); + __attribute__((fastcall)) int sub_5811A0(_DWORD *a1, int a2, int a3, _DWORD *a4, _DWORD *a5); + _DWORD* cmp_pointers(_DWORD *result, _DWORD *a2, _DWORD *a3); + int sub_582EB0(int *a1, int a2, int a3); + bool Validate_IssueCommand(int a1, int a2, int a3); + //--------------------------------------------------------------- + + //Get_Lua_Coordinates_State.cpp---------------------------------- + int Get_Lua_Coordinates_State(int a1, struct LuaState *a2, int a3, struct lua_State **a4, int a5); + + //Push_Coordinates.cpp---------------------------------- + int Push_Coordinates(int result, int a2); + + + + + + + + + + //----- (00924050) -------------------------------------------------------- + int lua_getglobaluserdata(int a1) + { + return *(_DWORD *)(*(_DWORD *)(a1 + 16) + 328); + } + //int lua_gettop(int &a1); + +}; diff --git a/sections/include/moho.h b/sections/include/moho.h new file mode 100644 index 00000000..d5dfbefe --- /dev/null +++ b/sections/include/moho.h @@ -0,0 +1,596 @@ +/** + MohoEngine.dll Disassembling notes +*/ + +// Nothing here is concrete. +#pragma once +typedef unsigned int uint; + +struct string +{ + // 0x1c bytes + void* ptr1; + void* m_data; // SSO space start + void* ptr3; + void* ptr4; + void* ptr5; + void* ptr6; + // at 0x18 + int size; // size < 0x10 => SSO + +#ifdef CXX_BUILD + const char* data() + { + if(size < 0x10) + return (const char*)&m_data; + else + return (const char*)m_data; + } +#endif +}; + +struct vector +{ + void* unknown1; + void** objects_begin; + void** objects_end; + void** objects_capacity_end; + +#ifdef CXX_BUILD + void* operator[](int index) + { + if(index >= size()) + return 0; + return objects_begin[index]; + } + + int size() + { + return objects_end - objects_begin; + } +#endif +}; + +struct list // probably not from visual c++, but made by gpg +// considering, it's not capacity based, probably made by gpg +{ + void* objects_start; // 0 if empty + void* objects_end; +}; + +typedef int SOCKET; +// GPGCore + +struct Stream +{ + +}; +struct PipeStream // : Stream +{ + // 0x48 bytes + char iDontSeeANeedToKnowTheStructure[0x48]; +}; + +struct gpg_mutex +{ + int vooodoo; +}; +// LuaPlus +struct lua_State +{ + int dummy; +}; +struct LuaState +{ + lua_State* _lua_State; + void* unknown1; + void* unknown2; + void* unknown3; + void* important1; + +}; +struct LuaStackObject +{ + // 0x8 bytes + LuaState* state; + int stack_index; +}; +struct LuaObject +{ + // 0x14 bytes + + void* unknown1; // objects_end? + void* unknown2; // objects_start? + LuaState* m_state; + int type; + void* unknown5; // n_objects?? + + /* Types: + -1 - None + 0 - Nil + 1 - Boolean + 2 - LightUserData // || UserData + 3 - Number // || Integer + 4 - String + 5 - Table + 6 - CFunction + 7 - Function + 8 - UserData + */ +}; + +// Moho +struct Moho__SSTICommandIssueData +{ + int unknown; +}; + +struct Moho__CUnitCommand +{ + int unknown; +}; + +struct linked_list +{ + void* not_sure; +}; +struct moho_set +{ + int set_base; // integer_base >> 5 (bits in dword) + int unknown2; + uint* items_begin; + uint* items_end; + uint* items_capacity_end; + void* unknown6; + void* unknown7; // Used as memory for Short Set 'Optimization' + void* unknown8; + +#ifdef CXX_BUILD + void add(int item) + { + items_begin[item>>5] |= 1 << (item & 0x1f); + } + + void remove(int item) + { + items_begin[item>>5] &= ~( 1 << (item & 0x1f) ); + } + + bool operator[](int item) + { + return items_begin[item>>5] & (1 << (item & 0x1f)); + } +#endif +}; + +struct Unknown1 // from WLD_SetupSessionInfo +{ + // 0xA4 bytes + void* vtable; + + void* self1; + void* self2; + + // at 0xC + string lua_gameMods; + // at 0x28 + string str2; + + // at 0x60 + int unknown1; + int unknown2; + int unknown3; // = -1 + // at 0x6C + string str3; + // at 0x88 + bool boolean1; + char _pad1[3]; + int unknown4; +}; + +struct IClientManager +{ + void* vtable; +}; + +struct RRuleGameRules +{ + int dummy; +}; +struct CWldMap +{ + void* zero1; + void* zero2; + void* zero3; +}; + +struct SWldSessionInfo +{ + // 0x30 bytes + string map_name; + + // at 0x1C + int unknown1; + + // at 0x20 + int unknown2; + bool b1; // = true + bool b2; + bool b3; + char _pad1; + + IClientManager* clientManager; + int unknown4; // = 255 possibly cmdSourceIndex +}; +struct UserArmy +{ + void* unknown1; // vtable? + + string name; + + // at 0x20 + string nickname; + +#ifndef FORGED_ALLIANCE + char datas[0xf4]; +#else + char datas[0xec]; +#endif + // at 0x130 Moho | at 0x128 FA + moho_set mValidCommandSources; + // at 0x148 FA + uint color; + // at 0x16C FA + int faction; +}; +struct SimArmy +{ +#ifdef FORGED_ALLIANCE + // Forged Alliance Code + void* vtable; + int unknown3; + int unknown4; + + string name; + string nickname; + + char datas[0xec]; + // at 0x138 Moho | at 0x130 FA + moho_set mValidCommandSources; + + // at 0x158 FA + string mArmyType; //? 'human' for players + + // at 0x1C4 FA + struct + { + float funknown1; + float funknown2; + } float_struct; + + // at 0x1F0 FA + int unknown1; + int unknown2; + // at 0x1F8 FA + string unknown5; +#else + // Moho Code + + // at 0x138 Moho | at 0x130 FA + moho_set mValidCommandSources; +#endif +}; + +struct Sim +{ + // 0xAF8 bytes + +#ifdef FORGED_ALLIANCE + char datas[0x90C]; + // at 0x91C Moho | at 0x90C FA + vector armies;// + // at 0x93C Moho | at 0x92C FA + int ourCmdSource; // possibly just current in simulation. + // at 0x984 FA + void* thing; +#else +#endif +}; +struct CWldSession +{ + // 0x508 bytes + // Information about values is from constructor. + + CWldSession* self1; // = this + CWldSession* self2; // = this + + void* self_weird1; // = this + 0x8 + void* self_weird2; // = this + 0x8 + + // at 0x10 + LuaState* state; // sim? set from constructor argument + void* zero1; + + RRuleGameRules* rules; + CWldMap* map; + + // at 0x20 + void* zero2; + void* zero3; + string map_name; + + char stuff[0x3ac]; + + // at 0x3f0 + list /*?*/ armies; // + + // at 0x470 + vector cmdSources; // + + // at 0x480 + int ourCmdSource; + + bool isReplay; + bool isBeingRecorded; + bool isMultiplayer; + + // at 0x487 + bool bool1; // set as true in Constructor. + + int focusArmyIndex; // focused army, -1 = observer + + bool isGameOver; + + // at 0x4d4 + bool cheatsEnabled; +}; + +struct STIDriver // : ISTIDriver +{ + // 0x230 bytes +}; + +struct STIMap +{ + // 0x1548 bytes +}; + +struct SSTICommandSource +{ + // 0x24 bytes + + int index; + string name; + int protocol; +}; + +struct CPushTask +{ + char datas[0x24]; +}; + +typedef CPushTask CPullTask; + +struct INetConnector +{ + void* vtable; +}; +struct CLobby +{ + // 0xC8 bytes + + // at 0x20 + LuaObject unknown0; + + int unknown1; + int unknown2; + int unknown3; + int unknown4; + // at 0x44 + CPushTask pushTask; + + // at 0x60 + CPullTask pullTask; + + // at 0x84 + bool hosted_or_joined; // Has CLobby been used to host/join yet? + + // at 0x88 + void* not_host; // 0 if we're host + + // at 0x90 + string our_name; + // at 0xAC + int our_UID; + + // at 0xB0 + struct + { + INetConnector* first_element; + INetConnector* last_element; // It will probably always be our CNetXXXConnector + } peer_list; // Probably singly-linked list +}; + +/// Tres Importante +struct sub_10392B10_ret +{ + // 0x20 bytes + + void* zero1; // self in CLobbyPeer.unknown2 + void* zero2; // self in CLobbyPeer.unknown2 + void* zero3; // self in CLobbyPeer.unknown2 + int unknown1; + + // at 0x10 + char one1; + char zero4; // 1 in CLobbyPeer.unknown2 +}; +struct CLobbyPeer +{ + // 0x50 bytes + CLobbyPeer* next; // Doubly linked list pointers + CLobbyPeer* prev; + + string playerName; + + // at 0x24 + int ownerID; // User UID + int constant1; + short constant2; + char _pad1[2]; + + // at 0x30 + int constant3; // enum? + float constant4; // = 0 + int constant5; + int unknown1; + + // at 0x40 + sub_10392B10_ret* unknown2; // made in sub_10394180 + int zero1; + int cmdSourceIndex; // == 255 => Unassigned + int playerNo; + + /* + constant1, constant2, constant3, constant5 + specially define the CLobbyUser + + constant3: + 1 - Host for a lobby we joined? + 3 - Peer who connected to us? + 6 - Game Peer of a Launched Game? + */ +}; + +struct CClientManagerImpl // : IClientManager +{ + // 0x184D0 bytes + void* vtable; + + // at 0x40C + gpg_mutex mLock; + + // at 0x420 + list mClients; // + INetConnector* mConnector; + + // at 0x434 + bool mWeAreReady; + bool mEveryoneIsReady; + char _pad1[2]; + + int mDispatchedBeat; + int mAvailableBeat; + int mFullyQueuedBeat; + int mPartiallyQueuedBeat; + int mGameSpeedClock; + int mGameSpeedRequester; // misspelling? :D + int mGameSpeed; +}; + +struct CClientBase // : IClient +{ + // 0xD8 bytes + void* vtable; + string mNickname; + // at 0x20 + int mIndex; // client index + int mUID; + IClientManager* clientManager; + + // at 0x30 + /** + +-------------------------------------------------------+ + |                                                       | + |    GOOD NEWS EVERYONE, IT'S A MOHO::SET***            | + |                                                       | + |    ( It's still a really weird structure              | + |      due to the magical optimizations             | + |      possible for AABB Sets via bit manipulation. )   | + |                                                       | + |    *** Probably | + +-------------------------------------------------------+ + + Actually, a shitty bitvector + */ + struct Unknown + { + int set_base; // integer_base >> 5 (bits in dword) + int unknown2; + void* memory; + void* memory_end; + void* unknown5; + void* unknown6; + void* unknown7; + void* unknown8; + } thisIsTheWeirdestStructureIHaveSeen; + + //vector mValidCommandSources; // ? + + //int unknwon3; + //int unknown4; + //int unknwon5; + //int unknown6; + + // at 0x50 + int mCommandSource; + bool mReady; + char _pad1[3]; + + PipeStream mPipe; + + // at 0xA0 + int mQueuedBeat; + int mDispatchedBeat; + int mAvailableBeatRemote; + vector mLatestAckReceived; + int mLatestBeatDispatchedRemote; + // at 0xC0 + bool mEjectPending; + bool mEjected; + char _pad2[2]; + list mEjectRequests; // + + void* unknown; + // at 0xD0 + void* uknown; +}; + +struct CNetUDPConnetor // : INetConnector +{ + INetConnector _base; + void* smth; // listen socket fd? + gpg_mutex mMutex; + // at 0x14 + SOCKET mSocket; + // at 0x24 + linked_list mConnections;// CNetUDPConnection* +}; + +struct ISTIDriver +{ + void* vtable; +}; +struct CSTIDriver // : ISTIDriver +{ + ISTIDriver _base; + void* notcarenow; + IClientManager* clientManager; +}; +/** Game Types + Multiplayer - CLobby::LaunchGame + Replay - VCR_SetupReplaySession + SinglePlayer - WLD_SetupSessionInfo + Saved Game - CSavedGame::CreateSinglePlayerSession +*/ + +/** Session State + 0 - None? + 1 - Loading? + 2 - Started? + 3 - SIM Initialized + 4 - SIM Started + 5 - Game Started + 7 - Restart Requested + 8 - Session Halted +*/ diff --git a/sections/include/typeDefs.h b/sections/include/typeDefs.h new file mode 100644 index 00000000..13524c0c --- /dev/null +++ b/sections/include/typeDefs.h @@ -0,0 +1,316 @@ +#pragma once +/* + This file contains definitions used by the Hex-Rays decompiler output. + It has type definitions and convenience macros to make the + output more readable. + Copyright (c) 2007 Hex-Rays +*/ + +#if defined(__GNUC__) +typedef long long ll; +typedef unsigned long long ull; +#define __int64 long long +#define __int32 int +#define __int16 short +#define __int8 char +#define MAKELL(num) num ## LL +#define FMT_64 "ll" +#elif defined(_MSC_VER) +typedef __int64 ll; +typedef unsigned __int64 ull; +#define MAKELL(num) num ## i64 +#define FMT_64 "I64" +#elif defined (__BORLANDC__) +typedef __int64 ll; +typedef unsigned __int64 ull; +#define MAKELL(num) num ## i64 +#define FMT_64 "L" +#else +#error "unknown compiler" +#endif +typedef unsigned int uint; +typedef unsigned char uchar; +typedef unsigned short ushort; +//typedef unsigned long ulong; + +typedef char int8; +typedef signed char sint8; +typedef unsigned char uint8; +typedef short int16; +typedef signed short sint16; +typedef unsigned short uint16; +typedef int int32; +typedef signed int sint32; +typedef unsigned int uint32; +typedef ll int64; +typedef ll sint64; +typedef ull uint64; + +// Partially defined types: +#define _BYTE uint8 +#define _WORD uint16 +#define _DWORD uint32 +#define _QWORD uint64 +#if !defined(_MSC_VER) +#define _LONGLONG __int128 +#endif + +#ifndef _WINDOWS_ +typedef int8 BYTE; +typedef int16 WORD; +typedef int32 DWORD; +typedef int32 LONG; +#endif +typedef int64 QWORD; +#ifndef __cplusplus +typedef int bool; // we want to use bool in our C programs +#endif + +// Some convenience macros to make partial accesses nicer +// first unsigned macros: +#define LOBYTE(x) (*((_BYTE*)&(x))) // low byte +#define LOWORD(x) (*((_WORD*)&(x))) // low word +#define LODWORD(x) (*((_DWORD*)&(x))) // low dword +#define HIBYTE(x) (*((_BYTE*)&(x)+1)) +#define HIWORD(x) (*((_WORD*)&(x)+1)) +#define HIDWORD(x) (*((_DWORD*)&(x)+1)) +#define BYTEn(x, n) (*((_BYTE*)&(x)+n)) +#define WORDn(x, n) (*((_WORD*)&(x)+n)) +#define BYTE1(x) BYTEn(x, 1) // byte 1 (counting from 0) +#define BYTE2(x) BYTEn(x, 2) +#define BYTE3(x) BYTEn(x, 3) +#define BYTE4(x) BYTEn(x, 4) +#define BYTE5(x) BYTEn(x, 5) +#define BYTE6(x) BYTEn(x, 6) +#define BYTE7(x) BYTEn(x, 7) +#define BYTE8(x) BYTEn(x, 8) +#define BYTE9(x) BYTEn(x, 9) +#define BYTE10(x) BYTEn(x, 10) +#define BYTE11(x) BYTEn(x, 11) +#define BYTE12(x) BYTEn(x, 12) +#define BYTE13(x) BYTEn(x, 13) +#define BYTE14(x) BYTEn(x, 14) +#define BYTE15(x) BYTEn(x, 15) +#define WORD1(x) WORDn(x, 1) +#define WORD2(x) WORDn(x, 2) // third word of the object, unsigned +#define WORD3(x) WORDn(x, 3) +#define WORD4(x) WORDn(x, 4) +#define WORD5(x) WORDn(x, 5) +#define WORD6(x) WORDn(x, 6) +#define WORD7(x) WORDn(x, 7) + +// now signed macros (the same but with sign extension) +#define SLOBYTE(x) (*((int8*)&(x))) +#define SLOWORD(x) (*((int16*)&(x))) +#define SLODWORD(x) (*((int32*)&(x))) +#define SHIBYTE(x) (*((int8*)&(x)+1)) +#define SHIWORD(x) (*((int16*)&(x)+1)) +#define SHIDWORD(x) (*((int32*)&(x)+1)) +#define SBYTEn(x, n) (*((int8*)&(x)+n)) +#define SWORDn(x, n) (*((int16*)&(x)+n)) +#define SBYTE1(x) SBYTEn(x, 1) +#define SBYTE2(x) SBYTEn(x, 2) +#define SBYTE3(x) SBYTEn(x, 3) +#define SBYTE4(x) SBYTEn(x, 4) +#define SBYTE5(x) SBYTEn(x, 5) +#define SBYTE6(x) SBYTEn(x, 6) +#define SBYTE7(x) SBYTEn(x, 7) +#define SBYTE8(x) SBYTEn(x, 8) +#define SBYTE9(x) SBYTEn(x, 9) +#define SBYTE10(x) SBYTEn(x, 10) +#define SBYTE11(x) SBYTEn(x, 11) +#define SBYTE12(x) SBYTEn(x, 12) +#define SBYTE13(x) SBYTEn(x, 13) +#define SBYTE14(x) SBYTEn(x, 14) +#define SBYTE15(x) SBYTEn(x, 15) +#define SWORD1(x) SWORDn(x, 1) +#define SWORD2(x) SWORDn(x, 2) +#define SWORD3(x) SWORDn(x, 3) +#define SWORD4(x) SWORDn(x, 4) +#define SWORD5(x) SWORDn(x, 5) +#define SWORD6(x) SWORDn(x, 6) +#define SWORD7(x) SWORDn(x, 7) + + +// Helper functions to represent some assembly instructions. + +#ifdef __cplusplus + +// Fill memory block with an integer value +inline void memset32(void *ptr, uint32 value, int count) +{ + uint32 *p = (uint32 *)ptr; + for ( int i=0; i < count; i++ ) + *p++ = value; +} + +// Generate a reference to pair of operands +template int16 __PAIR__( int8 high, T low) +{ + return ((( int16)high) << sizeof(high)*8) | uint8(low); +} +template int32 __PAIR__( int16 high, T low) +{ + return ((( int32)high) << sizeof(high)*8) | uint16(low); +} +template int64 __PAIR__( int32 high, T low) +{ + return ((( int64)high) << sizeof(high)*8) | uint32(low); +} +template uint16 __PAIR__(uint8 high, T low) +{ + return (((uint16)high) << sizeof(high)*8) | uint8(low); +} +template uint32 __PAIR__(uint16 high, T low) +{ + return (((uint32)high) << sizeof(high)*8) | uint16(low); +} +template uint64 __PAIR__(uint32 high, T low) +{ + return (((uint64)high) << sizeof(high)*8) | uint32(low); +} + +// rotate left +template T __ROL__(T value, uint count) +{ + const uint nbits = sizeof(T) * 8; + count %= nbits; + + T high = value >> (nbits - count); + value <<= count; + value |= high; + return value; +} + +// rotate right +template T __ROR__(T value, uint count) +{ + const uint nbits = sizeof(T) * 8; + count %= nbits; + + T low = value << (nbits - count); + value >>= count; + value |= low; + return value; +} + +// carry flag of left shift +template int8 __MKCSHL__(T value, uint count) +{ + const uint nbits = sizeof(T) * 8; + count %= nbits; + + return (value >> (nbits-count)) & 1; +} + +// carry flag of right shift +template int8 __MKCSHR__(T value, uint count) +{ + return (value >> (count-1)) & 1; +} + +// sign flag +template int8 __SETS__(T x) +{ + if ( sizeof(T) == 1 ) + return int8(x) < 0; + if ( sizeof(T) == 2 ) + return int16(x) < 0; + if ( sizeof(T) == 4 ) + return int32(x) < 0; + return int64(x) < 0; +} + +// overflow flag of subtraction (x-y) +template int8 __OFSUB__(T x, U y) +{ + if ( sizeof(T) < sizeof(U) ) + { + U x2 = x; + int8 sx = __SETS__(x2); + return (sx ^ __SETS__(y)) & (sx ^ __SETS__(x2-y)); + } + else + { + T y2 = y; + int8 sx = __SETS__(x); + return (sx ^ __SETS__(y2)) & (sx ^ __SETS__(x-y2)); + } +} + +// overflow flag of addition (x+y) +template int8 __OFADD__(T x, U y) +{ + if ( sizeof(T) < sizeof(U) ) + { + U x2 = x; + int8 sx = __SETS__(x2); + return ((1 ^ sx) ^ __SETS__(y)) & (sx ^ __SETS__(x2+y)); + } + else + { + T y2 = y; + int8 sx = __SETS__(x); + return ((1 ^ sx) ^ __SETS__(y2)) & (sx ^ __SETS__(x+y2)); + } +} + +// carry flag of subtraction (x-y) +template int8 __CFSUB__(T x, U y) +{ + int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U); + if ( size == 1 ) + return uint8(x) < uint8(y); + if ( size == 2 ) + return uint16(x) < uint16(y); + if ( size == 4 ) + return uint32(x) < uint32(y); + return uint64(x) < uint64(y); +} + +// carry flag of addition (x+y) +template int8 __CFADD__(T x, U y) +{ + int size = sizeof(T) > sizeof(U) ? sizeof(T) : sizeof(U); + if ( size == 1 ) + return uint8(x) > uint8(x+y); + if ( size == 2 ) + return uint16(x) > uint16(x+y); + if ( size == 4 ) + return uint32(x) > uint32(x+y); + return uint64(x) > uint64(x+y); +} + +#else +// The following definition is not quite correct because it always returns +// uint64. The above C++ functions are good, though. +#define __PAIR__(high, low) (((uint64)(high)<>y) +#define __CFADD__(x, y) invalid_operation // Generate carry flag for (x+y) +#define __CFSUB__(x, y) invalid_operation // Generate carry flag for (x-y) +#define __OFADD__(x, y) invalid_operation // Generate overflow flag for (x+y) +#define __OFSUB__(x, y) invalid_operation // Generate overflow flag for (x-y) +#endif + +// No definition for rcl/rcr because the carry flag is unknown +#define __RCL__(x, y) invalid_operation // Rotate left thru carry +#define __RCR__(x, y) invalid_operation // Rotate right thru carry +#define __MKCRCL__(x, y) invalid_operation // Generate carry flag for a RCL +#define __MKCRCR__(x, y) invalid_operation // Generate carry flag for a RCR +#define __SETP__(x, y) invalid_operation // Generate parity flag for (x-y) + +// In the decompilation listing there are some objects declarared as _UNKNOWN +// because we could not determine their types. Since the C compiler does not +// accept void item declarations, we replace them by anything of our choice, +// for example a char: + +#define _UNKNOWN char + +#ifdef _MSC_VER +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#endif diff --git a/sections/nanTest.cpp b/sections/nanTest.cpp new file mode 100644 index 00000000..5cdb1748 --- /dev/null +++ b/sections/nanTest.cpp @@ -0,0 +1,7 @@ +#include "include/global_func_table.h" +#include + +bool GFT::nanTest(float *a1) +{ + return !isnan(*a1) && !isnan(a1[1]) && !isnan(a1[2]); +} diff --git a/sections/setCoordsArray.cpp b/sections/setCoordsArray.cpp new file mode 100644 index 00000000..da0fb7f7 --- /dev/null +++ b/sections/setCoordsArray.cpp @@ -0,0 +1,101 @@ +#include "include/global_func_table.h" +#include "include/funcDefs.h" + +//----- (009072A0) -------------------------------------------------------- +_DWORD* GFT::LuaPlus_LuaObject_LuaObject(_DWORD *_this) +{ + _DWORD *result; // eax + + result = _this; + *_this = 0; + _this[1] = 0; + _this[2] = 0; + _this[3] = 0; + return result; +} + +/* //----- (0057ABB0) -------------------------------------------------------- +int __stdcall sub_57ABB0(int a1) +{ + int result; // eax + int *v2; // eax + int v3; // ecx + + sub_9075D0((_DWORD **)(a1 + 120)); + result = *(_DWORD *)(a1 + 88); + if ( result == *(_DWORD *)(a1 + 100) ) + { + *(_DWORD *)(a1 + 92) = result; + } + else + { + sub_A82542(*(_DWORD *)(a1 + 88)); + v2 = *(int **)(a1 + 100); + *(_DWORD *)(a1 + 88) = v2; + result = *v2; + v3 = *(_DWORD *)(a1 + 88); + *(_DWORD *)(a1 + 96) = result; + *(_DWORD *)(a1 + 92) = v3; + } + return result; +} */ + +//----- (005796A0) -------------------------------------------------------- +int GFT::sub_5796A0(_DWORD *a1) +{ + _DWORD *v1; // eax + int result; // eax + + if ( a1[2] != a1[5] ) + { + funcDefs Fd; + Fd.j_shi_delete_0(a1[2]); + v1 = (_DWORD *)a1[5]; + a1[2] = v1; + a1[4] = *v1; + } + a1[3] = a1[2]; + result = a1[1]; + *(_DWORD *)(*a1 + 4) = result; + *(_DWORD *)a1[1] = *a1; + a1[1] = a1; + *a1 = a1; + return result; +} + +//----- (00552550) -------------------------------------------------------- +_DWORD* GFT::Moho_SSTICommandIssueData_SSTICommandIssueData(_DWORD *_this, int a2) +{ + _DWORD *v2; // esi + + v2 = _this; + *_this = -1; + _this[1] = -1; + _this[2] = -1; + _this[3] = a2; + _this[4] = 0; + _this[5] = -268435456; + _this[6] = 0; + _this[7] = 0; + _this[8] = 0; + _this[9] = 0; + _this[10] = -268435456; + _this[11] = 0; + _this[12] = 0; + _this[13] = 0; + _this[14] = -1; + _this[15] = 1065353216; + _this[16] = 0; + _this[17] = 0; + _this[18] = 0; + _this[19] = 1065353216; + _this[20] = 0; + v2[22] = (int)v2 + 26; + v2[23] = (int)v2 + 26; + v2[24] = (int)v2 + 28; + v2[25] = (int)v2 + 26; + _this[28] = 1; + _this[29] = 1; + LuaPlus_LuaObject_LuaObject(_this + 30); + return v2; +}