forked from suleram/View8
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathv8dasm_legacy.cpp
101 lines (80 loc) · 3.18 KB
/
v8dasm_legacy.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
// From https://github.com/noelex/v8dasm
#include <iostream>
#include <string>
#include <cmath>
#include <libplatform/libplatform.h>
#include <v8.h>
#pragma comment(lib, "v8_libbase.lib")
#pragma comment(lib, "v8_libplatform.lib")
#pragma comment(lib, "wee8.lib")
#pragma comment(lib, "secur32.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "dmoguids.lib")
#pragma comment(lib, "wmcodecdspuuid.lib")
#pragma comment(lib, "msdmo.lib")
#pragma comment(lib, "Strmiids.lib")
#pragma comment(lib, "DbgHelp.lib")
using namespace v8;
static Isolate *isolate = nullptr;
static v8::ScriptCompiler::CachedData *compileCode(const char *data) {
auto str = String::NewFromUtf8(isolate, data).ToLocalChecked();
auto script =
Script::Compile(isolate->GetCurrentContext(), str).ToLocalChecked();
auto unboundScript = script->GetUnboundScript();
return ScriptCompiler::CreateCodeCache(unboundScript);
}
static void fixBytecode(uint8_t *bytecodeBuffer, const char *code) {
auto dummyBytecode = compileCode(code);
// Copy version hash, source hash and flag hash from dummy bytecode to source
// bytecode. Offsets of these value may differ in different version of V8.
// Refer V8 src/snapshot/code-serializer.h for details.
for (int i = 4; i < 16; i++) {
bytecodeBuffer[i] = dummyBytecode->data[i];
}
delete dummyBytecode;
}
static void runBytecode(uint8_t *bytecodeBuffer, int len) {
// Compile some dummy code to get version hash, source hash and flag hash.
const char *code = "\"ಠ_ಠ\"";
fixBytecode(bytecodeBuffer, code);
// Load code into code cache.
auto cached_data = new ScriptCompiler::CachedData(bytecodeBuffer, len);
// Create dummy source.
ScriptOrigin origin(String::NewFromUtf8Literal(isolate, "code.jsc"));
ScriptCompiler::Source source(
String::NewFromUtf8(isolate, code).ToLocalChecked(), origin, cached_data);
// Compile code from code cache to print disassembly.
MaybeLocal<UnboundScript> v8_script = ScriptCompiler::CompileUnboundScript(
isolate, &source, ScriptCompiler::kConsumeCodeCache);
}
static void readAllBytes(const std::string &file, std::vector<char> &buffer) {
std::ifstream infile(file, std::ifstream::binary);
infile.seekg(0, infile.end);
size_t length = infile.tellg();
infile.seekg(0, infile.beg);
if (length > 0) {
buffer.resize(length);
infile.read(&buffer[0], length);
}
}
int main(int argc, char *argv[]) {
// Set flags here, flags that affects code generation and serialization
// should be same as the target program. You can add other flags freely
// because flag hash will be overriden in fixBytecode().
v8::V8::SetFlagsFromString("--no-lazy --no-flush-bytecode --log-all");
v8::V8::InitializeICU();
auto plat = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(plat.get());
v8::V8::Initialize();
Isolate::CreateParams p = {};
p.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
isolate = Isolate::New(p);
{
v8::HandleScope scope(isolate);
auto ctx = v8::Context::New(isolate);
Context::Scope context_scope(ctx);
std::vector<char> data;
readAllBytes(argv[1], data);
runBytecode((uint8_t *)data.data(), data.size());
}
}