node.js - 在这个 Node.js 反汇编程序库使用代码中,exampleRipHi 和 exampleRipLo 代表什么?
问题描述
// iced-x86 features needed: --features "decoder nasm"
const { Decoder, DecoderOptions, Formatter, FormatterSyntax } = require("iced-x86");
/*
This code produces the following output:
00007FFAC46ACDA4 48895C2410 mov [rsp+10h],rbx
00007FFAC46ACDA9 4889742418 mov [rsp+18h],rsi
00007FFAC46ACDAE 55 push rbp
00007FFAC46ACDAF 57 push rdi
00007FFAC46ACDB0 4156 push r14
00007FFAC46ACDB2 488DAC2400FFFFFF lea rbp,[rsp-100h]
00007FFAC46ACDBA 4881EC00020000 sub rsp,200h
00007FFAC46ACDC1 488B0518570A00 mov rax,[rel 7FFA`C475`24E0h]
00007FFAC46ACDC8 4833C4 xor rax,rsp
00007FFAC46ACDCB 488985F0000000 mov [rbp+0F0h],rax
00007FFAC46ACDD2 4C8B052F240A00 mov r8,[rel 7FFA`C474`F208h]
00007FFAC46ACDD9 488D05787C0400 lea rax,[rel 7FFA`C46F`4A58h]
00007FFAC46ACDE0 33FF xor edi,edi
*/
const exampleBitness = 64;
const exampleRipLo = 0xC46ACDA4;
const exampleRipHi = 0x00007FFA;
const exampleCode = new Uint8Array([
0x48, 0x89, 0x5C, 0x24, 0x10, 0x48, 0x89, 0x74, 0x24, 0x18, 0x55, 0x57, 0x41, 0x56, 0x48, 0x8D,
0xAC, 0x24, 0x00, 0xFF, 0xFF, 0xFF, 0x48, 0x81, 0xEC, 0x00, 0x02, 0x00, 0x00, 0x48, 0x8B, 0x05,
0x18, 0x57, 0x0A, 0x00, 0x48, 0x33, 0xC4, 0x48, 0x89, 0x85, 0xF0, 0x00, 0x00, 0x00, 0x4C, 0x8B,
0x05, 0x2F, 0x24, 0x0A, 0x00, 0x48, 0x8D, 0x05, 0x78, 0x7C, 0x04, 0x00, 0x33, 0xFF
]);
const hexBytesColumnByteLength = 10;
const decoder = new Decoder(exampleBitness, exampleCode, DecoderOptions.None);
// You have to enable the bigint feature to get i64/u64 APIs, not all browsers support BigInt
decoder.ipLo = exampleRipLo;
decoder.ipHi = exampleRipHi;
// This decodes all bytes. There's also `decode()` which decodes the next instruction,
// `decodeInstructions(count)` which decodes `count` instructions and `decodeOut(instruction)`
// which overwrites an existing instruction.
const instructions = decoder.decodeAll();
// Create a nasm formatter. It supports: Masm, Nasm, Gas (AT&T) and Intel (XED).
// There's also `FastFormatter` which uses less code (smaller wasm files).
// const formatter = new FastFormatter();
const formatter = new Formatter(FormatterSyntax.Nasm);
// Change some options, there are many more
formatter.digitSeparator = "`";
formatter.firstOperandCharIndex = 10;
// Format the instructions
instructions.forEach(instruction => {
const disasm = formatter.format(instruction);
// Eg. "00007FFAC46ACDB2 488DAC2400FFFFFF lea rbp,[rsp-100h]"
let line = ("0000000" + instruction.ipHi.toString(16)).substr(-8).toUpperCase() +
("0000000" + instruction.ipLo.toString(16)).substr(-8).toUpperCase();
line += " ";
const startIndex = instruction.ipLo - exampleRipLo;
exampleCode.slice(startIndex, startIndex + instruction.length).forEach(b => {
line += ("0" + b.toString(16)).substr(-2).toUpperCase();
});
for (let i = instruction.length; i < hexBytesColumnByteLength; i++)
line += " ";
line += " ";
line += disasm;
console.log(line);
});
我正在学习 Assembly 作为以前的 Web 开发人员(因此修补了反汇编程序 Node.js 库)并阅读了Intel x86 架构开发人员手册,但不知何故,我不认识此处使用的变量的术语或目的/含义:
const exampleRipLo = 0xC46ACDA4;
const exampleRipHi = 0x00007FFA;
它们代表什么,我应该如何决定使用哪些值?
解决方案
RIP 是 x86-64 上的 64 位程序计数器。反汇编程序使用 RIP 来跟踪每条指令的地址。
exampleRip
是 的起始地址exampleCode
,显示为每条指令的地址。
通常您会为此使用单个 64 位整数变量,但 JavaScript 数字是 IEEEdouble
浮点数,因此它们会将大数四舍五入为 2 的某个幂的倍数,即舍入大数字的低位,使其无法用于内核地址(在规范地址范围的高半部分)。(awk 也使用double
, 和https://unix.stackexchange.com/questions/649013/why-does-awk-print-0xffffffffbb6002e0-as-ffffffffbb600000-using-printf on unix.SE 就是一个例子,用 FP解释。)
这就是这条评论的重点:
// 您必须启用 bigint 功能才能获得 i64/u64 API,并非所有浏览器都支持 BigInt
他们解释说他们没有使用 BigInt 功能,因此他们使用两个变量(exampleRipHi 和 exampleRipLo)来实现一个 64 位变量。
const exampleRipLo = 0xC46ACDA4;
const exampleRipHi = 0x00007FFA;
那是JS版本的uint64_t exampleRip = 0x00007FFAC46ACDA4
推荐阅读
- d3.js - 在没有 div 的 D3.js 中将 HTML 文本框锚定到 SVG
- .net-core - 所有 .Net Core 控制台输出都写入系统日志?
- pg-promise - Pg-promise - 如何将二进制数据直接流式传输到响应
- r - 如何在 R 中创建查找?
- go - Go Profiling - 错误的文件
- javascript - 获取 datalist 输入的值,使用 v-model 清除 datalist
- ios - 将循环视频同步到自定义音频
- javascript - 如何在 vanilla JS 的一个变量中声明一系列字段
- reactjs - React/Redux - 将变量传递给动作
- nginx - Nginx 入口控制器 websocket 支持