如何解决在这个 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,0x74,0x18,0x55,0x57,0x41,0x56,0x8D,0xAC,0x00,0xFF,0x81,0xEC,0x02,0x8B,0x05,0x0A,0x33,0xC4,0x85,0xF0,0x4C,0x2F,0x78,0x7C,0x04,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 Architecture Developer Manual 并且不知何故我不认识这里使用的变量的术语或目的/含义:
const exampleRipLo = 0xC46ACDA4;
const exampleRipHi = 0x00007FFA;
它们代表什么,我应该如何决定使用哪些值?
解决方法
RIP 是 x86-64 上的 64 位程序计数器。反汇编器使用 RIP 来跟踪每条指令的地址。
exampleRip
是 exampleCode
的起始地址,显示为每条指令的地址。
通常您会为此使用单个 64 位整数变量,但 JavaScript 数字是 IEEE double
浮点数,因此它们会将大数四舍五入为 2 的某个幂的倍数,即四舍五入低位大数字,使其无法用于内核地址(在规范地址范围的高半部分)。 (awk 也用了 double
,unix.SE 上的 https://unix.stackexchange.com/questions/649013/why-does-awk-print-0xffffffffbb6002e0-as-ffffffffbb600000-using-printf 就是效果的例子,有 FP 解释。)
这就是这条评论的重点:
// 需要开启 bigint 特性才能获取 i64/u64 API,并非所有浏览器都支持 BigInt
他们解释说他们没有使用 BigInt 功能,因此他们使用两个变量(exampleRipHi 和 exampleRipLo)来实现一个 64 位变量。
const exampleRipLo = 0xC46ACDA4;
const exampleRipHi = 0x00007FFA;
那是 uint64_t exampleRip = 0x00007FFAC46ACDA4
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。