我有以下一段飞镖代码,它检查输入是否为“ABCDE”,如果输入匹配,则打印正确,并且工作正常。
import 'dart:io';
final List<int> flag = [65, 66, 67, 68, 69];
void main() {
print("\ngive flag: ");
List<int> input = stdin.readLineSync(encoding: latin1)!.codeUnits;
if (input.length != flag.length) {
print("\nnot flag");
return;
}
for (int i = 0; i < flag.length; i++) {
if (input[i] != flag[i]) {
print("\nnot flag");
return;
}
}
StringBuffer newFlag = new StringBuffer();
input.forEach((e) {
newFlag.writeCharCode(e);
});
print("correct");
}
我用dart compile aot-snapshot exmaple. dart
编译了代码,然后尝试用IDA和Ghidra反编译。但是,反编译后的代码中,原来的十进制值似乎翻了一番。
Ghidra反编译代码:
void flag(void)
{
long lVar1;
long extraout_RAX;
long unaff_R14;
if (&stack0xfffffffffffffff8 < *(undefined **)(ulong *)(unaff_R14 + 0x40) ||
&stack0xfffffffffffffff8 == *(undefined **)(ulong *)(unaff_R14 + 0x40)) {
(**(code **)(unaff_R14 + 0x238))();
}
lVar1 = Precompiled_Stub__iso_stub_AllocateArrayStub();
*(undefined8 *)(lVar1 + 0x17) = 0x82;
*(undefined8 *)(lVar1 + 0x1f) = 0x84;
*(undefined8 *)(lVar1 + 0x27) = 0x86;
*(undefined8 *)(lVar1 + 0x2f) = 0x88;
*(undefined8 *)(lVar1 + 0x37) = 0x8a;
new__GrowableList._withData();
*(undefined8 *)(extraout_RAX + 0xf) = 10;
return;
}
0x82、0x84、0x86、0x88、0x8a十进制为130、132、134、136、138。
dec值是代码中最初值(65、66、67、68、69)的两倍。我不确定为什么会发生这种情况……
我的目标是能够通过. aot文件告诉“ABCDE”是所需的输入。谢谢:)
这是smi编码,它是VM如何在内部表示对象引用的实现细节。
通常,对象引用是指向堆分配对象结构的指针。
然而,为了节省空间和时间,DartVM在内部将小整数(简称Smi)直接表示为特殊格式(标记)的引用,而不是指向堆对象的指针。(在64位VM中,“小”整数实际上是所有可以存储在63位中的整数。)
小整数的表示形式正是向左移动一的整数,又名。乘以二,第0位有一个零。这有一个优点,就是可以直接在标记的值上添加或减去Smis,只要它不溢出。
相反,所有对堆对象的引用都将第0位设置为1
。无论如何,访问对象的成员都是通过相对于对象引用进行索引来完成的,因此使用n-1而不是n的偏移量不会花费额外的费用。