[Asm] 纯文本查看 复制代码 function readStringFromMemory(address) {
var maxStringLength = 256;
var rawValue = Memory.readByteArray(address, maxStringLength);
var str = '';
try {
str = AnsiStringDecode(rawValue, maxStringLength);
if (isPrintable(str)) {
return str
}
} catch (e) {}
try {
str = Memory.readUtf8String(address, maxStringLength);
if (isPrintable(str)) return str
} catch (e) {}
try {
str = Memory.readUtf16String(address, maxStringLength);
if (isPrintable(str)) return str
} catch (e) {}
return ''
}
function isPrintable(str) {
return /^[\u4e00-\u9fa5a-zA-Z0-9]+$/.test(str)
}
function trackFunctionCall(modelName, offset, printRegisters = true, printStack = true) {
var baseAddr = Module.findBaseAddress(modelName);
var targetAddress = baseAddr.add(offset);
console.log("\x1b[33m-----------------------------\x1b[0m");
console.log("\x1b[32m基地址:" + baseAddr + "\x1b[0m");
console.log("\x1b[34m当前HOOK函数地址:" + targetAddress + "\x1b[0m\x1b[31;4m { " + modelName + "!" + offset + " } \x1b[0m");
console.log("\x1b[33m-----------------------------\x1b[0m");
Interceptor.attach(targetAddress, {
onEnter: function(args) {
var is32bit = Process.arch === 'ia32';
console.log("\x1b[35m已进入函数 " + targetAddress + " 中\x1b[0m");
if (printRegisters) {
console.log("\x1b[36m寄存器 (" + (is32bit ? "x32" : "x64") + "):\x1b[0m");
if (is32bit) {
console.log("\x1b[36mEAX:", this.context.eax + "\x1b[0m");
console.log("\x1b[36mECX:", this.context.ecx + "\x1b[0m");
console.log("\x1b[36mEDX:", this.context.edx + "\x1b[0m");
console.log("\x1b[36mEBX:", this.context.ebx + "\x1b[0m");
console.log("\x1b[36mESP:", this.context.esp + "\x1b[0m");
console.log("\x1b[36mEBP:", this.context.ebp + "\x1b[0m");
console.log("\x1b[36mESI:", this.context.esi + "\x1b[0m");
console.log("\x1b[36mEDI:", this.context.edi + "\x1b[0m");
console.log("\x1b[36mEIP:", this.context.eip + "\x1b[0m")
} else {
console.log("\x1b[36mRCX (第1个参数):", this.context.rcx + "\x1b[0m");
console.log("\x1b[36mRDX (第2个参数):", this.context.rdx + "\x1b[0m");
console.log("\x1b[36mR8 (第3个参数):", this.context.r8 + "\x1b[0m");
console.log("\x1b[36mR9 (第4个参数):", this.context.r9 + "\x1b[0m")
}
console.log("\x1b[33m-----------------------------\x1b[0m")
}
if (printStack) {
console.log("\x1b[34m堆栈跟踪\x1b[0m");
this.stack = Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n");
console.log("\x1b[34m" + this.stack + "\x1b[0m");
console.log("\x1b[33m-----------------------------\x1b[0m");
console.log("\x1b[34m堆栈内容:\x1b[0m");
var stackIncrement = is32bit ? 4 : 8;
var stackPointer = is32bit ? this.context.esp : this.context.rsp;
var basePointer = is32bit ? this.context.ebp : this.context.rbp;
for (var address = stackPointer; address.compare(basePointer) <= 0; address = address.add(stackIncrement)) {
try {
var addressValue = ptr(address);
var pointerValue = addressValue.readPointer();
var data = '地址:' + address.toString(16).padStart(is32bit ? 8 : 16, '0') + ' => ';
if (pointerValue.isNull()) {
data += 'NULL'
} else {
var isValidPointer = true;
try {
pointerValue.readPointer()
} catch (e) {
isValidPointer = false
}
if (isValidPointer) {
try {
var maybeString = readStringFromMemory(pointerValue);
if (maybeString.length > 0 && isPrintable(maybeString)) {
data += '字符串: ' + JSON.stringify(maybeString)
} else {
throw new Error('Not a string');
}
} catch (e) {
try {
var pointedValue = pointerValue.readPointer();
data += '[' + pointerValue.toString(16).padStart(8, '0') + '] => ' + pointedValue.toString(16).padStart(8, '0')
} catch (e) {
data += pointerValue.toInt32()
}
}
} else {
data += pointerValue.toInt32()
}
}
console.log("\x1b[34m" + data + "\x1b[0m")
} catch (e) {
console.log("\x1b[31m读取内存地址错误:\x1b[37m " + address.toString(16) + "\x1b[0m")
}
}
}
}
})
}
var modelName = "Project1.exe";
var offset = ptr("0x117C0");
trackFunctionCall(modelName, offset, true, true);
随便写的存档一下,也许有用吧 |