反汇编区段加密代码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反汇编区段加密代码相关的知识,希望对你有一定的参考价值。

参考技术A 加区加密 都是小儿科的 给你一个 厉害的代码 输入表输出表 完全破坏 ! 实战输入表完全破坏 隐藏代码:(万能代码) 60 E8 01 00 00 00 00 58 80 38 00 0F 85 F5 00 00 00 FE 00 64 A1 30 00 00 00 8B 40 0C 8B 40 1C 8B 00 8B 40 08 8B D8 E8 0F 00 00 00 47 65 74 50 72 6F 63 41 64 64 72 65 73 73 00 59 60 89 C3 89 CF 30 C0 AE 75 FD 4F 29 CF 87 F9 8B 43 3C 8B 74 03 78 8D 74 1E 18 AD 92 AD 50 AD 95 AD 95 01 D8 89 7C 24 18 89 4C 24 14 4A 74 27 8B 34 90 01 DE F3 A6 74 0A 8B 7C 24 18 8B 4C 24 14 EB EA D1 E2 01 D5 0F B7 44 1D 00 C1 E0 02 03 04 24 8B 04 03 01 D8 59 89 44 24 1C 89 5C 24 18 E8 12 00 00 00 00 00 00 00 4C 6F 61 64 4C 69 62 72 61 72 79 41 00 00 59 83 C1 04 51 53 FF D0 89 44 24 14 E8 00 00 00 00 5D 81 E5 00 00 FF FF 33 C0 EB 06 81 ED 00 10 00 00 66 8B 45 00 66 3D 4D 5A 90 75 EF 8B 45 3C 8B 04 28 3D 50 45 00 00 75 E2 B8 48 61 11 00 36 8D 1C 28 8B 43 0C 85 C0 74 0A E8 0D 00 00 00 83 C3 14 EB EF 61 E9 82 8F F9 FF 90 90 53 8D 14 28 52 FF 54 24 20 8B D0 8B 5B 10 8D 1C 2B 8B 03 85 C0 74 23 3D 00 00 00 80 72 07 2D 00 00 00 80 EB 06 8D 04 28 83 C0 02 52 50 52 FF 54 24 30 89 03 83 C3 04 5A EB D7 5B C3

反汇编工具objdump的使用以及反汇编文件的解读

什么是反汇编

反汇编顾名思义就是汇编的逆过程,将二进制文件反汇编成汇编代码。arm-linux-objdump是交叉编译工具链里的一个工具,专门用来反汇编的,将二进制代码反汇编成汇编代码来查看。

为什么要反汇编

1.逆向破解。将可执行程序反汇编得到汇编代码,再根据汇编代码推理出整个程序的逻辑。这个不是一般人能做的,能看懂大量汇编语言写的程序都很困难了,更别说反推别人的代码逻辑。
2.调试程序时可以帮助我们理解并检测生成的可执行程序是否正常,尤其是在理解链接脚本和链接地址等概念时。
3.C语言的源代码编译链接生成的可执行文件再反汇编,可以帮助我们理解C语言和汇编语言的对应关系,有助于深入理解C语言。

反汇编文件的生成和解读

反汇编文件的生成:

led.bin: start.o 
	arm-linux-ld -Ttext 0x0 -o led.elf $^
	arm-linux-objcopy -O binary led.elf led.bin
	arm-linux-objdump -D led.elf > led_elf.dis
	gcc mkv210_image.c -o mkx210
	./mkx210 led.bin 210.bin
	
%.o : %.S
	arm-linux-gcc -o $@ $< -c

%.o : %.c
	arm-linux-gcc -o $@ $< -c 

clean:
	rm *.o *.elf *.bin *.dis mkx210 -f

上面是一个简单的Makefile,功能是把源文件.S和.c先编译成.o文件,再把.o文件链接成.elf的可执行文件。arm-linux-objdump -D led.elf > led_elf.dis是将led.elf反汇编成ed_elf.dis。

源文件:star.s是一个汇编文件

//.globl 表明后面的变量有全局属性,对应于C语言的全局变量
.globl _start

_start:
	 设置GPJ0CON的bit[0:15],配置GPJ0_0/1/2/3引脚为输出功能
	// 设置GPJ0CON的bit[12:23],配置GPJ0_3/4/5引脚为输出功能
	ldr r1, =0xE0200240 					
	ldr r0, =0x00111000
	str r0, [r1]

	mov r2, #0x1000

	//设置GPD0_1为输出模式
	ldr r1, =0xE02000A0 					
	ldr r0, =0x00000010
	str r0, [r1]	
	
led_blink:
	 设置GPJ2DAT的bit[0:3],使GPJ2_0/1/2/3引脚输出低电平,LED亮
	// 设置GPJ0DAT的bit[3:5],使GPJ0_3/4/5引脚输出低电平,LED亮
	ldr r1, =0xE0200244 					
	mov r0, #0
	str r0, [r1]
	
	ldr r1, =0xE02000A4					
	mov r0, #0
	str r0, [r1]

	// 延时
	bl delay							

	 设置GPJ2DAT的bit[0:3],使GPJ2_0/1/2/3引脚输出高电平,LED灭
	// 设置GPJ0DAT的bit[3:5],使GPJ0_3/4/5引脚输出高电平,LED灭
	ldr r1, =0xE0200244 					
	mov r0, #0x38
	str r0, [r1]
	
	ldr r1, =0xE02000A4					
	mov r0, #0x2
	str r0, [r1]

	// 延时
	bl delay	

	sub r2, r2, #1
	cmp r2,#0
	bne led_blink


halt:
	b halt


delay:
	mov r0, #0x900000
delay_loop:
	cmp r0, #0
	sub r0, r0, #1
	bne delay_loop
	mov pc, lr

star.s是一个学习S5PV210开发板时点亮LED的汇编程序,由开始、点亮、延时和死循环组成,在这里并不关注具体实现的功能,重点是和反汇编生成的文件进行对照。

得到的反汇编文件:led_elf.dis

led.elf:     file format elf32-littlearm

Disassembly of section .text:
//第一列  第二列     第三列 
00000000 <_start>:
   0:	e59f1070 	ldr	r1, [pc, #112]	; 78 <delay_loop+0x10>
   4:	e59f0070 	ldr	r0, [pc, #112]	; 7c <delay_loop+0x14>
   8:	e5810000 	str	r0, [r1]
   c:	e3a02a01 	mov	r2, #4096	; 0x1000
  10:	e59f1068 	ldr	r1, [pc, #104]	; 80 <delay_loop+0x18>
  14:	e3a00010 	mov	r0, #16
  18:	e5810000 	str	r0, [r1]

0000001c <led_blink>:
  1c:	e59f1060 	ldr	r1, [pc, #96]	; 84 <delay_loop+0x1c>
  20:	e3a00000 	mov	r0, #0
  24:	e5810000 	str	r0, [r1]
  28:	e59f1058 	ldr	r1, [pc, #88]	; 88 <delay_loop+0x20>
  2c:	e3a00000 	mov	r0, #0
  30:	e5810000 	str	r0, [r1]
  34:	eb00000a 	bl	64 <delay>
  38:	e59f1044 	ldr	r1, [pc, #68]	; 84 <delay_loop+0x1c>
  3c:	e3a00038 	mov	r0, #56	; 0x38
  40:	e5810000 	str	r0, [r1]
  44:	e59f103c 	ldr	r1, [pc, #60]	; 88 <delay_loop+0x20>
  48:	e3a00002 	mov	r0, #2
  4c:	e5810000 	str	r0, [r1]
  50:	eb000003 	bl	64 <delay>
  54:	e2422001 	sub	r2, r2, #1
  58:	e3520000 	cmp	r2, #0
  5c:	1affffee 	bne	1c <led_blink>

00000060 <halt>:
  60:	eafffffe 	b	60 <halt>

00000064 <delay>:
  64:	e3a00609 	mov	r0, #9437184	; 0x900000

00000068 <delay_loop>:
  68:	e3500000 	cmp	r0, #0
  6c:	e2400001 	sub	r0, r0, #1
  70:	1afffffc 	bne	68 <delay_loop>
  74:	e1a0f00e 	mov	pc, lr
  78:	e0200240 	eor	r0, r0, r0, asr #4
  7c:	00111000 	andseq	r1, r1, r0
  80:	e02000a0 	eor	r0, r0, r0, lsr #1
  84:	e0200244 	eor	r0, r0, r4, asr #4
  88:	e02000a4 	eor	r0, r0, r4, lsr #1

Disassembly of section .ARM.attributes:

00000000 <.ARM.attributes>:
   0:	00001a41 	andeq	r1, r0, r1, asr #20
   4:	61656100 	cmnvs	r5, r0, lsl #2
   8:	01006962 	tsteq	r0, r2, ror #18
   c:	00000010 	andeq	r0, r0, r0, lsl r0
  10:	45543505 	ldrbmi	r3, [r4, #-1285]	; 0x505
  14:	08040600 	stmdaeq	r4, {r9, sl}
  18:	Address 0x00000018 is out of bounds.


解析:
1.第一行:led.elf: file format elf32-littlearm。表明此汇编程序是由led.elf生成,程序是32的小端模式。
2.00000000 <_start>:前面的00000000是标号的地址,<_start>是标号,对应start.s的_start标号。其实标号就相当于C语言中的函数名,在C语言中也可以用函数名代表函数的首地址,在这里可以得到印证。反汇编的标号就是由汇编文件得来的,这样可以方便我们找到反汇编文件和汇编文件对应的部分。
3.整个反汇编文件分为三列,分别对应:指令地址、指令机器码、指令机器码反汇编到的指令。

反汇编文件led_elf.dis解读:

//汇编文件
_start:
	 设置GPJ0CON的bit[0:15],配置GPJ0_0/1/2/3引脚为输出功能
	// 设置GPJ0CON的bit[12:23],配置GPJ0_3/4/5引脚为输出功能
	ldr r1, =0xE0200240 					
	ldr r0, =0x00111000
	str r0, [r1]

	mov r2, #0x1000

//对应的反汇编文件部分
00000000 <_start>:
   0:	e59f1070 	ldr	r1, [pc, #112]	; 78 <delay_loop+0x10>
   4:	e59f0070 	ldr	r0, [pc, #112]	; 7c <delay_loop+0x14>
   8:	e5810000 	str	r0, [r1]
   c:	e3a02a01 	mov	r2, #4096	; 0x1000
   ......
  70:	1afffffc 	bne	68 <delay_loop>
  74:	e1a0f00e 	mov	pc, lr
  78:	e0200240 	eor	r0, r0, r0, asr #4
  7c:	00111000 	andseq	r1, r1, r0
  80:	e02000a0 	eor	r0, r0, r0, lsr #1
  84:	e0200244 	eor	r0, r0, r4, asr #4
  88:	e02000a4 	eor	r0, r0, r4, lsr #1

我们在这里对汇编文件的前几句进行解读:
1.ldr r1, [pc, #112]:此句对应于汇编文件的ldr r1, =0xE0200240。功能是将0xE0200240存到r1寄存器中。[pc, #112]代表pc+70地址处的数据(#112是十进制),此时PC指向的是当前地址的下两级,就是pc = 0 + 8,于是pc + 70 = 78。78地址处存放的数据就是e0200240,刚好等于汇编语句要加载的数据0xE0200240。所以ldr r1, [pc, #112]和ldr r1, =0xE0200240实现的是同样的功能。
2.ldr r0, [pc, #112]对应于汇编文件的ldr r0, =0x00111000。解读的方式和上面一致,只是要注意此时PC= 4 + 8。
3. str r0, [r1]语句汇编语句和反汇编语句是一致的。
4. mov r2, #4096对应于汇编的
mov r2, #0x1000
,两者是相同的,十进制的4096等于十六进制的0x1000。
补充:1.PC指向当前地址的前两级是因为流水线的存在,不同型号的ARM芯片流水线的级数是不同的,但是在反汇编文件里为了统一,都是按照3级流水线处理。
2.为什么向寄存器加载数据,有的是直接加载(mov r2, #4096),有的要用相对寻址的方式加载(ldr r1, [pc, #112])?这里涉及到合法立即数和非法立即数,简单来书就是数据太大,一条语句的数据部分表达不了,于是就将要加载的数据放在某个地址处,要用到的时候就去该地址处取,此时的ldr也是伪指令。

以上是关于反汇编区段加密代码的主要内容,如果未能解决你的问题,请参考以下文章

STM32F101RG 软加密解密 反汇编

汇编与反汇编

反汇编工具objdump的使用以及反汇编文件的解读

反编译和反汇编有啥区别?

黑客最简单的软件破解方法,反汇编nop指令覆盖

什么软件能将C语言的执行文件反汇编为汇编源代码