Skip to content

Commit 2beb6ab

Browse files
committed
BugFix
1 parent 0c04d7e commit 2beb6ab

1 file changed

Lines changed: 88 additions & 25 deletions

File tree

shell_libs/compiler.py

Lines changed: 88 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ def compile(self) -> bool:
6464
f.write('#include<string.h>\n')
6565
f.write('#include<time.h>\n')
6666
f.write('\n')
67-
f.write('#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__)\n')
67+
f.write(
68+
'#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__)\n')
6869
f.write(' #include <windows.h>\n')
6970
f.write('#elif __APPLE__\n')
7071
f.write(' #include <TargetConditionals.h>\n')
@@ -111,33 +112,92 @@ def compile(self) -> bool:
111112
f.write(' printf("rsi = %p => writable memory (%zd bytes)\\n", &ZEROARRAY, size2);\n')
112113

113114
f.write('\n')
114-
f.write(' wtext();\n')
115+
f.write(' if (wtext()) {\n')
116+
f.write(' printf("Error setting .text permission");\n')
117+
f.write(' return 1;\n')
118+
f.write(' }\n')
115119
f.write(' shell(&code_cave, &ZEROARRAY);\n')
116120
f.write(' return 0;\n')
117121
f.write('}\n')
118122
f.write('\n')
119123

120124
f.write('int wtext(){\n')
121125
if self.writable_text:
122-
f.write(' void *const target = &main;\n')
123-
f.write(' size_t length = (size_t)((intptr_t) end_of_code - (intptr_t)main);\n')
124-
f.write(' #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__)\n')
125-
f.write(' SYSTEM_INFO si;\n')
126-
f.write(' GetSystemInfo(&si);\n')
127-
f.write(' const long page = si.dwPageSize;\n')
128-
f.write(' DWORD l=0;\n')
129-
f.write(' void *start = (char *)target - ((long)target % page);\n')
130-
f.write(' size_t bytes = length;\n')
131-
f.write(' VirtualProtect(start, bytes, PAGE_EXECUTE_READWRITE, &l);\n')
132-
f.write(' #elif __linux__\n')
133-
f.write(' const long page = sysconf(_SC_PAGESIZE);\n')
134-
f.write(' void *start = (char *)target - ((long)target % page);\n')
135-
f.write(' size_t bytes = length;\n')
136-
f.write(' if (mprotect(start, page, PROT_READ | PROT_WRITE | PROT_EXEC))\n')
137-
f.write(' return errno;\n')
138-
f.write(' #else\n')
139-
f.write(' return errno;\n')
140-
f.write(' #endif\n')
126+
f.write('''
127+
DWORD page = 4096;
128+
intptr_t start_addr = (intptr_t)0x00;
129+
intptr_t end_addr = (intptr_t)0x00;
130+
131+
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
132+
SYSTEM_INFO si;
133+
GetSystemInfo(&si);
134+
page = (DWORD)si.dwPageSize;
135+
#elif __linux__
136+
page = (DWORD)sysconf(_SC_PAGESIZE);
137+
#else
138+
return errno;
139+
#endif
140+
141+
// calculate max address
142+
// main
143+
if ((intptr_t)main >= end_addr)
144+
end_addr = (intptr_t)main;
145+
// shell
146+
if ((intptr_t)shell >= end_addr)
147+
end_addr = (intptr_t)shell;
148+
// code_cave
149+
if ((intptr_t)code_cave >= end_addr)
150+
end_addr = (intptr_t)code_cave;
151+
// wtext
152+
if ((intptr_t)wtext >= end_addr)
153+
end_addr = (intptr_t)wtext;
154+
// end_of_code
155+
if ((intptr_t)end_of_code >= end_addr)
156+
end_addr = (intptr_t)end_of_code;
157+
158+
159+
// calculate min address
160+
start_addr = end_addr;
161+
// main
162+
if ((intptr_t)main <= start_addr)
163+
start_addr = (intptr_t)main;
164+
165+
// shell
166+
if ((intptr_t)shell <= start_addr)
167+
start_addr = (intptr_t)shell;
168+
169+
// code_cave
170+
if ((intptr_t)code_cave <= start_addr)
171+
start_addr = (intptr_t)code_cave;
172+
173+
// wtext
174+
if ((intptr_t)wtext <= start_addr)
175+
start_addr = (intptr_t)wtext;
176+
177+
// end_of_code
178+
if ((intptr_t)end_of_code <= start_addr)
179+
start_addr = (intptr_t)end_of_code;
180+
181+
// calculate page boundary
182+
size_t length = (size_t)(end_addr - start_addr);
183+
length += (page - (length % page));
184+
185+
//printf("start = %x\\n", start_addr);
186+
//printf("end_addr = %x\\n", end_addr);
187+
//printf("len = %d\\n", length);
188+
189+
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
190+
DWORD l=0;
191+
VirtualProtect(start_addr, length, PAGE_EXECUTE_READWRITE, &l);
192+
#elif __linux__
193+
if (mprotect(start_addr, length, PROT_READ | PROT_WRITE | PROT_EXEC))
194+
return errno;
195+
#else
196+
return errno;
197+
#endif
198+
199+
return 0;
200+
''')
141201
else:
142202
f.write(' return 0;\n')
143203
f.write('}\n')
@@ -207,7 +267,7 @@ def compile(self) -> bool:
207267
self.bin_file.unlink(missing_ok=True)
208268

209269
gcc_flags = '-fno-stack-protector'
210-
#if not Tools.is_platform_windows():
270+
# if not Tools.is_platform_windows():
211271
# gcc_flags = ' -z execstack'
212272
if self.arch == 'x86':
213273
gcc_flags += ' -m32'
@@ -254,20 +314,23 @@ def replace_on_file(self, filename: [str, Path],
254314
file = Path(filename)
255315
stat = self.bin_file.stat()
256316
if stat.st_size == 0:
257-
Logger.pl('{!} {R}Error putting the shellcode at {G}%s{R}:{O} %s{W}' % (file.name, 'Executable file is empty'))
317+
Logger.pl(
318+
'{!} {R}Error putting the shellcode at {G}%s{R}:{O} %s{W}' % (file.name, 'Executable file is empty'))
258319
return False
259320

260321
with open(file.resolve(), 'rb') as f:
261322
bin_data = f.read(stat.st_size)
262323

263324
idx = Tools.find_index(bin_data, pattern)
264325
if idx == -1:
265-
Logger.pl('{!} {R}Error putting the shellcode at {G}%s{R}:{O} %s{W}' % (file.name, 'Find pattern not found'))
326+
Logger.pl(
327+
'{!} {R}Error putting the shellcode at {G}%s{R}:{O} %s{W}' % (file.name, 'Find pattern not found'))
266328
return False
267329

268330
if idx + len(replace_to) > len(bin_data):
269331
Logger.pl(
270-
'{!} {R}Error putting the shellcode at {G}%s{R}:{O} %s{W}' % (file.name, 'replace_to data is greater than binary file'))
332+
'{!} {R}Error putting the shellcode at {G}%s{R}:{O} %s{W}' % (
333+
file.name, 'replace_to data is greater than binary file'))
271334
return False
272335

273336
fill_data = bytearray([

0 commit comments

Comments
 (0)