ch25.bin

逆向 root_me

ch25.bin

https://www.root-me.org/en/Challenges/Cracking/ELF-C-0-protection?lang=en

识别C++类

如何识别软件是用C++所写?
1 频繁使用ECX 保存this 指针 ,指向类对象,如在调用函数前
2 虚函数 要先知道类虚函数表,然后得到实际值,也是传到ECX中
3 使用STL code 可用IDA imports查看

类怎么在内存中存储

每个变量四字节
不足要对齐
内存中排列与定义相同


虚函数表要在最开头
表包含虚函数地址,按定义排序

如果继承另一个类

继承多个类
虚表按顺序排序


识别类

1 识别构建和撤销
1.1 全局变量

在编译时 保存到(PE)文件的数据段
构建在main()前调用

用this调用全局变量,在EP和main()间,确定为构建

1.2局部变量
指针指向未初始化的栈变量

1.3动态分配变量 new()

堆上分配

2多态类识别
2.1鉴别多态通过RTTI,其可以让对象在运行时确定类型。

RTTICompleteObjectLocator pointer


TypeDescriptor
指向的结构包含类名


RTTIClassHierarchyDescriptor


RTTIBaseClassDescriptor


vftable
vbtable (virtual base class table)


指令E9

指令E9 相对寻址
e9 xxxxxxxx
xxxxxxxx=要跳转的地址-当前指令地址-当前指令长度(5)
e9 00 00 00 00 即跳转到下一个地址
402005-402000-5=000000

指令EB

EB表示short jmp命令,进行短距离跳转
eb xx


指令setne

set if not equal
setne cl
if ZF=1 then cl=0
if ZF=0 then cl=1

strings 命令
display printable strings in [file(s)] (stdin by default)


破解方法1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ gdb ./ch25.bin 
(gdb) set args toto //设置输入参数toto
(gdb) b main //在main设置断点
Breakpoint 1 at 0x8048a95
(gdb) r //运行程序(到断点)
Breakpoint 1, 0x08048a95 in main ()
(gdb)disass //显示汇编代码
(gdb) b *main+268
gdb)c 继续执行
(gdb) layout prev 可以查看堆栈和汇编代码
(gdb) x/1xw $eax
“ x / 1xw $ eax命令在EAX寄存器中包含的地址处显示1个十六进制格式的16位字
(gdb) x/1s 0X08050b24
查看该地址值

破解方法2

radare2 类似IDA

1
2
3
4
r2 ch25.bin
aaa //分析函数,参数...
VV @main //使用 VV 进入 图形化模式(需要是函数范围内)。
pdf @ main //分析后就可以正常打印函数代码了(pdf 打印函数代码)

peda是GDB的一个插件
https://github.com/longld/peda

gdb-peda$ run jlkd 带参数运行