Open wowshy opened 4 months ago
Also consider using a python C extension module for the version detector instead of a pre-compiled binary so it's compatible with all operating systems. Or hashing the existing ~232 v8 versions directly in python (here's how I did it: https://github.com/j4k0xb/v8-version-analyzer/blob/2d36fc52d488f3913c0d9bba6db47126bba8ad7c/assets/analyzer.js)
Hi @wowshy, I will upload the patches for the V8 project in the coming days to replicate it for more versions. In the meantime, you might find it helpful to familiarize yourself with the process of compiling the V8 project. Here are some useful links for Windows:
https://gist.github.com/jhalon/5cbaab99dccadbf8e783921358020159 https://medium.com/angular-in-depth/how-to-build-v8-on-windows-and-not-go-mad-6347c69aacd4
Also, note that very similar versions can be used with the same disassembler by using the --path argument to the similar version.
The reason the disassembler binaries are not kept in the BIN folder alongside VersionDetector.exe is to avoid the need to download unnecessary files with each clone (potentially adding more and more disassembler versions).
@j4k0xb Thank you for the advice. I'll consider changing it according to your suggestion.
Hi @wowshy, I will upload the patches for the V8 project in the coming days to replicate it for more versions. In the meantime, you might find it helpful to familiarize yourself with the process of compiling the V8 project. Here are some useful links for Windows:
Hi wowshy, can you please upload the patch that you use?
No I do not have the patch. I came from this article https://research.checkpoint.com/2024/exploring-compiled-v8-javascript-usage-in-malware/
I will upload the patches for the V8 project in the coming days to replicate it for more versions
Hey, any news on this? I tried replicating it with https://github.com/v8/v8/tree/11.3.244.8 and https://github.com/noelex/v8dasm but it fails to deserialize the .jsc file (kMagicNumber mismatch despite being the same version). Even when compiling v8 straight from https://github.com/nodejs/node/tree/v20.10.0/deps/v8
v8 patch to enable disassembling:
diff --git a/src/diagnostics/objects-printer.cc b/src/diagnostics/objects-printer.cc
index 30d8095f62a..da51919111c 100644
--- a/src/diagnostics/objects-printer.cc
+++ b/src/diagnostics/objects-printer.cc
@@ -1843,6 +1843,13 @@ void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) {
} else {
os << "<none>";
}
+
+ os << "\n; #region SharedFunctionInfoDisassembly\n";
+ if (this->HasBytecodeArray()) {
+ this->GetBytecodeArray(isolate).Disassemble(os);
+ os << std::flush;
+ }
+ os << "; #endregion";
os << "\n";
}
diff --git a/src/objects/objects.cc b/src/objects/objects.cc
index 43ea4a73502..8452d5ef404 100644
--- a/src/objects/objects.cc
+++ b/src/objects/objects.cc
@@ -1828,6 +1828,8 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) {
os << accumulator.ToCString().get();
return;
}
+
+ size_t len;
switch (map(cage_base).instance_type()) {
case MAP_TYPE: {
os << "<Map";
@@ -1913,11 +1915,27 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) {
<< "]>";
break;
case FIXED_ARRAY_TYPE:
- os << "<FixedArray[" << FixedArray::cast(*this).length() << "]>";
+ len = FixedArray::cast(*this).length();
+ os << "<FixedArray[" << len << "]>";
+
+ if (len) {
+ os << "\nStart FixedArray\n";
+ FixedArray::cast(*this).FixedArrayPrint(os);
+ os << "End FixedArray";
+ }
+
break;
case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
- os << "<ObjectBoilerplateDescription[" << FixedArray::cast(*this).length()
- << "]>";
+ len = FixedArray::cast(*this).length();
+ os << "<ObjectBoilerplateDescription[" << len << "]>";
+
+ if (len) {
+ os << "\nStart ObjectBoilerplateDescription\n";
+ ObjectBoilerplateDescription::cast(*this).
+ ObjectBoilerplateDescriptionPrint(os);
+ os << "End ObjectBoilerplateDescription";
+ }
+
break;
case FIXED_DOUBLE_ARRAY_TYPE:
os << "<FixedDoubleArray[" << FixedDoubleArray::cast(*this).length()
diff --git a/src/snapshot/code-serializer.cc b/src/snapshot/code-serializer.cc
index c83e8e4581a..2b36d1e5504 100644
--- a/src/snapshot/code-serializer.cc
+++ b/src/snapshot/code-serializer.cc
@@ -447,6 +447,11 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
return MaybeHandle<SharedFunctionInfo>();
}
+ std::cout << "Start SharedFunctionInfo\n";
+ result->GetBytecodeArray(isolate).Disassemble(std::cout);
+ std::cout << "End SharedFunctionInfo\n";
+ std::cout << std::flush;
+
// Check whether the newly deserialized data should be merged into an
// existing Script from the Isolate compilation cache. If so, perform
// the merge in a single-threaded manner since this deserialization was
disassembler:
#include <fstream>
#include <iostream>
#include <string>
#include "include/libplatform/libplatform.h"
#include "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")
static v8::Isolate* isolate = nullptr;
static v8::ScriptCompiler::CachedData* compileCode(const char* data) {
auto str = v8::String::NewFromUtf8(isolate, data).ToLocalChecked();
auto script =
v8::Script::Compile(isolate->GetCurrentContext(), str).ToLocalChecked();
auto unboundScript = script->GetUnboundScript();
return v8::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 v8::ScriptCompiler::CachedData(bytecodeBuffer, len);
// Create dummy source.
v8::ScriptOrigin origin(isolate,
v8::String::NewFromUtf8Literal(isolate, "code.jsc"));
v8::ScriptCompiler::Source source(
v8::String::NewFromUtf8(isolate, code).ToLocalChecked(), origin,
cached_data);
// Compile code from code cache to print disassembly.
v8::MaybeLocal<v8::UnboundScript> v8_script =
v8::ScriptCompiler::CompileUnboundScript(
isolate, &source, v8::ScriptCompiler::kConsumeCodeCache);
}
static void readAllBytes(const std::string& file, std::vector<char>& buffer) {
std::ifstream infile(file, std::ios::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 --profile_deserialization");
v8::V8::InitializeICU();
auto platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator =
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope scope(isolate);
auto ctx = v8::Context::New(isolate);
v8::Context::Scope context_scope(ctx);
std::vector<char> data;
readAllBytes(argv[1], data);
runBytecode((uint8_t*)data.data(), data.size());
}
}
args.gn:
dcheck_always_on = false
is_component_build = false
is_debug = false
target_cpu = "x64"
use_custom_libcxx = false
v8_monolithic = true
v8_use_external_startup_data = false
v8_static_library = true
v8_enable_disassembler = true
v8_enable_object_print = true
@j4k0xb maybe the result of your disassembler different with the pre-built disassembler. Did you test it? (just do disassembler)
@j4k0xb the patch will not work on the version you mentioned 11.3.244.8 as the code has changed
the patch will not work on the version you mentioned 11.3.244.8 as the code has changed
I already adapted it to that version. Got it working now by using the flags that node uses when building (pointer compression had to be disabled):
dcheck_always_on = false
is_component_build = false
is_debug = false
target_cpu = "x64"
use_custom_libcxx = false
v8_monolithic = true
v8_use_external_startup_data = false
v8_static_library = true
v8_enable_disassembler = true
v8_enable_object_print = true
v8_enable_pointer_compression = false
Updated patch:
diff --git a/src/objects/code.cc b/src/objects/code.cc
index 1ca28beb309..823ea11f311 100644
--- a/src/objects/code.cc
+++ b/src/objects/code.cc
@@ -779,6 +779,8 @@ void BytecodeArray::Disassemble(Handle<BytecodeArray> handle,
iterator.Advance();
}
+ os << AsHex::Address(handle->address()) << ": [SharedFunctionInfo] in idk\n";
+
os << "Constant pool (size = " << handle->constant_pool().length() << ")\n";
#ifdef OBJECT_PRINT
if (handle->constant_pool().length() > 0) {
diff --git a/src/objects/objects.cc b/src/objects/objects.cc
index 43ea4a73502..2850dbbfef3 100644
--- a/src/objects/objects.cc
+++ b/src/objects/objects.cc
@@ -1828,6 +1828,8 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) {
os << accumulator.ToCString().get();
return;
}
+
+ size_t len;
switch (map(cage_base).instance_type()) {
case MAP_TYPE: {
os << "<Map";
@@ -1913,11 +1915,27 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) {
<< "]>";
break;
case FIXED_ARRAY_TYPE:
- os << "<FixedArray[" << FixedArray::cast(*this).length() << "]>";
+ len = FixedArray::cast(*this).length();
+ os << "<FixedArray[" << len << "]>";
+
+ if (len) {
+ os << "\nStart FixedArray\n";
+ FixedArray::cast(*this).FixedArrayPrint(os);
+ os << "End FixedArray";
+ }
+
break;
case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
- os << "<ObjectBoilerplateDescription[" << FixedArray::cast(*this).length()
- << "]>";
+ len = FixedArray::cast(*this).length();
+ os << "<ObjectBoilerplateDescription[" << len << "]>";
+
+ if (len) {
+ os << "\nStart ObjectBoilerplateDescription\n";
+ ObjectBoilerplateDescription::cast(*this).
+ ObjectBoilerplateDescriptionPrint(os);
+ os << "End ObjectBoilerplateDescription";
+ }
+
break;
case FIXED_DOUBLE_ARRAY_TYPE:
os << "<FixedDoubleArray[" << FixedDoubleArray::cast(*this).length()
@@ -2000,6 +2018,12 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) {
} else {
os << "<SharedFunctionInfo>";
}
+ Isolate* isolate;
+ if (GetIsolateFromHeapObject(shared, &isolate)) {
+ os << "\nStart SharedFunctionInfo\n";
+ shared.GetBytecodeArray(isolate).Disassemble(os);
+ os << "End SharedFunctionInfo\n";
+ }
break;
}
case JS_MESSAGE_OBJECT_TYPE:
diff --git a/src/snapshot/code-serializer.cc b/src/snapshot/code-serializer.cc
index c83e8e4581a..2b36d1e5504 100644
--- a/src/snapshot/code-serializer.cc
+++ b/src/snapshot/code-serializer.cc
@@ -447,6 +447,11 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
return MaybeHandle<SharedFunctionInfo>();
}
+ std::cout << "Start SharedFunctionInfo\n";
+ result->GetBytecodeArray(isolate).Disassemble(std::cout);
+ std::cout << "End SharedFunctionInfo\n";
+ std::cout << std::flush;
+
// Check whether the newly deserialized data should be merged into an
// existing Script from the Isolate compilation cache. If so, perform
// the merge in a single-threaded manner since this deserialization was
g++ -g -I. -Iinclude v8dasm.cpp -o v8dasm -fno-rtti -lv8_monolith -lv8_libbase -lv8_libplatform -ldl -Lout.gn/x64.release/obj/ -pthread -std=c++17
./v8dasm index.jsc
Start SharedFunctionInfo
Parameter count 1
Register count 1
Frame size 8
Bytecode age: 0
0 S> 0xf3b449e4dbe @ 0 : 80 00 00 00 CreateClosure [0], [0], #0
0xf3b449e4dc2 @ 4 : c4 Star0
272 S> 0xf3b449e4dc3 @ 5 : a9 Return
0x0f3b449e4d88: [SharedFunctionInfo] in idk
Constant pool (size = 1)
0xf3b449e4dc9: [FixedArray] in OldSpace
- map: 0x12d91b5c0211 <Map(FIXED_ARRAY_TYPE)>
- length: 1
0: 0x0f3b449e4de1 <SharedFunctionInfo>
Start SharedFunctionInfo
Parameter count 6
Register count 7
Frame size 56
Bytecode age: 0
10 E> 0xf3b449e4e4e @ 0 : 83 00 01 CreateFunctionContext [0], [1]
0xf3b449e4e51 @ 3 : 1a f8 PushContext r2
0xf3b449e4e53 @ 5 : 10 LdaTheHole
0xf3b449e4e54 @ 6 : 25 02 StaCurrentContextSlot [2]
78 S> 0xf3b449e4e56 @ 8 : 13 01 LdaConstant [1]
0xf3b449e4e58 @ 10 : c0 Star4
78 E> 0xf3b449e4e59 @ 11 : 62 04 f6 00 CallUndefinedReceiver1 a1, r4, [0]
0xf3b449e4e5d @ 15 : c4 Star0
109 S> 0xf3b449e4e5e @ 16 : 61 fa 02 CallUndefinedReceiver0 r0, [2]
0xf3b449e4e61 @ 19 : c3 Star1
132 S> 0xf3b449e4e62 @ 20 : 00 0d b8 0b LdaSmi.Wide [3000]
132 E> 0xf3b449e4e66 @ 24 : 25 02 StaCurrentContextSlot [2]
142 S> 0xf3b449e4e68 @ 26 : 2d f9 02 04 GetNamedProperty r1, [2], [4]
0xf3b449e4e6c @ 30 : c1 Star3
0xf3b449e4e6d @ 31 : 13 03 LdaConstant [3]
0xf3b449e4e6f @ 33 : bf Star5
0xf3b449e4e70 @ 34 : 80 04 00 02 CreateClosure [4], [0], #2
0xf3b449e4e74 @ 38 : be Star6
142 E> 0xf3b449e4e75 @ 39 : 5f f7 f9 f5 f4 06 CallProperty2 r3, r1, r5, r6, [6]
195 S> 0xf3b449e4e7b @ 45 : 2d f9 05 08 GetNamedProperty r1, [5], [8]
0xf3b449e4e7f @ 49 : c1 Star3
0xf3b449e4e80 @ 50 : 17 02 LdaImmutableCurrentContextSlot [2]
0xf3b449e4e82 @ 52 : bf Star5
202 E> 0xf3b449e4e83 @ 53 : 80 06 01 02 CreateClosure [6], [1], #2
0xf3b449e4e87 @ 57 : be Star6
195 E> 0xf3b449e4e88 @ 58 : 5f f7 f9 f5 f4 0a CallProperty2 r3, r1, r5, r6, [10]
0xf3b449e4e8e @ 64 : 0e LdaUndefined
269 S> 0xf3b449e4e8f @ 65 : a9 Return
0x0f3b449e4e18: [SharedFunctionInfo] in idk
Constant pool (size = 7)
0xf3b449e4e91: [FixedArray] in OldSpace
- map: 0x12d91b5c0211 <Map(FIXED_ARRAY_TYPE)>
- length: 7
0: 0x0f3b449e4ed9 <ScopeInfo FUNCTION_SCOPE>
1: 0x0f3b449e4f49 <String[7]: #express>
2: 0x12d91b5c63d1 <String[3]: #get>
3: 0x12d91b5c31e9 <String[1]: #/>
4: 0x0f3b449e4f61 <SharedFunctionInfo>
Start SharedFunctionInfo
Parameter count 3
Register count 3
Frame size 24
Bytecode age: 0
169 S> 0xf3b449e4fce @ 0 : 2d 04 00 00 GetNamedProperty a1, [0], [0]
0xf3b449e4fd2 @ 4 : c4 Star0
0xf3b449e4fd3 @ 5 : 13 01 LdaConstant [1]
0xf3b449e4fd5 @ 7 : c2 Star2
169 E> 0xf3b449e4fd6 @ 8 : 5e fa 04 f8 02 CallProperty1 r0, a1, r2, [2]
189 S> 0xf3b449e4fdb @ 13 : a9 Return
0x0f3b449e4f98: [SharedFunctionInfo] in idk
Constant pool (size = 2)
0xf3b449e4fe1: [FixedArray] in OldSpace
- map: 0x12d91b5c0211 <Map(FIXED_ARRAY_TYPE)>
- length: 2
0: 0x0f3b449e5001 <String[4]: #send>
1: 0x0f3b449e5019 <String[12]: #Hello World!>
Handler Table (size = 0)
Source Position Table (size = 9)
0x0f3b449e5039 <ByteArray[9]>
End SharedFunctionInfo
5: 0x0f3b449e5349 <String[6]: #listen>
6: 0x0f3b449e51b1 <SharedFunctionInfo>
Start SharedFunctionInfo
Parameter count 1
Register count 3
Frame size 24
Bytecode age: 0
222 S> 0xf3b449e521e @ 0 : 21 00 00 LdaGlobal [0], [0]
0xf3b449e5221 @ 3 : c3 Star1
222 E> 0xf3b449e5222 @ 4 : 2d f9 01 02 GetNamedProperty r1, [1], [2]
0xf3b449e5226 @ 8 : c4 Star0
0xf3b449e5227 @ 9 : 13 02 LdaConstant [2]
0xf3b449e5229 @ 11 : c2 Star2
0xf3b449e522a @ 12 : 17 02 LdaImmutableCurrentContextSlot [2]
259 E> 0xf3b449e522c @ 14 : aa 03 ThrowReferenceErrorIfHole [3]
0xf3b449e522e @ 16 : 77 ToString
0xf3b449e522f @ 17 : 38 f8 04 Add r2, [4]
0xf3b449e5232 @ 20 : c2 Star2
0xf3b449e5233 @ 21 : 13 04 LdaConstant [4]
0xf3b449e5235 @ 23 : 38 f8 04 Add r2, [4]
0xf3b449e5238 @ 26 : c2 Star2
222 E> 0xf3b449e5239 @ 27 : 5e fa f9 f8 05 CallProperty1 r0, r1, r2, [5]
267 S> 0xf3b449e523e @ 32 : a9 Return
0x0f3b449e51e8: [SharedFunctionInfo] in idk
Constant pool (size = 5)
0xf3b449e5241: [FixedArray] in OldSpace
- map: 0x12d91b5c0211 <Map(FIXED_ARRAY_TYPE)>
- length: 5
0: 0x12d91b5c5ce9 <String[7]: #console>
1: 0x20a936c419b1 <String[3]: #log>
2: 0x0f3b449e5291 <String[30]: #Example app listening on port >
3: 0x0f3b449e4f31 <String[4]: #port>
4: 0x12d91b5c3099 <String[1]: #!>
Handler Table (size = 0)
Source Position Table (size = 16)
0x0f3b449e52c1 <ByteArray[16]>
End SharedFunctionInfo
Handler Table (size = 0)
Source Position Table (size = 29)
0x0f3b449e5361 <ByteArray[29]>
End SharedFunctionInfo
Handler Table (size = 0)
Source Position Table (size = 7)
0x0f3b449e53a9 <ByteArray[7]>
End SharedFunctionInfo
After copying v8dasm to Bin/11.3.244.8
it can be used for decompiling:
python view8.py index.jsc out
function func_start_0x0c0502224d88()
{
r0 = func_unknown_0x0c0502224e18
return func_unknown_0x0c0502224e18
}
function func_unknown_0x0c0502224e18(a0, a1, a2, a3, a4)
{
r2 = Scope[0]
Scope[1][2] = null
r0 = a1("express")
r1 = r0()
Scope[1][2] = 3000
ACCU = r1["get"]("/", func_unknown_0x0c0502224f98)
ACCU = r1["listen"](Scope[1][2], func_unknown_0x0c05022251e8)
return undefined
}
function func_unknown_0x0c05022251e8()
{
r2 = ("Example app listening on port" + String(Scope[1][2]))
r2 = (r2 + "!")
return "console"["log"](r2)
}
function func_unknown_0x0c0502224f98(a0, a1)
{
return a1["send"]("Hello World!")
}
@j4k0xb have a look at the d8 code as that prints out everything. What version are you trying??
@j4k0xb Added 2 more patches: 1) Disabling the Sanit check 2) Support for FixedDoubleArray
diff --git a/orig/code-serializer.cc b/patch/code-serializer.cc
index c83e8e4..bf7555b 100644
--- a/orig/code-serializer.cc
+++ b/patch/code-serializer.cc
@@ -427,14 +427,14 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
const SerializedCodeData scd = SerializedCodeData::FromCachedData(
cached_data, SerializedCodeData::SourceHash(source, origin_options),
&sanity_check_result);
- if (sanity_check_result != SerializedCodeSanityCheckResult::kSuccess) {
+ /*if (sanity_check_result != SerializedCodeSanityCheckResult::kSuccess) {
if (v8_flags.profile_deserialization)
PrintF("[Cached code failed check]\n");
DCHECK(cached_data->rejected());
isolate->counters()->code_cache_reject_reason()->AddSample(
static_cast<int>(sanity_check_result));
return MaybeHandle<SharedFunctionInfo>();
- }
+ }*/
// Deserialize.
MaybeHandle<SharedFunctionInfo> maybe_result =
@@ -446,6 +446,12 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
if (v8_flags.profile_deserialization) PrintF("[Deserializing failed]\n");
return MaybeHandle<SharedFunctionInfo>();
}
+ // add patch
+ std::cout << "\nStart SharedFunctionInfo\n";
+ result->GetBytecodeArray(isolate).Disassemble(std::cout);
+ std::cout << "\nEnd SharedFunctionInfo\n";
+ std::cout << std::flush;
+ // end patch
// Check whether the newly deserialized data should be merged into an
// existing Script from the Isolate compilation cache. If so, perform
@@ -735,10 +741,10 @@ SerializedCodeData SerializedCodeData::FromCachedData(
DisallowGarbageCollection no_gc;
SerializedCodeData scd(cached_data);
*rejection_result = scd.SanityCheck(expected_source_hash);
- if (*rejection_result != SerializedCodeSanityCheckResult::kSuccess) {
+ /*if (*rejection_result != SerializedCodeSanityCheckResult::kSuccess) {
cached_data->Reject();
return SerializedCodeData(nullptr, 0);
- }
+ }*/
return scd;
}
diff --git a/orig/objects-printer.cc b/patch/objects-printer.cc
index 30d8095..28f5742 100644
--- a/orig/objects-printer.cc
+++ b/patch/objects-printer.cc
@@ -1821,7 +1821,7 @@ void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) {
} else {
os << "<unavailable>";
}
- PrintSourceCode(os);
+ //PrintSourceCode(os);
// Script files are often large, thus only print their {Brief} representation.
os << "\n - script: " << Brief(script());
os << "\n - function token position: " << function_token_position();
@@ -1844,6 +1844,13 @@ void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) {
os << "<none>";
}
os << "\n";
+ // add patch
+ os << "\nStart BytecodeArray\n";
+ this->GetBytecodeArray(isolate).Disassemble(os);
+ os << "\nEnd BytecodeArray\n";
+ os << std::flush;
+ // end patch
}
void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) {
diff --git a/orig/objects.cc b/patch/objects.cc
index 43ea4a7..89e8453 100644
--- a/orig/objects.cc
+++ b/patch/objects.cc
@@ -1914,15 +1914,33 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) {
break;
case FIXED_ARRAY_TYPE:
os << "<FixedArray[" << FixedArray::cast(*this).length() << "]>";
- break;
+ // add patch
+ os << "\nStart FixedArray\n";
+ FixedArray::cast(*this).FixedArrayPrint(os);
+ os << "\nEnd FixedArray\n";
+ os << std::flush;
+ // end patch
+ break;
case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
os << "<ObjectBoilerplateDescription[" << FixedArray::cast(*this).length()
<< "]>";
- break;
+ // add patch
+ os << "\nStart ObjectBoilerplateDescription\n";
+ ObjectBoilerplateDescription::cast(*this).ObjectBoilerplateDescriptionPrint(os);
+ os << "\nEnd ObjectBoilerplateDescription\n";
+ os << std::flush;
+ // end patch
+ break;
case FIXED_DOUBLE_ARRAY_TYPE:
os << "<FixedDoubleArray[" << FixedDoubleArray::cast(*this).length()
<< "]>";
- break;
+ // add patch
+ os << "\nStart FixedDoubleArray\n";
+ FixedDoubleArray::cast(*this).FixedDoubleArrayPrint(os);
+ os << "\nEnd FixedDoubleArray\n";
+ os << std::flush;
+ // end patch
+ break;
case BYTE_ARRAY_TYPE:
os << "<ByteArray[" << ByteArray::cast(*this).length() << "]>";
break;
@@ -2000,6 +2018,12 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) {
} else {
os << "<SharedFunctionInfo>";
}
+ // add patch
+ os << "\nStart SharedFunctionInfo\n";
+ shared.SharedFunctionInfoPrint(os);
+ os << "\nEnd SharedFunctionInfo\n";
+ os << std::flush;
+ // end patch
break;
}
case JS_MESSAGE_OBJECT_TYPE:
but it fails to deserialize the .jsc file (kMagicNumber mismatch despite being the same version).
This issue may be due to an x86-x64 mismatch (SharedFunctionInfo size). In my experience, manually changing the magic can resolve the problem.
I found the version of my program is: 10.6.194.27-electron.0, but I can't find corresponding v8 tag, please help.
I found the version of my program is: 10.6.194.27-electron.0, but I can't find corresponding v8 tag
Electron patches the v8 source and edited the version, 10.6.194.26 should work Maybe one of the disassemblers in https://github.com/suleram/View8/releases/tag/v1.0 work as well
I tried all but may be the version hash check was too strictly, so it failed on the version hash check. Any way, thank for your recommendation. I will build the 10.6.194.26 and try again.
@suleram Which patches are required in order to use v8 binary with this tool? Can you write a short instruction on how to apply these patches, at which stage? Should we apply them before compiling v8?
Can you also post a guide on how to use custom v8 version with this tool? I think I got it, you have to patch and build v8 for windows and then use the resulting exe file with your python tool, but it would be nice to get confirmation from you that I got that right
Hi @suleram Can you build a patched binary for 9.1.269.40 version? I already tried with the existents bin, but not works. Thanks in advance.
How is the executable generated?
Can you guys share and track the patch in Git too? I would really appreciate it if the compilation process were fully reproducible.
Also, why not keep the disassembler binary under https://github.com/suleram/View8/tree/main/Bin with
VersionDetector.exe
, instead of manually attaching a disassembler binary to the releases every time?