此博客来自他人,下面是自己的见解,因为正好用到相关内容
objdump对纯2进制文件(hello.bin)反汇编
objdump -m i386 -b binary -D hello.bin
-m:指出反汇编目标架构
-b:文件格式
在进程中加载执行纯2进制可执行文件bin
- mmap把2进制文件映射到进程用户内存空间,
- 将程序控制权交给bin
linux下用汇编通过中断调用api打印一个hello world (nasm版本),
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| [section .data] output: db "Hello World",0 length db 12 [section .text] global _start
_start: mov eax,4 mov ebx,1 mov ecx,output mov edx,[length] int 0x80 ;sys_write(1,buf,size) mov eax,1 mov ebx,0 ;sys_exit int 0x80
|
软中断调用api 参数意义
1. 编译成.o可重定位文件 `nasm -f elf64 hello.s -o hello.o`
- 因为bin文件被映射到进程内存空间,控制流jmp到映射的内存首地址就能够继续执行可执行二进制文件bin,
- 因为编译的时候指定bin的text段入口地址是0x00000000,链接完后text段的符号重定位值是根据入口地址=0决定的,(对此hello.s文件而言)
- 那么如果映射到虚拟内存空间地址A时,bin中的在链接期间可重定位符号的偏移量要加上A,
查看hello.o中的重定位信息,objdump -D -r hello.o
看到的符号在section中的偏移量分别是0x0B和0x12,并且在link前值都是0
静态链接: 将.data和.text合成一个.text section
link script test.ld
1 2 3 4 5 6 7 8
| SECTIONS { . = 0x00000000; .text : { *(.text) *(.data) } }
|
ld -T test.ld hello.o -o hello.elf
原来的重定位符号之被link修改,(根据.text的入口地址
所以在进程中加上加载到的虚拟地址就能成功执行纯2进制代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| #include <stdlib.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <sys/mman.h>
int main() { int fd; int ret; unsigned char *buf; struct stat stat; void *res; unsigned int ImageBase; int rebase[2] = {0x0B,0x12}; unsigned char *temp;
ImageBase = 0x00010000;
fd = open("hello.bin",O_RDWR); if (fd < 0) { perror("fd"); return -1; }
ret = fstat(fd,&stat); if (ret < 0) { perror("fstat"); return -1; }
buf = (unsigned char *)malloc(stat.st_size); if (buf == NULL) { perror("allocate"); return -1; }
ret = read(fd,buf,stat.st_size); if (ret < 0 || ret != stat.st_size) { perror("read"); return -1; }
res = mmap((void*)ImageBase,stat.st_size,PROT_EXEC | PROT_WRITE | PROT_READ,MAP_PRIVATE,fd,0); if (res == MAP_FAILED) { perror("mmap"); return -1; }
printf("%p \n",res); for (int i=0; i<2; i++) *(unsigned int *)((char *)res + rebase[i]) += ImageBase;
temp = (unsigned char *)res; for (int i=0; i<0x100; i++) printf("%02X%s",*temp++,(i+1)%0x10?" " : "\n");
__asm__ volatile ("\n\t"\ "jmp *%0\n\t"\ ::"mem"(res): ); printf("done\n"); return 0; }
|