From 7263fadd7f2a7f09a81d634a631eaac913185cf1 Mon Sep 17 00:00:00 2001 From: Igor Klopov Date: Sat, 27 May 2017 20:45:48 +0300 Subject: [PATCH] boundary-less payload for 0.12.18 --- patches/node.v0.12.18.patch | 101 +++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 49 deletions(-) diff --git a/patches/node.v0.12.18.patch b/patches/node.v0.12.18.patch index 41316422..86e481e4 100644 --- a/patches/node.v0.12.18.patch +++ b/patches/node.v0.12.18.patch @@ -201,7 +201,7 @@ --- node/src/node.js +++ node/src/node.js -@@ -65,10 +65,55 @@ +@@ -65,10 +65,57 @@ // There are various modes that Node can run in. The most common two // are running from a script and running the REPL - but there are a few // others like the debugger or running --eval arguments. Here we decide @@ -211,12 +211,14 @@ + var fs = NativeModule.require('fs'); + var vm = NativeModule.require('vm'); + function readPrelude (fd) { ++ var PAYLOAD_POSITION = process.env.PKG_PAYLOAD_POSITION | 0; ++ var PAYLOAD_SIZE = process.env.PKG_PAYLOAD_SIZE | 0; + var PRELUDE_POSITION = process.env.PKG_PRELUDE_POSITION | 0; + var PRELUDE_SIZE = process.env.PKG_PRELUDE_SIZE | 0; -+ var PAYLOAD_POSITION = process.env.PKG_PAYLOAD_POSITION | 0; ++ delete process.env.PKG_PAYLOAD_POSITION; ++ delete process.env.PKG_PAYLOAD_SIZE; + delete process.env.PKG_PRELUDE_POSITION; + delete process.env.PKG_PRELUDE_SIZE; -+ delete process.env.PKG_PAYLOAD_POSITION; + if (!PRELUDE_POSITION) { + // no prelude - remove entrypoint from argv[1] + process.argv.splice(1, 1); @@ -235,8 +237,8 @@ + } + var s = new vm.Script(prelude, { filename: 'pkg/prelude/bootstrap.js' }); + var fn = s.runInThisContext(); -+ return fn(process, NativeModule.require, console, fd, -+ PAYLOAD_POSITION, PRELUDE_POSITION - PAYLOAD_POSITION - 16); ++ return fn(process, NativeModule.require, ++ console, fd, PAYLOAD_POSITION, PAYLOAD_SIZE); + } + (function () { + var fd = fs.openSync(process.execPath, 'r'); @@ -333,7 +335,7 @@ TryCatch& try_catch) { --- node/src/node_main.cc +++ node/src/node_main.cc -@@ -19,10 +19,291 @@ +@@ -19,10 +19,292 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -342,8 +344,6 @@ +#include +#include "uv.h" + -+#define BOUNDARY 4096 -+ +uint16_t read16(uint8_t* buffer, uint32_t pos) { + buffer = &buffer[pos]; + uint16_t* buffer16 = (uint16_t*) buffer; @@ -441,38 +441,30 @@ + exit(1); +} + -+bool GetSentryPosition(FILE* file, int start, uint32_t s1, ++bool FindNextBlock(FILE* file, int start, uint32_t s1, + uint32_t s12, uint32_t s3, int* pposition, int* psize +) { + int read; -+ uint32_t sentry, length; ++ uint8_t probe[4096]; ++ uint32_t* psentry; + + if (fseek(file, start, SEEK_SET) != 0) return false; -+ -+ while (true) { -+ read = static_cast(fread(&sentry, 1, sizeof(sentry), file)); -+ if (read != sizeof(sentry)) return false; -+ if (sentry != s1) { -+ fseek(file, BOUNDARY - 4, SEEK_CUR); -+ continue; -+ } -+ fread(&length, 1, sizeof(length), file); -+ if ((sentry^length) != s12) { -+ fseek(file, BOUNDARY - 8, SEEK_CUR); -+ continue; -+ } -+ fread(&sentry, 1, sizeof(sentry), file); -+ if (sentry != s3) { -+ fseek(file, BOUNDARY - 12, SEEK_CUR); -+ continue; -+ } -+ break; ++ read = static_cast(fread(&probe, 1, sizeof(probe), file)); ++ ++ for (int i = 0; i < read - 16; i += 1) { ++ psentry = (uint32_t*) (probe + i); ++ if (*psentry != s1) continue; ++ psentry += 1; ++ if (((*psentry)^s1) != s12) continue; ++ psentry += 1; ++ if (*psentry != s3) continue; ++ psentry += 1; ++ *pposition = start + i + 16; ++ *psize = *psentry; ++ return true; + } + -+ fread(&length, 1, sizeof(length), file); -+ *pposition = ftell(file); -+ *psize = static_cast(length); -+ return true; ++ return false; +} + + @@ -507,39 +499,50 @@ + exit(1); + } + -+ char env[64]; -+ int position = (FindMeatEnd(file) / BOUNDARY) * BOUNDARY; int size; ++ int position = FindMeatEnd(file); ++ int size; + char* bakery = NULL; ++ char env[64]; + -+ if (GetSentryPosition(file, position, 0x4818c4df, ++ if (FindNextBlock(file, position, 0x4818c4df, + 0x32dbc2af, 0x56558a76, &position, &size) + ) { -+ bakery = static_cast(malloc(size)); -+ int read; -+ -+ for (int i = 0; i < size;) { -+ read = static_cast(fread(&bakery[i], 1, size - i, file)); -+ if (ferror(file) != 0) { ++ if (size) { ++ if (fseek(file, position, SEEK_SET) != 0) { + fprintf(stderr, "Pkg: Error reading from file.\n"); + fclose(file); + exit(1); + } -+ i += read; -+ } + -+ position -= 16; // align back to boundary ++ bakery = static_cast(malloc(size)); ++ int read; ++ ++ for (int i = 0; i < size;) { ++ read = static_cast(fread(&bakery[i], 1, size - i, file)); ++ if (ferror(file) != 0) { ++ fprintf(stderr, "Pkg: Error reading from file.\n"); ++ fclose(file); ++ exit(1); ++ } ++ i += read; ++ } ++ ++ position += size; ++ } + } + -+ if (GetSentryPosition(file, position, 0x75148eba, ++ if (FindNextBlock(file, position, 0x75148eba, + 0x1aa9270e, 0x2e20c08d, &position, &size) + ) { + sprintf(env, "%d", position); + setenv("PKG_PAYLOAD_POSITION", env, 1); ++ sprintf(env, "%d", size); ++ setenv("PKG_PAYLOAD_SIZE", env, 1); + -+ position -= 16; // align back to boundary ++ position += size; + } + -+ if (GetSentryPosition(file, position, 0x26e0c928, ++ if (FindNextBlock(file, position, 0x26e0c928, + 0x6713e24e, 0x3ea13ccf, &position, &size) + ) { + sprintf(env, "%d", position); @@ -625,7 +628,7 @@ // Convert argv to to UTF8 char** argv = new char*[argc]; for (int i = 0; i < argc; i++) { -@@ -55,13 +336,13 @@ +@@ -55,13 +337,13 @@ fprintf(stderr, "Could not convert arguments to utf8."); exit(1); }