反汇编二进制代码

最近又做了一些内核hook的工作,繁琐的地方在于二进制指令的可读性上,下面简要记录dump出指令二进制,之后利用binutils来转成可读的汇编代码.

hook的主要流程参考之前的linux内核态hook模块-splice,主要就是构建一个trampoline的代码区域,主要的工作就是操作堆栈,返回地址,还有修复跳转地址.

不聊这么复杂的东西,回归主题,dump指令很简单,将指令按照16进制打印出来,4个字节一组

void dump(void *buf, int len) {
    int i = 0;
    int *buffer = buf;
    for (; i < len; i++) {
             printk("%08x ", buffer[i]);
    }
    printk("\n");
}

之后dump出来的是assic字符串,类似于下面的东西:

3c02c147 67bdffb0 64427178 eba50124 eba700e6 eba900a8 ebab006a ffbf0008 0040f809 00000000 dfbf0008 cba50124 cba700e6 cba900a8 cbab006a 67bd0050 10400003 00000000 03e00008 00000000 3c1880a3 6718a358 10a00015 00000000 67bdfff0 00804825 03000008 00000000 00000000 00000000 00000000 00000000 004c5559 00000000 00000020 02000000 002f88ce 00000000 004c5565 00000000 00000020 02000000 002fa19c 00000000 004c5571 00000000 00000020 02000000 002eff2b 00000000 004c557d 00000000 00000020 02000000 002f6de8 00000000 004c5589 00000000 00000020 02000000 002f2b24 00000000 004c5595 00000000

之后需要将这些字符换重新转换成binary格式的,和打印的格式是相互约定好的,之后将assic格式的指令重新翻译成纯数据类型的的.

#define MYFILE	"ins.txt"
#define OBJFILE	"ins.obj"
int main(int argc, char **argv)
{
	char buf[9] = {0};
	int ret, ins;
	FILE *fp = fopen(MYFILE, "r");
	FILE *fp2 = fopen(OBJFILE, "w+");
	if (!fp||!fp2) {dprintf(2, "can't open %s", MYFILE); exit(-1);}

	while(fread(buf, sizeof(buf), 1, fp) > 0) {
		buf[8] = 0;
		ins = strtol(buf, NULL, 16);
		fwrite(&ins, sizeof(ins), 1, fp2);
	}

	fclose(fp);
	fclose(fp2);
	exit(0);
}

现在可以着手翻译了,但是objdump反汇编的对象一般是有格式的文件,通常是elf家族的,我们这里也取个巧,将指令加到现有elf的段中,之后使用objdump -D选项反编译所有的数据.

objcopy --add-section myins=ins.obj a.out
objcopy --update-section myins=ins.obj a.out
objdump -D a.out > 1

到这里我们就可以需要查看myins section的指令对应的汇编格式了.

Disassembly of section myins:

0000000000000000 :
   0:   3c02c147    lui v0,0xc147
   4:   67bdffb0    daddiu  sp,sp,-80
   8:   64427178    daddiu  v0,v0,29048
   c:   eba50124    gssq    a0,a1,64(sp)
  10:   eba700e6    gssq    a2,a3,48(sp)
  14:   eba900a8    gssq    a4,a5,32(sp)
  18:   ebab006a    gssq    a6,a7,16(sp)
...

上面不牵扯到任何的原理,纯粹是个小工具来帮助分析我们手工修改的指令内容.

应用层的指令翻译就很好整了,基本都只是gdb,直接attach上disassemble完事,只有内核这么复杂的东西才需要来回捯饬.

如有哪位大侠有更简便的方法,望不吝赐教.

你可能感兴趣的:(linux)