@@ -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