Hi, 

Really sorry about not posting any updates, been swamped with work and just 
got back from vacation. I don't have time to setup a git repo and commit 
the code, means I'll actually have to clean-up and comment the code. But I 
have attached a diff between the current origin/HEAD and the changes I made 
to get it working on 64bit host windows. Haven't made any changes since the 
initial work, since it has been stable for our use. Be warned tho, I have 
not tested this on a 32bit host system, it will however execute 32bit 
binaries on a 64bit host system.

~/tup64$ cat tup.config

CONFIG_TUP_MINGW=x86_64-w64-mingw32 


I can probably answer some questions about the code and help out some here 
on the forum, but I can't guarantee their timelyness. Really swamped with 
work. 

Again, really sorry for not posting responses here sooner!

On Monday, March 17, 2014 8:46:22 PM UTC+1, [email protected] wrote:
>
> On Mon, Mar 17, 2014 at 8:51 AM, Tristan Rybak <[email protected] 
> <javascript:>> wrote:
>
>> Hi Mike, Robert,
>> Any news on a patch for 64bit windows?
>> I am using the executable attached to first post and it's working great 
>> (very big thanks for that Robert!)
>> but I'd like to have new features and bugfixes introduced later too 
>> please.
>> Maybe I could help with integrating the fix into repository somehow?
>> Regards,
>> Tristan
>>
>
> Hi Tristan,
>
> I don't think I've seen the patch from Robert yet, though maybe I've 
> missed it. I'd be happy to get it included if he's interested in getting it 
> upstream.
>
> Thanks,
> -Mike
>

-- 
-- 
tup-users mailing list
email: [email protected]
unsubscribe: [email protected]
options: http://groups.google.com/group/tup-users?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"tup-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/Tuprules.tup b/Tuprules.tup
index 3f0953b..4e71066 100644
--- a/Tuprules.tup
+++ b/Tuprules.tup
@@ -28,10 +28,10 @@ CFLAGS += -Wswitch-enum
 CFLAGS += -fno-common
 CFLAGS += -I$(TUP_CWD)/src
 
-ifeq (@(TUP_32_BIT),y)
-CFLAGS += -m32
-LDFLAGS += -m32
-endif
+#ifeq (@(TUP_32_BIT),y)
+CFLAGS += -m64
+LDFLAGS += -m64
+#endif
 
 export PKG_CONFIG_PATH
 CFLAGS += `pkg-config fuse --cflags`
diff --git a/src/compat/win32/wow64.h b/src/compat/win32/wow64.h
new file mode 100644
index 0000000..8e63ece
--- /dev/null
+++ b/src/compat/win32/wow64.h
@@ -0,0 +1,52 @@
+#ifndef tup_win32_wow64_h
+#define tup_win32_wow64_h
+
+#define WOW64_MAXIMUM_SUPPORTED_EXTENSION 512
+#define WOW64_SIZE_OF_80387_REGISTERS 80
+
+#define WOW64_CONTEXT_i386 0x00010000
+#define WOW64_CONTEXT_i486 0x00010000
+#define WOW64_CONTEXT_CONTROL (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000001))
+
+typedef struct _WOW64_FLOATING_SAVE_AREA {
+  DWORD   ControlWord;
+  DWORD   StatusWord;
+  DWORD   TagWord;
+  DWORD   ErrorOffset;
+  DWORD   ErrorSelector;
+  DWORD   DataOffset;
+  DWORD   DataSelector;
+  BYTE    RegisterArea[WOW64_SIZE_OF_80387_REGISTERS];
+  DWORD   Cr0NpxState;
+} WOW64_FLOATING_SAVE_AREA, *PWOW64_FLOATING_SAVE_AREA;
+
+typedef struct _WOW64_CONTEXT {
+  DWORD ContextFlags;
+  DWORD Dr0;
+  DWORD Dr1;
+  DWORD Dr2;
+  DWORD Dr3;
+  DWORD Dr6;
+  DWORD Dr7;
+  WOW64_FLOATING_SAVE_AREA FloatSave;
+  DWORD SegGs;
+  DWORD SegFs;
+  DWORD SegEs;
+  DWORD SegDs;
+  DWORD Edi;
+  DWORD Esi;
+  DWORD Ebx;
+  DWORD Edx;
+  DWORD Ecx;
+  DWORD Eax;
+  DWORD Ebp;
+  DWORD Eip;
+  DWORD SegCs;
+  DWORD EFlags;
+  DWORD Esp;
+  DWORD SegSs;
+  BYTE ExtendedRegisters[WOW64_MAXIMUM_SUPPORTED_EXTENSION];
+} WOW64_CONTEXT, *PWOW64_CONTEXT;
+
+#endif
+
diff --git a/src/dllinject/dllinject.c b/src/dllinject/dllinject.c
index e781206..49b48f6 100644
--- a/src/dllinject/dllinject.c
+++ b/src/dllinject/dllinject.c
@@ -29,6 +29,7 @@
 
 #include <windows.h>
 #include <ntdef.h>
+#include <wow64.h>
 #ifndef STATUS_SUCCESS
 #include <ntstatus.h>
 #endif
@@ -40,6 +41,9 @@
 #include <ctype.h>
 #include <shlwapi.h>
 
+#define __DBG_W64		0
+#define __DBG_W32		0
+
 #ifndef __in
 #define __in
 #define __out
@@ -1122,8 +1126,10 @@ BOOL WINAPI CreateProcessA_hook(
 	}
 
 	/* Ignore mspdbsrv.exe, since it continues to run in the background */
-	if(!lpApplicationName || strcasestr(lpApplicationName, "mspdbsrv.exe") == NULL)
+	if(!lpApplicationName || strcasestr(lpApplicationName, "mspdbsrv.exe") == NULL
+						  || strcasestr(lpApplicationName, "tup32detect.exe") == NULL) {
 		tup_inject_dll(lpProcessInformation, s_depfilename, s_vardict_file);
+	}
 
 	if ((dwCreationFlags & CREATE_SUSPENDED) != 0)
 		return 1;
@@ -1166,8 +1172,10 @@ BOOL WINAPI CreateProcessW_hook(
 	}
 
 	/* Ignore mspdbsrv.exe, since it continues to run in the background */
-	if(!lpApplicationName || wcscasestr(lpApplicationName, L"mspdbsrv.exe") == NULL)
+	if(!lpApplicationName || wcscasestr(lpApplicationName, L"mspdbsrv.exe") == NULL
+						  || wcscasestr(lpApplicationName, L"tup32detect.exe") == NULL) {
 		tup_inject_dll(lpProcessInformation, s_depfilename, s_vardict_file);
+	}
 
 	if ((dwCreationFlags & CREATE_SUSPENDED) != 0)
 		return 1;
@@ -1211,8 +1219,10 @@ BOOL WINAPI CreateProcessAsUserA_hook(
 	}
 
 	/* Ignore mspdbsrv.exe, since it continues to run in the background */
-	if(!lpApplicationName || strcasestr(lpApplicationName, "mspdbsrv.exe") == NULL)
+	if(!lpApplicationName || strcasestr(lpApplicationName, "mspdbsrv.exe") == NULL
+						  || strcasestr(lpApplicationName, "tup32detect.exe") == NULL) {
 		tup_inject_dll(lpProcessInformation, s_depfilename, s_vardict_file);
+	}
 
 	if ((dwCreationFlags & CREATE_SUSPENDED) != 0)
 		return 1;
@@ -1256,8 +1266,10 @@ BOOL WINAPI CreateProcessAsUserW_hook(
 	}
 
 	/* Ignore mspdbsrv.exe, since it continues to run in the background */
-	if(!lpApplicationName || wcscasestr(lpApplicationName, L"mspdbsrv.exe") == NULL)
+	if(!lpApplicationName || wcscasestr(lpApplicationName, L"mspdbsrv.exe") == NULL
+						  || wcscasestr(lpApplicationName, L"tup32detect.exe") == NULL) {
 		tup_inject_dll(lpProcessInformation, s_depfilename, s_vardict_file);
+	}
 
 	if ((dwCreationFlags & CREATE_SUSPENDED) != 0)
 		return 1;
@@ -1301,8 +1313,10 @@ BOOL WINAPI CreateProcessWithLogonW_hook(
 	}
 
 	/* Ignore mspdbsrv.exe, since it continues to run in the background */
-	if(!lpApplicationName || wcscasestr(lpApplicationName, L"mspdbsrv.exe") == NULL)
+	if(!lpApplicationName || wcscasestr(lpApplicationName, L"mspdbsrv.exe") == NULL
+					      || wcscasestr(lpApplicationName, L"tup32detect.exe") == NULL) {
 		tup_inject_dll(lpProcessInformation, s_depfilename, s_vardict_file);
+	}
 
 	if ((dwCreationFlags & CREATE_SUSPENDED) != 0)
 		return 1;
@@ -1342,8 +1356,10 @@ BOOL WINAPI CreateProcessWithTokenW_hook(
 	}
 
 	/* Ignore mspdbsrv.exe, since it continues to run in the background */
-	if(!lpApplicationName || wcscasestr(lpApplicationName, L"mspdbsrv.exe") == NULL)
+	if(!lpApplicationName || wcscasestr(lpApplicationName, L"mspdbsrv.exe") == NULL
+	                      || wcscasestr(lpApplicationName, L"tup32detect.exe") == NULL) {
 		tup_inject_dll(lpProcessInformation, s_depfilename, s_vardict_file);
+	}
 
 	if ((dwCreationFlags & CREATE_SUSPENDED) != 0)
 		return 1;
@@ -1390,6 +1406,8 @@ int remove_hook(const char *pathname)
 typedef HMODULE (WINAPI *LoadLibraryA_t)(const char*);
 typedef FARPROC (WINAPI *GetProcAddress_t)(HMODULE, const char*);
 
+
+
 struct remote_thread_t
 {
 	LoadLibraryA_t load_library;
@@ -1401,6 +1419,19 @@ struct remote_thread_t
 	char func_name[256];
 };
 
+struct remote_thread32_t
+{
+	uint32_t load_library;
+	uint32_t get_proc_address;
+	char depfilename[MAX_PATH];
+	char vardict_file[MAX_PATH];
+	char execdir[MAX_PATH];
+	char dll_name[MAX_PATH];
+	char func_name[256];
+}__attribute__((packed));
+
+
+
 
 #define HOOK(name) { MODULE_NAME, #name, name##_hook, (void**)&name##_orig, 0 }
 static struct patch_entry patch_table[] = {
@@ -1810,16 +1841,48 @@ DWORD tup_inject_init(remote_thread_t* r)
 
 int remote_stub(void);
 __asm(
-  ".globl _remote_stub\n"
-  "_remote_stub:\n"
-  "pushl $0xDEADBEEF\n"    // return address, [1]
-  "pushfl\n"
-  "pushal\n"
-  "pushl $0xDEADBEEF\n"    // function parameter, [8]
-  "movl $0xDEADBEEF, %eax\n" // function to call, [13]
-  "call *%eax\n"
-  "popal\n"
-  "popfl\n"
+  ".globl remote_stub\n"
+  "remote_stub:\n"
+  "subq $8, %rsp\n"
+  "movl $0x556677, (%rsp)\n"		// return address, [0x7]
+  "movl $0x11223344, 4(%rsp)\n"		// return address, [0xf]
+  "pushf\n"
+  "push %r15\n"
+  "push %r14\n"
+  "push %r13\n"
+  "push %r12\n"
+  "push %r11\n"
+  "push %r10\n"
+  "push %r9\n"
+  "push %r8\n"
+  "push %rbp\n"
+  "push %rdi\n"
+  "push %rsi\n"
+  "push %rdx\n"
+  "push %rcx\n"
+  "push %rbx\n"
+  "push %rax\n"
+  "xorq %rcx, %rcx\n"
+  "movq $0x1100000055667788, %rcx\n"	// function parameter [0x30]
+  "xorq %rax, %rax\n"
+  "movq $0x9900000055667788, %rax\n" 	// function to call, [0x3d]
+  "call *%rax\n"
+  "pop %rax\n"
+  "pop %rbx\n"
+  "pop %rcx\n"
+  "pop %rdx\n"
+  "pop %rsi\n"
+  "pop %rdi\n"
+  "pop %rbp\n"
+  "pop %r8\n"
+  "pop %r9\n"
+  "pop %r10\n"
+  "pop %r11\n"
+  "pop %r12\n"
+  "pop %r13\n"
+  "pop %r14\n"
+  "pop %r15\n"
+  "popf\n"
   "ret"
 );
 
@@ -1842,86 +1905,388 @@ static void remote_end(void)
 {
 }
 
+
+#if __DBG_W64 == 1
+static void printHex(const void *lpvbits, const unsigned int n)
+{
+    char* data = (char*) lpvbits;
+    unsigned int i = 0;
+    char line[17] = {};
+    printf("%.8X | ", (unsigned char*)data);
+    while ( i < n ) {
+        line[i%16] = *(data+i);
+        if ((line[i%16] < 32) || (line[i%16] > 126)) {
+            line[i%16] = '.';
+        }
+        printf("%.2X", (unsigned char)*(data+i));
+        i++;
+        if (i%4 == 0) {
+            if (i%16 == 0) {
+                if (i < n-1)
+                    printf(" | %s\n%.8X | ", &line, data+i);
+            } else {
+                printf(" ");
+            }
+        }
+    }
+    while (i%16 > 0) {
+        (i%4 == 0)?printf("   "):printf("  ");
+        line[i%16] = ' ';
+        i++;
+    }
+    printf(" | %s\n", &line);
+}
+#endif
+
+inline long long unsigned int low32(long long unsigned int tall)
+{
+        return tall & 0x00000000ffffffff;
+}
+inline long long unsigned int high32(long long unsigned int tall)
+{
+        return tall >> 32;
+}
+
+struct remote_stub_t {
+	uint8_t stub[23];
+	uint8_t fileA_Hook[39];
+	uint8_t fileW_Hook[39];
+	uint8_t remote_init[60];
+}__attribute__((packed));
+
+static struct remote_stub_t remote_stub32 = {
+	.stub = {
+0x68, 0x00, 0x00, 0x00, 0x00,
+0x9c,
+0x60,
+0x68, 0xef, 0xbe, 0xad, 0xde,
+0xb8, 0xef, 0xbe, 0xad, 0xde,
+0xff, 0xd0,
+0x61,
+0x9d,
+0xc3
+},
+	.fileA_Hook = {
+0x55,
+0x89, 0xe5,
+0x83, 0xec, 0x18,
+0x8b, 0x45, 0x0c,
+0x89, 0x44, 0x24, 0x04,
+0x8b, 0x45, 0x08,
+0x89, 0x04, 0x24,
+0xff, 0x15, 0x78, 0x00, 0x00, 0x00,
+0x85, 0xc0,
+0x52,
+0x0f, 0x95, 0xc0,
+0x52,
+0x0f, 0xb6, 0xc0,
+0xc9,
+0xc2, 0x08, 0x00
+},
+
+	.fileW_Hook = {
+0x55,
+0x89, 0xe5,
+0x83, 0xec, 0x18,
+0x8b, 0x45, 0x0c,
+0x89, 0x44, 0x24, 0x04,
+0x8b, 0x45, 0x08,
+0x89, 0x04, 0x24,
+0xff, 0x15, 0x7c, 0x00, 0x00, 0x00,
+0x85, 0xc0,
+0x51,
+0x0f, 0x95, 0xc0,
+0x51,
+0x0f, 0xb6, 0xc0,
+0xc9,
+0xc2, 0x08, 0x00
+},
+
+	.remote_init = {
+0x55,
+0x89, 0xe5,
+0x53,
+0x83, 0xec, 0x14,
+0x8b, 0x5d, 0x08,
+0x8d, 0x83, 0x14, 0x03, 0x00, 0x00,
+0x89, 0x04, 0x24,
+0xff, 0x13,
+0x85, 0xc0,
+0x51,
+0x74, 0x1b,				// JE 0x1b
+0x8d, 0x93, 0x18, 0x04, 0x00, 0x00,
+0x89, 0x54, 0x24, 0x04,
+0x89, 0x04, 0x24,
+0xff, 0x53, 0x04,
+0x85, 0xc0,
+0x52,
+0x52,
+0x74, 0x05,				// JE 0x05
+0x89, 0x1c, 0x24,
+0xff, 0xd0,
+0x8b, 0x5d, 0xfc,
+0xc9,
+0xc2, 0x04, 0x00}
+};
+
+
+
+static uint32_t LOAD_LIBRARY_32 = 0;
+static uint32_t GET_PROC_ADDRESS_32 = 0;
+
+#define BUFSIZE 4096
+
+BOOL get_wow64_addresses(void)
+{
+	DWORD dwRead;
+	CHAR chBuf[BUFSIZE];
+	PROCESS_INFORMATION piProcInfo;
+	STARTUPINFO  siStartInfo;
+	BOOL ret;
+	
+	TCHAR szCmdline[]=TEXT("tup32detect.exe");
+	
+	HANDLE g_hChildStd_OUT_Rd = NULL;
+	HANDLE g_hChildStd_OUT_Wr = NULL;
+	
+	SECURITY_ATTRIBUTES saAttr; 
+	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
+	saAttr.bInheritHandle = TRUE; 
+	saAttr.lpSecurityDescriptor = NULL; 
+
+	// Pipe stdout
+	if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) )
+		return FALSE;
+
+	// Ensure the read handle to the pipe for STDOUT is not inherited.
+	if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
+		return FALSE;
+
+	// create process
+	memset(&siStartInfo, 0, sizeof(STARTUPINFO));
+	siStartInfo.cb = sizeof(STARTUPINFO);
+	siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
+	siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
+	
+	memset(&piProcInfo, 0, sizeof(PROCESS_INFORMATION));
+	
+	// Detect and avoid inception!
+	if (CreateProcessA_orig != NULL)
+		ret = CreateProcessA_orig(
+				NULL,
+				szCmdline,
+				NULL,
+				NULL,
+				TRUE,
+				0,
+				NULL,
+				NULL,
+				&siStartInfo,
+				&piProcInfo);
+	else
+		ret = CreateProcessA(
+				NULL,
+				szCmdline,
+				NULL,
+				NULL,
+				TRUE,
+				0,
+				NULL,
+				NULL,
+				&siStartInfo,
+				&piProcInfo);
+				
+	if (!ret)
+		return FALSE;
+	
+	ret = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
+	if (!ret || dwRead == 0)
+		return FALSE;
+	
+	if (sscanf(chBuf, "%x-%x", &LOAD_LIBRARY_32, &GET_PROC_ADDRESS_32) != 2)
+		return FALSE;
+
+	CloseHandle(piProcInfo.hProcess);
+	CloseHandle(piProcInfo.hThread);
+
+	return TRUE;
+}
+
+
+
 int tup_inject_dll(
 	LPPROCESS_INFORMATION lpProcessInformation,
 	const char *depfilename,
 	const char *vardict_file)
 {
-	remote_thread_t remote;
 	char* remote_data;
 	size_t code_size;
 	DWORD old_protect;
 	HANDLE process;
 	HMODULE kernel32;
+	BOOL bWow64 = 0;
 
-	memset(&remote, 0, sizeof(remote));
-	kernel32 = LoadLibraryA("kernel32.dll");
-	remote.load_library = (LoadLibraryA_t) GetProcAddress(kernel32, "LoadLibraryA");
-	remote.get_proc_address = (GetProcAddress_t) GetProcAddress(kernel32, "GetProcAddress");
-	strcpy(remote.depfilename, depfilename);
-	strcpy(remote.vardict_file, vardict_file);
-	strcat(remote.execdir, execdir);
-	strcat(remote.dll_name, execdir);
-	strcat(remote.dll_name, "\\");
-	strcat(remote.dll_name, "tup-dllinject.dll");
-	strcat(remote.func_name, "tup_inject_init");
-
-	CONTEXT ctx;
-	ctx.ContextFlags = CONTEXT_CONTROL;
-	if( !GetThreadContext( lpProcessInformation->hThread, &ctx ) )
-		return -1;
+	IsWow64Process(lpProcessInformation->hProcess, &bWow64);
 
-	DEBUG_HOOK("Injecting dll '%s' '%s' %s' '%s'\n",
-		remote.execdir,
-		remote.dll_name,
-		remote.func_name,
-		remote.depfilename,
-		remote.vardict_file);
+	//DWORD version = GetProcessVersion(lpProcessInformation->dwProcessId);
 
-	process = lpProcessInformation->hProcess;
+	// WOW64
+	if (bWow64) {
+		remote_thread32_t remote;
 
-	if (!WaitForInputIdle(process, INFINITE))
-		return -1;
+		if (GET_PROC_ADDRESS_32 == 0) {
+			if ( ! get_wow64_addresses() ) {
+				printf("Unable to retrieve WOW64 info\n");
+				return -1;
+			}
+		}
 
-	/* Align code_size to a 16 byte boundary */
-	code_size = (  (uintptr_t) &remote_end
-		     - (uintptr_t) &remote_stub + 0x0F)
-		  & ~0x0F;
+		memset(&remote, 0, sizeof(remote));
+		remote.load_library = LOAD_LIBRARY_32;
+		remote.get_proc_address = GET_PROC_ADDRESS_32;
+		strcpy(remote.depfilename, depfilename);
+		strcpy(remote.vardict_file, vardict_file);
+		strcat(remote.execdir, execdir);
+		strcat(remote.dll_name, execdir);
+		strcat(remote.dll_name, "\\");
+		strcat(remote.dll_name, "tup-dllinject32.dll");
+		strcat(remote.func_name, "tup_inject_init");
+
+		WOW64_CONTEXT ctx;
+		ctx.ContextFlags = WOW64_CONTEXT_CONTROL;
+		if ( !Wow64GetThreadContext( lpProcessInformation->hThread, &ctx ) )
+			return -1;
 
-	remote_data = (char*) VirtualAllocEx(
-		process,
-		NULL,
-		code_size + sizeof(remote),
-		MEM_COMMIT | MEM_RESERVE,
-		PAGE_EXECUTE_READWRITE);
+		/* Align code_size to a 16 byte boundary */
+		code_size = (sizeof(remote_stub32) + 0x0F) & ~0x0F;
 
-	if (!remote_data)
-		return -1;
+		DEBUG_HOOK("Injecting dll '%s' '%s' %s' '%s'\n",
+			remote.execdir,
+			remote.dll_name,
+			remote.func_name,
+			remote.depfilename,
+			remote.vardict_file);
 
-	if (!VirtualProtectEx(process, remote_data, code_size + sizeof(remote), PAGE_READWRITE, &old_protect))
-		return -1;
+		process = lpProcessInformation->hProcess;
 
-	unsigned char code[code_size];
-	memcpy( code, &remote_stub, code_size );
-	*(DWORD*)(code + 1) = ctx.Eip;
-	*(DWORD*)(code + 8) = (DWORD)remote_data + code_size;
-	*(DWORD*)(code + 13) = (DWORD)remote_data + ( (DWORD)&remote_init - (DWORD)&remote_stub );
-	if (!WriteProcessMemory(process, remote_data, code, code_size, NULL))
-		return -1;
+		if (!WaitForInputIdle(process, INFINITE))
+			return -1;
 
-	if (!WriteProcessMemory(process, remote_data + code_size, &remote, sizeof(remote), NULL))
-		return -1;
+		remote_data = (char*) VirtualAllocEx(
+			process,
+			NULL,
+			code_size + sizeof(remote),
+			MEM_COMMIT | MEM_RESERVE,
+			PAGE_EXECUTE_READWRITE);
 
-	if (!VirtualProtectEx(process, remote_data, code_size + sizeof(remote), PAGE_EXECUTE_READ, &old_protect))
-		return -1;
+		if (!remote_data)
+			return -1;
 
-	if (!FlushInstructionCache(process, remote_data, code_size + sizeof(remote)))
-		return -1;
+		if (!VirtualProtectEx(process, remote_data, code_size + sizeof(remote), PAGE_READWRITE, &old_protect))
+			return -1;
+
+		unsigned char code[code_size];
+
+		memcpy( code, &remote_stub32, code_size );
+
+		*(DWORD*)(code + 0x1) = ctx.Eip;											// Return addr
+		*(DWORD*)(code + 0x8) = (DWORD)((DWORD_PTR)remote_data + code_size);							// Arg (ptr to remote (TCB))
+		*(DWORD*)(code + 0xd) = (DWORD)((DWORD_PTR)remote_data + ((DWORD_PTR)&remote_stub32.remote_init - (DWORD_PTR)&remote_stub32));	// Func (ptr to remote_init)
+
+		if (!WriteProcessMemory(process, remote_data, code, code_size, NULL))
+			return -1;
+
+		if (!WriteProcessMemory(process, remote_data + code_size, &remote, sizeof(remote), NULL))
+			return -1;
+
+		if (!VirtualProtectEx(process, remote_data, code_size + sizeof(remote), PAGE_EXECUTE_READ, &old_protect))
+			return -1;
+
+		if (!FlushInstructionCache(process, remote_data, code_size + sizeof(remote)))
+			return -1;
+
+		ctx.Eip = (DWORD_PTR)remote_data;
+		ctx.ContextFlags = WOW64_CONTEXT_CONTROL;
+		if( !Wow64SetThreadContext( lpProcessInformation->hThread, &ctx ) )
+			return -1;
+	}
+	else
+	{
+		remote_thread_t remote;
+
+		memset(&remote, 0, sizeof(remote));
+		kernel32 = LoadLibraryA("kernel32.dll");
+		remote.load_library = (LoadLibraryA_t) GetProcAddress(kernel32, "LoadLibraryA");
+		remote.get_proc_address = (GetProcAddress_t) GetProcAddress(kernel32, "GetProcAddress");
+		strcpy(remote.depfilename, depfilename);
+		strcpy(remote.vardict_file, vardict_file);
+		strcat(remote.execdir, execdir);
+		strcat(remote.dll_name, execdir);
+		strcat(remote.dll_name, "\\");
+		strcat(remote.dll_name, "tup-dllinject.dll");
+		strcat(remote.func_name, "tup_inject_init");
+
+		CONTEXT ctx;
+		ctx.ContextFlags = CONTEXT_CONTROL;
+		if( !GetThreadContext( lpProcessInformation->hThread, &ctx ) )
+			return -1;
+
+		/* Align code_size to a 16 byte boundary */
+		code_size = (  (uintptr_t) &remote_end
+			     - (uintptr_t) &remote_stub + 0x0F)
+			  & ~0x0F;
 
-	ctx.Eip = (DWORD)remote_data;
-	ctx.ContextFlags = CONTEXT_CONTROL;
-	if( !SetThreadContext( lpProcessInformation->hThread, &ctx ) )
-        return -1;
+
+		DEBUG_HOOK("Injecting dll '%s' '%s' %s' '%s'\n",
+			remote.execdir,
+			remote.dll_name,
+			remote.func_name,
+			remote.depfilename,
+			remote.vardict_file);
+
+		process = lpProcessInformation->hProcess;
+
+		if (!WaitForInputIdle(process, INFINITE))
+			return -1;
+
+		remote_data = (char*) VirtualAllocEx(
+			process,
+			NULL,
+			code_size + sizeof(remote),
+			MEM_COMMIT | MEM_RESERVE,
+			PAGE_EXECUTE_READWRITE);
+
+		if (!remote_data)
+			return -1;
+
+		if (!VirtualProtectEx(process, remote_data, code_size + sizeof(remote), PAGE_READWRITE, &old_protect))
+			return -1;
+
+		unsigned char code[code_size];
+
+		memcpy( code, &remote_stub, code_size );
+		*(DWORD*)(code + 0x7) = low32(ctx.Rip);
+		*(DWORD*)(code + 0xf) = high32(ctx.Rip);
+		*(DWORD64*)(code + 0x30) = (long long unsigned int)(remote_data + code_size);
+		*(DWORD64*)(code + 0x3d) = (long long unsigned int)(DWORD_PTR)remote_data + ((DWORD_PTR)&remote_init - (DWORD_PTR)&remote_stub);
+
+		if (!WriteProcessMemory(process, remote_data, code, code_size, NULL))
+			return -1;
+
+		if (!WriteProcessMemory(process, remote_data + code_size, &remote, sizeof(remote), NULL))
+			return -1;
+
+		if (!VirtualProtectEx(process, remote_data, code_size + sizeof(remote), PAGE_EXECUTE_READ, &old_protect))
+			return -1;
+
+		if (!FlushInstructionCache(process, remote_data, code_size + sizeof(remote)))
+			return -1;
+
+		ctx.Rip = (DWORD_PTR)remote_data;
+		ctx.ContextFlags = CONTEXT_CONTROL;
+		if( !SetThreadContext( lpProcessInformation->hThread, &ctx ) )
+			return -1;
+	}
 
 	return 0;
 }
diff --git a/src/dllinject/dllinject.h b/src/dllinject/dllinject.h
index 2ba20d9..3062ee5 100644
--- a/src/dllinject/dllinject.h
+++ b/src/dllinject/dllinject.h
@@ -36,6 +36,8 @@ extern "C" {
 DLLINJECT_API BOOL WINAPI DllMain(HANDLE HDllHandle, DWORD Reason, LPVOID Reserved);
 
 typedef struct remote_thread_t remote_thread_t;
+typedef struct remote_thread32_t remote_thread32_t;
+
 DLLINJECT_API DWORD tup_inject_init(remote_thread_t *r);
 
 DLLINJECT_API void tup_inject_setexecdir(const char *dir);
diff --git a/src/dllinject/hot_patch.c b/src/dllinject/hot_patch.c
index 9ae8f8a..ce765cf 100644
--- a/src/dllinject/hot_patch.c
+++ b/src/dllinject/hot_patch.c
@@ -48,7 +48,7 @@ static int hot_patch_int(void *old_proc, void *new_proc, void **orig_proc)
 	}
 
 	*(begin + 0) = 0xe9; // long jump
-	*(DWORD*)(begin + 1) = (DWORD)new_proc - (DWORD)old_proc;
+	*(DWORD*)(begin + 1) = (DWORD_PTR)new_proc - (DWORD_PTR)old_proc;
 	*(WORD*)(begin + 5) = 0xf9eb; // short jump back
 
 	if(orig_proc)
diff --git a/src/dllinject/iat_patch.c b/src/dllinject/iat_patch.c
index c2bff3c..c164338 100644
--- a/src/dllinject/iat_patch.c
+++ b/src/dllinject/iat_patch.c
@@ -32,7 +32,7 @@ static void do_hook(void* fphook, void** fporig, IMAGE_THUNK_DATA* cur)
 		return;
 	}
 
-	cur->u1.Function = (DWORD)fphook;
+	cur->u1.Function = (DWORD_PTR)fphook;
 
 	if(!VirtualProtect(cur, sizeof(IMAGE_THUNK_DATA), old_protect, &old_protect)) {
 		return;
diff --git a/src/dllinject/trace.c b/src/dllinject/trace.c
index bf3799d..e7e9b9a 100644
--- a/src/dllinject/trace.c
+++ b/src/dllinject/trace.c
@@ -43,7 +43,7 @@ void debug_hook(const char* format, ...)
 	va_list ap;
 	if(debugf == NULL && !opening) {
 		opening = 1;
-		debugf = fopen("c:\\cygwin\\home\\marf\\ok.txt", "a");
+		debugf = fopen("ok.txt", "w");
 		fflush(stdout);
 	}
 	if(debugf == NULL) {
diff --git a/src/tup/server/windepfile.c b/src/tup/server/windepfile.c
index 0471ce0..1ed58d8 100644
--- a/src/tup/server/windepfile.c
+++ b/src/tup/server/windepfile.c
@@ -201,6 +201,7 @@ static int create_process(struct server *s, int dfd, char *cmdline,
 		fprintf(stderr, "tup error: Unable to change working directory to '%s'\n", win32_get_dirpath(dfd));
 		return -1;
 	}
+		
 	ret = CreateProcessA(
 		NULL,
 		cmdline,
@@ -220,7 +221,7 @@ static int create_process(struct server *s, int dfd, char *cmdline,
 }
 
 #define SHSTR  "sh -c '"
-#define CMDSTR "CMD.EXE /Q /C "
+#define CMDSTR "CMD.EXE /C "
 int server_exec(struct server *s, int dfd, const char *cmd, struct tup_env *newenv,
 		struct tup_entry *dtent, int full_deps)
 {
@@ -243,6 +244,9 @@ int server_exec(struct server *s, int dfd, const char *cmd, struct tup_env *newe
 		|| strncmp(cmd, "bash ", 5) == 0
 		|| strncmp(cmd, "cmd ", 4) == 0;
 
+	// Causes more problems than it fixes
+	have_shell = 1;
+
 	int need_sh = 0;
 
 	int need_cmd = 0;

Reply via email to