From b74db17375a37ba707fc98331e49ae6f6ecfde5f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 21 May 2024 11:29:19 -0700 Subject: [PATCH] peb trampling mule --- build.bat | 5 +++ project.4coder | 2 +- src/dbgi2/dbgi2.c | 7 ++-- src/mule/mule_peb_trample.c | 66 +++++++++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 src/mule/mule_peb_trample.c diff --git a/build.bat b/build.bat index defffb0b..509b4082 100644 --- a/build.bat +++ b/build.bat @@ -109,6 +109,11 @@ if "%look_at_raddbg%"=="1" %compile% ..\src\scratch\look if "%mule_main%"=="1" del vc*.pdb mule*.pdb && %compile_release% %only_compile% ..\src\mule\mule_inline.cpp && %compile_release% %only_compile% ..\src\mule\mule_o2.cpp && %compile_debug% %EHsc% ..\src\mule\mule_main.cpp ..\src\mule\mule_c.c mule_inline.obj mule_o2.obj %compile_link% %no_aslr% %out%mule_main.exe || exit /b 1 if "%mule_module%"=="1" %compile% ..\src\mule\mule_module.cpp %compile_link% %link_dll% %out%mule_module.dll || exit /b 1 if "%mule_hotload%"=="1" %compile% ..\src\mule\mule_hotload_main.c %compile_link% %out%mule_hotload.exe & %compile% ..\src\mule\mule_hotload_module_main.c %compile_link% %link_dll% %out%mule_hotload_module.dll || exit /b 1 +if "%mule_peb_trample%"=="1" ( + if exist mule_peb_trample_old.exe del mule_peb_trample_old.exe + if exist mule_peb_trample.exe move mule_peb_trample.exe mule_peb_trample_old.exe + %compile% ..\src\mule\mule_peb_trample.c %compile_link% %out%mule_peb_trample.exe || exit /b 1 +) popd :: --- Unset ------------------------------------------------------------------ diff --git a/project.4coder b/project.4coder index 0fb436c2..157ea4c7 100644 --- a/project.4coder +++ b/project.4coder @@ -56,7 +56,7 @@ commands = }, .rjf_f2 = { - .win = "build raddbgi_from_pdb telemetry release", + .win = "build mule_peb_trample", .linux = "", .out = "*compilation*", .footer_panel = true, diff --git a/src/dbgi2/dbgi2.c b/src/dbgi2/dbgi2.c index 31b5b841..13a5d65a 100644 --- a/src/dbgi2/dbgi2.c +++ b/src/dbgi2/dbgi2.c @@ -378,9 +378,10 @@ di_rdi_from_path_min_timestamp(DI_Scope *scope, String8 path, U64 min_timestamp, } //- rjf: parse not done, not working, asked a while ago -> ask for parse + B32 sent = 0; if(node != 0 && !node->parse_done && !node->is_working && ins_atomic_u64_eval(&node->last_time_requested_us)+1000000last_time_requested_us, os_now_microseconds()); @@ -394,7 +395,9 @@ di_rdi_from_path_min_timestamp(DI_Scope *scope, String8 path, U64 min_timestamp, } //- rjf: wait on this stripe - os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us); + { + os_condition_variable_wait_rw_r(stripe->cv, stripe->rw_mutex, endt_us); + } } scratch_end(scratch); } diff --git a/src/mule/mule_peb_trample.c b/src/mule/mule_peb_trample.c new file mode 100644 index 00000000..7a72eb3b --- /dev/null +++ b/src/mule/mule_peb_trample.c @@ -0,0 +1,66 @@ +#include +#include + +static void +HideModuleFromWindowsReload(HMODULE ModuleToFlush) +{ + /* NOTE(casey): Normally you cannot "reload" an executable module with the same name, + because Windows checks a linked list of loaded modules and assumes that if + it's already loaded, it doesn't need to reload it, even though it may have to because + it has changed on disk. + + This solution to that problem comes from some excellent spelunking by Martins Mozeiko, + who figured out that you could overwrite the filenames Windows stores in your process's + loaded module table, thus thwarting the Windows filename check against loaded modules, + allowing you to reload an existing module that has changed without requiring it to + have a different filename! + */ + + PEB *Peb = (PEB *)__readgsqword(offsetof(TEB, ProcessEnvironmentBlock)); + LIST_ENTRY *Head = &Peb->Ldr->InMemoryOrderModuleList; + for(LIST_ENTRY *Entry = Head->Flink; + Entry != Head; + Entry = Entry->Flink) + { + LDR_DATA_TABLE_ENTRY *Mod = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); + if(Mod->DllBase == ModuleToFlush) + { + ZeroMemory(Mod->FullDllName.Buffer, Mod->FullDllName.Length); + Mod->DllBase = 0; + break; + } + } +} + +__declspec(dllexport) void +loop_iteration(int it) +{ + printf("foobar iteration #%i\n", it); +} + +int main(int argument_count, char **arguments) +{ + char *exe_name = arguments[0]; + HANDLE last_module = GetModuleHandle(0); + void (*loop_iteration_function)(int it) = (void (*)(int))GetProcAddress(last_module, "loop_iteration"); + FILETIME last_filetime = {0}; + int should_exit = 0; + for(int it = 0; !should_exit; it += 1) + { + loop_iteration_function(it); + Sleep(50); + FILETIME current_filetime = {0}; + HANDLE current_exe_file = CreateFile(exe_name, 0, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + GetFileTime(current_exe_file, 0, 0, ¤t_filetime); + CloseHandle(current_exe_file); + if(it != 0 && CompareFileTime(&last_filetime, ¤t_filetime) < 0) + { + HideModuleFromWindowsReload(last_module); + //last_module = LoadLibrary(arguments[0]); + last_module = LoadLibrary("foobar.exe"); + loop_iteration_function = (void (*)(int))GetProcAddress(last_module, "loop_iteration"); + } + last_filetime = current_filetime; + } + return 0; +}