Change stack address on Windows

I rebooted Windows 7 and noticed that KERNEL32.DLL got relocated.
Microsoft needs to change and embrace the dream that was MULTICS.
Until then we'll need a better way to work around their dominion.
This commit is contained in:
Justine Tunney 2021-01-28 00:25:52 -08:00
parent b4dffa4726
commit d8fffd2123
2 changed files with 11 additions and 11 deletions

View file

@ -84,8 +84,7 @@ textwindows int ntspawn(
mkntenvblock(block->envvars, envp) != -1) { mkntenvblock(block->envvars, envp) != -1) {
if (CreateProcess(NULL, block->cmdline, opt_lpProcessAttributes, if (CreateProcess(NULL, block->cmdline, opt_lpProcessAttributes,
opt_lpThreadAttributes, bInheritHandles, opt_lpThreadAttributes, bInheritHandles,
dwCreationFlags | kNtCreateNewProcessGroup | dwCreationFlags | kNtCreateUnicodeEnvironment,
kNtCreateUnicodeEnvironment,
block->envvars, opt_lpCurrentDirectory, lpStartupInfo, block->envvars, opt_lpCurrentDirectory, lpStartupInfo,
opt_out_lpProcessInformation)) { opt_out_lpProcessInformation)) {
rc = 0; rc = 0;

View file

@ -46,9 +46,8 @@
/* /*
* TODO: Why can't we allocate addresses above 4GB on Windows 7 x64? * TODO: Why can't we allocate addresses above 4GB on Windows 7 x64?
* https://github.com/jart/cosmopolitan/issues/19 * TODO: How can we ensure we never overlap with KERNEL32.DLL?
*/ */
#define ADDRESS 0x77700000 /*0000*/
struct WinArgs { struct WinArgs {
char *argv[4096]; char *argv[4096];
@ -101,21 +100,23 @@ static textwindows wontreturn void WinMainNew(void) {
int64_t h; int64_t h;
size_t size; size_t size;
int i, count; int i, count;
uint64_t addr;
long auxv[1][2]; long auxv[1][2];
struct WinArgs *wa; struct WinArgs *wa;
const char16_t *env16; const char16_t *env16;
NormalizeCmdExe(); NormalizeCmdExe();
*(/*unconst*/ int *)&__hostos = WINDOWS; *(/*unconst*/ int *)&__hostos = WINDOWS;
addr = NtGetVersion() < kNtVersionWindows10 ? 0xff00000 : 0x777000000000;
size = ROUNDUP(STACKSIZE + sizeof(struct WinArgs), FRAMESIZE); size = ROUNDUP(STACKSIZE + sizeof(struct WinArgs), FRAMESIZE);
_mmi.p[0].h = __mmap$nt((char *)ADDRESS, size, _mmi.p[0].h =
PROT_READ | PROT_WRITE | PROT_EXEC, -1, 0) __mmap$nt((char *)addr, size, PROT_READ | PROT_WRITE | PROT_EXEC, -1, 0)
.maphandle; .maphandle;
_mmi.p[0].x = ADDRESS >> 16; _mmi.p[0].x = addr >> 16;
_mmi.p[0].y = (ADDRESS >> 16) + ((size >> 16) - 1); _mmi.p[0].y = (addr >> 16) + ((size >> 16) - 1);
_mmi.p[0].prot = PROT_READ | PROT_WRITE | PROT_EXEC; _mmi.p[0].prot = PROT_READ | PROT_WRITE | PROT_EXEC;
_mmi.p[0].flags = MAP_PRIVATE | MAP_ANONYMOUS; _mmi.p[0].flags = MAP_PRIVATE | MAP_ANONYMOUS;
_mmi.i = pushpop(1L); _mmi.i = pushpop(1L);
wa = (struct WinArgs *)(ADDRESS + size - sizeof(struct WinArgs)); wa = (struct WinArgs *)(addr + size - sizeof(struct WinArgs));
count = GetDosArgv(GetCommandLine(), wa->argblock, ARG_MAX, wa->argv, 4096); count = GetDosArgv(GetCommandLine(), wa->argblock, ARG_MAX, wa->argv, 4096);
for (i = 0; wa->argv[0][i]; ++i) { for (i = 0; wa->argv[0][i]; ++i) {
if (wa->argv[0][i] == '\\') { if (wa->argv[0][i] == '\\') {
@ -127,7 +128,7 @@ static textwindows wontreturn void WinMainNew(void) {
FreeEnvironmentStrings(env16); FreeEnvironmentStrings(env16);
auxv[0][0] = pushpop(0L); auxv[0][0] = pushpop(0L);
auxv[0][1] = pushpop(0L); auxv[0][1] = pushpop(0L);
_jmpstack((char *)ADDRESS + STACKSIZE, _executive, count, wa->argv, wa->envp, _jmpstack((char *)addr + STACKSIZE, _executive, count, wa->argv, wa->envp,
auxv); auxv);
} }