使用frida转储寄存器值

逆向工程 拆卸 视窗 调试 职能 弗里达
2021-06-15 21:12:04

我是 frida 的新手,遇到了这个问题。

我有我想反转工程师的 dll(没有调试符号)。具体来说,我想从函数中转储一些数据。所以我有这个大函数,这是它的片段:

在此处输入图片说明

在这里你可以看到一些 string( pf4) 被移到了edx,但更重要的是在那之后。您可以看到该sub_575FD30 函数被调用了几次。

对我来说最有趣的是eax通话后的登记。所以我想做的是eax在调用这个函数之后转储值

我不能考虑从sub_575FD30函数中转储某些东西,因为该函数是从许多其他地方eax调用的,我特别想在这个特定示例中调用它后转储

我的问题是如何使用 frida 实现它?我应该硬编码指令地址(地址push eax)并获取值eax吗?这是正确的方法还是有更好的方法来实现它?如何实现它和脚本示例的任何方向都将被应用。

1个回答

详细信息都可以在拦截器Javascript API 文档中找到

下面是一个小演示

假设您有如下源代码,adder 函数将从 3 个地方调用,总共调用 26 次

#include <stdio.h>
int adder( int a , int b) {
    return a+b;
}
int addonce (int a, int b) {
    return adder(a,b);
}
int addtwice (int a, int b) {
    return adder(a,b) + adder (a,b);
}
int addntimes(int a, int b, int c) {
    int res = 0;
    for (int i = 0; i < c; i++ ) {
        res = res + adder(a,b);
    }
    return res;
}
void main(void) {
    getchar();
    printf("%d\n", addonce(2,3));
    printf("%d\n", addtwice(2,3));
    printf("%d\n", addntimes(2,3,10));
    printf("%d\n", addonce(2,3)+addtwice(2,3)+addntimes(2,3,10));
}  

用 vs 2017 社区编译并执行

cl /Zi /W4 /analyze /Od /EHsc mulcall.cpp /link / release 
5
10
50
65

弗里达python脚本

import frida
import sys

session = frida.attach("mulcall.exe")
script = session.create_script("""
Interceptor.attach
(
    ptr("%s"),
    {
        onEnter: function(args) 
        {
            console.log("entering  intercepted function will return to " + this.returnAddress);
        } ,
        onLeave: function(retval)
        {
            console.log( "leaving intercepted function returning " + retval.toInt32());
        }
    }
);
""" % int(sys.argv[1], 16))

def on_message(message, data):
    print(message)
script.on('message', on_message)
script.load()
sys.stdin.read()

您需要必须传递的加法器函数的地址(在您的情况下为 sub_yyyy 的 5xxx 地址)请注意 ASLR 可能会起作用您总是需要正在运行的实例的新地址而不是过去实例的一些陈旧地址

你会像这样运行脚本

python friscript.py 7ff670901000

0x00007ff670901000 是我的 adder() 的地址我已经执行了 exe 并且它正在等待按键现在我运行它附加的上面的脚本并等待直到我在等待实例中按下一个键

这是弗里达的输出

python friscript.py 7ff670901000
entering  intercepted function will return to 0x7ff670901039
leaving intercepted function returning 5
entering  intercepted function will return to 0x7ff670901069
leaving intercepted function returning 5
entering  intercepted function will return to 0x7ff67090107a
leaving intercepted function returning 5
entering  intercepted function will return to 0x7ff6709010d4
leaving intercepted function returning 5 (10 times)
entering  intercepted function will return to 0x7ff670901039
leaving intercepted function returning 5
entering  intercepted function will return to 0x7ff670901069
leaving intercepted function returning 5
entering  intercepted function will return to 0x7ff67090107a
leaving intercepted function returning 5
entering  intercepted function will return to 0x7ff6709010d4
leaving intercepted function returning 5 (10 times)

编辑以解决评论

如果 eax 是指向某种类型的指针 (ansi,wide,utf8,utf16,bytearray,struct *)

在 onLeave {} 中使用适当的辅助函数
这里是返回 struct *
struct { int a , char * b } 的函数的实现

  // hack for getting the next member of struct  (adding pointer size  of 
  // 32bit machine read documents to see if you can cast the return 
  // value to proper structure type 
  // so that we can use (foo *) (this.context.eax)->a 
  // instead of hacks like add(4) 

  foo = Memory.readPointer(this.context.eax.add(4)) 
  blah = Memory.readCString(foo)
  log( blah )