Nodejs:换个问法,如何通过addon来调用 module._compile 方法

Nodejs:换个问法,如何通过addon来调用 module._compile 方法

我想直接在 addoncompile 代码,然后返回 exports。 主要用途是加密某些核心代码,通过内部解密并编译使用。使之不会被轻易的 toString() 出来 请问有高手尝试过吗

// Native extension for .js
Module._extensions['.js'] = function(module, filename) {
  var content = NativeModule.require('fs').readFileSync(filename, 'utf8');
  
  // 就是这行代码
  module._compile(stripBOM(content), filename);
};

3 回复

要通过 Node.js 的 C++ Addon 调用 module._compile 方法,你需要编写一个 C++ Addon 来实现这一功能。下面是一个简单的示例代码,展示如何通过 C++ Addon 调用 module._compile 方法。

示例代码

首先,我们需要创建一个 C++ Addon 文件,例如 addon.cc

#include <node.h>
#include <v8.h>
#include <string>

using namespace v8;

void CompileCode(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  HandleScope scope(isolate);

  // 获取传入的源代码字符串
  String::Utf8Value source_code(args[0]->ToString());
  std::string code(*source_code);

  // 获取文件名(这里可以自定义)
  String::Utf8Value file_name(args[1]->ToString());
  std::string filename(*file_name);

  // 获取 module 对象
  Local<Object> module_obj = args[2].As<Object>();

  // 获取 module._compile 方法
  Local<Function> compile_func = Local<Function>::Cast(module_obj->Get(String::NewFromUtf8(isolate, "_compile")));

  // 创建 arguments 列表
  Local<Value> argv[] = { String::NewFromUtf8(isolate, code.c_str()), String::NewFromUtf8(isolate, filename.c_str()) };

  // 调用 module._compile 方法
  compile_func->Call(isolate->GetCurrentContext()->Global(), 2, argv);
}

void Initialize(Local<Object> exports) {
  NODE_SET_METHOD(exports, "compileCode", CompileCode);
}

NODE_MODULE(addon, Initialize)

构建和使用 Addon

接下来,你需要构建这个 C++ Addon。假设你已经安装了 node-gyp,你可以通过以下命令来构建它:

node-gyp configure build

构建完成后,你可以在 Node.js 中加载和使用这个 Addon:

const addon = require('./build/Release/addon');

// 假设这是需要编译的加密代码
const encryptedCode = "console.log('Hello, world!');";

// 解密后的代码
const decryptedCode = decrypt(encryptedCode); // 你需要实现这个解密函数

// 创建一个模拟的 module 对象
const moduleObj = {
  _compile: function(code, filename) {
    console.log(`Compiled code: ${code}`);
  }
};

// 调用 C++ Addon 的方法来编译代码
addon.compileCode(decryptedCode, 'example.js', moduleObj);

解释

  1. C++ Addon:

    • CompileCode 函数接收三个参数:源代码、文件名和一个模拟的 module 对象。
    • 使用 moduleObj->Get 获取 _compile 方法,并调用它。
  2. JavaScript 代码:

    • 加载 C++ Addon 并传递解密后的代码、文件名和模拟的 module 对象。
    • 这样就可以在 Node.js 环境中调用 C++ Addon 编写的代码。

通过这种方式,你可以实现对核心代码的加密和动态编译,从而防止代码被轻易地 toString() 查看。


那就用 c++ 写呗

要在 Node.js 中通过 C++ Addon 调用 module._compile 方法,可以借助 Node.js 的 C++ API 来实现。下面将详细介绍如何编写一个简单的 addon,并调用 module._compile 方法。

示例代码

首先,你需要安装 Node.js 和相应的工具(如 node-gyp),以便构建 C++ 模块。

C++ Addon (addon.cc)

#include <node.h>
#include <v8.h>

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
using node::AtExit;

void CompileCode(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    
    if (args.Length() < 1 || !args[0]->IsString()) {
        isolate->ThrowException(v8::Exception::TypeError(
            String::NewFromUtf8(isolate, "Expected a string").ToChecked()));
        return;
    }

    Local<String> code = args[0].As<String>();
    Local<Object> module = Object::New(isolate);

    // 模拟 module 对象
    Local<Object> exports = Object::New(isolate);
    module->Set(String::NewFromUtf8(isolate, "exports"), exports);

    Local<String> filename = String::NewFromUtf8(isolate, "dummy.js").ToChecked();

    // 编译代码
    Module::CompileJavaScript(isolate, code, filename, nullptr, nullptr, nullptr, nullptr);
}

void Initialize(Local<Object> exports) {
    NODE_SET_METHOD(exports, "compile", CompileCode);
}

NODE_MODULE(addon, Initialize)

构建脚本 (binding.gyp)

{
  "targets": [
    {
      "target_name": "addon",
      "sources": [ "addon.cc" ]
    }
  ]
}

编译和使用

  1. 创建 binding.gyp 文件。
  2. 使用 node-gyp configure build 命令构建 addon。
  3. 在 Node.js 中加载并使用此 addon:
const addon = require('./build/Release/addon');

const encryptedCode = 'console.log("Hello, world!");'; // 实际中这部分应为解密后的代码
addon.compile(encryptedCode);

注意事项

  • 此代码仅作为示例,实际应用中需要处理更多的细节,例如错误处理、内存管理等。
  • Module::CompileJavaScript 是 Node.js 的内部函数,不建议在生产环境中使用。
  • 加密和解密逻辑需根据具体需求实现,以确保代码的安全性。

以上代码展示了如何通过 C++ Addon 调用 module._compile 方法,但这只是一个基本示例。实际应用中可能需要更多细节上的处理。

回到顶部