我觉得很庆幸,在 Linux 下和 MacOS 下(MacOS 本身就是 BSD 发展而来)写 C 语言的代码和 Windows 下都差不多,所以最近偶尔会看看关于 Linux 下的 C 的代码。
以前看过一些关于 Windows 下逆向方面的内容,最近想着不如有时间把 MacOS 下的逆向也看看,研究逆向比较关键的内容就是汇编(或者是虚拟机的中间字节码),这个应该在每个平台上都差不多,毕竟个人机的 CPU 架构差不多都是 x86/x64 或其兼容的平台架构。
写一个简单的待分析的 C 语言的代码,代码如下:
include <stdio.h>
int main()
{
int guess = 0;
int i = 1;
while (i <= 3)
{
printf("Please enter the num:");
scanf("%d", &guess);
if (guess == 666)
{
break;
}
i ++;
}
if (i <= 3)
{
printf("ok\n");
}
else
{
printf("error\n");
}
return 0;
}
上面的代码很简单,主要就是判断用户的输入是否输入了 666 这个数值。
用 clang 和 gcc 编译一下,然后观察它们两个的反汇编代码,后来发现没有任何区别,其反汇编代码如下:
<__text> @00000eb0 push rbp │
│_main+0 │
│ 100000eb0 ! │
│ ......... ! ;******************************************************** │
│ ......... ! ; function _main │
│ ......... ! ;******************************************************** │
│ ......... ! _main: │
│ ......... ! push rbp │
│ 100000eb1 ! mov rbp, rsp │
│ 100000eb4 ! sub rsp, 20h │
│ 100000eb8 ! mov dword ptr [rbp-4], 0 │
│ 100000ebf ! mov dword ptr [rbp-8], 0 │
│ 100000ec6 ! mov dword ptr [rbp-0ch], 1 │
│ 100000ecd ! │
│ ......... ! loc_100000ecd: ;xref j100000f18 │
│ ......... ! cmp dword ptr [rbp-0ch], 3 │
│ 100000ed1 ! jg loc_100000f1d │
│ 100000ed7 ! lea rdi, [strz_Please_enter_the_num:_100000f88] │
│ 100000ede ! mov al, 0 │
│ 100000ee0 ! call wrapper_100002000_100000f56 │
│ 100000ee5 ! lea rdi, [data_100000f9e] │
│ 100000eec ! lea rsi, [rbp-8] │
│ 100000ef0 ! mov [rbp-10h], eax │
│ 100000ef3 ! mov al, 0 │
│ 100000ef5 ! call wrapper_100002008_100000f5c │
│ 100000efa ! cmp dword ptr [rbp-8], 29ah │
│ 100000f01 ! mov [rbp-14h], eax │
│ 100000f04 ! jnz loc_100000f0f │
│ 100000f0a ! jmp loc_100000f1d │
│ 100000f0f ! │
│ ......... ! loc_100000f0f: ;xref j100000f04 │
│ ......... ! mov eax, [rbp-0ch] │
│ 100000f12 ! add eax, 1 │
│ 100000f15 ! mov [rbp-0ch], eax │
│ 100000f18 ! jmp loc_100000ecd │
│ 100000f1d ! │
│ ......... ! loc_100000f1d: ;xref j100000ed1 j100000f0a │
│ ......... ! cmp dword ptr [rbp-0ch], 3 │
│ 100000f21 ! jg loc_100000f3d │
│ 100000f27 ! lea rdi, [data_100000fa1] │
│ 100000f2e ! mov al, 0 │
│ 100000f30 ! call wrapper_100002000_100000f56 │
│ 100000f35 ! mov [rbp-18h], eax │
│ 100000f38 ! jmp loc_100000f4e │
│ 100000f3d ! │
│ ......... ! loc_100000f3d: ;xref j100000f21 │
│ ......... ! lea rdi, [strz_error__100000fa5] │
│ 100000f44 ! mov al, 0 │
│ 100000f46 ! call wrapper_100002000_100000f56 │
│ 100000f4b ! mov [rbp-1ch], eax │
│ 100000f4e ! │
│ ......... ! loc_100000f4e: ;xref j100000f38 │
│ ......... ! xor eax, eax │
│ 100000f50 ! add rsp, 20h │
│ 100000f54 ! pop rbp │
│ 100000f55 ! ret
这样的 x64 的反汇编代码看着还是很直观的。
绕过 666 的方法也是比较简单的,只要修改对应的跳转语句即可。在没有涉及到 PSDK 时,其实和在 Windows 下没有什么差别。
评论