Python逆向入门教程
Python逆向工程能够帮助我们深入理解程序的运行机制,强化我们的安全意识,同时也能够提高我们的开发能力。这篇教程将会介绍如何使用Python逆向工程。
1.准备工作
在正式开始前,我们需要安装一些工具:
- Python
- GDB (Gnu DeBugger)
- strace
2.逆向目标
在这个教程中,我们将会以一个简单的C语言程序hello.c
为例进行逆向工程,该程序的代码如下:
#include <stdio.h>
int main(){
printf("Hello World");
return 0;
}
3.使用strace跟踪程序
首先,我们需要使用strace来跟踪程序的系统调用,以了解程序的运行机制。
$ strace ./hello
execve("./hello", ["./hello"], [/* 73 vars */]) = 0
brk(NULL) = 0x55ac3c921000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
...
上面的输出展示了程序在运行时的系统调用,有些是我们熟悉的函数,比如fread()
、fwrite()
,有些则比较陌生。需要注意的是,strace只能跟踪Linux中的系统调用。
4.使用gdb调试程序
接下来,我们需要使用gdb来调试程序,以获取更加详细的信息。
首先,我们需要在编译时添加-g参数,生成debug信息:
$ gcc -g -o hello hello.c
然后,我们用gdb打开程序:
$ gdb hello
接下来,我们可以使用gdb的命令来进行调试。下面是一些常用的命令:
run
: 运行程序break
: 添加断点next
: 单步执行下一行代码info registers
: 显示当前寄存器中的值x/10x $esp
: 显示栈中的前10个元素的十六进制值
此处为了方便,不做过多的演示。你可以在gdb的官方文档中找到更多的命令和用法。
5.使用IDA Pro逆向程序
最后,我们使用IDA Pro分析程序,以获取更深入的代码信息。
首先,我们需要使用gcc的-m32
选项来让程序生成32位的可执行文件,以便IDA Pro进行分析。
然后,我们用IDA Pro打开程序:
$ ida hello
IDA Pro提供了一个直观的交互界面,可以让我们更加轻松地了解程序的结构。比如可以查看函数的调用关系,查看函数内的几乎执行路径等等。
6.示例
示例1:使用gdb查看函数调用栈
为了方便演示,我们重新编写一个C程序:
#include <stdio.h>
void func2(){
printf("Inside function 2\n");
}
void func1(){
func2();
}
int main(){
func1();
return 0;
}
首先我们需要用-g参数编译程序进行调试:
$ gcc -g -o callstack callstack.c
然后我们启动gdb调试程序:
$ gdb callstack
通过break
命令设置断点,并运行程序:
(gdb) break main
(gdb) run
程序暂停在了main
函数中,我们可以使用step
命令单步执行程序,然后使用bt
命令查看函数调用栈:
(gdb) step
(gdb) bt
输出结果如下:
#0 main () at callstack.c:12
(gdb) step
Inside function 1
13 void func1(){
(gdb) bt
#0 func1 () at callstack.c:13
#1 0x08048754 in main () at callstack.c:18
示例2:查看程序流程
我们继续使用刚才的程序,通过IDA Pro查看程序流程。打开IDA Pro并加载程序后,可以看到下面的汇编代码:
push ebp
mov ebp,esp
sub esp,0x10
call 0x8048440 <__x86.get_pc_thunk.ax>
add eax,0x1a19
mov DWORD PTR [esp+0x8],0x8048560
mov DWORD PTR [esp+0x4],0x1
mov DWORD PTR [esp],0x8048577
call 0x8048320 <printf@plt>
mov esp,ebp
pop ebp
ret
通过IDA Pro我们可以看到,程序的第7条语句调用了printf
函数。这个函数是如何被调用的呢?可以使用快捷键F5
进入函数:
push ebp
mov ebp,esp
sub esp,0x18
call 0x8048430 <__x86.get_pc_thunk.bx>
add ebx,0x1a08
mov eax,ebx
mov DWORD PTR [esp+0x4],eax
mov DWORD PTR [esp],0x8048586
call 0x8048310 <puts@plt>
mov eax,0x0
leave
ret
通过这个例子,我们可以清晰地了解程序的调用关系,以及函数内部执行逻辑。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python逆向入门教程 - Python技术站