jwzyjwzy 发表于 2024-3-20 21:32

打印堆栈信息

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);
随便写的存档一下,也许有用吧

zxb1997 发表于 2024-3-21 07:02

感谢分享。

天南地北一群魔 发表于 2024-3-21 07:55

分享快乐。

Adventure 发表于 2024-3-21 16:09

感谢分享 学习了
页: [1]
查看完整版本: 打印堆栈信息