mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-03 04:28:12 +00:00
git normalize all files
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
bias = (bias^x)&7;
|
||||
x -= bias;
|
||||
x *= 2;
|
||||
x *= x;
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
bias = (bias^x)&7;
|
||||
x -= bias;
|
||||
x *= 2;
|
||||
x *= x;
|
||||
x += bias;
|
||||
+106
-106
@@ -1,106 +1,106 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
/*
|
||||
* Program to run in debugger organized to provide tests for
|
||||
* single threaded stepping, breakpoints, evaluation.
|
||||
*/
|
||||
|
||||
////////////////////////////////
|
||||
// NOTE(allen): Complex Types
|
||||
|
||||
#include <complex.h>
|
||||
|
||||
void
|
||||
c_type_coverage_eval_tests(void){
|
||||
#if _WIN32
|
||||
_Fcomplex x = _FCbuild(0.f, 1.f);
|
||||
_Dcomplex y = _Cbuild(0.f, -1.f);
|
||||
|
||||
#else
|
||||
float complex x = 0.f + 1.f*I;
|
||||
double complex y = 0.0 - 1.0*I;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// NOTE(allen): Reuse Type Names From Another Module
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct Basics{
|
||||
double a;
|
||||
float b;
|
||||
unsigned long long c;
|
||||
long long d;
|
||||
unsigned int e;
|
||||
int f;
|
||||
unsigned short g;
|
||||
short h;
|
||||
unsigned char i;
|
||||
char j;
|
||||
|
||||
int z;
|
||||
} Basics;
|
||||
|
||||
typedef struct Basics_Stdint{
|
||||
double x1;
|
||||
float x2;
|
||||
uint64_t x3;
|
||||
int64_t x4;
|
||||
uint32_t x5;
|
||||
int32_t x6;
|
||||
uint16_t x7;
|
||||
int16_t x8;
|
||||
uint8_t x9;
|
||||
int8_t x0;
|
||||
} Basics_Stdint;
|
||||
|
||||
typedef struct Pair{
|
||||
int i;
|
||||
float f;
|
||||
} Pair;
|
||||
|
||||
void
|
||||
c_versions_of_same_types(void){
|
||||
Basics basics = { 1.5f, 1.50000000000001, -1, 1, -2, 2, -4, 4, -8, 8, };
|
||||
Basics_Stdint basics_stdint = { 1.5f, 1.50000000000001, -1, 1, -2, 2, -4, 4, -8, 8, };
|
||||
Pair memory_[] = {
|
||||
{100, 1.f},
|
||||
{101, 2.f},
|
||||
{102, 4.f},
|
||||
{103, 8.f},
|
||||
{104, 16.f},
|
||||
{105, 32.f},
|
||||
};
|
||||
|
||||
int x = memory_[3].i + basics.f;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(rjf): Bitfields
|
||||
|
||||
typedef struct TypeWithBitfield TypeWithBitfield;
|
||||
struct TypeWithBitfield
|
||||
{
|
||||
int v : 14;
|
||||
int w : 4;
|
||||
int x : 32;
|
||||
int y : 4;
|
||||
int z : 10;
|
||||
};
|
||||
|
||||
void
|
||||
c_type_with_bitfield_usage(void)
|
||||
{
|
||||
TypeWithBitfield b = {0};
|
||||
b.v = 100;
|
||||
b.w = 6;
|
||||
b.x = 434512;
|
||||
b.y = 7;
|
||||
b.z = 12;
|
||||
int x = (b.v + b.x);
|
||||
int y = (b.y - b.z);
|
||||
int z = (b.w) + 5;
|
||||
}
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
/*
|
||||
* Program to run in debugger organized to provide tests for
|
||||
* single threaded stepping, breakpoints, evaluation.
|
||||
*/
|
||||
|
||||
////////////////////////////////
|
||||
// NOTE(allen): Complex Types
|
||||
|
||||
#include <complex.h>
|
||||
|
||||
void
|
||||
c_type_coverage_eval_tests(void){
|
||||
#if _WIN32
|
||||
_Fcomplex x = _FCbuild(0.f, 1.f);
|
||||
_Dcomplex y = _Cbuild(0.f, -1.f);
|
||||
|
||||
#else
|
||||
float complex x = 0.f + 1.f*I;
|
||||
double complex y = 0.0 - 1.0*I;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// NOTE(allen): Reuse Type Names From Another Module
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct Basics{
|
||||
double a;
|
||||
float b;
|
||||
unsigned long long c;
|
||||
long long d;
|
||||
unsigned int e;
|
||||
int f;
|
||||
unsigned short g;
|
||||
short h;
|
||||
unsigned char i;
|
||||
char j;
|
||||
|
||||
int z;
|
||||
} Basics;
|
||||
|
||||
typedef struct Basics_Stdint{
|
||||
double x1;
|
||||
float x2;
|
||||
uint64_t x3;
|
||||
int64_t x4;
|
||||
uint32_t x5;
|
||||
int32_t x6;
|
||||
uint16_t x7;
|
||||
int16_t x8;
|
||||
uint8_t x9;
|
||||
int8_t x0;
|
||||
} Basics_Stdint;
|
||||
|
||||
typedef struct Pair{
|
||||
int i;
|
||||
float f;
|
||||
} Pair;
|
||||
|
||||
void
|
||||
c_versions_of_same_types(void){
|
||||
Basics basics = { 1.5f, 1.50000000000001, -1, 1, -2, 2, -4, 4, -8, 8, };
|
||||
Basics_Stdint basics_stdint = { 1.5f, 1.50000000000001, -1, 1, -2, 2, -4, 4, -8, 8, };
|
||||
Pair memory_[] = {
|
||||
{100, 1.f},
|
||||
{101, 2.f},
|
||||
{102, 4.f},
|
||||
{103, 8.f},
|
||||
{104, 16.f},
|
||||
{105, 32.f},
|
||||
};
|
||||
|
||||
int x = memory_[3].i + basics.f;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(rjf): Bitfields
|
||||
|
||||
typedef struct TypeWithBitfield TypeWithBitfield;
|
||||
struct TypeWithBitfield
|
||||
{
|
||||
int v : 14;
|
||||
int w : 4;
|
||||
int x : 32;
|
||||
int y : 4;
|
||||
int z : 10;
|
||||
};
|
||||
|
||||
void
|
||||
c_type_with_bitfield_usage(void)
|
||||
{
|
||||
TypeWithBitfield b = {0};
|
||||
b.v = 100;
|
||||
b.w = 6;
|
||||
b.x = 434512;
|
||||
b.y = 7;
|
||||
b.z = 12;
|
||||
int x = (b.v + b.x);
|
||||
int y = (b.y - b.z);
|
||||
int z = (b.w) + 5;
|
||||
}
|
||||
|
||||
+9
-9
@@ -1,10 +1,10 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
/*
|
||||
* Program to run in debugger organized to provide tests for
|
||||
* single threaded stepping, breakpoints, evaluation.
|
||||
*/
|
||||
|
||||
void c_type_coverage_eval_tests(void);
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
/*
|
||||
* Program to run in debugger organized to provide tests for
|
||||
* single threaded stepping, breakpoints, evaluation.
|
||||
*/
|
||||
|
||||
void c_type_coverage_eval_tests(void);
|
||||
void c_type_with_bitfield_usage(void);
|
||||
@@ -1,48 +1,48 @@
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int lib_loaded = 0;
|
||||
HANDLE lib = {0};
|
||||
FILETIME lib_last_filetime = {0};
|
||||
int (*get_number)(void) = 0;
|
||||
for(;;)
|
||||
{
|
||||
//- rjf: hot-load dll
|
||||
{
|
||||
HANDLE file = CreateFileA("mule_hotload_module.dll", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
FILETIME modified = {0};
|
||||
if(GetFileTime(file, 0, 0, &modified) &&
|
||||
CompareFileTime(&lib_last_filetime, &modified) == -1)
|
||||
{
|
||||
for(int reloaded = 0; !reloaded;)
|
||||
{
|
||||
if(lib_loaded)
|
||||
{
|
||||
FreeLibrary(lib);
|
||||
lib_loaded = 0;
|
||||
}
|
||||
BOOL copy_worked = CopyFile("mule_hotload_module.dll", "mule_hotload_module_temp.dll", 0);
|
||||
lib = LoadLibraryA("mule_hotload_module_temp.dll");
|
||||
if(lib != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
reloaded = 1;
|
||||
lib_last_filetime = modified;
|
||||
get_number = (int(*)(void))GetProcAddress(lib, "get_number");
|
||||
lib_loaded = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(file);
|
||||
}
|
||||
int number = get_number();
|
||||
printf("got a number: %i\n", number);
|
||||
if(number == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Sleep(1000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int lib_loaded = 0;
|
||||
HANDLE lib = {0};
|
||||
FILETIME lib_last_filetime = {0};
|
||||
int (*get_number)(void) = 0;
|
||||
for(;;)
|
||||
{
|
||||
//- rjf: hot-load dll
|
||||
{
|
||||
HANDLE file = CreateFileA("mule_hotload_module.dll", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
FILETIME modified = {0};
|
||||
if(GetFileTime(file, 0, 0, &modified) &&
|
||||
CompareFileTime(&lib_last_filetime, &modified) == -1)
|
||||
{
|
||||
for(int reloaded = 0; !reloaded;)
|
||||
{
|
||||
if(lib_loaded)
|
||||
{
|
||||
FreeLibrary(lib);
|
||||
lib_loaded = 0;
|
||||
}
|
||||
BOOL copy_worked = CopyFile("mule_hotload_module.dll", "mule_hotload_module_temp.dll", 0);
|
||||
lib = LoadLibraryA("mule_hotload_module_temp.dll");
|
||||
if(lib != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
reloaded = 1;
|
||||
lib_last_filetime = modified;
|
||||
get_number = (int(*)(void))GetProcAddress(lib, "get_number");
|
||||
lib_loaded = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(file);
|
||||
}
|
||||
int number = get_number();
|
||||
printf("got a number: %i\n", number);
|
||||
if(number == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Sleep(1000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
__declspec(dllexport) int
|
||||
get_number(void)
|
||||
{
|
||||
int sum = 0;
|
||||
for(int i = 0; i < 100; i += 1)
|
||||
{
|
||||
sum += i;
|
||||
sum += i;
|
||||
sum += 1;
|
||||
}
|
||||
sum = 1000;
|
||||
return sum;
|
||||
}
|
||||
__declspec(dllexport) int
|
||||
get_number(void)
|
||||
{
|
||||
int sum = 0;
|
||||
for(int i = 0; i < 100; i += 1)
|
||||
{
|
||||
sum += i;
|
||||
sum += i;
|
||||
sum += 1;
|
||||
}
|
||||
sum = 1000;
|
||||
return sum;
|
||||
}
|
||||
|
||||
+42
-42
@@ -1,42 +1,42 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#if _WIN32
|
||||
#define export_function extern "C" __declspec(dllexport)
|
||||
#else
|
||||
#define export_function extern "C"
|
||||
#endif
|
||||
|
||||
#if _WIN32
|
||||
# define thread_var __declspec(thread)
|
||||
#else
|
||||
# define thread_var __thread
|
||||
#endif
|
||||
|
||||
typedef struct Basics Basics;
|
||||
struct Basics
|
||||
{
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
int d;
|
||||
};
|
||||
|
||||
thread_var float tls_a = 1.015625f;
|
||||
thread_var int tls_b = -100;
|
||||
|
||||
export_function void
|
||||
dll_tls_eval_test(void)
|
||||
{
|
||||
tls_a *= 1.5f;
|
||||
tls_b *= -2;
|
||||
}
|
||||
|
||||
export_function void
|
||||
dll_type_eval_tests(void)
|
||||
{
|
||||
Basics basics1 = {1, 2, 3, 4};
|
||||
Basics basics2 = {4, 5, 6, 7};
|
||||
int x = 0;
|
||||
(void)x;
|
||||
}
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#if _WIN32
|
||||
#define export_function extern "C" __declspec(dllexport)
|
||||
#else
|
||||
#define export_function extern "C"
|
||||
#endif
|
||||
|
||||
#if _WIN32
|
||||
# define thread_var __declspec(thread)
|
||||
#else
|
||||
# define thread_var __thread
|
||||
#endif
|
||||
|
||||
typedef struct Basics Basics;
|
||||
struct Basics
|
||||
{
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
int d;
|
||||
};
|
||||
|
||||
thread_var float tls_a = 1.015625f;
|
||||
thread_var int tls_b = -100;
|
||||
|
||||
export_function void
|
||||
dll_tls_eval_test(void)
|
||||
{
|
||||
tls_a *= 1.5f;
|
||||
tls_b *= -2;
|
||||
}
|
||||
|
||||
export_function void
|
||||
dll_type_eval_tests(void)
|
||||
{
|
||||
Basics basics1 = {1, 2, 3, 4};
|
||||
Basics basics2 = {4, 5, 6, 7};
|
||||
int x = 0;
|
||||
(void)x;
|
||||
}
|
||||
|
||||
+119
-119
@@ -1,119 +1,119 @@
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
static int important_s32 = 0;
|
||||
static float important_f32 = 0;
|
||||
|
||||
#if _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
static void
|
||||
do_something_with_intermediate_values(void)
|
||||
{
|
||||
static int another_important_s32 = 0;
|
||||
static float another_important_f32 = 0;
|
||||
|
||||
another_important_s32 = (int)important_f32;
|
||||
another_important_f32 = (float)important_s32;
|
||||
|
||||
#if _WIN32
|
||||
char buffer[256] = "Hello, World!\n";
|
||||
buffer[0] += important_s32 + another_important_s32;
|
||||
buffer[1] += (int)another_important_f32 * important_f32;
|
||||
OutputDebugStringA(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
store_important_s32(int *ptr)
|
||||
{
|
||||
important_s32 = *ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
store_important_f32(float *ptr)
|
||||
{
|
||||
important_f32 = *ptr;
|
||||
}
|
||||
|
||||
void
|
||||
optimized_build_eval_tests(void)
|
||||
{
|
||||
int simple_sum = 0;
|
||||
for(int i = 0; i < 10000; i += 1)
|
||||
{
|
||||
simple_sum += i;
|
||||
}
|
||||
store_important_s32(&simple_sum);
|
||||
|
||||
do_something_with_intermediate_values();
|
||||
|
||||
static struct {float x, y;} vec2s[] =
|
||||
{
|
||||
{ 10.f, 76.f },
|
||||
{ 40.f, 50.f },
|
||||
{ -230.f, 20.f },
|
||||
{ 27.f, 27.f },
|
||||
{ 57.f, -57.f },
|
||||
{ -37.f, 97.f },
|
||||
{ 99.f, 67.f },
|
||||
{ 99.f, 37.f },
|
||||
{ 99.f, 57.f },
|
||||
};
|
||||
{
|
||||
struct{float x, y;}sum = {0};
|
||||
int count = sizeof(vec2s)/sizeof(vec2s[0]);
|
||||
for(int i = 0; i < count; i += 1)
|
||||
{
|
||||
sum.x += vec2s[i].x;
|
||||
sum.y += vec2s[i].y;
|
||||
}
|
||||
struct{float x, y;}avg = {sum.x/count, sum.y/count};
|
||||
float f32 = avg.x * avg.y;
|
||||
store_important_f32(&f32);
|
||||
}
|
||||
|
||||
do_something_with_intermediate_values();
|
||||
|
||||
int factorial = 1;
|
||||
for(int i = 10; i > 0; i -= 1)
|
||||
{
|
||||
factorial *= i;
|
||||
}
|
||||
store_important_s32(&factorial);
|
||||
|
||||
do_something_with_intermediate_values();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// NOTE(allen): Struct Parameters Eval
|
||||
|
||||
struct OptimizedBasics{
|
||||
char a;
|
||||
unsigned char b;
|
||||
short c;
|
||||
unsigned short d;
|
||||
int e;
|
||||
unsigned int f;
|
||||
long long g;
|
||||
unsigned long long h;
|
||||
float i;
|
||||
double j;
|
||||
};
|
||||
|
||||
static void
|
||||
optimized_struct_parameter_helper(int *ptr, OptimizedBasics basics)
|
||||
{
|
||||
basics.a += *ptr;
|
||||
basics.a += 1;
|
||||
basics.a += 1;
|
||||
}
|
||||
|
||||
void
|
||||
optimized_struct_parameters_eval_tests(void)
|
||||
{
|
||||
int x = 10;
|
||||
OptimizedBasics basics = {-1, 1, -2, 2, -4, 4, -8, 8, 1.5f, 1.50000000000001};
|
||||
optimized_struct_parameter_helper(&x, basics);
|
||||
}
|
||||
// Copyright (c) 2024 Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
static int important_s32 = 0;
|
||||
static float important_f32 = 0;
|
||||
|
||||
#if _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
static void
|
||||
do_something_with_intermediate_values(void)
|
||||
{
|
||||
static int another_important_s32 = 0;
|
||||
static float another_important_f32 = 0;
|
||||
|
||||
another_important_s32 = (int)important_f32;
|
||||
another_important_f32 = (float)important_s32;
|
||||
|
||||
#if _WIN32
|
||||
char buffer[256] = "Hello, World!\n";
|
||||
buffer[0] += important_s32 + another_important_s32;
|
||||
buffer[1] += (int)another_important_f32 * important_f32;
|
||||
OutputDebugStringA(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
store_important_s32(int *ptr)
|
||||
{
|
||||
important_s32 = *ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
store_important_f32(float *ptr)
|
||||
{
|
||||
important_f32 = *ptr;
|
||||
}
|
||||
|
||||
void
|
||||
optimized_build_eval_tests(void)
|
||||
{
|
||||
int simple_sum = 0;
|
||||
for(int i = 0; i < 10000; i += 1)
|
||||
{
|
||||
simple_sum += i;
|
||||
}
|
||||
store_important_s32(&simple_sum);
|
||||
|
||||
do_something_with_intermediate_values();
|
||||
|
||||
static struct {float x, y;} vec2s[] =
|
||||
{
|
||||
{ 10.f, 76.f },
|
||||
{ 40.f, 50.f },
|
||||
{ -230.f, 20.f },
|
||||
{ 27.f, 27.f },
|
||||
{ 57.f, -57.f },
|
||||
{ -37.f, 97.f },
|
||||
{ 99.f, 67.f },
|
||||
{ 99.f, 37.f },
|
||||
{ 99.f, 57.f },
|
||||
};
|
||||
{
|
||||
struct{float x, y;}sum = {0};
|
||||
int count = sizeof(vec2s)/sizeof(vec2s[0]);
|
||||
for(int i = 0; i < count; i += 1)
|
||||
{
|
||||
sum.x += vec2s[i].x;
|
||||
sum.y += vec2s[i].y;
|
||||
}
|
||||
struct{float x, y;}avg = {sum.x/count, sum.y/count};
|
||||
float f32 = avg.x * avg.y;
|
||||
store_important_f32(&f32);
|
||||
}
|
||||
|
||||
do_something_with_intermediate_values();
|
||||
|
||||
int factorial = 1;
|
||||
for(int i = 10; i > 0; i -= 1)
|
||||
{
|
||||
factorial *= i;
|
||||
}
|
||||
store_important_s32(&factorial);
|
||||
|
||||
do_something_with_intermediate_values();
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// NOTE(allen): Struct Parameters Eval
|
||||
|
||||
struct OptimizedBasics{
|
||||
char a;
|
||||
unsigned char b;
|
||||
short c;
|
||||
unsigned short d;
|
||||
int e;
|
||||
unsigned int f;
|
||||
long long g;
|
||||
unsigned long long h;
|
||||
float i;
|
||||
double j;
|
||||
};
|
||||
|
||||
static void
|
||||
optimized_struct_parameter_helper(int *ptr, OptimizedBasics basics)
|
||||
{
|
||||
basics.a += *ptr;
|
||||
basics.a += 1;
|
||||
basics.a += 1;
|
||||
}
|
||||
|
||||
void
|
||||
optimized_struct_parameters_eval_tests(void)
|
||||
{
|
||||
int x = 10;
|
||||
OptimizedBasics basics = {-1, 1, -2, 2, -4, 4, -8, 8, 1.5f, 1.50000000000001};
|
||||
optimized_struct_parameter_helper(&x, basics);
|
||||
}
|
||||
|
||||
+61
-61
@@ -1,61 +1,61 @@
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include "mule_peb_trample_reload.c"
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argument_count, char **arguments)
|
||||
{
|
||||
char *exe_name = arguments[0];
|
||||
HANDLE last_module = GetModuleHandle(0);
|
||||
int (*loop_iteration_function)(int it) = (int (*)(int))GetProcAddress(last_module, "loop_iteration");
|
||||
FILETIME last_filetime = {0};
|
||||
int should_exit = 0;
|
||||
for(int it = 0; !should_exit; it += 1)
|
||||
{
|
||||
int result = loop_iteration_function(it);
|
||||
printf("%i\n", result);
|
||||
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]);
|
||||
loop_iteration_function = (int (*)(int))GetProcAddress(last_module, "loop_iteration");
|
||||
}
|
||||
last_filetime = current_filetime;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include "mule_peb_trample_reload.c"
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argument_count, char **arguments)
|
||||
{
|
||||
char *exe_name = arguments[0];
|
||||
HANDLE last_module = GetModuleHandle(0);
|
||||
int (*loop_iteration_function)(int it) = (int (*)(int))GetProcAddress(last_module, "loop_iteration");
|
||||
FILETIME last_filetime = {0};
|
||||
int should_exit = 0;
|
||||
for(int it = 0; !should_exit; it += 1)
|
||||
{
|
||||
int result = loop_iteration_function(it);
|
||||
printf("%i\n", result);
|
||||
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]);
|
||||
loop_iteration_function = (int (*)(int))GetProcAddress(last_module, "loop_iteration");
|
||||
}
|
||||
last_filetime = current_filetime;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
__declspec(dllexport) int
|
||||
loop_iteration(int it)
|
||||
{
|
||||
//return 111;
|
||||
#if 1
|
||||
int sum = 0;
|
||||
for(int i = 0; i < 1000; i += 1)
|
||||
{
|
||||
sum += it*i;
|
||||
}
|
||||
return sum;
|
||||
#endif
|
||||
}
|
||||
__declspec(dllexport) int
|
||||
loop_iteration(int it)
|
||||
{
|
||||
//return 111;
|
||||
#if 1
|
||||
int sum = 0;
|
||||
for(int i = 0; i < 1000; i += 1)
|
||||
{
|
||||
sum += it*i;
|
||||
}
|
||||
return sum;
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user