-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathjmp2it.cpp
191 lines (155 loc) · 7.53 KB
/
jmp2it.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/* This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Created by Adam Kramer [2014] - Email: adamkramer at hotmail dot com */
#include "stdafx.h"
#include "windows.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
/* Intro line */
printf("** JMP2IT v1.4 - Created by Adam Kramer [2014] - Inspired by Malhost-Setup **\n");
/* Check that we have received the required arguments - if not, display help page */
if (argc < 3)
{
printf("This will allow you to transfer EIP control to a specified offset within a file\n");
printf("containing shellcode and then pause to support a malware analysis investigation\n");
printf("The file will be mapped to memory and maintain a handle, allowing shellcode\n");
printf("to egghunt for second stage payload as would have happened in original loader\n");
printf("-------------------------------------------------------------------------------\n");
printf("Patches / self modifications are dynamically written to jmp2it-flypaper.out\n");
printf("-------------------------------------------------------------------------------\n");
printf("Usage: jmp2it.exe <file containing shellcode> <file offset to transfer EIP to>\n");
printf("Example: jmp2it.exe malware.doc 0x15C\n");
printf(" Explaination: The file will be mapped and code at 0x15C will immediately run\n");
printf("Example: jmp2it.exe malware.doc 0x15C pause\n");
printf(" Explaination: As above, with JMP SHORT 0xFE inserted pre-offset causing loop\n");
printf("Example: jmp2it.exe malware.doc 0x15C addhandle another.doc pause\n");
printf(" Explaination: As above, but will create additional handle to specified file\n");
printf("-------------------------------------------------------------------------------\n");
printf("Optional extras (to be added after first two parameters):\n");
printf(" addhandle <path to file> - Create an arbatory handle to a specified file\n");
printf("Only one of the following two may be used:\n");
printf(" pause - Inserts JMP SHORT 0xFE just before offset causing infinite loop\n");
printf(" pause_int3 - Inserts INT3 just before offset <launch via debugger!>\n");
printf("Note: In these cases, you will be presented with step by step instructions\n");
printf(" on what you need to do inside a debugger to resume the analysis\n");
return 1;
}
/* Check that arguement 2 is a legimitmate memory address */
if (strlen(argv[2]) < 3 || (argv[2][0] != '0' && argv[2][1] != 'x'))
{
printf("Error: Parameter 2 must begin 0x to signify a hex offset has been used\n");
return 1;
}
/* Convert argument 1 to wide char pointer */
wchar_t w[MAX_PATH];
size_t size_of_w = sizeof(w);
mbstowcs_s(&size_of_w, w, argv[1], MAX_PATH);
LPWSTR pFile = w;
/* Copy original file to temp 'flypaper' file */
CopyFile(pFile, L"jmp2it-flypaper.out", FALSE);
pFile = L"jmp2it-flypaper.out";
/* Create handle to requested file */
HANDLE hFile = CreateFile(pFile, GENERIC_ALL, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
/* Error catching for handle creation */
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Error: Unable to create handle to file - check path to file\n");
return 1;
}
/* Check if offset is greater than the size of the file */
if (GetFileSize(hFile, NULL) < (DWORD)strtol(argv[2], NULL, 16))
{
printf("Error: Offset is larger than selected file size");
return 1;
}
/* Check if 'addhandle' parameter has been requested */
/* N.B. Argument loading is a little messy - will tidy up if more functionality is added */
if (argc > 4 && !strcmp(argv[3], "addhandle"))
{
wchar_t z[MAX_PATH];
size_t size_of_z = sizeof(z);
mbstowcs_s(&size_of_z, z, argv[4], MAX_PATH);
LPWSTR pAddHandleFile = z;
HANDLE pAddHandle = CreateFile (pAddHandleFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
/* Error catching for handle creation */
if (pAddHandle == INVALID_HANDLE_VALUE)
{
printf("Error: Unable to create handle to file (addhandle param) - check path to file\n");
return 1;
}
} else if (argc > 5 && !strcmp(argv[4], "addhandle"))
{
wchar_t z[MAX_PATH];
size_t size_of_z = sizeof(z);
mbstowcs_s(&size_of_z, z, argv[5], MAX_PATH);
LPWSTR pAddHandleFile = z;
HANDLE pAddHandle = CreateFile (pAddHandleFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
/* Error catching for handle creation */
if (pAddHandle == INVALID_HANDLE_VALUE)
{
printf("Error: Unable to create handle to file (addhandle param) - check path to file\n");
return 1;
}
/* If they have requested 'addhandle', but not provided enough parameters (i.e. not the path) */
} else if (argc == 4 && !strcmp(argv[3], "addhandle") || (argc == 5 && !strcmp(argv[4], "addhandle")))
{
printf("Error: Insufficient parameters to use 'addhandle' functionality\n");
return 1;
}
/* Map file into memory */
HANDLE pMap = CreateFileMapping(hFile, NULL, PAGE_EXECUTE_READWRITE, 0, 0, NULL);
LPVOID lpBase = MapViewOfFile(pMap, FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, 0, 0, 0);
/* Handle errors with the memory mapping */
if (!lpBase)
{
printf("Error: Unable to map file to memory\n");
return 1;
}
/* Calculate shellcode location based on mapped memory offset */
int iOffset = strtol(argv[2], NULL, 16);
lpBase = (char*)lpBase + iOffset;
/* Prepare function pointer to shellcode address */
int (*pFunction)() = (int(*)(void))lpBase;
/* Version 2 of breakpoint code - nothing in the user's code is modified */
if ((argc > 3 && !strcmp(argv[3], "pause")) || (argc > 5 && !strcmp(argv[5], "pause")))
{
printf("** As requested, the process has been paused ** \n\n" \
"To proceed with debugging:\n" \
"1. Load a debugger and attach it to this process\n" \
"2. If it has paused, instruct it to start running again\n" \
"3. Pause the process after a few seconds\n" \
"4. NOP the EF BE infinite loop which you should be on\n" \
"5. Step to the CALL immediately after and then 'step into' it\n\n" \
" === You will then be at the shellcode ===\n ");
__asm{ loc: jmp loc } // Assembly infinite loop
/* INT3 version */
} else if ((argc > 3 && !strcmp(argv[3], "pause_int3")) || (argc > 5 && !strcmp(argv[5], "pause_int3")))
{
if (!IsDebuggerPresent())
{
printf("Error: pause_int3 can only be used within the context of a debugger\n");
return 1;
}
printf("** As requested, the process has been paused using INT3 ** \n\n" \
"To proceed with debugging:\n" \
"1. It should already be running within a debugger...\n" \
"2. If it has paused, instruct it to start running again\n" \
"3. Pause the process after a few seconds\n" \
"4. NOP the INT3 break which you should be on\n" \
"5. Step to the CALL immediately after and then 'step into' it\n\n" \
" === You will then be at the shellcode ===\n ");
__asm{ int 3 }
} else {
printf("Executing without pausing, expect the program to crash if the memory location is incorrect\n");
}
pFunction(); // Execute the shellcode
}