Rust逆向基础-1

翻译并且进行了部分的筛选。

首先还是得尽量让代码比较好看,所以推荐一个 ida 插件,下面很多结果为了好看都使用了这个插件

IDARustDemangler

这个可以对函数名进行一定程度的重命名,然而好像有点 bug,尤其是对于一些较大的 rust 程序。。。。

好吧,下面是原文的一部分内容

一个空的程序

Rust 逆向基础 -1

首先是 main 函数。需要注意的不仅仅是 main 函数(rust 程序的),还有 lang_start 函数

点进来看

Rust 逆向基础 -1

除了有 c 语言版的函数参数,还多了 a1 传进 lang_start_internal,虽然很显然是原来 main 的指针,还是看一下 rs 源码吧

Rust 逆向基础 -1

确实是这样,可以看出注册了有异常处理相关的东西,在 Windows 下是 VEH,在 linux 下是 stack unwind

下面是 win 的

Rust 逆向基础 -1

然后还有一点,对于 linux(win 我没找到),rs 有垃圾回收机制,如图

Rust 逆向基础 -1

这个会被 internal 函数调用。但是,这个 drop 是可以自定义的(也许可以出题?坏笑)

好吧,基础流程就到这里,下面会讲一下别的例如字符串啥的

Hello World

fn main() {println!("Hello, world!");
}

代码如上,非常的简单。
以下是编译完的结果
Rust 逆向基础 -1

对于函数 core::fmt::Arguments::new_v1,很显然是在初始化下面要调用的 println 所需要的函数参数。而 off_4C1E8,点进去就能发现是我们储存的字符串。

不过在继续讲这个函数原理之前要提到另一个问题,就是 rust 中的字符串储存问题。点进去就能发现,其实 rs 储存字符串,也就是 &str, 采用的是不同于 c 语言的方式,使用了字符串的指针 + 长度的方式进行储存。

In [1]: 0xe
Out[1]: 14

In [2]: len("Hello, world!\n")
Out[2]: 14

所以其实可以说是这样

struct rs_string
{
  __int64 ptr_string;
  __int64 length;
};

但是,实际上点进指针就能发现,真正储存的时候还是以传统 c 风格进行了储存,因为最后还是出现了 0 位
Rust 逆向基础 -1

那么看完字符串的基本问题后,我们来看一下这个经常出现的 ArgumnentV1 到底是干什么的?不妨来看一下源码
Rust 逆向基础 -1
和我们直接反编译出来的其实很像。而原作者提到,他认为别的地方不是很容易出现这个,这个函数的出现往往预示着关键的字符串操作,如准备进行格式化的输出等。

他还提到了一点,对于 rust 程序有一点比较特别,就是在准备输出时会使用一条奇怪的指令,在伪代码中看起来是这样的:

_InterlockedCompareExchange((volatile signed __int32 *)v5 + 4, 1, 0)

而其实这是一条不常用的汇编代码

lock cmpxchg [rbx+10h], ecx

有可能也能凭借这一点进行判断,尤其是被扣了符号表的情况下
(真的是有这样的题的。。。)

 

 

 

正文完
 0
评论(没有评论)