-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathMain.cpp
141 lines (118 loc) · 3.94 KB
/
Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <stdio.h>
#include <windows.h>
#include "WoWMIPS.h"
// debug mode
DWORD dwGlobal_DebugMode = 1;
// imported functions
void* (WINAPI *pRtlAddVectoredExceptionHandler)(DWORD dwFirstHandler, void *pExceptionHandler) = NULL;
DWORD (WINAPI *pRtlRemoveVectoredExceptionHandler)(void *pHandle) = NULL;
BOOL (WINAPI *pSetProcessDEPPolicy)(DWORD dwFlags) = NULL;
// TLS index for emulated info storage
DWORD dwGlobal_CpuThreadDataTlsIndex = 0;
// main executable image
BYTE *pGlobal_ImageBase = NULL;
DWORD dwGlobal_ImageSize = 0;
IMAGE_NT_HEADERS32 *pGlobal_ImageNtHeader = NULL;
int main(int argc, char *argv[])
{
BYTE *pImageBase = NULL;
IMAGE_NT_HEADERS32 *pImageNtHeader = NULL;
BYTE *pEntryPoint = NULL;
char *pTargetPath = NULL;
char szFullPath[512];
char *pLastSlash = NULL;
DWORD dwIgnoreCommandLineCharacterCount = 0;
if(argc < 2)
{
printf("Usage: %s <target_mips_executable_path>\n", argv[0]);
return 1;
}
// get mips executable path
pTargetPath = argv[1];
// get RtlAddVectoredExceptionHandler function ptr
pRtlAddVectoredExceptionHandler = (VOID*(WINAPI*)(DWORD,VOID*))GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlAddVectoredExceptionHandler");
if(pRtlAddVectoredExceptionHandler == NULL)
{
return 1;
}
// get RtlRemoveVectoredExceptionHandler function ptr
pRtlRemoveVectoredExceptionHandler = (DWORD(WINAPI*)(VOID*))GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlRemoveVectoredExceptionHandler");
if(pRtlRemoveVectoredExceptionHandler == NULL)
{
return 1;
}
// get SetProcessDEPPolicy function ptr
pSetProcessDEPPolicy = (BOOL(WINAPI*)(DWORD))GetProcAddress(GetModuleHandle("kernel32.dll"), "SetProcessDEPPolicy");
if(pSetProcessDEPPolicy == NULL)
{
return 1;
}
// initialise thread list lock
InitializeCriticalSection(&Global_CpuThreadListCriticalSection);
// allocate cpu thread data TLS slot
dwGlobal_CpuThreadDataTlsIndex = TlsAlloc();
if(dwGlobal_CpuThreadDataTlsIndex == TLS_OUT_OF_INDEXES)
{
return 1;
}
// ensure DEP is enabled for this process - old compilers (eg msvc++ 6.0) won't set the NX_COMPAT flag in the output exe.
// this is required to capture user callbacks - an exception handler intercepts native execution within the MIPS executable code and emulates it instead.
pSetProcessDEPPolicy(1);
// get full mips executable path
memset(szFullPath, 0, sizeof(szFullPath));
if(GetFullPathName(pTargetPath, sizeof(szFullPath) - 1, szFullPath, NULL) == 0)
{
return 1;
}
// map mips executable into memory
if(MemoryMapPE(szFullPath, &pImageBase, &pImageNtHeader) != 0)
{
printf("Failed to map MIPS executable: %s\n", szFullPath);
return 1;
}
// set CWD to same directory as target mips exe
pLastSlash = strrchr(szFullPath, '\\');
if(pLastSlash == NULL)
{
return 1;
}
*pLastSlash = '\0';
SetCurrentDirectory(szFullPath);
// store image info
pGlobal_ImageBase = pImageBase;
pGlobal_ImageNtHeader = pImageNtHeader;
dwGlobal_ImageSize = pImageNtHeader->OptionalHeader.SizeOfImage;
// fix command-line (hook GetCommandLine globally rather than IAT hook - might be called indirectly via imported CRT functions)
dwIgnoreCommandLineCharacterCount = strlen(argv[0]);
if(*(char*)GetCommandLineA() == '\"')
{
// ignore quote characters
dwIgnoreCommandLineCharacterCount += 2;
}
if(FixCommandLine(dwIgnoreCommandLineCharacterCount) != 0)
{
return 1;
}
// initialise current thread
if(CPU_InitialiseThread() != 0)
{
return 1;
}
// initialise emulated process environment
if(NativeCall_InitialiseEnvironment() != 0)
{
return 1;
}
// begin execution at program entry-point
pEntryPoint = (BYTE*)((BYTE*)pImageBase + pImageNtHeader->OptionalHeader.AddressOfEntryPoint);
if(CPU_ExecuteSubroutine(pEntryPoint, NULL, 0, NULL) != 0)
{
return 1;
}
// restore original environment
if(NativeCall_RestoreEnvironment() != 0)
{
return 1;
}
return 0;
}