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;